Sfoglia il codice sorgente

Start using search result scores

debenoldert 5 anni fa
parent
commit
1b30b3b6be
10 ha cambiato i file con 204 aggiunte e 116 eliminazioni
  1. 16 0
      command/__init__.py
  2. 10 0
      command/directory.py
  3. 8 0
      command/help.py
  4. 13 0
      command/last.py
  5. 9 0
      command/quality.py
  6. 64 0
      command/search.py
  7. 12 0
      command/site.py
  8. 7 0
      helper/sites/item.py
  9. 61 0
      helper/sites/itemsort.py
  10. 4 116
      main.py

+ 16 - 0
command/__init__.py

@@ -0,0 +1,16 @@
+from .search import search
+from .site import choose_site
+from .directory import directory
+from .help import help
+from .last import last
+from .quality import quality
+
+commands = [
+    ('help', help, 'Display this list'),
+    ('last', last, 'See the last search'),
+    ('save', directory, 'Change the download directory'),
+    ('search', search, 'Search the selected site'),
+    ('sites', choose_site, 'Pick the site to search'),
+    ('quality', quality, 'Set the minimal quality to download without confirmation'),
+    #('quit', quit, 'Quit the program')
+]

+ 10 - 0
command/directory.py

@@ -0,0 +1,10 @@
+from helper import console
+
+
+def directory(dir=None):
+    if dir is None:
+        dir = console.ask_input('Enter new save directory')
+    Settings.SaveDir.set(dir)
+    os.makedirs(Settings.SaveDir.get(), exist_ok=True)
+    console.output('New save directory: {0}'.format(Settings.SaveDir.get()), level=console.DBG_INFO)
+    return True

+ 8 - 0
command/help.py

@@ -0,0 +1,8 @@
+from helper import console
+
+
+def help():
+    console.output('Possible commands are:')
+    for comm in commands:
+        console.output('{0}\t{1}'.format(comm[0], comm[2]))
+    return True

+ 13 - 0
command/last.py

@@ -0,0 +1,13 @@
+from helper import console
+
+
+def last(items=None):
+    global search_cache
+    if items is not None:
+        search_cache = items
+    else:
+        if search_cache is None:
+            console.output('First search has yet te be made', console.DBG_ERROR)
+        else:
+            search(search_cache)
+    return True

+ 9 - 0
command/quality.py

@@ -0,0 +1,9 @@
+from helper import console
+
+
+def quality(quality=None):
+    if quality is None:
+        quality = console.ask_input('Enter minimal quality for auto download')
+    Settings.MinQuality.set(quality)
+    console.output('Minimal quality for auto downloading is set to {0}'.format(Settings.MinQuality.get()), level=console.DBG_INFO)
+    return True

+ 64 - 0
command/search.py

@@ -0,0 +1,64 @@
+import sites
+from command import last
+from helper import console
+from main import selected_site
+from helper.sites import itemsort
+from .last import last
+
+def search(cache=None):
+    if cache is None:
+        keywords = console.ask_input('Search for')
+        _sites = []
+        if isinstance(sites.available[selected_site], sites.DefaultSite):
+            _sites = sites.available[1:]
+        else:
+            _sites = [sites.available[selected_site]]
+
+        items = []
+        for site in _sites:
+            console.output('Searching: {0}'.format(site.url))
+            _items = site.perform_search(keywords)
+            console.output('\tFound {0} results'.format(len(_items)))
+            items.extend(_items)
+
+        if len(items) == 0:
+            console.output('No results found')
+            return True
+
+        items = itemsort.smart(items, keywords)
+
+        last(items)
+    else:
+        items = cache
+
+    while True:
+        picked_item = console.option_picker('Pick a song to download',
+                                            items,
+                                            quit=True,
+                                            objects=[
+                                                '__id__',
+                                                'x.score',
+                                                'x.duration',
+                                                'x.size',
+                                                'x.artist',
+                                                'x.title'
+                                            ],
+                                            table=[
+                                                ('ID', 2),
+                                                ('Score', 5),
+                                                ('Time', 5),
+                                                ('Size', 4),
+                                                ('Artist', 50),
+                                                ('Title', 100)
+                                            ])
+        if picked_item is None:
+            break
+        else:
+            item = items[picked_item]
+            console.output('Downloading {0}'.format(item.title))
+
+            item.site.download(item)
+
+            break
+
+    return True

+ 12 - 0
command/site.py

@@ -0,0 +1,12 @@
+from helper import console
+
+
+def choose_site():
+    global selected_site
+    _index = console.option_picker('Available sites',
+                                   list(map(lambda x: x.url, sites.available)),
+                                   selected_site,
+                                   True)
+    if _index is not None:
+        selected_site = _index
+    return True

+ 7 - 0
helper/sites/item.py

@@ -44,6 +44,8 @@ class Item:
         self.bytes = None
         self.duration_seconds = None
 
+        self.score = 0.0
+
         # self.calculate_duration_seconds()
         # self.calculate_bytes()
         # self.calculate_bitrate()
@@ -104,3 +106,8 @@ class Item:
         if self.duration_seconds is not None and self.bytes is not None:
             self.bitrate = self.bytes / self.duration_seconds / 1024 * 8  # bytes / seconds / 1024 * 8
 
+    def increment_score(self, by=1):
+        self.score += by
+
+    def decrement_score(self, by=1):
+        self.score -= by

+ 61 - 0
helper/sites/itemsort.py

