ExecuteLabelProvider.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. from contextlib import closing
  2. from flask import abort
  3. from flask import make_response
  4. from flask import request
  5. from flask.views import View
  6. from pycs import app
  7. from pycs import db
  8. from pycs.database.LabelProvider import LabelProvider
  9. from pycs.database.Project import Project
  10. from pycs.database.Label import Label
  11. from pycs.frontend.notifications.NotificationManager import NotificationManager
  12. from pycs.jobs.JobGroupBusyException import JobGroupBusyException
  13. from pycs.jobs.JobRunner import JobRunner
  14. class ExecuteLabelProvider(View):
  15. """
  16. execute the label provider associated with a passed project identifier
  17. """
  18. # pylint: disable=arguments-differ
  19. methods = ['POST']
  20. def dispatch_request(self, identifier):
  21. # extract request data
  22. data = request.get_json(force=True)
  23. if 'execute' not in data or data['execute'] is not True:
  24. return abort(400)
  25. # find project
  26. project = Project.query.get(identifier)
  27. if project is None:
  28. return abort(404)
  29. # get label provider
  30. label_provider = project.label_provider
  31. if label_provider is None:
  32. return abort(400)
  33. # execute label provider and add labels to project
  34. try:
  35. self.execute_label_provider(project, label_provider)
  36. except JobGroupBusyException:
  37. return abort(400)
  38. return make_response()
  39. @staticmethod
  40. def execute_label_provider(project: Project, label_provider: LabelProvider):
  41. """
  42. start a job that loads and executes a label provider and saves its results to the
  43. database afterwards
  44. :param project: project
  45. :param label_provider: label provider
  46. :return:
  47. """
  48. # pylint: disable=invalid-name
  49. # receive loads and executes the given label provider
  50. def receive():
  51. with closing(label_provider.load()) as label_provider_impl:
  52. provided_labels = label_provider_impl.get_labels()
  53. return provided_labels
  54. project_id = project.id
  55. # result adds the received labels to the database and fires events
  56. def result(provided_labels):
  57. project = Project.query.get(project_id)
  58. created = []
  59. app.logger.info(f"Storing {len(provided_labels):,d} labels for project #{project_id}...")
  60. with db.session.begin_nested():
  61. for label in provided_labels:
  62. created_label, is_new = project.create_label(commit=False, **label)
  63. created.append((created_label, is_new))
  64. for label, is_new in created:
  65. notify = NotificationManager.created if is_new else NotificationManager.edited
  66. notify("label", label.id, Label)
  67. # run job with given functions
  68. JobRunner.Run(project,
  69. 'Label Provider',
  70. f'{project.name} ({label_provider.name})',
  71. f'{project.id}/label-provider',
  72. receive,
  73. result=result)