ExecuteLabelProvider.py 3.2 KB

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