async def add_bookshelf(request):
    """
    Add bookshelf (any user can)
    :param request:
    :return:
        :   -1  user's session expire, need to login again
        :   0   not add
        :   1   add successfully
    """
    user = request['session'].get('user', None)
    data = parse_qs(str(request.body, encoding='utf-8'))
    novels_name = data.get('novels_name', '')
    chapter_url = data.get('chapter_url', '')
    last_read_url = data.get('last_read_url', '')
    if user and novels_name and chapter_url:
        url = "/chapter?url={chapter_url}&novels_name={novels_name}".format(chapter_url=chapter_url[0],
                                                                            novels_name=novels_name[0])
        time = get_time()
        try:
            motor_db = motor_base.get_db()
            res = await motor_db.user_message.update_one({'user': user}, {'$set': {'last_update_time': time}},
                                                         upsert=True)
            if res:
                await motor_db.user_message.update_one(
                    {'user': user, 'books_url.book_url': {'$ne': url}},
                    {'$push': {
                        'books_url': {'book_url': url, 'add_time': time, 'last_read_url': unquote(last_read_url[0])}}})
                LOGGER.info('You have added this page successfully in your bookshelf!')
                return json({'status': 1})
        except Exception as e:
            LOGGER.exception(e)
            return json({'status': 0})
    else:
        return json({'status': -1})
async def add_bookmark(request):
    """
    Add bookmark (any user can)
    :param request:
    :return:
        :   -1  user's session expire, need to login again
        :   0   not add
        :   1   add successfully
    """
    user = request['session'].get('user', None)
    data = parse_qs(str(request.body, encoding='utf-8'))
    # get the bookmark url
    bookmark_url = data.get('bookmark_url', '')
    if user and bookmark_url:
        url = unquote(bookmark_url[0])
        time = get_time()
        try:
            motor_db = motor_base.get_db()
            res = await motor_db.user_message.update_one({'user': user}, {'$set': {'last_update_time': time}},
                                                         upsert=True)
            if res:
                # store the bookmark data in the mongodb, user_message collection
                await motor_db.user_message.update_one(
                    {'user': user, 'bookmarks.bookmark': {'$ne': url}},
                    {'$push': {'bookmarks': {'bookmark': url, 'add_time': time}}})
                LOGGER.info('bookmark has been added')
                return json({'status': 1})
        except Exception as e:
            LOGGER.exception(e)
            return json({'status': 0})
    else:
        return json({'status': -1})
