1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-03 07:55:36 +00:00

View repo history directory.

This commit is contained in:
xiez
2012-05-22 15:28:24 +08:00
parent de984749d0
commit c485c68b5d
4 changed files with 203 additions and 25 deletions

View File

@@ -14,7 +14,8 @@
<tr> <tr>
<th width="20%">修改时间</th> <th width="20%">修改时间</th>
<th width="10%">修改者</th> <th width="10%">修改者</th>
<th width="70%">描述</th> <th width="60%">描述</th>
<th width="10%">操作</th>
</tr> </tr>
{% for commit in commits %} {% for commit in commits %}
<tr> <tr>
@@ -25,6 +26,11 @@
<td>未知</td> <td>未知</td>
{% endif %} {% endif %}
<td>{{ commit.props.desc|translate_commit_desc }}</td> <td>{{ commit.props.desc|translate_commit_desc }}</td>
{% if not forloop.last %}
<td><a href="{{ SITE_ROOT }}repo/history/dir/{{ repo.id }}/?commit_id={{ commit.id }}">浏览</a></td>
{% else %}
<td></td>
{% endif %}
</tr> </tr>
{% endfor %} {% endfor %}
</table> </table>

View File

@@ -0,0 +1,79 @@
{% extends "myhome_base.html" %}
{% load seahub_tags %}
{% block main_panel %}
<div id="repo-page" class="ovhd">
<h2>{{repo.props.name}} 历史浏览</h2>
<div class="side fright">
{% if not repo.props.encrypted %}
{% if is_owner or repo_ap == 'public' or share_to_me %}
<p class="latest-commit mgt10">
{{ current_commit.props.desc|translate_commit_desc }}<br />
<span class="author">by
{% if current_commit.props.creator_name %}
{{ current_commit.props.creator_name }}
{% else %}
未知
{% endif %}
</span>
<span class="time">{{ current_commit.props.ctime|tsstr_sec }}</span>
</p>
{% endif %}
{% endif %}
<a href="{{ SITE_ROOT }}repo/history/{{ repo.id }}/"><p>返回历史列表</p></a>
</div>
<div class="main fleft">
{% if repo.props.encrypted %}
<p>该同步目录已加密,不能在线查看。</p>
{% else %}
{% if not is_owner and repo_ap == 'own' and not share_to_me %}
<p>该同步目录web匿名访问未开启不能在线查看。</p>
{% else %}
<div>
{% for name, link in zipped %}
{% if not forloop.last %}
<a href="{{ SITE_ROOT }}repo/history/dir/{{ repo.id }}/?commit_id={{ current_commit.id}}&p={{ link|urlencode }}">{{ name }}</a> /
{% else %}
{{ name }}
{% endif %}
{% endfor %}
</div>
<table>
<tr>
<th width="5%"></th>
<th width="55%">名字</th>
<th width="10%">大小</th>
<th width="30%">操作</th>
</tr>
{% for dirent in dir_list %}
<tr>
<td><img src="{{ MEDIA_URL }}img/folder-icon-24.png" /></td>
<td><a href="{{ SITE_ROOT }}repo/history/dir/{{ repo.id }}/?commit_id={{ current_commit.id }}&p={{ path|urlencode }}{{ dirent.obj_name|urlencode }}">{{ dirent.obj_name }}</a></td>
<td></td>
<td></td>
</tr>
{% endfor %}
{% for dirent in file_list %}
<tr>
<td><img src="{{ MEDIA_URL }}img/{{ dirent.obj_name|file_icon_filter }}" /></td>
<td>{{ dirent.props.obj_name }}</td>
<td>{{ dirent.file_size|filesizeformat }}</td>
<td>
<a class="op" href="{{ SITE_ROOT }}repo/{{ repo.props.id }}/{{ dirent.props.obj_id }}/?file_name={{ dirent.props.obj_name }}&op=view">查看</a>
<a class="op" href="{{ SITE_ROOT }}repo/{{ repo.props.id }}/{{ dirent.props.obj_id }}/?file_name={{ dirent.props.obj_name }}&op=download">下载</a>
</td>
</tr>
{% endfor %}
</table>
{% endif %}
{% endif %}
</div>
</div>
{% endblock %}
{% block extra_script %}
<script type="text/javascript">
</script>
{% endblock %}

View File

