reposter 24.2.0__tar.gz → 24.3.0__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.
- {reposter-24.2.0 → reposter-24.3.0}/PKG-INFO +3 -2
- {reposter-24.2.0 → reposter-24.3.0}/pyproject.toml +1 -1
- {reposter-24.2.0 → reposter-24.3.0}/readme.md +2 -1
- {reposter-24.2.0 → reposter-24.3.0}/reposter/core/config.py +9 -2
- {reposter-24.2.0 → reposter-24.3.0}/reposter/core/types.py +14 -0
- {reposter-24.2.0 → reposter-24.3.0}/reposter/db/models.py +1 -0
- {reposter-24.2.0 → reposter-24.3.0}/reposter/funcs/other.py +15 -0
- {reposter-24.2.0 → reposter-24.3.0}/reposter/funcs/parse_conf.py +13 -0
- {reposter-24.2.0 → reposter-24.3.0}/reposter/handlers/edit.py +17 -6
- reposter-24.3.0/reposter/handlers/forward_unrestricted.py +87 -0
- {reposter-24.2.0 → reposter-24.3.0}/reposter/handlers/on_msg.py +25 -7
- reposter-24.3.0/reposter/handlers/resend_restricted.py +154 -0
- {reposter-24.2.0 → reposter-24.3.0}/reposter/handlers/service.py +1 -1
- {reposter-24.2.0 → reposter-24.3.0}/reposter.egg-info/PKG-INFO +3 -2
- reposter-24.2.0/reposter/handlers/forward_unrestricted.py +0 -51
- reposter-24.2.0/reposter/handlers/resend_restricted.py +0 -68
- {reposter-24.2.0 → reposter-24.3.0}/reposter/__main__.py +0 -0
- {reposter-24.2.0 → reposter-24.3.0}/reposter/autotests/msgs.py +0 -0
- {reposter-24.2.0 → reposter-24.3.0}/reposter/autotests/pyright.py +0 -0
- {reposter-24.2.0 → reposter-24.3.0}/reposter/autotests/restricted.py +0 -0
- {reposter-24.2.0 → reposter-24.3.0}/reposter/autotests/ruff.py +0 -0
- {reposter-24.2.0 → reposter-24.3.0}/reposter/autotests/run.py +0 -0
- {reposter-24.2.0 → reposter-24.3.0}/reposter/autotests/timer.py +0 -0
- {reposter-24.2.0 → reposter-24.3.0}/reposter/autotests/unrestricted.py +0 -0
- {reposter-24.2.0 → reposter-24.3.0}/reposter/core/common.py +0 -0
- {reposter-24.2.0 → reposter-24.3.0}/reposter/db/init.py +0 -0
- {reposter-24.2.0 → reposter-24.3.0}/reposter/funcs/handle.py +0 -0
- {reposter-24.2.0 → reposter-24.3.0}/reposter/funcs/logging.py +0 -0
- {reposter-24.2.0 → reposter-24.3.0}/reposter/funcs/status.py +0 -0
- {reposter-24.2.0 → reposter-24.3.0}/reposter/funcs/suppress.py +0 -0
- {reposter-24.2.0 → reposter-24.3.0}/reposter/handlers/other.py +0 -0
- {reposter-24.2.0 → reposter-24.3.0}/reposter/handlers/set.py +0 -0
- {reposter-24.2.0 → reposter-24.3.0}/reposter/handlers/stream_notify.py +0 -0
- {reposter-24.2.0 → reposter-24.3.0}/reposter/tg/chunk_gen.py +0 -0
- {reposter-24.2.0 → reposter-24.3.0}/reposter/tg/history.py +0 -0
- {reposter-24.2.0 → reposter-24.3.0}/reposter/tg/restricted.py +0 -0
- {reposter-24.2.0 → reposter-24.3.0}/reposter/tg/save_file.py +0 -0
- {reposter-24.2.0 → reposter-24.3.0}/reposter.egg-info/SOURCES.txt +0 -0
- {reposter-24.2.0 → reposter-24.3.0}/reposter.egg-info/dependency_links.txt +0 -0
- {reposter-24.2.0 → reposter-24.3.0}/reposter.egg-info/entry_points.txt +0 -0
- {reposter-24.2.0 → reposter-24.3.0}/reposter.egg-info/requires.txt +0 -0
- {reposter-24.2.0 → reposter-24.3.0}/reposter.egg-info/top_level.txt +0 -0
- {reposter-24.2.0 → reposter-24.3.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: reposter
|
|
3
|
-
Version: 24.
|
|
3
|
+
Version: 24.3.0
|
|
4
4
|
Summary: python script for reposting telegram messages
|
|
5
5
|
Project-URL: repo, https://github.com/gmankab/reposter
|
|
6
6
|
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
@@ -29,7 +29,8 @@ userbot that forwards messages from telegram channels others in real time
|
|
|
29
29
|
- [repo](https://github.com/gmankab/reposter)
|
|
30
30
|
- [how to run](https://github.com/gmankab/reposter/blob/main/other/docs/run.md)
|
|
31
31
|
- [how to build](https://github.com/gmankab/reposter/blob/main/other/docs/build.md)
|
|
32
|
-
- [config
|
|
32
|
+
- [config](https://github.com/gmankab/reposter/blob/main/other/docs/config.md)
|
|
33
|
+
- [env](https://github.com/gmankab/reposter/blob/main/other/docs/env.md)
|
|
33
34
|
- [pypi](https://pypi.org/project/reposter)
|
|
34
35
|
|
|
35
36
|
|
|
@@ -9,7 +9,8 @@ userbot that forwards messages from telegram channels others in real time
|
|
|
9
9
|
- [repo](https://github.com/gmankab/reposter)
|
|
10
10
|
- [how to run](https://github.com/gmankab/reposter/blob/main/other/docs/run.md)
|
|
11
11
|
- [how to build](https://github.com/gmankab/reposter/blob/main/other/docs/build.md)
|
|
12
|
-
- [config
|
|
12
|
+
- [config](https://github.com/gmankab/reposter/blob/main/other/docs/config.md)
|
|
13
|
+
- [env](https://github.com/gmankab/reposter/blob/main/other/docs/env.md)
|
|
13
14
|
- [pypi](https://pypi.org/project/reposter)
|
|
14
15
|
|
|
15
16
|
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import reposter.core.common
|
|
2
|
+
|
|
3
|
+
|
|
1
4
|
class tests:
|
|
2
5
|
source: str = '@autotests_source'
|
|
3
6
|
target: str = '@autotests_target'
|
|
@@ -17,24 +20,28 @@ class env:
|
|
|
17
20
|
|
|
18
21
|
|
|
19
22
|
class json:
|
|
23
|
+
app_version: str
|
|
20
24
|
api_id: int
|
|
21
25
|
api_hash: str
|
|
22
26
|
tg_session: str
|
|
23
27
|
drop_author: bool
|
|
24
28
|
logs_chat: str | int
|
|
25
|
-
online_status_every_seconds: int
|
|
26
29
|
stream_notify_chats: list
|
|
30
|
+
edit_timeout_seconds: int
|
|
31
|
+
online_status_every_seconds: int
|
|
27
32
|
chats: dict
|
|
28
33
|
|
|
29
34
|
|
|
30
35
|
default = {
|
|
36
|
+
'app_version': reposter.core.common.app.version,
|
|
31
37
|
'api_id': 0,
|
|
32
38
|
'api_hash': '',
|
|
33
39
|
'tg_session': '',
|
|
34
40
|
'drop_author': True,
|
|
35
41
|
'logs_chat': 'me',
|
|
36
|
-
'online_status_every_seconds': 0,
|
|
37
42
|
'stream_notify_chats': [],
|
|
43
|
+
'edit_timeout_seconds': 0,
|
|
44
|
+
'online_status_every_seconds': 0,
|
|
38
45
|
'chats': {
|
|
39
46
|
tests.source: tests.target,
|
|
40
47
|
}
|
|
@@ -22,6 +22,20 @@ media_other = typing.Union[
|
|
|
22
22
|
pyrogram.types.Contact,
|
|
23
23
|
pyrogram.types.Sticker,
|
|
24
24
|
]
|
|
25
|
+
in_group_media = typing.Union[
|
|
26
|
+
pyrogram.types.Audio,
|
|
27
|
+
pyrogram.types.Photo,
|
|
28
|
+
pyrogram.types.Video,
|
|
29
|
+
pyrogram.types.Document,
|
|
30
|
+
pyrogram.types.Animation,
|
|
31
|
+
]
|
|
32
|
+
input_media = typing.Union[
|
|
33
|
+
pyrogram.types.InputMediaAudio,
|
|
34
|
+
pyrogram.types.InputMediaPhoto,
|
|
35
|
+
pyrogram.types.InputMediaVideo,
|
|
36
|
+
pyrogram.types.InputMediaDocument,
|
|
37
|
+
pyrogram.types.InputMediaAnimation,
|
|
38
|
+
]
|
|
25
39
|
|
|
26
40
|
|
|
27
41
|
class Progress(rich.progress.Progress):
|
|
@@ -4,6 +4,7 @@ import reposter.core.config
|
|
|
4
4
|
import pyrogram.client
|
|
5
5
|
import reposter.tg.save_file
|
|
6
6
|
import reposter.db.init
|
|
7
|
+
import hashlib
|
|
7
8
|
import types
|
|
8
9
|
import sys
|
|
9
10
|
import io
|
|
@@ -79,3 +80,17 @@ def double_links(
|
|
|
79
80
|
) -> str:
|
|
80
81
|
return f'[blue]{single_link(src_msg)}[/] -> [yellow]{single_link(target_msg)}[/]'
|
|
81
82
|
|
|
83
|
+
|
|
84
|
+
def get_hash(
|
|
85
|
+
msg: pyrogram.types.Message,
|
|
86
|
+
) -> str:
|
|
87
|
+
hash = hashlib.new('sha256')
|
|
88
|
+
if msg.text:
|
|
89
|
+
to_hash = msg.text.markdown.encode()
|
|
90
|
+
elif msg.caption:
|
|
91
|
+
to_hash = msg.caption.markdown.encode()
|
|
92
|
+
else:
|
|
93
|
+
return ''
|
|
94
|
+
hash.update(to_hash)
|
|
95
|
+
return hash.hexdigest()
|
|
96
|
+
|
|
@@ -4,6 +4,15 @@ import json
|
|
|
4
4
|
import os
|
|
5
5
|
|
|
6
6
|
|
|
7
|
+
def compatibility_from_24_2_0_to_24_2_1(
|
|
8
|
+
db_path: Path,
|
|
9
|
+
):
|
|
10
|
+
common.log(
|
|
11
|
+
f'removing {db_path} for compatibility'
|
|
12
|
+
)
|
|
13
|
+
db_path.unlink(missing_ok=True)
|
|
14
|
+
|
|
15
|
+
|
|
7
16
|
def write_config(
|
|
8
17
|
dict_to_write: dict,
|
|
9
18
|
) -> None:
|
|
@@ -25,6 +34,10 @@ def read_config() -> None:
|
|
|
25
34
|
common.path.config_json.read_text()
|
|
26
35
|
)
|
|
27
36
|
assert isinstance(loaded_config, dict)
|
|
37
|
+
if 'app_version' not in loaded_config:
|
|
38
|
+
compatibility_from_24_2_0_to_24_2_1(
|
|
39
|
+
db_path=common.path.db_path,
|
|
40
|
+
)
|
|
28
41
|
for key, value in config.default.items():
|
|
29
42
|
if key not in loaded_config:
|
|
30
43
|
loaded_config[key] = value
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import reposter.funcs.logging
|
|
2
2
|
import reposter.funcs.other
|
|
3
3
|
import reposter.core.common
|
|
4
|
+
import reposter.db.models
|
|
4
5
|
import pyrogram.types
|
|
5
6
|
|
|
6
7
|
|
|
@@ -9,36 +10,46 @@ class Edit:
|
|
|
9
10
|
self,
|
|
10
11
|
src_msg: pyrogram.types.Message,
|
|
11
12
|
target_msg: pyrogram.types.Message,
|
|
13
|
+
db_msg: reposter.db.models.Msg,
|
|
12
14
|
) -> None:
|
|
13
15
|
self.src_msg = src_msg
|
|
14
16
|
self.target_msg = target_msg
|
|
17
|
+
self.db_msg = db_msg
|
|
15
18
|
self.links = reposter.funcs.other.double_links(
|
|
16
19
|
src_msg=src_msg,
|
|
17
20
|
target_msg=target_msg,
|
|
18
21
|
)
|
|
19
22
|
|
|
20
|
-
def
|
|
23
|
+
async def log_and_save(self) -> None:
|
|
24
|
+
self.db_msg.hash = self.new_hash
|
|
25
|
+
await self.db_msg.save()
|
|
21
26
|
reposter.funcs.logging.log_msg(
|
|
22
|
-
to_log='[
|
|
27
|
+
to_log='[bright_cyan]\\[success edit][/]',
|
|
23
28
|
src_msg=self.src_msg,
|
|
24
29
|
target_msg=self.target_msg,
|
|
25
30
|
)
|
|
26
31
|
|
|
27
32
|
async def edit(self) -> None:
|
|
33
|
+
self.new_hash = reposter.funcs.other.get_hash(self.src_msg)
|
|
34
|
+
if self.db_msg.hash == self.new_hash:
|
|
35
|
+
reposter.core.common.log(
|
|
36
|
+
f'[yellow]\\[warn][/] can\'t see changes between {self.links}'
|
|
37
|
+
)
|
|
38
|
+
return
|
|
28
39
|
if self.src_msg.text or self.target_msg.text:
|
|
29
40
|
if self.src_msg.text.markdown != self.target_msg.text.markdown:
|
|
30
41
|
await self.target_msg.edit_text(self.src_msg.text.markdown)
|
|
31
|
-
return
|
|
42
|
+
return await self.log_and_save()
|
|
32
43
|
if self.src_msg.caption or self.target_msg.caption:
|
|
33
44
|
if not self.src_msg.caption:
|
|
34
45
|
await self.target_msg.edit_caption('')
|
|
35
|
-
return self.
|
|
46
|
+
return await self.log_and_save()
|
|
36
47
|
if not self.target_msg.caption:
|
|
37
48
|
await self.target_msg.edit_caption(self.src_msg.caption.markdown)
|
|
38
|
-
return self.
|
|
49
|
+
return await self.log_and_save()
|
|
39
50
|
if self.src_msg.caption.markdown != self.target_msg.caption.markdown:
|
|
40
51
|
await self.target_msg.edit_caption(self.src_msg.caption.markdown)
|
|
41
|
-
return self.
|
|
52
|
+
return await self.log_and_save()
|
|
42
53
|
reposter.core.common.log(
|
|
43
54
|
f'[yellow]\\[warn][/] can\'t see changes between {self.links}'
|
|
44
55
|
)
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import reposter.handlers.other
|
|
2
|
+
import reposter.funcs.logging
|
|
3
|
+
import reposter.funcs.handle
|
|
4
|
+
import reposter.funcs.other
|
|
5
|
+
import reposter.core.config
|
|
6
|
+
import reposter.core.common
|
|
7
|
+
import reposter.core.types
|
|
8
|
+
import reposter.db.models
|
|
9
|
+
import pyrogram.types
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ForwardUnrestricted:
|
|
13
|
+
def __init__(
|
|
14
|
+
self,
|
|
15
|
+
target_any: reposter.core.types.target,
|
|
16
|
+
src_to_forward: pyrogram.types.Message,
|
|
17
|
+
src_in_db: pyrogram.types.Message,
|
|
18
|
+
) -> None:
|
|
19
|
+
self.target_any: reposter.core.types.target = target_any
|
|
20
|
+
self.src_msg = src_to_forward
|
|
21
|
+
self.src_in_db: pyrogram.types.Message = src_in_db
|
|
22
|
+
assert isinstance(self.target_any, (str, int, list))
|
|
23
|
+
|
|
24
|
+
async def copy_all(
|
|
25
|
+
self,
|
|
26
|
+
) -> None:
|
|
27
|
+
if self.src_msg.media_group_id:
|
|
28
|
+
to_call = self.copy_media_group
|
|
29
|
+
else:
|
|
30
|
+
to_call = self.copy_one
|
|
31
|
+
await reposter.handlers.other.parse_targets(
|
|
32
|
+
target_any=self.target_any,
|
|
33
|
+
to_call=to_call,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
async def copy_one(
|
|
37
|
+
self,
|
|
38
|
+
target: str | int,
|
|
39
|
+
) -> None:
|
|
40
|
+
target_msg = await reposter.funcs.handle.run_excepted(
|
|
41
|
+
self.src_msg.forward,
|
|
42
|
+
chat_id=target,
|
|
43
|
+
drop_author=reposter.core.config.json.drop_author,
|
|
44
|
+
)
|
|
45
|
+
assert isinstance(target_msg, pyrogram.types.Message)
|
|
46
|
+
await reposter.db.models.Msg.create(
|
|
47
|
+
hash = reposter.funcs.other.get_hash(self.src_msg),
|
|
48
|
+
src_msg=self.src_in_db.id,
|
|
49
|
+
src_chat=self.src_in_db.chat.id,
|
|
50
|
+
target_msg=target_msg.id,
|
|
51
|
+
target_chat=target_msg.chat.id
|
|
52
|
+
)
|
|
53
|
+
reposter.funcs.logging.log_msg(
|
|
54
|
+
to_log='[green]\\[success forward][/]',
|
|
55
|
+
src_msg=self.src_msg,
|
|
56
|
+
target_msg=target_msg,
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
async def copy_media_group(
|
|
60
|
+
self,
|
|
61
|
+
target: str | int,
|
|
62
|
+
) -> None:
|
|
63
|
+
src_media_group = await self.src_msg.get_media_group()
|
|
64
|
+
if self.src_msg.id != src_media_group[0].id:
|
|
65
|
+
return
|
|
66
|
+
target_media_group = await reposter.core.common.tg.client.copy_media_group(
|
|
67
|
+
chat_id=target,
|
|
68
|
+
from_chat_id=self.src_msg.chat.id,
|
|
69
|
+
message_id=self.src_msg.id,
|
|
70
|
+
)
|
|
71
|
+
for src_msg, target_msg in zip(
|
|
72
|
+
src_media_group,
|
|
73
|
+
target_media_group,
|
|
74
|
+
):
|
|
75
|
+
await reposter.db.models.Msg.create(
|
|
76
|
+
hash = reposter.funcs.other.get_hash(self.src_msg),
|
|
77
|
+
src_msg=src_msg.id,
|
|
78
|
+
src_chat=src_msg.chat.id,
|
|
79
|
+
target_msg=target_msg.id,
|
|
80
|
+
target_chat=target_msg.chat.id
|
|
81
|
+
)
|
|
82
|
+
reposter.funcs.logging.log_msg(
|
|
83
|
+
to_log='[green]\\[success forward media group][/]',
|
|
84
|
+
src_msg=src_msg,
|
|
85
|
+
target_msg=target_msg,
|
|
86
|
+
)
|
|
87
|
+
|
|
@@ -5,9 +5,11 @@ import reposter.handlers.service
|
|
|
5
5
|
import reposter.handlers.edit
|
|
6
6
|
import reposter.funcs.other
|
|
7
7
|
import reposter.core.common
|
|
8
|
+
import reposter.core.config
|
|
8
9
|
import reposter.core.types
|
|
9
10
|
import reposter.db.models
|
|
10
11
|
import pyrogram.types
|
|
12
|
+
import datetime
|
|
11
13
|
|
|
12
14
|
|
|
13
15
|
class OnMsg:
|
|
@@ -40,18 +42,25 @@ class OnMsg:
|
|
|
40
42
|
await stream_notify.notify_all()
|
|
41
43
|
return
|
|
42
44
|
if src_msg.has_protected_content or src_msg.chat.has_protected_content:
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
if src_msg.media_group_id:
|
|
46
|
+
resend_media_group = reposter.handlers.resend_restricted.ResendMediaGroup(
|
|
47
|
+
src_msg=src_msg,
|
|
48
|
+
target_any=self.target_any,
|
|
49
|
+
)
|
|
50
|
+
await resend_media_group.all()
|
|
51
|
+
else:
|
|
52
|
+
resend_one = reposter.handlers.resend_restricted.ResendOne(
|
|
53
|
+
src_msg=src_msg,
|
|
54
|
+
target_any=self.target_any,
|
|
55
|
+
)
|
|
56
|
+
await resend_one.all()
|
|
48
57
|
else:
|
|
49
58
|
real_time_forward = reposter.handlers.forward_unrestricted.ForwardUnrestricted(
|
|
50
59
|
target_any=self.target_any,
|
|
51
60
|
src_to_forward=src_msg,
|
|
52
61
|
src_in_db=src_msg,
|
|
53
62
|
)
|
|
54
|
-
await real_time_forward.
|
|
63
|
+
await real_time_forward.copy_all()
|
|
55
64
|
|
|
56
65
|
async def on_edited_msg(
|
|
57
66
|
self,
|
|
@@ -60,8 +69,16 @@ class OnMsg:
|
|
|
60
69
|
) -> None:
|
|
61
70
|
link = reposter.funcs.other.single_link(src_msg)
|
|
62
71
|
reposter.core.common.log(
|
|
63
|
-
f'[bright_cyan]\\[
|
|
72
|
+
f'[bright_cyan]\\[new edit] [blue]{link}'
|
|
64
73
|
)
|
|
74
|
+
if reposter.core.config.json.edit_timeout_seconds:
|
|
75
|
+
send_how_long_ago = src_msg.edit_date - src_msg.date
|
|
76
|
+
timeout = datetime.timedelta(seconds=reposter.core.config.json.edit_timeout_seconds)
|
|
77
|
+
if send_how_long_ago > timeout:
|
|
78
|
+
reposter.core.common.log(
|
|
79
|
+
f'[yellow]\\[warn] [blue]{link} edited but send too long ago'
|
|
80
|
+
)
|
|
81
|
+
return
|
|
65
82
|
db_msgs = await reposter.db.models.Msg.filter(
|
|
66
83
|
src_msg=src_msg.id,
|
|
67
84
|
src_chat=src_msg.chat.id
|
|
@@ -83,6 +100,7 @@ class OnMsg:
|
|
|
83
100
|
edit = reposter.handlers.edit.Edit(
|
|
84
101
|
target_msg=target_msg,
|
|
85
102
|
src_msg=src_msg,
|
|
103
|
+
db_msg=db_msg,
|
|
86
104
|
)
|
|
87
105
|
await edit.edit()
|
|
88
106
|
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import reposter.handlers.forward_unrestricted
|
|
2
|
+
import reposter.handlers.other
|
|
3
|
+
import reposter.funcs.handle
|
|
4
|
+
import reposter.funcs.logging
|
|
5
|
+
import reposter.funcs.other
|
|
6
|
+
import reposter.core.config
|
|
7
|
+
import reposter.core.common
|
|
8
|
+
import reposter.core.types
|
|
9
|
+
import reposter.tg.restricted
|
|
10
|
+
import reposter.db.models
|
|
11
|
+
import pyrogram.types
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class ResendOne:
|
|
15
|
+
def __init__(
|
|
16
|
+
self,
|
|
17
|
+
target_any: reposter.core.types.target,
|
|
18
|
+
src_msg: pyrogram.types.Message,
|
|
19
|
+
) -> None:
|
|
20
|
+
self.target_any: reposter.core.types.target = target_any
|
|
21
|
+
self.src_msg = src_msg
|
|
22
|
+
assert isinstance(self.target_any, (str, int, list))
|
|
23
|
+
|
|
24
|
+
async def all(self):
|
|
25
|
+
if isinstance(self.target_any, list):
|
|
26
|
+
await self.multiple_targets()
|
|
27
|
+
elif isinstance(self.target_any, (str, int)):
|
|
28
|
+
await self.one_target(
|
|
29
|
+
target=self.target_any,
|
|
30
|
+
save_db=True,
|
|
31
|
+
)
|
|
32
|
+
else:
|
|
33
|
+
raise AssertionError
|
|
34
|
+
|
|
35
|
+
async def multiple_targets(self) -> None:
|
|
36
|
+
assert reposter.core.config.json.logs_chat
|
|
37
|
+
resent_to_log_chat = await self.one_target(
|
|
38
|
+
target=reposter.core.config.json.logs_chat,
|
|
39
|
+
save_db=False,
|
|
40
|
+
)
|
|
41
|
+
real_time_forward = reposter.handlers.forward_unrestricted.ForwardUnrestricted(
|
|
42
|
+
target_any=self.target_any,
|
|
43
|
+
src_to_forward=resent_to_log_chat,
|
|
44
|
+
src_in_db=self.src_msg,
|
|
45
|
+
)
|
|
46
|
+
await real_time_forward.copy_all()
|
|
47
|
+
|
|
48
|
+
async def one_target(
|
|
49
|
+
self,
|
|
50
|
+
target: str | int,
|
|
51
|
+
save_db: bool,
|
|
52
|
+
) -> pyrogram.types.Message:
|
|
53
|
+
resender = reposter.tg.restricted.Resender(
|
|
54
|
+
src_msg=self.src_msg,
|
|
55
|
+
target_chat=target,
|
|
56
|
+
)
|
|
57
|
+
target_msg = await reposter.funcs.handle.run_excepted(
|
|
58
|
+
resender.resend_anything,
|
|
59
|
+
)
|
|
60
|
+
assert target_msg
|
|
61
|
+
reposter.funcs.logging.log_msg(
|
|
62
|
+
to_log='[green]\\[success resend][/]',
|
|
63
|
+
src_msg=self.src_msg,
|
|
64
|
+
target_msg=target_msg,
|
|
65
|
+
)
|
|
66
|
+
if save_db:
|
|
67
|
+
await reposter.db.models.Msg.create(
|
|
68
|
+
hash = reposter.funcs.other.get_hash(self.src_msg),
|
|
69
|
+
src_msg=self.src_msg.id,
|
|
70
|
+
src_chat=self.src_msg.chat,
|
|
71
|
+
target_msg=target_msg.id,
|
|
72
|
+
target_chat=target_msg.chat.id
|
|
73
|
+
)
|
|
74
|
+
return target_msg
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class ResendMediaGroup:
|
|
79
|
+
def __init__(
|
|
80
|
+
self,
|
|
81
|
+
target_any: reposter.core.types.target,
|
|
82
|
+
src_msg: pyrogram.types.Message,
|
|
83
|
+
) -> None:
|
|
84
|
+
self.target_any: reposter.core.types.target = target_any
|
|
85
|
+
self.src_msg = src_msg
|
|
86
|
+
self.media: list[reposter.core.types.input_media] = []
|
|
87
|
+
self.src_media_group: list[pyrogram.types.Message]
|
|
88
|
+
assert isinstance(self.target_any, (str, int, list))
|
|
89
|
+
|
|
90
|
+
async def all(self) -> None:
|
|
91
|
+
self.src_media_group = await self.src_msg.get_media_group()
|
|
92
|
+
if self.src_msg.id != self.src_media_group[0].id:
|
|
93
|
+
return
|
|
94
|
+
for src_msg in self.src_media_group:
|
|
95
|
+
self.media.append(
|
|
96
|
+
await self.get_media(src_msg)
|
|
97
|
+
)
|
|
98
|
+
await reposter.handlers.other.parse_targets(
|
|
99
|
+
target_any=self.target_any,
|
|
100
|
+
to_call=self.one_target,
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
async def one_target(
|
|
104
|
+
self,
|
|
105
|
+
target: str | int,
|
|
106
|
+
):
|
|
107
|
+
target_media_group = await reposter.core.common.tg.client.send_media_group(
|
|
108
|
+
chat_id=target,
|
|
109
|
+
media=self.media,
|
|
110
|
+
)
|
|
111
|
+
for src_msg, target_msg in zip(
|
|
112
|
+
self.src_media_group,
|
|
113
|
+
target_media_group,
|
|
114
|
+
):
|
|
115
|
+
await reposter.db.models.Msg.create(
|
|
116
|
+
hash = reposter.funcs.other.get_hash(self.src_msg),
|
|
117
|
+
src_msg=src_msg.id,
|
|
118
|
+
src_chat=src_msg.chat.id,
|
|
119
|
+
target_msg=target_msg.id,
|
|
120
|
+
target_chat=target_msg.chat.id
|
|
121
|
+
)
|
|
122
|
+
reposter.funcs.logging.log_msg(
|
|
123
|
+
to_log='[green]\\[success resend media group][/]',
|
|
124
|
+
src_msg=src_msg,
|
|
125
|
+
target_msg=target_msg,
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
async def get_media(
|
|
129
|
+
self,
|
|
130
|
+
src_msg: pyrogram.types.Message,
|
|
131
|
+
) -> reposter.core.types.input_media:
|
|
132
|
+
resend_one = ResendOne(
|
|
133
|
+
target_any=reposter.core.config.json.logs_chat,
|
|
134
|
+
src_msg=src_msg,
|
|
135
|
+
)
|
|
136
|
+
resent_to_log_chat = await resend_one.one_target(
|
|
137
|
+
target=reposter.core.config.json.logs_chat,
|
|
138
|
+
save_db=False,
|
|
139
|
+
)
|
|
140
|
+
if resent_to_log_chat.caption:
|
|
141
|
+
caption: str = resent_to_log_chat.caption.markdown
|
|
142
|
+
else:
|
|
143
|
+
caption: str = ''
|
|
144
|
+
media_value = str(resent_to_log_chat.media.value)
|
|
145
|
+
media = getattr(resent_to_log_chat, media_value)
|
|
146
|
+
assert isinstance(media, reposter.core.types.in_group_media)
|
|
147
|
+
input_media = getattr(pyrogram.types, 'InputMedia' + media_value.capitalize())
|
|
148
|
+
inputted = input_media(
|
|
149
|
+
media=media.file_id,
|
|
150
|
+
caption=caption
|
|
151
|
+
)
|
|
152
|
+
assert isinstance(inputted, reposter.core.types.input_media)
|
|
153
|
+
return inputted
|
|
154
|
+
|
|
@@ -37,7 +37,7 @@ class Service:
|
|
|
37
37
|
)
|
|
38
38
|
assert isinstance(target_msg, pyrogram.types.Message)
|
|
39
39
|
reposter.funcs.logging.log_msg(
|
|
40
|
-
to_log=f'[green]\\[service][/] {text}',
|
|
40
|
+
to_log=f'[green]\\[success service][/] {text}',
|
|
41
41
|
src_msg=self.src_msg,
|
|
42
42
|
target_msg=target_msg,
|
|
43
43
|
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: reposter
|
|
3
|
-
Version: 24.
|
|
3
|
+
Version: 24.3.0
|
|
4
4
|
Summary: python script for reposting telegram messages
|
|
5
5
|
Project-URL: repo, https://github.com/gmankab/reposter
|
|
6
6
|
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
@@ -29,7 +29,8 @@ userbot that forwards messages from telegram channels others in real time
|
|
|
29
29
|
- [repo](https://github.com/gmankab/reposter)
|
|
30
30
|
- [how to run](https://github.com/gmankab/reposter/blob/main/other/docs/run.md)
|
|
31
31
|
- [how to build](https://github.com/gmankab/reposter/blob/main/other/docs/build.md)
|
|
32
|
-
- [config
|
|
32
|
+
- [config](https://github.com/gmankab/reposter/blob/main/other/docs/config.md)
|
|
33
|
+
- [env](https://github.com/gmankab/reposter/blob/main/other/docs/env.md)
|
|
33
34
|
- [pypi](https://pypi.org/project/reposter)
|
|
34
35
|
|
|
35
36
|
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import reposter.handlers.other
|
|
2
|
-
import reposter.funcs.logging
|
|
3
|
-
import reposter.funcs.handle
|
|
4
|
-
import reposter.core.config
|
|
5
|
-
import reposter.core.types
|
|
6
|
-
import reposter.db.models
|
|
7
|
-
import pyrogram.types
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class ForwardUnrestricted:
|
|
11
|
-
def __init__(
|
|
12
|
-
self,
|
|
13
|
-
target_any: reposter.core.types.target,
|
|
14
|
-
src_to_forward: pyrogram.types.Message,
|
|
15
|
-
src_in_db: pyrogram.types.Message,
|
|
16
|
-
) -> None:
|
|
17
|
-
self.target_any: reposter.core.types.target = target_any
|
|
18
|
-
self.src_msg = src_to_forward
|
|
19
|
-
self.src_in_db: pyrogram.types.Message = src_in_db
|
|
20
|
-
assert isinstance(self.target_any, (str, int, list))
|
|
21
|
-
|
|
22
|
-
async def forward_all(
|
|
23
|
-
self,
|
|
24
|
-
) -> None:
|
|
25
|
-
await reposter.handlers.other.parse_targets(
|
|
26
|
-
target_any=self.target_any,
|
|
27
|
-
to_call=self.forward_one,
|
|
28
|
-
)
|
|
29
|
-
|
|
30
|
-
async def forward_one(
|
|
31
|
-
self,
|
|
32
|
-
target: str | int,
|
|
33
|
-
) -> None:
|
|
34
|
-
target_msg = await reposter.funcs.handle.run_excepted(
|
|
35
|
-
self.src_msg.forward,
|
|
36
|
-
chat_id=target,
|
|
37
|
-
drop_author=reposter.core.config.json.drop_author,
|
|
38
|
-
)
|
|
39
|
-
assert isinstance(target_msg, pyrogram.types.Message)
|
|
40
|
-
await reposter.db.models.Msg.create(
|
|
41
|
-
src_msg=self.src_in_db.id,
|
|
42
|
-
src_chat=self.src_in_db.chat.id,
|
|
43
|
-
target_msg=target_msg.id,
|
|
44
|
-
target_chat=target_msg.chat.id
|
|
45
|
-
)
|
|
46
|
-
reposter.funcs.logging.log_msg(
|
|
47
|
-
to_log='[green]\\[forward][/]',
|
|
48
|
-
src_msg=self.src_msg,
|
|
49
|
-
target_msg=target_msg,
|
|
50
|
-
)
|
|
51
|
-
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import reposter.handlers.forward_unrestricted
|
|
2
|
-
import reposter.funcs.handle
|
|
3
|
-
import reposter.funcs.logging
|
|
4
|
-
import reposter.core.config
|
|
5
|
-
import reposter.core.types
|
|
6
|
-
import reposter.tg.restricted
|
|
7
|
-
import reposter.db.models
|
|
8
|
-
import pyrogram.types
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class ResendRestricted:
|
|
12
|
-
def __init__(
|
|
13
|
-
self,
|
|
14
|
-
target_any: reposter.core.types.target,
|
|
15
|
-
src_msg: pyrogram.types.Message,
|
|
16
|
-
) -> None:
|
|
17
|
-
self.target_any: reposter.core.types.target = target_any
|
|
18
|
-
self.src_msg = src_msg
|
|
19
|
-
assert isinstance(self.target_any, (str, int, list))
|
|
20
|
-
|
|
21
|
-
async def resend_all(self) -> None:
|
|
22
|
-
if isinstance(self.target_any, list):
|
|
23
|
-
assert reposter.core.config.json.logs_chat
|
|
24
|
-
resent_to_log_chat = await reposter.funcs.handle.run_excepted(
|
|
25
|
-
self.resend_one,
|
|
26
|
-
src_msg=self.src_msg,
|
|
27
|
-
target=reposter.core.config.json.logs_chat,
|
|
28
|
-
)
|
|
29
|
-
real_time_forward = reposter.handlers.forward_unrestricted.ForwardUnrestricted(
|
|
30
|
-
target_any=self.target_any,
|
|
31
|
-
src_to_forward=resent_to_log_chat,
|
|
32
|
-
src_in_db=self.src_msg,
|
|
33
|
-
)
|
|
34
|
-
return await real_time_forward.forward_all()
|
|
35
|
-
elif isinstance(self.target_any, (str, int)):
|
|
36
|
-
target_msg = await self.resend_one(
|
|
37
|
-
src_msg=self.src_msg,
|
|
38
|
-
target=self.target_any,
|
|
39
|
-
)
|
|
40
|
-
await reposter.db.models.Msg.create(
|
|
41
|
-
src_msg=self.src_msg.id,
|
|
42
|
-
src_chat=self.src_msg.chat,
|
|
43
|
-
target_msg=target_msg.id,
|
|
44
|
-
target_chat=target_msg.chat.id
|
|
45
|
-
)
|
|
46
|
-
else:
|
|
47
|
-
raise AssertionError
|
|
48
|
-
|
|
49
|
-
async def resend_one(
|
|
50
|
-
self,
|
|
51
|
-
src_msg: pyrogram.types.Message,
|
|
52
|
-
target: str | int,
|
|
53
|
-
) -> pyrogram.types.Message:
|
|
54
|
-
resender = reposter.tg.restricted.Resender(
|
|
55
|
-
src_msg=self.src_msg,
|
|
56
|
-
target_chat=target,
|
|
57
|
-
)
|
|
58
|
-
target_msg = await reposter.funcs.handle.run_excepted(
|
|
59
|
-
resender.resend_anything,
|
|
60
|
-
)
|
|
61
|
-
assert target_msg
|
|
62
|
-
reposter.funcs.logging.log_msg(
|
|
63
|
-
to_log='[green]\\[resend][/]',
|
|
64
|
-
src_msg=src_msg,
|
|
65
|
-
target_msg=target_msg,
|
|
66
|
-
)
|
|
67
|
-
return target_msg
|
|
68
|
-
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|