ifa-nextcloud 0.1.1__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.
@@ -0,0 +1,50 @@
1
+ name: Publish Python 🐍 distribution to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - '*' # ΠŸΡƒΠ±Π»ΠΈΠΊΠ°Ρ†ΠΈΡ ΠΏΡ€ΠΈ создании любого Ρ‚Π΅Π³Π°
7
+
8
+ jobs:
9
+ build:
10
+ name: Build distribution πŸ“¦
11
+ runs-on: ubuntu-latest
12
+
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+ - name: Set up Python
16
+ uses: actions/setup-python@v5
17
+ with:
18
+ python-version: "3.x"
19
+
20
+ - name: Install pypa/build
21
+ run: python -m pip install build --user
22
+
23
+ - name: Build a binary wheel and a source tarball
24
+ run: python -m build
25
+
26
+ - name: Store the distribution packages
27
+ uses: actions/upload-artifact@v4
28
+ with:
29
+ name: python-package-distributions
30
+ path: dist/
31
+
32
+ publish-to-pypi:
33
+ name: Publish to PyPI
34
+ needs: [build]
35
+ runs-on: ubuntu-latest
36
+ environment:
37
+ name: pypi
38
+ url: https://pypi.org/p/ifa_nextcloud
39
+ permissions:
40
+ id-token: write # ΠžΠ‘Π―Π—ΠΠ’Π•Π›Π¬ΠΠž для Trusted Publishing
41
+
42
+ steps:
43
+ - name: Download all the dists
44
+ uses: actions/download-artifact@v4
45
+ with:
46
+ name: python-package-distributions
47
+ path: dist/
48
+
49
+ - name: Publish to PyPI
50
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,6 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ifake
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ ...
@@ -0,0 +1,560 @@
1
+ Metadata-Version: 2.4
2
+ Name: ifa_nextcloud
3
+ Version: 0.1.1
4
+ Summary: Python Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° для создания Π±ΠΎΡ‚ΠΎΠ² Π² Nextcloud Talk с API, ΠΏΠΎΡ…ΠΎΠΆΠΈΠΌ Π½Π° python-telegram-bot
5
+ Project-URL: Homepage, https://github.com/ifake/nextcloud
6
+ Project-URL: Repository, https://github.com/ifake/nextcloud.git
7
+ Project-URL: Issues, https://github.com/ifake/nextcloud/issues
8
+ Author-email: ifake <your@email.com>
9
+ License: MIT
10
+ License-File: LICENSE
11
+ Keywords: bot,chat,ifa,messaging,nextcloud,talk
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Requires-Python: >=3.10
19
+ Requires-Dist: loguru>=0.6.0
20
+ Requires-Dist: requests>=2.25.0
21
+ Description-Content-Type: text/markdown
22
+
23
+ # Nextcloud Talk Bot
24
+
25
+ Python Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° для создания Π±ΠΎΡ‚ΠΎΠ² Π² Nextcloud Talk с API, ΠΏΠΎΡ…ΠΎΠΆΠΈΠΌ Π½Π° python-telegram-bot.
26
+
27
+ ## ВозмоТности
28
+
29
+ - πŸš€ **ΠŸΡ€ΠΎΡΡ‚ΠΎΠΉ API** β€” интСрфСйс, ΠΏΠΎΡ…ΠΎΠΆΠΈΠΉ Π½Π° python-telegram-bot
30
+ - πŸ“ **ΠžΡ‚ΠΏΡ€Π°Π²ΠΊΠ° сообщСний** с ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΎΠΉ Markdown
31
+ - πŸ“Ž **ΠžΡ‚ΠΏΡ€Π°Π²ΠΊΠ° Ρ„Π°ΠΉΠ»ΠΎΠ²** (Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Ρ‹, Ρ„ΠΎΡ‚ΠΎ, Π»ΡŽΠ±Ρ‹Π΅ влоТСния)
32
+ - πŸ”„ **АвтоматичСскоС ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ члСнством** Π² ΠΊΠΎΠΌΠ½Π°Ρ‚Π°Ρ…
33
+ - πŸ’¬ **ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° threading ΠΈ ΠΎΡ‚Π²Π΅Ρ‚ΠΎΠ² Π½Π° сообщСния**
34
+ - πŸ”Œ **АвтоматичСскоС ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ вСрсии API** (v1-v4)
35
+ - πŸ›‘οΈ **АвтоматичСская пСрСавторизация** ΠΏΡ€ΠΈ ΠΎΡˆΠΈΠ±ΠΊΠ°Ρ…
36
+ - πŸ“‘ **Polling Ρ€Π΅ΠΆΠΈΠΌ** для получСния сообщСний
37
+
38
+ ## ВрСбования
39
+
40
+ - Python 3.7+
41
+ - Nextcloud 33.x ΠΈ Π²Ρ‹ΡˆΠ΅ (с установлСнным ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΠΌ Talk)
42
+ - Аккаунт Π±ΠΎΡ‚Π° Π² Nextcloud (рСкомСндуСтся ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚ΠΎΠΊΠ΅Π½ прилоТСния)
43
+
44
+ ## Установка
45
+
46
+ ### Из исходного ΠΊΠΎΠ΄Π°
47
+
48
+ ```bash
49
+ git clone https://github.com/your-username/nextcloud-talk-bot.git
50
+ cd nextcloud-talk-bot
51
+ pip install -r requirements.txt
52
+ ```
53
+
54
+ ### ИспользованиС ΠΊΠ°ΠΊ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ
55
+
56
+ Π‘ΠΊΠΎΠΏΠΈΡ€ΡƒΠΉΡ‚Π΅ ΠΏΠ°ΠΏΠΊΡƒ `core/` Π² ваш ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ ΠΈΠ»ΠΈ установитС ΠΊΠ°ΠΊ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ:
57
+
58
+ ```python
59
+ # ΠŸΡ€ΠΎΡΡ‚ΠΎ скопируйтС Ρ„Π°ΠΉΠ»Ρ‹ Π² ваш ΠΏΡ€ΠΎΠ΅ΠΊΡ‚
60
+ from nextcloudbot import Bot
61
+ ```
62
+
63
+ ## Быстрый старт
64
+
65
+ ### ΠœΠΈΠ½ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€
66
+
67
+ ```python
68
+ from nextcloudbot import Bot
69
+
70
+ # Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ Π±ΠΎΡ‚Π°
71
+ bot = Bot(
72
+ host="https://nextcloud.example.com",
73
+ user="bot_user",
74
+ password="your-app-token", # ΠΈΠ»ΠΈ ΠΏΠ°Ρ€ΠΎΠ»ΡŒ
75
+ default_room="room_token_here"
76
+ )
77
+
78
+ # ΠžΡ‚ΠΏΡ€Π°Π²Π»ΡΠ΅ΠΌ сообщСниС
79
+ bot.send_message("Hello, World!")
80
+
81
+ # ЗапускаСм ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ сообщСний
82
+ bot.run_polling()
83
+ ```
84
+
85
+ ### Π‘ΠΎΡ‚ с ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΎΠΉ ΠΊΠΎΠΌΠ°Π½Π΄
86
+
87
+ ```python
88
+ from nextcloudbot import Bot
89
+
90
+ bot = Bot(
91
+ host="https://nextcloud.example.com",
92
+ user="my_bot",
93
+ password="app-xxxxx",
94
+ default_room="room_token"
95
+ )
96
+
97
+ # ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ /start
98
+ @bot.command("start")
99
+ def start_command(update, context):
100
+ update.message.reply_text("πŸ‘‹ ΠŸΡ€ΠΈΠ²Π΅Ρ‚! Π― Π±ΠΎΡ‚ для Nextcloud Talk!")
101
+
102
+ # ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ /help
103
+ @bot.command("help")
104
+ def help_command(update, context):
105
+ help_text = """
106
+ πŸ€– **ДоступныС ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹:**
107
+ /start - ΠŸΡ€ΠΈΠ²Π΅Ρ‚ΡΡ‚Π²ΠΈΠ΅
108
+ /help - Π­Ρ‚Π° справка
109
+ /echo <тСкст> - ΠŸΠΎΠ²Ρ‚ΠΎΡ€ΠΈΡ‚ΡŒ сообщСниС
110
+ """
111
+ update.message.reply_text(help_text)
112
+
113
+ # ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ /echo
114
+ @bot.command("echo")
115
+ def echo_command(update, context):
116
+ # ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ тСкст послС ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹
117
+ text = update.message.text.replace("/echo", "").strip()
118
+ if text:
119
+ update.message.reply_text(f"πŸ”Š {text}")
120
+ else:
121
+ update.message.reply_text("❌ ΠΠ°ΠΏΠΈΡˆΠΈΡ‚Π΅ Ρ‡Ρ‚ΠΎ-Π½ΠΈΠ±ΡƒΠ΄ΡŒ послС /echo")
122
+
123
+ # ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ всСх тСкстовых сообщСний
124
+ @bot.message_handler
125
+ def handle_message(update, context):
126
+ message = update.message
127
+ user = message.from_user
128
+ print(f"ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΎ сообщСниС ΠΎΡ‚ {user.full_name}: {message.text}")
129
+ message.reply_text(f"ΠŸΠΎΠ»ΡƒΡ‡ΠΈΠ»: {message.text}")
130
+
131
+ # ЗапускаСм Π±ΠΎΡ‚Π°
132
+ if __name__ == "__main__":
133
+ bot.run_polling()
134
+ ```
135
+
136
+ ## ΠžΡ‚ΠΏΡ€Π°Π²ΠΊΠ° сообщСний
137
+
138
+ ### ВСкстовыС сообщСния
139
+
140
+ ```python
141
+ # ΠŸΡ€ΠΎΡΡ‚ΠΎΠΉ тСкст
142
+ bot.send_message("Hello, World!")
143
+
144
+ # Markdown Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅
145
+ bot.send_message("**Π–ΠΈΡ€Π½Ρ‹ΠΉ тСкст** ΠΈ *курсив*")
146
+
147
+ # ΠžΡ‚Π²Π΅Ρ‚ Π½Π° сообщСниС
148
+ bot.send_message(
149
+ chat_id="room_token", # optional
150
+ text="Π­Ρ‚ΠΎ ΠΎΡ‚Π²Π΅Ρ‚ Π½Π° вашС сообщСниС",
151
+ reply_to_message_id=12345
152
+ )
153
+ ```
154
+
155
+ ### ΠžΡ‚ΠΏΡ€Π°Π²ΠΊΠ° Ρ„Π°ΠΉΠ»ΠΎΠ²
156
+
157
+ ```python
158
+ # ΠžΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ Ρ„Π°ΠΉΠ» с подписью
159
+ bot.send_message(
160
+ chat_id="room_token", # optional
161
+ text="Π‘ΠΌΠΎΡ‚Ρ€ΠΈΡ‚Π΅ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚",
162
+ file_path="/path/to/document.pdf"
163
+ )
164
+
165
+ # ΠžΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ Ρ„ΠΎΡ‚ΠΎ
166
+ bot.send_file("/path/to/photo.jpg", caption="ΠšΡ€Π°ΡΠΈΠ²Ρ‹ΠΉ Π·Π°ΠΊΠ°Ρ‚")
167
+
168
+ # Или Ρ‡Π΅Ρ€Π΅Π· ΠΌΠ΅Ρ‚ΠΎΠ΄ send_photo
169
+ bot.send_photo(
170
+ "room_token", # optional
171
+ "/path/to/photo.jpg",
172
+ caption="ΠšΡ€Π°ΡΠΈΠ²Ρ‹ΠΉ Π·Π°ΠΊΠ°Ρ‚"
173
+ )
174
+
175
+ # ΠžΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚
176
+ bot.send_document(
177
+ "room_token", # optional
178
+ "/path/to/report.pdf",
179
+ caption="ЕТСмСсячный ΠΎΡ‚Ρ‡Π΅Ρ‚"
180
+ )
181
+
182
+ # ΠžΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ Ρ„Π°ΠΉΠ» ΠΈΠ· памяти (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, сгСнСрированный)
183
+ import io
184
+
185
+ # Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ Ρ„Π°ΠΉΠ» Π² памяти
186
+ file_content = b"Hello, this is a text file!"
187
+ bot.send_message(
188
+ chat_id="room_token", # optional
189
+ text="Π‘Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ»",
190
+ file_content=file_content,
191
+ file_name="hello.txt",
192
+ mime_type="text/plain"
193
+ )
194
+
195
+ # ΠžΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ Ρ„Π°ΠΉΠ» ΠΈΠ· BytesIO
196
+ from io import BytesIO
197
+
198
+ buffer = BytesIO()
199
+ buffer.write(b"Some data")
200
+ buffer.seek(0)
201
+
202
+ bot.send_document(
203
+ "room_token", # optional
204
+ buffer,
205
+ caption="Π”Π°Π½Π½Ρ‹Π΅ ΠΈΠ· Π±ΡƒΡ„Π΅Ρ€Π°"
206
+ )
207
+ ```
208
+
209
+ ## Π Π°Π±ΠΎΡ‚Π° с сообщСниями
210
+
211
+ ### ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ сообщСний Ρ‡Π΅Ρ€Π΅Π· polling
212
+
213
+ ```python
214
+ # ЗапускаСм ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ сообщСний
215
+ bot.run_polling(chat_id="room_token", poll_interval=2)
216
+
217
+ # ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹:
218
+ # - chat_id: Ρ‚ΠΎΠΊΠ΅Π½ ΠΊΠΎΠΌΠ½Π°Ρ‚Ρ‹ (Ссли Π½Π΅ ΡƒΠΊΠ°Π·Π°Π½, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ default_room)
219
+ # - poll_interval: ΠΈΠ½Ρ‚Π΅Ρ€Π²Π°Π» опроса Π² сСкундах (ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ 2)
220
+ ```
221
+
222
+ ### ΠžΠ±ΡŠΠ΅ΠΊΡ‚ Message
223
+
224
+ ΠŸΡ€ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠΈ сообщСния Π²Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ `Message` со ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌΠΈ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π°ΠΌΠΈ:
225
+
226
+ ```python
227
+ @bot.message_handler
228
+ def handle_message(update, context):
229
+ message = update.message
230
+
231
+ # ΠžΡΠ½ΠΎΠ²Π½Ρ‹Π΅ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹
232
+ print(f"ID: {message.message_id}")
233
+ print(f"ВСкст: {message.text}")
234
+ print(f"ΠžΡ‚: {message.from_user.full_name}")
235
+ print(f"ВрСмя: {message.date}")
236
+
237
+ # ΠžΡ‚Π²Π΅Ρ‚ΠΈΡ‚ΡŒ Π½Π° сообщСниС
238
+ message.reply_text("ΠŸΠΎΠ»ΡƒΡ‡ΠΈΠ» вашС сообщСниС!")
239
+
240
+ # Или ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄ reply (алиас)
241
+ message.reply("ВоТС самоС")
242
+ ```
243
+
244
+ ## Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΊΠΎΠΌΠ½Π°Ρ‚Π°ΠΌΠΈ
245
+
246
+ ### ΠŸΡ€ΠΈΡΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠ΅ ΠΊ ΠΊΠΎΠΌΠ½Π°Ρ‚Π΅
247
+
248
+ ```python
249
+ # АвтоматичСскоС присоСдинСниС ΠΏΡ€ΠΈ запускС
250
+ bot = Bot(
251
+ host="https://nextcloud.example.com",
252
+ user="bot_user",
253
+ password="password",
254
+ default_room="room_token",
255
+ auto_join_room=True # По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ True
256
+ )
257
+
258
+ # Π ΡƒΡ‡Π½ΠΎΠ΅ присоСдинСниС
259
+ bot.join_room("room_token", password="room_password")
260
+ ```
261
+
262
+ ### ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΎ ΠΊΠΎΠΌΠ½Π°Ρ‚Π°Ρ…
263
+
264
+ ```python
265
+ # Бписок всСх доступных ΠΊΠΎΠΌΠ½Π°Ρ‚
266
+ rooms = bot.get_rooms()
267
+ for room in rooms:
268
+ print(f"ΠšΠΎΠΌΠ½Π°Ρ‚Π°: {room.get('name')} ({room.get('token')})")
269
+ print(f"Участников: {room.get('participantCount')}")
270
+
271
+ # Π˜Π½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡ ΠΎ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠΉ ΠΊΠΎΠΌΠ½Π°Ρ‚Π΅
272
+ room_info = bot.get_room_info("room_token")
273
+ print(f"НазваниС: {room_info.get('name')}")
274
+ print(f"Π’ΠΈΠΏ: {room_info.get('type')}")
275
+
276
+ # Бписок участников
277
+ participants = bot.get_room_participants("room_token")
278
+ for p in participants:
279
+ print(f"Участник: {p.get('actorDisplayName')}")
280
+ ```
281
+
282
+ ## Диагностика
283
+
284
+ ### ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ
285
+
286
+ ```python
287
+ # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° статуса сСссии
288
+ status = bot.check_session_status()
289
+ if status['authenticated']:
290
+ print(f"βœ… ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ ΠΊΠ°ΠΊ: {status['user']}")
291
+ else:
292
+ print("❌ Ошибка Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ")
293
+
294
+ # Диагностика доступа ΠΊ ΠΊΠΎΠΌΠ½Π°Ρ‚Π΅
295
+ diagnostic = bot.diagnose_room_access("room_token")
296
+ print(json.dumps(diagnostic, indent=2, ensure_ascii=False))
297
+ ```
298
+
299
+ ### Π›ΠΎΠ³ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅
300
+
301
+ Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ `loguru` для логирования. Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π½Π°ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ логирования:
302
+
303
+ ```python
304
+ from loguru import logger
305
+
306
+ # Установка уровня логирования
307
+ logger.remove() # УдаляСм стандартный ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ
308
+ logger.add(sys.stderr, level="INFO") # Волько INFO ΠΈ Π²Ρ‹ΡˆΠ΅
309
+ # ΠΈΠ»ΠΈ
310
+ logger.add(sys.stderr, level="DEBUG") # ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎΠ΅ Π»ΠΎΠ³ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅
311
+ ```
312
+
313
+ ## ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ
314
+
315
+ ### ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ Bot
316
+
317
+ | ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ | Π’ΠΈΠΏ | По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ | ОписаниС |
318
+ |----------|-----|--------------|------------------------------------------------------------------|
319
+ | `host` | str | - | URL Nextcloud сСрвСра |
320
+ | `user` | str | - | Имя ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ Π±ΠΎΡ‚Π° |
321
+ | `password` | str | - | ΠŸΠ°Ρ€ΠΎΠ»ΡŒ ΠΈΠ»ΠΈ Ρ‚ΠΎΠΊΠ΅Π½ прилоТСния |
322
+ | `default_room` | str | None | Π’ΠΎΠΊΠ΅Π½ ΠΊΠΎΠΌΠ½Π°Ρ‚Ρ‹ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ |
323
+ | `read_all_chat` | bool | False | Π§ΠΈΡ‚Π°Ρ‚ΡŒ всю ΠΈΡΡ‚ΠΎΡ€ΠΈΡŽ (c Π½ΠΎΠ²Ρ‹Ρ… ΠΊ старым) ΠΈΠ»ΠΈ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½ΠΎΠ²Ρ‹Π΅ сообщСния |
324
+ | `auto_join_room` | bool | True | АвтоматичСски ΠΏΡ€ΠΈΡΠΎΠ΅Π΄ΠΈΠ½ΡΡ‚ΡŒΡΡ ΠΊ ΠΊΠΎΠΌΠ½Π°Ρ‚Π°ΠΌ |
325
+
326
+
327
+ ## ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹
328
+
329
+ ### ΠŸΡ€ΠΎΡΡ‚ΠΎΠΉ эхо-Π±ΠΎΡ‚
330
+
331
+ ```python
332
+ from core.nextcloud import Bot
333
+
334
+ bot = Bot(
335
+ host="https://nextcloud.example.com",
336
+ user="echo_bot",
337
+ password="app-xxxxx",
338
+ default_room="room_token"
339
+ )
340
+
341
+ @bot.message_handler
342
+ def echo(update, context):
343
+ message = update.message
344
+ if message.text:
345
+ message.reply_text(f"πŸ”Š Π­Ρ…ΠΎ: {message.text}")
346
+ else:
347
+ message.reply_text("ΠΠ°ΠΏΠΈΡˆΠΈΡ‚Π΅ тСкст, я Π΅Π³ΠΎ ΠΏΠΎΠ²Ρ‚ΠΎΡ€ΡŽ!")
348
+
349
+ bot.run_polling()
350
+ ```
351
+
352
+ ### Π‘ΠΎΡ‚ для ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠΉ
353
+
354
+ ```python
355
+ import time
356
+ from core.nextcloud import Bot
357
+
358
+ class NotificationBot:
359
+ def __init__(self, host, user, password, room_token):
360
+ self.bot = Bot(
361
+ host=host,
362
+ user=user,
363
+ password=password,
364
+ default_room=room_token
365
+ )
366
+ self.room = room_token
367
+
368
+ def send_notification(self, title, message, priority="info"):
369
+ """ΠžΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠ΅ Π² Ρ‡Π°Ρ‚"""
370
+ emoji = {
371
+ "info": "ℹ️",
372
+ "success": "βœ…",
373
+ "warning": "⚠️",
374
+ "error": "❌"
375
+ }.get(priority, "πŸ“’")
376
+
377
+ text = f"{emoji} **{title}**\n{message}"
378
+ self.bot.send_message(self.room, text)
379
+
380
+ def send_file_notification(self, title, file_path, message=None):
381
+ """ΠžΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠ΅ с Ρ„Π°ΠΉΠ»ΠΎΠΌ"""
382
+ full_text = f"πŸ“Ž **{title}**"
383
+ if message:
384
+ full_text += f"\n{message}"
385
+
386
+ self.bot.send_message(
387
+ chat_id=self.room,
388
+ text=full_text,
389
+ file_path=file_path
390
+ )
391
+
392
+ # ИспользованиС
393
+ notifier = NotificationBot(
394
+ host="https://nextcloud.example.com",
395
+ user="notifier",
396
+ password="app-xxxxx",
397
+ room_token="room_token"
398
+ )
399
+
400
+ notifier.send_notification("БистСма", "Π Π΅Π·Π΅Ρ€Π²Π½ΠΎΠ΅ ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΎ", "success")
401
+ notifier.send_file_notification("ΠžΡ‚Ρ‡Π΅Ρ‚", "/tmp/report.pdf", "ЕТСмСсячный ΠΎΡ‚Ρ‡Π΅Ρ‚ Π³ΠΎΡ‚ΠΎΠ²")
402
+ ```
403
+
404
+ ### Π‘ΠΎΡ‚ с ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΎΠΉ ΠΊΠΎΠΌΠ°Π½Π΄
405
+
406
+ ```python
407
+ from core.nextcloud import Bot
408
+ from datetime import datetime
409
+
410
+ bot = Bot(
411
+ host="https://nextcloud.example.com",
412
+ user="helper_bot",
413
+ password="app-xxxxx",
414
+ default_room="room_token"
415
+ )
416
+
417
+ # Π₯Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ Π΄Π°Π½Π½Ρ‹Ρ… ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ
418
+ user_data = {}
419
+
420
+ @bot.command("start")
421
+ def cmd_start(update, context):
422
+ user = update.message.from_user
423
+ update.message.reply_text(
424
+ f"πŸ‘‹ ΠŸΡ€ΠΈΠ²Π΅Ρ‚, {user.first_name}!\n"
425
+ "Π― Π±ΠΎΡ‚-ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊ. ДоступныС ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹:\n"
426
+ "/time - Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ врСмя\n"
427
+ "/ping - ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚Ρƒ\n"
428
+ "/note <тСкст> - ΡΠΎΡ…Ρ€Π°Π½ΠΈΡ‚ΡŒ Π·Π°ΠΌΠ΅Ρ‚ΠΊΡƒ\n"
429
+ "/mynote - ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒ Π·Π°ΠΌΠ΅Ρ‚ΠΊΡƒ"
430
+ )
431
+
432
+ @bot.command("time")
433
+ def cmd_time(update, context):
434
+ now = datetime.now().strftime("%d.%m.%Y %H:%M:%S")
435
+ update.message.reply_text(f"πŸ• Π’Π΅ΠΊΡƒΡ‰Π΅Π΅ врСмя: {now}")
436
+
437
+ @bot.command("ping")
438
+ def cmd_ping(update, context):
439
+ update.message.reply_text("πŸ“ Pong!")
440
+
441
+ @bot.command("note")
442
+ def cmd_note(update, context):
443
+ user_id = update.message.from_user.id
444
+ text = update.message.text.replace("/note", "").strip()
445
+
446
+ if text:
447
+ user_data[user_id] = text
448
+ update.message.reply_text("βœ… Π—Π°ΠΌΠ΅Ρ‚ΠΊΠ° сохранСна!")
449
+ else:
450
+ update.message.reply_text("❌ ΠΠ°ΠΏΠΈΡˆΠΈΡ‚Π΅ тСкст Π·Π°ΠΌΠ΅Ρ‚ΠΊΠΈ послС /note")
451
+
452
+ @bot.command("mynote")
453
+ def cmd_mynote(update, context):
454
+ user_id = update.message.from_user.id
455
+ note = user_data.get(user_id)
456
+
457
+ if note:
458
+ update.message.reply_text(f"πŸ“ Π’Π°ΡˆΠ° Π·Π°ΠΌΠ΅Ρ‚ΠΊΠ°:\n{note}")
459
+ else:
460
+ update.message.reply_text("πŸ“­ Π£ вас Π½Π΅Ρ‚ сохранСнных Π·Π°ΠΌΠ΅Ρ‚ΠΎΠΊ")
461
+
462
+ @bot.message_handler
463
+ def handle_unknown(update, context):
464
+ text = update.message.text
465
+ if text:
466
+ update.message.reply_text(
467
+ f"НСизвСстная ΠΊΠΎΠΌΠ°Π½Π΄Π°. ΠΠ°ΠΏΠΈΡˆΠΈΡ‚Π΅ /help для списка ΠΊΠΎΠΌΠ°Π½Π΄."
468
+ )
469
+
470
+ if __name__ == "__main__":
471
+ bot.run_polling()
472
+ ```
473
+
474
+ ## API Reference
475
+
476
+ ### Bot
477
+
478
+ #### ΠœΠ΅Ρ‚ΠΎΠ΄Ρ‹ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ
479
+
480
+ | ΠœΠ΅Ρ‚ΠΎΠ΄ | ОписаниС |
481
+ |-------|----------|
482
+ | `send_message(chat_id, text, ...)` | Π£Π½ΠΈΠ²Π΅Ρ€ΡΠ°Π»ΡŒΠ½Ρ‹ΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ (тСкст/Ρ„Π°ΠΉΠ»Ρ‹) |
483
+ | `send_file(chat_id, file_path, caption, ...)` | ΠžΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ Ρ„Π°ΠΉΠ» |
484
+ | `send_photo(chat_id, photo, caption, ...)` | ΠžΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ Ρ„ΠΎΡ‚ΠΎ |
485
+ | `send_document(chat_id, document, caption, ...)` | ΠžΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ |
486
+
487
+ #### Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΊΠΎΠΌΠ½Π°Ρ‚Π°ΠΌΠΈ
488
+
489
+ | ΠœΠ΅Ρ‚ΠΎΠ΄ | ОписаниС |
490
+ |-------|----------|
491
+ | `join_room(chat_id, password)` | ΠŸΡ€ΠΈΡΠΎΠ΅Π΄ΠΈΠ½ΠΈΡ‚ΡŒΡΡ ΠΊ ΠΊΠΎΠΌΠ½Π°Ρ‚Π΅ |
492
+ | `get_rooms()` | ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ список всСх ΠΊΠΎΠΌΠ½Π°Ρ‚ |
493
+ | `get_room_info(chat_id)` | ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ ΠΊΠΎΠΌΠ½Π°Ρ‚Π΅ |
494
+ | `get_room_participants(chat_id)` | ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ список участников |
495
+
496
+ #### Диагностика
497
+
498
+ | ΠœΠ΅Ρ‚ΠΎΠ΄ | ОписаниС |
499
+ |-------|----------|
500
+ | `check_session_status()` | ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ статус сСссии |
501
+ | `diagnose_room_access(chat_id)` | Диагностика доступа ΠΊ ΠΊΠΎΠΌΠ½Π°Ρ‚Π΅ |
502
+
503
+ ### Message
504
+
505
+ | Атрибут/ΠœΠ΅Ρ‚ΠΎΠ΄ | ОписаниС |
506
+ |---------------|----------|
507
+ | `message_id` | ID сообщСния |
508
+ | `text` | ВСкст сообщСния |
509
+ | `from_user` | ΠžΠ±ΡŠΠ΅ΠΊΡ‚ User (ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚Π΅Π»ΡŒ) |
510
+ | `chat` | ΠžΠ±ΡŠΠ΅ΠΊΡ‚ Chat (ΠΊΠΎΠΌΠ½Π°Ρ‚Π°) |
511
+ | `date` | ВрСмя ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ |
512
+ | `reply_to_message` | ΠžΡ‚Π²Π΅Ρ‚ Π½Π° сообщСниС (Ссли Π΅ΡΡ‚ΡŒ) |
513
+ | `reply_text(text)` | ΠžΡ‚Π²Π΅Ρ‚ΠΈΡ‚ΡŒ Π½Π° сообщСниС |
514
+ | `reply(text)` | Алиас для reply_text |
515
+
516
+ ## УстранСниС Π½Π΅ΠΏΠΎΠ»Π°Π΄ΠΎΠΊ
517
+
518
+ ### Ошибка Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ
519
+
520
+ ```python
521
+ # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅
522
+ status = bot.check_session_status()
523
+ if not status['authenticated']:
524
+ print(f"Ошибка: {status.get('error')}")
525
+ print("ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ Π»ΠΎΠ³ΠΈΠ½ ΠΈ ΠΏΠ°Ρ€ΠΎΠ»ΡŒ/Ρ‚ΠΎΠΊΠ΅Π½")
526
+ ```
527
+
528
+ ### ΠšΠΎΠΌΠ½Π°Ρ‚Π° Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½Π°
529
+
530
+ ```python
531
+ # ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚Π΅ список доступных ΠΊΠΎΠΌΠ½Π°Ρ‚
532
+ rooms = bot.get_rooms()
533
+ print("ДоступныС ΠΊΠΎΠΌΠ½Π°Ρ‚Ρ‹:")
534
+ for room in rooms:
535
+ print(f" - {room.get('name')} (Ρ‚ΠΎΠΊΠ΅Π½: {room.get('token')})")
536
+ ```
537
+
538
+ ### ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ с ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΎΠΉ Ρ„Π°ΠΉΠ»ΠΎΠ²
539
+
540
+ ```python
541
+ # Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ диагностику
542
+ result = bot.diagnose_room_access("room_token")
543
+ print(json.dumps(result, indent=2))
544
+
545
+ # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ ΠΏΡ€Π°Π²Π° Π½Π° запись Π² WebDAV
546
+ # Π£Π±Π΅Π΄ΠΈΡ‚Π΅ΡΡŒ, Ρ‡Ρ‚ΠΎ Ρƒ Π±ΠΎΡ‚Π° Π΅ΡΡ‚ΡŒ ΠΏΡ€Π°Π²Π° Π½Π° Π·Π°Π³Ρ€ΡƒΠ·ΠΊΡƒ Ρ„Π°ΠΉΠ»ΠΎΠ²
547
+ ```
548
+
549
+ ## ЛицСнзия
550
+
551
+ MIT License
552
+
553
+ ## Π’ΠΊΠ»Π°Π΄ Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚
554
+
555
+ Π‘ΡƒΠ΄Ρƒ Ρ€Π°Π΄ вашим pull requests ΠΈ issue!
556
+
557
+ ## Бсылки
558
+
559
+ - [Nextcloud Talk API Documentation](https://nextcloud-talk.readthedocs.io/)
560
+ - [Nextcloud Developer Documentation](https://docs.nextcloud.com/server/latest/developer_manual/)