diff --git a/templates/repo_history.html b/templates/repo_history.html index 4658c9031c..983f6bccf9 100644 --- a/templates/repo_history.html +++ b/templates/repo_history.html @@ -14,7 +14,8 @@ 修改时间 修改者 - 描述 + 描述 + 操作 {% for commit in commits %} @@ -25,6 +26,11 @@ 未知 {% endif %} {{ commit.props.desc|translate_commit_desc }} + {% if not forloop.last %} + 浏览 + {% else %} + + {% endif %} {% endfor %} diff --git a/templates/repo_history_dir.html b/templates/repo_history_dir.html new file mode 100644 index 0000000000..f2677d27d2 --- /dev/null +++ b/templates/repo_history_dir.html @@ -0,0 +1,79 @@ +{% extends "myhome_base.html" %} +{% load seahub_tags %} + +{% block main_panel %} +
+

{{repo.props.name}} 历史浏览

+
+ {% if not repo.props.encrypted %} + {% if is_owner or repo_ap == 'public' or share_to_me %} +

+ {{ current_commit.props.desc|translate_commit_desc }}
+ by + {% if current_commit.props.creator_name %} + {{ current_commit.props.creator_name }} + {% else %} + 未知 + {% endif %} + + {{ current_commit.props.ctime|tsstr_sec }} +

+ {% endif %} + {% endif %} +

返回历史列表

+
+
+ {% if repo.props.encrypted %} +

该同步目录已加密,不能在线查看。

+ {% else %} + {% if not is_owner and repo_ap == 'own' and not share_to_me %} +

该同步目录web匿名访问未开启,不能在线查看。

