mirror of
https://github.com/ONLYOFFICE/document-server-integration.git
synced 2026-04-07 14:06:11 +08:00
Merge remote-tracking branch 'remotes/origin/develop' into feature/jwt-download-files
# Conflicts: # web/documentserver-example/csharp-mvc/Helpers/DocManagerHelper.cs # web/documentserver-example/csharp-mvc/Models/FileModel.cs # web/documentserver-example/csharp-mvc/WebEditor.ashx.cs # web/documentserver-example/csharp/DocEditor.aspx.cs # web/documentserver-example/csharp/WebEditor.ashx.cs # web/documentserver-example/java/src/main/java/controllers/IndexServlet.java # web/documentserver-example/java/src/main/java/entities/FileModel.java # web/documentserver-example/java/src/main/java/helpers/DocumentManager.java # web/documentserver-example/nodejs/helpers/docManager.js # web/documentserver-example/php/doceditor.php # web/documentserver-example/php/webeditor-ajax.php # web/documentserver-example/python/src/utils/docManager.py # web/documentserver-example/python/src/views/actions.py # web/documentserver-example/ruby/app/controllers/home_controller.rb # web/documentserver-example/ruby/app/models/document_helper.rb # web/documentserver-example/ruby/app/models/file_model.rb
This commit is contained in:
@ -73,18 +73,23 @@ LANGUAGES = {
|
||||
'vi': 'Vietnamese'
|
||||
}
|
||||
|
||||
# check if the file extension can be viewed
|
||||
def isCanView(ext):
|
||||
return ext in config.DOC_SERV_VIEWED
|
||||
|
||||
# check if the file extension can be edited
|
||||
def isCanEdit(ext):
|
||||
return ext in config.DOC_SERV_EDITED
|
||||
|
||||
# check if the file extension can be converted
|
||||
def isCanConvert(ext):
|
||||
return ext in config.DOC_SERV_CONVERT
|
||||
|
||||
# check if the file extension is supported by the editor (it can be viewed or edited or converted)
|
||||
def isSupportedExt(ext):
|
||||
return isCanView(ext) | isCanEdit(ext) | isCanConvert(ext)
|
||||
|
||||
# get internal extension for a given file type
|
||||
def getInternalExtension(fileType):
|
||||
mapping = {
|
||||
'word': '.docx',
|
||||
@ -92,31 +97,35 @@ def getInternalExtension(fileType):
|
||||
'slide': '.pptx'
|
||||
}
|
||||
|
||||
return mapping.get(fileType, '.docx')
|
||||
return mapping.get(fileType, '.docx') # the default file type is .docx
|
||||
|
||||
# get file name with an index if such a file name already exists
|
||||
def getCorrectName(filename, req):
|
||||
basename = fileUtils.getFileNameWithoutExt(filename)
|
||||
ext = fileUtils.getFileExt(filename)
|
||||
name = f'{basename}{ext}'
|
||||
|
||||
i = 1
|
||||
while os.path.exists(getStoragePath(name, req)):
|
||||
name = f'{basename} ({i}){ext}'
|
||||
while os.path.exists(getStoragePath(name, req)): # if file with such a name already exists
|
||||
name = f'{basename} ({i}){ext}' # add an index to its name
|
||||
i += 1
|
||||
|
||||
return name
|
||||
|
||||
# get server url
|
||||
def getServerUrl (forDocumentServer, req):
|
||||
if (forDocumentServer and config.EXAMPLE_DOMAIN is not None):
|
||||
return config.EXAMPLE_DOMAIN
|
||||
else:
|
||||
return req.headers.get("x-forwarded-proto") or req.scheme + "://" + req.get_host()
|
||||
|
||||
# get file url
|
||||
def getFileUri(filename, forDocumentServer, req):
|
||||
host = getServerUrl(forDocumentServer, req)
|
||||
curAdr = req.META['REMOTE_ADDR']
|
||||
return f'{host}{settings.STATIC_URL}{curAdr}/{filename}'
|
||||
|
||||
# get absolute URL to the document storage service
|
||||
def getCallbackUrl(filename, req):
|
||||
host = getServerUrl(True, req)
|
||||
curAdr = req.META['REMOTE_ADDR']
|
||||
@ -131,6 +140,7 @@ def getDownloadUrl(filename, req):
|
||||
curAdr = req.META['REMOTE_ADDR']
|
||||
return f'{host}/download?fileName={filename}&userAddress={curAdr}'
|
||||
|
||||
# get root folder for the current file
|
||||
def getRootFolder(req):
|
||||
if isinstance(req, str):
|
||||
curAdr = req
|
||||
@ -139,16 +149,18 @@ def getRootFolder(req):
|
||||
|
||||
directory = os.path.join(config.STORAGE_PATH, curAdr)
|
||||
|
||||
if not os.path.exists(directory):
|
||||
if not os.path.exists(directory): # if such a directory does not exist, make it
|
||||
os.makedirs(directory)
|
||||
|
||||
return directory
|
||||
|
||||
# get the file path
|
||||
def getStoragePath(filename, req):
|
||||
directory = getRootFolder(req)
|
||||
|
||||
return os.path.join(directory, fileUtils.getFileName(filename))
|
||||
|
||||
# get the path to the forcesaved file version
|
||||
def getForcesavePath(filename, req, create):
|
||||
if isinstance(req, str):
|
||||
curAdr = req
|
||||
@ -156,47 +168,50 @@ def getForcesavePath(filename, req, create):
|
||||
curAdr = req.META['REMOTE_ADDR']
|
||||
|
||||
directory = os.path.join(config.STORAGE_PATH, curAdr)
|
||||
if not os.path.exists(directory):
|
||||
if not os.path.exists(directory): # the directory with host address doesn't exist
|
||||
return ""
|
||||
|
||||
directory = os.path.join(directory, f'{filename}-hist')
|
||||
directory = os.path.join(directory, f'{filename}-hist') # get the path to the history of the given file
|
||||
if (not os.path.exists(directory)):
|
||||
if create:
|
||||
os.makedirs(directory)
|
||||
else:
|
||||
if create: # if the history directory doesn't exist
|
||||
os.makedirs(directory) # create history directory if it doesn't exist
|
||||
else: # the history directory doesn't exist and we are not supposed to create it
|
||||
return ""
|
||||
|
||||
directory = os.path.join(directory, filename)
|
||||
directory = os.path.join(directory, filename) # and get the path to the given file
|
||||
if (not os.path.exists(directory) and not create):
|
||||
return ""
|
||||
|
||||
return directory
|
||||
|
||||
# get information about all the stored files
|
||||
def getStoredFiles(req):
|
||||
directory = getRootFolder(req)
|
||||
|
||||
files = os.listdir(directory)
|
||||
files.sort(key=lambda x: os.path.getmtime(os.path.join(directory, x)), reverse=True)
|
||||
files.sort(key=lambda x: os.path.getmtime(os.path.join(directory, x)), reverse=True) # sort files by time of last modification
|
||||
|
||||
fileInfos = []
|
||||
|
||||
for f in files:
|
||||
if os.path.isfile(os.path.join(directory, f)):
|
||||
fileInfos.append({ 'type': fileUtils.getFileType(f), 'title': f, 'url': getFileUri(f, True, req), 'canEdit': isCanEdit(fileUtils.getFileExt(f))})
|
||||
fileInfos.append({ 'type': fileUtils.getFileType(f), 'title': f, 'url': getFileUri(f, True, req), 'canEdit': isCanEdit(fileUtils.getFileExt(f))}) # write information about file type, title and url
|
||||
|
||||
return fileInfos
|
||||
|
||||
# create a file
|
||||
def createFile(stream, path, req = None, meta = False):
|
||||
bufSize = 8192
|
||||
with io.open(path, 'wb') as out:
|
||||
with io.open(path, 'wb') as out: # write data to the file by streams
|
||||
read = stream.read(bufSize)
|
||||
while len(read) > 0:
|
||||
out.write(read)
|
||||
read = stream.read(bufSize)
|
||||
if meta:
|
||||
historyManager.createMeta(path, req)
|
||||
historyManager.createMeta(path, req) # create meta data for the file if needed
|
||||
return
|
||||
|
||||
# create file response
|
||||
def createFileResponse(response, path, req, meta):
|
||||
response.raise_for_status()
|
||||
with open(path, 'wb') as file:
|
||||
@ -204,43 +219,48 @@ def createFileResponse(response, path, req, meta):
|
||||
file.write(chunk)
|
||||
return
|
||||
|
||||
# save file from the given url
|
||||
def saveFileFromUri(uri, path, req = None, meta = False):
|
||||
resp = requests.get(uri, stream=True)
|
||||
createFileResponse(resp, path, req, meta)
|
||||
return
|
||||
|
||||
# create sample file
|
||||
def createSample(fileType, sample, req):
|
||||
ext = getInternalExtension(fileType)
|
||||
ext = getInternalExtension(fileType) # get the internal extension of the given file type
|
||||
|
||||
if not sample:
|
||||
sample = 'false'
|
||||
|
||||
sampleName = 'sample' if sample == 'true' else 'new'
|
||||
sampleName = 'sample' if sample == 'true' else 'new' # create sample or new template
|
||||
|
||||
filename = getCorrectName(f'{sampleName}{ext}', req)
|
||||
filename = getCorrectName(f'{sampleName}{ext}', req) # get file name with an index if such a file name already exists
|
||||
path = getStoragePath(filename, req)
|
||||
|
||||
with io.open(os.path.join('assets', 'sample' if sample == 'true' else 'new', f'{sampleName}{ext}'), 'rb') as stream:
|
||||
with io.open(os.path.join('assets', 'sample' if sample == 'true' else 'new', f'{sampleName}{ext}'), 'rb') as stream: # create sample file of the necessary extension in the directory
|
||||
createFile(stream, path, req, True)
|
||||
return filename
|
||||
|
||||
# remove file from the directory
|
||||
def removeFile(filename, req):
|
||||
path = getStoragePath(filename, req)
|
||||
if os.path.exists(path):
|
||||
os.remove(path)
|
||||
histDir = historyManager.getHistoryDir(path)
|
||||
if os.path.exists(histDir):
|
||||
histDir = historyManager.getHistoryDir(path) # get history directory
|
||||
if os.path.exists(histDir): # remove all the history information about this file
|
||||
shutil.rmtree(histDir)
|
||||
|
||||
# generate file key
|
||||
def generateFileKey(filename, req):
|
||||
path = getStoragePath(filename, req)
|
||||
uri = getFileUri(filename, False, req)
|
||||
stat = os.stat(path)
|
||||
stat = os.stat(path) # get the directory parameters
|
||||
|
||||
h = str(hash(f'{uri}_{stat.st_mtime_ns}'))
|
||||
h = str(hash(f'{uri}_{stat.st_mtime_ns}')) # get the hash value of the file url and the date of its last modification and turn it into a string format
|
||||
replaced = re.sub(r'[^0-9-.a-zA-Z_=]', '_', h)
|
||||
return replaced[:20]
|
||||
return replaced[:20] # take the first 20 characters for the key
|
||||
|
||||
# generate the document key value
|
||||
def generateRevisionId(expectedKey):
|
||||
if (len(expectedKey) > 20):
|
||||
expectedKey = str(hash(expectedKey))
|
||||
@ -248,14 +268,15 @@ def generateRevisionId(expectedKey):
|
||||
key = re.sub(r'[^0-9-.a-zA-Z_=]', '_', expectedKey)
|
||||
return key[:20]
|
||||
|
||||
# get files information
|
||||
def getFilesInfo(req):
|
||||
fileId = req.GET.get('fileId') if req.GET.get('fileId') else None
|
||||
|
||||
result = []
|
||||
resultID = []
|
||||
for f in getStoredFiles(req):
|
||||
stats = os.stat(os.path.join(getRootFolder(req), f.get("title")))
|
||||
result.append(
|
||||
for f in getStoredFiles(req): # run through all the files from the directory
|
||||
stats = os.stat(os.path.join(getRootFolder(req), f.get("title"))) # get file information
|
||||
result.append( # write file parameters to the file object
|
||||
{ "version" : historyManager.getFileVersion(historyManager.getHistoryDir(getStoragePath(f.get("title"), req))),
|
||||
"id" : generateFileKey(f.get("title"), req),
|
||||
"contentLength" : "%.2f KB" % (stats.st_size/1024),
|
||||
@ -263,9 +284,9 @@ def getFilesInfo(req):
|
||||
"title" : f.get("title"),
|
||||
"updated" : time.strftime("%Y-%m-%dT%X%z",time.gmtime(stats.st_mtime))
|
||||
})
|
||||
if fileId :
|
||||
if fileId == generateFileKey(f.get("title"), req) :
|
||||
resultID.append(result[-1])
|
||||
if fileId : # if file id is defined
|
||||
if fileId == generateFileKey(f.get("title"), req) : # and it is equal to the file key value
|
||||
resultID.append(result[-1]) # add file object to the response array
|
||||
|
||||
if fileId :
|
||||
if len(resultID) > 0 : return resultID
|
||||
@ -273,8 +294,9 @@ def getFilesInfo(req):
|
||||
else :
|
||||
return result
|
||||
|
||||
# download the file
|
||||
def download(filePath):
|
||||
response = FileResponse(open(filePath, 'rb'), True)
|
||||
response = FileResponse(open(filePath, 'rb'), True) # write headers to the response object
|
||||
response['Content-Length'] = os.path.getsize(filePath)
|
||||
response['Content-Disposition'] = "attachment;filename*=UTF-8\'\'" + urllib.parse.unquote(os.path.basename(filePath))
|
||||
response['Content-Type'] = magic.from_file(filePath, mime=True)
|
||||
|
||||
@ -26,20 +26,24 @@
|
||||
|
||||
import config
|
||||
|
||||
# get file name from the document url
|
||||
def getFileName(str):
|
||||
ind = str.rfind('/')
|
||||
return str[ind+1:]
|
||||
|
||||
# get file name without extension from the document url
|
||||
def getFileNameWithoutExt(str):
|
||||
fn = getFileName(str)
|
||||
ind = fn.rfind('.')
|
||||
return fn[:ind]
|
||||
|
||||
# get file extension from the document url
|
||||
def getFileExt(str):
|
||||
fn = getFileName(str)
|
||||
ind = fn.rfind('.')
|
||||
return fn[ind:].lower()
|
||||
|
||||
# get file type
|
||||
def getFileType(str):
|
||||
ext = getFileExt(str)
|
||||
if ext in config.EXT_DOCUMENT:
|
||||
@ -49,4 +53,4 @@ def getFileType(str):
|
||||
if ext in config.EXT_PRESENTATION:
|
||||
return 'slide'
|
||||
|
||||
return 'word'
|
||||
return 'word' # default file type is word
|
||||
@ -35,57 +35,67 @@ from src import settings
|
||||
from src.utils import docManager
|
||||
from src.utils import jwtManager
|
||||
|
||||
# get the path to the history direction
|
||||
def getHistoryDir(storagePath):
|
||||
return f'{storagePath}-hist'
|
||||
|
||||
# get the path to the given file version
|
||||
def getVersionDir(histDir, version):
|
||||
return os.path.join(histDir, str(version))
|
||||
|
||||
# get file version of the given history directory
|
||||
def getFileVersion(histDir):
|
||||
if not os.path.exists(histDir):
|
||||
return 0
|
||||
if not os.path.exists(histDir): # if the history directory doesn't exist
|
||||
return 0 # file version is 0
|
||||
|
||||
cnt = 1
|
||||
|
||||
for f in os.listdir(histDir):
|
||||
if not os.path.isfile(os.path.join(histDir, f)):
|
||||
for f in os.listdir(histDir): # run through all the files in the history directory
|
||||
if not os.path.isfile(os.path.join(histDir, f)): # and count the number of files
|
||||
cnt += 1
|
||||
|
||||
return cnt
|
||||
|
||||
# get the path to the next file version
|
||||
def getNextVersionDir(histDir):
|
||||
v = getFileVersion(histDir)
|
||||
path = getVersionDir(histDir, v)
|
||||
v = getFileVersion(histDir) # get file version of the given history directory
|
||||
path = getVersionDir(histDir, v) # get the path to the next file version
|
||||
|
||||
if not os.path.exists(path):
|
||||
os.makedirs(path)
|
||||
if not os.path.exists(path): # if this path doesn't exist
|
||||
os.makedirs(path) # make the directory for this file version
|
||||
return path
|
||||
|
||||
# get the path to a file archive with differences in the given file version
|
||||
def getChangesZipPath(verDir):
|
||||
return os.path.join(verDir, 'diff.zip')
|
||||
|
||||
# get the path to a json file with changes of the given file version
|
||||
def getChangesHistoryPath(verDir):
|
||||
return os.path.join(verDir, 'changes.json')
|
||||
|
||||
# get the path to the previous file version
|
||||
def getPrevFilePath(verDir, ext):
|
||||
return os.path.join(verDir, f'prev{ext}')
|
||||
|
||||
# get the path to a txt file with a key information in it
|
||||
def getKeyPath(verDir):
|
||||
return os.path.join(verDir, 'key.txt')
|
||||
|
||||
# get the path to a json file with meta data about this file
|
||||
def getMetaPath(histDir):
|
||||
return os.path.join(histDir, 'createdInfo.json')
|
||||
|
||||
# create a json file with file meta data using the storage path and request
|
||||
def createMeta(storagePath, req):
|
||||
histDir = getHistoryDir(storagePath)
|
||||
path = getMetaPath(histDir)
|
||||
path = getMetaPath(histDir) # get the path to a json file with meta data about file
|
||||
|
||||
if not os.path.exists(histDir):
|
||||
os.makedirs(histDir)
|
||||
|
||||
user = users.getUserFromReq(req)
|
||||
user = users.getUserFromReq(req) # get the user information (id and name)
|
||||
|
||||
obj = {
|
||||
obj = { # create the meta data object
|
||||
'created': datetime.today().strftime('%Y-%m-%d %H:%M:%S'),
|
||||
'uid': user['uid'],
|
||||
'uname': None if user['uid'] == 'uid-0' else user['uname']
|
||||
@ -95,14 +105,15 @@ def createMeta(storagePath, req):
|
||||
|
||||
return
|
||||
|
||||
# create a json file with file meta data using the file name, user id, user name and user address
|
||||
def createMetaData(filename, uid, uname, usAddr):
|
||||
histDir = getHistoryDir(docManager.getStoragePath(filename, usAddr))
|
||||
path = getMetaPath(histDir)
|
||||
path = getMetaPath(histDir) # get the path to a json file with meta data about file
|
||||
|
||||
if not os.path.exists(histDir):
|
||||
os.makedirs(histDir)
|
||||
|
||||
obj = {
|
||||
obj = { # create the meta data object
|
||||
'created': datetime.today().strftime('%Y-%m-%d %H:%M:%S'),
|
||||
'uid': uid,
|
||||
'uname': uname
|
||||
@ -112,93 +123,99 @@ def createMetaData(filename, uid, uname, usAddr):
|
||||
|
||||
return
|
||||
|
||||
# create file with a given content in it
|
||||
def writeFile(path, content):
|
||||
with io.open(path, 'w') as out:
|
||||
out.write(content)
|
||||
return
|
||||
|
||||
# read a file
|
||||
def readFile(path):
|
||||
with io.open(path, 'r') as stream:
|
||||
return stream.read()
|
||||
|
||||
# get the url to the previous file version with a given extension
|
||||
def getPrevUri(filename, ver, ext, req):
|
||||
host = docManager.getServerUrl(True, req)
|
||||
curAdr = req.META['REMOTE_ADDR']
|
||||
return f'{host}{settings.STATIC_URL}{curAdr}/{filename}-hist/{ver}/prev{ext}'
|
||||
|
||||
# get the url to a file archive with changes of the given file version
|
||||
def getZipUri(filename, ver, req):
|
||||
host = docManager.getServerUrl(True, req)
|
||||
curAdr = req.META['REMOTE_ADDR']
|
||||
return f'{host}{settings.STATIC_URL}{curAdr}/{filename}-hist/{ver}/diff.zip'
|
||||
|
||||
# get the meta data of the file
|
||||
def getMeta(storagePath):
|
||||
histDir = getHistoryDir(storagePath)
|
||||
path = getMetaPath(histDir)
|
||||
|
||||
if os.path.exists(path):
|
||||
if os.path.exists(path): # check if the json file with file meta data exists
|
||||
with io.open(path, 'r') as stream:
|
||||
return json.loads(stream.read())
|
||||
return json.loads(stream.read()) # turn meta data into python format
|
||||
|
||||
return None
|
||||
|
||||
# get the document history of a given file
|
||||
def getHistoryObject(storagePath, filename, docKey, docUrl, req):
|
||||
histDir = getHistoryDir(storagePath)
|
||||
version = getFileVersion(histDir)
|
||||
if version > 0:
|
||||
if version > 0: # if the file was modified (the file version is greater than 0)
|
||||
hist = []
|
||||
histData = {}
|
||||
|
||||
for i in range(1, version + 1):
|
||||
for i in range(1, version + 1): # run through all the file versions
|
||||
obj = {}
|
||||
dataObj = {}
|
||||
prevVerDir = getVersionDir(histDir, i - 1)
|
||||
verDir = getVersionDir(histDir, i)
|
||||
prevVerDir = getVersionDir(histDir, i - 1) # get the path to the previous file version
|
||||
verDir = getVersionDir(histDir, i) # get the path to the given file version
|
||||
|
||||
try:
|
||||
key = docKey if i == version else readFile(getKeyPath(verDir))
|
||||
key = docKey if i == version else readFile(getKeyPath(verDir)) # get document key
|
||||
|
||||
obj['key'] = key
|
||||
obj['version'] = i
|
||||
dataObj['key'] = key
|
||||
dataObj['version'] = i
|
||||
|
||||
if i == 1:
|
||||
meta = getMeta(storagePath)
|
||||
if meta:
|
||||
if i == 1: # check if the version number is equal to 1
|
||||
meta = getMeta(storagePath) # get meta data of this file
|
||||
if meta: # write meta information to the object (user information and creation date)
|
||||
obj['created'] = meta['created']
|
||||
obj['user'] = {
|
||||
'id': meta['uid'],
|
||||
'name': meta['uname']
|
||||
}
|
||||
|
||||
dataObj['url'] = docUrl if i == version else getPrevUri(filename, i, fileUtils.getFileExt(filename), req)
|
||||
dataObj['url'] = docUrl if i == version else getPrevUri(filename, i, fileUtils.getFileExt(filename), req) # write file url to the data object
|
||||
|
||||
if i > 1:
|
||||
changes = json.loads(readFile(getChangesHistoryPath(prevVerDir)))
|
||||
if i > 1: # check if the version number is greater than 1 (the file was modified)
|
||||
changes = json.loads(readFile(getChangesHistoryPath(prevVerDir))) # get the path to the changes.json file
|
||||
change = changes['changes'][0]
|
||||
|
||||
obj['changes'] = changes['changes']
|
||||
obj['changes'] = changes['changes'] # write information about changes to the object
|
||||
obj['serverVersion'] = changes['serverVersion']
|
||||
obj['created'] = change['created']
|
||||
obj['user'] = change['user']
|
||||
|
||||
prev = histData[str(i - 2)]
|
||||
prevInfo = {
|
||||
prev = histData[str(i - 2)] # get the history data from the previous file version
|
||||
prevInfo = { # write key and url information about previous file version
|
||||
'key': prev['key'],
|
||||
'url': prev['url']
|
||||
}
|
||||
dataObj['previous'] = prevInfo
|
||||
dataObj['changesUrl'] = getZipUri(filename, i - 1, req)
|
||||
dataObj['previous'] = prevInfo # write information about previous file version to the data object
|
||||
dataObj['changesUrl'] = getZipUri(filename, i - 1, req) # write the path to the diff.zip archive with differences in this file version
|
||||
|
||||
if jwtManager.isEnabled():
|
||||
dataObj['token'] = jwtManager.encode(dataObj)
|
||||
|
||||
hist.append(obj)
|
||||
histData[str(i - 1)] = dataObj
|
||||
hist.append(obj) # add object dictionary to the hist list
|
||||
histData[str(i - 1)] = dataObj # write data object information to the history data
|
||||
except Exception:
|
||||
return {}
|
||||
|
||||
histObj = {
|
||||
histObj = { # write history information about the current file version to the history object
|
||||
'currentVersion': version,
|
||||
'history': hist
|
||||
}
|
||||
|
||||
@ -27,11 +27,14 @@
|
||||
import config
|
||||
import jwt
|
||||
|
||||
# check if a secret key to generate token exists or not
|
||||
def isEnabled():
|
||||
return bool(config.DOC_SERV_JWT_SECRET)
|
||||
|
||||
# encode a payload object into a token using a secret key and decodes it into the utf-8 format
|
||||
def encode(payload):
|
||||
return jwt.encode(payload, config.DOC_SERV_JWT_SECRET, algorithm='HS256').decode('utf-8')
|
||||
|
||||
# decode a token into a payload object using a secret key
|
||||
def decode(string):
|
||||
return jwt.decode(string, config.DOC_SERV_JWT_SECRET, algorithms=['HS256'])
|
||||
@ -30,13 +30,14 @@ import config
|
||||
|
||||
from . import fileUtils, jwtManager
|
||||
|
||||
# convert file and give url to a new file
|
||||
def getConverterUri(docUri, fromExt, toExt, docKey, isAsync, filePass = None):
|
||||
if not fromExt:
|
||||
fromExt = fileUtils.getFileExt(docUri)
|
||||
if not fromExt: # check if the extension from the request matches the real file extension
|
||||
fromExt = fileUtils.getFileExt(docUri) # if not, overwrite the extension value
|
||||
|
||||
title = fileUtils.getFileName(docUri)
|
||||
|
||||
payload = {
|
||||
payload = { # write all the necessary data to the payload object
|
||||
'url': docUri,
|
||||
'outputtype': toExt.replace('.', ''),
|
||||
'filetype': fromExt.replace('.', ''),
|
||||
@ -47,20 +48,21 @@ def getConverterUri(docUri, fromExt, toExt, docKey, isAsync, filePass = None):
|
||||
|
||||
headers={'accept': 'application/json'}
|
||||
|
||||
if (isAsync):
|
||||
payload.setdefault('async', True)
|
||||
if (isAsync): # check if the operation is asynchronous
|
||||
payload.setdefault('async', True) # and write this information to the payload object
|
||||
|
||||
if jwtManager.isEnabled():
|
||||
jwtHeader = 'Authorization' if config.DOC_SERV_JWT_HEADER is None or config.DOC_SERV_JWT_HEADER == '' else config.DOC_SERV_JWT_HEADER
|
||||
headerToken = jwtManager.encode({'payload': payload})
|
||||
payload['token'] = jwtManager.encode(payload)
|
||||
headers[jwtHeader] = f'Bearer {headerToken}'
|
||||
if jwtManager.isEnabled(): # check if a secret key to generate token exists or not
|
||||
jwtHeader = 'Authorization' if config.DOC_SERV_JWT_HEADER is None or config.DOC_SERV_JWT_HEADER == '' else config.DOC_SERV_JWT_HEADER # get jwt header
|
||||
headerToken = jwtManager.encode({'payload': payload}) # encode a payload object into a header token
|
||||
payload['token'] = jwtManager.encode(payload) # encode a payload object into a body token
|
||||
headers[jwtHeader] = f'Bearer {headerToken}' # add a header Authorization with a header token with Authorization prefix in it
|
||||
|
||||
response = requests.post(config.DOC_SERV_SITE_URL + config.DOC_SERV_CONVERTER_URL, json=payload, headers=headers )
|
||||
response = requests.post(config.DOC_SERV_SITE_URL + config.DOC_SERV_CONVERTER_URL, json=payload, headers=headers ) # send the headers and body values to the converter and write the result to the response
|
||||
json = response.json()
|
||||
|
||||
return getResponseUri(json)
|
||||
|
||||
# get response url
|
||||
def getResponseUri(json):
|
||||
isEnd = json.get('endConvert')
|
||||
error = json.get('error')
|
||||
@ -70,6 +72,7 @@ def getResponseUri(json):
|
||||
if isEnd:
|
||||
return json.get('fileUrl')
|
||||
|
||||
# display an error that occurs during conversion
|
||||
def processError(error):
|
||||
prefix = 'Error occurred in the ConvertService: '
|
||||
|
||||
|
||||
@ -31,80 +31,85 @@ import os
|
||||
import json
|
||||
from . import jwtManager, docManager, historyManager, fileUtils, serviceConverter
|
||||
|
||||
# read request body
|
||||
def readBody(request):
|
||||
body = json.loads(request.body)
|
||||
if (jwtManager.isEnabled()):
|
||||
token = body.get('token')
|
||||
if (jwtManager.isEnabled()): # if the secret key to generate token exists
|
||||
token = body.get('token') # get the document token
|
||||
|
||||
if (not token):
|
||||
if (not token): # if JSON web token is not received
|
||||
jwtHeader = 'Authorization' if config.DOC_SERV_JWT_HEADER is None or config.DOC_SERV_JWT_HEADER == '' else config.DOC_SERV_JWT_HEADER
|
||||
token = request.headers.get(jwtHeader)
|
||||
token = request.headers.get(jwtHeader) # get it from the Authorization header
|
||||
if token:
|
||||
token = token[len('Bearer '):]
|
||||
token = token[len('Bearer '):] # and save it without Authorization prefix
|
||||
|
||||
if (not token):
|
||||
raise Exception('Expected JWT')
|
||||
if (not token): # if the token is not received
|
||||
raise Exception('Expected JWT') # an error occurs
|
||||
|
||||
body = jwtManager.decode(token)
|
||||
if (body.get('payload')):
|
||||
if (body.get('payload')): # get the payload object from the request body
|
||||
body = body['payload']
|
||||
return body
|
||||
|
||||
# file saving process
|
||||
def processSave(body, filename, usAddr):
|
||||
download = body.get('url')
|
||||
changesUri = body.get('changesurl')
|
||||
newFilename = filename
|
||||
|
||||
curExt = fileUtils.getFileExt(filename)
|
||||
downloadExt = fileUtils.getFileExt(download)
|
||||
curExt = fileUtils.getFileExt(filename) # get current file extension
|
||||
downloadExt = fileUtils.getFileExt(download) # get the extension of the downloaded file
|
||||
|
||||
# convert downloaded file to the file with the current extension if these extensions aren't equal
|
||||
if (curExt != downloadExt):
|
||||
try:
|
||||
newUri = serviceConverter.getConverterUri(download, downloadExt, curExt, docManager.generateRevisionId(download), False)
|
||||
newUri = serviceConverter.getConverterUri(download, downloadExt, curExt, docManager.generateRevisionId(download), False) # convert file and give url to a new file
|
||||
if not newUri:
|
||||
newFilename = docManager.getCorrectName(fileUtils.getFileNameWithoutExt(filename) + downloadExt, usAddr)
|
||||
newFilename = docManager.getCorrectName(fileUtils.getFileNameWithoutExt(filename) + downloadExt, usAddr) # get the correct file name if it already exists
|
||||
else:
|
||||
download = newUri
|
||||
except Exception:
|
||||
newFilename = docManager.getCorrectName(fileUtils.getFileNameWithoutExt(filename) + downloadExt, usAddr)
|
||||
|
||||
path = docManager.getStoragePath(newFilename, usAddr)
|
||||
path = docManager.getStoragePath(newFilename, usAddr) # get the file path
|
||||
|
||||
histDir = historyManager.getHistoryDir(path)
|
||||
if not os.path.exists(histDir):
|
||||
os.makedirs(histDir)
|
||||
histDir = historyManager.getHistoryDir(path) # get the path to the history direction
|
||||
if not os.path.exists(histDir): # if the path doesn't exist
|
||||
os.makedirs(histDir) # create it
|
||||
|
||||
versionDir = historyManager.getNextVersionDir(histDir)
|
||||
versionDir = historyManager.getNextVersionDir(histDir) # get the path to the next file version
|
||||
|
||||
os.rename(docManager.getStoragePath(filename, usAddr), historyManager.getPrevFilePath(versionDir, curExt))
|
||||
docManager.saveFileFromUri(download, path)
|
||||
docManager.saveFileFromUri(changesUri, historyManager.getChangesZipPath(versionDir))
|
||||
os.rename(docManager.getStoragePath(filename, usAddr), historyManager.getPrevFilePath(versionDir, curExt)) # get the path to the previous file version and rename the storage path with it
|
||||
docManager.saveFileFromUri(download, path) # save file to the storage path
|
||||
docManager.saveFileFromUri(changesUri, historyManager.getChangesZipPath(versionDir)) # save file changes to the diff.zip archive
|
||||
|
||||
hist = None
|
||||
hist = body.get('changeshistory')
|
||||
if (not hist) & ('history' in body):
|
||||
hist = json.dumps(body.get('history'))
|
||||
if hist:
|
||||
historyManager.writeFile(historyManager.getChangesHistoryPath(versionDir), hist)
|
||||
historyManager.writeFile(historyManager.getChangesHistoryPath(versionDir), hist) # write the history changes to the changes.json file
|
||||
|
||||
historyManager.writeFile(historyManager.getKeyPath(versionDir), body.get('key'))
|
||||
historyManager.writeFile(historyManager.getKeyPath(versionDir), body.get('key')) # write the key value to the key.txt file
|
||||
|
||||
forcesavePath = docManager.getForcesavePath(newFilename, usAddr, False)
|
||||
if (forcesavePath != ""):
|
||||
os.remove(forcesavePath)
|
||||
forcesavePath = docManager.getForcesavePath(newFilename, usAddr, False) # get the path to the forcesaved file version
|
||||
if (forcesavePath != ""): # if the forcesaved file version exists
|
||||
os.remove(forcesavePath) # remove it
|
||||
|
||||
return
|
||||
|
||||
# file force saving process
|
||||
def processForceSave(body, filename, usAddr):
|
||||
download = body.get('url')
|
||||
|
||||
curExt = fileUtils.getFileExt(filename)
|
||||
downloadExt = fileUtils.getFileExt(download)
|
||||
curExt = fileUtils.getFileExt(filename) # get current file extension
|
||||
downloadExt = fileUtils.getFileExt(download) # get the extension of the downloaded file
|
||||
newFilename = False
|
||||
|
||||
# convert downloaded file to the file with the current extension if these extensions aren't equal
|
||||
if (curExt != downloadExt):
|
||||
try:
|
||||
newUri = serviceConverter.getConverterUri(download, downloadExt, curExt, docManager.generateRevisionId(download), False)
|
||||
newUri = serviceConverter.getConverterUri(download, downloadExt, curExt, docManager.generateRevisionId(download), False) # convert file and give url to a new file
|
||||
if not newUri:
|
||||
newFilename = True
|
||||
else:
|
||||
@ -112,11 +117,11 @@ def processForceSave(body, filename, usAddr):
|
||||
except Exception:
|
||||
newFilename = True
|
||||
|
||||
isSubmitForm = body.get('forcesavetype') == 3
|
||||
isSubmitForm = body.get('forcesavetype') == 3 # SubmitForm
|
||||
|
||||
if(isSubmitForm):
|
||||
if (newFilename):
|
||||
filename = docManager.getCorrectName(fileUtils.getFileNameWithoutExt(filename) + "-form" + downloadExt, usAddr)
|
||||
filename = docManager.getCorrectName(fileUtils.getFileNameWithoutExt(filename) + "-form" + downloadExt, usAddr) # get the correct file name if it already exists
|
||||
else :
|
||||
filename = docManager.getCorrectName(fileUtils.getFileNameWithoutExt(filename) + "-form" + curExt, usAddr)
|
||||
forcesavePath = docManager.getStoragePath(filename, usAddr)
|
||||
@ -130,10 +135,11 @@ def processForceSave(body, filename, usAddr):
|
||||
docManager.saveFileFromUri(download, forcesavePath)
|
||||
|
||||
if(isSubmitForm):
|
||||
uid = body['actions'][0]['userid']
|
||||
historyManager.createMetaData(filename, uid, "Filling Form", usAddr)
|
||||
uid = body['actions'][0]['userid'] # get the user id
|
||||
historyManager.createMetaData(filename, uid, "Filling Form", usAddr) # create meta data for forcesaved file
|
||||
return
|
||||
|
||||
# create a command request
|
||||
def commandRequest(method, key):
|
||||
documentCommandUrl = config.DOC_SERV_SITE_URL + config.DOC_SERV_COMMAND_URL
|
||||
|
||||
@ -144,12 +150,12 @@ def commandRequest(method, key):
|
||||
|
||||
headers={'accept': 'application/json'}
|
||||
|
||||
if jwtManager.isEnabled():
|
||||
jwtHeader = 'Authorization' if config.DOC_SERV_JWT_HEADER is None or config.DOC_SERV_JWT_HEADER == '' else config.DOC_SERV_JWT_HEADER
|
||||
headerToken = jwtManager.encode({'payload': payload})
|
||||
headers[jwtHeader] = f'Bearer {headerToken}'
|
||||
if jwtManager.isEnabled(): # check if a secret key to generate token exists or not
|
||||
jwtHeader = 'Authorization' if config.DOC_SERV_JWT_HEADER is None or config.DOC_SERV_JWT_HEADER == '' else config.DOC_SERV_JWT_HEADER # get jwt header
|
||||
headerToken = jwtManager.encode({'payload': payload}) # encode a payload object into a header token
|
||||
headers[jwtHeader] = f'Bearer {headerToken}' # add a header Authorization with a header token with Authorization prefix in it
|
||||
|
||||
payload['token'] = jwtManager.encode(payload)
|
||||
payload['token'] = jwtManager.encode(payload) # encode a payload object into a body token
|
||||
|
||||
response = requests.post(documentCommandUrl, json=payload, headers=headers)
|
||||
|
||||
|
||||
@ -47,11 +47,12 @@ USERS = [
|
||||
|
||||
DEFAULT_USER = USERS[0]
|
||||
|
||||
# get user information from the request
|
||||
def getUserFromReq(req):
|
||||
uid = req.COOKIES.get('uid')
|
||||
uname = req.COOKIES.get('uname')
|
||||
|
||||
if (not uid) | (not uname):
|
||||
return DEFAULT_USER
|
||||
if (not uid) | (not uname): # check if we got both the user id and name parameters
|
||||
return DEFAULT_USER # if not, return default user values
|
||||
else:
|
||||
return { 'uid': unquote(uid), 'uname': unquote(uname) }
|
||||
@ -36,31 +36,33 @@ from django.shortcuts import render
|
||||
from src.utils import docManager, fileUtils, serviceConverter, users, jwtManager, historyManager, trackManager
|
||||
|
||||
|
||||
# upload a file from the document storage service to the document editing service
|
||||
def upload(request):
|
||||
response = {}
|
||||
|
||||
try:
|
||||
fileInfo = request.FILES['uploadedFile']
|
||||
if ((fileInfo.size > config.FILE_SIZE_MAX) | (fileInfo.size <= 0)):
|
||||
if ((fileInfo.size > config.FILE_SIZE_MAX) | (fileInfo.size <= 0)): # check if the file size exceeds the maximum size allowed (5242880)
|
||||
raise Exception('File size is incorrect')
|
||||
|
||||
curExt = fileUtils.getFileExt(fileInfo.name)
|
||||
if not docManager.isSupportedExt(curExt):
|
||||
if not docManager.isSupportedExt(curExt): # check if the file extension is supported by the document manager
|
||||
raise Exception('File type is not supported')
|
||||
|
||||
name = docManager.getCorrectName(fileInfo.name, request)
|
||||
name = docManager.getCorrectName(fileInfo.name, request) # get file name with an index if such a file name already exists
|
||||
path = docManager.getStoragePath(name, request)
|
||||
|
||||
docManager.createFile(fileInfo.file, path, request, True)
|
||||
docManager.createFile(fileInfo.file, path, request, True) # create file with meta information in the storage directory
|
||||
|
||||
response.setdefault('filename', name)
|
||||
response.setdefault('documentType', fileUtils.getFileType(name))
|
||||
|
||||
except Exception as e:
|
||||
response.setdefault('error', e.args[0])
|
||||
except Exception as e: # if an error occurs
|
||||
response.setdefault('error', e.args[0]) # save an error message to the response variable
|
||||
|
||||
return HttpResponse(json.dumps(response), content_type='application/json')
|
||||
return HttpResponse(json.dumps(response), content_type='application/json') # return http response in json format
|
||||
|
||||
# convert a file from one format to another
|
||||
def convert(request):
|
||||
response = {}
|
||||
|
||||
@ -71,30 +73,31 @@ def convert(request):
|
||||
fileUri = docManager.getFileUri(filename, True,request)
|
||||
fileExt = fileUtils.getFileExt(filename)
|
||||
fileType = fileUtils.getFileType(filename)
|
||||
newExt = docManager.getInternalExtension(fileType)
|
||||
newExt = docManager.getInternalExtension(fileType) # internal editor extensions: .docx, .xlsx or .pptx
|
||||
|
||||
if docManager.isCanConvert(fileExt):
|
||||
key = docManager.generateFileKey(filename, request)
|
||||
if docManager.isCanConvert(fileExt): # check if the file extension is available for converting
|
||||
key = docManager.generateFileKey(filename, request) # generate the file key
|
||||
|
||||
newUri = serviceConverter.getConverterUri(fileUri, fileExt, newExt, key, True, filePass)
|
||||
newUri = serviceConverter.getConverterUri(fileUri, fileExt, newExt, key, True, filePass) # get the url of the converted file
|
||||
|
||||
if not newUri:
|
||||
if not newUri: # if the converter url is not received, the original file name is passed to the response
|
||||
response.setdefault('step', '0')
|
||||
response.setdefault('filename', filename)
|
||||
else:
|
||||
correctName = docManager.getCorrectName(fileUtils.getFileNameWithoutExt(filename) + newExt, request)
|
||||
correctName = docManager.getCorrectName(fileUtils.getFileNameWithoutExt(filename) + newExt, request) # otherwise, create a new name with the necessary extension
|
||||
path = docManager.getStoragePath(correctName, request)
|
||||
docManager.saveFileFromUri(newUri, path, request, True)
|
||||
docManager.removeFile(filename, request)
|
||||
response.setdefault('filename', correctName)
|
||||
docManager.saveFileFromUri(newUri, path, request, True) # save the file from the new url in the storage directory
|
||||
docManager.removeFile(filename, request) # remove the original file
|
||||
response.setdefault('filename', correctName) # pass the name of the converted file to the response
|
||||
else:
|
||||
response.setdefault('filename', filename)
|
||||
response.setdefault('filename', filename) # if the file can't be converted, the original file name is passed to the response
|
||||
|
||||
except Exception as e:
|
||||
response.setdefault('error', e.args[0])
|
||||
|
||||
return HttpResponse(json.dumps(response), content_type='application/json')
|
||||
|
||||
# create a new file
|
||||
def createNew(request):
|
||||
response = {}
|
||||
|
||||
@ -102,15 +105,16 @@ def createNew(request):
|
||||
fileType = request.GET['fileType']
|
||||
sample = request.GET.get('sample', False)
|
||||
|
||||
filename = docManager.createSample(fileType, sample, request)
|
||||
filename = docManager.createSample(fileType, sample, request) # create a new sample file of the necessary type
|
||||
|
||||
return HttpResponseRedirect(f'edit?filename={filename}')
|
||||
return HttpResponseRedirect(f'edit?filename={filename}') # return http response with redirection url
|
||||
|
||||
except Exception as e:
|
||||
response.setdefault('error', e.args[0])
|
||||
|
||||
return HttpResponse(json.dumps(response), content_type='application/json')
|
||||
|
||||
# edit a file
|
||||
def edit(request):
|
||||
filename = fileUtils.getFileName(request.GET['filename'])
|
||||
|
||||
@ -120,7 +124,7 @@ def edit(request):
|
||||
fileUriUser = docManager.getFileUri(filename, False, request)
|
||||
docKey = docManager.generateFileKey(filename, request)
|
||||
fileType = fileUtils.getFileType(filename)
|
||||
user = users.getUserFromReq(request)
|
||||
user = users.getUserFromReq(request) # get user id and name
|
||||
userGroup = None
|
||||
reviewGroups = None
|
||||
if (user['uid'] == 'uid-2'):
|
||||
@ -130,32 +134,33 @@ def edit(request):
|
||||
userGroup = 'group-3'
|
||||
reviewGroups = ['group-2']
|
||||
|
||||
edMode = request.GET.get('mode') if request.GET.get('mode') else 'edit'
|
||||
canEdit = docManager.isCanEdit(ext)
|
||||
submitForm = canEdit & ((edMode == 'edit') | (edMode == 'fillForms'))
|
||||
mode = 'edit' if canEdit & (edMode != 'view') else 'view'
|
||||
edMode = request.GET.get('mode') if request.GET.get('mode') else 'edit' # get the editor mode: view/edit/review/comment/fillForms/embedded (the default mode is edit)
|
||||
canEdit = docManager.isCanEdit(ext) # check if the file with this extension can be edited
|
||||
submitForm = canEdit & ((edMode == 'edit') | (edMode == 'fillForms')) # if the Submit form button is displayed or hidden
|
||||
mode = 'edit' if canEdit & (edMode != 'view') else 'view' # if the file can't be edited, the mode is view
|
||||
|
||||
edType = request.GET.get('type') if request.GET.get('type') else 'desktop'
|
||||
lang = request.COOKIES.get('ulang') if request.COOKIES.get('ulang') else 'en'
|
||||
edType = request.GET.get('type') if request.GET.get('type') else 'desktop' # get the editor type: embedded/mobile/desktop (the default type is desktop)
|
||||
lang = request.COOKIES.get('ulang') if request.COOKIES.get('ulang') else 'en' # get the editor language (the default language is English)
|
||||
|
||||
storagePath = docManager.getStoragePath(filename, request)
|
||||
meta = historyManager.getMeta(storagePath)
|
||||
meta = historyManager.getMeta(storagePath) # get the document meta data
|
||||
infObj = None
|
||||
|
||||
actionData = request.GET.get('actionLink')
|
||||
actionData = request.GET.get('actionLink') # get the action data that will be scrolled to (comment or bookmark)
|
||||
actionLink = json.loads(actionData) if actionData else None
|
||||
|
||||
if (meta):
|
||||
infObj = {
|
||||
if (meta): # if the document meta data exists,
|
||||
infObj = { # write author and creation time parameters to the information object
|
||||
'owner': meta['uname'],
|
||||
'uploaded': meta['created']
|
||||
}
|
||||
else:
|
||||
else: # otherwise, write current meta information to this object
|
||||
infObj = {
|
||||
'owner': 'Me',
|
||||
'uploaded': datetime.today().strftime('%d.%m.%Y %H:%M:%S')
|
||||
}
|
||||
infObj['favorite'] = request.COOKIES.get('uid') == 'uid-2' if request.COOKIES.get('uid') else None
|
||||
# specify the document config
|
||||
edConfig = {
|
||||
'type': edType,
|
||||
'documentType': fileType,
|
||||
@ -165,10 +170,12 @@ def edit(request):
|
||||
'fileType': ext[1:],
|
||||
'key': docKey,
|
||||
'info': infObj,
|
||||
'permissions': {
|
||||
'permissions': { # the permission for the document to be edited and downloaded or not
|
||||
'comment': (edMode != 'view') & (edMode != 'fillForms') & (edMode != 'embedded') & (edMode != "blockcontent"),
|
||||
'download': True,
|
||||
'copy': False if user['uid'] == 'uid-2' else True,
|
||||
'download': False if user['uid'] == 'uid-2' else True,
|
||||
'edit': canEdit & ((edMode == 'edit') | (edMode == 'view') | (edMode == 'filter') | (edMode == "blockcontent")),
|
||||
'print': False if user['uid'] == 'uid-2' else True,
|
||||
'fillForms': (edMode != 'view') & (edMode != 'comment') & (edMode != 'embedded') & (edMode != "blockcontent"),
|
||||
'modifyFilter': edMode != 'filter',
|
||||
'modifyContentControl': edMode != "blockcontent",
|
||||
@ -180,94 +187,100 @@ def edit(request):
|
||||
'actionLink': actionLink,
|
||||
'mode': mode,
|
||||
'lang': lang,
|
||||
'callbackUrl': docManager.getCallbackUrl(filename, request),
|
||||
'callbackUrl': docManager.getCallbackUrl(filename, request), # absolute URL to the document storage service
|
||||
'createUrl': docManager.getCreateUrl(edType, request),
|
||||
'user': {
|
||||
'user': { # the user currently viewing or editing the document
|
||||
'id': user['uid'],
|
||||
'name': None if user['uid'] == 'uid-0' else user['uname'],
|
||||
'group': userGroup
|
||||
},
|
||||
'embedded': {
|
||||
'saveUrl': fileUriUser,
|
||||
'embedUrl': fileUriUser,
|
||||
'shareUrl': fileUriUser,
|
||||
'toolbarDocked': 'top'
|
||||
'embedded': { # the parameters for the embedded document type
|
||||
'saveUrl': fileUriUser, # the absolute URL that will allow the document to be saved onto the user personal computer
|
||||
'embedUrl': fileUriUser, # the absolute URL to the document serving as a source file for the document embedded into the web page
|
||||
'shareUrl': fileUriUser, # the absolute URL that will allow other users to share this document
|
||||
'toolbarDocked': 'top' # the place for the embedded viewer toolbar (top or bottom)
|
||||
},
|
||||
'customization': {
|
||||
'about': True,
|
||||
'feedback': True,
|
||||
'forcesave': False,
|
||||
'submitForm': submitForm,
|
||||
'goback': {
|
||||
'url': docManager.getServerUrl(False, request)
|
||||
'customization': { # the parameters for the editor interface
|
||||
'about': True, # the About section display
|
||||
'feedback': True, # the Feedback & Support menu button display
|
||||
'forcesave': False, # adds the request for the forced file saving to the callback handler
|
||||
'submitForm': submitForm, # if the Submit form button is displayed or not
|
||||
'goback': { # settings for the Open file location menu button and upper right corner button
|
||||
'url': docManager.getServerUrl(False, request) # the absolute URL to the website address which will be opened when clicking the Open file location menu button
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# an image which will be inserted into the document
|
||||
dataInsertImage = {
|
||||
'fileType': 'png',
|
||||
'url': docManager.getServerUrl(True, request) + 'static/images/logo.png'
|
||||
}
|
||||
|
||||
# a document which will be compared with the current document
|
||||
dataCompareFile = {
|
||||
'fileType': 'docx',
|
||||
'url': docManager.getServerUrl(True, request) + 'static/sample.docx'
|
||||
}
|
||||
|
||||
# recipient data for mail merging
|
||||
dataMailMergeRecipients = {
|
||||
'fileType': 'csv',
|
||||
'url': docManager.getServerUrl(True, request) + 'csv'
|
||||
}
|
||||
|
||||
if jwtManager.isEnabled():
|
||||
edConfig['token'] = jwtManager.encode(edConfig)
|
||||
dataInsertImage['token'] = jwtManager.encode(dataInsertImage)
|
||||
dataCompareFile['token'] = jwtManager.encode(dataCompareFile)
|
||||
dataMailMergeRecipients['token'] = jwtManager.encode(dataMailMergeRecipients)
|
||||
if jwtManager.isEnabled(): # if the secret key to generate token exists
|
||||
edConfig['token'] = jwtManager.encode(edConfig) # encode the edConfig object into a token
|
||||
dataInsertImage['token'] = jwtManager.encode(dataInsertImage) # encode the dataInsertImage object into a token
|
||||
dataCompareFile['token'] = jwtManager.encode(dataCompareFile) # encode the dataCompareFile object into a token
|
||||
dataMailMergeRecipients['token'] = jwtManager.encode(dataMailMergeRecipients) # encode the dataMailMergeRecipients object into a token
|
||||
|
||||
hist = historyManager.getHistoryObject(storagePath, filename, docKey, fileUri, request)
|
||||
hist = historyManager.getHistoryObject(storagePath, filename, docKey, fileUri, request) # get the document history
|
||||
|
||||
context = {
|
||||
'cfg': json.dumps(edConfig),
|
||||
'history': json.dumps(hist['history']) if 'history' in hist else None,
|
||||
'historyData': json.dumps(hist['historyData']) if 'historyData' in hist else None,
|
||||
'fileType': fileType,
|
||||
'apiUrl': config.DOC_SERV_SITE_URL + config.DOC_SERV_API_URL,
|
||||
'dataInsertImage': json.dumps(dataInsertImage)[1 : len(json.dumps(dataInsertImage)) - 1],
|
||||
'dataCompareFile': dataCompareFile,
|
||||
'dataMailMergeRecipients': json.dumps(dataMailMergeRecipients)
|
||||
context = { # the data that will be passed to the template
|
||||
'cfg': json.dumps(edConfig), # the document config in json format
|
||||
'history': json.dumps(hist['history']) if 'history' in hist else None, # the information about the current version
|
||||
'historyData': json.dumps(hist['historyData']) if 'historyData' in hist else None, # the information about the previous document versions if they exist
|
||||
'fileType': fileType, # the file type of the document (text, spreadsheet or presentation)
|
||||
'apiUrl': config.DOC_SERV_SITE_URL + config.DOC_SERV_API_URL, # the absolute URL to the api
|
||||
'dataInsertImage': json.dumps(dataInsertImage)[1 : len(json.dumps(dataInsertImage)) - 1], # the image which will be inserted into the document
|
||||
'dataCompareFile': dataCompareFile, # document which will be compared with the current document
|
||||
'dataMailMergeRecipients': json.dumps(dataMailMergeRecipients) # recipient data for mail merging
|
||||
}
|
||||
return render(request, 'editor.html', context)
|
||||
return render(request, 'editor.html', context) # execute the "editor.html" template with context data
|
||||
|
||||
# track the document changes
|
||||
def track(request):
|
||||
response = {}
|
||||
|
||||
try:
|
||||
body = trackManager.readBody(request)
|
||||
status = body['status']
|
||||
body = trackManager.readBody(request) # read request body
|
||||
status = body['status'] # and get status from it
|
||||
|
||||
if (status == 1): # Editing
|
||||
if (body['actions'] and body['actions'][0]['type'] == 0):# finished edit
|
||||
user = body['actions'][0]['userid']
|
||||
if (status == 1): # editing
|
||||
if (body['actions'] and body['actions'][0]['type'] == 0): # finished edit
|
||||
user = body['actions'][0]['userid'] # the user who finished editing
|
||||
if (not user in body['users']):
|
||||
trackManager.commandRequest('forcesave', body['key'])
|
||||
trackManager.commandRequest('forcesave', body['key']) # create a command request with the forcasave method
|
||||
|
||||
filename = fileUtils.getFileName(request.GET['filename'])
|
||||
usAddr = request.GET['userAddress']
|
||||
|
||||
if (status == 2) | (status == 3): # mustsave, corrupted
|
||||
if (status == 2) | (status == 3): # mustsave, corrupted
|
||||
trackManager.processSave(body, filename, usAddr)
|
||||
if (status == 6) | (status == 7): # mustforcesave, corruptedforcesave
|
||||
if (status == 6) | (status == 7): # mustforcesave, corruptedforcesave
|
||||
trackManager.processForceSave(body, filename, usAddr)
|
||||
|
||||
except Exception as e:
|
||||
response.setdefault('error', 1)
|
||||
response.setdefault('error', 1) # set the default error value as 1 (document key is missing or no document with such key could be found)
|
||||
response.setdefault('message', e.args[0])
|
||||
|
||||
response.setdefault('error', 0)
|
||||
response.setdefault('error', 0) # if no exceptions are raised, the default error value is 0 (no errors)
|
||||
# the response status is 200 if the changes are saved successfully; otherwise, it is equal to 500
|
||||
return HttpResponse(json.dumps(response), content_type='application/json', status=200 if response['error'] == 0 else 500)
|
||||
|
||||
# remove a file
|
||||
def remove(request):
|
||||
filename = fileUtils.getFileName(request.GET['filename'])
|
||||
|
||||
@ -278,6 +291,7 @@ def remove(request):
|
||||
response.setdefault('success', True)
|
||||
return HttpResponse(json.dumps(response), content_type='application/json')
|
||||
|
||||
# get file information
|
||||
def files(request):
|
||||
try:
|
||||
response = docManager.getFilesInfo(request)
|
||||
@ -286,14 +300,16 @@ def files(request):
|
||||
response.setdefault('error', e.args[0])
|
||||
return HttpResponse(json.dumps(response), content_type='application/json')
|
||||
|
||||
# download a csv file
|
||||
def csv(request):
|
||||
filePath = os.path.join('assets', 'sample', "csv.csv")
|
||||
response = docManager.download(filePath)
|
||||
return response
|
||||
|
||||
# download a file
|
||||
def download(request):
|
||||
try:
|
||||
fileName = fileUtils.getFileName(request.GET['fileName'])
|
||||
fileName = fileUtils.getFileName(request.GET['fileName']) # get the file name
|
||||
userAddress = request.GET.get('userAddress') if request.GET.get('userAddress') else request
|
||||
|
||||
if (jwtManager.isEnabled()):
|
||||
@ -306,10 +322,10 @@ def download(request):
|
||||
except Exception:
|
||||
return HttpResponse('JWT validation failed', status=403)
|
||||
|
||||
filePath = docManager.getForcesavePath(fileName, userAddress, False)
|
||||
filePath = docManager.getForcesavePath(fileName, userAddress, False) # get the path to the forcesaved file version
|
||||
if (filePath == ""):
|
||||
filePath = docManager.getStoragePath(fileName, userAddress)
|
||||
response = docManager.download(filePath)
|
||||
filePath = docManager.getStoragePath(fileName, userAddress) # get file from the storage directory
|
||||
response = docManager.download(filePath) # download this file
|
||||
return response
|
||||
except Exception:
|
||||
response = {}
|
||||
|
||||
@ -32,13 +32,13 @@ from django.shortcuts import render
|
||||
from src.utils import users
|
||||
from src.utils import docManager
|
||||
|
||||
def default(request):
|
||||
def default(request): # default parameters that will be passed to the template
|
||||
context = {
|
||||
'users': users.USERS,
|
||||
'languages': docManager.LANGUAGES,
|
||||
'preloadurl': config.DOC_SERV_SITE_URL + config.DOC_SERV_PRELOADER_URL,
|
||||
'editExt': json.dumps(config.DOC_SERV_EDITED),
|
||||
'convExt': json.dumps(config.DOC_SERV_CONVERT),
|
||||
'files': docManager.getStoredFiles(request)
|
||||
'editExt': json.dumps(config.DOC_SERV_EDITED), # file extensions that can be edited
|
||||
'convExt': json.dumps(config.DOC_SERV_CONVERT), # file extensions that can be converted
|
||||
'files': docManager.getStoredFiles(request) # information about stored files
|
||||
}
|
||||
return render(request, 'index.html', context)
|
||||
return render(request, 'index.html', context) # execute the "index.html" template with context data and return http response in json format
|
||||
Reference in New Issue
Block a user