chore(*): ready for packaging

Signed-off-by: Rongrong <15956627+Rongronggg9@users.noreply.github.com>
This commit is contained in:
Rongrong 2022-03-30 15:21:09 +08:00
parent e2e60328b2
commit 2339760532
No known key found for this signature in database
GPG Key ID: A36C9CDA260CB264
14 changed files with 141 additions and 30 deletions

3
pyproject.toml Normal file
View File

@ -0,0 +1,3 @@
[build-system]
requires = ["setuptools>=42", "wheel", "setuptools-declarative-requirements"]
build-backend = "setuptools.build_meta"

View File

@ -16,7 +16,7 @@ minify-html>=0.6.10, <=0.8.0 # 0.6.10 for Python 3.7 (however, minify-html<0.7.
matplotlib==3.5.1
# db
git+https://github.com/Rongronggg9/asyncpg.git@fix/pep-621
asyncpg@git+https://github.com/Rongronggg9/asyncpg.git@fix/pep-621
tortoise-orm[accel]==0.19.0
aerich==0.6.2

43
setup.cfg Normal file
View File

@ -0,0 +1,43 @@
[metadata]
name = rsstt
author = Rongrong
author_email = Rongronggg9@outlook.com
description = A Telegram RSS bot that cares about your reading experience
long_description = file: README.md
long_description_content_type = text/markdown
license = AGPLv3+
platforms = Linux, Windows, MacOS
url = https://github.com/Rongronggg9/RSS-to-Telegram-Bot
project_urls =
Bug Tracker = https://github.com/Rongronggg9/RSS-to-Telegram-Bot/issues
Documentation = https://github.com/Rongronggg9/RSS-to-Telegram-Bot/blob/dev/docs/README.md
Source Code = https://github.com/Rongronggg9/RSS-to-Telegram-Bot
Changelog = https://github.com/Rongronggg9/RSS-to-Telegram-Bot/blob/dev/docs/CHANGELOG.md
classifiers =
Development Status :: 5 - Production/Stable
Environment :: Console
Framework :: AsyncIO
Framework :: aiohttp
License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)
Operating System :: POSIX :: Linux
Operating System :: Microsoft :: Windows
Operating System :: MacOS
Programming Language :: Python :: 3 :: Only
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10
Topic :: Communications :: Chat
Topic :: Internet
Topic :: Multimedia
[requirements-files]
install_requires = requirements.txt
[options]
zip_safe = False
python_requires = >=3.7
[options.package_data]
* = *.json, *.opml, *.sql, *.txt
rsstt = ../requirements.txt

19
setup.py Normal file
View File

@ -0,0 +1,19 @@
import re
from functools import partial
from setuptools import setup, find_packages
from distutils.util import convert_path
version = {}
with open(convert_path('src/version.py')) as f:
exec(f.read(), version)
replacePackagePath = partial(re.compile(rf'^src').sub, 'rsstt')
source_packages = find_packages(include=['src', f'src.*'])
proj_packages = [replacePackagePath(name) for name in source_packages]
setup(
version=version['__version__'],
packages=proj_packages,
package_dir={'rsstt': 'src'},
)

View File

