mirror of
https://github.com/haiwen/seahub.git
synced 2025-10-21 19:00:12 +00:00
Add wiki home page and and tests
This commit is contained in:
@@ -62,7 +62,8 @@ class WikisView(APIView):
|
|||||||
|
|
||||||
username = request.user.username
|
username = request.user.username
|
||||||
try:
|
try:
|
||||||
wiki = Wiki.objects.add(name, permission, username, org_id)
|
wiki = Wiki.objects.add(name, username, permission=permission,
|
||||||
|
org_id=org_id)
|
||||||
except DuplicateWikiNameError:
|
except DuplicateWikiNameError:
|
||||||
result['error'] = _('%s is taken by others, please try another name.') % name
|
result['error'] = _('%s is taken by others, please try another name.') % name
|
||||||
return HttpResponse(json.dumps(result), status=400,
|
return HttpResponse(json.dumps(result), status=400,
|
||||||
@@ -95,4 +96,4 @@ class WikiView(APIView):
|
|||||||
|
|
||||||
Wiki.objects.filter(slug=slug).delete()
|
Wiki.objects.filter(slug=slug).delete()
|
||||||
|
|
||||||
return Response({"success": True})
|
return Response()
|
||||||
|
@@ -283,7 +283,7 @@ urlpatterns = patterns(
|
|||||||
|
|
||||||
## user::wiki
|
## user::wiki
|
||||||
url(r'^api/v2.1/wikis/$', WikisView.as_view(), name='api-v2.1-wikis'),
|
url(r'^api/v2.1/wikis/$', WikisView.as_view(), name='api-v2.1-wikis'),
|
||||||
url(r'^api/v2.1/wikis/(?P<slug>[^/]+)/$', WikiView.as_view(), name='api-v2.1-wikis'),
|
url(r'^api/v2.1/wikis/(?P<slug>[^/]+)/$', WikiView.as_view(), name='api-v2.1-wiki'),
|
||||||
|
|
||||||
## admin::sysinfo
|
## admin::sysinfo
|
||||||
url(r'^api/v2.1/admin/sysinfo/$', SysInfo.as_view(), name='api-v2.1-sysinfo'),
|
url(r'^api/v2.1/admin/sysinfo/$', SysInfo.as_view(), name='api-v2.1-sysinfo'),
|
||||||
|
0
seahub/wiki/management/__init__.py
Normal file
0
seahub/wiki/management/__init__.py
Normal file
0
seahub/wiki/management/commands/__init__.py
Normal file
0
seahub/wiki/management/commands/__init__.py
Normal file
27
seahub/wiki/management/commands/migrate_personal_wiki.py
Normal file
27
seahub/wiki/management/commands/migrate_personal_wiki.py
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
# Copyright (c) 2012-2016 Seafile Ltd.
|
||||||
|
# encoding: utf-8
|
||||||
|
import os
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from django.core.management.base import BaseCommand
|
||||||
|
|
||||||
|
from seahub.wiki.models import PersonalWiki, Wiki, DuplicateWikiNameError
|
||||||
|
|
||||||
|
# Get an instance of a logger
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
class Command(BaseCommand):
|
||||||
|
help = 'Migrate records in wiki_personal_wiki table to wiki_wiki table.'
|
||||||
|
label = "wiki_migrate_personal_wiki"
|
||||||
|
|
||||||
|
def handle(self, *args, **options):
|
||||||
|
print 'Start to migrate...'
|
||||||
|
for r in PersonalWiki.objects.all():
|
||||||
|
try:
|
||||||
|
Wiki.objects.add(wiki_name=r.username.split('@')[0],
|
||||||
|
username=r.username, repo_id=r.repo_id)
|
||||||
|
except DuplicateWikiNameError:
|
||||||
|
print 'Multiple personal wiki records found, user: %s, repo_id: %s. Skip.' % (r.username, r.repo_id)
|
||||||
|
continue
|
||||||
|
|
||||||
|
print 'Done.'
|
@@ -59,7 +59,8 @@ class DuplicateWikiNameError(Exception):
|
|||||||
|
|
||||||
|
|
||||||
class WikiManager(models.Manager):
|
class WikiManager(models.Manager):
|
||||||
def add(self, wiki_name, username, permission='private', org_id=-1):
|
def add(self, wiki_name, username, permission='private', repo_id=None,
|
||||||
|
org_id=-1):
|
||||||
if not permission:
|
if not permission:
|
||||||
permission = 'private'
|
permission = 'private'
|
||||||
|
|
||||||
@@ -68,18 +69,20 @@ class WikiManager(models.Manager):
|
|||||||
if self.filter(slug=slug).count() > 0:
|
if self.filter(slug=slug).count() > 0:
|
||||||
raise DuplicateWikiNameError
|
raise DuplicateWikiNameError
|
||||||
|
|
||||||
if org_id > 0:
|
if repo_id is None: # create new repo to store the wiki pages
|
||||||
repo_id = seafile_api.create_org_repo(wiki_name, '', username,
|
if org_id > 0:
|
||||||
passwd=None, org_id=org_id)
|
repo_id = seafile_api.create_org_repo(wiki_name, '', username,
|
||||||
else:
|
passwd=None, org_id=org_id)
|
||||||
repo_id = seafile_api.create_repo(wiki_name, '', username,
|
else:
|
||||||
passwd=None)
|
repo_id = seafile_api.create_repo(wiki_name, '', username,
|
||||||
|
passwd=None)
|
||||||
|
|
||||||
wiki = self.model(username=username, name=wiki_name, slug=slug,
|
wiki = self.model(username=username, name=wiki_name, slug=slug,
|
||||||
repo_id=repo_id, permission=permission)
|
repo_id=repo_id, permission=permission)
|
||||||
wiki.save(using=self._db)
|
wiki.save(using=self._db)
|
||||||
return wiki
|
return wiki
|
||||||
|
|
||||||
|
|
||||||
class Wiki(models.Model):
|
class Wiki(models.Model):
|
||||||
"""New wiki model to enable a user has multiple wikis and replace
|
"""New wiki model to enable a user has multiple wikis and replace
|
||||||
personal wiki.
|
personal wiki.
|
||||||
@@ -108,12 +111,22 @@ class Wiki(models.Model):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def updated_at(self):
|
def updated_at(self):
|
||||||
|
assert len(self.repo_id) == 36
|
||||||
|
|
||||||
repo = seafile_api.get_repo(self.repo_id)
|
repo = seafile_api.get_repo(self.repo_id)
|
||||||
if not repo:
|
if not repo:
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
return repo.last_modify
|
return repo.last_modify
|
||||||
|
|
||||||
|
def has_read_perm(self, user):
|
||||||
|
if self.permisson == 'public':
|
||||||
|
return True
|
||||||
|
elif self.permission == 'login-user':
|
||||||
|
return True if user.is_authenticated() else False
|
||||||
|
else: # private
|
||||||
|
return True if user.username == self.username else False
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
return {
|
return {
|
||||||
'id': self.pk,
|
'id': self.pk,
|
||||||
|
@@ -1,12 +1,13 @@
|
|||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
|
import urllib2
|
||||||
|
|
||||||
import seaserv
|
import seaserv
|
||||||
from seaserv import seafile_api
|
from seaserv import seafile_api
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django.http import HttpResponse, HttpResponseBadRequest, Http404, \
|
from django.http import HttpResponse, HttpResponseBadRequest, Http404, \
|
||||||
HttpResponseRedirect
|
HttpResponseRedirect
|
||||||
from django.shortcuts import render_to_response
|
from django.shortcuts import render_to_response, get_object_or_404
|
||||||
from django.template import Context, loader, RequestContext
|
from django.template import Context, loader, RequestContext
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
|
|
||||||
@@ -16,18 +17,92 @@ from pysearpc import SearpcError
|
|||||||
|
|
||||||
from seahub.auth.decorators import login_required
|
from seahub.auth.decorators import login_required
|
||||||
from seahub.base.decorators import user_mods_check
|
from seahub.base.decorators import user_mods_check
|
||||||
from seahub.wiki.models import PersonalWiki, WikiDoesNotExist, WikiPageMissing
|
from seahub.wiki.models import Wiki, WikiDoesNotExist, WikiPageMissing
|
||||||
from seahub.wiki import get_personal_wiki_page, get_personal_wiki_repo, \
|
from seahub.wiki import get_personal_wiki_page, get_personal_wiki_repo, \
|
||||||
convert_wiki_link, get_wiki_pages
|
convert_wiki_link, get_wiki_pages
|
||||||
from seahub.wiki.forms import WikiCreateForm, WikiNewPageForm
|
from seahub.wiki.forms import WikiCreateForm, WikiNewPageForm
|
||||||
from seahub.wiki.utils import clean_page_name, page_name_to_file_name
|
from seahub.wiki.utils import (clean_page_name, page_name_to_file_name,
|
||||||
|
get_wiki_dirent, get_inner_file_url)
|
||||||
from seahub.utils import render_error
|
from seahub.utils import render_error
|
||||||
from seahub.views import check_folder_permission
|
from seahub.views import check_folder_permission
|
||||||
|
|
||||||
# Get an instance of a logger
|
# Get an instance of a logger
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
|
||||||
def slug(request, slug, page_name="home"):
|
def slug(request, slug, page_name="home"):
|
||||||
assert False, 'TODO'
|
"""Show wiki page.
|
||||||
|
"""
|
||||||
|
username = request.user.username
|
||||||
|
# get or 404
|
||||||
|
wiki = get_object_or_404(Wiki, slug=slug)
|
||||||
|
|
||||||
|
# perm check
|
||||||
|
if not wiki.has_read_perm(request.user):
|
||||||
|
raise Http404
|
||||||
|
|
||||||
|
# show contents
|
||||||
|
if request.cloud_mode and request.user.org is not None:
|
||||||
|
org_id = request.user.org.org_id
|
||||||
|
joined_groups = seaserv.get_org_groups_by_user(org_id, username)
|
||||||
|
else:
|
||||||
|
joined_groups = seaserv.get_personal_groups_by_user(username)
|
||||||
|
|
||||||
|
if joined_groups:
|
||||||
|
joined_groups.sort(lambda x, y: cmp(x.group_name.lower(), y.group_name.lower()))
|
||||||
|
|
||||||
|
wiki_exists = True # TODO: remove
|
||||||
|
# 1. get wiki repo
|
||||||
|
repo = seafile_api.get_repo(wiki.repo_id)
|
||||||
|
if not repo:
|
||||||
|
assert False, "TODO"
|
||||||
|
|
||||||
|
# 2. get wiki repo content, ref: wiki/utils.py:get_personal_wiki_page
|
||||||
|
try:
|
||||||
|
wiki_dirent = get_wiki_dirent(repo.id, page_name)
|
||||||
|
except WikiPageMissing:
|
||||||
|
# create missing page...
|
||||||
|
filename = page_name_to_file_name(clean_page_name(page_name))
|
||||||
|
if not seaserv.post_empty_file(repo.id, "/", filename, username):
|
||||||
|
return render_error(request, _("Failed to create wiki page. Please retry later."))
|
||||||
|
# ...and redirect
|
||||||
|
return HttpResponseRedirect(reverse('wiki:slug', args=[slug, page_name]))
|
||||||
|
|
||||||
|
url = get_inner_file_url(repo, wiki_dirent.obj_id, wiki_dirent.obj_name)
|
||||||
|
file_response = urllib2.urlopen(url)
|
||||||
|
content = file_response.read()
|
||||||
|
|
||||||
|
# fetch file modified time and modifier
|
||||||
|
path = '/' + wiki_dirent.obj_name
|
||||||
|
try:
|
||||||
|
dirent = seafile_api.get_dirent_by_path(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
|
||||||
|
|
||||||
|
wiki_index_exists = True
|
||||||
|
index_pagename = 'index'
|
||||||
|
index_content = None
|
||||||
|
try:
|
||||||
|
index_content, index_repo, index_dirent = get_personal_wiki_page(username, index_pagename)
|
||||||
|
except (WikiDoesNotExist, WikiPageMissing):
|
||||||
|
wiki_index_exists = False
|
||||||
|
|
||||||
|
return render_to_response(
|
||||||
|
"wiki/personal_wiki.html", {
|
||||||
|
"wiki_exists": wiki_exists,
|
||||||
|
"content": content,
|
||||||
|
"page": os.path.splitext(dirent.obj_name)[0],
|
||||||
|
"last_modified": last_modified,
|
||||||
|
"latest_contributor": latest_contributor or _("Unknown"),
|
||||||
|
"path": path,
|
||||||
|
"repo_id": repo.id,
|
||||||
|
"search_repo_id": repo.id,
|
||||||
|
"search_wiki": True,
|
||||||
|
"wiki_index_exists": wiki_index_exists,
|
||||||
|
"index_content": index_content,
|
||||||
|
"grps": joined_groups,
|
||||||
|
}, context_instance=RequestContext(request))
|
||||||
|
59
tests/api/endpoints/test_wikis.py
Normal file
59
tests/api/endpoints/test_wikis.py
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
from django.core.urlresolvers import reverse
|
||||||
|
import seaserv
|
||||||
|
from seaserv import seafile_api, ccnet_api
|
||||||
|
|
||||||
|
from seahub.wiki.models import Wiki
|
||||||
|
from seahub.test_utils import BaseTestCase
|
||||||
|
|
||||||
|
|
||||||
|
class WikisViewTest(BaseTestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.url = reverse('api-v2.1-wikis')
|
||||||
|
self.login_as(self.user)
|
||||||
|
|
||||||
|
def test_can_list(self):
|
||||||
|
resp = self.client.get(self.url)
|
||||||
|
self.assertEqual(200, resp.status_code)
|
||||||
|
|
||||||
|
json_resp = json.loads(resp.content)
|
||||||
|
assert len(json_resp['data']) == 0
|
||||||
|
|
||||||
|
wiki = Wiki.objects.add('test wiki', self.user.username,
|
||||||
|
repo_id=self.repo.id)
|
||||||
|
resp = self.client.get(self.url)
|
||||||
|
self.assertEqual(200, resp.status_code)
|
||||||
|
|
||||||
|
json_resp = json.loads(resp.content)
|
||||||
|
assert len(json_resp['data']) == 1
|
||||||
|
assert json_resp['data'][0]['name'] == wiki.name
|
||||||
|
assert 'wikis/test-wiki' in json_resp['data'][0]['link']
|
||||||
|
|
||||||
|
def test_can_add(self):
|
||||||
|
assert len(Wiki.objects.all()) == 0
|
||||||
|
|
||||||
|
resp = self.client.post(self.url, {
|
||||||
|
'name': 'test wiki',
|
||||||
|
'permission': 'private',
|
||||||
|
})
|
||||||
|
self.assertEqual(200, resp.status_code)
|
||||||
|
|
||||||
|
assert len(Wiki.objects.all()) == 1
|
||||||
|
|
||||||
|
|
||||||
|
class WikiViewTest(BaseTestCase):
|
||||||
|
def setUp(self):
|
||||||
|
wiki = Wiki.objects.add('test wiki', self.user.username,
|
||||||
|
repo_id=self.repo.id)
|
||||||
|
|
||||||
|
self.url = reverse('api-v2.1-wiki', args=[wiki.slug])
|
||||||
|
self.login_as(self.user)
|
||||||
|
|
||||||
|
def test_can_delete(self):
|
||||||
|
assert len(Wiki.objects.all()) == 1
|
||||||
|
|
||||||
|
resp = self.client.delete(self.url)
|
||||||
|
self.assertEqual(200, resp.status_code)
|
||||||
|
|
||||||
|
assert len(Wiki.objects.all()) == 0
|
Reference in New Issue
Block a user