1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-19 01:44:13 +00:00

revision url (#5558)

* revision url

* update revision_id
This commit is contained in:
欢乐马
2023-07-24 10:47:12 +08:00
committed by GitHub
parent 6ce5fbbdef
commit c31334d657
13 changed files with 215 additions and 25 deletions

View File

@@ -199,6 +199,9 @@ class DirentGridItem extends React.Component {
dirHref = siteRoot + 'library/' + this.props.repoID + '/' + this.props.currentRepoInfo.repo_name + Utils.encodePath(direntPath);
}
let fileHref = siteRoot + 'lib/' + this.props.repoID + '/file' + Utils.encodePath(direntPath);
if (dirent.is_sdoc_revision && dirent.revision_id) {
fileHref = siteRoot + 'lib/' + this.props.repoID + '/revisions/' + dirent.revision_id + '/';
}
let gridClass = 'grid-file-img-link cursor-pointer';
gridClass += this.state.isGridSelected ? ' grid-selected-active' : ' ';

View File

@@ -673,6 +673,9 @@ class DirentListItem extends React.Component {
dirHref = siteRoot + 'library/' + this.props.repoID + '/' + this.props.currentRepoInfo.repo_name + Utils.encodePath(direntPath);
}
let fileHref = siteRoot + 'lib/' + this.props.repoID + '/file' + Utils.encodePath(direntPath);
if (dirent.is_sdoc_revision && dirent.revision_id) {
fileHref = siteRoot + 'lib/' + this.props.repoID + '/revisions/' + dirent.revision_id + '/';
}
let toolTipID = '';
let tagTitle = '';

View File

@@ -39,6 +39,8 @@ class Dirent {
}
if (Utils.isSdocFile(json.name)) {
this.is_sdoc_draft = json.is_sdoc_draft || false;
this.is_sdoc_revision = json.is_sdoc_revision || false;
this.revision_id = json.revision_id || null;
}
}
}

View File

