6
0

CreateProject.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. from contextlib import closing
  2. from os import mkdir
  3. from os import path
  4. from shutil import copytree
  5. from uuid import uuid1
  6. from flask import make_response, request, abort
  7. from flask.views import View
  8. from pycs.database.Database import Database
  9. from pycs.database.Project import Project
  10. from pycs.frontend.endpoints.projects.ExecuteExternalStorage import ExecuteExternalStorage
  11. from pycs.frontend.endpoints.projects.ExecuteLabelProvider import ExecuteLabelProvider
  12. from pycs.frontend.notifications.NotificationManager import NotificationManager
  13. from pycs.jobs.JobRunner import JobRunner
  14. from pycs.util.PipelineUtil import load_from_root_folder as load_pipeline
  15. class CreateProject(View):
  16. """
  17. create a project, insert data into database and create directories
  18. """
  19. # pylint: disable=arguments-differ
  20. methods = ['POST']
  21. def __init__(self, db: Database, nm: NotificationManager, jobs: JobRunner):
  22. # pylint: disable=invalid-name
  23. self.db = db
  24. self.nm = nm
  25. self.jobs = jobs
  26. def dispatch_request(self):
  27. # extract request data
  28. data = request.get_json(force=True)
  29. if 'name' not in data or 'description' not in data:
  30. return abort(400, "name and description information missing!")
  31. name = data['name']
  32. description = data['description']
  33. # start transaction
  34. with self.db:
  35. # find model
  36. model_id = int(data['model'])
  37. model = self.db.model(model_id)
  38. if model is None:
  39. return abort(404, "Model not found")
  40. # find label provider
  41. if data['label'] is None:
  42. label_provider = None
  43. else:
  44. label_provider_id = int(data['label'])
  45. label_provider = self.db.label_provider(label_provider_id)
  46. if label_provider is None:
  47. return abort(404, "Label provider not found")
  48. # create project folder
  49. project_folder = path.join('projects', str(uuid1()))
  50. mkdir(project_folder)
  51. temp_folder = path.join(project_folder, 'temp')
  52. mkdir(temp_folder)
  53. # check project data directory
  54. if data['external'] is None:
  55. external_data = False
  56. data_folder = path.join(project_folder, 'data')
  57. mkdir(data_folder)
  58. else:
  59. external_data = True
  60. data_folder = data['external']
  61. # check if exists
  62. if not path.exists(data_folder):
  63. return abort(400)
  64. # copy model to project folder
  65. model_folder = path.join(project_folder, 'model')
  66. copytree(model.root_folder, model_folder)
  67. model, _ = model.copy_to(f'{model.name} ({name})', model_folder)
  68. # create entry in database
  69. project = self.db.create_project(name, description, model, label_provider,
  70. project_folder, external_data, data_folder)
  71. # execute label provider and add labels to project
  72. if label_provider is not None:
  73. ExecuteLabelProvider.execute_label_provider(self.db, self.nm, self.jobs, project,
  74. label_provider)
  75. # load model and add collections to the project
  76. def load_model_and_get_collections():
  77. with closing(load_pipeline(model.root_folder)) as pipeline:
  78. return pipeline.collections()
  79. project_id = project.id
  80. def add_collections_to_project(provided_collections):
  81. project = Project.query.get(project_id)
  82. with self.db:
  83. for position, collection in enumerate(provided_collections):
  84. project.create_collection(collection['reference'],
  85. collection['name'],
  86. collection['description'],
  87. position + 1,
  88. collection['autoselect'])
  89. self.jobs.run(project,
  90. 'Media Collections',
  91. f'{project.name}',
  92. f'{project.id}/media-collections',
  93. executable=load_model_and_get_collections,
  94. result=add_collections_to_project)
  95. # find media files
  96. if external_data:
  97. ExecuteExternalStorage.find_media_files(self.db, self.nm, self.jobs, project)
  98. # fire event
  99. self.nm.create_model(model.id)
  100. self.nm.create_project(project.id)
  101. # return success response
  102. return make_response()