@@ -0,0 +1,61 @@
+from helper import console
+
+
+def smart(items, criteria):
+
+    if '-' in criteria:
+        _criteria = criteria.split('-')
+        artist = _criteria[0].split(' ')
+        title = _criteria[1].split(' ')
+    else:
+        artist = title = criteria.split(' ')
+
+    for item in items:
+
+        # First do negative stuff, bad news comes always first
+
+        if item.duration_seconds is not None and item.duration_seconds < 150:
+            item.decrement_score(0.5)
+
+        if item.duration_seconds is not None and item.duration_seconds > 600:
+            item.decrement_score(1)
+
+        if 'radio' in item.title.lower():
+            item.decrement_score(1)
+
+        if len(set(item.artist.lower().split(' ')).intersection(artist)) == 0:
+            item.decrement_score(2)
+
+        if len(set(item.title.lower().split(' ')).intersection(title)) == 0:
+            item.decrement_score(2)
+
+        # Now do the positive stuff
+
+        # The following 2 rules are not always correct. Need more testing to evaluate
+
+        # if 'original' in item.title.lower():
+        #     item.increment_score(0.5)
+        # if 'extended' in item.title.lower():
+        #     item.increment_score(1)
+
+        if ' '.join(title).strip().lower() == item.title.strip().lower():
+            item.increment_score(1)
+
+        if item.duration_seconds is not None:
+            item.increment_score(0.1)
+
+        if item.size is not None:
+            item.increment_score(0.1)
+
+    sortedlist = []
+
+    for item in items:
+        # We don't show negative scores
+        if item.score > 0:
+            sortedlist.append(item)
+        else:
+            console.output('Removing {x.artist} - {x.title} from list: Score to low'.format(x=item), console.DBG_INFO)
+
+    sortedlist.sort(reverse=True, key=lambda x: (x.score, x.duration_seconds))
+
+    return sortedlist

+ 4 - 116
main.py

@@ -2,6 +2,7 @@ import sites as sites
 from helper.settings import Settings
 from helper import console as console
 import os.path
+import command
 
 
 def main():
@@ -28,136 +29,23 @@ def main():
     exit(0)
 
 
-def choose_site():
-    global selected_site
-    _index = console.option_picker('Available sites',
-                                   list(map(lambda x: x.url, sites.available)),
-                                   selected_site,
-                                   True)
-    if _index is not None:
-        selected_site = _index
-    return True
-
-
 def idle():
     _command = console.ask_input('Type command')
 
-    for command in commands:
-        if command[0] == _command.lower():
-            return command[1]()
+    for comm in command.commands:
+        if comm[0] == _command.lower():
+            return comm[1]()
 
     console.output('Command \'{0}\' not found. Type help to see a list of possible commands'.format(_command))
     return True
 
 
-def help():
-    console.output('Possible commands are:')
-    for command in commands:
-        console.output('{0}\t{1}'.format(command[0], command[2]))
-    return True
-
-
-def search(cache=None):
-    if cache is None:
-        keywords = console.ask_input('Search for')
-        _sites = []
-        if isinstance(sites.available[selected_site], sites.DefaultSite):
-            _sites = sites.available[1:]
-        else:
-            _sites = [sites.available[selected_site]]
-
-        items = []
-        for site in _sites:
-            console.output('Searching: {0}'.format(site.url))
-            _items = site.perform_search(keywords)
-            console.output('\tFound {0} results'.format(len(_items)))
-            items.extend(_items)
-
-        if len(items) == 0:
-            console.output('No results found')
-            return True
-
-        last(items)
-    else:
-        items = cache
-
-    while True:
-        picked_item = console.option_picker('Pick a song to download',
-                                            items,
-                                            # list(map(lambda x: '[{0:5}] [{1:4}] {2}'.format(x.duration, x.size, x.title), items)),
-                                            quit=True,
-                                            objects=[
-                                                '__id__',
-                                                'x.duration',
-                                                'x.size',
-                                                'x.artist',
-                                                'x.title'
-                                            ],
-                                            table=[
-                                                ('ID', 2),
-                                                ('Time', 5),
-                                                ('Size', 4),
-                                                ('Artist', 50),
-                                                ('Title', 100)
-                                            ])
-        if picked_item is None:
-            break
-        else:
-            item = items[picked_item]
-            console.output('Downloading {0}'.format(item.title))
-
-            item.site.download(item)
-
-            break
-
-    return True
-
-
-def directory(dir=None):
-    if dir is None:
-        dir = console.ask_input('Enter new save directory')
-    Settings.SaveDir.set(dir)
-    os.makedirs(Settings.SaveDir.get(), exist_ok=True)
-    console.output('New save directory: {0}'.format(Settings.SaveDir.get()), level=console.DBG_INFO)
-    return True
-
-
-def quality(quality=None):
-    if quality is None:
-        quality = console.ask_input('Enter minimal quality for auto download')
-    Settings.MinQuality.set(quality)
-    console.output('Minimal quality for auto downloading is set to {0}'.format(Settings.MinQuality.get()), level=console.DBG_INFO)
-    return True
-
-
-def last(items=None):
-    global search_cache
-    if items is not None:
-        search_cache = items
-    else:
-        if search_cache is None:
-            console.output('First search has yet te be made', console.DBG_ERROR)
-        else:
-            search(search_cache)
-    return True
-
-
 def quit():
     return False
 
 
 selected_site = 0
 search_cache = None
-commands = [
-    ('help', help, 'Display this list'),
-    ('last', last, 'See the last search'),
-    ('save', directory, 'Change the download directory'),
-    ('search', search, 'Search the selected site'),
-    ('sites', choose_site, 'Pick the site to search'),
-    ('quality', quality, 'Set the minimal quality to download without confirmation'),
-    ('quit', quit, 'Quit the program')
-]
-
 
 if __name__ == '__main__':
     main()