cli2telegram 2.0.0__tar.gz → 2.0.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,23 +1,29 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: cli2telegram
3
- Version: 2.0.0
3
+ Version: 2.0.2
4
4
  Summary: Small utility to send Telegram messages from the CLI.
5
- Home-page: https://github.com/markusressel/cli2telegram
5
+ License: AGPL-3.0-or-later
6
+ License-File: LICENSE
7
+ Keywords: cli,telegram,notification
6
8
  Author: Markus Ressel
7
9
  Author-email: mail@markusressel.de
8
- License: AGPLv3+
9
- Platform: UNKNOWN
10
+ Requires-Python: >=3.12,<4.0
10
11
  Classifier: Development Status :: 5 - Production/Stable
11
12
  Classifier: License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)
12
- Classifier: Programming Language :: Python :: 3 :: Only
13
13
  Classifier: Programming Language :: Python :: 3
14
- Classifier: Programming Language :: Python :: 3.6
15
- Classifier: Programming Language :: Python :: 3.7
16
- Classifier: Programming Language :: Python :: 3.8
17
- Classifier: Programming Language :: Python :: 3.9
18
- Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
16
+ Classifier: Programming Language :: Python :: 3.14
17
+ Classifier: Programming Language :: Python :: 3.15
18
+ Classifier: Programming Language :: Python :: 3 :: Only
19
+ Requires-Dist: aiofiles
20
+ Requires-Dist: click
21
+ Requires-Dist: container-app-conf
22
+ Requires-Dist: emoji
23
+ Requires-Dist: python-telegram-bot
24
+ Project-URL: Homepage, https://github.com/markusressel/cli2telegram
25
+ Project-URL: Repository, https://github.com/markusressel/cli2telegram
19
26
  Description-Content-Type: text/markdown
20
- License-File: LICENSE
21
27
 
22
28
  # cli2telegram
23
29
  Small utility to send Telegram messages from the CLI.
@@ -167,4 +173,3 @@ You should have received a copy of the GNU Affero General Public License
167
173
  along with this program. If not, see <https://www.gnu.org/licenses/>.
