Example #1
0
 def prepare(self):
     super().prepare()
     cursor = self.db.posts.find()
     self.post_count = yield cursor.count()
     self.max_page = ceil(self.post_count / N_POST_PER_PAGE)
     logger.debug('prepare for post_count {}, max_page {}'.format(
         self.post_count, self.max_page))
Example #2
0
    def ramjet_login(self):
        """
        GET 一个包含 source, id, username 的 token
        """
        try:
            token = self.get_argument('token')
            d = validate_token(token)
        except Exception:
            logger.debug('ramjet_login validate error')
            self.http_400_bad_request(err='token validate error')
            return

        # login from twitter
        sid_str = '{}.id'.format(d['source'])  # like "twitter.id"
        old_user = yield self.db.users.find_one({sid_str: d['id']})
        username = old_user['username'] if old_user else d['username']
        yield self.db.users.update({sid_str: d['id']}, {
            '$set': {
                'username': username,
                sid_str: d['id'],
                'last_update': utcnow()
            }
        },
                                   upsert=True)
        user_docu = yield self.db.users.find_one({sid_str: d['id']})

        token = generate_token({
            'username': d['username'],
            'uid': user_docu['_id']
        })
        self.set_cookie('token', token, expires_days=30)
        self.write_json(msg=OK)
        self.finish()
Example #3
0
    def ramjet_login(self):
        """
        GET 一个包含 source, id, username 的 token
        """
        try:
            token = self.get_argument('token')
            d = validate_token(token)
        except Exception:
            logger.debug('ramjet_login validate error')
            self.http_400_bad_request(err='token validate error')
            return

        # login from twitter
        sid_str = '{}.id'.format(d['source'])  # like "twitter.id"
        old_user = yield self.db.users.find_one({sid_str: d['id']})
        username = old_user['username'] if old_user else d['username']
        yield self.db.users.update(
            {sid_str: d['id']},
            {'$set': {'username': username,
                      sid_str: d['id'],
                      'last_update': utcnow()}},
            upsert=True
        )
        user_docu = yield self.db.users.find_one({sid_str: d['id']})

        token = generate_token({'username': d['username'], 'uid': user_docu['_id']})
        self.set_cookie('token', token, expires_days=30)
        self.write_json(msg=OK)
        self.finish()
Example #4
0
    def setup_db(self):
        logger.debug('connect database at {}:{}'.format(
            options.dbhost, options.dbport))

        model = BaseBlogModel.make_connection(host=options.dbhost,
                                              port=options.dbport)
        self.conn = model.conn
        self.db = model.db
        self.mongo_conn = model.mongo_conn
        self.mongo_db = model.mongo_db

        # ensure index
        # posts
        # posts_idx = pymongo.IndexModel([('post_name',)], unique=True)
        # self.mongo_db.posts.create_indexes([posts_idx])
        self.mongo_db.posts.ensure_index([('post_name', pymongo.ASCENDING)],
                                         unique=True)  # PyMongo2.8
        # users
        # account_idx = pymongo.IndexModel([('account',)], unique=True)
        # username_idx = pymongo.IndexModel([('username',)], unique=True)
        # self.mongo_db.users.create_indexes([account_idx, username_idx])
        self.mongo_db.users.ensure_index([('account', pymongo.ASCENDING)],
                                         unique=True)  # PyMongo2.8
        self.mongo_db.users.ensure_index([('username', pymongo.ASCENDING)],
                                         unique=True)  # PyMongo2.8
Example #5
0
 def write_not_accept(self, data):
     logger.debug('write_not_accept for Accept: {}'.format(self.accept))
     _accept_map = self._get_accept_map()
     self.http_406_not_acceptable(
         'Only Accept {}! But Got {}'
         .format(list(_accept_map.keys()), self.accept)
     )
