1
0
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:
xiez
2012-08-10 21:16:55 +08:00
parent 354b1154a4
commit bfefa7df70
13 changed files with 160 additions and 28 deletions

View File

@@ -3,8 +3,15 @@ import os
from django import forms from django import forms
class MessageForm(forms.Form): class MessageForm(forms.Form):
message = forms.CharField(max_length=500) message = forms.CharField(max_length=5)
class MessageReplyForm(forms.Form): class MessageReplyForm(forms.Form):
message = forms.CharField(max_length=150) 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()

View File

@@ -23,6 +23,17 @@ class MessageReply(models.Model):
message = models.CharField(max_length=150) message = models.CharField(max_length=150)
timestamp = models.DateTimeField(default=datetime.datetime.now) 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) at_pattern = re.compile(r'(\s|^)(@\w+)', flags=re.U)
@receiver(post_save, sender=MessageReply) @receiver(post_save, sender=MessageReply)

View File

@@ -102,7 +102,17 @@
<a href="{{ SITE_ROOT }}profile/{{ msg.from_email }}/" title="{{ msg.from_email }}">{{ msg.from_email|email2nickname }}</a> <a href="{{ SITE_ROOT }}profile/{{ msg.from_email }}/" title="{{ msg.from_email }}">{{ msg.from_email|email2nickname }}</a>
</div> </div>
<div class="msg-bd"> <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 %} {% if msg.reply_cnt == 0 %}
<a class="reply op" href="#" data="{{ msg.id }}">回复</a> <a class="reply op" href="#" data="{{ msg.id }}">回复</a>
{% else %} {% else %}

View File

@@ -1,7 +1,7 @@
from django.conf.urls.defaults import * from django.conf.urls.defaults import *
from views import group_list, group_info, group_member_operations, \ 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('', urlpatterns = patterns('',
url(r'^(?P<group_id>[\d]+)/$', group_info, name='group_info'), 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'^reply/new/$', msg_reply_new, name='msg_reply_new'),
url(r'^(?P<group_id>[\d]+)/members/$', group_members, name='group_members'), url(r'^(?P<group_id>[\d]+)/members/$', group_members, name='group_members'),
(r'^(?P<group_id>[\d]+)/member/(?P<user_name>[^/]+)/$', group_member_operations), (r'^(?P<group_id>[\d]+)/member/(?P<user_name>[^/]+)/$', group_member_operations),
url(r'^recommend/$', group_recommend, name='group_recommend'),
) )

View File

@@ -1,6 +1,7 @@
# encoding: utf-8 # encoding: utf-8
import simplejson as json import simplejson as json
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.contrib import messages
from django.http import HttpResponse, HttpResponseRedirect, Http404, \ from django.http import HttpResponse, HttpResponseRedirect, Http404, \
HttpResponseBadRequest HttpResponseBadRequest
from django.shortcuts import render_to_response, redirect 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 get_personal_groups, get_group, get_group_members
from pysearpc import SearpcError from pysearpc import SearpcError
from models import GroupMessage, MessageReply from models import GroupMessage, MessageReply, MessageAttachment
from forms import MessageForm, MessageReplyForm from forms import MessageForm, MessageReplyForm, FileRecommendForm
from signals import grpmsg_added, grpmsg_reply_added from signals import grpmsg_added, grpmsg_reply_added
from seahub.contacts.models import Contact from seahub.contacts.models import Contact
from seahub.contacts.signals import mail_sended from seahub.contacts.signals import mail_sended
from seahub.notifications.models import UserNotification from seahub.notifications.models import UserNotification
from seahub.profile.models import Profile from seahub.profile.models import Profile
from seahub.settings import SITE_ROOT from seahub.settings import SITE_ROOT
from seahub.shortcuts import get_first_object_or_none
from seahub.utils import render_error, render_permission_error, \ from seahub.utils import render_error, render_permission_error, \
validate_group_name, emails2list validate_group_name, string2list
from seahub.views import is_registered_user from seahub.views import is_registered_user
@login_required @login_required
@@ -209,7 +211,9 @@ def render_group_info(request, group_id, form):
group_msgs = msgs_plus_one[:per_page] group_msgs = msgs_plus_one[:per_page]
for msg in group_msgs: for msg in group_msgs:
msg.reply_cnt = len(MessageReply.objects.filter(reply_to=msg)) 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", { return render_to_response("group/group_info.html", {
"managers": managers, "managers": managers,
"common_members": common_members, "common_members": common_members,
@@ -370,7 +374,7 @@ def group_members(request, group_id):
""" """
member_name_str = request.POST.get('user_name', '') member_name_str = request.POST.get('user_name', '')
member_list = emails2list(member_name_str) member_list = string2list(member_name_str)
if request.user.org: if request.user.org:
for member_name in member_list: 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: if seafserv_threaded_rpc.group_unshare_repo(repo_id, group_id, from_email) != 0:
return render_error(request, u'共享失败:内部错误') 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)

