|         |      1 #!/usr/bin/python | 
|         |      2  | 
|         |      3 import os | 
|         |      4 import sqlite | 
|         |      5 from ogg.vorbis import VorbisFile | 
|         |      6 import ID3 | 
|         |      7 import readline | 
|         |      8 import imms | 
|         |      9 from utils import unique, copy_file, set_file_completer | 
|         |     10  | 
|         |     11  | 
|         |     12 class CleanupIMMS: | 
|         |     13     def __init__(self, db_file): | 
|         |     14         self.db = imms.IMMSDb(db_file) | 
|         |     15     def check_uid(self, uid): | 
|         |     16         lib = self.db.get_library_entries(uid = uid) | 
|         |     17         if len(lib) == 0: | 
|         |     18             print "Erased uid = ", uid | 
|         |     19             self.db.erase_uid(uid) | 
|         |     20     def check_sid(self, sid): | 
|         |     21         lib = self.db.get_library_entries(sid = sid) | 
|         |     22         if len(lib) == 0: | 
|         |     23             print "Erased sid = ", uid | 
|         |     24             self.db.erase_sid(sid) | 
|         |     25     def handle_no_file(self, path, uid, sid): | 
|         |     26         other_paths = self.db.get_library_entries(uid = uid) | 
|         |     27         other_paths = unique(map(lambda x: x[0], other_paths)) | 
|         |     28         for opath in other_paths: | 
|         |     29             if os.path.isfile(opath): | 
|         |     30                 return None | 
|         |     31         other_paths = self.db.get_library_entries(sid = sid) | 
|         |     32         other_paths = unique(map(lambda x: x[0], other_paths)) | 
|         |     33         for opath in other_paths: | 
|         |     34             if os.path.isfile(opath): | 
|         |     35                 readline.add_history(opath) | 
|         |     36         readline.add_history(path) | 
|         |     37         readline.insert_text('Edit') | 
|         |     38         while 1: | 
|         |     39             cmd = raw_input("I can't find '%s'.\n" | 
|         |     40                             "Edit, Skip or Remove? " % path) | 
|         |     41             if len(cmd) > 0: | 
|         |     42                 cmd = cmd.lstrip()[0].lower() | 
|         |     43                 if cmd == 'e': | 
|         |     44                     newpath = raw_input() | 
|         |     45                     if newpath in other_paths: | 
|         |     46                         return None | 
|         |     47                     if os.path.isfile(newpath): | 
|         |     48                         return newpath | 
|         |     49                     print "Invalid filename!" | 
|         |     50                 elif cmd == 's': | 
|         |     51                     return path; | 
|         |     52                 elif cmd == 'r': | 
|         |     53                     return None | 
|         |     54     def clean_library(self): | 
|         |     55         lib = self.db.get_library_entries() | 
|         |     56         deleted_uids = [] | 
|         |     57         deleted_sids = [] | 
|         |     58         for entry in lib: | 
|         |     59             path, uid, sid = entry | 
|         |     60             if not os.path.isfile(path): | 
|         |     61                 uid = int(uid) | 
|         |     62                 sid = int(sid) | 
|         |     63                 newfile = self.handle_no_file(path, uid, sid) | 
|         |     64                 if not newfile: | 
|         |     65                     print "Erasing ", path | 
|         |     66                     self.db.erase_filename(path) | 
|         |     67                     deleted_uids.append(uid) | 
|         |     68                     deleted_sids.append(sid) | 
|         |     69                 elif newfile != path: | 
|         |     70                     print "Renaming ", path, " into ", newfile | 
|         |     71                     self.db.update_filename(path, newfile) | 
|         |     72                 else: | 
|         |     73                     print "Skipping ", path | 
|         |     74         map(self.check_uid, unique(deleted_uids)) | 
|         |     75         map(self.check_sid, unique(deleted_sids)) | 
|         |     76     def clean_rating(self): | 
|         |     77         rates = self.db.get_ratings() | 
|         |     78         rates = unique(map(lambda x: x[0], rates)) | 
|         |     79         map(self.check_uid, rates) | 
|         |     80     def clean_acoustic(self): | 
|         |     81         uids = map(lambda x: x[0], self.db.get_acoustics()) | 
|         |     82         map(self.check_uid, uids) | 
|         |     83     def clean_info(self): | 
|         |     84         sids = map(lambda x: x[0], self.db.get_infos()) | 
|         |     85         map(self.check_sid, sids) | 
|         |     86     def clean_last(self): | 
|         |     87         sids = map(lambda x: x[0], self.db.get_last()) | 
|         |     88         map(self.check_sid, sids) | 
|         |     89     def clean_all(self): | 
|         |     90         self.clean_library() | 
|         |     91         self.clean_rating() | 
|         |     92         self.clean_acoustic() | 
|         |     93         self.clean_info() | 
|         |     94         self.clean_last() | 
|         |     95  | 
|         |     96 if __name__ == '__main__': | 
|         |     97     set_file_completer() | 
|         |     98     readline.parse_and_bind('tab: complete') | 
|         |     99     db_file = os.environ['HOME'] + '/.imms/imms.db' | 
|         |    100     db_backup = db_file + '.bak' | 
|         |    101     copy_file(db_file, db_backup).close() | 
|         |    102     try: | 
|         |    103         clean_up = CleanupIMMS(db_file) | 
|         |    104     except Exception, inst: | 
|         |    105         print inst | 
|         |    106         ans = raw_input('Do you want to get back the backup file? ') | 
|         |    107         if len(ans) > 0: | 
|         |    108             if ans.lstrip()[0].lower() == 'y': | 
|         |    109                 copy_file(db_backup, db_file) | 
|         |    110     print "backup file preserved: %s." % db_backup |