-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit dae23f8
Showing
9 changed files
with
965 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
name: CI | ||
|
||
on: | ||
push: | ||
branches: [ main, master ] | ||
tags: | ||
- 'v*.*.*' | ||
pull_request: | ||
branches: [ main, master ] | ||
|
||
jobs: | ||
test: | ||
runs-on: ubuntu-latest | ||
strategy: | ||
matrix: | ||
python-version: ['3.8', '3.11'] | ||
steps: | ||
- uses: actions/checkout@v2 | ||
- name: Set up Python ${{ matrix.python-version }} | ||
uses: actions/setup-python@v2 | ||
with: | ||
python-version: ${{ matrix.python-version }} | ||
- name: Install dependencies | ||
run: | | ||
python -m pip install --upgrade pip | ||
python -m pip install '.[dev]' | ||
- name: Check code with black | ||
run: | | ||
black --check . | ||
- name: Lint code | ||
run: | | ||
pylama | ||
- name: Test with pytest | ||
run: | | ||
#pytest | ||
deploy: | ||
needs: test | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v2 | ||
- uses: actions/setup-python@v2 | ||
with: | ||
python-version: '3.x' | ||
- id: check-tag | ||
run: | | ||
if [[ "${{ github.event.ref }}" =~ ^refs/tags/v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then | ||
echo ::set-output name=match::true | ||
fi | ||
- name: Create PyPI release | ||
uses: casperdcl/deploy-pypi@v2 | ||
with: | ||
password: ${{ secrets.PYPI_TOKEN }} | ||
build: true | ||
# only upload if a tag is pushed (otherwise just build & check) | ||
upload: ${{ github.event_name == 'push' && steps.check-tag.outputs.match == 'true' }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
__pycache__ | ||
.cache | ||
.mypy_cache | ||
.pytest_cache | ||
build | ||
dist | ||
.eggs | ||
*.egg-info | ||
*/_version.py | ||
|
||
*~ | ||
.#* | ||
*# |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
# Web to PDF | ||
|
||
[![Latest Release](https://img.shields.io/pypi/v/web2pdf.svg)](https://pypi.org/project/web2pdf) | ||
[![CI](https://github.com/deltachat-bot/web2pdf/actions/workflows/python-ci.yml/badge.svg)](https://github.com/deltachat-bot/web2pdf/actions/workflows/python-ci.yml) | ||
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) | ||
|
||
Delta Chat bot that allows to fetch websites as PDF. Just send any URL to the bot | ||
in private or add it to get a PDF in any message containing an URL. | ||
|
||
## Install | ||
|
||
```sh | ||
pip install web2pdf | ||
``` | ||
|
||
You also need to install wkhtmltopdf package. Debian/Ubuntu example: | ||
|
||
```sh | ||
sudo apt-get install wkhtmltopdf | ||
``` | ||
|
||
**Warning!** Version in debian/ubuntu repos have reduced functionality (because it | ||
is compiled without the wkhtmltopdf QT patches), such as adding outlines, headers, | ||
footers, TOC etc. To use this options you should install static binary from | ||
wkhtmltopdf site: https://wkhtmltopdf.org/ | ||
|
||
## Usage | ||
|
||
Configure the bot's Delta Chat account: | ||
|
||
```sh | ||
web2pdf init [email protected] PASSWORD | ||
``` | ||
|
||
You can run `web2pdf init` several times to add multiple different accounts to the | ||
bot so it can be reached in more than one email address. | ||
|
||
The bot's display name, avatar and status/signature can also be tweaked: | ||
|
||
``` | ||
web2pdf config selfavatar "/path/to/avatar.png" | ||
web2pdf config displayname "My Bot" | ||
web2pdf config selfstatus "Hi, I am a Delta Chat bot" | ||
``` | ||
|
||
To run the bot so it starts processing messages: | ||
|
||
```sh | ||
web2pdf serve | ||
``` | ||
|
||
To see all available options run `web2pdf --help` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[pylama] | ||
linters=mccabe,pyflakes,pylint,isort,mypy | ||
skip=.*,build/*,tests/*,*/_version.py,*/flycheck_* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
[build-system] | ||
requires = ["setuptools>=64", "setuptools_scm>=8"] | ||
build-backend = "setuptools.build_meta" | ||
|
||
[project] | ||
name = "web2pdf" | ||
description = "Download websites as PDF in Delta Chat" | ||
dynamic = ["version"] | ||
readme = "README.md" | ||
requires-python = ">=3.8" | ||
keywords = ["deltachat", "bot", "web", "pdf"] | ||
authors = [ | ||
{name = "adbenitez", email = "[email protected]"}, | ||
] | ||
classifiers = [ | ||
"Development Status :: 4 - Beta", | ||
"Programming Language :: Python", | ||
"License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)", | ||
] | ||
dependencies = [ | ||
"deltabot-cli>=6.2.0,<7.0", | ||
"pdfkit", | ||
] | ||
|
||
[project.urls] | ||
Homepage = "https://github.com/deltachat-bot/web2pdf" | ||
|
||
[project.optional-dependencies] | ||
dev = [ | ||
"black", | ||
"mypy", | ||
"isort", | ||
"pylint", | ||
"pylama", | ||
"pytest", | ||
"types-requests", | ||
] | ||
|
||
[project.scripts] | ||
web2pdf = "web2pdf:main" | ||
|
||
[tool.setuptools_scm] | ||
# can be empty if no extra settings are needed, presence enables setuptools_scm | ||
version_file = "web2pdf/_version.py" | ||
|
||
[tool.isort] | ||
profile = "black" | ||
|
||
[tool.mypy] | ||
ignore_missing_imports = "True" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
"""Web2PDF bot.""" | ||
|
||
from .hooks import cli | ||
|
||
|
||
def main() -> None: | ||
"""Run the application.""" | ||
try: | ||
cli.start() | ||
except KeyboardInterrupt: | ||
pass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
"""Support for package execution.""" | ||
|
||
from . import main | ||
|
||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
"""Event Hooks""" | ||
|
||
import re | ||
from argparse import Namespace | ||
from tempfile import NamedTemporaryFile | ||
|
||
import pdfkit | ||
from deltabot_cli import BotCli | ||
from deltachat2 import Bot, ChatType, CoreEvent, EventType, MsgData, NewMsgEvent, events | ||
from rich.logging import RichHandler | ||
|
||
from ._version import __version__ | ||
|
||
cli = BotCli("web2pdf") | ||
cli.add_generic_option("-v", "--version", action="version", version=__version__) | ||
cli.add_generic_option( | ||
"--no-time", | ||
help="do not display date timestamp in log messages", | ||
action="store_false", | ||
) | ||
|
||
|
||
@cli.on_init | ||
def _on_init(bot: Bot, args: Namespace) -> None: | ||
bot.logger.handlers = [ | ||
RichHandler(show_path=False, omit_repeated_times=False, show_time=args.no_time) | ||
] | ||
for accid in bot.rpc.get_all_account_ids(): | ||
if not bot.rpc.get_config(accid, "displayname"): | ||
bot.rpc.set_config(accid, "displayname", "Web to PDF") | ||
status = "I am a Delta Chat bot, send me /help for more info" | ||
bot.rpc.set_config(accid, "selfstatus", status) | ||
bot.rpc.set_config(accid, "delete_device_after", str(60 * 60 * 24)) | ||
|
||
|
||
@cli.on(events.RawEvent) | ||
def _log_event(bot: Bot, accid: int, event: CoreEvent) -> None: | ||
if event.kind == EventType.INFO: | ||
bot.logger.debug(event.msg) | ||
elif event.kind == EventType.WARNING: | ||
bot.logger.warning(event.msg) | ||
elif event.kind == EventType.ERROR: | ||
bot.logger.error(event.msg) | ||
elif event.kind == EventType.MSG_DELIVERED: | ||
bot.rpc.delete_messages(accid, [event.msg_id]) | ||
elif event.kind == EventType.SECUREJOIN_INVITER_PROGRESS: | ||
if event.progress == 1000: | ||
if not bot.rpc.get_contact(accid, event.contact_id).is_bot: | ||
bot.logger.debug("QR scanned by contact id=%s", event.contact_id) | ||
chatid = bot.rpc.create_chat_by_contact_id(accid, event.contact_id) | ||
_send_help(bot, accid, chatid) | ||
|
||
|
||
@cli.after(events.NewMessage) | ||
def delete_msgs(bot: Bot, accid: int, event: NewMsgEvent) -> None: | ||
"""Delete messages after processing""" | ||
msg = event.msg | ||
bot.rpc.delete_messages(accid, [msg.id]) | ||
bot.logger.debug(f"[chat={msg.chat_id}] Deleted message={msg.id}") | ||
|
||
|
||
@cli.on(events.NewMessage(is_info=False)) | ||
def _web2pdf_filter(bot: Bot, accid: int, event: NewMsgEvent) -> None: | ||
if bot.has_command(event.command): | ||
return | ||
msg = event.msg | ||
chat = bot.rpc.get_basic_chat_info(accid, msg.chat_id) | ||
match = re.search( | ||
r"http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*(),]|" | ||
r"(?:%[0-9a-fA-F][0-9a-fA-F]))+", | ||
msg.text, | ||
) | ||
if match: | ||
url = match.group() | ||
elif msg.text and chat.chat_type == ChatType.SINGLE: | ||
url = msg.text | ||
else: | ||
return | ||
with NamedTemporaryFile(suffix=".pdf") as file: | ||
try: | ||
pdfkit.from_url(url, file.name) | ||
reply = MsgData(file=file.name, quoted_message_id=msg.id) | ||
bot.rpc.send_msg(accid, msg.chat_id, reply) | ||
except Exception as ex: # noqa: W0718 | ||
bot.logger.exception(ex) | ||
text = "Failed to retrieve web site, is the URL correct?" | ||
reply = MsgData(text=text, quoted_message_id=msg.id) | ||
bot.rpc.send_msg(accid, msg.chat_id, reply) | ||
|
||
|
||
@cli.on(events.NewMessage(command="/help")) | ||
def _help(bot: Bot, accid: int, event: NewMsgEvent) -> None: | ||
_send_help(bot, accid, event.msg.chat_id) | ||
|
||
|
||
def _send_help(bot: Bot, accid: int, chatid: int) -> None: | ||
text = ( | ||
"I'm a bot, I allow to retrieve HTML pages as PDF." | ||
" Just send me any link to a website you would like to save as PDF." | ||
) | ||
bot.rpc.send_msg(accid, chatid, MsgData(text=text)) |