RubigramClient 1.6.8__py3-none-any.whl → 1.7.0__py3-none-any.whl

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.

Potentially problematic release.


This version of RubigramClient might be problematic. Click here for more details.

rubigram/rubino/client.py CHANGED
@@ -1,11 +1,16 @@
1
- from aiohttp import ClientSession
2
1
  from typing import Literal, Optional, Union, Any
2
+ from aiohttp import ClientSession, FormData
3
+ from urllib.parse import urlparse
3
4
  from random import randint
5
+ from pathlib import Path
6
+ from json import loads
7
+ import os
4
8
 
5
9
 
6
- class Rubino:
10
+ class Http:
7
11
  def __init__(self, auth: str):
8
12
  self.auth = auth
13
+ self.session: Optional[ClientSession] = None
9
14
  self.api = f"https://rubino{randint(1, 30)}.iranlms.ir"
10
15
  self.client = {
11
16
  "app_name": "Main",
@@ -15,8 +20,24 @@ class Rubino:
15
20
  "platform": "Android"
16
21
  }
17
22
 
18
-
19
- async def reauest(self, method: str, data: dict[str, Any]):
23
+ async def connect(self):
24
+ if self.session is None:
25
+ self.session = ClientSession()
26
+
27
+ async def disconnect(self):
28
+ if self.session:
29
+ await self.session.close()
30
+ self.session = None
31
+
32
+ async def __aenter__(self):
33
+ await self.connect()
34
+ return self
35
+
36
+ async def __aexit__(self, exc_type, exc_val, exc_tb):
37
+ await self.disconnect()
38
+
39
+ async def request(self, method: str, data: dict[str, Any]):
40
+ await self.connect()
20
41
  json = {
21
42
  "api_version": "0",
22
43
  "auth": self.auth,
@@ -24,52 +45,175 @@ class Rubino:
24
45
  "data": data,
25
46
  "method": method
26
47
  }
27
- async with ClientSession() as session:
28
- async with session.post(self.api, json=json) as response:
29
- response.raise_for_status()
30
- return await response.json()
48
+ async with self.session.post(self.api, json=json) as response:
49
+ response.raise_for_status()
50
+ return await response.json()
51
+
52
+ async def getBytes(self, url: str) -> bytes:
53
+ await self.connect()
54
+ async with self.session.get(url) as response:
55
+ response.raise_for_status()
56
+ return await response.read()
57
+
58
+ async def getName(self, url: str) -> str:
59
+ parser = urlparse(url)
60
+ return os.path.basename(parser.path)
61
+
62
+ async def request_upload_file(
63
+ self,
64
+ file_name: str,
65
+ file_size: str,
66
+ file_type: str,
67
+ profile_id: str,
68
+ ):
69
+ data = {
70
+ "file_name": file_name,
71
+ "file_size": file_size,
72
+ "file_type": file_type,
73
+ "profile_id": profile_id,
74
+ }
75
+ return await self.request("requestUploadFile", data)
76
+
77
+ async def requestUpload(
78
+ self,
79
+ file: str,
80
+ file_type: str,
81
+ file_name: Optional[str] = None,
82
+ profile_id: Optional[str] = None,
83
+ ):
84
+ path = Path(file)
85
+ if path.is_file():
86
+ data = path.read_bytes()
87
+ file_name = file_name if file_name else path.name
88
+ file_size = path.stat().st_size
89
+
90
+ elif file.startswith("http"):
91
+ data = await self.getBytes(file)
92
+ file_name = file_name if file_name else await self.getName(file)
93
+ file_size = len(data)
94
+
95
+ else:
96
+ raise Exception(f"Can't find this file : {file}")
97
+
98
+ request = await self.request_upload_file(file_name, file_size, file_type, profile_id)
99
+ request: dict[str, str] = request["data"]
100
+
101
+ file_id: str = request["file_id"]
102
+ hash_file_request: str = request["hash_file_request"]
103
+ server_url: str = request["server_url"]
104
+
105
+ headers = {
106
+ "auth": self.auth,
107
+ "chunk-size": str(file_size),
108
+ "file-id": file_id,
109
+ "hash-file-request": hash_file_request,
110
+ "content-length": str(file_size),
111
+ "part-number": "1",
112
+ "total-part": "1"
113
+ }
114
+ form = FormData()
115
+ form.add_field(
116
+ "file", data, filename=file_name, content_type="application/octet-stream"
117
+ )
118
+ async with self.session.post(server_url, data=form, headers=headers) as response:
119
+ text = await response.text()
120
+ hash_file_receive = loads(text)["data"]["hash_file_receive"]
121
+ return {"file_id": file_id, "hash_file_receive": hash_file_receive}
122
+
31
123
 
