You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

kiara 7.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. #!/bin/python
  2. import argparse
  3. import os, os.path
  4. import sys
  5. import libkiara
  6. parser = argparse.ArgumentParser(
  7. description='Do stuff with anime files and anidb.')
  8. parser.add_argument('-w', '--watch',
  9. action='store_true', dest='watch',
  10. help='Mark all the files watched.')
  11. parser.add_argument('-o', '--organize',
  12. action='store_true', dest='organize',
  13. help='Organize ALL THE FILES _o/')
  14. parser.add_argument('--copy',
  15. action='store_true', dest='organize_copy',
  16. help='When organizing files, copy them instead of moving them.')
  17. parser.add_argument('--overwrite',
  18. action='store_true', dest='organize_overwrite',
  19. help='When organizing files, always overwrite any existing files.')
  20. parser.add_argument('--skip-update',
  21. action='store_false', dest='update_info', default=True,
  22. help='Skip updating file info from anidb, when the cached info is old. '
  23. '(missing info will still be fetched)')
  24. parser.add_argument('-c', '--config',
  25. action='store', dest='config', type=argparse.FileType('r'),
  26. help='Alternative config file to use.')
  27. parser.add_argument('--find-duplicates',
  28. action='store_true', dest='find_duplicates',
  29. help='Lists all episode for which you have more than one file')
  30. parser.add_argument('--forget',
  31. type=int, metavar='FID', nargs='*', dest='forget_fid',
  32. help='Delete all info from the database (but not the file itself) about '
  33. 'the files with the giver anidb file-id. (These are the numbers output '
  34. 'by --find-duplicates')
  35. parser.add_argument('--brief',
  36. action='store_true', dest='brief',
  37. help='If nothing goes wrong, print only a single line for each file')
  38. parser.add_argument('--kill',
  39. action='store_true', dest='kill',
  40. help='Shut down the backend')
  41. parser.add_argument('file',
  42. metavar='FILE', type=str, nargs='*',
  43. help='A file to do something with')
  44. args = parser.parse_args()
  45. # Status printing.
  46. LINES = 80
  47. try:
  48. _, LINES = map(int, os.popen('stty size', 'r').read().split())
  49. except:
  50. pass
  51. def pp(head):
  52. def inner(s):
  53. res = ''
  54. tag = head
  55. line = ''
  56. parts = str(s).split(' ')
  57. while parts:
  58. if line:
  59. line += ' '
  60. line += parts.pop(0)
  61. if parts and len(line) + len(parts[0]) > LINES-10:
  62. res += tag + line + '\n'
  63. line = ''
  64. tag = ' ' * len(tag)
  65. return res + tag + line
  66. return inner
  67. legacy = pp('ERROR ')
  68. status = pp(' ')
  69. success = pp('OK ')
  70. error = pp('ERROR ')
  71. debug = pp('debug ')
  72. try:
  73. import colorama
  74. colorama.init()
  75. prnt = {
  76. 'legacy': lambda s:
  77. (colorama.Fore.YELLOW + legacy(s) + colorama.Fore.RESET),
  78. 'status': status,
  79. 'success': lambda s:
  80. (colorama.Fore.GREEN + success(s) + colorama.Fore.RESET),
  81. 'error': lambda s:
  82. (colorama.Fore.RED + error(s) + colorama.Fore.RESET),
  83. 'debug': lambda s:
  84. (colorama.Fore.CYAN + debug(s) + colorama.Fore.RESET),
  85. }
  86. except ImportError:
  87. prnt = {
  88. 'legacy': legacy,
  89. 'status': status,
  90. 'success': success,
  91. 'error': error,
  92. 'debug': debug,
  93. }
  94. trans = {
  95. '_': '{0}',
  96. 'abandon_ship': 'Well... something went wrong',
  97. 'anidb_adding_file': 'Adding {0} {1} to your mylist...',
  98. 'anidb_busy': 'AniDB is busy, please try again later.',
  99. 'anidb_file_unknown': 'File is unknown to anidb. Will not process further.',
  100. 'anidb_marking_watched': 'Marking {0} {1} watched...',
  101. 'anidb_ping_error': 'No answer from anidb :(',
  102. 'anidb_ping_ok': 'Pinged anidb.',
  103. 'backend_shutting_down': 'Backend shutting down...',
  104. 'backend_start': 'Unable to contact the backend. Will try to start one...',
  105. 'backend_start_failed': 'Unable to start a new backend, sorry :(',
  106. 'backend_killed': 'Backend shut down',
  107. 'banned': 'We got banned :(\n{0}\nTry again in 30 minutes',
  108. 'dup': '- {0} {1} [{2}]',
  109. 'dup_no_type': '- {0} {1} [unknown - '
  110. 'please try re-kiara\'ing this file]',
  111. 'dups_for': 'Duplicate files for {0} - {1}:',
  112. 'dups_forget_others': 'Other users are using that file, I won\'t forget '
  113. 'about that',
  114. 'dups_forgot': 'Forgot about {0}',
  115. 'dups_none': 'No duplicate files :)',
  116. 'file_added': 'File added.',
  117. 'file_already_organized': '{0} is already organized.',
  118. 'file_copied': 'Copied {0} to {1}',
  119. 'file_exists': '{0} already exists, not overwriting without --overwrite',
  120. 'file_marked_watched': 'File marked watched',
  121. 'file_moved': 'Moved {0} to {1}',
  122. 'file_type': 'File type is {0}',
  123. 'file_type_location': 'Type is {0}, so I\'ll put this in {1}',
  124. 'hashing_file': 'Hashing {0}...',
  125. 'kiara_banned': 'kiara is banned from AniDB.\nYour AniDB user should be ok',
  126. 'kiara_outdated': 'kiara have become outdated :(\nCheck the interwebs for '
  127. 'an updated version',
  128. 'killing_backend': 'Killing backend...',
  129. 'logging_in': 'Logging in...',
  130. 'login_accepted_outdated_client': 'Login accepted, but your copy of kiara '
  131. 'is outdated.\nPlease consider updating it.',
  132. 'login_again': 'We need to log in again ({0} {1})',
  133. 'login_successful': 'Login successful.',
  134. 'login_session_key': 'We got session key {0}',
  135. 'login_unexpected_return': 'Unexpected return code to AUTH command. Please '
  136. 'show this to the delevopers of kiara: {0} {1}',
  137. 'no_backend_running': 'No backend running',
  138. 'oh_no': 'OH NOES: {0} {1}',
  139. 'removing_empty_dir': 'The dir {0} is now empty, will remove it.',
  140. 'socket_timeout': 'We got a socket timeout... hang on',
  141. 'socket_timeout_again': 'Another timeout... bailing out',
  142. 'unexpected_reply': 'Unexpected reply: {0} {1}',
  143. 'unknown_file_extension': 'Unknown file extension: {0}',
  144. 'wrong_tag': 'We got a message with the wrong tag... we have probably '
  145. 'missed the previous message. I\'ll try again.',
  146. }
  147. def format_status(status):
  148. try:
  149. if type(status) == list and len(status) >= 2:
  150. tag, msg, data = status[0], status[1], status[2:]
  151. if tag != 'debug' or 'debug' in libkiara._config:
  152. return prnt[tag](trans[msg].format(*data))
  153. else:
  154. return None
  155. except Exception as e:
  156. if 'colorama' in globals():
  157. print(colorama.Fore.WHITE + colorama.Back.RED)
  158. print(e)
  159. print(colorama.Fore.RESET + colorama.Back.RESET)
  160. else:
  161. print(e)
  162. # Legacy status.
  163. return prnt['legacy'](status)
  164. # Should we kill the backend?
  165. if args.kill:
  166. print(format_status(['status', 'killing_backend', []]))
  167. for line in libkiara.kill():
  168. print(format_status(line))
  169. print(format_status(['success', 'backend_killed', []]))
  170. sys.exit()
  171. # Make sure that all the files are actually files.
  172. for file in args.file:
  173. if not os.path.isfile(os.path.abspath(file)):
  174. print('!!! %s is not a file' % file)
  175. sys.exit()
  176. # Load configuration
  177. if args.config:
  178. libkiara.load_config_file(args.config.name)
  179. if not libkiara.check_config():
  180. sys.exit(-1)
  181. # OK, run over the files.
  182. for file in args.file:
  183. printed = False
  184. msgs = list()
  185. for line in libkiara.process(os.path.abspath(file),
  186. update_info=args.update_info,
  187. watch=args.watch,
  188. organize=args.organize,
  189. organize_copy=args.organize_copy,
  190. organize_overwrite=args.organize_overwrite):
  191. f = format_status(line)
  192. if f:
  193. if args.brief:
  194. if printed:
  195. print(f)
  196. else:
  197. if line[0] == 'error':
  198. while msgs:
  199. print(msgs.pop(0))
  200. print(f)
  201. printed = True
  202. else:
  203. msgs.append(f)
  204. else:
  205. printed = True
  206. print(f)
  207. if args.brief and not printed:
  208. print(format_status(['success', '_', file]))
  209. elif printed:
  210. print() # Blank line
  211. if args.find_duplicates:
  212. print('Locating duplicate files...')
  213. for line in libkiara.find_duplicates():
  214. f = format_status(line)
  215. if f:
  216. print(f)
  217. if args.forget_fid:
  218. for line in libkiara.forget(*args.forget_fid):
  219. f = format_status(line)
  220. if f:
  221. print(f)