Example #6
0
    def post_article_password(self):
        """Validate the password of locked article.
        """
        logger.info("post_article_password")

        name = self.parse_post_name(self.get_argument('name', default='', strip=True))
        password = self.get_argument('password', strip=True)
        logger.debug('post_article_password for name {}, password {}'
                     .format(name, password))

        post = yield ArticlesModel.get({'post_name': name})
        if not post:
            self.set_status(202, 'Post name not exists.')
            self.write_json(msg='post_name 不存在', status=ERROR)
            self.finish()
            return
        elif password != post['post_password']:
            self.set_status(202, 'Password wrong.')
            self.write_json(msg='密码错误', status=ERROR)
            self.finish()
            return

        cookie_name = self.get_cookie_name(name)
        self.set_secure_cookie(cookie_name, password, expires_days=None)
        self.write_json(msg='ok')
Example #7
0
 def prepare(self):
     super().prepare()
     cursor = self.db.posts.find()
     self.post_count = yield cursor.count()
     self.max_page = ceil(self.post_count / N_POST_PER_PAGE)
     logger.debug('prepare for post_count {}, max_page {}'
                  .format(self.post_count, self.max_page))
Example #8
0
    def get_post_by_keyword(self):
        logger.info('GET get_post_by_keyword')

        keyword = self.get_argument('keyword', strip=True)
        logger.debug('GET get_post_by_keyword for keyword {}'.format(keyword))

        q = 'https://cse.google.com/cse/publicurl?cx=004733495569415005684:-c6y46kjqva&q={keyword}'
        self.redirect(q.format(keyword=keyword, permanent=True))
Example #9
0
    def get(self, url=None):
        logger.debug('GET PageNotFound for url {}'.format(url))

        if url is None:
            self.render2('404.html', url=url)
            self.finish()
            return

        self.redirect_404()
Example #10
0
    async def get_cursor(self):
        col = self.get_col()
        query, projection = await self.pass_query_makers()
        if query is None:
            logger.debug('not get query')
            return

        cursor = col.find(query, projection)
        return await self.pass_filter(cursor)
Example #11
0
    def get(self, url=None):
        logger.debug('GET PageNotFound for url {}'.format(url))

        if url is None:
            self.render2('404.html', url=url)
            self.finish()
            return

        self.redirect_404()
Example #12
0
    def _get_resp_method(self):
        _accept_map = self._get_accept_map()
        for accept in self.accept:
            m = _accept_map.get(accept.name)
            if m:
                logger.debug('_get_resp_method {}'.format(m))
                return m

        logger.debug('_get_resp_method fail')
        return self.write_not_accept
Example #13
0
    async def pass_filter(self, cursor):
        for f in (self._base_filters + getattr(self, '_filters', tuple())):
            try:
                cursor = await f.query_cursor(self, cursor)
            except FilterError as err:
                logger.debug(err)
                self.http_400_bad_request(err=err)
                return

        return cursor
Example #14
0
    async def parse_docus(self, docus):
        try:
            for p in (self._base_parsers + getattr(self, '_parsers', tuple())):
                docus = await p.parse_results(self, docus)
        except ParserError as err:
            logger.debug(err)
            self.http_400_bad_request(err=err)
            return None

        return docus
Example #15
0
    async def put(self, category=None):
        try:
            categories = self.get_argument('categories', strip=True)
            categories = json.loads(categories)
        except Exception as err:
            self.http_400_bad_request(err=err)
            return

        logger.debug('PostCategoriesAPIHandler PUT for categories %s', categories)
        await ArticlesModel.update_posts_categories(categories)
        return self.success(data='ok')
Example #16
0
    def extract_reveal_html(self, html):
        logger.debug('extract_reveal_html for html {}'.format(html[: 50]))

        tree = etree.HTML(html)
        node = tree.xpath('//div[@class="reveal"]')
        ret = etree.tostring(node[0], encoding='unicode')

        if '{{' in ret:
            return '{% raw %}' + ret + '{% endraw %}'
        else:
            return ret
