def inviteUser(request, user, projectid, inviteusermail): """Lädt einen anderen Benutzer zur Kollaboration an einem Projekt ein. :param request: Anfrage des Clients, wird unverändert zurückgesendet :param user: User Objekt (eingeloggter Benutzer) :param projectid: ID des Projektes, zu dessen Zusammenarbeit eingeladen werden soll :param inviteusermail: E-Mail-Adresse des Benutzers, welcher eingeladen werden soll :return: HttpResponse (JSON) """ inviteusermail_lower = inviteusermail.lower() # wenn sich die übergebene E-Mail-Adresse des einzuladenen Nutzers von der des aufrufenden Nutzers unterscheidet if user.username.lower()!=inviteusermail_lower : # wenn die übergebene E-Mail-Adresse registriert ist if User.objects.filter(username__iexact=inviteusermail_lower).exists() : # einzuladener Nutzer inviteuser = User.objects.get(username__iexact=inviteusermail_lower) # wenn noch keine entsprechende Kollaboration vorliegt if not Collaboration.objects.filter(user=inviteuser.id,project=projectid).exists() : # versucht eine entsprechende Kollaboration anzulegen try: Collaboration.objects.create(user=inviteuser, project=Project.objects.get(id=projectid)) return util.jsonResponse({}, True, request) except: return util.jsonErrorResponse(ERROR_MESSAGES['DATABASEERROR'], request) # wenn eine entsprechende Kollaboration bereits vorliegt else : return util.jsonErrorResponse(ERROR_MESSAGES['USERALREADYINVITED'] % inviteuser.username, request) else : return util.jsonErrorResponse(ERROR_MESSAGES['USERNOTFOUND'] % inviteusermail, request) # wenn es sich bei der übergebenen E-Mail-Adresse des einzuladenen Nutzers um die des aufrufenden Nutzers handelt else : return util.jsonErrorResponse(ERROR_MESSAGES['USERALREADYINVITED'] % user.username, request)
def renameDir(request, user, folderid, newdirectoryname): """Benennt den Ordner mit der angegebenen Id um. :param request: Anfrage des Clients, wird unverändert zurückgesendet :param user: User Objekt (eingeloggter Benutzer) :param folderid: Id des Ordners, welcher umbenannt werden soll :param newdirectoryname: neuer Name des Ordners :return: HttpResponse (JSON) """ # hole das Ordner Objekt folder = Folder.objects.get(id=folderid) # Teste ob Ordnername in diesem Verzeichnis bereits existiert unique, failurereturn = util.checkIfFileOrFolderIsUnique(newdirectoryname, Folder, folder.parent, request) if not unique: return failurereturn # Versuche die Änderung in die Datenbank zu übernehmen try: folder.name = newdirectoryname folder.save() return util.jsonResponse({'id': folder.id, 'name': folder.name}, True, request) except: return util.jsonErrorResponse(ERROR_MESSAGES['DATABASEERROR'], request)
def createDir(request, user, parentdirid=0, directoryname=""): """Erstellt einen neuen Ordner im angegebenen Verzeichnis. :param request: Anfrage des Clients, wird unverändert zurückgesendet :param user: User Objekt (eingeloggter Benutzer) :param parentdirid: Id des übergeordneten Ordners :param directoryname: Name des zu erstellenden Ordners :return: HttpResponse (JSON) """ # hole das übergeordnete Ordner Objekt parentdirobj = Folder.objects.get(id=parentdirid) # Teste ob Ordnername in diesem Verzeichnis bereits existiert unique, failurereturn = util.checkIfFileOrFolderIsUnique(directoryname, Folder, parentdirobj, request) if not unique: return failurereturn # Versuche den Ordner in der Datenbank zu speichern try: newfolder = Folder(name=directoryname, parent=parentdirobj, root=parentdirobj.getRoot()) newfolder.save() return util.jsonResponse({'id': newfolder.id, 'name': newfolder.name, 'parentid': parentdirobj.id, 'parentname': parentdirobj.name}, True, request) except: return util.jsonErrorResponse(ERROR_MESSAGES['DATABASEERROR'], request)
def renameFile(request, user, fileid, newfilename): """Benennt eine vom Client angegebene Datei um. :param request: Anfrage des Clients, wird unverändert zurückgesendet :param user: User Objekt (eingeloggter Benutzer) :param fileid: Id der Datei welche umbenannt werden soll :param newfilename: neuer Dateiname :return: HttpResponse (JSON) """ # hole das file object fileobj = File.objects.get(id=fileid) # Teste ob eine Datei mit dem selben Namen schon existiert unique, failurereturn = util.checkIfFileOrFolderIsUnique(newfilename, File, fileobj.folder, request) if not unique: return failurereturn # versuche den neuen Dateinamen zu setzen try: fileobj.name = newfilename fileobj.save() return util.jsonResponse({'id': fileobj.id, 'name': fileobj.name}, True, request) except: return util.jsonErrorResponse(ERROR_MESSAGES['DATABASEERROR'], request)
def createDir(request, user, parentdirid=0, directoryname=""): """Erstellt einen neuen Ordner im angegebenen Verzeichnis. :param request: Anfrage des Clients, wird unverändert zurückgesendet :param user: User Objekt (eingeloggter Benutzer) :param parentdirid: Id des übergeordneten Ordners :param directoryname: Name des zu erstellenden Ordners :return: HttpResponse (JSON) """ # hole das übergeordnete Ordner Objekt parentdirobj = Folder.objects.get(id=parentdirid) # Teste ob Ordnername in diesem Verzeichnis bereits existiert unique, failurereturn = util.checkIfFileOrFolderIsUnique( directoryname, Folder, parentdirobj, request) if not unique: return failurereturn # Versuche den Ordner in der Datenbank zu speichern try: newfolder = Folder(name=directoryname, parent=parentdirobj, root=parentdirobj.getRoot()) newfolder.save() return util.jsonResponse( { 'id': newfolder.id, 'name': newfolder.name, 'parentid': parentdirobj.id, 'parentname': parentdirobj.name }, True, request) except: return util.jsonErrorResponse(ERROR_MESSAGES['DATABASEERROR'], request)
def moveFile(request, user, fileid, newfolderid): """Verschiebt eine Datei in einen anderen Ordner. :param request: Anfrage des Clients, wird unverändert zurückgesendet :param user: User Objekt (eingeloggter Benutzer) :param fileid: Id der Datei welche verschoben werden soll :param newfolderid: Id des Ordners, in welchen die Datei verschoben werden soll :return: HttpResponse (JSON) """ # hole das folder und file object folderobj = Folder.objects.get(id=newfolderid) fileobj = File.objects.get(id=fileid) # Teste ob eine Datei mit dem selben Namen schon existiert unique, failurereturn = util.checkIfFileOrFolderIsUnique(fileobj.name, File, folderobj, request) # Man darf eine Datei in dieselbes Verzeichnis verschieben (dann passiert einfach nichts) if not unique and folderobj != fileobj.folder: return failurereturn # versuche den neuen Ordner des fileobj zu setzen try: fileobj.folder = folderobj fileobj.save() return util.jsonResponse({'id': fileobj.id, 'name': fileobj.name, 'folderid': fileobj.folder.id, 'foldername': fileobj.folder.name, 'rootid': fileobj.folder.getRoot().id}, True, request) except: return util.jsonErrorResponse(ERROR_MESSAGES['DATABASEERROR'], request)
def moveDir(request, user, folderid, newfolderid): """Verschiebt den Ordner mit der angegebenen id in den neuen Ordner mit der newfolderid. :param request: Anfrage des Clients, wird unverändert zurückgesendet :param user: User Objekt (eingeloggter Benutzer) :param folderid: Id des Ordners, der verschoben werden soll :param newfolderid: Id des Ordners, in welchen der Ordner mit der folderid verschoben werden soll :return: HttpResponse (JSON) """ # hole die beiden Ordner Objekte folderobj = Folder.objects.get(id=folderid) newparentfolderobj = Folder.objects.get(id=newfolderid) # Teste ob Ordnername in diesem Verzeichnis bereits existiert unique, failurereturn = util.checkIfFileOrFolderIsUnique(folderobj.name, Folder, newparentfolderobj, request) # Man darf ein Verzeichnis in dieselbes Verzeichnis verschieben (dann passiert einfach nichts) if not unique and folderobj.parent != newparentfolderobj: return failurereturn # Versuche die Änderung in die Datenbank zu übernehmen try: # setze den newfolder als neues übergeordnetes Verzeichnis folderobj.parent = newparentfolderobj # dessen root Verzeichnis wird auch das Rootverzeichnis vom folderobj (verschieben zwischen Projekten) folderobj.root = newparentfolderobj.getRoot() folderobj.save() return util.jsonResponse({'id': folderobj.id, 'name': folderobj.name, 'parentid': folderobj.parent.id, 'parentname': folderobj.parent.name, 'rootid': folderobj.root.id}, True, request) except: return util.jsonErrorResponse(ERROR_MESSAGES['DATABASEERROR'], request)
def renameDir(request, user, folderid, newdirectoryname): """Benennt den Ordner mit der angegebenen Id um. :param request: Anfrage des Clients, wird unverändert zurückgesendet :param user: User Objekt (eingeloggter Benutzer) :param folderid: Id des Ordners, welcher umbenannt werden soll :param newdirectoryname: neuer Name des Ordners :return: HttpResponse (JSON) """ # hole das Ordner Objekt folder = Folder.objects.get(id=folderid) # Teste ob Ordnername in diesem Verzeichnis bereits existiert unique, failurereturn = util.checkIfFileOrFolderIsUnique( newdirectoryname, Folder, folder.parent, request) if not unique: return failurereturn # Versuche die Änderung in die Datenbank zu übernehmen try: folder.name = newdirectoryname folder.save() return util.jsonResponse({ 'id': folder.id, 'name': folder.name }, True, request) except: return util.jsonErrorResponse(ERROR_MESSAGES['DATABASEERROR'], request)
def uploadFiles(request, user, folderid): """Speichert vom Client gesendete Dateien im entsprechenden Projektordner. :param request: Anfrage des Clients, wird unverändert zurückgesendet :param user: User Objekt (eingeloggter Benutzer) :param folderid: Id des Ordners, in welchen die hochgeladenen Dateien gespeichert werden sollen. :return: HttpResponse (JSON) """ # dictionary für die Rückgabe von erfolgreich gespeicherten Dateien bzw. fehlgeschlagenen # es wird jeweils der name zurückgegeben (bei Erfolg zusätzlich die fileid, bei Fehlschlag der Grund) errors = [] success = [] folder = Folder.objects.get(id=folderid) # Teste ob auch Dateien gesendet wurden if not request.FILES and not request.FILES.getlist('files'): return util.jsonErrorResponse(ERROR_MESSAGES['NOTALLPOSTPARAMETERS'], request) # Hole dateien aus dem request files = request.FILES.getlist('files') # Gehe die Dateien einzeln durch, bei Erfolg, setze id und name auf die success Liste # Bei Fehler, setzte mit name und Grund auf die errors Liste for f in files: rsp, response = util.uploadFile(f, folder, request) if not rsp: errors.append({'name': f.name, 'reason': response}) else: success.append(response) return util.jsonResponse({'success': success, 'failure': errors}, True, request)
def updateFile(request, user, fileid, filecontenttostring): """Aktualisiert eine geänderte Datei eines Projektes in der Datenbank (akzeptiert nur PlainTextFiles). :param request: Anfrage des Clients, wird unverändert zurückgesendet :param user: User Objekt (eingeloggter Benutzer) :param fileid: Id der Datei, welche geändert werden soll :param filecontenttostring: neuer Dateiinhalt als String :return: HttpResponse (JSON) """ # lese die PlainTextFile Datei ein plaintextobj = PlainTextFile.objects.get(id=fileid) isallowedit = not plaintextobj.isLocked() or plaintextobj.lockedBy() == user # wenn die Datei vom aktuellen Benutzer nicht bearbeitet werden darf (gesperrt bzw. nicht selber gesperrt) if not isallowedit: # speichere den Inhalt als neue Datei mit dem aktuellen Datum als Suffix newplaintextobj_name = plaintextobj.name + '_' + user.username + '_' \ + util.datetimeToString(datetime.now().strftime("%Y-%m-%d_%H-%M-%S")) if not PlainTextFile.objects.filter(name=newplaintextobj_name, folder=plaintextobj.folder).exists(): newplaintextobj = TexFile.objects.create(name=newplaintextobj_name, folder=plaintextobj.folder, source_code=filecontenttostring) lasteditor = "" if plaintextobj.lasteditor: plaintextobj.lasteditor.username return util.jsonResponse({'id': newplaintextobj.id, 'name': newplaintextobj.name, 'lasteditor': lasteditor}, True, request) return util.jsonErrorResponse(ERROR_MESSAGES['FILELOCKED']) # sonst sperre die Datei plaintextobj.lock(user) # versuche den source code in der Datenbank durch den übergebenen String zu ersetzen try: plaintextobj.source_code = filecontenttostring plaintextobj.lasteditor = user plaintextobj.save() return util.jsonResponse({'id': plaintextobj.id, 'name': plaintextobj.name}, True, request) except: return util.jsonErrorResponse(ERROR_MESSAGES['DATABASEERROR'], request)
def quitCollaboration(request, user, projectid): """Kündigt der Kollaboration (bzw. Einladung) an einem Projekt (als Kollaborateur) :param request: Anfrage des Clients, wird unverändert zurückgesendet :param user: User Objekt (eingeloggter Benutzer) :param projectid: ID des Projektes, zu dessen die Kollaboration (bzw. die Einladung) gekündigt werden soll :return: HttpResponse (JSON) """ try: project = Project.objects.get(pk=projectid) if user == project.author: return util.jsonErrorResponse(ERROR_MESSAGES['SELFCOLLABORATIONCANCEL'], request) collaboration = Collaboration.objects.get(user=user, project=project) collaboration.delete() return util.jsonResponse({}, True, request) except ObjectDoesNotExist: return util.jsonErrorResponse(ERROR_MESSAGES['COLLABORATIONNOTFOUND'], request) except: return util.jsonErrorResponse(ERROR_MESSAGES['DATABASEERROR'], request)
def rmDir(request, user, folderid): """Löscht den Ordner mit der angegebenen Id. :param request: Anfrage des Clients, wird unverändert zurückgesendet :param user: User Objekt (eingeloggter Benutzer) :param folderid: Id des zu löschenden Ordners :return: HttpResponse (JSON) """ # hole das Ordner Objekt folderobj = Folder.objects.get(id=folderid) # überprüfe, ob der Ordner ein Rootfolder eines Projektes ist, diese dürfen nicht gelöscht werden if folderobj.isRoot(): return util.jsonErrorResponse(ERROR_MESSAGES['NOTENOUGHRIGHTS'], request) # versuche das Ordner Objekt zu löschen try: folderobj.delete() return util.jsonResponse({}, True, request) except: return util.jsonErrorResponse(ERROR_MESSAGES['DATABASEERROR'], request)
def latexCompile(request, user, fileid, formatid, forcecompile): """Kompiliert eine LaTeX Datei. :param request: Anfrage des Clients, wird unverändert zurückgesendet :param user: User Objekt (eingeloggter Benutzer) :param fileid: Id der tex Datei welche kompiliert werden soll :param formatid 0 - PDF, 1 - HTML :return: HttpResponse (JSON) """ errors, success = latexcompile(fileid, formatid=formatid, forcecompile=forcecompile) if errors: if success: ret = success else: ret = dict() ret['error'] = json.dumps(errors) return util.jsonErrorResponse(ret, request) if success: return util.jsonResponse(success, True, request) # Sonst Fehlermeldung an Client return util.jsonErrorResponse(ERROR_MESSAGES['COMPILATIONERROR'], request)
def projectRename(request, user, projectid, newprojectname): """Benennt ein Projekt um. :param request: Anfrage des Clients, wird unverändert zurückgesendet :param user: User Objekt (eingeloggter Benutzer) :param projectid: Id des Projektes welches umbenannt werden soll :param newprojectname: neuer Name des Projektes :return: HttpResponse (JSON) """ # hole das Projekt, welches umbenannt werden soll projectobj = Project.objects.get(id=projectid) # überprüfe ob ein Projekt mit dem Namen 'projectname' bereits für diese Benutzer existiert if Project.objects.filter(name__iexact=newprojectname.lower(), author=user).exists(): return util.jsonErrorResponse(ERROR_MESSAGES['PROJECTALREADYEXISTS'] % newprojectname, request) else: # versuche das Projekt umzubenennen try: projectobj.name = newprojectname projectobj.save() return util.jsonResponse({'id': projectobj.id, 'name': projectobj.name}, True, request) except: return util.jsonErrorResponse(ERROR_MESSAGES['DATABASEERROR'], request)
def cancelCollaboration(request, user, projectid, collaboratoremail): """Entzieht der Freigabe :param request: Anfrage des Clients, wird unverändert zurückgesendet :param user: User Objekt (eingeloggter Benutzer) :param projectid: ID des Projektes, zu dessen der Freigabe entzieht werden soll :param collaboratoremail: E-Mail-Adresse der Kollaborateur :return: HttpResponse (JSON) """ try: project = Project.objects.get(pk=projectid) collaborator = User.objects.get(username=collaboratoremail) if user == collaborator: return util.jsonErrorResponse(ERROR_MESSAGES['SELFCOLLABORATIONCANCEL'], request) collaboration = Collaboration.objects.get(user=collaborator, project=project) collaboration.delete() except ObjectDoesNotExist: return util.jsonErrorResponse(ERROR_MESSAGES['COLLABORATIONNOTFOUND'], request) except: return util.jsonErrorResponse(ERROR_MESSAGES['DATABASEERROR'], request) if not collaboration.isConfirmed: return util.jsonResponse({}, True, request) # ermittelt einen noch nicht verwendeten Projektnamen anhand des übergebenen Namens validname = util.getNextValidProjectName(collaborator,project.name+' ['+user.username+']') # versucht ein Duplikat des Projektes für den Kollaborateur in der Datenbank zu erstellen try: Project.objects.cloneProject(project=project, name=validname, author=collaborator) except: return util.jsonErrorResponse(ERROR_MESSAGES['DATABASEERROR'], request) return util.jsonResponse({}, True, request)
def unlockFile(request, user, fileid): """Entsperrt die Datei. :param request: Anfrage des Clients, wird unverändert zurückgesendet :param user: User Objekt (eingeloggter Benutzer) :param fileid: Id der Datei welche entsperrt werden soll :return: HttpResponse (JSON) """ file = File.objects.get(pk=fileid) if file.isLocked() and file.lockedBy() != user: return util.jsonErrorResponse(ERROR_MESSAGES['UNLOCKERROR'], request) file.unlock() return util.jsonResponse({}, True, request)
def templateRename(request, user, templateid, newtemplatename): """Benennt eine Vorlage um. :param request: Anfrage des Clients, wird unverändert zurückgesendet :param user: User Objekt (eingeloggter Benutzer) :param templateid: Id der Vorlage welche umbenannt werden soll :param newtemplatename: neuer Name der Vorlage :return: HttpResponse (JSON) """ # hole die Vorlage, welche umbenannt werden soll templateobj = ProjectTemplate.objects.get(id=templateid) # überprüfe ob eine Vorlage mit dem Namen 'newtemplatename' bereits für diese Benutzer existiert if ProjectTemplate.objects.filter(name__iexact=newtemplatename.lower(), author=user).exists(): return util.jsonErrorResponse(ERROR_MESSAGES['TEMPLATEALREADYEXISTS'] % newtemplatename, request) else: # versuche die Vorlage umzubenennen try: templateobj.name = newtemplatename templateobj.save() return util.jsonResponse({'id': templateobj.id, 'name': templateobj.name}, True, request) except: return util.jsonErrorResponse(ERROR_MESSAGES['DATABASEERROR'], request)
def activateCollaboration(request, user, projectid): """Bestätigt der Einladung zur Kollaboration an einem Projekt. :param request: Anfrage des Clients, wird unverändert zurückgesendet :param user: User Objekt (eingeloggter Benutzer) :param projectid: ID des Projektes, zu dessen die Einladung bestätigt werden soll :return: HttpResponse (JSON) """ try: project = Project.objects.get(pk=projectid) collaboration = Collaboration.objects.get(user=user, project=project) except ObjectDoesNotExist: return util.jsonErrorResponse(ERROR_MESSAGES['COLLABORATIONNOTFOUND'], request) try: if not collaboration.isConfirmed: collaboration.isConfirmed = True collaboration.save() except: return util.jsonErrorResponse(ERROR_MESSAGES['DATABASEERROR'], request) return util.jsonResponse({}, True, request)
def hasInvitedUsers(request, user, projectid): """Gibt an, ob für das, der übergebenen Projekt-ID entsprechende, Projekt eingeladene Nutzer vorliegen. Hierbei ist es unerheblich, ob die jeweilige Einladung bereits bestätigt wurde. :param request: Anfrage des Clients, wird unverändert zurückgesendet :param user: User Objekt (eingeloggter Benutzer) :param projectid: ID des Projektes, von dessen eingeladenen Benutzern die Nutzernamen zurückgegeben werden sollen :return: HttpResponse (JSON) """ collaborations = Collaboration.objects.filter(project=Project.objects.get(id=projectid)) if collaborations is None: return util.jsonErrorResponse(ERROR_MESSAGES['DATABASEERROR'], request) else: return util.jsonResponse(collaborations.exists(), True, request)
def listUnconfirmedCollaborativeProjects(request, user): """Liefert eine Liste aller Projekte, zu deren Kollaboration der übergebene Benutzer eingeladen ist, diese jedoch noch nicht bestätigt hat. :param request: Anfrage des Clients, wird unverändert zurückgesendet :param user: User Objekt (eingeloggter Benutzer) :return: HttpResponse (JSON) """ unconfirmedCollaborations = Collaboration.objects.filter(user=user,isConfirmed=False) if unconfirmedCollaborations is None: return util.jsonErrorResponse(ERROR_MESSAGES['DATABASEERROR'], request) else: json_return = [util.projectToJson(collaboration.project) for collaboration in unconfirmedCollaborations] return util.jsonResponse(json_return, True, request)
def listTemplates(request, user): """Liefert eine Übersicht aller Vorlagen eines Benutzers. :param request: Anfrage des Clients, wird unverändert zurückgesendet :param user: User Objekt (eingeloggter Benutzer) :return: HttpResponse (JSON) """ availableprojects = ProjectTemplate.objects.filter(author=user, project__isnull=True) if availableprojects is None: return util.jsonErrorResponse(ERROR_MESSAGES['DATABASEERROR'], request) else: json_return = [util.projectToJson(template) for template in availableprojects] return util.jsonResponse(json_return, True, request)
def projectRm(request, user, projectid): """Löscht ein vorhandenes Projekt eines Benutzers. :param request: Anfrage des Clients, wird unverändert zurückgesendet :param user: User Objekt (eingeloggter Benutzer) :param projectid: Id des Projektes welches gelöscht werden soll :return: HttpResponse (JSON) """ # hole das zu löschende Projekt projectobj = Project.objects.get(id=projectid) # versuche das Projekt zu löschen try: projectobj.delete() return util.jsonResponse({}, True, request) except: return util.jsonErrorResponse(ERROR_MESSAGES['DATABASEERROR'], request)
def templateRm(request, user, templateid): """Löscht eine vorhandene Vorlage. :param request: Anfrage des Clients, wird unverändert zurückgesendet :param user: User Objekt (eingeloggter Benutzer) :param templateid: Id der Vorlage welche gelöscht werden soll :return: HttpResponse (JSON) """ # hole die zu löschende Vorlage templateobj = ProjectTemplate.objects.get(id=templateid) # versuche die Vorlage zu löschen try: templateobj.delete() return util.jsonResponse({}, True, request) except: return util.jsonErrorResponse(ERROR_MESSAGES['DATABASEERROR'], request)
def deleteFile(request, user, fileid): """Löscht eine vom Client angegebene Datei eines Projektes. :param request: Anfrage des Clients, wird unverändert zurückgesendet :param user: User Objekt (eingeloggter Benutzer) :param fileid: Id der Datei welche gelöscht werden soll :return: HttpResponse (JSON) """ # hole das file object fileobj = File.objects.get(id=fileid) # versuche die Datei zu löschen try: fileobj.delete() return util.jsonResponse({}, True, request) except: return util.jsonErrorResponse(ERROR_MESSAGES['DATABASEERROR'], request)
def listInvitedUsers(request, user, projectid): """Liefert eine Liste der Nutzernamen aller Nutzer, welche für das, der übergebenen Projekt-ID entsprechende, Projekt eingeladen sind. Hierbei ist es unerheblich, ob die jeweilige Einladung bereits bestätigt wurde. :param request: Anfrage des Clients, wird unverändert zurückgesendet :param user: User Objekt (eingeloggter Benutzer) :param projectid: ID des Projektes, von dessen eingeladenen Benutzern die Nutzernamen zurückgegeben werden sollen :return: HttpResponse (JSON) """ collaborations = Collaboration.objects.filter(project=Project.objects.get(id=projectid)).order_by('user__username') if collaborations is None: return util.jsonErrorResponse(ERROR_MESSAGES['DATABASEERROR'], request) else: json_return = [collaboration.user.username for collaboration in collaborations] return util.jsonResponse(json_return, True, request)
def listProjects(request, user): """Liefert eine Übersicht aller Projekte eines Benutzers (einschließlich seiner kollaborativen Projekte). :param request: Anfrage des Clients, wird unverändert zurückgesendet :param user: User Objekt (eingeloggter Benutzer) :return: HttpResponse (JSON) """ userprojects = Project.objects.filter(author=user) collaborations = Collaboration.objects.filter(user=user,isConfirmed=True) if userprojects is None or collaborations is None: return util.jsonErrorResponse(ERROR_MESSAGES['DATABASEERROR'], request) else: json_return = [util.projectToJson(project) for project in userprojects] json_return += [util.projectToJson(collaboration.project) for collaboration in collaborations] return util.jsonResponse(json_return, True, request)
def moveDir(request, user, folderid, newfolderid): """Verschiebt den Ordner mit der angegebenen id in den neuen Ordner mit der newfolderid. :param request: Anfrage des Clients, wird unverändert zurückgesendet :param user: User Objekt (eingeloggter Benutzer) :param folderid: Id des Ordners, der verschoben werden soll :param newfolderid: Id des Ordners, in welchen der Ordner mit der folderid verschoben werden soll :return: HttpResponse (JSON) """ # hole die beiden Ordner Objekte folderobj = Folder.objects.get(id=folderid) newparentfolderobj = Folder.objects.get(id=newfolderid) # Teste ob Ordnername in diesem Verzeichnis bereits existiert unique, failurereturn = util.checkIfFileOrFolderIsUnique( folderobj.name, Folder, newparentfolderobj, request) # Man darf ein Verzeichnis in dieselbes Verzeichnis verschieben (dann passiert einfach nichts) if not unique and folderobj.parent != newparentfolderobj: return failurereturn # Versuche die Änderung in die Datenbank zu übernehmen try: # setze den newfolder als neues übergeordnetes Verzeichnis folderobj.parent = newparentfolderobj # dessen root Verzeichnis wird auch das Rootverzeichnis vom folderobj (verschieben zwischen Projekten) folderobj.root = newparentfolderobj.getRoot() folderobj.save() return util.jsonResponse( { 'id': folderobj.id, 'name': folderobj.name, 'parentid': folderobj.parent.id, 'parentname': folderobj.parent.name, 'rootid': folderobj.root.id }, True, request) except: return util.jsonErrorResponse(ERROR_MESSAGES['DATABASEERROR'], request)
def projectCreate(request, user, projectname): """Erstellt ein neues Projekt mit dem Namen projectname (ggf. mit einem generierten numerischen Suffix). Es wird ein neues Projekt in der Datenbank angelegt. Durch das Projektmodell wird automatisch eine leere main.tex Datei im Hauptverzeichnis erstellt. :param request: Anfrage des Clients, wird unverändert zurückgesendet :param user: User Objekt (eingeloggter Benutzer) :param projectname: Name des neuen Projektes :return: HttpResponse (JSON) """ # ermittelt einen noch nicht verwendeten Projektnamen anhand des übergebenen Namens validname = util.getNextValidProjectName(user,projectname) # versucht das Projekt in der Datenbank zu erstellen try: newproject = Project.objects.createWithMainTex(author=user, name=validname) except: return util.jsonErrorResponse(ERROR_MESSAGES['DATABASEERROR'], request) # gibt die Id und den Namen des erstellten Projektes zurück return util.jsonResponse({'id': newproject.id, 'name': newproject.name}, True, request)
def projectClone(request, user, projectid, newprojectname): """Erstellt eine Kopie eines Projektes mit dem Namen newprojectname (ggf. mit einem generierten numerischen Suffix). :param request: Anfrage des Clients, wird unverändert zurückgesendet :param user: User Objekt (eingeloggter Benutzer) :param projectid: Id des Projektes, welches geklont werden soll :param newprojectname: Name des neuen Projektes :return: HttpResponse (JSON) """ # ermittelt einen noch nicht verwendeten Projektnamen anhand des übergebenen Namens validname = util.getNextValidProjectName(user,newprojectname) # holt des aktuelle Projekt-Objekt projectobj = Project.objects.get(id=projectid) # versucht das Projekt in der Datenbank zu erstellen try: newproject = Project.objects.cloneProject(project=projectobj, name=validname, author=user) except: return util.jsonErrorResponse(ERROR_MESSAGES['DATABASEERROR'], request) # gibt die Id und den Namen des erstellte Projektes zurück return util.jsonResponse({'id': newproject.id, 'name': newproject.name}, True, request)
def createTexFile(request, user, folderid, texname): """Erstellt eine neue .tex Datei in der Datenbank ohne Textinhalt. :param request: Anfrage des Clients, wird unverändert zurückgesendet :param user: User Objekt (eingeloggter Benutzer) :param folderid: Id des Ordners, in welchen die Datei erstellt werden soll :param texname: Name der .tex Datei :return: HttpResponse (JSON) """ # hole das Ordner Objekt folderobj = Folder.objects.get(id=folderid) # Teste ob eine .tex Datei mit dem selben Namen in diesem Ordner schon existiert unique, failurereturn = util.checkIfFileOrFolderIsUnique(texname, File, folderobj, request) if not unique: return failurereturn # versuche die tex Datei zu erstellen try: texobj = TexFile.objects.create(name=texname, folder=Folder.objects.get(id=folderid), source_code='') return util.jsonResponse({'id': texobj.id, 'name': texobj.name}, True, request) except: return util.jsonErrorResponse(ERROR_MESSAGES['DATABASEERROR'], request)
def execute(request): if request.method == 'POST' and 'command' in request.POST: # hole den aktuellen Benutzer user = request.user # wenn der Schlüssel nicht gefunden wurde # gib Fehlermeldung zurück if request.POST['command'] not in available_commands: return util.jsonErrorResponse(ERROR_MESSAGES['COMMANDNOTFOUND'], request) args = [] # aktueller Befehl c = available_commands[request.POST['command']] # Parameter dieses Befehls paras = c['parameters'] # durchlaufe alle Parameter des Befehls for para in paras: # wenn der Parameter nicht gefunden wurde oder ein Parameter, welcher eine id angeben sollte # Zeichen enthält, die keine Zahlen sind, gib Fehlermeldung zurück if request.POST.get(para['para']['name']) is None: return util.jsonErrorResponse(ERROR_MESSAGES['MISSINGPARAMETER'] % (para['para']), request) elif para['para']['type'] == int and (not request.POST.get(para['para']['name']).isdigit()): return util.jsonErrorResponse(ERROR_MESSAGES['MISSINGPARAMETER'] % (para['para']), request) # sonst füge den Parameter zu der Argumentliste hinzu else: args.append(request.POST[para['para']['name']]) # Teste auf ungültige strings if para.get('stringcheck'): failstring, failurereturn = util.checkObjectForInvalidString( request.POST.get(para['para']['name']), request) if not failstring: return failurereturn elif para.get('filenamecheck'): failstring, failurereturn = util.checkFileForInvalidString( request.POST.get(para['para']['name']), request) if not failstring: return failurereturn # Teste, dass der User rechte auf das Objekt mit der angegebenen id # hat und diese existiert if para.get('type') and para['para']['type'] == int: objType = para.get('type') objId = request.POST.get(para['para']['name']) requireRights = para.get('requirerights', ['owner']) lockcheck = para.get('lockcheck', False) if objType == Project: rights, failurereturn = util.checkIfProjectExistsAndUserHasRights(objId, user, request, requireRights) if not rights: return failurereturn elif objType == Folder: rights, failurereturn = util.checkIfDirExistsAndUserHasRights(objId, user, request, requireRights, lockcheck) if not rights: return failurereturn elif objType == File: rights, failurereturn = util.checkIfFileExistsAndUserHasRights(objId, user, request, requireRights, lockcheck, objecttype=File) if not rights: return failurereturn elif objType == TexFile: rights, failurereturn = util.checkIfFileExistsAndUserHasRights(objId, user, request, requireRights, lockcheck, objecttype=TexFile) if not rights: return failurereturn elif objType == PlainTextFile: rights, failurereturn = util.checkIfFileExistsAndUserHasRights(objId, user, request, requireRights, lockcheck, objecttype=PlainTextFile) if not rights: return failurereturn elif objType == ProjectTemplate: # Überprüfe, ob Vorlage existiert und der User darauf Rechte hat emptystring, failurereturn = util.checkIfTemplateExistsAndUserHasRights(objId, user, request) if not emptystring: return failurereturn # führe den übergebenen Befehl aus return c['command'](request, user, *args) elif request.method == 'GET' and request.GET.get('command'): command = request.GET.get('command') pdfid = request.GET.get('id') texid = request.GET.get('texid') defaultpdfPath = filepath = os.path.join(settings.BASE_DIR, 'app', 'static', 'default.pdf') if (pdfid and not pdfid.isdigit()) or (texid and not texid.isdigit()): return serve(request, os.path.basename(defaultpdfPath), os.path.dirname(defaultpdfPath)) if command == 'getpdf' and pdfid: requireRights = ['owner', 'collaborator'] rights, failurereturn = util.checkIfFileExistsAndUserHasRights(pdfid, request.user, request, requireRights, lockcheck=False, objecttype=PDF) if not rights: return serve(request, os.path.basename(defaultpdfPath), os.path.dirname(defaultpdfPath)) return file.getPDF(request, request.user, pdfid=pdfid, default=defaultpdfPath) elif command == 'getpdf' and texid: requireRights = ['owner', 'collaborator'] rights, failurereturn = util.checkIfFileExistsAndUserHasRights(texid, request.user, request, requireRights, lockcheck=False, objecttype=TexFile) if not rights: return serve(request, os.path.basename(defaultpdfPath), os.path.dirname(defaultpdfPath)) return file.getPDF(request, request.user, texid=texid, default=defaultpdfPath) return util.jsonErrorResponse(ERROR_MESSAGES['MISSINGPARAMETER'] % 'unknown', request)
def execute(request): if request.method == 'POST' and 'command' in request.POST: # hole den aktuellen Benutzer user = request.user # wenn der Schlüssel nicht gefunden wurde # gib Fehlermeldung zurück if request.POST['command'] not in available_commands: return util.jsonErrorResponse(ERROR_MESSAGES['COMMANDNOTFOUND'], request) args = [] # aktueller Befehl c = available_commands[request.POST['command']] # Parameter dieses Befehls paras = c['parameters'] # durchlaufe alle Parameter des Befehls for para in paras: # wenn der Parameter nicht gefunden wurde oder ein Parameter, welcher eine id angeben sollte # Zeichen enthält, die keine Zahlen sind, gib Fehlermeldung zurück if request.POST.get(para['para']['name']) is None: return util.jsonErrorResponse( ERROR_MESSAGES['MISSINGPARAMETER'] % (para['para']), request) elif para['para']['type'] == int and (not request.POST.get( para['para']['name']).isdigit()): return util.jsonErrorResponse( ERROR_MESSAGES['MISSINGPARAMETER'] % (para['para']), request) # sonst füge den Parameter zu der Argumentliste hinzu else: args.append(request.POST[para['para']['name']]) # Teste auf ungültige strings if para.get('stringcheck'): failstring, failurereturn = util.checkObjectForInvalidString( request.POST.get(para['para']['name']), request) if not failstring: return failurereturn elif para.get('filenamecheck'): failstring, failurereturn = util.checkFileForInvalidString( request.POST.get(para['para']['name']), request) if not failstring: return failurereturn # Teste, dass der User rechte auf das Objekt mit der angegebenen id # hat und diese existiert if para.get('type') and para['para']['type'] == int: objType = para.get('type') objId = request.POST.get(para['para']['name']) requireRights = para.get('requirerights', ['owner']) lockcheck = para.get('lockcheck', False) if objType == Project: rights, failurereturn = util.checkIfProjectExistsAndUserHasRights( objId, user, request, requireRights) if not rights: return failurereturn elif objType == Folder: rights, failurereturn = util.checkIfDirExistsAndUserHasRights( objId, user, request, requireRights, lockcheck) if not rights: return failurereturn elif objType == File: rights, failurereturn = util.checkIfFileExistsAndUserHasRights( objId, user, request, requireRights, lockcheck, objecttype=File) if not rights: return failurereturn elif objType == TexFile: rights, failurereturn = util.checkIfFileExistsAndUserHasRights( objId, user, request, requireRights, lockcheck, objecttype=TexFile) if not rights: return failurereturn elif objType == PlainTextFile: rights, failurereturn = util.checkIfFileExistsAndUserHasRights( objId, user, request, requireRights, lockcheck, objecttype=PlainTextFile) if not rights: return failurereturn elif objType == ProjectTemplate: # Überprüfe, ob Vorlage existiert und der User darauf Rechte hat emptystring, failurereturn = util.checkIfTemplateExistsAndUserHasRights( objId, user, request) if not emptystring: return failurereturn # führe den übergebenen Befehl aus return c['command'](request, user, *args) elif request.method == 'GET' and request.GET.get('command'): command = request.GET.get('command') pdfid = request.GET.get('id') texid = request.GET.get('texid') defaultpdfPath = filepath = os.path.join(settings.BASE_DIR, 'app', 'static', 'default.pdf') if (pdfid and not pdfid.isdigit()) or (texid and not texid.isdigit()): return serve(request, os.path.basename(defaultpdfPath), os.path.dirname(defaultpdfPath)) if command == 'getpdf' and pdfid: requireRights = ['owner', 'collaborator'] rights, failurereturn = util.checkIfFileExistsAndUserHasRights( pdfid, request.user, request, requireRights, lockcheck=False, objecttype=PDF) if not rights: return serve(request, os.path.basename(defaultpdfPath), os.path.dirname(defaultpdfPath)) return file.getPDF(request, request.user, pdfid=pdfid, default=defaultpdfPath) elif command == 'getpdf' and texid: requireRights = ['owner', 'collaborator'] rights, failurereturn = util.checkIfFileExistsAndUserHasRights( texid, request.user, request, requireRights, lockcheck=False, objecttype=TexFile) if not rights: return serve(request, os.path.basename(defaultpdfPath), os.path.dirname(defaultpdfPath)) return file.getPDF(request, request.user, texid=texid, default=defaultpdfPath) return util.jsonErrorResponse( ERROR_MESSAGES['MISSINGPARAMETER'] % 'unknown', request)
def importZip(request, user): """Importiert ein Projekt aus einer vom Client übergebenen zip Datei. :param request: Anfrage des Clients, wird unverändert zurückgesendet :param user: User Objekt (eingeloggter Benutzer) :return: HttpResponse (JSON) """ # Teste ob auch Dateien gesendet wurden if not request.FILES and not request.FILES.getlist('files'): return util.jsonErrorResponse(ERROR_MESSAGES['NOTALLPOSTPARAMETERS'], request) # Hole dateien aus dem request files = request.FILES.getlist('files') # Erstelle ein temp Verzeichnis, in welches die .zip Datei entpackt werden soll tmpfolder = util.getNewTempFolder() zip_file_name = files[0].name # speichere die .zip Datei im tmp Verzeichnis zip_file_path = os.path.join(tmpfolder, zip_file_name) zip_file = open(zip_file_path, 'wb') zip_file.write(files[0].read()) zip_file.close() transaction.commit() # überprüfe ob es sich um eine gültige .zip Datei handelt # und ob die zip Datei kleiner als 150 bytes ist # zip Datei ohne Inhalt ist 105 bytes gross if not os.path.getsize(zip_file_path) > 105 : return util.jsonErrorResponse(ERROR_MESSAGES['EMPTYZIPFILE'],request) if not zipfile.is_zipfile(zip_file_path) : return util.jsonErrorResponse(ERROR_MESSAGES['NOTAZIPFILE'], request) extract_path = os.path.join(tmpfolder, 'extracted') # erstelle einen Unterorder 'extracted' if not os.path.isdir(extract_path): os.mkdir(extract_path) # entpacke die .zip Datei in .../tmpfolder/extracted util.extractZipToFolder(extract_path, zip_file_path) # benutze den Namen der zip Datei (ohne Dateiendung) als Projektnamen project_name, fileExtension = os.path.splitext(zip_file_name) # Erstelle das neue Projekt mit einen Namen, welcher ungültig ist. projectobj = Project.objects.create(name=project_name + '<old', author=user) # dictionary in der als keyword der Pfad und als value ein Folder objekt gespeichert werden soll. # Dies soll dafür sorgen, dass wir später ohne probleme das # Elternverzeichnis eines Verzeichnis herausfinden können projdict = {} parent = None folder = projectobj.rootFolder # Tiefe des Verzeichnis, wo die zip entpackt wurde rootdepth = len(extract_path.split(os.sep)) # durchlaufe alle Ordner/Unterordner in extracted # und erstelle die jeweiligen Objekte in der Datenbank # Dateien werden über die util.uploadfiles() Methode erstellt returnmsg = util.jsonResponse({'id': projectobj.id, 'name': project_name, 'rootid': projectobj.rootFolder.id}, True, request) failed = False transaction.commit() try: for root, dirs, files in os.walk(extract_path): # relativer Pfad des derzeitigen Verzeichnis path = root.split(os.sep)[rootdepth:] # falls path true ist, ist root nicht das root Verzeichnis, wo die zip # entpackt wurde if path: # path is also ein subsubfolder und wir müssen den subfolder als parent setzen if path[:-1]: parent = projdict[os.path.join('', *path[:-1])] else: parent = projectobj.rootFolder name = util.convertLatinToUnicode(util.getFolderName(root)) if name == '__MACOSX': continue # speichere Ordner folder = Folder.objects.create( name=util.convertLatinToUnicode(util.getFolderName(root)), parent=parent, root=projectobj.rootFolder) projdict[os.path.join('', *path)] = folder for f in files: # füge die Dateien dem Ordner hinzu fileobj = open(os.path.join(root, f), 'rb') result, msg = util.uploadFile(fileobj, folder, request, True) fileobj.close() if not result: returnmsg = util.jsonErrorResponse(msg, request) raise TypeError except TypeError: transaction.rollback() projectobj.delete() # bei Fehler muss noch das Projekt selbst gelöscht werden failed = True if not failed: # prüfe ob ein Projekt mit dem gleichen Namen bereits existiert # Groß- und Kleinschreibung wird hierbei nicht beachtet # wenn es existiert, dann lösche dies # Achtung: Projekt wird ohne weitere Abfrage komplett gelöscht # Es ist Aufgabe des Clients, vorher eine Abfrage anzuzeigen if Project.objects.filter(name__iexact=project_name.lower(), author=user).exists(): Project.objects.get(name__iexact=project_name.lower(), author=user).delete() projectobj.name = project_name projectobj.save() # lösche alle temporären Dateien und Ordner if os.path.isdir(tmpfolder): shutil.rmtree(tmpfolder) transaction.commit() return returnmsg