|      1 #!/usr/bin/python |      1 #!/usr/bin/python | 
|      2  |      2  | 
|      3 import os |      3 import os | 
|      4 import sqlite |         | 
|      5 from ogg.vorbis import VorbisFile |         | 
|      6 import ID3 |         | 
|      7 import readline |      4 import readline | 
|      8 import imms |      5 from imms import IMMSCleaner, IMMSDb | 
|      9 from utils import unique, copy_file, set_file_completer |      6 from utils import unique, copy_file, set_file_completer | 
|     10  |      7  | 
|     11  |      8 class CLICleaner(IMMSCleaner): | 
|     12 class CleanupIMMS: |      9     def check_if_uid_exist(self, uid): | 
|     13     def __init__(self, db_file): |     10         other_paths = self.db.get_library_entry(uid = uid) | 
|     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)) |     11         other_paths = unique(map(lambda x: x[0], other_paths)) | 
|     28         for opath in other_paths: |     12         for opath in other_paths: | 
|     29             if os.path.isfile(opath): |     13             if os.path.isfile(opath): | 
|     30                 return None |     14 	        # if one, release it. | 
|     31         other_paths = self.db.get_library_entries(sid = sid) |     15                 return 1 | 
|         |     16         return 0 | 
|         |     17     def check_and_edit_path(self, path, uid, sid): | 
|         |     18         """Must return the new file name, None to remove | 
|         |     19         it.  If the new file name is already in the Db, | 
|         |     20         it will be skip.""" | 
|         |     21         # if path exist, skip it. | 
|         |     22         if os.path.isfile(path): | 
|         |     23             return path | 
|         |     24         # if exist another uid with a valid path, remove it. | 
|         |     25         if self.check_if_uid_exist(uid): | 
|         |     26             return None | 
|         |     27 	# Elsewhere, first build a list of valid candidate from sid... | 
|         |     28         other_paths = self.db.get_library_entry(sid = sid) | 
|     32         other_paths = unique(map(lambda x: x[0], other_paths)) |     29         other_paths = unique(map(lambda x: x[0], other_paths)) | 
|         |     30         return self.edit_filename(path, other_paths) | 
|         |     31     def edit_filename(self, path, other_paths): | 
|         |     32 	# Add them to the history for editing | 
|     33         for opath in other_paths: |     33         for opath in other_paths: | 
|     34             if os.path.isfile(opath): |     34             if os.path.isfile(opath): | 
|     35                 readline.add_history(opath) |     35                 readline.add_history(opath) | 
|         |     36         # And also add the current file as a base for editing. | 
|     36         readline.add_history(path) |     37         readline.add_history(path) | 
|         |     38 	# Sniff!  This doesn't seems to work | 
|     37         readline.insert_text('Edit') |     39         readline.insert_text('Edit') | 
|     38         while 1: |     40         while 1: | 
|     39             cmd = raw_input("I can't find '%s'.\n" |     41             cmd = raw_input("I can't find '%s'.\n" | 
|     40                             "Edit, Skip or Remove? " % path) |     42                             "Edit, Skip or Remove? " % path) | 
|     41             if len(cmd) > 0: |     43             if len(cmd) > 0: | 
|     42                 cmd = cmd.lstrip()[0].lower() |     44                 cmd = cmd.lstrip()[0].lower() | 
|     43                 if cmd == 'e': |     45                 if cmd == 'e': | 
|     44                     newpath = raw_input() |     46                     newpath = raw_input() | 
|         |     47 		    # Already exist, so delete. | 
|     45                     if newpath in other_paths: |     48                     if newpath in other_paths: | 
|     46                         return None |     49                         return None | 
|         |     50 		    # new file so keep it. | 
|     47                     if os.path.isfile(newpath): |     51                     if os.path.isfile(newpath): | 
|     48                         return newpath |     52                         return newpath | 
|         |     53 		    # Elsewhere move it. | 
|     49                     print "Invalid filename!" |     54                     print "Invalid filename!" | 
|     50                 elif cmd == 's': |     55                 elif cmd == 's': | 
|     51                     return path; |     56                     return path; | 
|     52                 elif cmd == 'r': |     57                 elif cmd == 'r': | 
|     53                     return None |     58                     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  |     59  | 
|     96 if __name__ == '__main__': |     60 if __name__ == '__main__': | 
|     97     set_file_completer() |     61     set_file_completer() | 
|     98     readline.parse_and_bind('tab: complete') |     62     readline.parse_and_bind('tab: complete') | 
|     99     db_file = os.environ['HOME'] + '/.imms/imms.db' |     63     db_file = os.environ['HOME'] + '/.imms/imms.db' | 
|    100     db_backup = db_file + '.bak' |     64     db_backup = db_file + '.bak' | 
|    101     copy_file(db_file, db_backup).close() |     65     copy_file(db_file, db_backup).close() | 
|    102     try: |     66     try: | 
|    103         clean_up = CleanupIMMS(db_file) |     67         CLICleaner(IMMSDb(db_file)).clean_all() | 
|    104     except Exception, inst: |     68     except Exception, inst: | 
|    105         print inst |     69         print inst | 
|    106         ans = raw_input('Do you want to get back the backup file? ') |     70         while 1: | 
|    107         if len(ans) > 0: |     71             ans = raw_input('Do you want to get back the backup file? ') | 
|    108             if ans.lstrip()[0].lower() == 'y': |     72             if len(ans) > 0: | 
|    109                 copy_file(db_backup, db_file) |     73                 ans = ans.lstrip()[0].lower() | 
|         |     74                 if ans == 'y': | 
|         |     75                     copy_file(db_backup, db_file) | 
|         |     76                 elif ans == 'n': | 
|         |     77                     break | 
|    110     print "backup file preserved: %s." % db_backup |     78     print "backup file preserved: %s." % db_backup |