|
|
@ -1,3 +1,5 @@
|
|
|
|
|
|
|
|
import fuzzywuzzy.fuzz
|
|
|
|
|
|
|
|
import fuzzywuzzy.process
|
|
|
|
import googleapiclient
|
|
|
|
import googleapiclient
|
|
|
|
import googleapiclient.discovery
|
|
|
|
import googleapiclient.discovery
|
|
|
|
|
|
|
|
|
|
|
@ -63,3 +65,25 @@ class Youtube(object):
|
|
|
|
return self._search(channel_id, query, playlists, limit)
|
|
|
|
return self._search(channel_id, query, playlists, limit)
|
|
|
|
except googleapiclient.errors.HttpError as e:
|
|
|
|
except googleapiclient.errors.HttpError as e:
|
|
|
|
raise YoutubeError('Failed to query Youtube API: {}'.format(e))
|
|
|
|
raise YoutubeError('Failed to query Youtube API: {}'.format(e))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def find_best_match(self, channel_ids, query):
|
|
|
|
|
|
|
|
results = []
|
|
|
|
|
|
|
|
for channel_id in channel_ids:
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
|
|
results.extend(self._search(channel_id, query, playlists=True, limit=1))
|
|
|
|
|
|
|
|
results.extend(self._search(channel_id, query, playlists=False, limit=1))
|
|
|
|
|
|
|
|
except googleapiclient.errors.HttpError as e:
|
|
|
|
|
|
|
|
raise YoutubeError('Failed to query Youtube API: {}'.format(e))
|
|
|
|
|
|
|
|
if not results:
|
|
|
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
tokens = [t for t in query.split('|') if not t.strip().startswith('-')] or ['']
|
|
|
|
|
|
|
|
matches = []
|
|
|
|
|
|
|
|
for token in tokens:
|
|
|
|
|
|
|
|
titles = {i: r['title'] for i, r in enumerate(results)}
|
|
|
|
|
|
|
|
descriptions = {i: r['description'] for i, r in enumerate(results)}
|
|
|
|
|
|
|
|
matches.append(fuzzywuzzy.process.extractOne(token, titles,
|
|
|
|
|
|
|
|
scorer=fuzzywuzzy.fuzz.token_sort_ratio))
|
|
|
|
|
|
|
|
matches.append(fuzzywuzzy.process.extractOne(token, descriptions,
|
|
|
|
|
|
|
|
scorer=fuzzywuzzy.fuzz.token_sort_ratio))
|
|
|
|
|
|
|
|
_, _, i = sorted(matches, key=lambda m: m[1], reverse=True)[0]
|
|
|
|
|
|
|
|
return results[i]
|
|
|
|