Exemple #3
0
async def quickreading_search(request):
    """
    Search Button
    :param request:novel's name
    :return:
        result.html: search result(original website link, chapter page link, Whether parsed or recommended)
        html("No result"): There is an error
    """
    start = time.time()
    # delete space in the beginning and the ending of input novel's name
    name = str(request.args.get('wd', '')).strip()
    novels_keyword = name.split(' ')[0]
    # use motor to manage mongodb
    motor_db = motor_base.get_db()
    if not name:
        return redirect('/')
    else:
        # store the search record
        try:
            await motor_db.search_records.update_one({'keyword': name},
                                                     {'$inc': {
                                                         'count': 1
                                                     }},
                                                     upsert=True)
        except Exception as e:
            LOGGER.exception(e)
    # Retrieve the search results through a search engine
    parse_result = None
    # choose different search engine to search novels
    if name.startswith('!baidu'):
        novels_keyword = name.split('baidu')[1].strip()
        novels_name = 'intitle:{name} 小说 阅读'.format(name=novels_keyword)
        parse_result = await get_novels_info(class_name='baidu',
                                             novels_name=novels_name)
    elif name.startswith('!360'):
        novels_keyword = name.split('360')[1].strip()
        novels_name = "{name} 小说 最新章节".format(name=novels_keyword)
        parse_result = await get_novels_info(class_name='so',
                                             novels_name=novels_name)
    elif name.startswith('!bing'):
        novels_keyword = name.split('bing')[1].strip()
        novels_name = "{name} 小说 阅读 最新章节".format(name=novels_keyword)
        parse_result = await get_novels_info(class_name='bing',
                                             novels_name=novels_name)
    elif name.startswith('!google'):
        novels_keyword = name.split('google')[1].strip()
        novels_name = "{name} 小说 阅读 最新章节".format(name=novels_keyword)
        parse_result = await get_novels_info(class_name='google',
                                             novels_name=novels_name)
    else:
        for each_engine in ENGINE_PRIORITY:
            # for bing
            if each_engine == "bing":
                novels_name = "{name} 小说 阅读 最新章节".format(name=name)
                parse_result = await get_novels_info(class_name='bing',
                                                     novels_name=novels_name)
                if parse_result:
                    break
            # for 360 so
            if each_engine == "360":
                novels_name = "{name} 小说 最新章节".format(name=name)
                parse_result = await get_novels_info(class_name='so',
                                                     novels_name=novels_name)
                if parse_result:
                    break
            # for baidu
            if each_engine == "baidu":
                novels_name = 'intitle:{name} 小说 阅读'.format(name=name)
                parse_result = await get_novels_info(class_name='baidu',
                                                     novels_name=novels_name)
                if parse_result:
                    break
            if each_engine == "google":
                novels_name = '{name} 小说 阅读'.format(name=name)
                parse_result = await get_novels_info(class_name='google',
                                                     novels_name=novels_name)
                if parse_result:
                    break
    if parse_result:
        # sort the search result (is_recommend, is_parse put first place)
        result_sorted = sorted(parse_result,
                               reverse=True,
                               key=itemgetter('is_recommend', 'is_parse',
                                              'timestamp'))
        user = request['session'].get('user', None)
        if user:
            data = await motor_db.user.find_one({'user': user})
            user_role = data.get('role', None)
            try:
                time_now = get_time()
                # store search date
                res = await motor_db.user_message.update_one(
                    {'user': user}, {'$set': {
                        'last_update_time': time_now
                    }},
                    upsert=True)
                if res:
                    # store novels name and count(if searched before add one )
                    store_search_information = await motor_db.user_message.update_one(
                        {
                            'user': user,
                            'search_records.keyword': {
                                '$ne': novels_keyword
                            }
                        },
                        {
                            '$push': {
                                'search_records': {
                                    'keyword': novels_keyword,
                                    'counts': 1
                                }
                            }
                        },
                    )

                    if store_search_information:
                        await motor_db.user_message.update_one(
                            {
                                'user': user,
                                'search_records.keyword': novels_keyword
                            }, {'$inc': {
                                'search_records.$.counts': 1
                            }})
            except Exception as e:
                LOGGER.exception(e)
            return template('result.html',
                            is_login=1,
                            user=user,
                            user_role=user_role,
                            name=novels_keyword,
                            time='%.2f' % (time.time() - start),
                            result=result_sorted,
                            count=len(parse_result))
        else:
            return template('result.html',
                            is_login=0,
                            name=novels_keyword,
                            time='%.2f' % (time.time() - start),
                            result=result_sorted,
                            count=len(parse_result))

    else:
        return html("No Result!")
async def user_register(request):
    """
    User Register
    :param request:
    :return:
        :   -2  question answer is wrong
        :   -1  user name is existing
        :   0   user name or password is null
        :   1   register successfully
    """
    register_data = parse_qs(str(request.body, encoding='utf-8'))
    user = register_data.get('user', [None])[0]
    pwd = register_data.get('pwd', [None])[0]
    Email = register_data.get('email', [None])[0]
    answer = register_data.get('answer', [None])[0]
    reg_index = request.cookies.get('reg_index')
    if user and pwd and Email and answer and reg_index and len(user) > 2 and len(pwd) > 5:
        motor_db = motor_base.get_db()
        is_exist = await motor_db.user.find_one({'user': user})
        if not is_exist:
            # check question whether right(non-robot check)
            real_answer = get_real_answer(str(reg_index))
            if real_answer and real_answer == answer:
                # use md5 generate token+password to hash value
                pass_first = hashlib.md5((CONFIG.WEBSITE["TOKEN"] + pwd).encode("utf-8")).hexdigest()
                password = hashlib.md5(pass_first.encode("utf-8")).hexdigest()
                time = get_time()
                data = {
                    "user": user,
                    "password": password,
                    "email": Email,
                    "register_time": time,
                    "role": "General User"
                }
                # send register notification email
                RECIPIENT = Email
                msg = MIMEMultipart('alternative')
                msg['Subject'] = SUBJECT1
                msg['From'] = email.utils.formataddr((SENDERNAME, SENDER))
                msg['To'] = RECIPIENT
                part2 = MIMEText(BODY_HTML.format(User=user), 'html')
                msg.attach(part2)
                try:
                    server = smtplib.SMTP(HOST, PORT)
                    server.ehlo()
                    server.starttls()
                    server.ehlo()
                    server.login(USERNAME_SMTP, PASSWORD_SMTP)
                    server.sendmail(SENDER, RECIPIENT, msg.as_string())
                    server.close()
                # Display an error message if something goes wrong.
                except Exception as e:
                    print("Error: ", e)
                else:
                    print("Email sent!")
                await motor_db.user.save(data)
                return json({'status': 1})
            else:
                return json({'status': -2})
        else:
            return json({'status': -1})
    else:
        return json({'status': 0})