@ -18,7 +18,7 @@ from telethon import TelegramClient, events
from telethon.errors import ApiIdPublishedFloodError
from telethon.tl import types
from random import sample
from pathlib import Path
from os import path
from . import env, log, db, command
from .i18n import i18n, ALL_LANGUAGES, get_commands_list
@ -30,7 +30,6 @@ logger = log.getLogger('RSStT')
# initializing bot
loop = env.loop
Path("config").mkdir(parents=True, exist_ok=True)
bot: Optional[TelegramClient] = None
if not env.API_ID or not env.API_HASH:
logger.info('API_ID and/or API_HASH not set, use sample APIs instead. API_ID_PUBLISHED_FLOOD_ERROR may occur.')
@ -44,7 +43,8 @@ while API_KEYs:
sleep_for += 10
API_ID, API_HASH = API_KEYs.popitem()
try:
bot = TelegramClient('config/bot', API_ID, API_HASH, proxy=env.TELEGRAM_PROXY_DICT, request_retries=2,
bot = TelegramClient(path.join(env.config_folder_path, 'bot'),
API_ID, API_HASH, proxy=env.TELEGRAM_PROXY_DICT, request_retries=2,
raise_last_call_error=True, loop=loop).start(bot_token=env.TOKEN)
break
except ApiIdPublishedFloodError:

View File

@ -19,7 +19,7 @@ from ...parsing.utils import html_space_stripper
FeedSnifferCache = TTLCache(maxsize=256, ttl=60 * 60 * 24)
with open(path.join(path.dirname(__file__), '../..', 'opml_template.opml'), 'r') as __template:
with open(path.normpath(path.join(path.dirname(__file__), '../..', 'opml_template.opml')), 'r') as __template:
OPML_TEMPLATE = __template.read()

View File

@ -8,7 +8,7 @@ TORTOISE_ORM = {
},
"apps": {
"models": {
"models": ["aerich.models", "src.db.models"],
"models": ["aerich.models", f"{env.self_module_name}.db.models"],
"default_connection": "default",
},
},

View File

View File

View File

@ -4,12 +4,19 @@ from .compat import Final
import asyncio
import os
import sys
import logging
import re
import argparse
from telethon import TelegramClient
from telethon.tl.types import User, InputPeerUser
from python_socks import parse_proxy_url
from dotenv import load_dotenv
from pathlib import Path
from .version import __version__
logging.basicConfig(level=logging.INFO)
# ----- utils -----
@ -36,36 +43,73 @@ def __list_parser(var: Optional[str]) -> list[str]:
return var_t
# ----- determine the environment -----
__arg_parser = argparse.ArgumentParser(
description='RSS to Telegram Bot, a Telegram RSS bot that cares about your reading experience.')
__arg_parser.add_argument('-c', '--config', metavar='/path/to/config/folder', type=str, nargs=1,
help='path to the config folder')
cli_args = __arg_parser.parse_args()
cli_entry = sys.argv[0] # expect `-m` or `/path/to/telegramRSSbot.py`
custom_config_path = cli_args.config[0] if cli_args.config else None
is_self_run_as_a_whole_package = cli_entry.endswith('telegramRSSbot.py')
user_home = os.path.expanduser('~')
self_path = os.path.dirname(__file__)
self_module_name = os.path.basename(self_path)
if custom_config_path:
config_folder_path = os.path.normpath(os.path.abspath(custom_config_path))
elif is_self_run_as_a_whole_package:
config_folder_path = os.path.normpath(os.path.join(self_path, '..', 'config'))
else:
config_folder_path = os.path.join(user_home, '.rsstt')
Path(config_folder_path).mkdir(parents=True, exist_ok=True)
logging.info(f'Config folder: {config_folder_path}')
# ----- load .env -----
load_dotenv(override=True)
dot_env_paths = (os.path.join(config_folder_path, '.env'),
os.path.join(os.path.abspath('.'), '.env'))
if is_self_run_as_a_whole_package:
dot_env_paths = (os.path.normpath(os.path.join(self_path, '..', '.env')),) + dot_env_paths
for dot_env_path in sorted(set(dot_env_paths), key=dot_env_paths.index):
if os.path.isfile(dot_env_path):
load_dotenv(dot_env_path, override=True)
logging.info(f'Found .env file at "{dot_env_path}", loaded')
# ----- get version -----
# noinspection PyBroadException
try:
with open('.version', 'r') as v:
_version = v.read().strip()
except Exception:
_version = 'dirty'
if _version == 'dirty':
from subprocess import Popen, PIPE, DEVNULL
if is_self_run_as_a_whole_package:
# noinspection PyBroadException
try:
with Popen(['git', 'describe', '--tags'], shell=False, stdout=PIPE, stderr=DEVNULL, bufsize=-1) as __:
__.wait(3)
_version = __.stdout.read().decode().strip()
with Popen(['git', 'branch', '--show-current'], shell=False, stdout=PIPE, stderr=DEVNULL, bufsize=-1) as __:
__.wait(3)
__ = __.stdout.read().decode().strip()
if __:
_version += f'@{__}'
with open(os.path.normpath(os.path.join(self_path, '..', '.version')), 'r') as v:
_version = v.read().strip()
except Exception:
_version = 'dirty'
if not _version or _version == '@':
if _version == 'dirty':
from subprocess import Popen, PIPE, DEVNULL
# noinspection PyBroadException
try:
with Popen(['git', 'describe', '--tags'], shell=False, stdout=PIPE, stderr=DEVNULL, bufsize=-1) as __:
__.wait(3)
_version = __.stdout.read().decode().strip()
with Popen(['git', 'branch', '--show-current'], shell=False, stdout=PIPE, stderr=DEVNULL, bufsize=-1) as __:
__.wait(3)
__ = __.stdout.read().decode().strip()
if __:
_version += f'@{__}'
except Exception:
_version = 'dirty'
if not _version or _version == '@':
_version = 'dirty'
else:
_version = 'dirty'
if not re.match(r'v?\d+\.\d+(\.\d+)?', _version):
_version = 'v' + (__version__ + '-' + _version if not _version == 'dirty' else __version__)
VERSION: Final = _version
del _version
@ -152,7 +196,7 @@ else:
PROXY_BYPASS_PRIVATE: Final = __bool_parser(os.environ.get('PROXY_BYPASS_PRIVATE'))
PROXY_BYPASS_DOMAINS: Final = __list_parser(os.environ.get('PROXY_BYPASS_DOMAINS'))
USER_AGENT: Final = os.environ.get('USER_AGENT') or 'RSStT/2.2 RSS Reader'
USER_AGENT: Final = os.environ.get('USER_AGENT') or f'RSStT/{__version__} RSS Reader'
IPV6_PRIOR: Final = __bool_parser(os.environ.get('IPV6_PRIOR'))
# ----- img relay server config -----
@ -170,7 +214,7 @@ IMAGES_WESERV_NL: Final = ('https://' if not _images_weserv_nl.startswith('http'
del _images_weserv_nl
# ----- db config -----
_database_url = os.environ.get('DATABASE_URL') or 'sqlite://config/db.sqlite3?journal_mode=OFF'
_database_url = os.environ.get('DATABASE_URL') or f'sqlite://{config_folder_path}/db.sqlite3?journal_mode=OFF'
DATABASE_URL: Final = (_database_url.replace('postgresql', 'postgres', 1) if _database_url.startswith('postgresql')
else _database_url)
del _database_url
@ -204,8 +248,8 @@ if any((os.environ.get('REDISHOST'), os.environ.get('REDISUSER'), os.environ.get
'REDISPORT\n'
'REDIS_NUM')
if os.path.exists('config/rss.db'):
os.rename('config/rss.db', 'config/rss.db.bak')
if is_self_run_as_a_whole_package and os.path.exists(os.path.join(config_folder_path, 'rss.db')):
os.rename(os.path.join(config_folder_path, 'rss.db'), os.path.join(config_folder_path, 'rss.db.bak'))
logging.warning('Sqlite DB "rss.db" with old schema is DEPRECATED and renamed to "rss.db.bak" automatically!\n'
'ALL SUBS IN THE OLD DB WILL NOT BE MIGRATED. '
'IF YOU NEED TO BACKUP YOUR SUBS, DOWNGRADE AND USE "/export" COMMAND TO BACKUP.')

1
src/parsing/__init__.py Normal file
View File

@ -0,0 +1 @@
from __future__ import annotations

1
src/version.py Normal file
View File

@ -0,0 +1 @@
__version__ = "2.2.1.dev0"