Exemple #1
0
    def _delete(self, msg):
        string = msg.content
        try:
            argv = string.split()
            article_id = int(argv[1])
        except:
            logger.info("_delete parse string fail: " + string)
            return "delete 失败,不是合法的输入,请检查格式"

        db = DbOperator()
        success, result = db.find_article(article_id)
        if not success:
            logger.debug("_delete fetch nothing: " + string)
            return "试图删除编号为" + str(article_id) + "的文章,但未找到"
        user = msg.source
        if result['open_id'] == user:  # 确实是本人的观察目标
            if update_article_status(article_id,
                                     False,
                                     optionals={
                                         "reason": REASON_DELETE_BY_USER
                                     }):
                return "成功删除观察目标:" + str(article_id)
            else:
                logger.error("_delete process fail: " + string)
                return "您的输入合法,但后台处理失败,请联系管理员"
        else:
            logger.info(user + " try to delete article: " + str(article_id))
            return str(article_id) + " 不是您的观察目标,无法删除"
Exemple #2
0
    def ob_this_one(self, URL, open_id):
        """Add a new article to watch list.
        This function receive a unique(guaranteed by caller) article URL to be
        observed. It first check the accessibility of the article, then add
        it to watch list in database.

        Args:
            URL : str

        Returns:
            success: bool
        """
        db = DbOperator()
        # 先添加一次,然后获取 article_id 给 Checker 用
        success, article_id = db.db_add_helper(URL, open_id,
                                               FAKE_PATH_PLACE_HOLDER,
                                               STATUS_NEW_UNKNOWN)
        if not success:
            print("db_add_helper FAIL!!!")
            logger.warning("ob_this_one fail, add db fail: "
                           + " ".join(map(str, [article_id, URL, open_id])))
            return False
        self.q.put(article_id=article_id, url=URL,
                   download=True, block=True, timeout=1)
        # 放进 Checker 的队列就不管了。后续由回调函数实现
        return True