124
+ class Rubino(Http):
125
+ def __init__(self, auth: str):
126
+ super().__init__(auth)
32
127
 
128
+ def rnd(self):
129
+ return randint(100000, 999999999)
130
+
131
+ async def app_post(
132
+ self,
133
+ file: str,
134
+ caption: Optional[str] = None,
135
+ post_type: Literal["Picture", "Video"] = "Picture",
136
+ profile_id: Optional[str] = None,
137
+ file_name: Optional[str] = None,
138
+ is_multi_file: Optional[str] = None,
139
+ ):
140
+ request = await self.requestUpload(file, post_type, file_name, profile_id)
141
+ file_id, hash_file_receive = request["file_id"], request["hash_file_receive"]
142
+ data = {
143
+ "caption": caption,
144
+ "file_id": file_id,
145
+ "hash_file_receive": hash_file_receive,
146
+ "height": 800,
147
+ "width": 800,
148
+ "is_multi_file": is_multi_file,
149
+ "post_type": post_type,
150
+ "rnd": self.rnd(),
151
+ "thumbnail_file_id": file_id,
152
+ "thumbnail_hash_file_receive": hash_file_receive,
153
+ "profile_id": profile_id
154
+ }
155
+ return await self.request("addPost", data)
156
+
33
157
  async def get_post_by_share_link(self, post_link: str):
34
- return await self.reauest("getPostByShareLink", {"share_string": post_link.split("/")[-1]})
35
-
36
-
158
+ return await self.request("getPostByShareLink", {"share_string": post_link.split("/")[-1]})
159
+
37
160
  async def add_post_view_count(self, post_id: str, post_profile_id: str):
38
161
  data = {"post_id": post_id, "post_profile_id": post_profile_id}
39
- return await self.reauest("addPostViewCount", data)
40
-
41
-
162
+ return await self.request("addPostViewCount", data)
163
+
42
164
  async def add_view_story(self, story_profile_id: str, story_ids: Union[str, list[str]], profile_id: Optional[str] = None):
43
165
  story_ids = story_ids if isinstance(story_ids, list) else [story_ids]
44
- data = {"story_profile_id": story_profile_id, "story_ids": story_ids, "profile_id": profile_id}
45
- return await self.reauest("addViewStory", data)
46
-
47
-
166
+ data = {
167
+ "story_profile_id": story_profile_id,
168
+ "story_ids": story_ids,
169
+ "profile_id": profile_id
170
+ }
171
+ return await self.request("addViewStory", data)
172
+
48
173
  async def is_exist_username(self, username: str):
49
- username = username.replace("@", "")
50
- return await self.reauest("isExistUsername", {"username": username})
51
-
52
-
174
+ return await self.request("isExistUsername", {"username": username.replace("@", "")})
175
+
53
176
  async def create_page(self, username: str, name: str, bio: Optional[str] = None):
54
- return await self.reauest("createPage", {"username": username, "name": name, "bio": bio})
55
-
56
-
177
+ return await self.request("createPage", {"username": username, "name": name, "bio": bio})
178
+
57
179
  async def add_comment(self, content: str, post_id: str, post_profile_id: str, profile_id: Optional[str] = None):
58
- rnd = randint(100000, 999999999)
59
- data = {"content": content, "post_id": post_id, "post_profile_id": post_profile_id, "profile_id": profile_id, "rnd": rnd}
60
- return await self.reauest("addComment", data)
61
-
62
-
180
+ data = {
181
+ "content": content,
182
+ "post_id": post_id,
183
+ "post_profile_id": post_profile_id,
184
+ "profile_id": profile_id,
185
+ "rnd": self.rnd()
186
+ }
187
+ return await self.request("addComment", data)
188
+
63
189
  async def request_follow(self, followee_id: str, f_type: Literal["Follow", "Unfollow"] = "Follow", profile_id: Optional[str] = None):