@@ -1264,7 +1264,10 @@ class LibContentView extends React.Component {
if (this.state.currentMode === 'column' && Utils.isMarkdownFile(direntPath)) {
this.showColumnMarkdownFile(direntPath);
} else {
const url = siteRoot + 'lib/' + repoID + '/file' + Utils.encodePath(direntPath);
let url = siteRoot + 'lib/' + repoID + '/file' + Utils.encodePath(direntPath);
if (dirent.is_sdoc_revision && dirent.revision_id) {
url = siteRoot + 'lib/' + repoID + '/revisions/' + dirent.revision_id + '/';
}
let isWeChat = Utils.isWeChat();
if (!isWeChat) {
@@ -1633,7 +1636,11 @@ class LibContentView extends React.Component {
this.showColumnMarkdownFile(node.path);
}
} else {
const url = siteRoot + 'lib/' + repoID + '/file' + Utils.encodePath(node.path);
let url = siteRoot + 'lib/' + repoID + '/file' + Utils.encodePath(node.path);
let dirent = node.object;
if (dirent.is_sdoc_revision && dirent.revision_id) {
url = siteRoot + 'lib/' + repoID + '/revisions/' + dirent.revision_id + '/';
}
window.open(url);
}
}

View File

@@ -107,12 +107,14 @@ def get_dir_file_info_list(username, request_type, repo_obj, parent_dir,
try:
from seahub.tags.models import FileUUIDMap
from seahub.seadoc.models import SeadocDraft
from seahub.seadoc.models import SeadocDraft, SeadocRevision
file_uuid_queryset = FileUUIDMap.objects.get_fileuuidmaps_by_parent_path(
repo_id, parent_dir)
file_uuid_list = [item.uuid for item in file_uuid_queryset]
seadoc_draft_queryset = SeadocDraft.objects.list_by_doc_uuids(
file_uuid_list)
seadoc_revision_queryset = SeadocRevision.objects.list_by_doc_uuids(
file_uuid_list)
except Exception as e:
logger.error(e)
@@ -197,6 +199,13 @@ def get_dir_file_info_list(username, request_type, repo_obj, parent_dir,
file_info['is_sdoc_draft'] = True
else:
file_info['is_sdoc_draft'] = False
sdoc_revision = seadoc_revision_queryset.filter(
doc_uuid=file_uuid_map.uuid).first()
if sdoc_revision:
file_info['is_sdoc_revision'] = True
file_info['revision_id'] = sdoc_revision.revision_id
else:
file_info['is_sdoc_revision'] = False
except Exception as e:
logger.error(e)

View File

@@ -15,6 +15,7 @@ from django.utils.translation import gettext as _
from django.http import HttpResponseRedirect, HttpResponse
from django.core.files.base import ContentFile
from django.utils import timezone
from django.db import transaction
from seaserv import seafile_api, check_quota
@@ -995,6 +996,25 @@ class SeadocRevisions(APIView):
revision_file_uuid = str(uuid.uuid4())
revision_filename = revision_file_uuid + '.sdoc'
with transaction.atomic():
revision_uuid_map = FileUUIDMap(
uuid=revision_file_uuid,
repo_id=repo_id,
parent_path='/Revisions',
filename=revision_filename,
is_dir=False,
)
revision_uuid_map.save()
revision = SeadocRevision.objects.add(
doc_uuid=revision_file_uuid,
origin_doc_uuid=origin_file_uuid,
repo_id=repo_id,
origin_doc_path=path,
username=username,
origin_file_version=origin_file_id,
)
# copy file to revision dir
seafile_api.copy_file(
repo_id, parent_dir,
@@ -1004,24 +1024,6 @@ class SeadocRevisions(APIView):
username=username, need_progress=0, synchronous=1,
)
revision_uuid_map = FileUUIDMap(
uuid=revision_file_uuid,
repo_id=repo_id,
parent_path='/Revisions',
filename=revision_filename,
is_dir=False,
)
revision_uuid_map.save()
revision = SeadocRevision.objects.create(
doc_uuid=revision_file_uuid,
origin_doc_uuid=origin_file_uuid,
repo_id=repo_id,
origin_doc_path=path,
username=username,
origin_file_version=origin_file_id,
)
# copy image files
origin_image_parent_path = '/images/sdoc/' + origin_file_uuid + '/'
dir_id = seafile_api.get_dir_id_by_path(repo_id, origin_image_parent_path)

View File

@@ -81,6 +81,25 @@ class SeadocDraft(models.Model):
class SeadocRevisionManager(models.Manager):
def add(self, doc_uuid, origin_doc_uuid, repo_id, origin_doc_path, username, origin_file_version):
last_revision = self.filter(repo_id=repo_id).order_by('revision_id').last()
if not last_revision:
revision_id = 1
else:
revision_id = last_revision.revision_id + 1
return self.create(
doc_uuid=doc_uuid,
origin_doc_uuid=origin_doc_uuid,
repo_id=repo_id,
revision_id=revision_id,
origin_doc_path=origin_doc_path,
username=username,
origin_file_version=origin_file_version,
)
def get_by_revision_id(self, repo_id, revision_id):
return self.filter(repo_id=repo_id, revision_id=revision_id).first()
def get_by_doc_uuid(self, doc_uuid):
return self.filter(doc_uuid=doc_uuid).first()
@@ -113,6 +132,7 @@ class SeadocRevision(models.Model):
doc_uuid = models.CharField(max_length=36, unique=True)
origin_doc_uuid = models.CharField(max_length=36, db_index=True)
repo_id = models.CharField(max_length=36, db_index=True)
revision_id = models.IntegerField() # revision_id in repo
origin_doc_path = models.TextField() # used when origin file deleted
username = models.CharField(max_length=255, db_index=True)
origin_file_version = models.CharField(max_length=100)
@@ -126,6 +146,7 @@ class SeadocRevision(models.Model):
class Meta:
db_table = 'sdoc_revision'
unique_together = ('repo_id', 'revision_id')
def to_dict(self, fileuuidmap_queryset=None):
from seahub.tags.models import FileUUIDMap
@@ -157,6 +178,7 @@ class SeadocRevision(models.Model):
'username': self.username,
'nickname': email2nickname(self.username),
'repo_id': self.repo_id,
'revision_id': self.revision_id,
'doc_uuid': self.doc_uuid,
'parent_path': parent_path,
'filename': filename,

View File

@@ -178,12 +178,14 @@ def can_access_seadoc_asset(request, repo_id, path, file_uuid):
return False
def is_seadoc_revision(doc_uuid):
def is_seadoc_revision(doc_uuid, revision=None):
info = {}
revision = SeadocRevision.objects.get_by_doc_uuid(doc_uuid)
if not revision:
revision = SeadocRevision.objects.get_by_doc_uuid(doc_uuid)
if revision:
info = {'is_sdoc_revision': True}
revision_info = revision.to_dict()
info['revision_id'] = revision_info['revision_id']
info['origin_doc_uuid'] = revision_info['origin_doc_uuid']
info['origin_parent_path'] = revision_info['origin_parent_path']
info['origin_filename'] = revision_info['origin_filename']

View File

@@ -15,6 +15,7 @@ assetsUrl: '{{ assets_url }}',
seadocAccessToken: '{{ seadoc_access_token }}',
seadocServerUrl: '{{ seadoc_server_url }}',
isSdocRevision: {% if is_sdoc_revision %}true{% else %}false{% endif %},
revisionId: '{{ revision_id }}',
originDocUuid: '{{ origin_doc_uuid }}',
originParentPath: '{{ origin_parent_path }}',
originFilename: '{{ origin_filename }}',

View File

@@ -19,6 +19,7 @@
assetsUrl: '{{ assets_url }}',
fileDownloadLink: '{{ file_download_link }}',
isSdocRevision: {% if is_sdoc_revision %}true{% else %}false{% endif %},
revisionId: '{{ revision_id }}',
originDocUuid: '{{ origin_doc_uuid }}',
originFileDownloadLink: '{{ origin_file_download_link }}',
originParentPath: '{{ origin_parent_path }}',

View File

@@ -13,7 +13,7 @@ from seahub.views.file import view_history_file, view_trash_file,\
view_snapshot_file, view_shared_file, view_file_via_shared_dir,\
text_diff, view_raw_file, download_file, view_lib_file, \
file_access, view_lib_file_via_smart_link, view_media_file_via_share_link, \
view_media_file_via_public_wiki
view_media_file_via_public_wiki, view_sdoc_revision
from seahub.views.repo import repo_history_view, repo_snapshot, view_shared_dir, \
view_shared_upload_link, view_lib_as_wiki
@@ -240,6 +240,7 @@ urlpatterns = [
### lib (replace the old `repo` urls) ###
# url(r'^lib/(?P<repo_id>[-0-9a-f]{36})/dir/(?P<path>.*)$', view_lib_dir, name='view_lib_dir'),
re_path(r'^lib/(?P<repo_id>[-0-9a-f]{36})/file(?P<path>.*)$', view_lib_file, name='view_lib_file'),
re_path(r'^lib/(?P<repo_id>[-0-9a-f]{36})/revisions/(?P<revision_id>\d+)/$', view_sdoc_revision, name='view_sdoc_revision'),
re_path(r'^wiki/lib/(?P<repo_id>[-0-9a-f]{36})/(?P<path>.*)$', view_lib_as_wiki, name='view_lib_as_wiki'),
re_path(r'^smart-link/(?P<dirent_uuid>[-0-9a-f]{36})/(?P<dirent_name>.*)$', view_lib_file_via_smart_link, name="view_lib_file_via_smart_link"),

View File

@@ -76,7 +76,7 @@ from seahub.thumbnail.utils import extract_xmind_image, get_thumbnail_src, \
from seahub.drafts.utils import get_file_draft, \
is_draft_file, has_draft_file
from seahub.seadoc.utils import get_seadoc_file_uuid, gen_seadoc_access_token, is_seadoc_revision
from seahub.seadoc.models import SeadocDraft
from seahub.seadoc.models import SeadocDraft, SeadocRevision
if HAS_OFFICE_CONVERTER:
from seahub.utils import (
@@ -2117,3 +2117,138 @@ def get_file_content_from_cache(file_id, repo_id, file_name):
cache.set(cache_key, file_content, 24 * 60 * 60)
return err_msg, file_content
@login_required
@repo_passwd_set_required
def view_sdoc_revision(request, repo_id, revision_id):
# resource check
repo = seafile_api.get_repo(repo_id)
if not repo:
raise Http404
revision = SeadocRevision.objects.get_by_revision_id(repo_id, revision_id)
if not revision:
return render_error(request, 'revision not found')
uuid_map = FileUUIDMap.objects.filter(
uuid=revision.doc_uuid).first()
if not uuid_map:
return render_error(request, _('File does not exist'))
path = posixpath.join(uuid_map.parent_path, uuid_map.filename)
file_id = seafile_api.get_file_id_by_path(repo_id, path)
if not file_id:
return render_error(request, _('File does not exist'))
# permission check
username = request.user.username
parent_dir = uuid_map.parent_path
filename = uuid_map.filename
permission = check_folder_permission(request, repo_id, parent_dir)
if not permission:
return convert_repo_path_when_can_not_view_file(request, repo_id, path)
org_id = request.user.org.org_id if is_org_context(request) else -1
# basic file info
return_dict = {
'is_pro': is_pro_version(),
'repo': repo,
'file_id': file_id,
'last_commit_id': repo.head_cmmt_id,
'is_repo_owner': is_repo_owner(request, repo_id, username),
'path': path,
'parent_dir': parent_dir,
'filename': filename,
'file_perm': permission,
'highlight_keyword': settings.HIGHLIGHT_KEYWORD,
'enable_file_comment': settings.ENABLE_FILE_COMMENT,
'enable_watermark': ENABLE_WATERMARK,
'share_link_force_use_password': SHARE_LINK_FORCE_USE_PASSWORD,
'share_link_password_min_length': SHARE_LINK_PASSWORD_MIN_LENGTH,
'share_link_password_strength_level': SHARE_LINK_PASSWORD_STRENGTH_LEVEL,
'share_link_expire_days_default': SHARE_LINK_EXPIRE_DAYS_DEFAULT,
'share_link_expire_days_min': SHARE_LINK_EXPIRE_DAYS_MIN,
'share_link_expire_days_max': SHARE_LINK_EXPIRE_DAYS_MAX,
'can_download_file': parse_repo_perm(permission).can_download,
'seafile_collab_server': SEAFILE_COLLAB_SERVER,
}
# check whether file is starred
is_starred = is_file_starred(username, repo_id, path, org_id)
return_dict['is_starred'] = is_starred
# check file lock info
try:
is_locked, locked_by_me = check_file_lock(repo_id, path, username)
except Exception as e:
logger.error(e)
is_locked = False
locked_by_me = False
if is_pro_version() and permission == 'rw':
can_lock_unlock_file = True
else:
can_lock_unlock_file = False
return_dict['file_locked'] = is_locked
return_dict['locked_by_me'] = locked_by_me
return_dict['can_lock_unlock_file'] = can_lock_unlock_file
# file shared link
l = FileShare.objects.filter(repo_id=repo_id).filter(
username=username).filter(path=path)
fileshare = l[0] if len(l) > 0 else None
file_shared_link = gen_file_share_link(fileshare.token) if fileshare else ''
return_dict['fileshare'] = fileshare,
return_dict['file_shared_link'] = file_shared_link
if parse_repo_perm(permission).can_download and \
request.user.permissions.can_generate_share_link():
return_dict['can_share_file'] = True
else:
return_dict['can_share_file'] = False
# fetch file contributors and latest contributor
try:
# get real path for sub repo
real_path = repo.origin_path + path if repo.origin_path else path
dirent = seafile_api.get_dirent_by_path(repo.store_id, real_path)
if dirent:
latest_contributor, last_modified = dirent.modifier, dirent.mtime
else:
latest_contributor, last_modified = None, 0
except Exception as e:
logger.error(e)
latest_contributor, last_modified = None, 0
return_dict['latest_contributor'] = latest_contributor
return_dict['last_modified'] = last_modified
# get file type and extention
filetype, fileext = get_file_type_and_ext(filename)
return_dict['fileext'] = fileext
return_dict['filetype'] = filetype
file_uuid = str(uuid_map.uuid)
return_dict['file_uuid'] = file_uuid
return_dict['assets_url'] = '/api/v2.1/seadoc/download-image/' + file_uuid
return_dict['seadoc_server_url'] = SEADOC_SERVER_URL
can_edit_file = True
if parse_repo_perm(permission).can_edit_on_web is False:
can_edit_file = False
elif is_locked and not locked_by_me:
can_edit_file = False
seadoc_perm = 'rw' if can_edit_file else 'r'
return_dict['can_edit_file'] = can_edit_file
return_dict['seadoc_access_token'] = gen_seadoc_access_token(file_uuid, filename, username, permission=seadoc_perm)
# revision
revision_info = is_seadoc_revision(file_uuid, revision)
return_dict.update(revision_info)
send_file_access_msg(request, repo, path, 'web')
return render(request, 'sdoc_file_view_react.html', return_dict)

View File

@@ -1401,6 +1401,7 @@ CREATE TABLE `sdoc_draft` (
CREATE TABLE `sdoc_revision` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`repo_id` varchar(36) NOT NULL,
`revision_id` int(11) NOT NULL,
`doc_uuid` varchar(36) NOT NULL,
`origin_doc_uuid` varchar(36) NOT NULL,
`origin_doc_path` longtext NOT NULL,
@@ -1413,6 +1414,7 @@ CREATE TABLE `sdoc_revision` (
`updated_at` datetime NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `sdoc_revise_doc_uuid` (`doc_uuid`),
UNIQUE KEY `sdoc_revision_repo_id_revision_id` (`repo_id`, `revision_id`),
KEY `sdoc_revision_repo_id` (`repo_id`),
KEY `sdoc_revision_origin_doc_uuid` (`origin_doc_uuid`),
KEY `sdoc_revision_username` (`username`),