mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-03 07:55:36 +00:00
resolve conflict in merge
This commit is contained in:
@@ -17,6 +17,7 @@ ul > li { list-style:none; }
|
|||||||
.label { color:#333; font-size:12px; font-style:normal; }
|
.label { color:#333; font-size:12px; font-style:normal; }
|
||||||
a { color:#ee8833; text-decoration:none; font-weight:bold; }
|
a { color:#ee8833; text-decoration:none; font-weight:bold; }
|
||||||
a:hover { color: #ff9933; text-decoration: underline; }
|
a:hover { color: #ff9933; text-decoration: underline; }
|
||||||
|
img { border:none; }
|
||||||
/* table */
|
/* table */
|
||||||
table { border-spacing: 0; border-collapse: collapse; width:100%; table-layout:fixed; margin:3px 0 5px; }
|
table { border-spacing: 0; border-collapse: collapse; width:100%; table-layout:fixed; margin:3px 0 5px; }
|
||||||
td, th { padding: 3px; word-break:break-word; }
|
td, th { padding: 3px; word-break:break-word; }
|
||||||
@@ -44,7 +45,7 @@ tr.first { background-color: #00FF00; }
|
|||||||
#other-info { color: #ccc; text-align:right; }
|
#other-info { color: #ccc; text-align:right; }
|
||||||
#other-info .wish { font-style:italic; margin-bottom:10px; }
|
#other-info .wish { font-style:italic; margin-bottom:10px; }
|
||||||
#other-info .version { font-size: 12px; }
|
#other-info .version { font-size: 12px; }
|
||||||
#header .nav { border-bottom: 1px solid #ddd; }
|
#header .nav { border-bottom: 1px solid #ddd; margin-top:8px; }
|
||||||
#header .nav li { float: left; height: 18px; padding: 0px 25px 4px 0; background: none; }
|
#header .nav li { float: left; height: 18px; padding: 0px 25px 4px 0; background: none; }
|
||||||
#header .nav a, #header .nav a:visited { color:#8A948F; font-weight:bold; text-decoration:none; }
|
#header .nav a, #header .nav a:visited { color:#8A948F; font-weight:bold; text-decoration:none; }
|
||||||
#header .nav a.cur { color: #000; }
|
#header .nav a.cur { color: #000; }
|
||||||
@@ -55,13 +56,11 @@ tr.first { background-color: #00FF00; }
|
|||||||
h2 { font-size:18px; color:#808; margin-bottom:8px; }
|
h2 { font-size:18px; color:#808; margin-bottom:8px; }
|
||||||
h3 { font-size:14px; color:#808; font-weight:normal; }
|
h3 { font-size:14px; color:#808; font-weight:normal; }
|
||||||
ol { margin:0; padding:0px 0 0 2em; list-style-position:inside; }
|
ol { margin:0; padding:0px 0 0 2em; list-style-position:inside; }
|
||||||
ul { padding:0 0 0 0; margin: 8px 0 8px 0; }
|
|
||||||
ul > li { background: url('../img/li.gif') no-repeat scroll; background-position:left 6px; padding-left:10px; }
|
ul > li { background: url('../img/li.gif') no-repeat scroll; background-position:left 6px; padding-left:10px; }
|
||||||
/* #main ul.ui-tabs-nav > li { background: none; } */
|
/* #main ul.ui-tabs-nav > li { background: none; } */
|
||||||
#main ol > li { }
|
#main ol > li { }
|
||||||
#main li { line-height:20px; }
|
#main li { line-height:20px; }
|
||||||
#main img.click { margin-left:2px; cursor:pointer; }
|
#main img.click { margin-left:2px; cursor:pointer; }
|
||||||
|
|
||||||
/* profile */
|
/* profile */
|
||||||
.avatar_op .pic { float:left; margin-right:15px; }
|
.avatar_op .pic { float:left; margin-right:15px; }
|
||||||
.avatar_op .text { float:left; }
|
.avatar_op .text { float:left; }
|
||||||
@@ -235,3 +234,14 @@ input.ccnet_id { width: 400px; }
|
|||||||
font-size:16px;
|
font-size:16px;
|
||||||
margin-bottom:14px;
|
margin-bottom:14px;
|
||||||
}
|
}
|
||||||
|
/*repo-share-form*/
|
||||||
|
#to_email {
|
||||||
|
width:260px;
|
||||||
|
height:80px;
|
||||||
|
}
|
||||||
|
.text-core {
|
||||||
|
width:272px;
|
||||||
|
}
|
||||||
|
.text-suggestion {
|
||||||
|
background:none;
|
||||||
|
}
|
||||||
|
9
media/js/jquery.textext.js
Normal file
9
media/js/jquery.textext.js
Normal file
File diff suppressed because one or more lines are too long
@@ -36,7 +36,7 @@
|
|||||||
<div id="header">
|
<div id="header">
|
||||||
<div class="top-info ovhd">
|
<div class="top-info ovhd">
|
||||||
<a href="{{ SITE_ROOT }}" class="fleft"><img src="{{ MEDIA_URL }}img/logo.png" title="Seafile" alt="Seafile logo" /></a>
|
<a href="{{ SITE_ROOT }}" class="fleft"><img src="{{ MEDIA_URL }}img/logo.png" title="Seafile" alt="Seafile logo" /></a>
|
||||||
<div id="other-info">
|
<div id="other-info" class="fright">
|
||||||
<p class="wish">Hope our efforts will bring you benefits.</p>
|
<p class="wish">Hope our efforts will bring you benefits.</p>
|
||||||
<p class="version">服务器版本: {{ seafile_version }}</p>
|
<p class="version">服务器版本: {{ seafile_version }}</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -94,6 +94,7 @@
|
|||||||
<script type="text/javascript" src="{{ MEDIA_URL }}js/jquery.simplemodal.1.4.1.min.js"></script>
|
<script type="text/javascript" src="{{ MEDIA_URL }}js/jquery.simplemodal.1.4.1.min.js"></script>
|
||||||
<script type="text/javascript" src="{{ MEDIA_URL }}js/jquery.cookie.js"></script>
|
<script type="text/javascript" src="{{ MEDIA_URL }}js/jquery.cookie.js"></script>
|
||||||
<script type="text/javascript" src="{{ MEDIA_URL }}js/jquery-ui-1.8.16.custom.min.js"></script>
|
<script type="text/javascript" src="{{ MEDIA_URL }}js/jquery-ui-1.8.16.custom.min.js"></script>
|
||||||
|
<script type="text/javascript" src="{{ MEDIA_URL }}js/jquery.textext.js"></script>
|
||||||
<script type="text/javascript" src="{{ MEDIA_URL }}js/utils.js"></script>
|
<script type="text/javascript" src="{{ MEDIA_URL }}js/utils.js"></script>
|
||||||
{% block extra_script %}{% endblock %}
|
{% block extra_script %}{% endblock %}
|
||||||
</body>
|
</body>
|
||||||
|
@@ -71,7 +71,7 @@
|
|||||||
|
|
||||||
<form id="repo-share-form" action="{{ SITE_ROOT }}home/my/" method="post" name="repo-share-form" class="hide">
|
<form id="repo-share-form" action="{{ SITE_ROOT }}home/my/" method="post" name="repo-share-form" class="hide">
|
||||||
<label>邮箱(多个邮箱以;分隔)</label><br />
|
<label>邮箱(多个邮箱以;分隔)</label><br />
|
||||||
<textarea id="to_email" name="to_email" value="" cols="30" rows="5" ></textarea><br />
|
<textarea id="to_email" name="to_email"></textarea>
|
||||||
<input id="share_repo_id" type="hidden" name="share_repo_id" value="" />
|
<input id="share_repo_id" type="hidden" name="share_repo_id" value="" />
|
||||||
<input type="submit" value="提交" />
|
<input type="submit" value="提交" />
|
||||||
</form>
|
</form>
|
||||||
@@ -87,5 +87,31 @@ $(".repo-share-btn").click(function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
addConfirmTo($('.repo-delete-btn'));
|
addConfirmTo($('.repo-delete-btn'));
|
||||||
|
|
||||||
|
//repo-share-form email autocomplete
|
||||||
|
$('#to_email').textext({
|
||||||
|
plugins: 'autocomplete',
|
||||||
|
autocomplete: {
|
||||||
|
dropdownPosition: 'below',
|
||||||
|
render: function(suggestion) {
|
||||||
|
return suggestion;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
html: {
|
||||||
|
dropdown: '<div class="text-dropdown"><ul class="text-list"></ul></div>',
|
||||||
|
suggestion: '<li class="text-suggestion"><span class="text-label"></span></li>'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.bind('getSuggestions', function(e, data) {
|
||||||
|
var list = [],
|
||||||
|
textext = $(e.target).textext()[0],
|
||||||
|
query = (data ? data.query : '') || '';
|
||||||
|
|
||||||
|
{% for contact in contacts %}
|
||||||
|
list.push('{{ contact.contact_email }}');
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
$(this).trigger('setSuggestions', { result: textext.itemManager().filter(list, query) });
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@@ -8,6 +8,8 @@
|
|||||||
<p>{{repo.props.desc}}</p>
|
<p>{{repo.props.desc}}</p>
|
||||||
<p>大小:{{ repo_size|filesizeformat }}</p>
|
<p>大小:{{ repo_size|filesizeformat }}</p>
|
||||||
|
|
||||||
|
{% if not repo.props.encrypted %}
|
||||||
|
{% if is_owner or repo_ap == 'public' or share_to_me %}
|
||||||
<p class="latest-commit mgt10">
|
<p class="latest-commit mgt10">
|
||||||
{{ latest_commit.props.desc }}<br />
|
{{ latest_commit.props.desc }}<br />
|
||||||
<span class="author">by
|
<span class="author">by
|
||||||
@@ -34,10 +36,15 @@
|
|||||||
<span>只有同步目录拥有者可设置</span>
|
<span>只有同步目录拥有者可设置</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</p>
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div class="main fleft">
|
<div class="main fleft">
|
||||||
{% if repo.props.encrypted %}
|
{% if repo.props.encrypted %}
|
||||||
<p>该同步目录已加密,不能在线查看。</p>
|
<p>该同步目录已加密,不能在线查看。</p>
|
||||||
|
{% else %}
|
||||||
|
{% if not is_owner and repo_ap == 'own' and not share_to_me %}
|
||||||
|
<p>该同步目录web匿名访问未开启,不能在线查看。</p>
|
||||||
{% else %}
|
{% else %}
|
||||||
<table class="repo-list">
|
<table class="repo-list">
|
||||||
<tr>
|
<tr>
|
||||||
@@ -61,6 +68,7 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div id="public-access-start-confirm" class="hide">
|
<div id="public-access-start-confirm" class="hide">
|
||||||
<p>确定要开启吗?</p>
|
<p>确定要开启吗?</p>
|
||||||
|
65
views.py
65
views.py
@@ -9,6 +9,7 @@ from django.views.decorators.csrf import csrf_protect
|
|||||||
from auth.forms import AuthenticationForm, PasswordResetForm, SetPasswordForm, PasswordChangeForm
|
from auth.forms import AuthenticationForm, PasswordResetForm, SetPasswordForm, PasswordChangeForm
|
||||||
from auth.tokens import default_token_generator
|
from auth.tokens import default_token_generator
|
||||||
|
|
||||||
|
from pysearpc import SearpcError
|
||||||
from seaserv import cclient, ccnet_rpc, get_groups, get_users, get_repos, \
|
from seaserv import cclient, ccnet_rpc, get_groups, get_users, get_repos, \
|
||||||
get_repo, get_commits, get_branches, \
|
get_repo, get_commits, get_branches, \
|
||||||
seafserv_threaded_rpc, seafserv_rpc, get_binding_peerids, get_ccnetuser
|
seafserv_threaded_rpc, seafserv_rpc, get_binding_peerids, get_ccnetuser
|
||||||
@@ -19,6 +20,8 @@ from seahub.base.accounts import CcnetUser
|
|||||||
from forms import AddUserForm
|
from forms import AddUserForm
|
||||||
from urllib import quote
|
from urllib import quote
|
||||||
|
|
||||||
|
from seahub.contacts.models import Contact
|
||||||
|
|
||||||
import stat
|
import stat
|
||||||
import time
|
import time
|
||||||
import settings
|
import settings
|
||||||
@@ -161,33 +164,39 @@ def validate_emailuser(email):
|
|||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@login_required
|
|
||||||
def repo(request, repo_id):
|
def repo(request, repo_id):
|
||||||
# if user is not staff and not owner and not fetch this repo
|
# 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 repo is 'own' and user is not staff and is not owner
|
||||||
# and not shared this repo, then goto 404 page..
|
# and not shared this repo, then goto 404 page..
|
||||||
if not validate_owner(request, repo_id) and not check_shared_repo(request, repo_id) \
|
if cmp(repo_ap, 'own') == 0 and not validate_owner(request, repo_id) \
|
||||||
and not request.user.is_staff:
|
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:
|
||||||
|
raise Http404
|
||||||
|
|
||||||
latest_commit = get_commits(repo_id, 0, 1)[0]
|
latest_commit = get_commits(repo_id, 0, 1)[0]
|
||||||
|
|
||||||
token = ""
|
token = ""
|
||||||
is_owner = False
|
is_owner = False
|
||||||
repo_ap = ""
|
|
||||||
|
|
||||||
if request.user.is_authenticated():
|
if request.user.is_authenticated():
|
||||||
if validate_owner(request, repo_id):
|
if validate_owner(request, repo_id):
|
||||||
is_owner = True
|
is_owner = True
|
||||||
token = seafserv_threaded_rpc.get_repo_token(repo_id)
|
|
||||||
repo_ap = seafserv_threaded_rpc.repo_query_access_property(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 = []
|
||||||
if not repo.props.encrypted:
|
if not repo.props.encrypted:
|
||||||
|
latest_commit = get_commits(repo_id, 0, 1)[0]
|
||||||
if not request.GET.get('root_id'):
|
if not request.GET.get('root_id'):
|
||||||
# ..use HEAD commit's root id
|
# use HEAD commit's root id
|
||||||
commit = seafserv_rpc.get_commit(repo.props.head_cmmt_id)
|
commit = seafserv_rpc.get_commit(repo.props.head_cmmt_id)
|
||||||
root_id = commit.props.root_id
|
root_id = commit.props.root_id
|
||||||
else:
|
else:
|
||||||
@@ -203,14 +212,20 @@ def repo(request, repo_id):
|
|||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# used to determin whether show repo content in repo.html
|
||||||
|
# if a repo is shared to me, 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.html', {
|
return render_to_response('repo.html', {
|
||||||
"repo": repo,
|
"repo": repo,
|
||||||
"latest_commit": latest_commit,
|
"latest_commit": latest_commit,
|
||||||
"is_owner": is_owner,
|
"is_owner": is_owner,
|
||||||
"repo_ap": repo_ap,
|
"repo_ap": repo_ap,
|
||||||
"repo_size": repo_size,
|
"repo_size": repo_size,
|
||||||
"token": token,
|
|
||||||
"dirs": dirs,
|
"dirs": dirs,
|
||||||
|
"share_to_me": share_to_me,
|
||||||
}, context_instance=RequestContext(request))
|
}, context_instance=RequestContext(request))
|
||||||
|
|
||||||
|
|
||||||
@@ -297,11 +312,14 @@ def myhome(request):
|
|||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
output_msg = repo_add_share(request)
|
output_msg = repo_add_share(request)
|
||||||
|
|
||||||
|
contacts = Contact.objects.filter(user_email=email)
|
||||||
|
|
||||||
return render_to_response('myhome.html', {
|
return render_to_response('myhome.html', {
|
||||||
"owned_repos": owned_repos,
|
"owned_repos": owned_repos,
|
||||||
"quota_usage": quota_usage,
|
"quota_usage": quota_usage,
|
||||||
"in_repos": in_repos,
|
"in_repos": in_repos,
|
||||||
"output_msg": output_msg
|
"output_msg": output_msg,
|
||||||
|
"contacts": contacts,
|
||||||
}, context_instance=RequestContext(request))
|
}, context_instance=RequestContext(request))
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@@ -371,24 +389,31 @@ def repo_list_dir(request, repo_id):
|
|||||||
},
|
},
|
||||||
context_instance=RequestContext(request))
|
context_instance=RequestContext(request))
|
||||||
|
|
||||||
@login_required
|
|
||||||
def repo_operation_file(request, op, repo_id, obj_id):
|
def repo_operation_file(request, op, repo_id, obj_id):
|
||||||
if repo_id:
|
if repo_id:
|
||||||
# any person visit private repo, go to 404 page
|
# if a repo doesn't have access property in db, then assume it's 'own'
|
||||||
repo_ap = seafserv_threaded_rpc.repo_query_access_property(repo_id)
|
repo_ap = seafserv_threaded_rpc.repo_query_access_property(repo_id)
|
||||||
if repo_ap == 'private':
|
if not repo_ap:
|
||||||
raise Http404
|
repo_ap = 'own'
|
||||||
|
|
||||||
|
# if a repo is shared to me, then I can view and download file no mater whether
|
||||||
|
# repo's access property is 'own' or 'public'
|
||||||
|
if check_shared_repo(request, repo_id):
|
||||||
|
share_to_me = True
|
||||||
|
else:
|
||||||
|
share_to_me = False
|
||||||
|
|
||||||
token = ''
|
token = ''
|
||||||
if not repo_ap or repo_ap == 'own':
|
if repo_ap == 'own':
|
||||||
# people who is not owner visits own repo, go to 404 page
|
# people who is owner or this repo is shared to him, can visit the repo;
|
||||||
if not validate_owner(request, repo_id):
|
# others, just go to 404 page
|
||||||
raise Http404
|
if validate_owner(request, repo_id) or share_to_me:
|
||||||
else:
|
|
||||||
# owner should get a token to visit repo
|
# owner should get a token to visit repo
|
||||||
token = gen_token()
|
token = gen_token()
|
||||||
# put token into memory in seaf-server
|
# put token into memory in seaf-server
|
||||||
seafserv_rpc.web_save_access_token(token, obj_id)
|
seafserv_rpc.web_save_access_token(token, obj_id)
|
||||||
|
else:
|
||||||
|
raise Http404
|
||||||
|
|
||||||
http_server_root = get_httpserver_root()
|
http_server_root = get_httpserver_root()
|
||||||
file_name = request.GET.get('file_name', '')
|
file_name = request.GET.get('file_name', '')
|
||||||
|
Reference in New Issue
Block a user