64
- data = {"f_type": f_type, "followee_id": followee_id, "profile_id": profile_id}
65
- return self.reauest("requestFollow", data)
66
-
190
+ data = {
191
+ "f_type": f_type,
192
+ "followee_id": followee_id,
193
+ "profile_id": profile_id
194
+ }
195
+ return self.request("requestFollow", data)
67
196
 
197
+ async def follow(self, followee_id: str, profile_id: Optional[str] = None):
198
+ return await self.request_follow(followee_id, "Follow", profile_id)
199
+
200
+ async def unfollow(self, followee_id: str, profile_id: Optional[str] = None):
201
+ return await self.request_follow(followee_id, "Unfollow", profile_id)
202
+
68
203
  async def set_block_profile(self, block_id: str, action: Literal["Block", "Unblock"] = "Block", profile_id: Optional[str] = None):
69
- data = {"block_id": block_id, "action": action, "profile_id": profile_id}
70
- return self.reauest("setBlockProfile", data)
71
-
204
+ data = {
205
+ "block_id": block_id,
206
+ "action": action,
207
+ "profile_id": profile_id
208
+ }
209
+ return self.request("setBlockProfile", data)
210
+
211
+ async def block_profile(self, block_id: str, profile_id: Optional[str] = None):
212
+ return await self.set_block_profile(block_id, "Block", profile_id)
72
213
 
214
+ async def unblock_profile(self, block_id: str, profile_id: Optional[str] = None):
215
+ return await self.set_block_profile(block_id, "Unblock", profile_id)
216
+
73
217
  async def get_comments(self, post_id: str, post_profile_id: str, limit: Optional[int] = 100, profile_id: Optional[str] = None):
74
218
  data = {
75
219
  "post_id": post_id,
@@ -79,4 +223,258 @@ class Rubino:
79
223
  "equal": False,
80
224
  "sort": "FromMax"
81
225
  }