+ {% else %} +
+ {% for name, link in zipped %} + {% if not forloop.last %} + {{ name }} / + {% else %} + {{ name }} + {% endif %} + {% endfor %} +
+ + + + + + + + + {% for dirent in dir_list %} + + + + + + + {% endfor %} + + {% for dirent in file_list %} + + + + + + + {% endfor %} +
名字大小操作
{{ dirent.obj_name }}
{{ dirent.props.obj_name }}{{ dirent.file_size|filesizeformat }} + 查看 + 下载 +
+ {% endif %} + {% endif %} +
+
+{% endblock %} + +{% block extra_script %} + +{% endblock %} diff --git a/urls.py b/urls.py index 5ea8b9a099..fdc6b0db68 100644 --- a/urls.py +++ b/urls.py @@ -5,7 +5,7 @@ from django.views.generic.simple import direct_to_template from seahub.views import root, peers, myhome, \ repo, repo_history, modify_token, remove_repo, seafadmin, useradmin, \ role_add, role_remove, activate_user, user_add, user_remove, \ - ownerhome, remove_fetched_repo, \ + ownerhome, remove_fetched_repo, repo_history_dir, \ user_info, repo_set_access_property, repo_access_file, \ repo_add_share, repo_list_share, repo_remove_share, repo_download, \ seafile_access_check, back_local @@ -38,6 +38,7 @@ urlpatterns = patterns('', (r'^repo/(?P[^/]+)/$', repo), (r'^repo/history/(?P[^/]+)/$', repo_history), + (r'^repo/history/dir/(?P[^/]+)/$', repo_history_dir), (r'^repo/token/modify/(?P[^/]+)/$', modify_token), (r'^repo/remove/(?P[^/]+)/$', remove_repo), (r'^repo/removefetched/(?P[^/]+)/(?P[^/]+)/$', remove_fetched_repo), diff --git a/views.py b/views.py index ec735767b9..d412f14603 100644 --- a/views.py +++ b/views.py @@ -92,6 +92,42 @@ def validate_emailuser(emailuser): else: return False +def access_to_repo(request, repo_id, repo_ap): + """ + Check whether user in the request can access to repo, which means user can + view directory entries on repo page, and repo_history_dir page. + + """ + # if repo is 'own' and user is not staff and is not owner + # and not shared this repo, then goto 404 page.. + if repo_ap == 'own' and not validate_owner(request, repo_id) \ + and not check_shared_repo(request, repo_id) and not request.user.is_staff: + return False + else: + return True + +def gen_path_link(path, repo_name): + """ + Generate navigate paths and links in repo page and repo_history_dir page. + Note: `path` must be end with '/'. + + """ + paths = [] + links = [] + if path and path != '/': + paths = path[1:-1].split('/') + i=1 + for name in paths: + link = '/' + '/'.join(paths[:i]) + i = i + 1 + links.append(link) + paths.insert(0, repo_name) + links.insert(0, '/') + + zipped = zip(paths, links) + + return zipped + def repo(request, repo_id): # get repo web access property, if no repo access property in db, then # assume repo ap is 'own' @@ -99,19 +135,15 @@ def repo(request, repo_id): if repo_ap == None: repo_ap = 'own' - # if repo is 'own' and user is not staff and is not owner - # and not shared this repo, then goto 404 page.. - if cmp(repo_ap, 'own') == 0 and not validate_owner(request, repo_id) \ - and not check_shared_repo(request, repo_id) and not request.user.is_staff: + if not access_to_repo(request, repo_id, repo_ap): raise Http404 repo = get_repo(repo_id) - if repo == None: + if not repo: raise Http404 latest_commit = get_commits(repo_id, 0, 1)[0] - token = "" is_owner = False if request.user.is_authenticated(): if validate_owner(request, repo_id): @@ -119,20 +151,19 @@ def repo(request, repo_id): repo_size = seafserv_threaded_rpc.server_repo_size(repo_id) - latest_commit = {} dirs = [] path = '' zipped = [] dir_list = [] file_list = [] if not repo.props.encrypted: - latest_commit = get_commits(repo_id, 0, 1)[0] path = request.GET.get('p', '/') if path[-1] != '/': path = path + '/' try: - dirs = seafserv_rpc.list_dir_by_path(latest_commit.id, path.encode('utf-8')) + dirs = seafserv_rpc.list_dir_by_path(latest_commit.id, + path.encode('utf-8')) except SearpcError, e: return go_error(request, e.msg) for dirent in dirs: @@ -148,20 +179,8 @@ def repo(request, repo_id): file_list.sort(lambda x, y : cmp(x.obj_name.lower(), y.obj_name.lower())) # generate path and link - paths = [] - links = [] - if path and path != '/': - paths = path[1:-1].split('/') - i=1 - for name in paths: - link = '/' + '/'.join(paths[:i]) - i = i + 1 - links.append(link) - paths.insert(0, repo.name) - links.insert(0, '/') + zipped = gen_path_link(path, repo.name) - zipped = zip(paths, links) - # used to determin whether show repo content in repo.html # if a repo is shared to me, or repo shared to the group I joined, # then I can view repo content on the web @@ -213,7 +232,81 @@ def repo_history(request, repo_id): 'page_next': page_next, }, context_instance=RequestContext(request)) +def repo_history_dir(request, repo_id): + # get repo web access property, if no repo access property in db, then + # assume repo ap is 'own' + repo_ap = seafserv_threaded_rpc.repo_query_access_property(repo_id) + if repo_ap == None: + repo_ap = 'own' + + if not access_to_repo(request, repo_id, repo_ap): + raise Http404 + repo = get_repo(repo_id) + if not repo: + raise Http404 + + current_commit = None + commit_id = request.GET.get('commit_id', None) + if commit_id: + current_commit = seafserv_rpc.get_commit(commit_id) + if not current_commit: + raise Http404 + + is_owner = False + if request.user.is_authenticated(): + if validate_owner(request, repo_id): + is_owner = True + + dirs = [] + path = '' + zipped = [] + dir_list = [] + file_list = [] + if not repo.props.encrypted: + path = request.GET.get('p', '/') + if path[-1] != '/': + path = path + '/' + try: + dirs = seafserv_rpc.list_dir_by_path(current_commit.id, + path.encode('utf-8')) + except SearpcError, e: + return go_error(request, e.msg) + for dirent in dirs: + if stat.S_ISDIR(dirent.props.mode): + dir_list.append(dirent) + else: + file_list.append(dirent) + try: + dirent.file_size = seafserv_rpc.get_file_size(dirent.obj_id) + except: + dirent.file_size = 0 + dir_list.sort(lambda x, y : cmp(x.obj_name.lower(), y.obj_name.lower())) + file_list.sort(lambda x, y : cmp(x.obj_name.lower(), y.obj_name.lower())) + + # generate path and link + zipped = gen_path_link(path, repo.name) + + # used to determin whether show repo content in repo.html + # if a repo is shared to me, or repo shared to the group I joined, + # then I can view repo content on the web + if check_shared_repo(request, repo_id): + share_to_me = True + else: + share_to_me = False + + return render_to_response('repo_history_dir.html', { + "repo": repo, + "current_commit": current_commit, + "is_owner": is_owner, + "repo_ap": repo_ap, + "dir_list": dir_list, + "file_list": file_list, + "share_to_me": share_to_me, + "path" : path, + "zipped" : zipped, + }, context_instance=RequestContext(request)) + @login_required def modify_token(request, repo_id): if not validate_owner(request, repo_id): @@ -225,7 +318,6 @@ def modify_token(request, repo_id): return HttpResponseRedirect(reverse(repo, args=[repo_id])) - @login_required def remove_repo(request, repo_id): if not validate_owner(request, repo_id) and not request.user.is_staff: