def start(self): self.db = DataBase([User, UserTimeLine, UserContact, UserBoard, ContentType]) self.notifier = Notifier(self.db)
class Article(Base): def start(self): from movuca import DataBase, User, UserTimeLine from datamodel.article import Category, Article, ContentType, Favoriters, Subscribers, Likers, Dislikers, Comments self.db = DataBase([User, UserTimeLine, ContentType, Category, Article, Favoriters, Subscribers, Likers, Dislikers, Comments]) from handlers.notification import Notifier self.notifier = Notifier(self.db) def pre_render(self): # obrigatorio ter um config, um self.response|request, que tenha um render self.response.render self.response = self.db.response self.request = self.db.request self.config = self.db.config self.session = self.db.session self.T = self.db.T self.CURL = self.db.CURL self.get_image = self.db.get_image self.context.theme_name = self.config.theme.name #self.view = "app/home.html" self.context.content_types = self.db(self.db.ContentType).select() def lastest_articles(self): from helpers.article import latest_articles self.context.latest_articles = latest_articles(self.db) def related_articles(self): from helpers.article import related_articles related_articles = related_articles(self.db, self.context.article.tags, self.context.article.category_id, self.context.article.id) if related_articles: self.context.related_articles = UL(*[LI( DIV( IMG(_src=self.get_image(related.thumbnail, related.content_type_id.identifier), _width=100, _height=100, _style="max-height:100px;"), A(related.title, _href=self.CURL('article', 'show', args=[related.id, related.slug])), _class="thumbnail"), **{'_class': "span2", '_data-url': self.CURL('article', 'show', args=[related.id, related.slug])} ) for related in related_articles], **dict(_class="related-articles thumbnails")) else: self.context.related_articles = False def comments(self): comment_system = { "internal": self.comment_internal, "disqus": self.comment_disqus, "intense": self.comment_intense, "facebook": self.comment_facebook, "disabled": self.comment_disabled } self.context.comments = comment_system[self.config.comment.system]() def comment_disabled(self): return " " def comment_internal(self): is_author = False if self.session.auth and self.session.auth.user: is_author = True if self.session.auth.user.id == self.context.article.author else False self.db.Comments.article_id.default = self.context.article.id self.db.Comments.user_id.default = self.session.auth.user.id self.db.Comments.commenttime.default = self.request.now self.db.Comments.comment_text.label = self.T("Post your comment") from plugin_ckeditor import CKEditor ckeditor = CKEditor() self.db.Comments.comment_text.widget = ckeditor.basicwidget form = SQLFORM(self.db.Comments, formstyle='divs') submit_button = form.elements(_type='submit')[0] submit_button['_class'] = "btn btn-info" submit_button['_value'] = self.T("Post comment") if form.process(message_onsuccess=self.T('Comment included')).accepted: self.new_article_event('new_article_comment', self.session.auth.user, data={'event_text': form.vars.comment_text, 'event_link': form.vars.nickname or form.vars.user_id, 'event_image': self.get_image(None, 'user', themename=self.context.theme_name, user=self.session.auth.user), 'event_link_to': "%s/%s#comment_%s" % (self.context.article.id, self.context.article.slug, form.vars.id)}) else: form = CAT(A(self.T("Login to post comments"), _class="button btn", _href=self.CURL('default', 'user', args='login', vars=dict(_next=self.CURL('article', 'show', args=[self.context.article.id, self.context.article.slug])))), BR(), BR()) if 'commentlimitby' in self.request.vars: limitby = [int(item) for item in self.request.vars.commentlimitby.split(',')] else: limitby = (0, 5) comment_set = self.db(self.db.Comments.article_id == self.context.article.id) comments = comment_set.select(orderby=~self.db.Comments.created_on, limitby=limitby) if comments and is_author: edit_in_place = ckeditor.bulk_edit_in_place(["comment_%(id)s" % comment for comment in comments], URL('editcomment')) elif comments and self.session.auth and self.session.auth.user: usercomments = comments.find(lambda row: row.user_id == self.session.auth.user.id) if usercomments: edit_in_place = ckeditor.bulk_edit_in_place(["comment_%(id)s" % comment for comment in usercomments], URL('editcomment')) else: edit_in_place = ('', '') else: edit_in_place = ('', '') self.context.lencomments = comment_set.count() def showmore(anchor, limitby=limitby, lencomments=self.context.lencomments): if lencomments > limitby[1]: return A(self.T('show more comments'), _class="button btn", _style="width:97%;", _href=self.CURL(args=self.request.args, vars={"commentlimitby": "0,%s" % (limitby[1] + 10)}, anchor=anchor)) else: return '' return DIV( H4(IMG(_src=URL('static', '%s/images/icons' % self.context.theme_name, args='board.24.png')), self.T("Comments"), " (%s)" % self.context.lencomments), UL(form, *[LI( H5( A( self.T("%s %s", (comment.nickname or comment.user_id, self.db.pdate(comment.commenttime))), _href=self.CURL('person', 'show', args=comment.nickname or comment.user_id)) ), DIV( XML(comment.comment_text), **{'_class': 'editable commentitem', '_data-object': 'comment', '_data-id': comment.id, '_id': "comment_%s" % comment.id} ), _class="comment_li" ) for comment in comments], **dict(_class="comment_ul")), edit_in_place[1], showmore("comment_%s" % comment.id) if comments else '', _class="internal-comments article-box" ) def editcomment(self): user = self.session.auth.user if self.session.auth else None if user: data_id = self.request.vars['data[id]'] content = self.request.vars['content'] comment = self.db.Comments[data_id] if (comment and user) and (user.id == comment.user_id or user.id == comment.article_id.author): comment.update_record(comment_text=content) self.db.commit() def removecomment(self): user = self.session.auth.user if self.session.auth else None if user: comment_id = self.request.args(0).split('_')[1] try: comment = self.db.Comments[int(comment_id)] if (comment and user) and (user.id == comment.user_id or user.id == comment.article_id.author): comment.delete_record() self.db.commit() except: pass def comment_disqus(self): js = """ <div id="disqus_thread"></div> <script type="text/javascript"> /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */ var disqus_shortname = '%(disqus_shortname)s'; // required: replace example with your forum shortname var disqus_identifier = '%(disqus_identifier)s'; //var disqus_url = '%(disqus_url)s'; var disqus_developer = %(disqus_developer)s; // developer mode is on /* * * DON'T EDIT BELOW THIS LINE * * */ (function() { var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true; dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js'; (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq); })(); </script> <noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript> <a href="http://disqus.com" class="dsq-brlink">blog comments powered by <span class="logo-disqus">Disqus</span></a> """ % dict( disqus_shortname=self.config.comment.disqus_shortname, disqus_developer=self.config.comment.disqus_developer, disqus_identifier="%s/%s" % (self.context.article.id, self.context.article.slug), disqus_url=self.request.url ) return XML(js) def comment_intense(self): # counterjs = """ # <script> # var idcomments_acct = 'fe83a2e2af975dd1095a8e4e9ebe1902'; # var idcomments_post_id; # var idcomments_post_url; # </script> # <script type="text/javascript" src="http://www.intensedebate.com/js/genericLinkWrapperV2.js"></script> # """ js = """ <script> var idcomments_acct = '%(intense_acct)s'; var idcomments_post_id; var idcomments_post_url; </script> <span id="IDCommentsPostTitle" style="display:none"></span> <script type='text/javascript' src='http://www.intensedebate.com/js/genericCommentWrapperV2.js'></script> """ % dict( intense_acct=self.config.comment.intense_acct, idcomments_post_id="%s/%s" % (self.context.article.id, self.context.article.slug), idcomments_post_url=self.request.url ) return XML(js) def comment_facebook(self): js = """ <div id="fb-root"></div> <script>(function(d, s, id) { var js, fjs = d.getElementsByTagName(s)[0]; if (d.getElementById(id)) {return;} js = d.createElement(s); js.id = id; js.src = "//connect.facebook.net/en_US/all.js#xfbml=1&appId=%(facebook_appid)s"; fjs.parentNode.insertBefore(js, fjs); }(document, 'script', 'facebook-jssdk'));</script> <div class="fb-comments" data-href="%(url)s" data-num-posts="%(facebook_numposts)s" data-width="700"></div> """ % dict( facebook_appid=self.config.comment.facebook_appid, facebook_numposts=self.config.comment.facebook_numposts, url=self.request.url ) return XML(js) def get(self, redir=True): article_id = self.request.args(0) article_slug = self.request.args(1) queries = [self.db.article.id == article_id] if article_slug: queries.append(self.db.article.slug == article_slug) query = reduce(lambda a, b: (a & b), queries) self.context.article = self.db(query).select().first() if not self.context.article and redir: redirect(self.CURL('home', 'index')) def show(self): self.get() self.related_articles() self.comments() content, self.context.article_data = self.get_content(self.context.article.content_type_id.classname, self.context.article.id) self.response.meta.title = "%s | %s | %s" % ( self.context.article.title, self.T(self.context.article.content_type_id.title), self.db.config.meta.title, ) self.response.meta.description = self.context.article.description self.response.meta.keywords = ",".join(self.context.article.tags) self.context.article.update_record(views=self.context.article.views + 1) self.context.action_links = self.action_links() self.db.commit() def edit(self): self.context.customfield = customfield self.get() self.db.article.thumbnail.compute = lambda r: THUMB2(r['picture'], gae=self.request.env.web2py_runtime_gae) self.db.article.medium_thumbnail.compute = lambda r: THUMB2(r['picture'], gae=self.request.env.web2py_runtime_gae, nx=400, ny=400, name='medium_thumb') self.context.article_form = SQLFORM(self.db.article, self.context.article) content, article_data = self.get_content(self.context.article.content_type_id.classname, self.context.article.id) if self.context.article_form.process().accepted: article_data.update_record(**content.entity._filter_fields(self.request.vars)) self.new_article_event('update_article', data={'event_link_to': "%s/%s" % (self.context.article.id, IS_SLUG()(self.context.article_form.vars.title)[0]), 'event_text': self.context.article_form.vars.description, 'event_to': "%s (%s)" % (self.context.article.content_type_id.title, self.context.article.title), 'event_image_to': self.get_image(self.context.article.thumbnail, self.context.article.content_type_id.identifier)}) self.session.flash = self.T("%s updated." % self.context.article.content_type_id.title) self.context.article.update_record(search_index="|".join(str(value) for value in self.request.vars.values())) redirect(self.CURL('article', 'show', args=[self.context.article.id, IS_SLUG()(self.request.vars.title)[0]])) self.context.content_form = SQLFORM(content.entity, article_data) def define_content_type(self, classname): from datamodel import contenttypes return getattr(contenttypes, classname)(self.db) def get_content(self, classname, article_id): content = self.define_content_type(classname) row = self.db(content.entity.article_id == article_id).select().first() if self.request.vars: row.update(**content.entity._filter_fields(self.request.vars)) return (content, row) def new(self): if not self.session.auth: redirect(self.CURL('default', 'user', args='login', vars=dict(_next=self.CURL('article', 'new', args=self.request.args)))) arg = self.request.args(0) query = self.db.content_type.identifier == arg content_type = self.db(query).select().first() or redirect(self.CURL('home', 'index')) self.context.viewname = content_type.viewname content = self.define_content_type(content_type.classname) path = os.path.join(self.request.folder, 'uploads/') if not self.request.env.web2py_runtime_gae: self.db.article.picture.uploadfolder = path self.db.article.thumbnail.uploadfolder = path else: self.db.article.picture.uploadfield = "picture_blob" self.db.article.thumbnail.uploadfield = "thumbnail_blob" self.db.article.author.default = self.session.auth.user.id self.db.article.thumbnail.compute = lambda r: THUMB2(r['picture'], gae=self.request.env.web2py_runtime_gae) self.db.article.medium_thumbnail.compute = lambda r: THUMB2(r['picture'], gae=self.request.env.web2py_runtime_gae, nx=400, ny=400, name='medium_thumb') self.db.article.content_type_id.default = content_type.id category_set = self.db(self.db.Category.content_type == content_type.id) self.db.article.category_id.requires = IS_IN_DB(category_set, self.db.Category.id, "%(name)s") self.context.form = SQLFORM.factory(self.db.article, content.entity, table_name="article", formstyle='divs', separator='') self.context.customfield = customfield if self.context.form.process().accepted: try: article_id = self.db.article.insert(**self.db.article._filter_fields(self.context.form.vars)) self.context.form.vars.article_id = article_id self.context.form.vars.type_id = content_type.id content_id = content.entity.insert(**content.entity._filter_fields(self.context.form.vars)) if not content_id: raise Exception("Content not added") except Exception: self.db.rollback() self.response.flash = self.T("error including %s." % content_type.title) else: self.db.commit() self.session.flash = self.T("%s included." % content_type.title) self.context.article = self.db.article[article_id] self.context.article.update_record(search_index="|".join(str(value) for value in self.context.form.vars.values())) if not self.context.article.draft: self.new_article_event('new_article') count = int(self.context.article.author.articles) + 1 self.context.article.author.update_record(articles=count) else: count = int(self.context.article.author.draft_articles) + 1 self.context.article.author.update_record(draft_articles=count) redirect(self.CURL('article', 'show', args=[article_id, IS_SLUG()(self.context.form.vars.title)[0]])) def tag(self): pass def category(self): category = None try: category = self.db.Category[int(self.request.args(0))] except: category = self.db(self.db.Category.name == self.request.args(0).replace('_', ' ')).select() if category: category = category[0] self.context.category = category def search(self): q = self.request.vars.q or None self.context.form = FORM(INPUT(_type="text", _name="q", _id="q", _value=q or ''), _method="GET") if q: query = (self.db.Article.search_index.like("%" + q + "%")) | (self.db.Article.tags.contains(q)) self.context.results = self.db(query).select() else: self.context.results = [] def list(self): self.context.title = str(self.db.T("Articles ")) queries = [] for field, value in self.request.vars.items(): if field not in ['limitby', 'orderby', 'tag', 'category', 'or']: queries.append(self.db.Article[field] == value) if field == 'tag': queries.append(self.db.Article.tags.contains(value)) self.context.title += str(self.db.T("tagged with %s ", value)) if field == 'category': try: cat_qry = self.db.Article.category_id == int(value) except: cat_id = self.db(self.db.Category.name == value.replace('_', ' ')).select().first().id cat_qry = self.db.Article.category_id == cat_id queries.append(cat_qry) self.context.title += str(self.db.T("in %s category ", value.replace('_', ' '))) queries.append(self.db.Article.draft == False) query = reduce(lambda a, b: (a & b), queries) if self.request.vars.limitby: limitby = [int(item) for item in self.request.vars.limitby.split(',')] else: limitby = (0, 10) self.context.articles = self.db(query).select(limitby=limitby, orderby=~self.db.Article.publish_date) if 'author' in self.request.vars and self.context.articles: self.context.title = str(self.db.T("Articles wrote by %s", self.context.articles[0].author.nickname)) def new_article_event(self, event_type, user=None, data={}): if not user: user = self.session.auth.user if self.session.auth else None if user: self.db.UserTimeLine._new_event(v=dict( user_id=user.id, nickname=user.nickname or "%(first_name)s %(last_name)s" % user, event_type=event_type, event_image=data.get('event_image', self.get_image(None, 'user', themename=self.context.theme_name, user=user)), event_to=data.get('event_to', "%s (%s)" % (self.context.article.content_type_id.title, self.context.article.title)), event_reference=data.get('event_reference', self.context.article.id), event_text=data.get('event_text', self.context.article.description), event_link=data.get('event_link', user.nickname or user.id), event_image_to=data.get('event_image_to', self.get_image(self.context.article.thumbnail, self.context.article.content_type_id.identifier)), event_link_to=data.get('event_link_to', "%s/%s" % (self.context.article.id, self.context.article.slug)), )) events = dict(self.notifier.permission.events) if event_type not in ['update_article', 'new_article'] and self.context.article.author != user.id: self.notifier.notify(event_type, self.context.article.author, event_text=self.T(events.get(event_type, "%s done something on %s"), (user.nickname, data.get('event_to', self.context.article.title))), event_link=data.get('event_link_to', "%s/%s" % (self.context.article.id, self.context.article.slug)), event_reference=data.get('event_reference', self.context.article.id), event_image=data.get('event_image', self.get_image(None, 'user', themename=self.context.theme_name, user=user)), data=data ) if event_type in ['new_article_comment', 'update_article']: subscribers = self.db(self.db.Subscribers.article_id == self.context.article.id).select() user_ids = [subscriber.user_id for subscriber in subscribers] rows = self.db(self.db.auth_user.id.belongs(user_ids)).select() emails = [row.email for row in rows] users = [row.id for row in rows] events.update({"new_article_comment_subscribers": self.T("%s commented on article %s"), "update_article_subscribers": self.T("%s updated %s")}) self.notifier.notify_all("%s_subscribers" % event_type, emails=emails, users=users, event_text=self.T(events.get("%s_subscribers" % event_type, "%s done something on %s"), (user.nickname, data.get('event_to', self.context.article.title))), event_link=data.get('event_link_to', "%s/%s" % (self.context.article.id, self.context.article.slug)), event_reference=data.get('event_reference', self.context.article.id), event_image=data.get('event_image', self.get_image(None, 'user', themename=self.context.theme_name, user=user)), data=data ) def favorite(self): user = self.session.auth.user if self.session.auth else None if user: self.get() # get article object try: self.context.favorited = self.db.Favoriters.update_or_insert(article_id=self.context.article.id, user_id=user.id) except Exception, e: self.context.error = str(e) else: try: count = self.db(self.db.Favoriters.article_id == self.context.article.id).count() self.context.article.update_record(favorited=count) count = self.db(self.db.Favoriters.user_id == user.id).count() self.db.auth_user[user.id] = dict(favorites=count) self.new_article_event('favorited', user) except Exception, e: print str(e) self.db.rollback() else:
class Person(Base): def start(self): self.db = DataBase([User, UserTimeLine, UserContact, UserBoard, ContentType]) self.notifier = Notifier(self.db) def pre_render(self): # obrigatorio ter um config, um self.response|request, que tenha um render self.response.render self.response = self.db.response self.request = self.db.request self.config = self.db.config self.session = self.db.session self.T = self.db.T self.CURL = self.db.CURL self.get_image = self.db.get_image self.context.theme_name = self.config.theme.name self.context.use_facebook = self.db.config.auth.use_facebook self.context.use_google = self.db.config.auth.use_google self.mail = self.db.auth.settings.mailer self.context.content_types = self.db(self.db.ContentType).select() def check_if_allowed(self, row): if self.db.auth.user_id: relation = self.db.UserContact._relation(self.db.auth.user_id, row.user_timeline.user_id) else: relation = 'unknown' if row.user_timeline.user_id.privacy != 1 and \ relation not in ['contacts', 'follower', 'yourself'] and \ not self.db.auth.has_membership("admin", self.db.auth.user_id): return False else: return True def get_private_timeline(self, query, orderby=None, limitby=None): timeline = self.db.UserTimeLine timeline.allowed = Field.Lazy(lambda row: self.check_if_allowed(row)) rows = self.db(query).select(orderby=orderby or ~timeline.created_on, limitby=limitby or (0, 20)) self.context.events = rows.find(lambda row: row.allowed() == True) def get_timeline(self, query, orderby=None, limitby=None, public=True): timeline = self.db.UserTimeLine if public: self.context.events = self.db(query).select(orderby=orderby or ~timeline.created_on, limitby=limitby or (0, 20)) else: timeline.allowed = Field.Lazy(lambda row: self.check_if_allowed(row)) rows = self.db(query).select(orderby=orderby or ~timeline.created_on, limitby=limitby or (0, 20)) self.context.events = rows.find(lambda row: row.allowed() == True) def usertimeline(self): if self.request.args(0): try: user = self.db.auth_user[int(self.request.args(0))] except Exception: user = self.db.auth_user(nickname=self.request.args(0)) else: user = self.db.auth_user[self.session.auth.user.id] self.context.user = user if self.request.extension == "html": self.show(user.id) if user: query = self.db.UserTimeLine.user_id == user.id #### pagination self.context.paginate_selector = PaginateSelector(paginates=(10, 25, 50, 100)) self.context.paginator = Paginator(paginate=self.context.paginate_selector.paginate) self.context.paginator.records = self.db(query).count() self.context.paginate_info = PaginateInfo(self.context.paginator.page, self.context.paginator.paginate, self.context.paginator.records) limitby = self.context.paginator.limitby() #### /pagination if 'limitby' in self.request.vars: limitby = [int(item) for item in self.request.vars.limitby.split(',')] self.get_timeline(query, limitby=limitby, public=user.privacy == 1) #self.context.paginator.records = self.context.paginate_info.records = len(self.context.events) self.context.TIMELINEFUNCTIONS = '%s/app/person/usertimeline_events.html' % self.context.theme_name def publictimeline(self): query = (self.db.UserTimeLine.user_id == self.db.auth_user.id) & (self.db.auth_user.privacy == 1) #### pagination self.context.paginate_selector = PaginateSelector(paginates=(10, 25, 50, 100)) self.context.paginator = Paginator(paginate=self.context.paginate_selector.paginate) self.context.paginator.records = self.db(query).count() self.context.paginate_info = PaginateInfo(self.context.paginator.page, self.context.paginator.paginate, self.context.paginator.records) limitby = self.context.paginator.limitby() #### /pagination if 'limitby' in self.request.vars: limitby = [int(item) for item in self.request.vars.limitby.split(',')] self.get_timeline(query, limitby=limitby, public=True) #self.context.paginator.records = self.context.paginate_info.records = len(self.context.events) if self.db.request.args(0) == "sidebar": self.context.TIMELINEFUNCTIONS = '%s/app/person/sidebar_publictimeline_events.html' % self.context.theme_name else: self.context.TIMELINEFUNCTIONS = '%s/app/person/publictimeline_events.html' % self.context.theme_name def privatetimeline(self): self.board(self.session.auth.user.id) self.contacts() allowed = list(self.context.following_list) + list(self.context.contacts_list) allowed.append(self.session.auth.user.id) query = self.db.UserTimeLine.created_by.belongs(allowed) #### pagination self.context.paginate_selector = PaginateSelector(paginates=(10, 25, 50, 100)) self.context.paginator = Paginator(paginate=self.context.paginate_selector.paginate) self.context.paginator.records = self.db(query).count() self.context.paginate_info = PaginateInfo(self.context.paginator.page, self.context.paginator.paginate, self.context.paginator.records) limitby = self.context.paginator.limitby() #### /pagination if 'limitby' in self.request.vars: limitby = [int(item) for item in self.request.vars.limitby.split(',')] self.get_private_timeline(query, limitby=limitby) #self.context.paginator.records = self.context.paginate_info.records = len(self.context.events) if self.db.request.args(0) == "sidebar": self.context.TIMELINEFUNCTIONS = '%s/app/person/sidebar_privatetimeline_events.html' % self.context.theme_name else: self.context.TIMELINEFUNCTIONS = '%s/app/person/privatetimeline_events.html' % self.context.theme_name def update_contact_counter(self, follower=None, followed=None, arg=None): if arg: try: query = self.db.auth_user.id == int(self.request.args(0)) except: query = self.db.auth_user.nickname == self.request.args(0) follower = self.db(query).select().first() else: follower = self.session.auth.user if self.session.auth else redirect(self.CURL('person', 'account', args='login')) def update_counter(person): i_follow = self.db(self.db.UserContact.follower == person.id).select(self.db.UserContact.followed) follows_me = self.db(self.db.UserContact.followed == person.id).select(self.db.UserContact.follower) i_follow_set = set([row.followed for row in i_follow]) follows_me_set = set([row.follower for row in follows_me]) contacts = len(i_follow_set & follows_me_set) following = len(i_follow_set - follows_me_set) followers = len(follows_me_set - i_follow_set) self.db(self.db.auth_user.id == person.id).update(contacts=contacts, isfollowing=following, followers=followers) self.db.commit() if person.id == self.db.auth.user_id: self.db.auth.user.update(contacts=contacts, isfollowing=following, followers=followers) if follower: update_counter(follower) if followed: update_counter(followed) def follow(self): follower = self.session.auth.user if self.session.auth else None if not follower and 'profile' in self.request.args: return "window.location = '%s'" % self.CURL('default', 'user', args='login', vars={'_next': self.CURL('person', 'show', args=self.request.args(0))}) try: followed = self.db.auth_user[int(self.request.args(0))] except: followed = self.db(self.db.auth_user.nickname == self.request.args(0)).select(0).first() yourself = followed.id == follower.id if follower and followed: if not yourself: self.db.UserContact.update_or_insert(follower=follower.id, followed=followed.id) self.db.commit() self.db.UserTimeLine._new_event(v={"user_id": follower.id, "nickname": follower.nickname, "event_type": "new_contact", "event_image": self.get_image(None, 'user', themename=self.context.theme_name, user=follower), "event_to": followed.nickname or followed.first_name, "event_reference": followed.id, "event_text": "", "event_link": follower.nickname or follower.id, "event_link_to": followed.nickname or followed.id, "event_image_to": self.get_image(None, 'user', themename=self.context.theme_name, user=followed)}) self.notifier.notify("new_contact", followed, event_text=self.T("%(nickname)s followed you", follower), event_link=follower.nickname or follower.id, event_reference=followed.id, event_image=self.get_image(None, 'user', themename=self.context.theme_name, user=follower), follower=follower ) # relation = self.db.UserContact._relation(follower.id, followed.id) # if relation == 'contacts': # acount = followed.contacts + 1 # followed.update_record(contacts=acount) # follower_user = self.db.auth_user[int(follower.id)] # bcount = follower_user.contacts + 1 # follower_user.update_record(contacts=bcount) self.update_contact_counter(follower, followed) return contact_box(followed, 'contact', ajax=True, css={"main": "well span5", "img": "span", "div": "four columns"}) else: return self.T('You cannot follow yourself') else: return self.T('Error following') def unfollow(self): follower = self.session.auth.user if self.session.auth else None try: followed = self.db.auth_user[int(self.request.args(0))] except: followed = self.db(self.db.auth_user.nickname == self.request.args(0)).select(0).first() yourself = followed.id == follower.id if follower and followed: if not yourself: #relation = self.db.UserContact._relation(follower.id, followed.id) query = (self.db.UserContact.follower == follower.id) & (self.db.UserContact.followed == followed.id) self.db(query).delete() self.db.commit() # if relation == 'contacts': # acount = followed.contacts - 1 # followed.update_record(contacts=acount) # follower_user = self.db.auth_user[int(follower.id)] # bcount = follower_user.contacts - 1 # follower_user.update_record(contacts=bcount) self.update_contact_counter(follower, followed) return contact_box(followed, 'follower', ajax=True, css={"main": "well span5", "img": "span", "div": "four columns"}) else: return self.T('You cannot unfollow yourself') else: return self.T('Error unfollowing') def followers(self, arg=None): if arg: try: query = self.db.auth_user.id == int(self.request.args(0)) except: query = self.db.auth_user.nickname == self.request.args(0) followed = self.db(query).select().first() else: followed = self.session.auth.user if self.session.auth else redirect(self.CURL('person', 'account', args='login')) if followed: self.context.followers = self.db(self.db.UserContact.followed == followed.id).select() def following(self, arg=None): if arg: try: query = self.db.auth_user.id == int(self.request.args(0)) except: query = self.db.auth_user.nickname == self.request.args(0) follower = self.db(query).select().first() else: follower = self.session.auth.user if self.session.auth else redirect(self.CURL('person', 'account', args='login')) if follower: self.context.following = self.db(self.db.UserContact.follower == follower.id).select() def contacts(self, arg=None): if 'refresh' in self.request.vars: self.update_contact_counter(arg=arg) self.followers(arg) self.following(arg) followers = [follower.follower for follower in self.context.followers] following = [followed.followed for followed in self.context.following] friends = set() [friends.add(friend) for friend in followers if friend in following] [friends.add(friend) for friend in following if friend in followers] self.context.contacts_list = friends self.context.followers_list = followers self.context.following_list = following if self.request.env.web2py_runtime_gae: queries = [] for friend in friends: queries.append(self.db.auth_user.id == friend) query = reduce(lambda a, b: (a | b), queries) self.context.contacts = self.db(query).select() else: if friends: self.context.contacts = self.db(self.db.auth_user.id.belongs(list(friends))).select() else: self.context.contacts = [] from helpers.person import contact_box self.context.contact_box = contact_box def search(self, q): self.contacts() self.context.results = [] if q: words = q.split() queries = [] for word in words: queries.append(self.db.auth_user.first_name.like("%" + word + "%")) queries.append(self.db.auth_user.last_name.like("%" + word + "%")) queries.append(self.db.auth_user.email.like("%" + word + "%")) queries.append(self.db.auth_user.nickname.like("%" + word + "%")) queries.append(self.db.auth_user.about.like("%" + word + "%")) queries.append(self.db.auth_user.tagline.like("%" + word + "%")) query = reduce(lambda a, b: (a | b), queries) finalquery = query & (self.db.auth_user.id != self.session.auth.user.id) #### pagination self.context.paginate_selector = PaginateSelector(paginates=(26, 50, 100)) self.context.paginator = Paginator(paginate=self.context.paginate_selector.paginate) self.context.paginator.records = self.db(finalquery).count() self.context.paginate_info = PaginateInfo(self.context.paginator.page, self.context.paginator.paginate, self.context.paginator.records) limitby = self.context.paginator.limitby() #### /pagination self.context.results = self.db(finalquery).select(orderby=~self.db.auth_user.id, limitby=limitby) from helpers.person import contact_box self.context.contact_box = contact_box self.context.form = SQLFORM.factory(Field('q', default=q or '', label=self.T("Search Term"), comment=self.T("In name, email, nickname, about")), formstyle='divs', _method="GET") def new_board_event(self, form=None, writer=None, user=None, relation=None): writer_user = self.db.auth_user[writer] self.db.UserTimeLine._new_event(v={"user_id": writer_user.id, "nickname": writer_user.nickname, "event_type": "wrote_on_wall", "event_image": self.get_image(None, 'user', themename=self.context.theme_name, user=writer_user), "event_to": "" if relation == 'yourself' else user.nickname or user.first_name, "event_reference": form.vars.id, "event_text": form.vars.board_text, "event_link": writer_user.nickname or writer_user.id, "event_link_to": "" if relation == 'yourself' else user.nickname or user.id, "event_image_to": "" if relation == 'yourself' else self.get_image(None, 'user', themename=self.context.theme_name, user=user)}) if writer_user.id != user.id: # self.mail.send(to=user.email, # subject=self.T("Hi, %(nickname)s posted on your Movuca board", writer_user), # message=[None, """<h1>You got a new post on your board!</h1><p>%(board_text)s</p>Note: this is a beta test of http://movu.ca CMS, thank you for the help with tests""" % form.vars]) self.notifier.notify("wrote_on_wall", user, event_text=self.db.T("%s wrote on your wall: %s", (writer_user.nickname, form.vars.board_text)), event_link=user.nickname or user.id, event_reference=form.vars.id, event_image=self.get_image(None, 'user', themename=self.context.theme_name, user=writer_user), writer=writer_user ) # TODO: RENDER TEMPLATE EMAILS CHECK PREFERENCES FOR NOTIFICATIONS def board(self, uid, post_id=None): if self.request.extension == 'html': self.show(uid) T = self.T try: user = self.db.auth_user[int(uid)] except Exception: user = self.db.auth_user(nickname=uid) self.context.user = user self.db.UserBoard.user_id.default = user.id self.db.UserBoard.writer.default = self.session.auth.user.id if self.session.auth else 0 relation = self.db.UserContact._relation(self.session.auth.user.id if self.session.auth else 0, user.id) self.context.relation = relation if relation == "yourself": board_text_label = T("Whats up?") elif relation in ["contacts", "follower"]: board_text_label = T("Write something on %s's board", user.nickname) if relation in ['contacts', 'yourself', 'follower']: #self.db.UserBoard.board_text.label = CAT(board_text_label, A(T(" add photo "), _onclick="alert('Sorry, Photo upload is under development!');")) self.db.UserBoard.board_text.label = board_text_label self.context.form = SQLFORM(self.db.UserBoard, formstyle='divs', submit_button=T('Post'), separator='').process(onsuccess=lambda form: self.new_board_event(form, writer=self.session.auth.user.id, user=user, relation=relation)) else: self.context.form = '' query = self.db.UserBoard.user_id == user.id if post_id: query = query & (self.db.UserBoard.id == post_id) self.context.form = self.context.paginate_selector = \ self.context.paginator = self.context.paginate_info = "" limitby = None else: #### pagination self.context.paginate_selector = PaginateSelector(paginates=(10, 25, 50, 100)) self.context.paginator = Paginator(paginate=self.context.paginate_selector.paginate) self.context.paginator.records = self.db(query).count() self.context.paginate_info = PaginateInfo(self.context.paginator.page, self.context.paginator.paginate, self.context.paginator.records) limitby = self.context.paginator.limitby() #### /pagination if 'limitby' in self.request.vars: limitby = [int(item) for item in self.request.vars.limitby.split(',')] if self.context.user.privacy != 1 and \ relation not in ['contacts', 'follower', 'yourself'] and \ not self.db.auth.has_membership("admin", self.db.auth.user_id): self.view = 'app/person/board_private' self.context.board = [] else: self.view = 'app/person/board' self.context.board = self.db(query).select(orderby=~self.db.UserBoard.created_on, limitby=limitby) def removeboard(self, msg_id, user_id): msg = self.db.UserBoard[int(msg_id)] if msg and (user_id in [msg.created_by, msg.user_id]): msg.delete_record() self.db.commit() self.context.eval = "$('#msg_%s').hide();" % msg_id else: self.context.eval = "alert('%s')" % self.T("It is not possible to delete") def removeevent(self, event_id, user_id): event = self.db.UserTimeLine[int(event_id)] if event and (user_id in [event.created_by, event.event_reference]): event.delete_record() self.db.commit() self.context.eval = "$('#event_%s').hide();" % event_id else: self.context.eval = "alert('%s')" % self.T("It is not possible to delete") def show(self, uid): T = self.T CURL = self.CURL self.db.auth.notifier = self.notifier user = None try: user = self.db.auth_user[int(uid)] except Exception: user = self.db.auth_user(nickname=uid) self.context.user = user or redirect(self.CURL('home', 'index')) buttons = CAT() if self.session.auth and self.session.auth.user: relation = self.db.UserContact._relation(self.session.auth.user.id if self.session.auth else 0, user.id) else: relation = 'unknown' relation_text = {'unknown': T('Your are mutually oblivious'), 'contacts': T('This person is in your contact list (following each other)'), 'following': T('You follow this person'), 'follower': T('This person follows you'), 'yourself': T('This is you')} self.context.relation = relation self.context.relation_text = relation_text[relation] if relation != 'yourself': text = {'unknown': T('follow'), 'contacts': T('unfollow'), 'following': T('unfollow'), 'follower': T('follow')} post_text = {'unknown': T('Followed!'), 'contacts': T('Contact removed!'), 'following': T('Unfollowed!'), 'follower': T('Contact added!')} url = {'unknown': CURL('person', 'follow', args=[user.id, 'profile']), 'contacts': CURL('person', 'unfollow', args=[user.id, 'profile']), 'following': CURL('person', 'unfollow', args=[user.id, 'profile']), 'follower': CURL('person', 'follow', args=[user.id, 'profile'])} buttons.append(TAG.BUTTON(text[relation], _onclick="jQuery(this).text('%s');ajax('%s', [], ':eval');jQuery('#relation-text').text('%s');" % (post_text[relation], url[relation], post_text[relation]), _class="btn btn-danger" if relation in ['following', 'contacts'] else 'btn btn-success')) #buttons.append(TAG.BUTTON(T("Message"), _class="btn", _onclick="alert('Sorry, it is not implemented yet')")) buttons.append(TAG.BUTTON(T("Report/Block"), _class="btn", _onclick="alert('Sorry, it is not implemented yet')")) else: buttons.append(A(T("Edit Profile"), _class="button btn", _href=CURL('default', 'user', args='profile'))) #buttons.append(A(T("My Messages"), _class="button btn", _href=CURL('person', 'messages', args=user.nickname or user.id))) self.context.buttons = buttons self.context.resume = UL( LI(IMG(_src=URL('static', '%s/images/icons' % self.context.theme_name, args='attach_round.24.png')), A(T("Wrote %s articles", user.articles), _href=self.CURL('article', 'list', vars={'author': user.id}))), LI(IMG(_src=URL('static', '%s/images/icons' % self.context.theme_name, args='favorite_rounded.24.png')), A(T("Has %s favorites", user.favorites), _href=self.CURL('article', 'list', vars={'favorite': user.id}))), LI(IMG(_src=URL('static', '%s/images/icons' % self.context.theme_name, args='like_rounded.24.png')), A(T("Liked %s articles", user.likes), _href=self.CURL('article', 'list', vars={'like': user.id}))), LI(IMG(_src=URL('static', '%s/images/icons' % self.context.theme_name, args='face.24.png')), A(T("Has %s contacts", user.contacts), _href=self.CURL('person', 'contacts', args=user.nickname or user.id))), #LI(IMG(_src=URL('static', '%s/images/icons' % self.context.theme_name, args='movuca.24.png')), A(T("Joined %s groups", user.groups))), _class="person-resume" ) if user.id == self.db.auth.user_id: self.context.resume.append(LI(IMG(_src=URL('static', '%s/images/icons' % self.context.theme_name, args='like_rounded.24.png')), A(T("Disliked %s articles", user.dislikes), _href=self.CURL('article', 'list', vars={'dislike': user.id})))) self.context.resume.append(LI(IMG(_src=URL('static', '%s/images/icons' % self.context.theme_name, args='like_rounded.24.png')), A(T("Subscribed to %s articles", user.subscriptions), _href=self.CURL('article', 'list', vars={'subscribe': user.id})))) self.response.meta.title = "%s | %s | %s" % ( user.nickname or user.first_name, self.T("Profile"), self.db.config.meta.title, ) self.response.meta.description = str(user.tagline or user.about) + ' ' + str(user.city or '') + ' ' + str(user.country or '') self.response.meta.keywords = [user.first_name, user.last_name, user.nickname] self.context.twittername = self.context.user.twitter.split('/')[-1].strip() if self.context.user.twitter else "" if self.db.config.auth.use_mailhide: key = dict(self.db.config.get_list('auth', 'mailhide')) from helpers.mailhide import asurl self.context.hiddenmail = asurl(self.context.user.email, key['public'], key['private']) else: self.context.hiddenmail = '' #facebook/google issue if self.db.session["%s_setpassword" % self.context.user.id]: self.context.user.update_record(password=self.db.session["%s_setpassword" % self.context.user.id]) self.db.session["%s_setpassword" % self.context.user.id] = None if self.db.session["is_new_from"]: self.context.alerts.append(XML(self.T("Welcome! You logged in using your %s account, please go to your <a href='%s'>settings</a> page choose your username and complete your profile!", (self.db.session["is_new_from"], self.db.CURL('person', 'account', args='profile'))))) self.db.auth.initial_user_permission(self.context.user) #user extra links image # TODO: limit the number of links? self.context.extra_links = [] if user.extra_links: image_map = {"github.com": 'github.png', "plus.google.com": 'gplus.png', 'twitter.com': 'twitter.png', 'facebook.com': 'facebook.png'} titles = {"github.com": 'Github', "plus.google.com": 'Google +', 'twitter.com': 'Twitter', 'facebook.com': 'Facebook'} for link in user.extra_links: for key, img in image_map.items(): if key in link: self.context.extra_links.append({"img": URL('static', '%s/images/icons' % self.context.theme_name, args=img), "link": link, "title": titles.get(key, "")}) continue if link not in [item['link'] for item in self.context.extra_links]: self.context.extra_links.append({"img": URL('static', '%s/images/icons' % self.context.theme_name, args='globe.png'), "link": link, "title": link}) if self.context.user.privacy != 1 and \ relation not in ['contacts', 'follower', 'yourself'] and \ not self.db.auth.has_membership("admin", self.db.auth.user_id): self.view = 'app/person/show_private' else: self.view = 'app/person/show' def account(self): self.db.auth.notifier = self.notifier verify_email = self.notifier.build_message_from_template("verify_email") reset_password = self.notifier.build_message_from_template("reset_password") self.db.auth.messages.verify_email = verify_email['message'][1] self.db.auth.messages.reset_password = reset_password['message'][1] self.db.auth.messages.verify_email_subject = verify_email['subject'] self.db.auth.messages.reset_password_subject = reset_password['subject'] self.context.auth = self.db.auth self.context.form = self.db.auth() self.context.customfield = customfield if 'profile' in self.request.args: self.notifier.permission.add_permission_if_dont_exists(self.db.auth.user) self.context.permissions = self.db(self.notifier.permission.entity.user_id == self.db.auth.user_id).select() self.context.permission_events = dict(self.notifier.permission.events) def loginbare(self): username = self.request.vars.email password = self.request.vars.password user = self.db.auth.login_bare(username, password) if user: redirect(self.CURL('person', 'show')) else: redirect(self.CURL('home', 'index', args=[username, 'loginerror'])) def facebook(self): self.db.auth.notifier = self.notifier if not self.db.config.auth.use_facebook: redirect(self.CURL('person', 'account', args=self.request.args, vars=self.request.vars)) self.context.auth = self.db.auth self.context.auth.settings.controller = 'person' self.context.auth.settings.login_url = self.CURL('person', 'facebook', args='login') self.context.auth.settings.login_next = self.CURL('person', 'show') self.context.auth.settings.register_next = self.CURL('person', 'show') from helpers.facebook import FaceBookAccount self.context.auth.settings.login_form = FaceBookAccount(self.db) self.context.form = self.context.auth() def google(self): self.db.auth.notifier = self.notifier if not self.db.config.auth.use_google: redirect(self.CURL('person', 'account', args=self.request.args, vars=self.request.vars)) self.context.auth = self.db.auth self.context.auth.settings.controller = 'person' self.context.auth.settings.login_url = self.CURL('person', 'google', args='login') self.context.auth.settings.login_next = self.CURL('person', 'show') self.context.auth.settings.register_next = self.CURL('person', 'show') from helpers.googleplus import GooglePlusAccount self.context.auth.settings.login_form = GooglePlusAccount(self.db) self.context.form = self.context.auth() def check_availability(self, items): #returns True when error, False when ok if not all(items.values()): return {items['field']: self.db.T("Empty")} items_to_check = {items['field']: items['value']} if self.db.session.auth: if items_to_check[items['field']] == self.db.session.auth.user[items['field']]: return {} return self.db.auth_user._validate(**items_to_check) def notificationpermission(self, pid, way, action): permission = self.notifier.permission.entity(user_id=self.db.auth.user.id, id=pid) if permission: current_way = permission.way if action == "enable" and not way in current_way: current_way.append(way) permission.update_record(way=current_way) self.db.commit() self.context.button = TAG.BUTTON(TAG['i'](_class="icon-ok", _style="margin-right:5px;"), self.T("Enabled"), _class="notificationpermission btn btn-success", _id="%s_%s" % (way, pid), **{"_data-url": URL('person', 'notificationpermission', args=[pid, way, 'disable'])}) elif action == "disable" and way in current_way: current_way.remove(way) permission.update_record(way=current_way) self.db.commit() self.context.button = TAG.BUTTON(TAG['i'](_class="icon-off", _style="margin-right:5px;"), self.T("Disabled"), _class="notificationpermission btn btn-danger", _id="%s_%s" % (way, pid), **{"_data-url": URL('person', 'notificationpermission', args=[pid, way, 'enable'])})
def start(self): from movuca import DataBase, User, UserTimeLine from datamodel.article import Category, Article, ContentType, Favoriters, Subscribers, Likers, Dislikers, Comments self.db = DataBase([User, UserTimeLine, ContentType, Category, Article, Favoriters, Subscribers, Likers, Dislikers, Comments]) from handlers.notification import Notifier self.notifier = Notifier(self.db)
##################################################################################### # # set worker to 'queue' in config.notification_options # in a separate terminal run # # python web2py.py -S demo -M -N -R applications/demo/private/notification_worker.py # # ###################################################################################### import time import datetime from movuca import DataBase, User, Mailer from handlers.notification import Notifier db = DataBase([User]) notifier = Notifier(db) mail = Mailer(db) while True: rows = db(db.notification.mail_sent == False).select() for row in rows: email = row.user_id.email try: s_to_parse = row.kwargs or "{}" kwargs = eval(s_to_parse.strip()) # from str to dict (can user json?) if notifier.send_email(email, row.event_type, bypass=True, **kwargs): row.update_record(mail_sent=True) message = ["success:", email, row.event_type, row.id, datetime.datetime.now(), "\n"] else: message = ["failed on send_mail", email, row.event_type, row.id, datetime.datetime.now(), "\n"] except Exception, e:
##################################################################################### # # set worker to 'queue' in config.notification_options # in a separate terminal run # # python web2py.py -S demo -M -N -R applications/demo/private/notification_worker.py # # ###################################################################################### import time import datetime from movuca import DataBase, User, Mailer from handlers.notification import Notifier db = DataBase([User]) notifier = Notifier(db) mail = Mailer(db) while True: rows = db(db.notification.mail_sent == False).select() for row in rows: email = row.user_id.email try: s_to_parse = row.kwargs or "{}" kwargs = eval( s_to_parse.strip()) # from str to dict (can user json?) if notifier.send_email(email, row.event_type, bypass=True, **kwargs): row.update_record(mail_sent=True)
def start(self): self.db = DataBase([ User, UserTimeLine, UserContact, UserBoard, Category, ContentType, Article ]) self.notifier = Notifier(self.db)
class Person(Base): def start(self): self.db = DataBase([ User, UserTimeLine, UserContact, UserBoard, Category, ContentType, Article ]) self.notifier = Notifier(self.db) def pre_render(self): # obrigatorio ter um config, um self.response|request, que tenha um render self.response.render self.response = self.db.response self.request = self.db.request self.config = self.db.config self.session = self.db.session self.T = self.db.T self.CURL = self.db.CURL self.get_image = self.db.get_image self.context.theme_name = self.config.theme.name self.context.use_facebook = self.db.config.auth.use_facebook self.context.use_google = self.db.config.auth.use_google self.mail = self.db.auth.settings.mailer self.context.content_types = self.allowed_content_types() self.context.categories = self.allowed_categories() def check_if_allowed(self, row): if self.db.auth.user_id: relation = self.db.UserContact._relation(self.db.auth.user_id, row.user_timeline.user_id) else: relation = 'unknown' if row.user_timeline.user_id.privacy != 1 and \ relation not in ['contacts', 'follower', 'yourself'] and \ not self.db.auth.has_membership("admin", self.db.auth.user_id): return False else: return True def get_private_timeline(self, query, orderby=None, limitby=None): timeline = self.db.UserTimeLine timeline.allowed = Field.Lazy(lambda row: self.check_if_allowed(row)) rows = self.db(query).select(orderby=orderby or ~timeline.created_on, limitby=limitby or (0, 20)) self.context.events = rows.find(lambda row: row.allowed() == True) def get_timeline(self, query, orderby=None, limitby=None, public=True): timeline = self.db.UserTimeLine if public: self.context.events = self.db(query).select( orderby=orderby or ~timeline.created_on, limitby=limitby or (0, 20)) else: timeline.allowed = Field.Lazy( lambda row: self.check_if_allowed(row)) rows = self.db(query).select(orderby=orderby or ~timeline.created_on, limitby=limitby or (0, 20)) self.context.events = rows.find(lambda row: row.allowed() == True) def usertimeline(self): if self.request.args(0): try: user = self.db.auth_user[int(self.request.args(0))] except Exception: user = self.db.auth_user(nickname=self.request.args(0)) else: user = self.db.auth_user[self.db.auth.user_id] self.context.user = user if self.request.extension == "html": if user: self.show(user.id) else: redirect(self.CURL('home', 'index')) if user: query = self.db.UserTimeLine.user_id == user.id #### pagination self.context.paginate_selector = PaginateSelector(paginates=(10, 25, 50, 100)) self.context.paginator = Paginator( paginate=self.context.paginate_selector.paginate) self.context.paginator.records = self.db(query).count() self.context.paginate_info = PaginateInfo( self.context.paginator.page, self.context.paginator.paginate, self.context.paginator.records) limitby = self.context.paginator.limitby() #### /pagination if 'limitby' in self.request.vars: limitby = [ int(item) for item in self.request.vars.limitby.split(',') ] self.get_timeline(query, limitby=limitby, public=user.privacy == 1) #self.context.paginator.records = self.context.paginate_info.records = len(self.context.events) self.response.meta.title = "%s | %s" % ( self.db.T("%s's timeline", user.nickname.title() or user.first_name.title()), self.db.config.meta.title, ) self.context.TIMELINEFUNCTIONS = '%s/app/person/usertimeline_events.html' % self.context.theme_name def publictimeline(self): self.response.meta.title = "%s | %s" % ( self.db.T("Public timeline"), self.db.config.meta.title, ) query = (self.db.UserTimeLine.user_id == self.db.auth_user.id) & (self.db.auth_user.privacy == 1) #### pagination self.context.paginate_selector = PaginateSelector(paginates=(10, 25, 50, 100)) self.context.paginator = Paginator( paginate=self.context.paginate_selector.paginate) self.context.paginator.records = self.db(query).count() self.context.paginate_info = PaginateInfo( self.context.paginator.page, self.context.paginator.paginate, self.context.paginator.records) limitby = self.context.paginator.limitby() #### /pagination if 'limitby' in self.request.vars: limitby = [ int(item) for item in self.request.vars.limitby.split(',') ] self.get_timeline(query, limitby=limitby, public=True) #self.context.paginator.records = self.context.paginate_info.records = len(self.context.events) if self.db.request.args(0) == "sidebar": self.context.TIMELINEFUNCTIONS = '%s/app/person/sidebar_publictimeline_events.html' % self.context.theme_name else: self.context.TIMELINEFUNCTIONS = '%s/app/person/publictimeline_events.html' % self.context.theme_name def privatetimeline(self): try: self.board(self.db.auth.user_id) except: redirect(self.CURL('home', 'index')) self.contacts() allowed = list(self.context.following_list) + list( self.context.contacts_list) allowed.append(self.session.auth.user.id) query = self.db.UserTimeLine.created_by.belongs(allowed) #### pagination self.context.paginate_selector = PaginateSelector(paginates=(10, 25, 50, 100)) self.context.paginator = Paginator( paginate=self.context.paginate_selector.paginate) self.context.paginator.records = self.db(query).count() self.context.paginate_info = PaginateInfo( self.context.paginator.page, self.context.paginator.paginate, self.context.paginator.records) limitby = self.context.paginator.limitby() #### /pagination if 'limitby' in self.request.vars: limitby = [ int(item) for item in self.request.vars.limitby.split(',') ] self.get_private_timeline(query, limitby=limitby) #self.context.paginator.records = self.context.paginate_info.records = len(self.context.events) if self.db.request.args(0) == "sidebar": self.context.TIMELINEFUNCTIONS = '%s/app/person/sidebar_privatetimeline_events.html' % self.context.theme_name else: self.context.TIMELINEFUNCTIONS = '%s/app/person/privatetimeline_events.html' % self.context.theme_name self.response.meta.title = "%s | %s" % ( self.db.T( "%s's private timeline", self.context.user.nickname.title() or self.context.user.first_name.title()), self.db.config.meta.title, ) def update_contact_counter(self, follower=None, followed=None, arg=None): if arg: try: query = self.db.auth_user.id == int(self.request.args(0)) except: query = self.db.auth_user.nickname == self.request.args(0) follower = self.db(query).select().first() else: follower = self.session.auth.user if self.session.auth else redirect( self.CURL('person', 'account', args='login')) def update_counter(person): i_follow = self.db( self.db.UserContact.follower == person.id).select( self.db.UserContact.followed) follows_me = self.db( self.db.UserContact.followed == person.id).select( self.db.UserContact.follower) i_follow_set = set([row.followed for row in i_follow]) follows_me_set = set([row.follower for row in follows_me]) contacts = len(i_follow_set & follows_me_set) following = len(i_follow_set - follows_me_set) followers = len(follows_me_set - i_follow_set) self.db(self.db.auth_user.id == person.id).update( contacts=contacts, isfollowing=following, followers=followers) self.db.commit() if person.id == self.db.auth.user_id: self.db.auth.user.update(contacts=contacts, isfollowing=following, followers=followers) if follower: update_counter(follower) if followed: update_counter(followed) def follow(self): follower = self.session.auth.user if self.session.auth else None if not follower and 'profile' in self.request.args: return "window.location = '%s'" % self.CURL( 'default', 'user', args='login', vars={ '_next': self.CURL( 'person', 'show', args=self.request.args(0)) }) try: followed = self.db.auth_user[int(self.request.args(0))] except: followed = self.db(self.db.auth_user.nickname == self.request.args( 0)).select(0).first() yourself = followed.id == follower.id if follower and followed: if not yourself: self.db.UserContact.update_or_insert(follower=follower.id, followed=followed.id) self.db.commit() self.db.UserTimeLine._new_event( v={ "user_id": follower.id, "nickname": follower.nickname, "event_type": "new_contact", "event_image": self.get_image(None, 'user', themename=self.context.theme_name, user=follower), "event_to": followed.nickname or followed.first_name, "event_reference": followed.id, "event_text": "", "event_link": follower.nickname or follower.id, "event_link_to": followed.nickname or followed.id, "event_image_to": self.get_image(None, 'user', themename=self.context.theme_name, user=followed) }) self.notifier.notify( "new_contact", followed, event_text=self.T("%(nickname)s followed you", follower), event_link=follower.nickname or follower.id, event_reference=followed.id, event_image=self.get_image( None, 'user', themename=self.context.theme_name, user=follower), follower=follower) # relation = self.db.UserContact._relation(follower.id, followed.id) # if relation == 'contacts': # acount = followed.contacts + 1 # followed.update_record(contacts=acount) # follower_user = self.db.auth_user[int(follower.id)] # bcount = follower_user.contacts + 1 # follower_user.update_record(contacts=bcount) self.update_contact_counter(follower, followed) return contact_box(followed, 'contact', ajax=True, css={ "main": "well span5", "img": "span", "div": "four columns" }) else: return self.T('You cannot follow yourself') else: return self.T('Error following') def unfollow(self): follower = self.session.auth.user if self.session.auth else None try: followed = self.db.auth_user[int(self.request.args(0))] except: followed = self.db(self.db.auth_user.nickname == self.request.args( 0)).select(0).first() yourself = followed.id == follower.id if follower and followed: if not yourself: #relation = self.db.UserContact._relation(follower.id, followed.id) query = (self.db.UserContact.follower == follower.id) & ( self.db.UserContact.followed == followed.id) self.db(query).delete() self.db.commit() # if relation == 'contacts': # acount = followed.contacts - 1 # followed.update_record(contacts=acount) # follower_user = self.db.auth_user[int(follower.id)] # bcount = follower_user.contacts - 1 # follower_user.update_record(contacts=bcount) self.update_contact_counter(follower, followed) return contact_box(followed, 'follower', ajax=True, css={ "main": "well span5", "img": "span", "div": "four columns" }) else: return self.T('You cannot unfollow yourself') else: return self.T('Error unfollowing') def followers(self, arg=None): if arg: try: query = self.db.auth_user.id == int(self.request.args(0)) except: query = self.db.auth_user.nickname == self.request.args(0) followed = self.db(query).select().first() else: followed = self.session.auth.user if self.session.auth else redirect( self.CURL('person', 'account', args='login')) if followed: self.context.followers = self.db( self.db.UserContact.followed == followed.id).select() def following(self, arg=None): if arg: try: query = self.db.auth_user.id == int(self.request.args(0)) except: query = self.db.auth_user.nickname == self.request.args(0) follower = self.db(query).select().first() else: follower = self.session.auth.user if self.session.auth else redirect( self.CURL('person', 'account', args='login')) if follower: self.context.following = self.db( self.db.UserContact.follower == follower.id).select() def contacts(self, arg=None): self.response.meta.title = "%s | %s" % ( self.db.T("Contacts"), self.db.config.meta.title, ) if 'refresh' in self.request.vars: self.update_contact_counter(arg=arg) self.followers(arg) self.following(arg) self.context.followers = self.context.followers or [] self.context.following = self.context.following or [] followers = [follower.follower for follower in self.context.followers] following = [followed.followed for followed in self.context.following] friends = set() [friends.add(friend) for friend in followers if friend in following] [friends.add(friend) for friend in following if friend in followers] self.context.contacts_list = friends self.context.followers_list = followers self.context.following_list = following if self.request.env.web2py_runtime_gae: queries = [] for friend in friends: queries.append(self.db.auth_user.id == friend) query = reduce(lambda a, b: (a | b), queries) self.context.contacts = self.db(query).select() else: if friends: self.context.contacts = self.db( self.db.auth_user.id.belongs(list(friends))).select() else: self.context.contacts = [] from helpers.person import contact_box self.context.contact_box = contact_box def search(self, q): self.response.meta.title = "%s | %s" % ( self.db.T("Search in members"), self.db.config.meta.title, ) self.contacts() self.context.results = [] if q: words = q.split() queries = [] for word in words: queries.append( self.db.auth_user.first_name.like("%" + word + "%")) queries.append( self.db.auth_user.last_name.like("%" + word + "%")) queries.append(self.db.auth_user.email.like("%" + word + "%")) queries.append( self.db.auth_user.nickname.like("%" + word + "%")) queries.append(self.db.auth_user.about.like("%" + word + "%")) queries.append(self.db.auth_user.tagline.like("%" + word + "%")) query = reduce(lambda a, b: (a | b), queries) finalquery = query & (self.db.auth_user.id != self.session.auth.user.id) & ( self.db.auth_user.is_active == True) #### pagination self.context.paginate_selector = PaginateSelector(paginates=(26, 50, 100)) self.context.paginator = Paginator( paginate=self.context.paginate_selector.paginate) self.context.paginator.records = self.db(finalquery).count() self.context.paginate_info = PaginateInfo( self.context.paginator.page, self.context.paginator.paginate, self.context.paginator.records) limitby = self.context.paginator.limitby() #### /pagination self.context.results = self.db(finalquery).select( orderby=~self.db.auth_user.id, limitby=limitby) from helpers.person import contact_box self.context.contact_box = contact_box qdefault = q if q and q != '@' else '' self.context.form = SQLFORM.factory(Field( 'q', default=qdefault, label=self.T("Search Term"), comment=self.T("In name, email, nickname, about")), formstyle='divs', _method="GET") def new_board_event(self, form=None, writer=None, user=None, relation=None): writer_user = self.db.auth_user[writer] self.db.UserTimeLine._new_event( v={ "user_id": writer_user.id, "nickname": writer_user.nickname, "event_type": "wrote_on_wall", "event_image": self.get_image(None, 'user', themename=self.context.theme_name, user=writer_user), "event_to": "" if relation == 'yourself' else user.nickname or user.first_name, "event_reference": form.vars.id, "event_text": form.vars.board_text, "event_link": writer_user.nickname or writer_user.id, "event_link_to": "" if relation == 'yourself' else user.nickname or user.id, "event_image_to": "" if relation == 'yourself' else self.get_image( None, 'user', themename=self.context.theme_name, user=user) }) if writer_user.id != user.id: # self.mail.send(to=user.email, # subject=self.T("Hi, %(nickname)s posted on your Movuca board", writer_user), # message=[None, """<h1>You got a new post on your board!</h1><p>%(board_text)s</p>Note: this is a beta test of http://movu.ca CMS, thank you for the help with tests""" % form.vars]) self.notifier.notify( "wrote_on_wall", user, event_text=self.db.T( "%s wrote on your wall: %s", (writer_user.nickname, form.vars.board_text)), event_link=user.nickname or user.id, event_reference=form.vars.id, event_image=self.get_image(None, 'user', themename=self.context.theme_name, user=writer_user), writer=writer_user) # TODO: RENDER TEMPLATE EMAILS CHECK PREFERENCES FOR NOTIFICATIONS def board(self, uid, post_id=None): self.context.extrajs = "" if self.request.vars.reply: try: self.context.reply = self.db.UserBoard[self.request.vars.reply] self.db.UserBoard.parent_id.default = self.context.reply.id except Exception: self.context.reply = [] else: self.context.reply = [] if self.request.extension == 'html': self.show(uid) T = self.T try: user = self.db.auth_user[int(uid)] except Exception: user = self.db.auth_user(nickname=uid) self.context.user = user if user: self.response.meta.title = "%s | %s" % ( self.db.T("%s's board", user.nickname.title() or user.first_name.title()), self.db.config.meta.title, ) self.db.UserBoard.user_id.default = user.id self.db.UserBoard.writer.default = self.session.auth.user.id if self.session.auth else 0 relation = self.db.UserContact._relation( self.session.auth.user.id if self.session.auth else 0, user.id) self.context.relation = relation if relation == "yourself": board_text_label = T("Whats up?") elif relation in ["contacts", "follower"]: board_text_label = T("Write something on %s's board", user.nickname) if relation in ['contacts', 'yourself', 'follower']: #self.db.UserBoard.board_text.label = CAT(board_text_label, A(T(" add photo "), _onclick="alert('Sorry, Photo upload is under development!');")) self.db.UserBoard.board_text.label = board_text_label self.context.form = SQLFORM(self.db.UserBoard, formstyle='divs', submit_button=T('Post'), separator='')\ .process(onsuccess=lambda form: self.board_posted(form, user, relation)) else: self.context.form = '' self.db.UserBoard.replies = Field.Lazy(lambda row: self.db( self.db.UserBoard.parent_id == row.user_board.id).select( orderby=~self.db.UserBoard.created_on, limitby=(0, 10))) query = (self.db.UserBoard.user_id == user.id) & (self.db.UserBoard.parent_id == 0) if post_id: query = query & (self.db.UserBoard.id == post_id) self.context.form = self.context.paginate_selector = \ self.context.paginator = self.context.paginate_info = "" limitby = None else: #### pagination self.context.paginate_selector = PaginateSelector(paginates=(10, 25, 50, 100)) self.context.paginator = Paginator( paginate=self.context.paginate_selector.paginate) self.context.paginator.records = self.db(query).count() self.context.paginate_info = PaginateInfo( self.context.paginator.page, self.context.paginator.paginate, self.context.paginator.records) limitby = self.context.paginator.limitby() #### /pagination if 'limitby' in self.request.vars: limitby = [ int(item) for item in self.request.vars.limitby.split(',') ] if self.context.user.privacy != 1 and \ relation not in ['contacts', 'follower', 'yourself'] and \ not self.db.auth.has_membership("admin", self.db.auth.user_id): self.view = 'app/person/board_private' self.context.board = [] else: self.view = 'app/person/board' self.context.board = self.db(query).select( orderby=~self.db.UserBoard.created_on, limitby=limitby) def board_posted(self, form, user=None, relation=None): self.new_board_event(form, writer=self.session.auth.user.id, user=user, relation=relation) if self.request.vars.isreply: self.context.extrajs = "refresh_board_box();" def removeboard(self, msg_id, user_id): msg = self.db.UserBoard[int(msg_id)] if msg and (user_id in [msg.created_by, msg.user_id]): msg.delete_record() self.db.commit() self.context.eval = "$('#msg_%s').hide();" % msg_id else: self.context.eval = "alert('%s')" % self.T( "It is not possible to delete") def removeevent(self, event_id, user_id): event = self.db.UserTimeLine[int(event_id)] if event and (user_id in [event.created_by, event.event_reference]): event.delete_record() self.db.commit() self.context.eval = "$('#event_%s').hide();" % event_id else: self.context.eval = "alert('%s')" % self.T( "It is not possible to delete") def delete_account(self): self.db.auth_user.is_active.readable = self.db.auth_user.is_active.writable = True uid = self.db.auth.user_id or redirect(self.CURL('home', 'index')) try: user = self.db.auth_user[int(uid)] except Exception: user = self.db.auth_user(nickname=uid) self.context.user = user or redirect(self.CURL('home', 'index')) self.context.form = SQLFORM(self.db.auth_user, user.id, formstyle='divs', submit_button=self.T('Delete my account'), fields=['id'], hidden={'delete': '1'}) if self.context.form.process().accepted: if self.request.vars.delete == '1': self.context.user.update_record(is_active=False) self.db(self.db.user_timeline.created_by == user.id).delete() self.db.commit() self.response.flash = self.session.flash = "Deleted" redirect(self.CURL('person', 'account', args='logout')) def show(self, uid): T = self.T CURL = self.CURL self.db.auth.notifier = self.notifier user = None try: user = self.db.auth_user[int(uid)] except Exception: user = self.db.auth_user(nickname=uid) self.context.user = user or redirect(self.CURL('home', 'index')) buttons = CAT() if self.session.auth and self.session.auth.user: relation = self.db.UserContact._relation( self.session.auth.user.id if self.session.auth else 0, user.id) else: relation = 'unknown' relation_text = { 'unknown': T('Your are mutually oblivious'), 'contacts': T('This person is in your contact list (following each other)'), 'following': T('You follow this person'), 'follower': T('This person follows you'), 'yourself': T('This is you') } self.context.relation = relation self.context.relation_text = relation_text[relation] if relation != 'yourself': text = { 'unknown': T('follow'), 'contacts': T('unfollow'), 'following': T('unfollow'), 'follower': T('follow') } post_text = { 'unknown': T('Followed!'), 'contacts': T('Contact removed!'), 'following': T('Unfollowed!'), 'follower': T('Contact added!') } url = { 'unknown': CURL('person', 'follow', args=[user.id, 'profile']), 'contacts': CURL('person', 'unfollow', args=[user.id, 'profile']), 'following': CURL('person', 'unfollow', args=[user.id, 'profile']), 'follower': CURL('person', 'follow', args=[user.id, 'profile']) } buttons.append( TAG.BUTTON( text[relation], _onclick= "jQuery(this).text('%s');ajax('%s', [], ':eval');jQuery('#relation-text').text('%s');" % (post_text[relation], url[relation], post_text[relation]), _class="btn btn-danger" if relation in ['following', 'contacts'] else 'btn btn-success')) #buttons.append(TAG.BUTTON(T("Message"), _class="btn", _onclick="alert('Sorry, it is not implemented yet')")) buttons.append( A(T("Report/Block"), _class="btn", _href=CURL('page', 'reportcontent', args=[ "Person", user.id, user.nickname or user.first_name ]))) else: buttons.append( A(T("Edit Profile"), _class="button btn", _href=CURL('default', 'user', args='profile'))) #buttons.append(A(T("My Messages"), _class="button btn", _href=CURL('person', 'messages', args=user.nickname or user.id))) self.context.buttons = buttons self.context.resume = UL( LI( IMG(_src=URL('static', '%s/images/icons' % self.context.theme_name, args='attach_round.24.png')), A(T("Wrote %s articles", user.articles), _href=self.CURL('article', 'list', vars={'author': user.id}))), LI( IMG(_src=URL('static', '%s/images/icons' % self.context.theme_name, args='favorite_rounded.24.png')), A(T("Has %s favorites", user.favorites), _href=self.CURL('article', 'list', vars={'favorite': user.id}))), LI( IMG(_src=URL('static', '%s/images/icons' % self.context.theme_name, args='like_rounded.24.png')), A(T("Liked %s articles", user.likes), _href=self.CURL('article', 'list', vars={'like': user.id}))), LI( IMG(_src=URL('static', '%s/images/icons' % self.context.theme_name, args='face.24.png')), A(T("Has %s contacts", user.contacts), _href=self.CURL('person', 'contacts', args=user.nickname or user.id))), #LI(IMG(_src=URL('static', '%s/images/icons' % self.context.theme_name, args='movuca.24.png')), A(T("Joined %s groups", user.groups))), _class="person-resume") if user.id == self.db.auth.user_id: #self.context.resume.append(LI(IMG(_src=URL('static', '%s/images/icons' % self.context.theme_name, args='like_rounded.24.png')), A(T("Disliked %s articles", user.dislikes), _href=self.CURL('article', 'list', vars={'dislike': user.id})))) self.context.resume.append( LI( IMG(_src=URL('static', '%s/images/icons' % self.context.theme_name, args='like_rounded.24.png')), A(T("Subscribed to %s articles", user.subscriptions), _href=self.CURL('article', 'list', vars={'subscribe': user.id})))) self.response.meta.title = "%s | %s | %s" % ( user.nickname or user.first_name, self.T("Profile"), self.db.config.meta.title, ) self.response.meta.description = str( user.tagline or user.about) + ' ' + str( user.city or '') + ' ' + str(user.country or '') self.response.meta.keywords = ",".join( [user.first_name, user.last_name, user.nickname]) self.response.meta.og_type = "profile" self.response.meta.og_url = self.CURL('person', 'show', args=user.nickname or user.id, host=True, scheme=True) self.response.meta.og_images = self.response.meta.og_images or [] self.response.meta.og_images.append( self.get_image(None, 'user', themename='menu', user=user, host=True, scheme=True)) self.context.twittername = self.context.user.twitter.split( '/')[-1].strip() if self.context.user.twitter else "" if self.db.config.auth.use_mailhide: key = dict(self.db.config.get_list('auth', 'mailhide')) from helpers.mailhide import asurl self.context.hiddenmail = asurl(self.context.user.email, key['public'], key['private']) else: self.context.hiddenmail = '' #facebook/google issue if self.db.session["%s_setpassword" % self.context.user.id]: self.context.user.update_record( password=self.db.session["%s_setpassword" % self.context.user.id]) self.db.session["%s_setpassword" % self.context.user.id] = None if self.db.session["is_new_from"]: self.context.alerts.append( XML( self.T( "Welcome! You logged in using your %s account, please go to your <a href='%s'>settings</a> page choose your username and complete your profile!", (self.db.session["is_new_from"], self.db.CURL('person', 'account', args='profile'))))) self.db.auth.initial_user_permission(self.context.user) #user extra links image # TODO: limit the number of links? self.context.extra_links = [] if user.extra_links: image_map = { "github.com": 'github.png', "plus.google.com": 'gplus.png', 'twitter.com': 'twitter.png', 'facebook.com': 'facebook.png' } titles = { "github.com": 'Github', "plus.google.com": 'Google +', 'twitter.com': 'Twitter', 'facebook.com': 'Facebook' } for link in user.extra_links: for key, img in image_map.items(): if key in link: self.context.extra_links.append({ "img": URL('static', '%s/images/icons' % self.context.theme_name, args=img), "link": link, "title": titles.get(key, "") }) continue if link not in [ item['link'] for item in self.context.extra_links ]: self.context.extra_links.append({ "img": URL('static', '%s/images/icons' % self.context.theme_name, args='globe.png'), "link": link, "title": link }) if self.context.user.privacy != 1 and \ relation not in ['contacts', 'follower', 'yourself'] and \ not self.db.auth.has_membership("admin", self.db.auth.user_id): self.view = 'app/person/show_private' else: self.view = 'app/person/show' def account(self): self.response.meta.title = "%s | %s" % ( self.db.T("Me"), self.db.config.meta.title, ) self.db.auth.notifier = self.notifier verify_email = self.notifier.build_message_from_template( "verify_email") reset_password = self.notifier.build_message_from_template( "reset_password") self.db.auth.messages.verify_email = verify_email['message'][1] self.db.auth.messages.reset_password = reset_password['message'][1] self.db.auth.messages.verify_email_subject = verify_email['subject'] self.db.auth.messages.reset_password_subject = reset_password[ 'subject'] self.context.auth = self.db.auth self.context.form = self.db.auth() self.context.customfield = customfield if 'profile' in self.request.args: self.notifier.permission.add_permission_if_dont_exists( self.db.auth.user) self.context.permissions = self.db( self.notifier.permission.entity.user_id == self.db.auth.user_id).select() self.context.permission_events = dict( self.notifier.permission.events) def loginbare(self): username = self.request.vars.email password = self.request.vars.password user = self.db.auth.login_bare(username, password) if user: redirect(self.CURL('person', 'show')) else: redirect(self.CURL('home', 'index', args=[username, 'loginerror'])) def facebook(self): self.db.auth.notifier = self.notifier if not self.db.config.auth.use_facebook: redirect( self.CURL('person', 'account', args=self.request.args, vars=self.request.vars)) self.context.auth = self.db.auth self.context.auth.settings.controller = 'person' self.context.auth.settings.login_url = self.CURL('person', 'facebook', args='login', host=True, scheme=True) self.context.auth.settings.login_next = self.CURL('person', 'show', host=True, scheme=True) self.context.auth.settings.register_next = self.CURL('person', 'show', host=True, scheme=True) from helpers.facebook import FaceBookAccount self.context.auth.settings.login_form = FaceBookAccount(self.db) self.context.form = self.context.auth() def google(self): self.db.auth.notifier = self.notifier if not self.db.config.auth.use_google: redirect( self.CURL('person', 'account', args=self.request.args, vars=self.request.vars)) self.context.auth = self.db.auth self.context.auth.settings.controller = 'person' self.context.auth.settings.login_url = self.CURL('person', 'google', args='login') self.context.auth.settings.login_next = self.CURL('person', 'show') self.context.auth.settings.register_next = self.CURL('person', 'show') from helpers.googleplus import GooglePlusAccount self.context.auth.settings.login_form = GooglePlusAccount(self.db) self.context.form = self.context.auth() def check_availability(self, items): #returns True when error, False when ok if not all(items.values()): return {items['field']: self.db.T("Empty")} items_to_check = {items['field']: items['value']} if self.db.session.auth: if items_to_check[items['field']] == self.db.session.auth.user[ items['field']]: return {} return self.db.auth_user._validate(**items_to_check) def notificationpermission(self, pid, way, action): permission = self.notifier.permission.entity( user_id=self.db.auth.user.id, id=pid) if permission: current_way = permission.way if action == "enable" and not way in current_way: current_way.append(way) permission.update_record(way=current_way) self.db.commit() self.context.button = TAG.BUTTON( TAG['i'](_class="icon-ok", _style="margin-right:5px;"), self.T("Enabled"), _class="notificationpermission btn btn-success", _id="%s_%s" % (way, pid), **{ "_data-url": URL('person', 'notificationpermission', args=[pid, way, 'disable']) }) elif action == "disable" and way in current_way: current_way.remove(way) permission.update_record(way=current_way) self.db.commit() self.context.button = TAG.BUTTON( TAG['i'](_class="icon-off", _style="margin-right:5px;"), self.T("Disabled"), _class="notificationpermission btn btn-danger", _id="%s_%s" % (way, pid), **{ "_data-url": URL('person', 'notificationpermission', args=[pid, way, 'enable']) })