View File

@@ -118,6 +118,7 @@ p {
.w100 { .w100 {
width: 100%; width: 100%;
} }
.info,
.notification { .notification {
padding:5px; padding:5px;
background:#FDF; background:#FDF;
@@ -559,6 +560,10 @@ p {
#recommend-msg { #recommend-msg {
width:260px; width:260px;
height:80px; height:80px;
display:block;
}
#groups {
width:260px;
} }
/* group, org */ /* group, org */
.group-list { .group-list {
@@ -690,6 +695,10 @@ p {
.msg-bd .op:hover { .msg-bd .op:hover {
text-decoration:none; text-decoration:none;
} }
.msg-bd .recommend {
font-size:12px;
color: #880088;
}
.msg-bd p a { .msg-bd p a {
color: #666666; color: #666666;
font-weight: normal; font-weight: normal;

View File

@@ -28,7 +28,7 @@ from seahub.contacts import Contact
from seahub.forms import RepoCreateForm from seahub.forms import RepoCreateForm
import seahub.settings as seahub_settings import seahub.settings as seahub_settings
from seahub.utils import render_error, render_permission_error, gen_token, \ 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 MAX_INT
from seahub.views import myhome from seahub.views import myhome
@@ -155,7 +155,7 @@ def org_useradmin(request, url_prefix):
if request.method == 'POST': if request.method == 'POST':
emails = request.POST.get('added-member-name') emails = request.POST.get('added-member-name')
email_list = emails2list(emails) email_list = string2list(emails)
for email in email_list: for email in email_list:
if not email or email.find('@') <= 0 : if not email or email.find('@') <= 0 :
continue continue

View File

@@ -105,7 +105,7 @@ INSTALLED_APPS = (
# 'django.contrib.admin', # 'django.contrib.admin',
'django.contrib.messages', 'django.contrib.messages',
'auth', # 'auth',
'avatar', 'avatar',
'registration', 'registration',

View File

@@ -11,7 +11,7 @@ from django.contrib import messages
from django.contrib.sites.models import Site, RequestSite from django.contrib.sites.models import Site, RequestSite
from pysearpc import SearpcError from pysearpc import SearpcError
from seaserv import seafserv_threaded_rpc, get_repo, ccnet_rpc, \ from seaserv import seafserv_threaded_rpc, get_repo, ccnet_rpc, \
ccnet_threaded_rpc ccnet_threaded_rpc, get_personal_groups
from forms import RepoShareForm from forms import RepoShareForm
from models import AnonymousShare from models import AnonymousShare
@@ -20,7 +20,7 @@ from tokens import anon_share_token_generator
from seahub.contacts.signals import mail_sended from seahub.contacts.signals import mail_sended
from seahub.share.models import FileShare from seahub.share.models import FileShare
from seahub.views import validate_owner, is_registered_user 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 @login_required
def share_repo(request): def share_repo(request):
@@ -43,7 +43,7 @@ def share_repo(request):
if not validate_owner(request, repo_id): if not validate_owner(request, repo_id):
return render_permission_error(request, u'只有目录拥有者有权共享目录') 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: for to_email in to_email_list:
# if to_email is user name, the format is: 'example@mail.com'; # 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>' # 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_name = to_email.split(' ')[0]
group_creator = to_email.split(' ')[1] group_creator = to_email.split(' ')[1]
# get all the groups the user joined # 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 find = False
for group in groups: for group in groups:
# for every group that user joined, if group name and # for every group that user joined, if group name and

View File

@@ -11,6 +11,16 @@
{% endif %} {% endif %}
{% endblock %} {% 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 %} {% block main_panel %}
<h2> <h2>
{% if not view_history %} {% if not view_history %}
@@ -68,17 +78,20 @@
<p id="success" class="hide"></p> <p id="success" class="hide"></p>
</form> </form>
<form action="" method="post" id="recommend-form" class="hide"> <form action="{% url group_recommend %}" method="post" id="recommend-form" class="hide">
<p>推荐 <p>推荐
{% for name, link in zipped %} {% for name, link in zipped %}
{% if not forloop.last %} {% if not forloop.last %}
{{ name }} / {{ name }} /
{% else %} {% else %}
{{ name }} {{ name }}
{% endif %} {% endif %}
{% endfor %} : {% endfor %} 到小组:
</p> </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="提交" /> <input type="submit" class="submit" value="提交" />
<button class="simplemodal-close">取消</button> <button class="simplemodal-close">取消</button>
</form> </form>
@@ -195,6 +208,16 @@ $("#link-send-form").submit(function(event) {
return false; 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" %} {% include "snippets/bottom_bar.html" %}
{% endif %} {% endif %}
</script> </script>

View File

@@ -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); $('#wrapper').append(Bottom_bar);
$('#bottom-bar').css({'position':'fixed', 'bottom':0, 'left':$('#main').offset().left + $('#main').width() + 15}); $('#bottom-bar').css({'position':'fixed', 'bottom':0, 'left':$('#main').offset().left + $('#main').width() + 15});
$('#recommend').click(function() { $('#recommend').click(function() {

View File

@@ -297,14 +297,15 @@ def get_ccnet_server_addr_port():
"""get ccnet server host and port""" """get ccnet server host and port"""
return CCNET_SERVER_ADDR, CCNET_SERVER_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', ',') tmp_str = string.replace(';', ',').replace('\n', ',').replace('\r', ',')
# Remove empty strings and duplicate emails # Remove empty and duplicate strings
s = set() s = set()
for e in email_str.split(','): for e in tmp_str.split(','):
e = e.strip(' ') e = e.strip(' ')
if not e: if not e:
continue continue

View File

@@ -48,7 +48,7 @@ from utils import render_permission_error, render_error, list_to_string, \
calculate_repo_last_modify, valid_previewed_file, \ calculate_repo_last_modify, valid_previewed_file, \
check_filename_with_rename, get_accessible_repos, EMPTY_SHA1, \ check_filename_with_rename, get_accessible_repos, EMPTY_SHA1, \
get_file_revision_id_size, get_ccnet_server_addr_port, \ 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 from seahub.profile.models import Profile
try: try:
from settings import CROCODOC_API_TOKEN from settings import CROCODOC_API_TOKEN
@@ -822,6 +822,9 @@ def repo_view_file(request, repo_id):
# my constacts # my constacts
contacts = Contact.objects.filter(user_email=request.user.username) 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', { return render_to_response('repo_view_file.html', {
'repo': repo, 'repo': repo,
@@ -843,6 +846,7 @@ def repo_view_file(request, repo_id):
'contacts': contacts, 'contacts': contacts,
'err': err, 'err': err,
'file_content': file_content, 'file_content': file_content,
'groups': groups,
}, context_instance=RequestContext(request)) }, context_instance=RequestContext(request))
def repo_file_get(raw_path): def repo_file_get(raw_path):
@@ -1582,7 +1586,7 @@ def repo_create(request):
repo_name = form.cleaned_data['repo_name'] repo_name = form.cleaned_data['repo_name']
repo_desc = form.cleaned_data['repo_desc'] repo_desc = form.cleaned_data['repo_desc']
encrypted = form.cleaned_data['encryption'] encrypted = form.cleaned_data['encryption']
passwd = form.cleaned_data['passwd'] passwd = form.cleasened_data['passwd']
passwd_again = form.cleaned_data['passwd_again'] passwd_again = form.cleaned_data['passwd_again']
user = request.user.username user = request.user.username
@@ -1856,7 +1860,7 @@ def send_shared_link(request):
file_shared_link = form.cleaned_data['file_shared_link'] file_shared_link = form.cleaned_data['file_shared_link']
t = loader.get_template('shared_link_email.html') 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: for to_email in to_email_list:
# Add email to contacts # Add email to contacts
mail_sended.send(sender=None, user=request.user.username, mail_sended.send(sender=None, user=request.user.username,