mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-11 11:51:27 +00:00
Add diff functionality on seahub.
This commit is contained in:
@@ -264,6 +264,21 @@ table img {
|
||||
font-size:16px;
|
||||
margin-bottom:14px;
|
||||
}
|
||||
.lsch {
|
||||
font-size:12px;
|
||||
color:#666;
|
||||
text-decoration:underline;
|
||||
}
|
||||
#ls-ch {/*repo commit details container*/
|
||||
min-width:300px;
|
||||
min-height:300px;
|
||||
max-width:850px;
|
||||
max-height:550px;
|
||||
overflow:auto;
|
||||
}
|
||||
#ls-ch ul {
|
||||
padding:0 0 6px 0;
|
||||
}
|
||||
/*repo-share-form*/
|
||||
#to_email,
|
||||
#added-member-name {
|
||||
|
3
po.py
3
po.py
@@ -9,5 +9,8 @@ TRANSLATION_MAP = {
|
||||
'and' : u'以及另外',
|
||||
'more files' : u'个文件',
|
||||
'Reverted repo to status at' : u'同步目录内容还原到',
|
||||
'Merged ' : u'合并了',
|
||||
'\'s changes' : u' 的修改',
|
||||
'other' : u'其他人',
|
||||
'Merged others\' changes' : u'合并了其他人的修改',
|
||||
}
|
||||
|
@@ -25,7 +25,12 @@
|
||||
{% else %}
|
||||
<td>未知</td>
|
||||
{% endif %}
|
||||
<td>{{ commit.props.desc|translate_commit_desc }}</td>
|
||||
<td>
|
||||
{{ commit.props.desc|translate_commit_desc }}
|
||||
{% if not forloop.last %}
|
||||
<a class="lsch" href="{{ SITE_ROOT }}repo/history/changes/{{ repo.id }}/?commit_id={{ commit.id }}">详情</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
{% if not forloop.last %}
|
||||
<td>
|
||||
<a href="{{ SITE_ROOT }}repo/history/dir/{{ repo.id }}/?commit_id={{ commit.id }}">浏览</a>
|
||||
@@ -63,10 +68,57 @@
|
||||
<a href="?per_page=100" class="per-page">100</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div id="ls-ch" class="hide"></div><!--list modification details of a commit-->
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_script %}
|
||||
<script type="text/javascript">
|
||||
addConfirmTo($(".repo-revert"), '确定要还原该目录?');
|
||||
//list modification made by a commit;for repo,repo_history
|
||||
$('.lsch').each(function() {
|
||||
$(this).click(function() {
|
||||
$.ajax({
|
||||
url: $(this).attr('href'),
|
||||
dataType: 'json',
|
||||
cache: false,
|
||||
contentType: 'application/json; charset=utf-8',
|
||||
success: function(data) {
|
||||
var str_title = '<h3>修改详情</h3>';
|
||||
var str_con = '';
|
||||
var show = function(data_) {
|
||||
str_con += '<ul>';
|
||||
for (var i = 0, len = data_.length; i < len; i++) {
|
||||
str_con += '<li>' + data_[i] + '</li>';
|
||||
}
|
||||
str_con += '</ul>';
|
||||
};
|
||||
if (data['new'].length > 0) {
|
||||
str_con += '<h4 id="ls-ch-new">新文件</h4>';
|
||||
show(data['new']);
|
||||
}
|
||||
if (data['removed'].length > 0) {
|
||||
str_con += '<h4 id="ls-ch-rm">删除的文件</h4>';
|
||||
show(data['removed']);
|
||||
}
|
||||
if (data['renamed'].length > 0) {
|
||||
str_con += '<h4 id="ls-ch-rn">移动的文件</h4>';
|
||||
show(data['renamed']);
|
||||
}
|
||||
if (data['modified'].length > 0) {
|
||||
str_con += '<h4 id="ls-ch-modi">修改的文件</h4>';
|
||||
show(data['modified']);
|
||||
}
|
||||
if (!str_con) {
|
||||
str_con = '<p>没有文件被改动</p>';
|
||||
}
|
||||
$('#ls-ch').html(str_title + str_con);
|
||||
$('#ls-ch').modal({appendTo:'#main'});
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
addConfirmTo($(".repo-revert"), '确定要还原该目录?');
|
||||
{% endblock %}
|
||||
|
3
urls.py
3
urls.py
@@ -8,7 +8,7 @@ from seahub.views import root, peers, myhome, \
|
||||
ownerhome, remove_fetched_repo, repo_history_dir, repo_history_revert, \
|
||||
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, group_admin
|
||||
seafile_access_check, back_local, group_admin, repo_history_changes
|
||||
|
||||
# Uncomment the next two lines to enable the admin:
|
||||
#from django.contrib import admin
|
||||
@@ -41,6 +41,7 @@ urlpatterns = patterns('',
|
||||
(r'^repo/history/dir/(?P<repo_id>[^/]+)/$', repo_history_dir),
|
||||
(r'^repo/history/revert/(?P<repo_id>[^/]+)/$', repo_history_revert),
|
||||
# (r'^repo/token/modify/(?P<repo_id>[^/]+)/$', modify_token),
|
||||
(r'^repo/history/changes/(?P<repo_id>[^/]+)/$', repo_history_changes),
|
||||
(r'^repo/remove/(?P<repo_id>[^/]+)/$', remove_repo),
|
||||
# (r'^repo/removefetched/(?P<user_id>[^/]+)/(?P<repo_id>[^/]+)/$', remove_fetched_repo),
|
||||
(r'^repo/setap/(?P<repo_id>[^/]+)/$', repo_set_access_property),
|
||||
|
83
views.py
83
views.py
@@ -1,6 +1,7 @@
|
||||
# encoding: utf-8
|
||||
import settings
|
||||
import stat
|
||||
import simplejson as json
|
||||
from urllib import quote
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.db import IntegrityError
|
||||
@@ -426,6 +427,88 @@ def repo_history_revert(request, repo_id):
|
||||
|
||||
return HttpResponseRedirect(reverse(repo_history, args=[repo_id]))
|
||||
|
||||
def get_filename(start, ent):
|
||||
i = start + 1
|
||||
lenidx = start - 1
|
||||
while i <= len(ent):
|
||||
tmp = " ".join(ent[start:i])
|
||||
if len(tmp) == int(ent[lenidx]):
|
||||
return (tmp, i)
|
||||
i = i + 1
|
||||
return ("", 0)
|
||||
|
||||
def add_to_status_list(lists, status_ent):
|
||||
if status_ent[1] == 'A':
|
||||
filename, index = get_filename(4, status_ent)
|
||||
lists['new'].append(filename)
|
||||
elif status_ent[1] == 'D':
|
||||
filename, index = get_filename(4, status_ent)
|
||||
lists['removed'].append(filename)
|
||||
elif status_ent[1] == 'R':
|
||||
filename1, index1 = get_filename(4, status_ent)
|
||||
filename2, index2 = get_filename(index1 + 1, status_ent)
|
||||
lists['renamed'].append(filename1 + u' 被移动到 ' + filename2)
|
||||
elif status_ent[1] == 'M':
|
||||
filename, index = get_filename(4, status_ent)
|
||||
lists['modified'].append(filename)
|
||||
|
||||
def get_diff(repo_id, arg1, arg2):
|
||||
lists = {'new' : [], 'removed' : [], 'renamed' : [], 'modified' : []}
|
||||
|
||||
diff_result = seafserv_threaded_rpc.get_diff(repo_id, arg1, arg2)
|
||||
if diff_result == "":
|
||||
return lists;
|
||||
|
||||
diff_result = diff_result[:len(diff_result)-1]
|
||||
|
||||
for d in diff_result.split("\n"):
|
||||
tmp = d.split(" ")
|
||||
if tmp[0] == 'C':
|
||||
add_to_status_list(lists, tmp)
|
||||
|
||||
return lists
|
||||
|
||||
def repo_history_changes(request, repo_id):
|
||||
changes = {}
|
||||
content_type = 'application/json; charset=utf-8'
|
||||
|
||||
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):
|
||||
return HttpResponse(json.dumps(changes),
|
||||
content_type=content_type)
|
||||
|
||||
repo = get_repo(repo_id)
|
||||
if not repo:
|
||||
return HttpResponse(json.dumps(changes),
|
||||
content_type=content_type)
|
||||
|
||||
password_set = False
|
||||
if repo.props.encrypted:
|
||||
try:
|
||||
ret = seafserv_rpc.is_passwd_set(repo_id, request.user.username)
|
||||
if ret == 1:
|
||||
password_set = True
|
||||
except:
|
||||
return HttpResponse(json.dumps(changes),
|
||||
content_type=content_type)
|
||||
|
||||
if repo.props.encrypted and not password_set:
|
||||
return HttpResponse(json.dumps(changes),
|
||||
content_type=content_type)
|
||||
|
||||
commit_id = request.GET.get('commit_id', '')
|
||||
if not commit_id:
|
||||
return HttpResponse(json.dumps(changes),
|
||||
content_type=content_type)
|
||||
|
||||
changes = get_diff(repo_id, '', commit_id)
|
||||
|
||||
return HttpResponse(json.dumps(changes),
|
||||
content_type=content_type)
|
||||
|
||||
@login_required
|
||||
def modify_token(request, repo_id):
|
||||
if not validate_owner(request, repo_id):
|
||||
|
Reference in New Issue
Block a user