1
1

CreateProject.py 4.5 KB

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