Example #17
0
 def emit(self, record):
     logger.debug('LogMailHandler for record {}'.format(record))
     delay_task(
         send_mail,
         mailhost=self.mailhost,
         mailport=self.mailport,
         username=self.username,
         passwd=self.password,
         from_addr=self.fromaddr,
         to_addrs=self.toaddrs,  # 会自动被转换为列表
         subject=self.subject,
         content=record.getMessage())
Example #18
0
    async def pass_query_makers(self):
        query, projection = {}, None
        try:
            for qm in (self._base_query_makers + getattr(self, '_query_makers', tuple())):
                query, projection = await qm.update_query(self, query, projection)

        except QueryMakerError as err:
            logger.debug(err)
            self.http_400_bad_request(err=err)
            return None, None

        return query, projection
Example #19
0
    def validate_post(self, create_new=False):
        try:
            post_title = self.get_argument('postTitle', strip=True)
            post_name = self.get_argument('postName', strip=True)
            post_name = urllib.parse.quote(post_name).lower()
            post_content = self.get_argument('postContent')
            post_type = self.get_argument('postType', strip=True, default='text')

            assert post_name, 'post_name cannot be empry!'
        except Exception as err:
            logger.exception(err)
            raise PostValidatorError('Post arguments error!')
        else:
            post_docu = {
                'post_modified_gmt': utcnow(),
                'post_status': 'publish',
                'comment_status': 'open',
                'post_title': post_title,
                'post_name': post_name,
                'post_type': post_type,
            }
            if create_new:
                post_docu.update({
                    'post_author': self.current_user['_id'],
                    'post_created_at': utcnow(),
                })

            logger.debug('validate_post for post_title {}, post_name {}, '
                         'post_content {}, post_type {}'
                         .format(post_title, post_name, post_content, post_type))

        post_menu = None
        if post_type == 'slide':
            # extract slide body from the file generated by ipython nbconvert
            post_content = self.extract_reveal_html(post_content)
        elif post_type == 'markdown':
            # renfer github flavor markdown to html
            post_markdown = post_content
            post_content, post_menu = render_md_to_html(post_content, is_extract_menu=True)
        else:
            logger.debug('unknown post_type: {}'.format(post_type))
            raise PostValidatorError('unknown post_type')

        post_docu.update({
            'post_content': post_content,
            'post_menu': post_menu,
        })
        if post_type == 'markdown':
            post_docu.update({
                'post_markdown': post_markdown,
            })

        return post_docu
Example #20
0
 def emit(self, record):
     logger.debug('LogMailHandler for record {}'.format(record))
     delay_task(send_mail,
                mailhost=self.mailhost,
                mailport=self.mailport,
                username=self.username,
                passwd=self.password,
                from_addr=self.fromaddr,
                to_addrs=self.toaddrs,  # 会自动被转换为列表
                subject=self.subject,
                content=record.getMessage()
                )
Example #21
0
 def update_posts_categories(cls, postid_category_map):
     """
     Args:
         postname_category_map (dict): {post_id: category_id}
     """
     logger.info('CategoriesModel.update_posts_categories')
     for post_id, cate in postid_category_map.items():
         r = yield cls.collection.update_one(
             {'_id': cls.oid(post_id)},
             {'$set': {'category': cls.oid(cate)}},
             upsert=False
         )
         logger.debug('update post %s category to %s for %s', post_id, cate, r.modified_count)
Example #22
0
    async def parse_results(cls, app, results):
        try:
            truncate = int(app.get_argument('truncate', default=-1))
        except Exception as e:
            raise ParserError(e)
        else:
            logger.debug('TruncateParser.parse_results for truncate %s', truncate)

        if truncate >= 0:
            for docu in results:
                docu['post_content'] = docu.get('post_markdown', '')[:truncate]
                docu['post_markdown'] = ''

        return results
