mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-01 15:09:14 +00:00
Add basic recommend feature
This commit is contained in:
@@ -3,8 +3,15 @@ import os
|
||||
from django import forms
|
||||
|
||||
class MessageForm(forms.Form):
|
||||
message = forms.CharField(max_length=500)
|
||||
message = forms.CharField(max_length=5)
|
||||
|
||||
class MessageReplyForm(forms.Form):
|
||||
message = forms.CharField(max_length=150)
|
||||
|
||||
class FileRecommendForm(MessageForm):
|
||||
"""
|
||||
A form used to recommend a file.
|
||||
"""
|
||||
groups = forms.CharField()
|
||||
repo_id = forms.CharField(max_length=40)
|
||||
file_path = forms.CharField()
|
||||
|
@@ -23,6 +23,17 @@ class MessageReply(models.Model):
|
||||
message = models.CharField(max_length=150)
|
||||
timestamp = models.DateTimeField(default=datetime.datetime.now)
|
||||
|
||||
class MessageAttachment(models.Model):
|
||||
"""
|
||||
|
||||
"""
|
||||
group_message = models.ForeignKey(GroupMessage)
|
||||
repo_id = models.CharField(max_length=40)
|
||||
file_path = models.TextField()
|
||||
|
||||
|
||||
|
||||
|
||||
at_pattern = re.compile(r'(\s|^)(@\w+)', flags=re.U)
|
||||
|
||||
@receiver(post_save, sender=MessageReply)
|
||||
|
@@ -102,7 +102,17 @@
|
||||
<a href="{{ SITE_ROOT }}profile/{{ msg.from_email }}/" title="{{ msg.from_email }}">{{ msg.from_email|email2nickname }}</a>
|
||||
</div>
|
||||
<div class="msg-bd">
|
||||
<p>{{ msg.message|linebreaksbr|seahub_urlize|find_at }}</p>
|
||||
{% if msg.attachment %}
|
||||
<span class="recommend">(推荐)</span>
|
||||
{% endif %}
|
||||
<p>
|
||||
{{ msg.message|linebreaksbr|seahub_urlize|find_at }}
|
||||
</p>
|
||||
{% if msg.attachment %}
|
||||
<span>
|
||||
附件: <a href="{% url repo_view_file msg.attachment.repo_id %}?p={{ msg.attachment.file_path }}" target="_blank">查看</a>
|
||||
</span>
|
||||
{% endif %}
|
||||
{% if msg.reply_cnt == 0 %}
|
||||
<a class="reply op" href="#" data="{{ msg.id }}">回复</a>
|
||||
{% else %}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
from django.conf.urls.defaults import *
|
||||
|
||||
from views import group_list, group_info, group_member_operations, \
|
||||
group_members, msg_reply, msg_reply_new
|
||||
group_members, msg_reply, msg_reply_new, group_recommend
|
||||
|
||||
urlpatterns = patterns('',
|
||||
url(r'^(?P<group_id>[\d]+)/$', group_info, name='group_info'),
|
||||
@@ -9,4 +9,5 @@ urlpatterns = patterns('',
|
||||
url(r'^reply/new/$', msg_reply_new, name='msg_reply_new'),
|
||||
url(r'^(?P<group_id>[\d]+)/members/$', group_members, name='group_members'),
|
||||
(r'^(?P<group_id>[\d]+)/member/(?P<user_name>[^/]+)/$', group_member_operations),
|
||||
url(r'^recommend/$', group_recommend, name='group_recommend'),
|
||||
)
|
||||
|
@@ -1,6 +1,7 @@
|
||||
# encoding: utf-8
|
||||
import simplejson as json
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.contrib import messages
|
||||
from django.http import HttpResponse, HttpResponseRedirect, Http404, \
|
||||
HttpResponseBadRequest
|
||||
from django.shortcuts import render_to_response, redirect
|
||||
@@ -13,16 +14,17 @@ from seaserv import ccnet_rpc, ccnet_threaded_rpc, seafserv_threaded_rpc, \
|
||||
get_personal_groups, get_group, get_group_members
|
||||
from pysearpc import SearpcError
|
||||
|
||||
from models import GroupMessage, MessageReply
|
||||
from forms import MessageForm, MessageReplyForm
|
||||
from models import GroupMessage, MessageReply, MessageAttachment
|
||||
from forms import MessageForm, MessageReplyForm, FileRecommendForm
|
||||
from signals import grpmsg_added, grpmsg_reply_added
|
||||
from seahub.contacts.models import Contact
|
||||
from seahub.contacts.signals import mail_sended
|
||||
from seahub.notifications.models import UserNotification
|
||||
from seahub.profile.models import Profile
|
||||
from seahub.settings import SITE_ROOT
|
||||
from seahub.shortcuts import get_first_object_or_none
|
||||
from seahub.utils import render_error, render_permission_error, \
|
||||
validate_group_name, emails2list
|
||||
validate_group_name, string2list
|
||||
from seahub.views import is_registered_user
|
||||
|
||||
@login_required
|
||||
@@ -209,6 +211,8 @@ def render_group_info(request, group_id, form):
|
||||
group_msgs = msgs_plus_one[:per_page]
|
||||
for msg in group_msgs:
|
||||
msg.reply_cnt = len(MessageReply.objects.filter(reply_to=msg))
|
||||
msg.attachment = get_first_object_or_none(
|
||||
MessageAttachment.objects.filter(group_message=msg))
|
||||
|
||||
return render_to_response("group/group_info.html", {
|
||||
"managers": managers,
|
||||
@@ -370,7 +374,7 @@ def group_members(request, group_id):
|
||||
"""
|
||||
member_name_str = request.POST.get('user_name', '')
|
||||
|
||||
member_list = emails2list(member_name_str)
|
||||
member_list = string2list(member_name_str)
|
||||
|
||||
if request.user.org:
|
||||
for member_name in member_list:
|
||||
@@ -489,3 +493,65 @@ def group_unshare_repo(request, repo_id, group_id, from_email):
|
||||
|
||||
if seafserv_threaded_rpc.group_unshare_repo(repo_id, group_id, from_email) != 0:
|
||||
return render_error(request, u'共享失败:内部错误')
|
||||
|
||||
@login_required
|
||||
def group_recommend(request):
|
||||
"""
|
||||
Recommend a file to a group.
|
||||
"""
|
||||
if request.method != 'POST':
|
||||
raise Http404
|
||||
|
||||
next = request.META.get('HTTP_REFERER', None)
|
||||
if not next:
|
||||
next = SITE_ROOT
|
||||
|
||||
form = FileRecommendForm(request.POST)
|
||||
if form.is_valid():
|
||||
groups = form.cleaned_data['groups']
|
||||
repo_id = form.cleaned_data['repo_id']
|
||||
file_path = form.cleaned_data['file_path']
|
||||
message = form.cleaned_data['message']
|
||||
|
||||
group_list = string2list(groups)
|
||||
for e in group_list:
|
||||
group_name = e.split(' ')[0]
|
||||
try:
|
||||
group_creator = e.split(' ')[1]
|
||||
except IndexError:
|
||||
messages.add_message(request, messages.ERROR,
|
||||
u'推荐到 %s 失败,请检查是否参加了该小组。' % \
|
||||
group_name)
|
||||
continue
|
||||
|
||||
# get all the groups the user joined
|
||||
groups = get_personal_groups(request.user.username)
|
||||
find = False
|
||||
for group in groups:
|
||||
# for every group that user joined, if group name and
|
||||
# group creator matchs, then has find the group
|
||||
if group.group_name == group_name and \
|
||||
group_creator.find(group.creator_name) >= 0:
|
||||
find = True
|
||||
# save message to group
|
||||
gm = GroupMessage(group_id=int(group.id),
|
||||
from_email=request.user.username,
|
||||
message=message)
|
||||
gm.save()
|
||||
|
||||
# save attachment
|
||||
ma = MessageAttachment(group_message=gm, repo_id=repo_id,
|
||||
file_path=file_path)
|
||||
ma.save()
|
||||
|
||||
messages.add_message(request, messages.INFO,
|
||||
u'推荐成功,请到该小组页面查看。')
|
||||
break
|
||||
if not find:
|
||||
messages.add_message(request, messages.ERROR,
|
||||
u'推荐到 %s 失败,请检查是否参加了该小组。' % \
|
||||
group_name)
|
||||
else:
|
||||
# TODO: need more clear error message
|
||||
messages.add_message(request, messages.ERROR, '推荐失败')
|
||||
return HttpResponseRedirect(next)
|
||||
|
@@ -118,6 +118,7 @@ p {
|
||||
.w100 {
|
||||
width: 100%;
|
||||
}
|
||||
.info,
|
||||
.notification {
|
||||
padding:5px;
|
||||
background:#FDF;
|
||||
@@ -559,6 +560,10 @@ p {
|
||||
#recommend-msg {
|
||||
width:260px;
|
||||
height:80px;
|
||||
display:block;
|
||||
}
|
||||
#groups {
|
||||
width:260px;
|
||||
}
|
||||
/* group, org */
|
||||
.group-list {
|
||||
@@ -690,6 +695,10 @@ p {
|
||||
.msg-bd .op:hover {
|
||||
text-decoration:none;
|
||||
}
|
||||
.msg-bd .recommend {
|
||||
font-size:12px;
|
||||
color: #880088;
|
||||
}
|
||||
.msg-bd p a {
|
||||
color: #666666;
|
||||
font-weight: normal;
|
||||
|
@@ -28,7 +28,7 @@ from seahub.contacts import Contact
|
||||
from seahub.forms import RepoCreateForm
|
||||
import seahub.settings as seahub_settings
|
||||
from seahub.utils import render_error, render_permission_error, gen_token, \
|
||||
validate_group_name, emails2list, set_cur_ctx, calculate_repo_last_modify,\
|
||||
validate_group_name, string2list, set_cur_ctx, calculate_repo_last_modify,\
|
||||
MAX_INT
|
||||
from seahub.views import myhome
|
||||
|
||||
@@ -155,7 +155,7 @@ def org_useradmin(request, url_prefix):
|
||||
if request.method == 'POST':
|
||||
emails = request.POST.get('added-member-name')
|
||||
|
||||
email_list = emails2list(emails)
|
||||
email_list = string2list(emails)
|
||||
for email in email_list:
|
||||
if not email or email.find('@') <= 0 :
|
||||
continue
|
||||
|
@@ -105,7 +105,7 @@ INSTALLED_APPS = (
|
||||
# 'django.contrib.admin',
|
||||
'django.contrib.messages',
|
||||
|
||||
'auth',
|
||||
# 'auth',
|
||||
'avatar',
|
||||
'registration',
|
||||
|
||||
|
@@ -11,7 +11,7 @@ from django.contrib import messages
|
||||
from django.contrib.sites.models import Site, RequestSite
|
||||
from pysearpc import SearpcError
|
||||
from seaserv import seafserv_threaded_rpc, get_repo, ccnet_rpc, \
|
||||
ccnet_threaded_rpc
|
||||
ccnet_threaded_rpc, get_personal_groups
|
||||
|
||||
from forms import RepoShareForm
|
||||
from models import AnonymousShare
|
||||
@@ -20,7 +20,7 @@ from tokens import anon_share_token_generator
|
||||
from seahub.contacts.signals import mail_sended
|
||||
from seahub.share.models import FileShare
|
||||
from seahub.views import validate_owner, is_registered_user
|
||||
from seahub.utils import render_permission_error, emails2list
|
||||
from seahub.utils import render_permission_error, string2list
|
||||
|
||||
@login_required
|
||||
def share_repo(request):
|
||||
@@ -43,7 +43,7 @@ def share_repo(request):
|
||||
if not validate_owner(request, repo_id):
|
||||
return render_permission_error(request, u'只有目录拥有者有权共享目录')
|
||||
|
||||
to_email_list = emails2list(email_or_group)
|
||||
to_email_list = string2list(email_or_group)
|
||||
for to_email in to_email_list:
|
||||
# if to_email is user name, the format is: 'example@mail.com';
|
||||
# if to_email is group, the format is 'group_name <creator@mail.com>'
|
||||
@@ -57,7 +57,7 @@ def share_repo(request):
|
||||
group_name = to_email.split(' ')[0]
|
||||
group_creator = to_email.split(' ')[1]
|
||||
# get all the groups the user joined
|
||||
groups = ccnet_threaded_rpc.get_groups(request.user.username)
|
||||
groups = get_personal_groups(request.user.username)
|
||||
find = False
|
||||
for group in groups:
|
||||
# for every group that user joined, if group name and
|
||||
|
@@ -11,6 +11,16 @@
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block right_panel %}
|
||||
{% if messages %}
|
||||
<ul class="messages">
|
||||
{% for message in messages %}
|
||||
<li class="{{ message.tags }}">{{ message }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block main_panel %}
|
||||
<h2>
|
||||
{% if not view_history %}
|
||||
@@ -68,7 +78,7 @@
|
||||
<p id="success" class="hide"></p>
|
||||
</form>
|
||||
|
||||
<form action="" method="post" id="recommend-form" class="hide">
|
||||
<form action="{% url group_recommend %}" method="post" id="recommend-form" class="hide">
|
||||
<p>推荐
|
||||
{% for name, link in zipped %}
|
||||
{% if not forloop.last %}
|
||||
@@ -76,9 +86,12 @@
|
||||
{% else %}
|
||||
{{ name }}
|
||||
{% endif %}
|
||||
{% endfor %} :
|
||||
{% endfor %} 到小组:
|
||||
</p>
|
||||
<textarea name="recommend-msg" id="recommend-msg"></textarea><br />
|
||||
<input type="input" name="groups" id="groups" value="" />
|
||||
<textarea name="message" id="recommend-msg"></textarea><br />
|
||||
<input type="hidden" name="repo_id" value="{{ repo.id }}" />
|
||||
<input type="hidden" name="file_path" value="{{ path }}" />
|
||||
<input type="submit" class="submit" value="提交" />
|
||||
<button class="simplemodal-close">取消</button>
|
||||
</form>
|
||||
@@ -195,6 +208,16 @@ $("#link-send-form").submit(function(event) {
|
||||
return false;
|
||||
});
|
||||
|
||||
$(function() {
|
||||
// recommend form autocomplete
|
||||
var group_list = []
|
||||
{% for group in groups %}
|
||||
group_list.push('{{ group.props.group_name }} <{{ group.props.creator_name }}>');
|
||||
{% endfor %}
|
||||
addAutocomplete('#groups', '#recommend-form', group_list);
|
||||
$('.ui-autocomplete').css({'max-height': window.innerHeight - $('.ui-autocomplete-input').offset().top - $('.ui-autocomplete-input').height() - 10, 'overflow': 'auto'});
|
||||
|
||||
});
|
||||
{% include "snippets/bottom_bar.html" %}
|
||||
{% endif %}
|
||||
</script>
|
||||
|
@@ -1,4 +1,4 @@
|
||||
var Bottom_bar = '<div id="bottom-bar"><button id="recommend">推荐</button> <button id="recommend">发送到私信</button></div>';
|
||||
var Bottom_bar = '<div id="bottom-bar"><button id="recommend">推荐到小组</button> <button id="recommend">发送到私信</button></div>';
|
||||
$('#wrapper').append(Bottom_bar);
|
||||
$('#bottom-bar').css({'position':'fixed', 'bottom':0, 'left':$('#main').offset().left + $('#main').width() + 15});
|
||||
$('#recommend').click(function() {
|
||||
|
11
utils.py
11
utils.py
@@ -297,14 +297,15 @@ def get_ccnet_server_addr_port():
|
||||
"""get ccnet server host and port"""
|
||||
return CCNET_SERVER_ADDR, CCNET_SERVER_PORT
|
||||
|
||||
def emails2list(emails):
|
||||
def string2list(string):
|
||||
"""
|
||||
Split email strings contacted with diffent separator.
|
||||
Split strings contacted with diffent separator to a list, and remove
|
||||
duplicated string.
|
||||
"""
|
||||
email_str = emails.replace(';', ',').replace('\n', ',').replace('\r', ',')
|
||||
# Remove empty strings and duplicate emails
|
||||
tmp_str = string.replace(';', ',').replace('\n', ',').replace('\r', ',')
|
||||
# Remove empty and duplicate strings
|
||||
s = set()
|
||||
for e in email_str.split(','):
|
||||
for e in tmp_str.split(','):
|
||||
e = e.strip(' ')
|
||||
if not e:
|
||||
continue
|
||||
|
10
views.py
10
views.py
@@ -48,7 +48,7 @@ from utils import render_permission_error, render_error, list_to_string, \
|
||||
calculate_repo_last_modify, valid_previewed_file, \
|
||||
check_filename_with_rename, get_accessible_repos, EMPTY_SHA1, \
|
||||
get_file_revision_id_size, get_ccnet_server_addr_port, \
|
||||
gen_file_get_url, emails2list, set_cur_ctx, MAX_INT
|
||||
gen_file_get_url, string2list, set_cur_ctx, MAX_INT
|
||||
from seahub.profile.models import Profile
|
||||
try:
|
||||
from settings import CROCODOC_API_TOKEN
|
||||
@@ -823,6 +823,9 @@ def repo_view_file(request, repo_id):
|
||||
# my constacts
|
||||
contacts = Contact.objects.filter(user_email=request.user.username)
|
||||
|
||||
# my groups
|
||||
groups = get_personal_groups(request.user.username)
|
||||
|
||||
return render_to_response('repo_view_file.html', {
|
||||
'repo': repo,
|
||||
'obj_id': obj_id,
|
||||
@@ -843,6 +846,7 @@ def repo_view_file(request, repo_id):
|
||||
'contacts': contacts,
|
||||
'err': err,
|
||||
'file_content': file_content,
|
||||
'groups': groups,
|
||||
}, context_instance=RequestContext(request))
|
||||
|
||||
def repo_file_get(raw_path):
|
||||
@@ -1582,7 +1586,7 @@ def repo_create(request):
|
||||
repo_name = form.cleaned_data['repo_name']
|
||||
repo_desc = form.cleaned_data['repo_desc']
|
||||
encrypted = form.cleaned_data['encryption']
|
||||
passwd = form.cleaned_data['passwd']
|
||||
passwd = form.cleasened_data['passwd']
|
||||
passwd_again = form.cleaned_data['passwd_again']
|
||||
user = request.user.username
|
||||
|
||||
@@ -1856,7 +1860,7 @@ def send_shared_link(request):
|
||||
file_shared_link = form.cleaned_data['file_shared_link']
|
||||
|
||||
t = loader.get_template('shared_link_email.html')
|
||||
to_email_list = emails2list(email)
|
||||
to_email_list = string2list(email)
|
||||
for to_email in to_email_list:
|
||||
# Add email to contacts
|
||||
mail_sended.send(sender=None, user=request.user.username,
|
||||
|
Reference in New Issue
Block a user