async def get_the_latest_chapter(chapter_url, timeout=15):
    try:
        with async_timeout.timeout(timeout):
            url = parse_qs(urlparse(chapter_url).query).get('url', '')
            novels_name = parse_qs(urlparse(chapter_url).query).get(
                'novels_name', '')
            data = None
            if url and novels_name:
                url = url[0]
                novels_name = novels_name[0]
                netloc = urlparse(url).netloc
                if netloc in LATEST_RULES.keys():
                    headers = {'user-agent': await get_random_user_agent()}
                    try:
                        html = await target_fetch(url=url,
                                                  headers=headers,
                                                  timeout=timeout)
                        if html is None:
                            html = get_html_by_requests(url=url,
                                                        headers=headers,
                                                        timeout=timeout)
                    except TypeError:
                        html = get_html_by_requests(url=url,
                                                    headers=headers,
                                                    timeout=timeout)
                    except Exception as e:
                        LOGGER.exception(e)
                        return None
                    try:
                        soup = BeautifulSoup(html, 'html5lib')
                    except Exception as e:
                        LOGGER.exception(e)
                        return None
                    latest_chapter_name, latest_chapter_url = None, None
                    if LATEST_RULES[netloc].plan:
                        meta_value = LATEST_RULES[netloc].meta_value
                        latest_chapter_name = soup.select(
                            'meta[property="{0}"]'.format(
                                meta_value["latest_chapter_name"])
                        ) or soup.select('meta[name="{0}"]'.format(
                            meta_value["latest_chapter_name"]))

                        latest_chapter_name = latest_chapter_name[0].get(
                            'content', None) if latest_chapter_name else None
                        latest_chapter_url = soup.select(
                            'meta[property="{0}"]'.format(
                                meta_value["latest_chapter_url"])
                        ) or soup.select('meta[name="{0}"]'.format(
                            meta_value["latest_chapter_url"]))
                        latest_chapter_url = urljoin(
                            chapter_url, latest_chapter_url[0].get(
                                'content',
                                None)) if latest_chapter_url else None
                    else:
                        selector = LATEST_RULES[netloc].selector
                        content_url = selector.get('content_url')
                        if selector.get('id', None):
                            latest_chapter_soup = soup.find_all(
                                id=selector['id'])
                        elif selector.get('class', None):
                            latest_chapter_soup = soup.find_all(
                                class_=selector['class'])
                        else:
                            latest_chapter_soup = soup.select(
                                selector.get('tag'))
                        if latest_chapter_soup:
                            if content_url == '1':
                                pass
                            elif content_url == '0':
                                pass
                            else:
                                latest_chapter_url = content_url + latest_chapter_soup[
                                    0].get('href', None)
                            latest_chapter_name = latest_chapter_soup[0].get(
                                'title', None)
                    if latest_chapter_name and latest_chapter_url:
                        time_current = get_time()
                        # print(latest_chapter_url)
                        data = {
                            "latest_chapter_name":
                            latest_chapter_name,
                            "latest_chapter_url":
                            latest_chapter_url,
                            "quickreading_chapter_url":
                            chapter_url,
                            "quickreading_content_url":
                            "/quickreading_content?url={latest_chapter_url}&name={name}&chapter_url={chapter_url}&novels_name={novels_name}"
                            .format(
                                latest_chapter_url=latest_chapter_url,
                                name=latest_chapter_name,
                                chapter_url=url,
                                novels_name=novels_name,
                            ),
                        }
                        # store latest chapter
                        motor_db = MotorBase().get_db()
                        await motor_db.latest_chapter.update_one(
                            {
                                "novels_name": novels_name,
                                'quickreading_chapter_url': chapter_url
                            }, {
                                '$set': {
                                    'data': data,
                                    "finished_at": time_current
                                }
                            },
                            upsert=True)
            return data
    except Exception as e:
        LOGGER.exception(e)
        return None