Example #23
0
    async def parse_results(cls, app, results):
        try:
            truncate = int(app.get_argument('truncate', default=-1))
        except Exception as e:
            raise ParserError(e)
        else:
            logger.debug('TruncateParser.parse_results for truncate %s',
                         truncate)

        if truncate >= 0:
            for docu in results:
                docu['post_content'] = docu['post_content'][:truncate]
                docu['post_markdown'] = ''

        return results
Example #24
0
 def update_posts_categories(cls, postid_category_map):
     """
     Args:
         postname_category_map (dict): {post_id: category_id}
     """
     logger.info('CategoriesModel.update_posts_categories')
     for post_id, cate in postid_category_map.items():
         r = yield cls.collection.update_one(
             {'_id': cls.oid(post_id)},
             {'$set': {
                 'category': cls.oid(cate)
             }},
             upsert=False)
         logger.debug('update post %s category to %s for %s', post_id, cate,
                      r.modified_count)
Example #25
0
    async def parse_results(cls, app, results):
        logger.debug('PostContentParser.parse_results')
        try:
            plaintext = app.get_argument('plaintext',
                                         default='false',
                                         strip=True)
            assert (plaintext in ['true', 'false'])
        except (ValueError, AssertionError) as err:
            raise ParserError(err)
        else:
            plaintext = plaintext == 'true'

        r = []
        for docu in results:
            content = docu['post_content']
            if docu.get('post_password'):
                content = ''
            else:
                if plaintext:
                    content = app.plaintext_content(content)

            if 'category' in docu:
                category = (await app.db.categories.find_one(
                    {'_id': ObjectId(docu['category'])})) or {}
            else:
                category = {}

            print(">>", docu.get("post_created_at"),
                  type(docu.get("post_created_at")))
            r.append({
                'post_tags': docu.get('post_tags', []),
                'post_category': category.get('name'),
                'post_title': docu['post_title'],
                'post_type': docu.get('post_type', 'markdown'),
                'link': app.hyperlink_postname(docu['post_name']),
                'post_name': docu['post_name'],
                'post_markdown': docu.get('post_markdown'),
                'post_menu': docu.get('post_menu'),
                'post_content': content,
                'post_id': str(docu['_id']),
                'post_author': str(docu['post_author']),
                'post_modified_gmt': docu['post_modified_gmt'],
                'post_created_at': docu['post_created_at'],
                'post_status': docu['post_status'],
            })

        return r
Example #26
0
    def login_api(self):
        email = self.get_argument('email', strip=True)
        passwd = self.get_argument('password')
        is_keep_login = self.get_argument('is_keep_login', bool=True)
        logger.debug('login_api with email %s, passwd %s, is_keep_login %s',
                     email, passwd, is_keep_login)

        if not validate_email(email):
            logger.debug("invalidate email: %s", email)
            self.write_json(msg="invalidate email", status=ERROR)
            self.finish()
            return

        user_docu = (yield self.db.users.find_one({'email': email}))
        if not user_docu:
            logger.debug('email not existed: %s', email)
            self.http_400_bad_request(err='Wrong Account or Password')
            self.finish()
            return
        elif not validate_passwd(passwd, user_docu['password']):
            logger.debug('invalidate password: %s', passwd)
            self.http_400_bad_request(err='Wrong Account or Password')
            self.finish()
            return

        uid = str(user_docu['_id'])
        dtoken = {
            'uid': uid,
            'username': user_docu['username'],
            'exp': utcnow() + datetime.timedelta(days=30)
        }
        token = generate_token(dtoken)

        yield self.db.users.update(
            {'_id': user_docu['_id']},
            {'$set': {
                'token': token,
                'last_update': utcnow()
            }})

        expires_days = 30 if is_keep_login else None
        self.set_cookie('token', token, expires_days=expires_days)
        logger.debug('set cookies with uid %s, token %s, expires_days %s', uid,
                     token, expires_days)
        self.write_json(msg=OK)
        self.finish()
