marqetive-lib 0.1.2__py3-none-any.whl → 0.1.3__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.
- marqetive/__init__.py +13 -13
- marqetive/core/__init__.py +1 -1
- marqetive/core/account_factory.py +2 -2
- marqetive/core/base_manager.py +4 -4
- marqetive/core/registry.py +3 -3
- marqetive/platforms/__init__.py +6 -6
- marqetive/platforms/base.py +3 -3
- marqetive/platforms/instagram/__init__.py +3 -3
- marqetive/platforms/instagram/client.py +4 -4
- marqetive/platforms/instagram/exceptions.py +1 -1
- marqetive/platforms/instagram/factory.py +5 -5
- marqetive/platforms/instagram/manager.py +4 -4
- marqetive/platforms/instagram/media.py +2 -2
- marqetive/platforms/linkedin/__init__.py +3 -3
- marqetive/platforms/linkedin/client.py +4 -4
- marqetive/platforms/linkedin/exceptions.py +1 -1
- marqetive/platforms/linkedin/factory.py +5 -5
- marqetive/platforms/linkedin/manager.py +4 -4
- marqetive/platforms/linkedin/media.py +4 -4
- marqetive/platforms/tiktok/__init__.py +3 -3
- marqetive/platforms/tiktok/client.py +319 -104
- marqetive/platforms/tiktok/exceptions.py +170 -66
- marqetive/platforms/tiktok/factory.py +5 -5
- marqetive/platforms/tiktok/manager.py +5 -5
- marqetive/platforms/tiktok/media.py +547 -159
- marqetive/platforms/twitter/__init__.py +3 -3
- marqetive/platforms/twitter/client.py +7 -53
- marqetive/platforms/twitter/exceptions.py +1 -1
- marqetive/platforms/twitter/factory.py +5 -6
- marqetive/platforms/twitter/manager.py +4 -4
- marqetive/platforms/twitter/media.py +4 -4
- marqetive/registry_init.py +10 -8
- marqetive/utils/__init__.py +3 -3
- marqetive/utils/file_handlers.py +1 -1
- marqetive/utils/oauth.py +2 -2
- marqetive/utils/token_validator.py +1 -1
- {marqetive_lib-0.1.2.dist-info → marqetive_lib-0.1.3.dist-info}/METADATA +1 -1
- marqetive_lib-0.1.3.dist-info/RECORD +47 -0
- marqetive/platforms/twitter/threads.py +0 -442
- marqetive_lib-0.1.2.dist-info/RECORD +0 -48
- {marqetive_lib-0.1.2.dist-info → marqetive_lib-0.1.3.dist-info}/WHEEL +0 -0
|
@@ -1,442 +0,0 @@
|
|
|
1
|
-
"""Twitter thread creation and management.
|
|
2
|
-
|
|
3
|
-
This module provides utilities for creating and managing Twitter threads
|
|
4
|
-
(sequences of connected tweets).
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
from dataclasses import dataclass
|
|
8
|
-
from typing import Any
|
|
9
|
-
|
|
10
|
-
import tweepy
|
|
11
|
-
|
|
12
|
-
from src.marqetive.platforms.exceptions import PlatformError, ValidationError
|
|
13
|
-
from src.marqetive.platforms.models import Post, PostStatus
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
@dataclass
|
|
17
|
-
class TweetData:
|
|
18
|
-
"""Data for a single tweet in a thread.
|
|
19
|
-
|
|
20
|
-
Attributes:
|
|
21
|
-
content: Tweet text content (max 280 characters).
|
|
22
|
-
media_ids: List of Twitter media IDs to attach.
|
|
23
|
-
alt_texts: Optional alt texts for media (same order as media_ids).
|
|
24
|
-
"""
|
|
25
|
-
|
|
26
|
-
content: str
|
|
27
|
-
media_ids: list[str] | None = None
|
|
28
|
-
alt_texts: list[str] | None = None
|
|
29
|
-
|
|
30
|
-
def __post_init__(self) -> None:
|
|
31
|
-
"""Validate tweet data after initialization."""
|
|
32
|
-
# Validate content length
|
|
33
|
-
if not self.content:
|
|
34
|
-
raise ValidationError(
|
|
35
|
-
"Tweet content cannot be empty",
|
|
36
|
-
platform="twitter",
|
|
37
|
-
field="content",
|
|
38
|
-
)
|
|
39
|
-
|
|
40
|
-
if len(self.content) > 280:
|
|
41
|
-
raise ValidationError(
|
|
42
|
-
f"Tweet exceeds 280 characters ({len(self.content)} characters)",
|
|
43
|
-
platform="twitter",
|
|
44
|
-
field="content",
|
|
45
|
-
)
|
|
46
|
-
|
|
47
|
-
# Validate media count (Twitter allows max 4 images or 1 video per tweet)
|
|
48
|
-
if self.media_ids and len(self.media_ids) > 4:
|
|
49
|
-
raise ValidationError(
|
|
50
|
-
f"Too many media attachments ({len(self.media_ids)}). "
|
|
51
|
-
"Twitter allows maximum 4 images or 1 video per tweet.",
|
|
52
|
-
platform="twitter",
|
|
53
|
-
field="media_ids",
|
|
54
|
-
)
|
|
55
|
-
|
|
56
|
-
# Validate alt texts match media count
|
|
57
|
-
if self.alt_texts:
|
|
58
|
-
if not self.media_ids:
|
|
59
|
-
raise ValidationError(
|
|
60
|
-
"Cannot provide alt_texts without media_ids",
|
|
61
|
-
platform="twitter",
|
|
62
|
-
field="alt_texts",
|
|
63
|
-
)
|
|
64
|
-
if len(self.alt_texts) != len(self.media_ids):
|
|
65
|
-
raise ValidationError(
|
|
66
|
-
f"Number of alt_texts ({len(self.alt_texts)}) must match "
|
|
67
|
-
f"number of media_ids ({len(self.media_ids)})",
|
|
68
|
-
platform="twitter",
|
|
69
|
-
field="alt_texts",
|
|
70
|
-
)
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
@dataclass
|
|
74
|
-
class ThreadResult:
|
|
75
|
-
"""Result of creating a Twitter thread.
|
|
76
|
-
|
|
77
|
-
Attributes:
|
|
78
|
-
thread_id: ID of the first tweet in the thread.
|
|
79
|
-
tweet_ids: List of all tweet IDs in order.
|
|
80
|
-
tweets: List of Post objects for each tweet.
|
|
81
|
-
total_tweets: Total number of tweets in the thread.
|
|
82
|
-
"""
|
|
83
|
-
|
|
84
|
-
thread_id: str
|
|
85
|
-
tweet_ids: list[str]
|
|
86
|
-
tweets: list[Post]
|
|
87
|
-
|
|
88
|
-
@property
|
|
89
|
-
def total_tweets(self) -> int:
|
|
90
|
-
"""Get total number of tweets in thread."""
|
|
91
|
-
return len(self.tweet_ids)
|
|
92
|
-
|
|
93
|
-
def __str__(self) -> str:
|
|
94
|
-
"""String representation of thread result."""
|
|
95
|
-
return (
|
|
96
|
-
f"Thread(id={self.thread_id}, "
|
|
97
|
-
f"tweets={self.total_tweets}, "
|
|
98
|
-
f"ids={self.tweet_ids})"
|
|
99
|
-
)
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
class TwitterThreadManager:
|
|
103
|
-
"""Manager for creating and managing Twitter threads.
|
|
104
|
-
|
|
105
|
-
Example:
|
|
106
|
-
>>> manager = TwitterThreadManager(tweepy_client)
|
|
107
|
-
>>> tweets = [
|
|
108
|
-
... TweetData("First tweet in thread"),
|
|
109
|
-
... TweetData("Second tweet with more info"),
|
|
110
|
-
... TweetData("Final tweet with conclusion"),
|
|
111
|
-
... ]
|
|
112
|
-
>>> result = await manager.create_thread(tweets)
|
|
113
|
-
>>> print(f"Created thread: {result.thread_id}")
|
|
114
|
-
"""
|
|
115
|
-
|
|
116
|
-
def __init__(self, tweepy_client: tweepy.Client) -> None:
|
|
117
|
-
"""Initialize thread manager.
|
|
118
|
-
|
|
119
|
-
Args:
|
|
120
|
-
tweepy_client: Authenticated tweepy Client instance.
|
|
121
|
-
"""
|
|
122
|
-
self.client = tweepy_client
|
|
123
|
-
|
|
124
|
-
async def create_thread(
|
|
125
|
-
self,
|
|
126
|
-
tweets: list[TweetData],
|
|
127
|
-
*,
|
|
128
|
-
auto_number: bool = False,
|
|
129
|
-
number_format: str = "{index}/{total}",
|
|
130
|
-
) -> ThreadResult:
|
|
131
|
-
"""Create a Twitter thread from multiple tweets.
|
|
132
|
-
|
|
133
|
-
Args:
|
|
134
|
-
tweets: List of TweetData objects representing the thread.
|
|
135
|
-
auto_number: If True, automatically add tweet numbers to content.
|
|
136
|
-
number_format: Format string for auto-numbering (supports {index}, {total}).
|
|
137
|
-
|
|
138
|
-
Returns:
|
|
139
|
-
ThreadResult with thread ID and all tweet information.
|
|
140
|
-
|
|
141
|
-
Raises:
|
|
142
|
-
ValidationError: If thread data is invalid.
|
|
143
|
-
PlatformError: If thread creation fails.
|
|
144
|
-
|
|
145
|
-
Example:
|
|
146
|
-
>>> tweets = [
|
|
147
|
-
... TweetData("Part 1: Introduction"),
|
|
148
|
-
... TweetData("Part 2: Details"),
|
|
149
|
-
... TweetData("Part 3: Conclusion"),
|
|
150
|
-
... ]
|
|
151
|
-
>>> result = await manager.create_thread(tweets, auto_number=True)
|
|
152
|
-
"""
|
|
153
|
-
if not tweets:
|
|
154
|
-
raise ValidationError(
|
|
155
|
-
"Thread must contain at least one tweet",
|
|
156
|
-
platform="twitter",
|
|
157
|
-
field="tweets",
|
|
158
|
-
)
|
|
159
|
-
|
|
160
|
-
if len(tweets) > 25:
|
|
161
|
-
raise ValidationError(
|
|
162
|
-
f"Thread too long ({len(tweets)} tweets). "
|
|
163
|
-
"Consider splitting into multiple threads.",
|
|
164
|
-
platform="twitter",
|
|
165
|
-
field="tweets",
|
|
166
|
-
)
|
|
167
|
-
|
|
168
|
-
thread_id: str | None = None
|
|
169
|
-
tweet_ids: list[str] = []
|
|
170
|
-
post_objects: list[Post] = []
|
|
171
|
-
previous_tweet_id: str | None = None
|
|
172
|
-
|
|
173
|
-
try:
|
|
174
|
-
for index, tweet_data in enumerate(tweets, start=1):
|
|
175
|
-
# Prepare tweet content
|
|
176
|
-
content = tweet_data.content
|
|
177
|
-
|
|
178
|
-
# Add auto-numbering if requested
|
|
179
|
-
if auto_number and len(tweets) > 1:
|
|
180
|
-
number_prefix = number_format.format(
|
|
181
|
-
index=index,
|
|
182
|
-
total=len(tweets),
|
|
183
|
-
)
|
|
184
|
-
content = f"{number_prefix} {content}"
|
|
185
|
-
|
|
186
|
-
# Validate length after numbering
|
|
187
|
-
if len(content) > 280:
|
|
188
|
-
raise ValidationError(
|
|
189
|
-
f"Tweet {index} exceeds 280 characters after auto-numbering "
|
|
190
|
-
f"({len(content)} characters). Consider shorter content or "
|
|
191
|
-
"disable auto_number.",
|
|
192
|
-
platform="twitter",
|
|
193
|
-
field="content",
|
|
194
|
-
)
|
|
195
|
-
|
|
196
|
-
# Prepare tweet parameters
|
|
197
|
-
tweet_params: dict[str, Any] = {"text": content}
|
|
198
|
-
|
|
199
|
-
# Add reply-to for threading
|
|
200
|
-
if previous_tweet_id:
|
|
201
|
-
tweet_params["in_reply_to_tweet_id"] = previous_tweet_id
|
|
202
|
-
|
|
203
|
-
# Add media if provided
|
|
204
|
-
if tweet_data.media_ids:
|
|
205
|
-
tweet_params["media_ids"] = tweet_data.media_ids
|
|
206
|
-
|
|
207
|
-
# Create tweet
|
|
208
|
-
response = self.client.create_tweet(**tweet_params)
|
|
209
|
-
tweet_id = str(response.data["id"]) # type: ignore[index]
|
|
210
|
-
|
|
211
|
-
# Store IDs
|
|
212
|
-
if thread_id is None:
|
|
213
|
-
thread_id = tweet_id
|
|
214
|
-
tweet_ids.append(tweet_id)
|
|
215
|
-
previous_tweet_id = tweet_id
|
|
216
|
-
|
|
217
|
-
# Fetch full tweet details
|
|
218
|
-
tweet_response = self.client.get_tweet(
|
|
219
|
-
tweet_id,
|
|
220
|
-
tweet_fields=[
|
|
221
|
-
"created_at",
|
|
222
|
-
"public_metrics",
|
|
223
|
-
"attachments",
|
|
224
|
-
"author_id",
|
|
225
|
-
],
|
|
226
|
-
)
|
|
227
|
-
|
|
228
|
-
# Convert to Post object
|
|
229
|
-
tweet = tweet_response.data # type: ignore[attr-defined]
|
|
230
|
-
post = Post(
|
|
231
|
-
post_id=tweet_id,
|
|
232
|
-
platform="twitter",
|
|
233
|
-
content=content,
|
|
234
|
-
status=PostStatus.PUBLISHED,
|
|
235
|
-
created_at=tweet.created_at,
|
|
236
|
-
author_id=str(tweet.author_id) if tweet.author_id else None,
|
|
237
|
-
raw_data=tweet.data,
|
|
238
|
-
)
|
|
239
|
-
post_objects.append(post)
|
|
240
|
-
|
|
241
|
-
except tweepy.TweepyException as e:
|
|
242
|
-
# If thread creation fails partway through, we have partial thread
|
|
243
|
-
# Log the created tweets for cleanup if needed
|
|
244
|
-
if tweet_ids:
|
|
245
|
-
raise PlatformError(
|
|
246
|
-
f"Thread creation failed at tweet {len(tweet_ids) + 1}. "
|
|
247
|
-
f"Partial thread created with IDs: {tweet_ids}. "
|
|
248
|
-
f"Error: {e}",
|
|
249
|
-
platform="twitter",
|
|
250
|
-
) from e
|
|
251
|
-
raise PlatformError(
|
|
252
|
-
f"Failed to create thread: {e}",
|
|
253
|
-
platform="twitter",
|
|
254
|
-
) from e
|
|
255
|
-
|
|
256
|
-
if not thread_id:
|
|
257
|
-
raise PlatformError(
|
|
258
|
-
"Thread creation completed but no thread ID available",
|
|
259
|
-
platform="twitter",
|
|
260
|
-
)
|
|
261
|
-
|
|
262
|
-
return ThreadResult(
|
|
263
|
-
thread_id=thread_id,
|
|
264
|
-
tweet_ids=tweet_ids,
|
|
265
|
-
tweets=post_objects,
|
|
266
|
-
)
|
|
267
|
-
|
|
268
|
-
async def delete_thread(
|
|
269
|
-
self,
|
|
270
|
-
thread_id: str,
|
|
271
|
-
tweet_ids: list[str],
|
|
272
|
-
*,
|
|
273
|
-
continue_on_error: bool = True,
|
|
274
|
-
) -> dict[str, bool]:
|
|
275
|
-
"""Delete all tweets in a thread.
|
|
276
|
-
|
|
277
|
-
Args:
|
|
278
|
-
thread_id: ID of the first tweet (for logging).
|
|
279
|
-
tweet_ids: List of all tweet IDs to delete.
|
|
280
|
-
continue_on_error: If True, continue deleting even if some fail.
|
|
281
|
-
|
|
282
|
-
Returns:
|
|
283
|
-
Dictionary mapping tweet_id to deletion success status.
|
|
284
|
-
|
|
285
|
-
Example:
|
|
286
|
-
>>> result = await manager.delete_thread(
|
|
287
|
-
... thread_id="123",
|
|
288
|
-
... tweet_ids=["123", "456", "789"]
|
|
289
|
-
... )
|
|
290
|
-
>>> print(f"Deleted: {sum(result.values())} / {len(result)} tweets")
|
|
291
|
-
"""
|
|
292
|
-
results: dict[str, bool] = {}
|
|
293
|
-
errors: list[str] = []
|
|
294
|
-
|
|
295
|
-
# Delete in reverse order (newest to oldest)
|
|
296
|
-
for tweet_id in reversed(tweet_ids):
|
|
297
|
-
try:
|
|
298
|
-
self.client.delete_tweet(tweet_id)
|
|
299
|
-
results[tweet_id] = True
|
|
300
|
-
except tweepy.TweepyException as e:
|
|
301
|
-
results[tweet_id] = False
|
|
302
|
-
errors.append(f"Tweet {tweet_id}: {e}")
|
|
303
|
-
|
|
304
|
-
if not continue_on_error:
|
|
305
|
-
raise PlatformError(
|
|
306
|
-
f"Failed to delete tweet {tweet_id} in thread {thread_id}: {e}",
|
|
307
|
-
platform="twitter",
|
|
308
|
-
) from e
|
|
309
|
-
|
|
310
|
-
# If there were errors but continue_on_error=True, log them
|
|
311
|
-
if errors:
|
|
312
|
-
error_summary = "; ".join(errors)
|
|
313
|
-
raise PlatformError(
|
|
314
|
-
f"Some tweets in thread {thread_id} failed to delete: {error_summary}",
|
|
315
|
-
platform="twitter",
|
|
316
|
-
)
|
|
317
|
-
|
|
318
|
-
return results
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
def split_content_into_tweets(
|
|
322
|
-
content: str,
|
|
323
|
-
*,
|
|
324
|
-
max_length: int = 280,
|
|
325
|
-
split_on_sentences: bool = True,
|
|
326
|
-
add_continuation: bool = True,
|
|
327
|
-
continuation_suffix: str = "...",
|
|
328
|
-
) -> list[str]:
|
|
329
|
-
"""Split long content into multiple tweet-sized chunks.
|
|
330
|
-
|
|
331
|
-
Attempts to split on sentence boundaries when possible.
|
|
332
|
-
|
|
333
|
-
Args:
|
|
334
|
-
content: Long text content to split.
|
|
335
|
-
max_length: Maximum characters per tweet (default: 280).
|
|
336
|
-
split_on_sentences: Try to split on sentence boundaries.
|
|
337
|
-
add_continuation: Add continuation indicator to split tweets.
|
|
338
|
-
continuation_suffix: Suffix to add when splitting mid-content.
|
|
339
|
-
|
|
340
|
-
Returns:
|
|
341
|
-
List of tweet content strings.
|
|
342
|
-
|
|
343
|
-
Example:
|
|
344
|
-
>>> long_text = "This is a very long piece of content..." * 20
|
|
345
|
-
>>> tweets = split_content_into_tweets(long_text)
|
|
346
|
-
>>> print(f"Split into {len(tweets)} tweets")
|
|
347
|
-
"""
|
|
348
|
-
if len(content) <= max_length:
|
|
349
|
-
return [content]
|
|
350
|
-
|
|
351
|
-
tweets: list[str] = []
|
|
352
|
-
remaining = content
|
|
353
|
-
|
|
354
|
-
while remaining:
|
|
355
|
-
# Calculate available space
|
|
356
|
-
available = max_length
|
|
357
|
-
if add_continuation and len(remaining) > max_length:
|
|
358
|
-
available -= len(continuation_suffix)
|
|
359
|
-
|
|
360
|
-
if len(remaining) <= available:
|
|
361
|
-
# Last chunk
|
|
362
|
-
tweets.append(remaining)
|
|
363
|
-
break
|
|
364
|
-
|
|
365
|
-
# Find split point
|
|
366
|
-
split_point = available
|
|
367
|
-
|
|
368
|
-
if split_on_sentences:
|
|
369
|
-
# Try to split on sentence boundary
|
|
370
|
-
sentence_ends = [". ", "! ", "? ", ".\n", "!\n", "?\n"]
|
|
371
|
-
best_split = 0
|
|
372
|
-
|
|
373
|
-
for sent_end in sentence_ends:
|
|
374
|
-
pos = remaining[:available].rfind(sent_end)
|
|
375
|
-
if pos > best_split:
|
|
376
|
-
best_split = pos + len(sent_end)
|
|
377
|
-
|
|
378
|
-
if best_split > 0:
|
|
379
|
-
split_point = best_split
|
|
380
|
-
else:
|
|
381
|
-
# Try to split on word boundary
|
|
382
|
-
last_space = remaining[:available].rfind(" ")
|
|
383
|
-
if last_space > 0:
|
|
384
|
-
split_point = last_space + 1
|
|
385
|
-
|
|
386
|
-
# Extract chunk
|
|
387
|
-
chunk = remaining[:split_point].rstrip()
|
|
388
|
-
|
|
389
|
-
# Add continuation indicator if not at end
|
|
390
|
-
if add_continuation and len(remaining) > split_point:
|
|
391
|
-
chunk += continuation_suffix
|
|
392
|
-
|
|
393
|
-
tweets.append(chunk)
|
|
394
|
-
remaining = remaining[split_point:].lstrip()
|
|
395
|
-
|
|
396
|
-
return tweets
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
def create_numbered_thread(
|
|
400
|
-
content_parts: list[str],
|
|
401
|
-
*,
|
|
402
|
-
number_format: str = "{index}/{total}",
|
|
403
|
-
media_per_tweet: list[list[str]] | None = None,
|
|
404
|
-
) -> list[TweetData]:
|
|
405
|
-
"""Create a numbered thread from content parts.
|
|
406
|
-
|
|
407
|
-
Convenience function to create TweetData with auto-numbering.
|
|
408
|
-
|
|
409
|
-
Args:
|
|
410
|
-
content_parts: List of content strings, one per tweet.
|
|
411
|
-
number_format: Format string for numbering.
|
|
412
|
-
media_per_tweet: Optional list of media ID lists, one per tweet.
|
|
413
|
-
|
|
414
|
-
Returns:
|
|
415
|
-
List of TweetData objects ready for thread creation.
|
|
416
|
-
|
|
417
|
-
Example:
|
|
418
|
-
>>> parts = ["Introduction", "Main content", "Conclusion"]
|
|
419
|
-
>>> tweets = create_numbered_thread(parts)
|
|
420
|
-
>>> # Tweets will be: "1/3 Introduction", "2/3 Main content", "3/3 Conclusion"
|
|
421
|
-
"""
|
|
422
|
-
total = len(content_parts)
|
|
423
|
-
tweet_data_list: list[TweetData] = []
|
|
424
|
-
|
|
425
|
-
for index, content in enumerate(content_parts, start=1):
|
|
426
|
-
# Add number prefix
|
|
427
|
-
number_prefix = number_format.format(index=index, total=total)
|
|
428
|
-
numbered_content = f"{number_prefix} {content}"
|
|
429
|
-
|
|
430
|
-
# Get media for this tweet if provided
|
|
431
|
-
media_ids = None
|
|
432
|
-
if media_per_tweet and index - 1 < len(media_per_tweet):
|
|
433
|
-
media_ids = media_per_tweet[index - 1]
|
|
434
|
-
|
|
435
|
-
tweet_data_list.append(
|
|
436
|
-
TweetData(
|
|
437
|
-
content=numbered_content,
|
|
438
|
-
media_ids=media_ids,
|
|
439
|
-
)
|
|
440
|
-
)
|
|
441
|
-
|
|
442
|
-
return tweet_data_list
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
marqetive/__init__.py,sha256=XVnYmB817AILAnJYg1WVNnmrd1MvJns3QpPbfdjmwRE,3142
|
|
2
|
-
marqetive/core/__init__.py,sha256=5Wgcby-EQkTxrPVD4so69nBmZ66Ng9JGqBov4RQMT4A,117
|
|
3
|
-
marqetive/core/account_factory.py,sha256=9fsP6fzLYp3UGU59fkxwURgzn7eBxr8-WJt3aP-Z65U,7153
|
|
4
|
-
marqetive/core/base_manager.py,sha256=z28bV4p1FC7s9g_YkXIKW_qkv8bjF4tMoF-cGGksJuA,10047
|
|
5
|
-
marqetive/core/client.py,sha256=2_FoNpqaRglsWg10i5RTbyDg_kRQKhgWjYs6iDdFxLg,3210
|
|
6
|
-
marqetive/core/progress.py,sha256=5Vyksf8YfQUVRudwDEuegcxoc0js5qbHM2SFZ6VLxHM,8593
|
|
7
|
-
marqetive/core/registry.py,sha256=D6qlafpvemYfE9GouWcWZyltK0aNcFLSi_2M-WdTIdE,8084
|
|
8
|
-
marqetive/platforms/__init__.py,sha256=6QjetNWodf32pgGQsmLKs7W-v-pG2kKckb5JEPqIPNI,1351
|
|
9
|
-
marqetive/platforms/base.py,sha256=zmCda00Szq_LswRdsWPI5V88TysLH3FIZ0mKwH6b8dE,11957
|
|
10
|
-
marqetive/platforms/exceptions.py,sha256=Xyj0bzNiZm5VTErmzXgVW8T6IQnOpF92-HJiKPKjIio,7076
|
|
11
|
-
marqetive/platforms/instagram/__init__.py,sha256=9V0GPVm9HSTtDdV0bQEfuND8r7PEF2smOL3lb5BZevg,343
|
|
12
|
-
marqetive/platforms/instagram/client.py,sha256=PxVsHUW8SSpPe2Kdd5zGezD7LUvJj5tdyNj8In_ChxI,24955
|
|
13
|
-
marqetive/platforms/instagram/exceptions.py,sha256=zFG_CkstlZWG47zsFdnObOZviTDIx3Z8yVG9-x7GMVY,8987
|
|
14
|
-
marqetive/platforms/instagram/factory.py,sha256=082cF47zs9GvrnrFFaKmftbt_GmvcHZvSNIJsOQcupY,3553
|
|
15
|
-
marqetive/platforms/instagram/manager.py,sha256=RhV2QpLp9z2p-MCP3E-UzeYFCmuB0K8PIdDfwSaxdJI,3730
|
|
16
|
-
marqetive/platforms/instagram/media.py,sha256=tbFzOf670T8UDoCD9fVeS03Uzhp6HSUFrpPgJVgpdRE,21174
|
|
17
|
-
marqetive/platforms/linkedin/__init__.py,sha256=mcHNOKW5niq0MGBMuRpCJfEg2DkE3sCt0J0AqSZUPBs,333
|
|
18
|
-
marqetive/platforms/linkedin/client.py,sha256=d7YDd23VAqUMAHw8Oi9Swpq5RwhIIpl4TjbrBI9GkfE,23574
|
|
19
|
-
marqetive/platforms/linkedin/exceptions.py,sha256=64J02_99cUcUW5i5xHE_sa0_6V4ibW8PmCEz2aROIE4,9771
|
|
20
|
-
marqetive/platforms/linkedin/factory.py,sha256=8JNxAMC-lJcU1trnd0PFge0LQWQMiIVzZORJHwcBhmM,4536
|
|
21
|
-
marqetive/platforms/linkedin/manager.py,sha256=XB6HB6-MWsDz2Arij5GuyRH_j5xWkYb8sHCTlKFWzMg,4000
|
|
22
|
-
marqetive/platforms/linkedin/media.py,sha256=busrlTA3CisY43qDy9dmiAmbFVz8De4nDsA4CV9PeWk,16917
|
|
23
|
-
marqetive/platforms/models.py,sha256=W_yOuRWItWSn82n8vXRNN_ScdNkzY1De2qqXaVN2RGU,10974
|
|
24
|
-
marqetive/platforms/tiktok/__init__.py,sha256=_lfPj-5VfNaL4cE39Uiv8QOI1DtRnKiP5feKdPQ53zI,313
|
|
25
|
-
marqetive/platforms/tiktok/client.py,sha256=p0uhPCyjykMj8mx0y3oCEOTNwEM_obr1CW8iLz-8AMw,10715
|
|
26
|
-
marqetive/platforms/tiktok/exceptions.py,sha256=SKzmAEIfBf9qeYPXdOFKL2ARx7MK_h57fyohbg_86vY,5780
|
|
27
|
-
marqetive/platforms/tiktok/factory.py,sha256=aqzyWe42i0R3Tvr2ml2xEYeW2e3USqIkz5-o8O5ae64,6764
|
|
28
|
-
marqetive/platforms/tiktok/manager.py,sha256=0bIL26NCppN5PFk0DKPaH2zyrm4wwA-Mfm8KQwq97UY,4113
|
|
29
|
-
marqetive/platforms/tiktok/media.py,sha256=B3QoE05xlQ0OSZ_1y_MiNX8bJFwbyM4jDvM4w7A-HHA,10652
|
|
30
|
-
marqetive/platforms/twitter/__init__.py,sha256=TRVOejA-wa_tw50_YUwTYnhGyGuOK2IFpZWvVZP94HQ,325
|
|
31
|
-
marqetive/platforms/twitter/client.py,sha256=s5nLUc3wOSEBCNuFCqxoLqUypBI6eDK6fRC1iP5OnZU,20856
|
|
32
|
-
marqetive/platforms/twitter/exceptions.py,sha256=yRLLcodSouaFV076iwbxcWZzXUuoswAOXuL_-iPvLOk,8935
|
|
33
|
-
marqetive/platforms/twitter/factory.py,sha256=nBBl5aFcNCgIwf45PWywjpx_Qp0aOdbOHthvQX-BzI4,5286
|
|
34
|
-
marqetive/platforms/twitter/manager.py,sha256=NEqFllDdQ6nlUQMV1M5koX8DMURuvNsa39gKiTpm5A0,4108
|
|
35
|
-
marqetive/platforms/twitter/media.py,sha256=szkILg8geuH5wVbGXUBeHr9B-48j08njb-NlClPDcQQ,24984
|
|
36
|
-
marqetive/platforms/twitter/threads.py,sha256=F1msBRcmpAb_NKaZvdDn0oA_cQwwzFoXGeiUIdr7rrY,14772
|
|
37
|
-
marqetive/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
38
|
-
marqetive/registry_init.py,sha256=ozvGN_lWWx_vvYcU_ONA49EzwN4ymbrB1jtkRchYvAU,2051
|
|
39
|
-
marqetive/utils/__init__.py,sha256=qBn_DN-L2YTfuB_G-n_bHJjtuVRiyH3ftl9JZ0JO93M,989
|
|
40
|
-
marqetive/utils/file_handlers.py,sha256=IUdRZxr_jxAuwxUypUkUgKqiGDcIHNr1LhCb2Ne2a98,12572
|
|
41
|
-
marqetive/utils/helpers.py,sha256=8-ljhL47SremKcQO2GF8DIHOPODEv1rSioVNuSPCbec,2634
|
|
42
|
-
marqetive/utils/media.py,sha256=Rvxw9XKU65n-z4G1bEihG3wXZBmjSDZUqClfjGFrg6k,12013
|
|
43
|
-
marqetive/utils/oauth.py,sha256=B8GbzliQKEV5XpPshrKCHNlFl_arEOfZ10KKIUDKfQg,12113
|
|
44
|
-
marqetive/utils/retry.py,sha256=lAniJLMNWp9XsHrvU0XBNifpNEjfde4MGfd5hlFTPfA,7636
|
|
45
|
-
marqetive/utils/token_validator.py,sha256=asLMiEgT-BtqEpn_HDX15vJoSBcH7CGW0abervFOXxM,6707
|
|
46
|
-
marqetive_lib-0.1.2.dist-info/METADATA,sha256=xk2oWdG9QJlzw1Mu49BWngovHJ4izI2N0pwZFKNzP-4,7798
|
|
47
|
-
marqetive_lib-0.1.2.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
48
|
-
marqetive_lib-0.1.2.dist-info/RECORD,,
|
|
File without changes
|