82
- return await self.reauest("getComments", data)
226
+ return await self.request("getComments", data)
227
+
228
+ async def get_my_profile_info(self, profile_id: Optional[str] = None):
229
+ return await self.request("getMyProfileInfo", {"profile_id": profile_id})
230
+
231
+ async def get_profile_list(self, limit: Optional[int] = 10):
232
+ data = {
233
+ "limit": limit,
234
+ "equal": False,
235
+ "sort": "FromMax"
236
+ }
237
+ return await self.request("getProfileList", data)
238
+
239
+ async def get_profile_stories(self, profile_id: Optional[str] = None, limit: Optional[int] = 10):
240
+ return self.request("getProfileStories", {"limit": limit, "profile_id": profile_id})
241
+
242
+ async def get_recent_following_posts(self, profile_id: Optional[str] = None, limit: Optional[int] = 10):
243
+ data = {
244
+ "limit": limit,
245
+ "equal": False,
246
+ "sort": "FromMax",
247
+ "profile_id": profile_id
248
+ }
249
+ return await self.request("getRecentFollowingPosts", data)
250
+
251
+ async def get_share_link(self, post_id: str, target_profile_id: str, profile_id: Optional[str] = None):
252
+ return await self.request("getShareLink", {"post_id": post_id, "target_profile_id": target_profile_id, "profile_id": profile_id})
253
+
254
+ async def get_story_id(self, post_profile_id: str, profile_id: Optional[str] = None):
255
+ return await self.request("getStoryIds", {"post_profile_id": post_profile_id, "profile_id": profile_id})
256
+
257
+ async def save_post(self, post_id: str, target_profile_id: str, profile_id: Optional[str] = None):
258
+ data = {
259
+ "action_type": "Bookmark",
260
+ "post_id": post_id,
261
+ "target_profile_id": target_profile_id,
262
+ "profile_id": profile_id
263
+ }
264
+ return await self.request("postBookmarkAction", data)
265
+
266
+ async def unsave_post(self, post_id: str, post_profile_id: str, profile_id: Optional[str] = None):
267
+ data = {
268
+ "action_type": "Unbookmark",
269
+ "post_id": post_id,
270
+ "post_profile_id": post_profile_id,
271
+ "profile_id": profile_id
272
+ }
273
+ return await self.request("postBookmarkAction", data)
274
+
275
+ async def update_profile(self, profile_id: Optional[str] = None):
276
+ data = {
277
+ "profile_id": profile_id,
278
+ "profile_status": "Public"
279
+ }
280
+ return await self.request("updateProfile", data)
281
+
282
+ async def like_post(self, post_id: str, target_profile_id: str, profile_id: Optional[str] = None):
283
+ data = {
284
+ "action_type": "Like",
285
+ "post_id": post_id,
286
+ "target_profile_id": target_profile_id,
287
+ "profile_id": profile_id
288
+ }
289
+ return await self.request("likePostAction", data)
290
+
291
+ async def unlike_post(self, post_id: str, target_profile_id: str, profile_id: Optional[str] = None):
292
+ data = {
293
+ "action_type": "Unlike",
294
+ "post_id": post_id,
295
+ "target_profile_id": target_profile_id,
296
+ "profile_id": profile_id
297
+ }
298
+ return await self.request("likePostAction", data)
299
+
300
+ async def like_comment(self, comment_id: str, post_id: str, profile_id: Optional[str] = None):
301
+ data = {
302
+ "action_type": "Like",
303
+ "comment_id": comment_id,
304
+ "post_id": post_id,
305
+ "profile_id": profile_id
306
+ }
307
+ return await self.request("likeCommentAction", data)
308
+
309
+ async def unlike_comment(self, comment_id: str, post_id: str, profile_id: Optional[str] = None):
310
+ data = {
311
+ "action_type": "Unlike",
312
+ "comment_id": comment_id,
313
+ "post_id": post_id,
314
+ "profile_id": profile_id
315
+ }
316
+ return await self.request("likeCommentAction", data)
317
+
318
+ async def get_saved_posts(self, limit: int = 10, profile_id: Optional[str] = None):
319
+ data = {
320
+ "equal": False,
321
+ "limit": limit,
322
+ "sort": "FromMax",
323
+ "profile_id": profile_id
324
+ }
325
+ return await self.request("getBookmarkedPosts", data)
326
+
327
+ async def get_archive_stories(self, limit: int = 10, start_id: Optional[str] = None, profile_id: Optional[str] = None):
328
+ data = {
329
+ "equal": False,
330
+ "limit": limit,
331
+ "start_id": start_id,
332
+ "sort": "FromMax",
333
+ "profile_id": profile_id
334
+ }
335
+ return await self.request("getMyArchiveStories", data)
336
+
337
+ async def get_profile_highlights(self, target_profile_id: str, limit: int = 10, profile_id: Optional[str] = None):
338
+ data = {
339
+ "equal": False,
340
+ "limit": limit,
341
+ "sort": "FromMax",
342
+ "target_profile_id": target_profile_id,
343
+ "profile_id": profile_id
344
+ }
345
+ return await self.request("getProfileHighlights", data)
346
+
347
+ async def get_blocked_profiles(self, limit: int = 50, max_id: Optional[str] = None, profile_id: Optional[str] = None):
348
+ data = {
349
+ "equal": False,
350
+ "limit": limit,
351
+ "max_id": max_id,
352
+ "sort": "FromMax",
353
+ "profile_id": profile_id
354
+ }
355
+ return await self.request("getBlockedProfiles", data)
356
+
357
+ async def get_profile_following(self, target_profile_id: str, limit: int = 50, profile_id: Optional[str] = None):
358
+ data = {
359
+ "equal": False,
360
+ "f_type": "Following",
361
+ "limit": limit,
362
+ "sort": "FromMax",
363
+ "target_profile_id": target_profile_id,
364
+ "profile_id": profile_id
365
+ }
366
+ return await self.request("getProfileFollowers", data)
367
+
368
+ async def get_profile_followers(self, target_profile_id: str, limit: int = 50, profile_id: Optional[str] = None):
369
+ data = {
370
+ "equal": False,
371
+ "f_type": "Follower",
372
+ "limit": limit,
373
+ "sort": "FromMax",
374
+ "target_profile_id": target_profile_id,
375
+ "profile_id": profile_id
376
+ }
377
+ return await self.request("getProfileFollowers", data)
378
+
379
+ async def get_my_stories_list(self, limit: Optional[int] = None, profile_id: Optional[str] = None):
380
+ data = {
381
+ "limit": limit,
382
+ "profile_id": profile_id
383
+ }
384
+ return await self.request("getMyStoriesList", data)
385
+
386
+ async def delete_story(self, story_id: str, profile_id: Optional[str] = None):
387
+ data = {
388
+ "profile_id": profile_id,
389
+ "story_id": story_id
390
+ }
391
+ return await self.request("deleteStory", data)
392
+
393
+ async def get_explore_posts(self, topic_id: str, limit: int = 50, max_id: Optional[str] = None, profile_id: Optional[str] = None):
394
+ data = {
395
+ "equal": False,
396
+ "limit": limit,
397
+ "max_id": max_id,
398
+ "sort": "FromMax",
399
+ "topic_id": topic_id,
400
+ "profile_id": profile_id
401
+ }
402
+ return await self.request("getExplorePosts", data)
403
+
404
+ async def search_profile(self, username: str, limit: int = 50, profile_id: Optional[str] = None):
405
+ data = {
406
+ "equal": False,
407
+ "limit": limit,
408
+ "sort": "FromMax",
409
+ "username": username.replace("@", ""),
410
+ "profile_id": profile_id
411
+ }
412
+ return await self.request("searchProfile", data)
413
+
414
+ async def search_in_rubino(self, username: str, limit: int = 50, profile_id: Optional[str] = None):
415
+ data = {
416
+ "equal": False,
417
+ "limit": limit,
418
+ "sort": "FromMax",
419
+ "username": username.startswith("@"),
420
+ "profile_id": profile_id
421
+ }
422
+ return await self.request("searchProfile", data)
423
+
424
+ async def get_hashtag_trend(self, limit: int = 50, profile_id: Optional[str] = None):
425
+ data = {
426
+ "equal": False,
427
+ "limit": limit,
428
+ "sort": "FromMax",
429
+ "profile_id": profile_id
430
+ }
431
+ return await self.request("getHashTagTrend", data)
432
+
433
+ async def search_hashtag(self, content: str, limit: int = 50, profile_id: Optional[str] = None):
434
+ data = {
435
+ "content": content,
436
+ "equal": False,
437
+ "limit": limit,
438
+ "sort": "FromMax",
439
+ "profile_id": profile_id
440
+ }
441
+ return await self.request("searchHashTag", data)
442
+
443
+ async def get_posts_by_hashtag(self, hashtag: str, limit: int = 50, profile_id: Optional[str] = None):
444
+ data = {
445
+ "equal": False,
446
+ "hashtag": hashtag,
447
+ "limit": limit,
448
+ "profile_id": profile_id
449
+ }
450
+ return await self.request("getPostsByHashTag", data)
451
+
452
+ async def remove_page(self, profile_id: str, record_id: str):
453
+ data = {
454
+ "model": "Profile",
455
+ "record_id": record_id,
456
+ "profile_id": profile_id
457
+ }
458
+ return await self.request("removeRecord", data)
459
+
460
+ async def get_new_follow_requests(self, profile_id: Optional[str] = None, limit: Optional[int] = 20):
461
+ data = {
462
+ "profile_id": profile_id,
463
+ "limit": limit,
464
+ "sort": "FromMax"
465
+ }
466
+ return await self.request("getNewFollowRequests", data)
467
+
468
+ async def action_on_request(self, request_id: str, profile_id: Optional[str] = None, action: Literal["Accept", "Decline"] = "Accept"):
469
+ data = {
470
+ "action": action,
471
+ "request_id": request_id,
472
+ "profile_id": profile_id
473
+ }
474
+ return await self.request("actionOnRequest", data)
475
+
476
+ async def accept_request(self, request_id: str, profile_id: Optional[str] = None):
477
+ return await self.action_on_request(request_id, profile_id)
478
+
479
+ async def reject_request(self, request_id: str, profile_id: Optional[str] = None):
480
+ return await self.action_on_request(request_id, profile_id, "Decline")