def overwrite_existing_file(dbfile, uploaded_file, user): # type: (File, UploadedFile, User) -> File hash = hash_file(dbfile, uploaded_file) latest_file_version = dbfile.versions.filter( number=dbfile.version_number).get() # type: FileVersion if latest_file_version.hash == hash: return dbfile # current file is the same as uploaded one uploaded_file.name = hash new_version_number = latest_file_version.number + 1 new_file_version = FileVersion(upload=uploaded_file, number=new_version_number, hash=hash, file=dbfile, created_by=user, creation_date=timezone.now()) new_file_version.save() dbfile.version_number = new_version_number dbfile.save() log_activity( dbfile.project, user, action_text="created version number {} of".format(new_version_number), file=dbfile) return dbfile
def rename(self, new_name, user): # type: (File, str, User) -> File from apps.files_management.helpers import uploaded_file_object_from_string from apps.projects.helpers import log_activity old_name = self.name if old_name == new_name: return current_version = self.versions.filter( number=self.version_number).get() contents = current_version.get_content() hashed = bytes(new_name, encoding='utf8') + \ bytes(str(self.project_id), encoding='utf8') + \ bytes(str(self.parent_dir_id), encoding='utf8') + \ bytes(contents, encoding='utf-8') hash = hashlib.sha512(hashed).hexdigest() uf = uploaded_file_object_from_string(contents, hash) fv = FileVersion(upload=uf, hash=hash, file=self, number=current_version.number + 1, created_by=user) fv.save() self.version_number += 1 self.name = new_name self.save() log_activity(project=self.project, user=user, file=self, action_text="renamed {} to".format(old_name))
def upload_new_file(uploaded_file, project, parent_dir, user): # type: (UploadedFile, Project, int, User) -> File # I assume that the project exists, bc few level above we checked if user has permissions to write to it. dbfile = File(name=uploaded_file.name, parent_dir_id=parent_dir, project=project, version_number=1) dbfile.save() try: hash = hash_file(dbfile, uploaded_file) uploaded_file.name = hash file_version = FileVersion(upload=uploaded_file, number=1, hash=hash, file=dbfile, created_by=user) file_version.save() except Exception as e: dbfile.delete() raise e else: log_activity(project, user, "created", file=dbfile) return dbfile
def move(request, move_to): # type: (HttpRequest, int) -> HttpResponse data = request.body data = loads(data) move_to_dir = Directory.objects.filter(id=move_to).get() statuses = [] for directory_id in data.get('directories', ()): dir = Directory.objects.filter(id=directory_id).get() try: dir.move_to(move_to) except (ReferenceError, IntegrityError) as e: statuses += [str(e)] else: log_activity(project=dir.project, user=request.user, related_dir=dir, action_text="moved {} to {}".format( dir.name, move_to_dir.name)) statuses += ["OK"] for file_id in data.get('files', ()): file = File.objects.filter(id=file_id).get() file.move_to(move_to) log_activity(project=file.project, user=request.user, file=file, action_text="moved file to {}: ".format(move_to_dir.name)) return JsonResponse(statuses, safe=False)
def create(request): # type: (HttpRequest) -> HttpResponse if request.method == "POST" and request.body: try: data = loads(request.body) except JSONDecodeError: return HttpResponseBadRequest(dumps({"message": "Invalid JSON"})) try: if not data['title']: return HttpResponseBadRequest( dumps({"message": "Title cannot be empty"})) project = Project(title=data['title'], description=data["description"]) project.save() profile = Profile.objects.get(user=request.user) contributor = Contributor(project=project, user=request.user, permissions="AD", profile=profile) contributor.save() base_dir = Directory(name=data['title'], project=project) base_dir.save() log_activity(project, request.user, "created project") return HttpResponse(dumps({"id": project.id})) except (ValidationError, KeyError): return HttpResponseBadRequest(dumps({"message": "Invalid value"})) return HttpResponseBadRequest( dumps({"message": "Invalid request type or empty request"}))
def rename(self, new_name, user): # type: (Directory, str, User) -> Directory from apps.projects.helpers import log_activity old_name = self.name self.name = new_name self.save() log_activity(project=self.project, user=user, related_dir=self, action_text="renamed directory {} to {}".format( old_name, new_name))
def create_subdirectory(self, name, user): # type: (Directory, str, User) -> Directory from apps.projects.helpers import log_activity d = Directory(name=name, project=self.project, parent_dir=self) d.save() log_activity(project=d.project, user=user, related_dir=d, action_text="created directory {} in {}".format( d.name, self.name)) return d
def delete(request, **kwargs): if request.method != 'DELETE': return HttpResponseBadRequest("Only delete method is allowed here") if 'directory_id' in kwargs: dir = Directory.objects.filter(id=kwargs['directory_id']).get() log_activity(project=dir.project, user=request.user, related_dir=dir, action_text="deleted") dir.delete() elif 'file_id' in kwargs: file = File.objects.filter(id=kwargs['file_id']).get() log_activity(project=file.project, user=request.user, file=file, action_text="deleted") file.delete() else: return HttpResponseBadRequest("Invalid arguments") return HttpResponse("OK")
def upload(request, directory_id): # type: (HttpRequest, int) -> HttpResponse if request.method == "POST" and request.FILES: files_list = request.FILES.getlist("file") if not files_list: return HttpResponseBadRequest("File not attached properly") parent_dir = directory_id project = Directory.objects.filter(id=parent_dir).get().project upload_statuses = [] for i, file in enumerate(files_list): file_name = file.name upload_status = { 'file_name': file_name, 'uploaded': False, 'migrated': False, 'message': None } upload_statuses.append(upload_status) try: dbfile = upload_file(file, project, request.user, parent_dir) upload_status = {'uploaded': True} upload_statuses[i].update(upload_status) file_version = FileVersion.objects.get( file_id=dbfile.id, number=dbfile.version_number) path_to_file = file_version.upload.path tei_handler = TeiHandler(path_to_file) migration, is_tei_p5_unprefixed = tei_handler.recognize() if not migration and not is_tei_p5_unprefixed: upload_status = { "message": "Invalid filetype, please provide TEI file or compatible ones.", "uploaded": False } upload_statuses[i].update(upload_status) dbfile.activities.get().delete() dbfile.delete() continue if migration: tei_handler.migrate() try: tei_handler = IDsFiller(tei_handler, file_name) except XMLSyntaxError: is_id_filled = False else: is_id_filled = tei_handler.process() if migration or is_id_filled: migrated_string = tei_handler.text.read() text, entities = extract_text_and_entities( migrated_string, project.id, dbfile.id) uploaded_file = uploaded_file_object_from_string( migrated_string, file_name) dbfile = upload_file(uploaded_file, project, request.user, parent_dir) message = tei_handler.get_message() migration_status = {'migrated': True, 'message': message} upload_statuses[i].update(migration_status) index_entities(entities) index_file(dbfile, text) log_activity(dbfile.project, request.user, "File migrated: {} ".format(message), dbfile) else: file.seek(0) text, entities = extract_text_and_entities( file.read(), project.id, dbfile.id) index_entities(entities) index_file(dbfile, text) except Exception as exception: upload_status = {'message': str(exception)} upload_statuses[i].update(upload_status) response = dumps(upload_statuses) return HttpResponse(response, status=200, content_type='application/json') return HttpResponseBadRequest( "Invalid request method or files not attached")