168
174
  ```
169
175
 
170
-
@@ -13,17 +13,19 @@
13
13
  #
14
14
  # You should have received a copy of the GNU Affero General Public License
15
15
  # along with this program. If not, see <https://www.gnu.org/licenses/>.
16
-
16
+ import asyncio
17
17
  import logging
18
18
  import sys
19
19
  from typing import Tuple, List
20
20
 
21
21
  import click
22
+ from telegram.ext import Application
22
23
 
24
+ from cli2telegram import util
23
25
  from cli2telegram.config import Config
24
26
  from cli2telegram.const import CODEBLOCK_MARKER_END, CODEBLOCK_MARKER_START, TELEGRAM_MESSAGE_LENGTH_LIMIT
25
27
  from cli2telegram.daemon import Daemon
26
- from cli2telegram.util import split_message, prepare_code_message, _try_send_message
28
+ from cli2telegram.util import split_message, prepare_code_message
27
29
 
28
30
  LOGGER = logging.getLogger(__name__)
29
31
  # LOGGER.setLevel(logging.DEBUG)
@@ -86,15 +88,9 @@ def cli(bot_token: str or None, chat_id: str or None, code_block: bool, lines: T
86
88
  text = "".join(lines)
87
89
  messages = prepare_messages(text, code_block)
88
90
 
89
- for message in messages:
90
- _try_send_message(
91
- bot_token=CONFIG.TELEGRAM_BOT_TOKEN.value,
92
- chat_id=CONFIG.TELEGRAM_CHAT_ID.value,
93
- message=message,
94
- retry=CONFIG.RETRY_ENABLED.value,
95
- retry_timeout=CONFIG.RETRY_TIMEOUT.value,
96
- give_up_after=CONFIG.RETRY_GIVE_UP_AFTER.value
97
- )
91
+ app = Application.builder().token(CONFIG.TELEGRAM_BOT_TOKEN.value).build()
92
+
93
+ asyncio.run(_send_messages(app, messages))
98
94
 
99
95
 
100
96
  def prepare_messages(text: str, code_block: bool) -> List[str]:
@@ -114,5 +110,17 @@ def prepare_messages(text: str, code_block: bool) -> List[str]:
114
110
  return result
115
111
 
116
112
 
113
+ async def _send_messages(app, messages):
114
+ for message in messages:
115
+ await util.try_send_message(
116
+ app=app,
117
+ chat_id=CONFIG.TELEGRAM_CHAT_ID.value,
118
+ message=message,
119
+ retry=CONFIG.RETRY_ENABLED.value,
120
+ retry_timeout=CONFIG.RETRY_TIMEOUT.value,
121
+ give_up_after=CONFIG.RETRY_GIVE_UP_AFTER.value
122
+ )
123
+
124
+
117
125
  if __name__ == '__main__':
118
126
  cli()
@@ -13,20 +13,19 @@
13
13
  #
14
14
  # You should have received a copy of the GNU Affero General Public License
15
15
  # along with this program. If not, see <https://www.gnu.org/licenses/>.
16
-
16
+ import asyncio
17
17
  import logging
18
18
  import os
19
- import queue
20
19
  import sys
21
- import threading
22
20
  from signal import signal, SIGINT, SIGTERM
23
21
  from time import time, sleep
24
22
 
25
- from telegram.ext import Updater
23
+ import aiofiles
24
+ from telegram.ext import ApplicationBuilder
26
25
 
27
26
  from cli2telegram import RetryLimitReachedException
28
27
  from cli2telegram.config import Config
29
- from cli2telegram.util import _try_send_message, prepare_code_message
28
+ from cli2telegram.util import try_send_message, prepare_code_message
30
29
 
31
30
  LOGGER = logging.getLogger(__name__)
32
31
  HANDLER = logging.StreamHandler(sys.stdout)
@@ -40,8 +39,8 @@ class Daemon:
40
39
  self.config = config
41
40
  self.running = True
42
41
  self.pipe_file_path = config.DAEMON_PIPE_PATH.value
43
- self.message_queue = queue.Queue()
44
- self.updater = Updater(token=config.TELEGRAM_BOT_TOKEN.value, use_context=True)
42
+ self.message_queue = asyncio.Queue()
43
+ self._app = ApplicationBuilder().token(config.TELEGRAM_BOT_TOKEN.value).build()
45
44
 
46
45
  def run(self):
47
46
  if os.path.exists(self.pipe_file_path):
@@ -55,22 +54,27 @@ class Daemon:
55
54
  signal(SIGINT, self.signal_handler) # ctrl+c
56
55
  signal(SIGTERM, self.signal_handler) # systemctl stop
57
56
 
58
- threading.Thread(target=self.send_message_worker, daemon=True).start()
57
+ asyncio.run(self._run_workers())
59
58
 
60
- LOGGER.info(f"Daemon is listening for input on {self.pipe_file_path}...")
61
- self.read_pipe_loop(self.pipe_file_path)
59
+ async def _run_workers(self):
60
+ await asyncio.gather(
61
+ self.send_message_worker(),
62
+ self.read_pipe_loop(),
63
+ )
62
64
 
63
- def read_pipe_loop(self, path: str):
65
+ async def read_pipe_loop(self):
66
+ LOGGER.info(f"Daemon is listening for input on {self.pipe_file_path}...")
64
67
  while True:
65
68
  LOGGER.debug("Waiting for new input on pipe")
66
- with open(path) as pipe:
69
+
70
+ async with aiofiles.open(self.pipe_file_path, 'r') as pipe:
67
71
  pipe_buffer = ''
68
72
  while True:
69
- data = pipe.read()
73
+ data = await pipe.read()
70
74
  LOGGER.debug(f"received: {data}")
71
75
  if len(data) == 0 and self.running:
72
76
  LOGGER.debug("No new data from pipe, adding current buffer to message queue")
73
- self.message_queue.put(pipe_buffer)
77
+ await self.message_queue.put(pipe_buffer)
74
78
  break
75
79
  elif not self.running:
76
80
  break
@@ -80,21 +84,23 @@ class Daemon:
80
84
  if not self.running:
81
85
  break
82
86
 
83
- def send_message_worker(self):
87
+ async def send_message_worker(self):
84
88
  while True:
85
- message = self.message_queue.get()
89
+ LOGGER.debug("Waiting for item in message queue...")
90
+ message = await self.message_queue.get()
91
+ LOGGER.debug(f"Got new message: {message}")
86
92
 
87
93
  if not message.strip():
88
94
  LOGGER.warning("Message is empty, ignoring")
89
95
  self.message_queue.task_done()
90
96
  continue
91
97
 
92
- prepared_message = prepare_code_message(message.splitlines())
98
+ prepared_message = prepare_code_message(message)
93
99
  LOGGER.debug(f"Trying to send message from queue...")
94
100
 
95
101
  try:
96
- _try_send_message(
97
- bot_token=self.config.TELEGRAM_BOT_TOKEN.value,
102
+ await try_send_message(
103
+ app=self._app,
98
104
  chat_id=self.config.TELEGRAM_CHAT_ID.value,
99
105
  message=prepared_message,
100
106
  retry=self.config.RETRY_ENABLED.value,
@@ -120,7 +126,8 @@ class Daemon:
120
126
  LOGGER.warning("Unable to clean up named pipe")
121
127
 
122
128
  stop = time() + 5
123
- while self.message_queue.unfinished_tasks and time() < stop:
129
+
130
+ while self.message_queue._unfinished_tasks and time() < stop:
124
131
  sleep(1)
125
132
 
126
133
  sys.exit(0)
@@ -18,7 +18,7 @@ import time
18
18
  from datetime import datetime, timedelta
19
19
 
20
20
  from telegram import Bot, InlineKeyboardMarkup, Message
21
- from telegram.ext import Updater
21
+ from telegram.ext import Application
22
22
 
23
23
  from cli2telegram import RetryLimitReachedException
24
24
  from cli2telegram.const import CODEBLOCK_MARKER_START, CODEBLOCK_MARKER_END
@@ -26,7 +26,7 @@ from cli2telegram.const import CODEBLOCK_MARKER_START, CODEBLOCK_MARKER_END
26
26
  LOGGER = logging.getLogger(__name__)
27
27
 
28
28
 
29
- def send_message(
29
+ async def send_message(
30
30
  bot: Bot, chat_id: str, message: str, parse_mode: str = None, reply_to: int = None,
31
31
  menu: InlineKeyboardMarkup = None
32
32
  ) -> Message:
@@ -40,10 +40,10 @@ def send_message(
40
40
  :param menu: inline keyboard menu markup
41
41
  """
42
42
  from emoji import emojize
43
- emojized_text = emojize(message, use_aliases=True)
44
- return bot.send_message(
43
+ emojized_text = emojize(message, language='alias')
44
+ return await bot.send_message(
45
45
  chat_id=chat_id, parse_mode=parse_mode, text=emojized_text, reply_to_message_id=reply_to, reply_markup=menu,
46
- timeout=10
46
+ connect_timeout=10, read_timeout=10, write_timeout=10
47
47
  )
48
48
 
49
49
 
@@ -73,14 +73,14 @@ def prepare_code_message(message: str) -> str:
73
73
  return result
74
74
 
75
75
 
76
- def _try_send_message(
77
- bot_token: str,
76
+ async def try_send_message(
77
+ app: Application,
78
78
  chat_id: str, message: str,
79
79
  retry: bool, retry_timeout: timedelta, give_up_after: timedelta
80
80
  ):
81
81
  """
82
82
  Sends a message
83
- :param bot_token: telegram bot token
83
+ :param app: telegram application
84
84
  :param chat_id: chat id
85
85
  :param message: the message to send
86
86
  :param retry: whether to retry if something fails
@@ -91,8 +91,7 @@ def _try_send_message(
91
91
  success = False
92
92
  while not success:
93
93
  try:
94
- updater = Updater(token=bot_token, use_context=True)
95
- send_message(bot=updater.bot, chat_id=chat_id, message=message, parse_mode="markdown")
94
+ await send_message(bot=app.bot, chat_id=chat_id, message=message, parse_mode="markdown")
96
95
  success = True
97
96
  except Exception as ex:
98
97
  LOGGER.exception(ex)
@@ -0,0 +1,51 @@
1
+ [tool.poetry]
2
+ name = "cli2telegram"
3
+ version = "2.0.2"
4
+ description = "Small utility to send Telegram messages from the CLI."
5
+
6
+ license = "AGPL-3.0-or-later"
7
+
8
+ authors = [
9
+ "Markus Ressel <mail@markusressel.de>",
10
+ ]
11
+
12
+ readme = 'README.md'
13
+
14
+ repository = "https://github.com/markusressel/cli2telegram"
15
+ homepage = "https://github.com/markusressel/cli2telegram"
16
+
17
+ keywords = ['cli', 'telegram', 'notification']
18
+
19
+ classifiers = [
20
+ "License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)",
21
+ "Programming Language :: Python :: 3 :: Only",
22
+ "Programming Language :: Python :: 3",
23
+ "Programming Language :: Python :: 3.12",
24
+ "Programming Language :: Python :: 3.13",
25
+ "Programming Language :: Python :: 3.14",
26
+ "Development Status :: 5 - Production/Stable"
27
+ ]
28
+
29
+ [build-system]
30
+ requires = ["poetry-core>=1.0.0"]
31
+ build-backend = "poetry.core.masonry.api"
32
+
33
+ [tool.poetry.dependencies]
34
+ python = "^3.12" # Compatible python versions must be declared here
35
+
36
+ container-app-conf = "*"
37
+ click = "*"
38
+ emoji = "*"
39
+ python-telegram-bot = "*"
40
+ aiofiles = "*"
41
+
42
+ [tool.poetry.dev-dependencies]
43
+ pytest = "*"
44
+
45
+ [tool.pytest.ini_options]
46
+ testpaths = [
47
+ "tests",
48
+ ]
49
+
50
+ [tool.poetry.scripts]
51
+ cli2telegram = 'cli2telegram.cli:cli'
@@ -1,170 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: cli2telegram
3
- Version: 2.0.0
4
- Summary: Small utility to send Telegram messages from the CLI.
5
- Home-page: https://github.com/markusressel/cli2telegram
6
- Author: Markus Ressel
7
- Author-email: mail@markusressel.de
8
- License: AGPLv3+
9
- Platform: UNKNOWN
10
- Classifier: Development Status :: 5 - Production/Stable
11
- Classifier: License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)
12
- Classifier: Programming Language :: Python :: 3 :: Only
13
- Classifier: Programming Language :: Python :: 3
14
- Classifier: Programming Language :: Python :: 3.6
15
- Classifier: Programming Language :: Python :: 3.7
16
- Classifier: Programming Language :: Python :: 3.8
17
- Classifier: Programming Language :: Python :: 3.9
18
- Classifier: Programming Language :: Python :: 3.10
19
- Description-Content-Type: text/markdown
20
- License-File: LICENSE
21
-
22
- # cli2telegram
23
- Small utility to send Telegram messages from the CLI.
24
-
25
- This can f.ex. be used to
26
- * quickly send arbitrary messages to a Telegram chat of your choice
27
- * use it as a replacement for the "mail" program on linux
28
- * use Telegram as a notification backend for the ZFS Event Daemon (zed)
29
-
30
- ## Features
31
- * [x] Read messages from argument or STDIN
32
- * [x] (Optional) Configuration file
33
- * [x] Retry sending messages for a specified amount of time
34
- * [x] Handling of long messages
35
- * [x] Run as a daemon and echo messages into a linux pipe
36
-
37
- ## Examples
38
-
39
- ```shell
40
- cli2telegram -h
41
-
42
- # From arguments
43
- cli2telegram "This is a message"
44
-
45
- cli2telegram "Header" "This is a multiline message."
46
-
47
- # From STDIN
48
- echo My Message | cli2telegram
49
-
50
- printf "Header\nThis is a multiline message." | cli2telegram
51
-
52
- # Config via parameters
53
- printf "Message" | cli2telegram -b "123456789:ABCDEFG" -c "123456789"
54
-
55
- # Config via parameters and send message in a code block
56
- printf "Message" | cli2telegram -b "123456789:ABCDEFG" -c "123456789" -C
57
-
58
- # as a Daemon
59
- cli2telegram -d -p "/tmp/cli2telegram"
60
- echo "hello world!" > /tmp/cli2telegram
61
- ```
62
-
63
- # Install
64
-
65
- To use this utility install it either using:
66
- ```
67
- pip install cli2telegram
68
- ```
69
-
70
- or - if you don't want to install it globally - using f.ex. [venv-install](https://github.com/markusressel/venv-install):
71
- ```
72
- venv-install cli2telegram cli2telegram
73
- ```
74
-
75
- or your custom `venv` manager of choice.
76
-
77
- # Configuration
78
-
79
- To be able to send you messages you have to provide a **bot token** and a **chat id**.
80
- You can configure cli2telegram using cli parameters, a configuration file,
81
- environment variables, or a combination of them.
82
-
83
- ## Parameters
84
-
85
- | Name | Type | Description |
86
- |----------------------|--------|-------------------------------------------|
87
- | `-b`, `--bot-token` | String | Telegram Bot Token |
88
- | `-c`, `--chat-id` | String | Telegram Chat ID |
89
- | `-C`, `--code-block` | String | Send message inside a code block |
90
- | `-d`, `--daemon` | Flag | Run as a daemon |
91
- | `-p`, `--pipe` | String | File path to the pipe used in daemon mode |
92
-
93
- ## File
94
- cli2telegram uses [container-app-conf](https://github.com/markusressel/container-app-conf) so you can use YAML, TOML, or ENV to set those.
95
-
96
- Have a look at the [cli2telegram.toml_example](cli2telegram.toml_example) file to get an idea.
97
-
98
- # Daemon
99
-
100
- When running cli2telegram as a daemon, the pipe will close for a brief amount of time between receiving input messages.
101
- If you are sending multiple messages to the pipe using f.ex. a script, make sure to wait a bit (f.ex. 0.5 seconds)
102
- between sending messages, otherwise:
103
- * multiple messages may be received as one
104
- * messages may get lost
105
- * you may receive a `Broken pipe` error
106
-
107
- # Use Cases
108
-
109
- ## ZFS Event Daemon (ZED)
110
- To make `zed` call cli2telegram we will trick it and make it use cli2telegram as an E-Mail client.
111
-
112
- Edit `/etc/zfs/zed.d/zed.rc` as root:
113
- ```bash
114
- sudo nano -w /etc/zfs/zed.d/zed.rc
115
- ```
116
-
117
- and
118
- * uncomment `ZED_EMAIL_ADDR`, the value does not matter since we use our own email script, but **it is necessary to set a value to make ZED send 'emails'**
119
- * set `ZED_EMAIL_PROG` to the path of the script, f.ex. `/usr/bin/cli2telegram`
120
- * it is important to note that zed does not seem to work if your command needs arguments to run
121
- ```
122
- # this must not be empty!
123
- ZED_EMAIL_ADDR="root"
124
-
125
- [...]
126
-
127
- ZED_EMAIL_PROG="/usr/bin/cli2telegram"
128
-
129
- [...]
130
-
131
- # this must not be empty!
132
- ZED_EMAIL_OPTS="#zfs #$(hostname)"
133
-
134
- [...]
135
-
136
- # If you want to receive email no matter the state of your pool, you’ll want to set:
137
- ZED_NOTIFY_VERBOSE=1
138
-
139
- [...]
140
- ```
141
-
142
- Since `zed` will run your scripts as root, if you want to use a config file
143
- you have to put it in f.ex. `/root/.config/cli2telegram.toml`.
144
-
145
- # Contributing
146
-
147
- GitHub is for social coding: if you want to write code, I encourage contributions through pull requests from forks
148
- of this repository. Create GitHub tickets for bugs and new features and comment on the ones that you are interested in.
149
-
150
- # License
151
-
152
- ```text
153
- cli2telegram by Markus Ressel
154
- Copyright (C) 2018 Markus Ressel
155
-
156
- This program is free software: you can redistribute it and/or modify
157
- it under the terms of the GNU Affero General Public License as
158
- published by the Free Software Foundation, either version 3 of the
159
- License, or (at your option) any later version.
160
-
161
- This program is distributed in the hope that it will be useful,
162
- but WITHOUT ANY WARRANTY; without even the implied warranty of
163
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
164
- GNU Affero General Public License for more details.
165
-
166
- You should have received a copy of the GNU Affero General Public License
167
- along with this program. If not, see <https://www.gnu.org/licenses/>.
168
- ```
169
-
170
-
@@ -1,17 +0,0 @@
1
- LICENSE
2
- README.md
3
- setup.py
4
- cli2telegram/__init__.py
5
- cli2telegram/cli.py
6
- cli2telegram/config.py
7
- cli2telegram/const.py
8
- cli2telegram/daemon.py
9
- cli2telegram/util.py
10
- cli2telegram.egg-info/PKG-INFO
11
- cli2telegram.egg-info/SOURCES.txt
12
- cli2telegram.egg-info/dependency_links.txt
13
- cli2telegram.egg-info/entry_points.txt
14
- cli2telegram.egg-info/requires.txt
15
- cli2telegram.egg-info/top_level.txt
16
- tests/__init__.py
17
- tests/test_message_processing.py
@@ -1,3 +0,0 @@
1
- [console_scripts]
2
- cli2telegram = cli2telegram.cli:cli
3
-
@@ -1,4 +0,0 @@
1
- container-app-conf==5.2.2
2
- click
3
- emoji
4
- python-telegram-bot>=13.10.0
@@ -1,2 +0,0 @@
1
- cli2telegram
2
- tests
@@ -1,4 +0,0 @@
1
- [egg_info]
2
- tag_build =
3
- tag_date = 0
4
-
@@ -1,89 +0,0 @@
1
- # Copyright (c) 2019 Markus Ressel
2
- #
3
- # Permission is hereby granted, free of charge, to any person obtaining a copy
4
- # of this software and associated documentation files (the "Software"), to deal
5
- # in the Software without restriction, including without limitation the rights
6
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
- # copies of the Software, and to permit persons to whom the Software is
8
- # furnished to do so, subject to the following conditions:
9
- #
10
- # The above copyright notice and this permission notice shall be included in all
11
- # copies or substantial portions of the Software.
12
- #
13
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
- # SOFTWARE.
20
- #
21
-
22
- from setuptools import setup, find_packages
23
-
24
- VERSION_NUMBER = "2.0.0"
25
-
26
- DEVELOPMENT_STATUS = "Development Status :: 5 - Production/Stable"
27
- VERSION_NAME = VERSION_NUMBER
28
-
29
-
30
- def readme_type() -> str:
31
- import os
32
- if os.path.exists("README.rst"):
33
- return "text/x-rst"
34
- if os.path.exists("README.md"):
35
- return "text/markdown"
36
-
37
-
38
- def readme() -> [str]:
39
- if readme_type() == "text/markdown":
40
- file_name = "README.md"
41
- else:
42
- file_name = "README.rst"
43
-
44
- with open(file_name) as f:
45
- return f.read()
46
-
47
-
48
- def install_requirements() -> [str]:
49
- return read_requirements_file("requirements.txt")
50
-
51
-
52
- def test_requirements() -> [str]:
53
- return read_requirements_file("test_requirements.txt")
54
-
55
-
56
- def read_requirements_file(file_name: str):
57
- with open(file_name, encoding='utf-8') as f:
58
- requirements_file = f.readlines()
59
- return [r.strip() for r in requirements_file]
60
-
61
-
62
- setup(
63
- name='cli2telegram',
64
- version=VERSION_NAME,
65
- description='Small utility to send Telegram messages from the CLI.',
66
- long_description=readme(),
67
- long_description_content_type=readme_type(),
68
- license='AGPLv3+',
69
- author='Markus Ressel',
70
- author_email='mail@markusressel.de',
71
- url='https://github.com/markusressel/cli2telegram',
72
- packages=find_packages(),
73
- classifiers=[
74
- DEVELOPMENT_STATUS,
75
- 'License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)',
76
- 'Programming Language :: Python :: 3 :: Only',
77
- 'Programming Language :: Python :: 3',
78
- 'Programming Language :: Python :: 3.6',
79
- 'Programming Language :: Python :: 3.7',
80
- 'Programming Language :: Python :: 3.8',
81
- 'Programming Language :: Python :: 3.9',
82
- 'Programming Language :: Python :: 3.10',
83
- ],
84
- install_requires=install_requirements(),
85
- tests_require=test_requirements(),
86
- entry_points={
87
- 'console_scripts': ['cli2telegram = cli2telegram.cli:cli']
88
- }
89
- )
@@ -1,22 +0,0 @@
1
- # cli2telegram
2
- # Copyright (c) 2019. Markus Ressel
3
- #
4
- # This program is free software: you can redistribute it and/or modify
5
- # it under the terms of the GNU Affero General Public License as
6
- # published by the Free Software Foundation, either version 3 of the
7
- # License, or (at your option) any later version.
8
- #
9
- # This program is distributed in the hope that it will be useful,
10
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
- # GNU Affero General Public License for more details.
13
- #
14
- # You should have received a copy of the GNU Affero General Public License
15
- # along with this program. If not, see <https://www.gnu.org/licenses/>.
16
-
17
- import unittest
18
-
19
-
20
- class TestBase(unittest.TestCase):
21
- if __name__ == '__main__':
22
- unittest.main()
@@ -1,97 +0,0 @@
1
- # cli2telegram
2
- # Copyright (c) 2019. Markus Ressel
3
- #
4
- # This program is free software: you can redistribute it and/or modify
5
- # it under the terms of the GNU Affero General Public License as
6
- # published by the Free Software Foundation, either version 3 of the
7
- # License, or (at your option) any later version.
8
- #
9
- # This program is distributed in the hope that it will be useful,
10
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
- # GNU Affero General Public License for more details.
13
- #
14
- # You should have received a copy of the GNU Affero General Public License
15
- # along with this program. If not, see <https://www.gnu.org/licenses/>.
16
- from cli2telegram.cli import prepare_messages
17
- from cli2telegram.util import prepare_code_message, split_message
18
- from tests import TestBase
19
-
20
-
21
- class MessageProcessingTest(TestBase):
22
-
23
- def test_long_message_with_codeblock_doesnt_exceed_limit(self):
24
- std_in = "A" * 4096 + "B" * 4096
25
- messages = prepare_messages(std_in, True)
26
-
27
- assert len(messages) == 3
28
- for m in messages:
29
- assert len(m) <= 4096
30
- assert "B" not in messages[0]
31
- assert "A" in messages[1]
32
- assert "B" in messages[1]
33
- assert "A" not in messages[2]
34
-
35
- def test_long_message_doesnt_exceed_limit(self):
36
- std_in = "A" * 4096 + "B" * 4096
37
- messages = prepare_messages(std_in, False)
38
-
39
- assert len(messages) == 2
40
- for i, m in enumerate(messages):
41
- if i < len(messages) - 1:
42
- assert len(m) == 4096
43
- else:
44
- assert len(m) <= 4096
45
- assert "B" not in messages[0]
46
- assert "A" not in messages[1]
47
-
48
- def test_long_message_is_split(self):
49
- length = 32
50
- std_in = "A" * length + "B" * length
51
- messages = split_message(std_in, length)
52
-
53
- assert len(messages) == 2
54
- for i, m in enumerate(messages):
55
- if i < len(messages) - 1:
56
- assert len(m) == length
57
- else:
58
- assert len(m) <= length
59
- assert "B" not in messages[0]
60
- assert "A" not in messages[1]
61
-
62
- def test_prepare_code_message(self):
63
- message = "Code"
64
- output = prepare_code_message(message)
65
-
66
- assert output.startswith("```\n")
67
- assert output.endswith("\n```")
68
- assert message[0] in output
69
-
70
- def test_newlines_are_retained_in_code_block(self):
71
- std_in = "\nCo\nde\n"
72
- output = prepare_code_message(std_in)
73
-
74
- assert output == "```\n\nCo\nde\n\n```"
75
-
76
- def test_message_preparation(self):
77
- std_in = """ZFS has finished a scrub:\n
78
- \n
79
- eid: 3337\n
80
- class: scrub_finish\n
81
- host: \n
82
- time: 2019-12-01 19:36:01+0100\n
83
- pool: rpool\n
84
- state: ONLINE\n
85
- scan: scrub repaired 0B in 0 days 00:00:24 with 0 errors on Sun Dec 1 19:36:01 2019\n
86
- config:\n
87
- \n
88
- \tNAME STATE READ WRITE CKSUM\n
89
- \trpool ONLINE 0 0 0\n
90
- \t mirror-0 ONLINE 0 0 0\n
91
- \t ata-Samsung_SSD_860_EVO_500GB_S4XBNF1M807031E-part2 ONLINE 0 0 0\n
92
- \t ata-Samsung_SSD_860_EVO_500GB_S4XBNF1M807033B-part2 ONLINE 0 0 0\n
93
- \n
94
- errors: No known data errors\n"""
95
-
96
- output = prepare_code_message(std_in)
97
- assert output
File without changes
File without changes