Example #27
0
    async def parse_results(cls, app, results):
        logger.debug('PostContentParser.parse_results')
        try:
            plaintext = app.get_argument('plaintext', default='false', strip=True)
            assert(plaintext in ['true', 'false'])
        except (ValueError, AssertionError) as err:
            raise ParserError(err)
        else:
            plaintext = plaintext == 'true'

        r = []
        for docu in results:
            content = docu['post_content']
            if docu.get('post_password'):
                content = ''
            else:
                if plaintext:
                    content = app.plaintext_content(content)

            if 'category' in docu:
                category = (await app.db.categories.find_one({'_id': ObjectId(docu['category'])})) or {}
            else:
                category = {}

            print(">>", docu.get("post_created_at"), type(docu.get("post_created_at")))
            r.append({
                'post_tags': docu.get('post_tags', []),
                'post_category': category.get('name'),
                'post_title': docu['post_title'],
                'post_type': docu.get('post_type', 'markdown'),
                'link': app.hyperlink_postname(docu['post_name']),
                'post_name': docu['post_name'],
                'post_markdown': docu.get('post_markdown'),
                'post_menu': docu.get('post_menu'),
                'post_content': content,
                'post_id': str(docu['_id']),
                'post_author': str(docu['post_author']),
                'post_modified_gmt': docu['post_modified_gmt'],
                'post_created_at': docu['post_created_at'],
                'post_status': docu['post_status'],
            })

        return r
Example #28
0
    def get_post_by_page(self):
        logger.info('GET get_post_by_page')

        try:
            page = int(self.get_argument('page', strip=True, default=1))
            is_full = self.get_argument('is_full', strip=True, default=False)
            logger.debug('get_post_by_page for page {}'.format(page))
        except ValueError as err:
            logger.error('when get_post_by_page: ', exc_info=err)
            self.finish()
            return

        skip = (page - 1) * N_POST_PER_PAGE
        cursor = self.db.posts.find()
        cursor.sort([('_id', pymongo.DESCENDING)]) \
            .limit(N_POST_PER_PAGE) \
            .skip(skip)
        posts = []
        while (yield cursor.fetch_next):
            docu = cursor.next_object()
            docu = unquote_fr_mongo(docu)
            if not is_full:
                if docu.get('post_password'):
                    docu['post_content'] = """
                        <div class="preview">
                            <span class="glyphicon glyphicon-lock" aria-hidden="true"></span>
                        </div>
                    """
                else:
                    docu['post_content'] = self.shortly_content(docu['post_content'], 500)

            posts.append(docu)

        # tags
        tags = (yield self.db.statistics.find_one(
            {'types': 'keyword'},
            {'keywords': 1}
        ))['keywords']

        self.render_post('archives/archives.html',
                         posts=posts, current_page=page, tags=tags)
        self.finish()
Example #29
0
    def get_post_by_name(self, name):
        logger.info('get_post_by_name for name {}'.format(name))

        name = self.parse_post_name(name)
        post = yield ArticlesModel.get({'post_name': name})
        if not post:
            self.redirect_404()
            return

        if post.get('post_password'):
            cookie_name = self.get_cookie_name(name)
            cookie = self.get_secure_cookie(cookie_name)
            logger.debug('get cookie {}'.format(cookie))
            if not cookie or cookie.decode() != post['post_password']:
                self.render2('archives/ajax/auth.html', post_name=post['post_name'])
                return

        post['post_type'] = post.get('post_type', 'text')
        self.render2('archives/article.html', post=post)
        self.finish()
Example #30
0
    def setup_db(self):
        logger.debug('connect database at {}:{}'
                     .format(options.dbhost, options.dbport))

        model = BaseBlogModel.make_connection(host=options.dbhost, port=options.dbport)
        self.conn = model.conn
        self.db = model.db
        self.mongo_conn = model.mongo_conn
        self.mongo_db = model.mongo_db

        # ensure index
        # posts
        # posts_idx = pymongo.IndexModel([('post_name',)], unique=True)
        # self.mongo_db.posts.create_indexes([posts_idx])
        self.mongo_db.posts.ensure_index([('post_name', pymongo.ASCENDING)], unique=True)  # PyMongo2.8
        # users
        # account_idx = pymongo.IndexModel([('account',)], unique=True)
        # username_idx = pymongo.IndexModel([('username',)], unique=True)
        # self.mongo_db.users.create_indexes([account_idx, username_idx])
        self.mongo_db.users.ensure_index([('account', pymongo.ASCENDING)], unique=True)   # PyMongo2.8
        self.mongo_db.users.ensure_index([('username', pymongo.ASCENDING)], unique=True)  # PyMongo2.8