Exemple #3
0
 def _status(self, msg):
     open_id = msg.source
     db = DbOperator()
     success, user = db.find_user(open_id)
     if not success:
         logger.info("_status can't find user:"******"没有找到邮箱绑定记录,请重新绑定"
     email = user['email']
     return "你的账号现在绑定邮箱为:" + email
Exemple #4
0
 def _list(self, msg):
     open_id = msg.source
     db = DbOperator()
     success, article_list = db.find_my_article(open_id)
     if not success:
         logger.info("_list no record by user:"******"没有正在观察中的记录"
     reply = "现有" + str(len(article_list)) + "条记录观察中\n-------\n"
     URL_list = []
     for item in article_list:
         URL_list.append(str(item['article_id']) + " " + item['URL'])
     reply = reply + "\n\n".join(URL_list)
     return reply
Exemple #5
0
    def ob_all(self):
        """Observe all objects in watch list.
        No paras needed. It automatically fetches data from database,
        then loop through all items.

        Args:

        Returns:
            success: bool
        """
        db = DbOperator()
        success, watch_list = db.fetch_all_article()
        if not success:
            logger.warning("ob_all find nothing")
            return False
        for item in watch_list:
            article_id = item['article_id']
            URL = item['URL']
            status = item['status']
            start_date = item['start_date']

            if _out_of_date(start_date):
                # 超出30天的观察目标,停止观察
                backup_addr = item['backup_addr']
                update_article_status(article_id, False, backup_addr)
                logger.info(
                    "move article to archive: " +
                    " ".join(map(str, [article_id, status, start_date])))
                continue
            else:
                if status == 0:  # 初次观察,需要制作备份
                    self.q.put(article_id=article_id,
                               url=URL,
                               download=True,
                               block=True,
                               timeout=1)
                elif status == 1:  # 正常观察期,不再制作备份
                    self.q.put(article_id=article_id,
                               url=URL,
                               download=False,
                               block=True,
                               timeout=1)
                else:
                    logger.error("Unknow article status: " +
                                 " ".join(map(str, [article_id, URL, status])))
        return True
Exemple #6
0
    def _admin_list(self, msg):
        user = msg.source
        if user not in ADMIN_LIST:
            return "非管理员账号,无法执行admin命令"
        db = DbOperator()
        success, result = db.fetch_all_article()
        if not success:
            logger.info("_admin_list fetch 0")
            return "admin-list 查询失败,结果为空"

        output = []
        for item in result:
            output.append(item['article_id'])
            output.append(item['URL'])
            output.append(item['open_id'])
            output.append(item['backup_addr'])
            output.append(item['start_date'])
            output.append(item['status'])
            output.append('--------')
        return "\n".join(map(str, output))
Exemple #7
0
    def _handle_URL(self, msg):
        open_id = msg.source
        URL = self._trim_URL(msg.content)

        db = DbOperator()
        success, result = db.find_my_article(open_id)
        if success:
            for item in result:
                if URL == item['URL']:
                    reply = "目标已在观察列表中:" + URL
                    return reply

        success = self.ob.ob_this_one(URL, open_id)
        if not success:
            reply = "目标初次访问异常,无法进行备份。若确定是误判,请联系管理员:[email protected]"
        else:
            reply = "收到!开始观察目标!"
        # 判断一下用户是否绑定邮箱,没绑定的话提供警告
        success, _ = db.find_user(open_id)
        if not success:
            reply = reply + "\n--------------\n【警告】你的账号未绑定邮箱,无法收到备份及通知。请回复[help]查看规则"
        return reply
Exemple #8
0
 def _handle_email(self, msg):
     open_id = msg.source
     email = msg.content
     user = (open_id, email)
     send_flag = False
     db = DbOperator()
     success, _ = db.find_user(open_id)
     if success:  # 已有记录,更新绑定关系
         result = db.update_user(user)
     else:  # 无记录,添加绑定关系
         result = db.add_user(user)
         send_flag = send_user_check_email(email)
     if result:
         reply = "你的账号成功绑定邮箱:" + email
         if send_flag:
             reply += "\n--------\n"
             reply += """你是初次绑定邮箱,我发送了一封确认邮件给您
                         请检查邮箱,确认能收到我的通知邮件
                         (注意垃圾箱!)"""
     else:
         # db 操作失败的日志 db 那边会记录
         reply = "绑定邮箱:" + email + "失败!请联系管理员处理:[email protected]"
     return reply
Exemple #9
0
    def _admin_status(self, msg):
        user = msg.source
        if user not in ADMIN_LIST:
            return "非管理员账号,无法执行admin命令"

        db = DbOperator()
        reply = analyze_article_status(db)
        reply += "\n-------\n"
        reply += analyze_user_status(db)
        reply += "\n-------\n"
        qsize = self.ob.get_cur_q_size()
        reply += "队列中的条目数量:" + str(qsize)
        reply += "\n-------\n"
        space_info = total_used_space(DEFAULT_PATH)
        reply += space_info
        return reply
Exemple #10
0
def update_article_status(article_id, valid, backup_path=None):
    # 做点准备工作
    db = DbOperator()
    success, item = db.find_article(article_id)
    if not success:
        # log it
        print("can't find article by article_id: " + str(article_id))
        logger.error("can't find article by article_id: " + str(article_id))
        return False
    URL = item['URL']
    open_id = item['open_id']
    success, result = db.find_user(open_id)
    if not success:
        logger.error("article & user no match: " +
                     " ".join(map(str, [article_id, open_id])))
        return False
    email = result['email']

    if not valid:  # 当文章已不可访问
        if item['backup_addr'] == FAKE_PATH_PLACE_HOLDER:
            backup_addr = None
        else:
            backup_addr = item['backup_addr']
        notify_user(email, URL, backup_addr)
        db.archive_article(item)
        logger.info("article expired, move to archive: " +
                    " ".join(map(str, [article_id, URL])))
    else:
        prev_status = item['status']
        if prev_status == 1:  # 正常观察状态,无需额外操作
            return True
        elif prev_status == 0:  # 初次完成观察,制作备份
            if backup_path == None:
                print("backup addr not valid")
                return False
            else:
                new_path = _backup_article(article_id, backup_path)
                if new_path == None:
                    return False
                article_info = (article_id, new_path, 1)  # 制作备份完成,状态更新成1
                return db.update_article(article_info)
        else:
            print("unknown status!")
            logger.error(
                "article status Error: " +
                " ".join(map(str, [article_id, open_id, prev_status])))

    return True
Exemple #11
0
def update_article_status(article_id, valid, backup_path=None, optionals={}):
    """Do jobs when article status changed.

    Args:
        article_id : int
        valid : bool
        backup_path : str
        optionals : dict 
            maybe contains: "reason" shows why status changed
                            "title" shows article title detected
    Returns:
        success: bool
    """
    # 做点准备工作
    db = DbOperator()
    success, item = db.find_article(article_id)
    if not success:
        # log it
        print("can't find article by article_id: " + str(article_id))
        logger.error("can't find article by article_id: " + str(article_id))
        return False
    open_id = item['open_id']
    success, result = db.find_user(open_id)
    if success:
        email = result['email']
        user_registered_flag = True
    else:
        logger.info("article & user no match: "
                     + " ".join(map(str, [article_id, open_id])))
        user_registered_flag = False

    # 根据状态变化执行处理
    if not valid:  # 当文章已不可访问
        if user_registered_flag: # 用户有绑定邮箱,则执行通知
            update_info = (article_id, optionals)
            _stop_watching(update_info, item, email, db)
        else: # 没有绑定邮箱,记错误日志
            logger.error("article invalid, can't notify user. "
                        + " ".join(map(str, [article_id, open_id])))
    else:
        prev_status = item['status']
        if prev_status == STATUS_NORMAL_OB:  # 正常观察状态,无需额外操作
            return True
        elif prev_status == STATUS_NEW_UNKNOWN:  # 初次完成观察,制作备份
            if backup_path is None:
                print("backup addr not valid")
                return False
            else:
                new_path = _backup_article(article_id, backup_path)
                try:
                    title = optionals["title"]
                except KeyError:
                    title = ''
                if new_path is None:
                    return False
                article_info = (article_id, new_path, STATUS_NORMAL_OB, title) # 制作备份完成,状态更新
                return db.update_article(article_info)
        else:
            print("unknown status!")
            logger.error("article status Error: "
                         + " ".join(map(str, [article_id, open_id, prev_status])))

    return True
Exemple #12
0
def update_article_status(article_id, valid, backup_path=None, optionals={}):
    """Do jobs when article status changed.

    Args:
        article_id : int
        valid : bool
        backup_path : str
        optionals : dict 
            maybe contains: "reason" shows why status changed
                            "title" shows article title detected
    Returns:
        success: bool
    """
    # 做点准备工作
    db = DbOperator()
    success, item = db.find_article(article_id)
    if not success:
        # log it
        print("can't find article by article_id: " + str(article_id))
        logger.error("can't find article by article_id: " + str(article_id))
        return False
    URL = item['URL']
    open_id = item['open_id']
    success, result = db.find_user(open_id)
    if not success:
        logger.error("article & user no match: "
                     + " ".join(map(str, [article_id, open_id])))
        return False
    email = result['email']
    # 开始更新数据库
    if not valid:  # 当文章已不可访问
        if item['backup_addr'] == FAKE_PATH_PLACE_HOLDER:
            backup_addr = None
        else:
            backup_addr = item['backup_addr']
        try:
            notify_user(email, URL, backup_addr)
            item['status'] = reason2status[optionals["reason"]]
            db.archive_article(item)
        except:
            logger.error("update_article_status ERROR")
            return False
        logger.info("article expired, move to archive: "
                    + " ".join(map(str, [article_id, URL])))
    else:
        prev_status = item['status']
        if prev_status == STATUS_NORMAL_OB:  # 正常观察状态,无需额外操作
            return True
        elif prev_status == STATUS_NEW_UNKNOWN:  # 初次完成观察,制作备份
            if backup_path == None:
                print("backup addr not valid")
                return False
            else:
                new_path = _backup_article(article_id, backup_path)
                if new_path == None:
                    return False
                article_info = (article_id, new_path, STATUS_NORMAL_OB) # 制作备份完成,状态更新
                return db.update_article(article_info)
        else:
            print("unknown status!")
            logger.error("article status Error: "
                         + " ".join(map(str, [article_id, open_id, prev_status])))

    return True