reprocess.py 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. # GNU MediaGoblin -- federated, autonomous media hosting
  2. # Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS.
  3. #
  4. # This program is free software: you can redistribute it and/or modify
  5. # it under the terms of the GNU Affero General Public License as published by
  6. # the Free Software Foundation, either version 3 of the License, or
  7. # (at your option) any later version.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. # GNU Affero General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU Affero General Public License
  15. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. from __future__ import print_function
  17. import argparse
  18. import os
  19. from mediagoblin import mg_globals
  20. from mediagoblin.db.models import MediaEntry
  21. from mediagoblin.gmg_commands import util as commands_util
  22. from mediagoblin.submit.lib import run_process_media
  23. from mediagoblin.tools.translate import lazy_pass_to_ugettext as _
  24. from mediagoblin.tools.pluginapi import hook_handle
  25. from mediagoblin.processing import (
  26. ProcessorDoesNotExist, ProcessorNotEligible,
  27. get_entry_and_processing_manager, get_processing_manager_for_type,
  28. ProcessingManagerDoesNotExist)
  29. def reprocess_parser_setup(subparser):
  30. subparser.add_argument(
  31. '--celery',
  32. action='store_true',
  33. help="Don't process eagerly, pass off to celery")
  34. subparsers = subparser.add_subparsers(dest="reprocess_subcommand")
  35. ###################
  36. # available command
  37. ###################
  38. available_parser = subparsers.add_parser(
  39. "available",
  40. help="Find out what actions are available for this media")
  41. available_parser.add_argument(
  42. "id_or_type",
  43. help="Media id or media type to check")
  44. available_parser.add_argument(
  45. "--action-help",
  46. action="store_true",
  47. help="List argument help for each action available")
  48. available_parser.add_argument(
  49. "--state",
  50. help="The state of media you would like to reprocess")
  51. #############
  52. # run command
  53. #############
  54. run_parser = subparsers.add_parser(
  55. "run",
  56. help="Run a reprocessing on one or more media")
  57. run_parser.add_argument(
  58. 'media_id',
  59. help="The media_entry id(s) you wish to reprocess.")
  60. run_parser.add_argument(
  61. 'reprocess_command',
  62. help="The reprocess command you intend to run")
  63. run_parser.add_argument(
  64. 'reprocess_args',
  65. nargs=argparse.REMAINDER,
  66. help="rest of arguments to the reprocessing tool")
  67. ################
  68. # thumbs command
  69. ################
  70. thumbs = subparsers.add_parser(
  71. 'thumbs',
  72. help='Regenerate thumbs for all processed media')
  73. thumbs.add_argument(
  74. '--size',
  75. nargs=2,
  76. type=int,
  77. metavar=('max_width', 'max_height'))
  78. #################
  79. # initial command
  80. #################
  81. subparsers.add_parser(
  82. 'initial',
  83. help='Reprocess all failed media')
  84. ##################
  85. # bulk_run command
  86. ##################
  87. bulk_run_parser = subparsers.add_parser(
  88. 'bulk_run',
  89. help='Run reprocessing on a given media type or state')
  90. bulk_run_parser.add_argument(
  91. 'type',
  92. help='The type of media you would like to process')
  93. bulk_run_parser.add_argument(
  94. '--state',
  95. default='processed',
  96. nargs='?',
  97. help='The state of the media you would like to process. Defaults to' \
  98. " 'processed'")
  99. bulk_run_parser.add_argument(
  100. 'reprocess_command',
  101. help='The reprocess command you intend to run')
  102. bulk_run_parser.add_argument(
  103. 'reprocess_args',
  104. nargs=argparse.REMAINDER,
  105. help='The rest of the arguments to the reprocessing tool')
  106. ###############
  107. # help command?
  108. ###############
  109. def available(args):
  110. # Get the media type, either by looking up media id, or by specific type
  111. try:
  112. media_id = int(args.id_or_type)
  113. media_entry, manager = get_entry_and_processing_manager(media_id)
  114. media_type = media_entry.media_type
  115. except ValueError:
  116. media_type = args.id_or_type
  117. media_entry = None
  118. manager = get_processing_manager_for_type(media_type)
  119. except ProcessingManagerDoesNotExist:
  120. entry = MediaEntry.query.filter_by(id=args.id_or_type).first()
  121. print('No such processing manager for {0}'.format(entry.media_type))
  122. if args.state:
  123. processors = manager.list_all_processors_by_state(args.state)
  124. elif media_entry is None:
  125. processors = manager.list_all_processors()
  126. else:
  127. processors = manager.list_eligible_processors(media_entry)
  128. print("Available processors:")
  129. print("=====================")
  130. print("")
  131. if args.action_help:
  132. for processor in processors:
  133. print(processor.name)
  134. print("-" * len(processor.name))
  135. parser = processor.generate_parser()
  136. parser.print_help()
  137. print("")
  138. else:
  139. for processor in processors:
  140. if processor.description:
  141. print(" - %s: %s" % (processor.name, processor.description))
  142. else:
  143. print(" - %s" % processor.name)
  144. def run(args, media_id=None):
  145. if not media_id:
  146. media_id = args.media_id
  147. try:
  148. media_entry, manager = get_entry_and_processing_manager(media_id)
  149. # TODO: (maybe?) This could probably be handled entirely by the
  150. # processor class...
  151. try:
  152. processor_class = manager.get_processor(
  153. args.reprocess_command, media_entry)
  154. except ProcessorDoesNotExist:
  155. print('No such processor "%s" for media with id "%s"' % (
  156. args.reprocess_command, media_entry.id))
  157. return
  158. except ProcessorNotEligible:
  159. print('Processor "%s" exists but media "%s" is not eligible' % (
  160. args.reprocess_command, media_entry.id))
  161. return
  162. reprocess_parser = processor_class.generate_parser()
  163. reprocess_args = reprocess_parser.parse_args(args.reprocess_args)
  164. reprocess_request = processor_class.args_to_request(reprocess_args)
  165. run_process_media(
  166. media_entry,
  167. reprocess_action=args.reprocess_command,
  168. reprocess_info=reprocess_request)
  169. except ProcessingManagerDoesNotExist:
  170. entry = MediaEntry.query.filter_by(id=media_id).first()
  171. print('No such processing manager for {0}'.format(entry.media_type))
  172. def bulk_run(args):
  173. """
  174. Bulk reprocessing of a given media_type
  175. """
  176. query = MediaEntry.query.filter_by(media_type=args.type,
  177. state=args.state)
  178. for entry in query:
  179. run(args, entry.id)
  180. def thumbs(args):
  181. """
  182. Regenerate thumbs for all processed media
  183. """
  184. query = MediaEntry.query.filter_by(state='processed')
  185. for entry in query:
  186. try:
  187. media_entry, manager = get_entry_and_processing_manager(entry.id)
  188. # TODO: (maybe?) This could probably be handled entirely by the
  189. # processor class...
  190. try:
  191. processor_class = manager.get_processor(
  192. 'resize', media_entry)
  193. except ProcessorDoesNotExist:
  194. print('No such processor "%s" for media with id "%s"' % (
  195. 'resize', media_entry.id))
  196. return
  197. except ProcessorNotEligible:
  198. print('Processor "%s" exists but media "%s" is not eligible' % (
  199. 'resize', media_entry.id))
  200. return
  201. reprocess_parser = processor_class.generate_parser()
  202. # prepare filetype and size to be passed into reprocess_parser
  203. if args.size:
  204. extra_args = 'thumb --{0} {1} {2}'.format(
  205. processor_class.thumb_size,
  206. args.size[0],
  207. args.size[1])
  208. else:
  209. extra_args = 'thumb'
  210. reprocess_args = reprocess_parser.parse_args(extra_args.split())
  211. reprocess_request = processor_class.args_to_request(reprocess_args)
  212. run_process_media(
  213. media_entry,
  214. reprocess_action='resize',
  215. reprocess_info=reprocess_request)
  216. except ProcessingManagerDoesNotExist:
  217. print('No such processing manager for {0}'.format(entry.media_type))
  218. def initial(args):
  219. """
  220. Reprocess all failed media
  221. """
  222. query = MediaEntry.query.filter_by(state='failed')
  223. for entry in query:
  224. try:
  225. media_entry, manager = get_entry_and_processing_manager(entry.id)
  226. run_process_media(
  227. media_entry,
  228. reprocess_action='initial')
  229. except ProcessingManagerDoesNotExist:
  230. print('No such processing manager for {0}'.format(entry.media_type))
  231. def reprocess(args):
  232. # Run eagerly unless explicetly set not to
  233. if not args.celery:
  234. os.environ['CELERY_ALWAYS_EAGER'] = 'true'
  235. commands_util.setup_app(args)
  236. if args.reprocess_subcommand == "run":
  237. run(args)
  238. elif args.reprocess_subcommand == "available":
  239. available(args)
  240. elif args.reprocess_subcommand == "bulk_run":
  241. bulk_run(args)
  242. elif args.reprocess_subcommand == "thumbs":
  243. thumbs(args)
  244. elif args.reprocess_subcommand == "initial":
  245. initial(args)