Example #31
0
    async def update_query(cls, app, query, projection):
        try:
            category = app.get_argument('category', default=None, strip=True)
            if category and category != 'null':
                if is_objectid(category):
                    category = ObjectId(category)
                else:
                    docu = await app.db.categories.find_one({'name': category})
                    if docu:
                        category = docu['_id']
        except Exception as err:
            raise QueryMakerError(err)

        if 'category' not in query and category:
            logger.debug('CategoryFilterMaker.update_query for category %s', category)
            if category == 'null':
                query['category'] = {'$exists': False}
            else:
                query['category'] = category

        return query, projection
Example #32
0
    def get_post_by_id(self):
        try:
            is_full = self.get_argument('is_full', strip=True, default=False)
            _id = self.get_argument('id', strip=True)
        except ValueError:
            self.finish()
            return
        else:
            logger.debug('get_post_by_id for _id {}, is_full {}'.format(_id, is_full))

        docu = yield self.db.posts.find_one({'_id': ObjectId(_id)})
        if docu:
            docu['post_created_gmt'] = \
                docu['_id'].generation_time.timestamp() * 1000
            docu['_id'] = str(docu['_id'])
            docu['post_modified_gmt'] = \
                docu['post_modified_gmt'].timestamp() * 1000
            if not is_full:
                docu['post_content'] = docu['post_content'][: 1000]

        self.write_json(data=docu)
        self.finish()
Example #33
0
    def login_api(self):
        email = self.get_argument('email', strip=True)
        passwd = self.get_argument('password')
        is_keep_login = self.get_argument('is_keep_login', bool=True)
        logger.debug('login_api with email %s, passwd %s, is_keep_login %s', email, passwd, is_keep_login)

        if not validate_email(email):
            logger.debug("invalidate email: %s", email)
            self.write_json(msg="invalidate email", status=ERROR)
            self.finish()
            return

        user_docu = (yield self.db.users.find_one({'email': email}))
        if not user_docu:
            logger.debug('email not existed: %s', email)
            self.http_400_bad_request(err='Wrong Account or Password')
            self.finish()
            return
        elif not validate_passwd(passwd, user_docu['password']):
            logger.debug('invalidate password: %s', passwd)
            self.http_400_bad_request(err='Wrong Account or Password')
            self.finish()
            return

        uid = str(user_docu['_id'])
        dtoken = {'uid': uid, 'username': user_docu['username'], 'exp': utcnow() + datetime.timedelta(days=30)}
        token = generate_token(dtoken)

        yield self.db.users.update(
            {'_id': user_docu['_id']},
            {'$set': {'token': token, 'last_update': utcnow()}})

        expires_days = 30 if is_keep_login else None
        self.set_cookie('token', token, expires_days=expires_days)
        logger.debug('set cookies with uid %s, token %s, expires_days %s', uid, token, expires_days)
        self.write_json(msg=OK)
        self.finish()
Example #34
0
 def login_page(self):
     logger.debug('login_page')
     self.render2('login/index.html')
     self.finish()
Example #35
0
 def login_page(self):
     logger.debug('login_page')
     self.render2('login/index.html')
     self.finish()
Example #36
0
 def write_json(self, data):
     logger.debug('Resp: {}'.format(str(data)[: 50]))
     resp = json.dumps(data)
     self.set_header('Content-Type', 'application/json; charset=utf-8')
     self.write(resp)