@@ -5,7 +5,7 @@ from django.views.generic.simple import direct_to_template
from seahub.views import root, peers, myhome, \ from seahub.views import root, peers, myhome, \
repo, repo_history, modify_token, remove_repo, seafadmin, useradmin, \ repo, repo_history, modify_token, remove_repo, seafadmin, useradmin, \
role_add, role_remove, activate_user, user_add, user_remove, \ 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, \ user_info, repo_set_access_property, repo_access_file, \
repo_add_share, repo_list_share, repo_remove_share, repo_download, \ repo_add_share, repo_list_share, repo_remove_share, repo_download, \
seafile_access_check, back_local seafile_access_check, back_local
@@ -38,6 +38,7 @@ urlpatterns = patterns('',
(r'^repo/(?P<repo_id>[^/]+)/$', repo), (r'^repo/(?P<repo_id>[^/]+)/$', repo),
(r'^repo/history/(?P<repo_id>[^/]+)/$', repo_history), (r'^repo/history/(?P<repo_id>[^/]+)/$', repo_history),
(r'^repo/history/dir/(?P<repo_id>[^/]+)/$', repo_history_dir),
(r'^repo/token/modify/(?P<repo_id>[^/]+)/$', modify_token), (r'^repo/token/modify/(?P<repo_id>[^/]+)/$', modify_token),
(r'^repo/remove/(?P<repo_id>[^/]+)/$', remove_repo), (r'^repo/remove/(?P<repo_id>[^/]+)/$', remove_repo),
(r'^repo/removefetched/(?P<user_id>[^/]+)/(?P<repo_id>[^/]+)/$', remove_fetched_repo), (r'^repo/removefetched/(?P<user_id>[^/]+)/(?P<repo_id>[^/]+)/$', remove_fetched_repo),

138
views.py
View File

@@ -92,6 +92,42 @@ def validate_emailuser(emailuser):
else: else:
return False 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): def repo(request, repo_id):
# get repo web access property, if no repo access property in db, then # get repo web access property, if no repo access property in db, then
# assume repo ap is 'own' # assume repo ap is 'own'
@@ -99,19 +135,15 @@ def repo(request, repo_id):
if repo_ap == None: if repo_ap == None:
repo_ap = 'own' repo_ap = 'own'
# if repo is 'own' and user is not staff and is not owner if not access_to_repo(request, repo_id, repo_ap):
# 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:
raise Http404 raise Http404
repo = get_repo(repo_id) repo = get_repo(repo_id)
if repo == None: if not repo:
raise Http404 raise Http404
latest_commit = get_commits(repo_id, 0, 1)[0] latest_commit = get_commits(repo_id, 0, 1)[0]
token = ""
is_owner = False is_owner = False
if request.user.is_authenticated(): if request.user.is_authenticated():
if validate_owner(request, repo_id): 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) repo_size = seafserv_threaded_rpc.server_repo_size(repo_id)
latest_commit = {}
dirs = [] dirs = []
path = '' path = ''
zipped = [] zipped = []
dir_list = [] dir_list = []
file_list = [] file_list = []
if not repo.props.encrypted: if not repo.props.encrypted:
latest_commit = get_commits(repo_id, 0, 1)[0]
path = request.GET.get('p', '/') path = request.GET.get('p', '/')
if path[-1] != '/': if path[-1] != '/':
path = path + '/' path = path + '/'
try: 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: except SearpcError, e:
return go_error(request, e.msg) return go_error(request, e.msg)
for dirent in dirs: 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())) file_list.sort(lambda x, y : cmp(x.obj_name.lower(), y.obj_name.lower()))
# generate path and link # generate path and link
paths = [] zipped = gen_path_link(path, repo.name)
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)
# used to determin whether show repo content in repo.html # 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, # if a repo is shared to me, or repo shared to the group I joined,
# then I can view repo content on the web # then I can view repo content on the web
@@ -213,7 +232,81 @@ def repo_history(request, repo_id):
'page_next': page_next, 'page_next': page_next,
}, context_instance=RequestContext(request)) }, 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 @login_required
def modify_token(request, repo_id): def modify_token(request, repo_id):
if not validate_owner(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])) return HttpResponseRedirect(reverse(repo, args=[repo_id]))
@login_required @login_required
def remove_repo(request, repo_id): def remove_repo(request, repo_id):
if not validate_owner(request, repo_id) and not request.user.is_staff: if not validate_owner(request, repo_id) and not request.user.is_staff: