def start(self):
     self.db = DataBase([User, UserTimeLine, UserContact, UserBoard, ContentType])
     self.notifier = Notifier(self.db)
Exemple #2
0
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'])})
Exemple #4
0
 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)
Exemple #7
0
 def start(self):
     self.db = DataBase([
         User, UserTimeLine, UserContact, UserBoard, Category, ContentType,
         Article
     ])
     self.notifier = Notifier(self.db)
Exemple #8
0
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'])
                    })