- {!currentPageConfig.icon && (
+ {!currentPageConfig.icon && wikiPermission !== 'public' && (
)}
- {!currentPageConfig.cover_img_url && (
+ {!currentPageConfig.cover_img_url && wikiPermission !== 'public' && (
{gettext('Add cover')}
diff --git a/frontend/src/utils/constants.js b/frontend/src/utils/constants.js
index 0c1295af9f..ca3bd1d643 100644
--- a/frontend/src/utils/constants.js
+++ b/frontend/src/utils/constants.js
@@ -115,6 +115,7 @@ export const wikiId = window.wiki ? window.wiki.config.wikiId : '';
export const repoID = window.wiki ? window.wiki.config.repoId : '';
export const initialPath = window.wiki ? window.wiki.config.initial_path : '';
export const permission = window.wiki ? window.wiki.config.permission === 'True' : '';
+export const wikiPermission = window.wiki ? window.wiki.config.permission : '';
export const isDir = window.wiki ? window.wiki.config.isDir : '';
export const serviceUrl = window.wiki ? window.wiki.config.serviceUrl : '';
export const isPublicWiki = window.wiki ? window.wiki.config.isPublicWiki === 'True' : '';
diff --git a/frontend/src/utils/wiki-api.js b/frontend/src/utils/wiki-api.js
index 15ca3b5e07..c93e02d521 100644
--- a/frontend/src/utils/wiki-api.js
+++ b/frontend/src/utils/wiki-api.js
@@ -176,6 +176,11 @@ class WikiAPI {
return this.req.get(url);
}
+ getWiki2PublishConfig(wikiId) {
+ const url = this.server + '/api/v2.1/wiki2/' + wikiId + '/publish/config/';
+ return this.req.get(url);
+ }
+
createWiki2Page(wikiId, pageName, currentId) {
const url = this.server + '/api/v2.1/wiki2/' + wikiId + '/pages/';
let form = new FormData();
@@ -211,6 +216,11 @@ class WikiAPI {
return this.req.get(url);
}
+ getWiki2PublishPage(wikiId, pageId) {
+ const url = this.server + '/api/v2.1/wiki2/' + wikiId + '/publish/page/' + pageId + '/';
+ return this.req.get(url);
+ }
+
renameWiki2(wikiId, wikiName) {
const url = this.server + '/api/v2.1/wiki2/' + wikiId + '/';
let params = {
@@ -253,6 +263,23 @@ class WikiAPI {
});
}
+ publishWiki(wikiId, publish_url) {
+ const url = this.server + '/api/v2.1/wiki2/' + wikiId + '/publish/';
+ let form = new FormData();
+ form.append('publish_url', publish_url);
+ return this._sendPostRequest(url, form);
+ }
+
+ getPublishWikiLink(wikiId) {
+ const url = this.server + '/api/v2.1/wiki2/' + wikiId + '/publish/';
+ return this.req.get(url);
+ }
+
+ deletePublishWikiLink(wikiId, customUrl) {
+ const url = this.server + '/api/v2.1/wiki2/' + wikiId + '/publish/';
+ return this.req.delete(url);
+ }
+
}
let wikiAPI = new WikiAPI();
diff --git a/seahub/api2/endpoints/wiki2.py b/seahub/api2/endpoints/wiki2.py
index cf4279cfb0..174e5951fa 100644
--- a/seahub/api2/endpoints/wiki2.py
+++ b/seahub/api2/endpoints/wiki2.py
@@ -8,6 +8,7 @@ import posixpath
import time
import datetime
import uuid
+import re
import urllib.request, urllib.error, urllib.parse
from copy import deepcopy
from constance import config
@@ -26,7 +27,7 @@ from seahub.api2.throttling import UserRateThrottle
from seahub.api2.utils import api_error, to_python_boolean, is_wiki_repo
from seahub.utils.db_api import SeafileDB
from seahub.wiki2.models import Wiki2 as Wiki
-from seahub.wiki2.models import WikiPageTrash
+from seahub.wiki2.models import WikiPageTrash, Wiki2Publish
from seahub.wiki2.utils import is_valid_wiki_name, can_edit_wiki, get_wiki_dirs_by_path, \
get_wiki_config, WIKI_PAGES_DIR, WIKI_CONFIG_PATH, WIKI_CONFIG_FILE_NAME, is_group_wiki, \
check_wiki_admin_permission, check_wiki_permission, get_all_wiki_ids, get_and_gen_page_nav_by_id, \
@@ -36,7 +37,6 @@ from seahub.wiki2.utils import is_valid_wiki_name, can_edit_wiki, get_wiki_dirs_
from seahub.utils import is_org_context, get_user_repos, gen_inner_file_get_url, gen_file_upload_url, \
normalize_dir_path, is_pro_version, check_filename_with_rename, is_valid_dirent_name, get_no_duplicate_obj_name
from seahub.views import check_folder_permission
-from seahub.views.file import send_file_access_msg
from seahub.base.templatetags.seahub_tags import email2nickname
from seahub.utils.file_op import check_file_lock, ONLINE_OFFICE_LOCK_OWNER, if_locked_by_online_office
from seahub.utils.repo import parse_repo_perm, get_repo_owner
@@ -61,7 +61,8 @@ HTTP_520_OPERATION_FAILED = 520
logger = logging.getLogger(__name__)
-def _merge_wiki_in_groups(group_wikis):
+
+def _merge_wiki_in_groups(group_wikis, publish_wiki_ids):
group_ids = [gw.group_id for gw in group_wikis]
group_id_wikis_map = {key: [] for key in group_ids}
@@ -77,7 +78,8 @@ def _merge_wiki_in_groups(group_wikis):
repo_info = {
"type": "group",
"permission": gw.permission,
- "owner_nickname": owner_nickname
+ "owner_nickname": owner_nickname,
+ "is_published": True if wiki.repo_id in publish_wiki_ids else False
}
wiki_info.update(repo_info)
group_id = gw.group_id
@@ -105,8 +107,14 @@ class Wikis2View(APIView):
user_groups = ccnet_api.get_org_groups_by_user(org_id, username, return_ancestors=True)
else:
user_groups = ccnet_api.get_groups(username, return_ancestors=True)
-
owned_wikis = [r for r in owned if is_wiki_repo(r)]
+ shared_wikis = [r for r in shared if is_wiki_repo(r)]
+ group_wikis = [r for r in groups if is_wiki_repo(r)]
+ wiki_ids = [w.repo_id for w in owned_wikis + shared_wikis + group_wikis]
+ publish_wiki_ids = []
+ published_wikis = Wiki2Publish.objects.filter(repo_id__in=wiki_ids)
+ for w in published_wikis:
+ publish_wiki_ids.append(w.repo_id)
wiki_list = []
for r in owned_wikis:
r.owner = username
@@ -116,12 +124,12 @@ class Wikis2View(APIView):
repo_info = {
"type": "mine",
"permission": 'rw',
- "owner_nickname": email2nickname(username)
+ "owner_nickname": email2nickname(username),
+ "is_published": True if wiki_info['repo_id'] in publish_wiki_ids else False
}
wiki_info.update(repo_info)
wiki_list.append(wiki_info)
-
- shared_wikis = [r for r in shared if is_wiki_repo(r)]
+
for r in shared_wikis:
owner = r.user
r.owner = owner
@@ -135,12 +143,12 @@ class Wikis2View(APIView):
repo_info = {
"type": "shared",
"permission": r.permission,
- "owner_nickname": owner_nickname
+ "owner_nickname": owner_nickname,
+ "is_published": True if wiki_info['repo_id'] in publish_wiki_ids else False
}
wiki_info.update(repo_info)
wiki_list.append(wiki_info)
- group_wikis = [r for r in groups if is_wiki_repo(r)]
group_id_in_wikis = list(set([r.group_id for r in group_wikis]))
try:
group_ids_admins_map = {}
@@ -157,7 +165,7 @@ class Wikis2View(APIView):
r.owner = r.user
group_wiki_list = []
- group_id_wikis_map = _merge_wiki_in_groups(group_wikis)
+ group_id_wikis_map = _merge_wiki_in_groups(group_wikis, publish_wiki_ids)
for group_obj in user_wiki_groups:
group_wiki = {
'group_name': group_obj.group_name,
@@ -354,6 +362,8 @@ class Wiki2View(APIView):
else:
seafile_api.remove_repo(wiki.repo_id)
+ Wiki2Publish.objects.filter(repo_id=wiki.repo_id).delete()
+
return Response()
@@ -426,6 +436,35 @@ class Wiki2ConfigView(APIView):
return Response({'wiki': wiki})
+
+class Wiki2PublishConfigView(APIView):
+ throttle_classes = (UserRateThrottle,)
+
+ def get(self, request, wiki_id):
+ wiki = Wiki.objects.get(wiki_id=wiki_id)
+ if not wiki:
+ error_msg = "Wiki not found."
+ return api_error(status.HTTP_404_NOT_FOUND, error_msg)
+ if not Wiki2Publish.objects.filter(repo_id=wiki.repo_id).exists():
+ error_msg = "Wiki not found."
+ return api_error(status.HTTP_404_NOT_FOUND, error_msg)
+ try:
+ repo = seafile_api.get_repo(wiki.repo_id)
+ if not repo:
+ error_msg = "Wiki library not found."
+ return api_error(status.HTTP_404_NOT_FOUND, error_msg)
+ except SearpcError:
+ error_msg = _("Internal Server Error")
+ return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
+
+ wiki = wiki.to_dict()
+ wiki_config = get_wiki_config(repo.repo_id, '')
+
+ wiki['wiki_config'] = wiki_config
+
+ return Response({'wiki': wiki})
+
+
class Wiki2PagesView(APIView):
authentication_classes = (TokenAuthentication, SessionAuthentication)
permission_classes = (IsAuthenticated, )
@@ -613,8 +652,6 @@ class Wiki2PageView(APIView):
throttle_classes = (UserRateThrottle, )
def get(self, request, wiki_id, page_id):
-
-
wiki = Wiki.objects.get(wiki_id=wiki_id)
if not wiki:
error_msg = "Wiki not found."
@@ -658,9 +695,6 @@ class Wiki2PageView(APIView):
if not file_id:
return api_error(status.HTTP_404_NOT_FOUND, "File not found")
- # send stats message
- send_file_access_msg(request, repo, path, 'api')
-
filename = os.path.basename(path)
try:
dirent = seafile_api.get_dirent_by_path(repo.repo_id, path)
@@ -767,6 +801,68 @@ class Wiki2PageView(APIView):
return Response({'success': True})
+class Wiki2PublishPageView(APIView):
+ throttle_classes = (UserRateThrottle,)
+
+ def get(self, request, wiki_id, page_id):
+
+ wiki = Wiki.objects.get(wiki_id=wiki_id)
+ if not wiki:
+ error_msg = "Wiki not found."
+ return api_error(status.HTTP_404_NOT_FOUND, error_msg)
+
+ repo_id = wiki.repo_id
+ if not Wiki2Publish.objects.filter(repo_id=repo_id).exists():
+ error_msg = "Wiki not found."
+ return api_error(status.HTTP_404_NOT_FOUND, error_msg)
+
+ repo = seafile_api.get_repo(repo_id)
+ if not repo:
+ error_msg = 'Library %s not found.' % repo_id
+ return api_error(status.HTTP_404_NOT_FOUND, error_msg)
+
+ wiki_config = get_wiki_config(repo_id, "")
+ pages = wiki_config.get('pages', [])
+ page_info = next(filter(lambda t: t['id'] == page_id, pages), {})
+ path = page_info.get('path')
+ doc_uuid = page_info.get('docUuid')
+
+ if not page_info:
+ error_msg = 'page %s not found.' % page_id
+ return api_error(status.HTTP_404_NOT_FOUND, error_msg)
+
+ try:
+ file_id = seafile_api.get_file_id_by_path(repo.repo_id, path)
+ except SearpcError as e:
+ logger.error(e)
+ return api_error(HTTP_520_OPERATION_FAILED,
+ "Failed to get file id by path.")
+ if not file_id:
+ return api_error(status.HTTP_404_NOT_FOUND, "File not found")
+
+ filename = os.path.basename(path)
+ try:
+ dirent = seafile_api.get_dirent_by_path(repo.repo_id, path)
+ if dirent:
+ latest_contributor, last_modified = dirent.modifier, dirent.mtime
+ else:
+ latest_contributor, last_modified = None, 0
+ except SearpcError as e:
+ logger.error(e)
+ latest_contributor, last_modified = None, 0
+
+ assets_url = '/api/v2.1/seadoc/download-image/' + doc_uuid
+ seadoc_access_token = gen_seadoc_access_token(doc_uuid, filename, request.user.username, permission='r',
+ default_title='')
+
+ return Response({
+ "latest_contributor": email2nickname(latest_contributor),
+ "last_modified": last_modified,
+ "permission": 'r',
+ "seadoc_access_token": seadoc_access_token,
+ "assets_url": assets_url,
+ })
+
class Wiki2DuplicatePageView(APIView):
authentication_classes = (TokenAuthentication, SessionAuthentication)
permission_classes = (IsAuthenticated, )
@@ -1073,4 +1169,102 @@ class WikiPageTrashView(APIView):
return Response({'success': True})
+class Wiki2PublishView(APIView):
+ authentication_classes = (TokenAuthentication, SessionAuthentication)
+ permission_classes = (IsAuthenticated,)
+ throttle_classes = (UserRateThrottle,)
+ def _check_custom_url(self, publish_url):
+ return True if re.search(r'^[-0-9a-zA-Z]+$', publish_url) else False
+
+ def get(self, request, wiki_id):
+ wiki = Wiki.objects.get(wiki_id=wiki_id)
+ if not wiki:
+ error_msg = "Wiki not found."
+ return api_error(status.HTTP_404_NOT_FOUND, error_msg)
+ username = request.user.username
+ repo_owner = get_repo_owner(request, wiki_id)
+ wiki.owner = repo_owner
+ if not check_wiki_admin_permission(wiki, username):
+ error_msg = 'Permission denied.'
+ return api_error(status.HTTP_403_FORBIDDEN, error_msg)
+
+ try:
+ publish_config = Wiki2Publish.objects.get(repo_id=wiki.repo_id)
+ publish_url = publish_config.publish_url
+ creator = publish_config.username
+ created_at = publish_config.created_at
+ visit_count = publish_config.visit_count
+ except Wiki2Publish.DoesNotExist:
+ publish_url = ''
+ creator = ''
+ created_at = ''
+ visit_count = 0
+ publish_info = {
+ 'publish_url': publish_url,
+ 'creator': creator,
+ 'created_at': created_at,
+ 'visit_count': visit_count
+ }
+ return Response(publish_info)
+
+ def post(self, request, wiki_id):
+ publish_url = request.data.get('publish_url', None)
+ if not publish_url:
+ error_msg = 'wiki custom url invalid.'
+ return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
+
+ publish_url = publish_url.strip()
+ if not self._check_custom_url(publish_url):
+ error_msg = _('URL is invalid')
+ return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
+
+ if len(publish_url) < 5 or len(publish_url) > 30:
+ error_msg = _('The custom part of URL should have 5-30 characters.')
+ return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
+
+ wiki = Wiki.objects.get(wiki_id=wiki_id)
+ if not wiki:
+ error_msg = "Wiki not found."
+ return api_error(status.HTTP_404_NOT_FOUND, error_msg)
+
+ # check permission
+ repo_owner = get_repo_owner(request, wiki_id)
+ wiki.owner = repo_owner
+ username = request.user.username
+ if not check_wiki_admin_permission(wiki, username):
+ error_msg = 'Permission denied.'
+ return api_error(status.HTTP_403_FORBIDDEN, error_msg)
+ wiki_pub = Wiki2Publish.objects.filter(publish_url=publish_url).first()
+ if wiki_pub:
+ if wiki_pub.repo_id != wiki_id:
+ error_msg = _('This custom domain is already in use and cannot be used for your wiki')
+ return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
+ return Response({"publish_url": publish_url})
+
+ wiki_publish = Wiki2Publish.objects.filter(repo_id=wiki.repo_id).first()
+ if not wiki_publish:
+ wiki_publish = Wiki2Publish(repo_id=wiki.repo_id, username=username, publish_url=publish_url)
+ else:
+ wiki_publish.publish_url = publish_url
+ wiki_publish.save()
+
+ return Response({"publish_url": publish_url})
+
+ def delete(self, request, wiki_id):
+ wiki = Wiki.objects.get(wiki_id=wiki_id)
+ if not wiki:
+ error_msg = "Wiki not found."
+ return api_error(status.HTTP_404_NOT_FOUND, error_msg)
+
+ repo_owner = get_repo_owner(request, wiki_id)
+ wiki.owner = repo_owner
+ username = request.user.username
+ if not check_wiki_admin_permission(wiki, username):
+ error_msg = 'Permission denied.'
+ return api_error(status.HTTP_403_FORBIDDEN, error_msg)
+
+ publish_config = Wiki2Publish.objects.filter(repo_id=wiki.repo_id).first()
+ if publish_config:
+ publish_config.delete()
+ return Response({'success': True})
diff --git a/seahub/seadoc/apis.py b/seahub/seadoc/apis.py
index 04b81cc495..bd0e2dbed3 100644
--- a/seahub/seadoc/apis.py
+++ b/seahub/seadoc/apis.py
@@ -61,6 +61,7 @@ from seahub.base.accounts import User
from seahub.avatar.settings import AVATAR_DEFAULT_SIZE
from seahub.repo_tags.models import RepoTags
from seahub.file_tags.models import FileTags
+from seahub.wiki2.models import Wiki2Publish
if HAS_FILE_SEARCH or HAS_FILE_SEASEARCH:
from seahub.search.utils import search_files, ai_search_files, format_repos
@@ -410,11 +411,13 @@ class SeadocDownloadImage(APIView):
repo_id = uuid_map.repo_id
username = request.user.username
+ wiki_publish = Wiki2Publish.objects.filter(repo_id=repo_id).first()
# permission check
- file_path = posixpath.join(uuid_map.parent_path, uuid_map.filename)
- if not can_access_seadoc_asset(request, repo_id, file_path, file_uuid):
- error_msg = 'Permission denied.'
- return api_error(status.HTTP_403_FORBIDDEN, error_msg)
+ if not wiki_publish:
+ file_path = posixpath.join(uuid_map.parent_path, uuid_map.filename)
+ if not can_access_seadoc_asset(request, repo_id, file_path, file_uuid):
+ error_msg = 'Permission denied.'
+ return api_error(status.HTTP_403_FORBIDDEN, error_msg)
# main
parent_path = gen_seadoc_image_parent_path(file_uuid, repo_id, username)
diff --git a/seahub/templates/wiki/wiki_publish.html b/seahub/templates/wiki/wiki_publish.html
new file mode 100644
index 0000000000..5ad0103854
--- /dev/null
+++ b/seahub/templates/wiki/wiki_publish.html
@@ -0,0 +1,35 @@
+{% extends "base_for_react.html" %}
+{% load i18n %}
+{% load render_bundle from webpack_loader %}
+{% load seahub_tags %}
+{% block extra_ogp_tags %}
+
+
+
+
+
+
+{% endblock %}
+{% block extra_style %}
+
+
+{% render_bundle 'wiki2' 'css' %}
+{% endblock %}
+
+{% block wiki_title %}{{repo_name}}{% endblock %}
+
+{% block extra_script %}
+
+{% render_bundle 'wiki2' 'js' %}
+{% endblock %}
diff --git a/seahub/urls.py b/seahub/urls.py
index 775ef18cd2..fbd39ff45b 100644
--- a/seahub/urls.py
+++ b/seahub/urls.py
@@ -206,10 +206,9 @@ from seahub.api2.endpoints.repo_related_users import RepoRelatedUsersView
from seahub.api2.endpoints.repo_auto_delete import RepoAutoDeleteView
from seahub.seadoc.views import sdoc_revision, sdoc_revisions, sdoc_to_docx
from seahub.ocm.settings import OCM_ENDPOINT
-
-from seahub.wiki2.views import wiki_view
+from seahub.wiki2.views import wiki_view, wiki_publish_view
from seahub.api2.endpoints.wiki2 import Wikis2View, Wiki2View, Wiki2ConfigView, Wiki2PagesView, Wiki2PageView, \
- Wiki2DuplicatePageView, WikiPageTrashView
+ Wiki2DuplicatePageView, WikiPageTrashView, Wiki2PublishView, Wiki2PublishConfigView, Wiki2PublishPageView
from seahub.api2.endpoints.subscription import SubscriptionView, SubscriptionPlansView, SubscriptionLogsView
from seahub.api2.endpoints.metadata_manage import MetadataRecords, MetadataManage, MetadataColumns, MetadataRecordInfo, \
MetadataViews, MetadataViewsMoveView, MetadataViewsDetailView, MetadataViewsDuplicateView
@@ -546,11 +545,13 @@ urlpatterns = [
re_path(r'^api/v2.1/wikis2/$', Wikis2View.as_view(), name='api-v2.1-wikis2'),
re_path(r'^api/v2.1/wiki2/(?P
[-0-9a-f]{36})/$', Wiki2View.as_view(), name='api-v2.1-wiki2'),
re_path(r'^api/v2.1/wiki2/(?P[-0-9a-f]{36})/config/$', Wiki2ConfigView.as_view(), name='api-v2.1-wiki2-config'),
+ re_path(r'^api/v2.1/wiki2/(?P[-0-9a-f]{36})/publish/config/$', Wiki2PublishConfigView.as_view(), name='api-v2.1-wiki2-publish-config'),
re_path(r'^api/v2.1/wiki2/(?P[-0-9a-f]{36})/pages/$', Wiki2PagesView.as_view(), name='api-v2.1-wiki2-pages'),
re_path(r'^api/v2.1/wiki2/(?P[-0-9a-f]{36})/page/(?P[-0-9a-zA-Z]{4})/$', Wiki2PageView.as_view(), name='api-v2.1-wiki2-page'),
+ re_path(r'^api/v2.1/wiki2/(?P[-0-9a-f]{36})/publish/page/(?P[-0-9a-zA-Z]{4})/$', Wiki2PublishPageView.as_view(), name='api-v2.1-wiki2-page'),
re_path(r'^api/v2.1/wiki2/(?P[-0-9a-f]{36})/duplicate-page/$', Wiki2DuplicatePageView.as_view(), name='api-v2.1-wiki2-duplicate-page'),
re_path(r'^api/v2.1/wiki2/(?P[-0-9a-f]{36})/trash/', WikiPageTrashView.as_view(), name='api-v2.1-wiki2-trash'),
-
+ re_path(r'^api/v2.1/wiki2/(?P[-0-9a-f]{36})/publish/$', Wiki2PublishView.as_view(), name='api-v2.1-wiki2-publish'),
## user::drafts
re_path(r'^api/v2.1/drafts/$', DraftsView.as_view(), name='api-v2.1-drafts'),
re_path(r'^api/v2.1/drafts/(?P\d+)/$', DraftView.as_view(), name='api-v2.1-draft'),
@@ -737,6 +738,7 @@ urlpatterns = [
re_path(r'^api/v2.1/admin/invitations/(?P[a-f0-9]{32})/$', AdminInvitation.as_view(), name='api-v2.1-admin-invitation'),
re_path(r'^wikis/(?P[^/]+)/$', wiki_view, name='wiki'),
+ re_path(r'^wiki/publish/(?P[-0-9a-zA-Z]+)/$', wiki_publish_view, name='wiki-publish'),
path('avatar/', include('seahub.avatar.urls')),
path('group/', include('seahub.group.urls')),
diff --git a/seahub/wiki2/models.py b/seahub/wiki2/models.py
index b47757091d..e731500783 100644
--- a/seahub/wiki2/models.py
+++ b/seahub/wiki2/models.py
@@ -33,7 +33,6 @@ class Wiki2(object):
self.name = wiki.repo_name
self.updated_at = timestamp_to_isoformat_timestr(wiki.last_modify)
self.repo_id = wiki.repo_id
-
def to_dict(self):
return {
@@ -71,6 +70,25 @@ class WikiPageTrash(models.Model):
'size': self.size
}
+class Wiki2Publish(models.Model):
+ repo_id = models.CharField(max_length=36, unique=True, db_index=True)
+ publish_url = models.CharField(max_length=40, null=True, unique=True)
+ username = models.CharField(max_length=255)
+ created_at = models.DateTimeField(auto_now_add=True)
+ visit_count = models.IntegerField(default=0)
+
+ class Meta:
+ db_table = 'wiki_wiki2_publish'
+
+ def to_dict(self):
+ return {
+ 'repo_id': self.repo_id,
+ 'publish_url': self.publish_url,
+ 'username': self.username,
+ 'created_at': self.created_at,
+ 'visit_count': self.visit_count
+ }
+
###### signal handlers
from django.dispatch import receiver
from seahub.signals import repo_deleted
diff --git a/seahub/wiki2/views.py b/seahub/wiki2/views.py
index 4ba5cef141..763230c766 100644
--- a/seahub/wiki2/views.py
+++ b/seahub/wiki2/views.py
@@ -11,6 +11,7 @@ from django.http import Http404
from django.shortcuts import render
from seahub.wiki2.models import Wiki2 as Wiki
+from seahub.wiki2.models import Wiki2Publish
from seahub.utils import get_file_type_and_ext, render_permission_error
from seahub.utils.file_types import SEADOC
from seahub.auth.decorators import login_required
@@ -81,3 +82,66 @@ def wiki_view(request, wiki_id):
"permission": permission,
"enable_user_clean_trash": config.ENABLE_USER_CLEAN_TRASH
})
+
+
+def wiki_publish_view(request, publish_url):
+ """ view wiki page. for wiki2
+ 1 permission
+ All user
+ """
+ # get wiki_publish object or 404
+ wiki_publish = Wiki2Publish.objects.filter(publish_url=publish_url).first()
+ if not wiki_publish:
+ raise Http404
+
+ wiki_id = wiki_publish.repo_id
+ wiki = Wiki.objects.get(wiki_id=wiki_id)
+ if not wiki:
+ raise Http404
+
+ repo_owner = get_repo_owner(request, wiki_id)
+ wiki.owner = repo_owner
+
+ page_id = request.GET.get('page_id')
+ file_path = ''
+
+ if page_id:
+ wiki_config = get_wiki_config(wiki.repo_id, request.user.username)
+ pages = wiki_config.get('pages', [])
+ page_info = next(filter(lambda t: t['id'] == page_id, pages), {})
+ file_path = page_info.get('path', '')
+
+ is_page = False
+ if file_path:
+ is_page = True
+
+ latest_contributor = ''
+ last_modified = 0
+ file_type, ext = get_file_type_and_ext(posixpath.basename(file_path))
+ repo = seafile_api.get_repo(wiki.repo_id)
+ if is_page and file_type == SEADOC:
+ try:
+ dirent = seafile_api.get_dirent_by_path(wiki.repo_id, file_path)
+ if dirent:
+ latest_contributor, last_modified = dirent.modifier, dirent.mtime
+ except Exception as e:
+ logger.warning(e)
+
+ last_modified = datetime.fromtimestamp(last_modified)
+ # update visit_count
+ try:
+ current_count = wiki_publish.visit_count
+ wiki_publish.visit_count = current_count + 1
+ wiki_publish.save()
+ except Exception as e:
+ logger.warning(e)
+
+ return render(request, "wiki/wiki_publish.html", {
+ "wiki": wiki,
+ "file_path": file_path,
+ "repo_name": repo.name if repo else '',
+ "modifier": latest_contributor,
+ "modify_time": last_modified,
+ "seadoc_server_url": SEADOC_SERVER_URL,
+ "permission": 'public'
+ })
diff --git a/sql/mysql.sql b/sql/mysql.sql
index 98b7a9788c..c5bdece528 100644
--- a/sql/mysql.sql
+++ b/sql/mysql.sql
@@ -1557,3 +1557,16 @@ CREATE TABLE `sdoc_operation_log` (
KEY `sdoc_operation_log_doc_uuid` (`doc_uuid`),
KEY `sdoc_idx_operation_log_doc_uuid_op_id` (`doc_uuid`,`op_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
+
+CREATE TABLE IF NOT EXISTS `wiki_wiki2_publish` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `repo_id` varchar(36) NOT NULL,
+ `publish_url` varchar(40) DEFAULT NULL,
+ `username` varchar(255) NOT NULL,
+ `created_at` timestamp NOT NULL DEFAULT current_timestamp(),
+ `visit_count` int(11) NOT NULL DEFAULT 0,
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `repo_id` (`repo_id`),
+ UNIQUE KEY `publish_url` (`publish_url`),
+ KEY `ix_wiki2_publish_repo_id` (`repo_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;