def forum_reply(self, group_id, category_id, thread_id): try: group_id = int(group_id) group = Group.get(group_id) except ValueError: group = Group.get(group_id) try: thread_id = int(thread_id) category_id = int(category_id) except ValueError: abort(404) category = ForumCategory.get(category_id) thread = ForumPost.get(thread_id) if group is None or category is None or thread is None: abort(404) post = make_forum_post(c.user, thread.title, self.form_result['message'], group_id=group.group_id, category_id=category_id, thread_id=thread_id, controller='forum') thread.mark_as_seen_by(c.user) meta.Session.commit() if request.params.has_key('js'): return render_mako_def('/sections/wall_entries.mako', 'thread_reply', id=post.id, author_id=post.created.id, message=post.message, created_on=post.created_on, allow_comment_deletion=True) else: self._redirect()
def setUpModeratorGroup(): u = User.get('*****@*****.**', LocationTag.get(u'uni')) meta.set_active_user(u.id) g = Group('moderators', u'Moderatoriai', LocationTag.get(u'uni'), date.today(), u'U2ti moderatoriai.') g.moderators = True g.add_member(u, True) meta.Session.add(g) meta.Session.commit() meta.set_active_user(u.id)
def mailinglist_reply(self, group_id, thread_id): try: group = Group.get(int(group_id)) thread_id = int(thread_id) except ValueError: abort(404) thread = GroupMailingListMessage.get(thread_id, group.id) if group is None or thread is None: abort(404) last_post = thread.posts[-1] msg = post_message(group, c.user, u"Re: %s" % thread.subject, self.form_result['message'], reply_to=last_post.message_id) if request.params.has_key('js'): return render_mako_def('/sections/wall_entries.mako', 'thread_reply', id=msg.id, author_id=msg.author_id if msg.author_id is not None else msg.author_or_anonymous, message=msg.body, created_on=msg.sent, attachments=msg.attachments, allow_comment_deletion=False) else: self._redirect()
def _handle_group_message(self, msg): parts = msg.message_text.split(None, 1) if len(parts) != 2: return _('Invalid group message: %s') % msg.message_text group_id, text = parts if not msg.sender: return _('The phone number %s is not associated with a Ututi user') % (msg.sender_phone_number) group = Group.get(group_id) if group is None: return _('Invalid group: %s') % group_id max_group_members = config.get('sms_max_group_members', 40) if len(group.recipients_sms(sender=msg.sender)) > max_group_members: return ungettext( 'More than %d recipient, cannot send message.', 'More than %d recipients, cannot send message.', max_group_members) % max_group_members # Send message. msg = OutgoingGroupSMSMessage(sender=msg.sender, group=group, message_text=text) meta.Session.add(msg) msg.send() msg.success = True return _('SMS message sent to group %s.') % group_id
def create(self): if hasattr(self, 'form_result'): values = self.form_result year = int(values.get('year') or date.today().year) group = Group(group_id=values['id'], title=values['title'], description=values['description'], year=date(year, 1, 1)) group.mailinglist_enabled = True group.location = values.get('location', None) meta.Session.add(group) if values['logo_upload'] is not None: logo = values['logo_upload'] group.logo = logo.file.read() group.add_member(c.user, admin=True) meta.Session.commit() redirect(group.url(action='invite_members_step')) defaults = dict([('location-%d' % n, tag) for n, tag in enumerate(c.user.location.hierarchy())]) c.preset_location = c.user.location return htmlfill.render(self._create_form(), defaults=defaults)
def validate_python(self, value, state): if value != 0: g = Group.get(value) if g is not None: raise Invalid(self.message('duplicate', state), value, state) usernameRE = re.compile(r"^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*$", re.I) if not usernameRE.search(value): raise Invalid(self.message('badId', state), value, state)
def validate_python(self, form_dict, state): group_id = form_dict.get('group_id') group = Group.get(int(group_id)) if group is not None and group.is_member(c.user): form_dict['group'] = group else: raise Invalid(self.message('invalid', state), form_dict, state, error_dict={'group_id': Invalid(self.message('invalid', state), form_dict, state)})
def update_binding(self): from ututi.model import Group hostname = config.get('mailing_list_host', 'groups.ututi.lt') self.group = None if self.email.endswith(hostname): group = Group.get(self.email[:-(len(hostname)+1)]) if group is not None: self.group = group else: raise GroupNotFoundException()
def _handle_group_space(self, msg): group_id = msg.message_text.strip() group = Group.get(group_id) if group is None: return _('Invalid group: %s') % group_id group.purchase_days(31) msg.success = True return _('Purchased another month of group space for "%s" (until %s).' ) % (group.group_id, group.private_files_lock_date.date().isoformat())
def group_members(group_id, limit=6): from ututi.model import Group group = Group.get(int(group_id)) members = group.members[:limit] return [{'id': member.user_id, 'title': member.user.fullname, 'url': member.user.url(), 'logo_url': member.user.url(action='logo', width=45), 'logo_small_url': member.user.url(action='logo', width=30)} for member in members]
def get(cls, message_id, group_id): try: g = Group.get(group_id) if g is None: return None #??? is the way it is supposed to be? if isinstance(message_id, (long, int)): return meta.Session.query(cls).filter_by(id=message_id, group_id=g.id).one() return meta.Session.query(cls).filter_by(message_id=message_id, group_id=g.id).one() except NoResultFound: return None
def _send_emails(user, post, group_id=None, category_id=None, controller=""): if group_id: forum_title = Group.get(group_id).title else: forum_title = _("Community") if category_id == 1 else _("Bugs") thread = ForumPost.get(post.thread_id) new_thread = thread.is_thread() extra_vars = dict( message=post.message, person_title=user.fullname, forum_title=forum_title, thread_url=url( controller=controller, action="thread", id=group_id, category_id=category_id, thread_id=post.thread_id, qualified=True, ), ) email_message = render("/emails/forum_message.mako", extra_vars=extra_vars) recipients = set() for subscription in thread.subscriptions: if subscription.active and subscription.user.id != user.id: for email in subscription.user.emails: if email.confirmed: recipients.add(email.email) break else: # Explicit unsubscription. for email in subscription.user.emails: try: recipients.remove(email.email) except KeyError: pass ml_id = group_id if not ml_id: ml_id = {1: _("ututi-community"), 2: _("ututi-bugs")}[int(category_id)] if recipients: re = "Re: " if not new_thread else "" send_email( config["ututi_email_from"], config["ututi_email_from"], "[%s] %s%s" % (ml_id, re, post.title), email_message, message_id=_generateMessageId(), send_to=list(recipients), )
def _group_action(self, id=None): if id is None: redirect(url(controller='search', obj_type='group')) group = Group.get(id) if group is None: abort(404) check_forum_setting(group) c.security_context = group c.object_location = group.location c.group = group c.group_menu_items = group_menu_items() c.breadcrumbs = [{'title': group.title, 'link': group.url()}] c.theme = group.location.get_theme() return method(self, group)
def _group_action(self, id, file_id): group = Group.get(id) if group is None: abort(404) file = File.get(file_id) if file not in group.files: abort(404) c.security_context = file c.object_location = group.location c.group = group c.breadcrumbs = [{'title': group.title, 'link': group.url()}] return method(self, group, file)
def _to_python(self, value, state): obj = None # check if this is a plain numeric id try: num_id = int(value) obj = ContentItem.get(num_id) except ValueError: pass # check if the id is a path to a subject if obj is None and value.startswith('subject'): path = value.split('/')[1:] location = LocationTag.get(path[:-1]) obj = Subject.get(location, path.pop()) # check if the object is a group if obj is None and value.startswith('group'): id = value.split('/') obj = Group.get(id.pop()) return obj
def make_forum_post(user, title, message, group_id, category_id, thread_id=None, controller=None): new_thread = thread_id is None post = ForumPost(title, message, category_id=category_id, thread_id=thread_id) meta.Session.add(post) meta.Session.commit() meta.Session.refresh(post) # Subscribe logged in user to the thread subscription = SubscribedThread.get_or_create(post.thread_id, user, activate=True) # If this is a new thread; automatically subscribe all # interested members. if group_id and new_thread: group = Group.get(group_id) for member in group.members: if member.subscribed_to_forum: SubscribedThread.get_or_create(post.thread_id, member.user, activate=True) _send_emails(user, post, group_id, category_id, controller=controller) return post
def set_up_context(self, id=None, category_id=None, thread_id=None): if id is not None: c.group = Group.get(id) if c.group is None: abort(404) c.group_id = c.group.group_id c.group_menu_items = group_menu_items() c.object_location = c.group.location c.security_context = c.group c.theme = c.group.location.get_theme() c.breadcrumbs.append({'title': c.group.title, 'link': c.group.url()}) else: c.group = None c.group_id = None if category_id is not None: try: category_id = int(category_id) except ValueError: abort(404) c.category = ForumCategory.get(category_id) if c.category is None: abort(404) c.breadcrumbs.append({'title': c.category.title, 'link': url(controller=c.controller, action='index', id=id, category_id=category_id)}) else: c.category = None if thread_id is not None: try: thread_id = int(thread_id) except ValueError: abort(404) c.thread = ForumPost.get(thread_id) if c.thread is None: abort(404) assert c.thread.category_id == int(c.category.id), repr(c.thread.category_id) else: c.thread = None
def getGroup(self): mailing_list_host = config.get('mailing_list_host') mailing_list_hosts = [mailing_list_host, 'lists.ututi.lt', 'groups.ututi.lt'] group_ids = [] for name, address in self.getToAddresses(): if '@' not in address: continue prefix, suffix = address.split('@') if suffix in mailing_list_hosts: group_ids.append(prefix) # XXX what if I CC message to 2 groups at the same time? g = None if group_ids: for group_id in group_ids: g = Group.get(group_id) if g is not None: break return g
def _group_action(self, id, thread_id): group = Group.get(id) if group is None: abort(404) check_forum_setting(group) thread = meta.Session.query(GroupMailingListMessage).filter_by( id=thread_id).first() if (thread is None or thread.group != group): abort(404) if (thread.thread != thread and not thread.in_moderation_queue): abort(404) c.security_context = group c.group = group c.object_location = group.location c.group_menu_items = group_menu_items() c.breadcrumbs = [{'title': group.title, 'link': group.url()}] c.theme = group.location.get_theme() return method(self, group, thread)
def _group_action(self, id, message_id, file_id): group = Group.get(id) if group is None: abort(404) message = meta.Session.query(GroupMailingListMessage).filter_by(id=message_id).first() if message is None: abort(404) if isinstance(file_id, basestring): file_id = re.search(r"\d*", file_id).group() file = File.get(file_id) if file is None: #not in group.files: ??? are mailing list files added as the group's files? abort(404) c.security_context = group c.object_location = group.location c.group = group c.group_menu_items = group_menu_items() c.breadcrumbs = [{'title': group.title, 'link': group.url()}] c.theme = group.location.get_theme() return method(self, group, message, file)
def ftest_setUp(test): ututi.tests.setUp(test) # U-niversity and D-epartment # should be used in writing new functional tests uni = LocationTag(u'U-niversity', u'uni', u'', member_policy='PUBLIC') dep = LocationTag(u'D-epartment', u'dep', u'', uni, member_policy='PUBLIC') meta.Session.add(uni) meta.Session.add(dep) meta.Session.commit() # Admin user, named 'Adminas Adminovix' for backward compatibility create_user('Adminas Adminovix', '*****@*****.**', 'xnIVufqLhFFcgX+XjkkwGbrY6kBBk0vvwjA7', 'uni') # Below are old locations, users, groups and subjects for backward compatibility # Note: objects that didn't have their location specified are now assigned to U-niversity vu = LocationTag(u'Vilniaus universitetas', u'vu', u'Seniausias universitetas Lietuvoje.', member_policy='PUBLIC') ef = LocationTag(u'Ekonomikos fakultetas', u'ef', u'', vu, member_policy='PUBLIC') gf = LocationTag(u'Geografijos fakultetas', u'gf', u'', vu, member_policy='PUBLIC') meta.Session.add(vu) meta.Session.add(ef) meta.Session.add(gf) region = Region(u'Mazowieckie', u'lt') meta.Session.add(region) # Users: first = User(u'Alternative user', '*****@*****.**', uni, 'password', True) meta.Session.add(first) email = Email('*****@*****.**') email.confirmed = True first.emails.append(email) second = User(u'Second user', '*****@*****.**', uni, 'password', True) meta.Session.add(second) email = Email('*****@*****.**') email.confirmed = True second.emails.append(email) second.phone_number = '+37067412345' second.phone_confirmed = True admin = User.get('*****@*****.**', uni) admin.phone_number = '+37067812375' admin.phone_confirmed = True # Third user has hist email uncofirmed third = User(u'Third user', '*****@*****.**', uni, 'password', True) meta.Session.add(third) email = Email('*****@*****.**') email.confirmed = False third.emails.append(email) # A verified teacher Benas benas = Teacher(fullname=u'Benas', username='******', location=uni, password='******', gen_password=True) benas.teacher_verified = True meta.Session.add(benas) email = Email('*****@*****.**') email.confirmed = True benas.emails.append(email) # Groups: meta.Session.execute("SET LOCAL ututi.active_user TO %d" % admin.id) moderators = Group('moderators', u'Moderatoriai', uni, date(date.today().year, 1, 1), u'U2ti moderatoriai.') meta.Session.add(moderators) moderators.add_member(admin, True) moderators.add_member(third) testgroup = Group('testgroup', u'Testing group', LocationTag.get(u'vu'), date(date.today().year, 1, 1), u'Testing group') meta.Session.add(testgroup) testgroup.mailinglist_enabled = False testgroup.add_member(admin, True) testgroup.add_member(second) # Subjects: math = Subject(u'mat_analize', u'Matematin\u0117 analiz\u0117', LocationTag.get(u'vu'), u'prof. E. Misevi\u010dius') meta.Session.add(math) third.watchSubject(math) # Tags: tag = SimpleTag(u'simple_tag') meta.Session.add(tag) meta.Session.commit()
def test_setup(test): """Create some models needed for the tests.""" ututi.tests.setUp(test) initialize_dictionaries(meta.engine) config = pylons.test.pylonsapp.config config['default_search_dict'] = 'public.universal' vu = LocationTag(u'Vilniaus universitetas', u'vu', u'', member_policy='PUBLIC') ef = LocationTag(u'Ekonomikos fakultetas', u'ef', u'', vu, member_policy='PUBLIC') meta.Session.add(vu) meta.Session.add(ef) # We need someone who can create subjects and groups user = User(u'User', '*****@*****.**', vu, 'password') meta.Session.add(user) meta.Session.commit() meta.Session.execute("SET default_text_search_config TO 'public.universal'") meta.set_active_user(user.id) l = LocationTag(u'Kauno technologijos universitetas', u'ktu', u'', member_policy='PUBLIC') f = LocationTag(u'Ekologijos fakultetas', u'ef', u'', l, member_policy='PUBLIC') mtag = SimpleTag(u'Ekologijos fakultetas') #a mixed tag meta.Session.add(l) meta.Session.add(f) g = Group('agroup', u'Ekologai', description=u'testas') g.location = f meta.Session.add(g) g = Group('new_group', u'Bioinformatikai', description=u'Grup\u0117 kurioje domimasi biologija ir informatika') meta.Session.add(g) # a tagged group g2 = Group('new_grp', u'Biology students', description=u'biologija matematika informatikos mokslas') g2.location = LocationTag.get(u'vu/ef') meta.Session.add(g2) tg = SimpleTag(u'test tag') g2.tags.append(tg) s = Subject(u'subj_id', u'Test subject', LocationTag.get(u'VU')) s.description = u'pagrindai' t = SimpleTag(u'a tag') meta.Session.add(t) s.tags.append(t) s.tags.append(mtag) meta.Session.add(s) p = Page(u'page title', u'Puslapio tekstas') meta.Session.add(p) s.pages.append(p) s = Subject('biologija', u'Biologijos pagrindai', LocationTag.get(u'vu')) p = Page(u'page title', u'Puslapio tekstas') s.pages.append(p) meta.Session.add(s) meta.Session.add(p) f = File(u'test.txt', u'geografija', 'text/txt') f.parent = s meta.Session.add(f) meta.Session.commit() meta.Session.execute("SET default_text_search_config TO 'public.universal'")