media2md 0.9.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.
Files changed (140) hide show
  1. media2md-0.9.1/.github/workflows/release-pypi.yml +25 -0
  2. media2md-0.9.1/.github/workflows/release-testpypi.yml +27 -0
  3. media2md-0.9.1/.github/workflows/security.yml +14 -0
  4. media2md-0.9.1/.github/workflows/tests.yml +19 -0
  5. media2md-0.9.1/.gitignore +22 -0
  6. media2md-0.9.1/CHANGELOG.md +177 -0
  7. media2md-0.9.1/CONTRIBUTING.md +3 -0
  8. media2md-0.9.1/LICENSE +9 -0
  9. media2md-0.9.1/MEDIA2MD_V070_INSTALL.md +61 -0
  10. media2md-0.9.1/MEDIA2MD_V071_INSTALL.md +102 -0
  11. media2md-0.9.1/MEDIA2MD_V072_INSTALL.md +181 -0
  12. media2md-0.9.1/MEDIA2MD_V073_INSTALL.md +107 -0
  13. media2md-0.9.1/MEDIA2MD_V074_INSTALL.md +43 -0
  14. media2md-0.9.1/MEDIA2MD_V075_INSTALL.md +65 -0
  15. media2md-0.9.1/MEDIA2MD_V076_INSTALL.md +124 -0
  16. media2md-0.9.1/MEDIA2MD_V077_INSTALL.md +108 -0
  17. media2md-0.9.1/MEDIA2MD_V078_INSTALL.md +57 -0
  18. media2md-0.9.1/MEDIA2MD_V079_INSTALL.md +72 -0
  19. media2md-0.9.1/MEDIA2MD_V080_INSTALL.md +81 -0
  20. media2md-0.9.1/MEDIA2MD_V081_INSTALL.md +93 -0
  21. media2md-0.9.1/MEDIA2MD_V082_INSTALL.md +61 -0
  22. media2md-0.9.1/MEDIA2MD_V083_INSTALL.md +56 -0
  23. media2md-0.9.1/MEDIA2MD_V084_INSTALL.md +101 -0
  24. media2md-0.9.1/MEDIA2MD_V085_INSTALL.md +162 -0
  25. media2md-0.9.1/MEDIA2MD_V086_INSTALL.md +120 -0
  26. media2md-0.9.1/MEDIA2MD_V090_INSTALL.md +82 -0
  27. media2md-0.9.1/MEDIA2MD_V091_INSTALL.md +82 -0
  28. media2md-0.9.1/PKG-INFO +257 -0
  29. media2md-0.9.1/README.md +198 -0
  30. media2md-0.9.1/RELEASE_MANIFEST.json +155 -0
  31. media2md-0.9.1/SECURITY.md +3 -0
  32. media2md-0.9.1/START_HERE.md +10 -0
  33. media2md-0.9.1/STRICT_ACCEPTANCE_V071.md +48 -0
  34. media2md-0.9.1/STRICT_ACCEPTANCE_V072.md +41 -0
  35. media2md-0.9.1/STRICT_ACCEPTANCE_V073.md +71 -0
  36. media2md-0.9.1/STRICT_ACCEPTANCE_V074.md +84 -0
  37. media2md-0.9.1/STRICT_ACCEPTANCE_V075.md +93 -0
  38. media2md-0.9.1/STRICT_ACCEPTANCE_V076.md +100 -0
  39. media2md-0.9.1/STRICT_ACCEPTANCE_V077.md +109 -0
  40. media2md-0.9.1/STRICT_ACCEPTANCE_V078.md +114 -0
  41. media2md-0.9.1/STRICT_ACCEPTANCE_V079.md +124 -0
  42. media2md-0.9.1/STRICT_ACCEPTANCE_V080.md +134 -0
  43. media2md-0.9.1/STRICT_ACCEPTANCE_V081.md +152 -0
  44. media2md-0.9.1/STRICT_ACCEPTANCE_V082.md +165 -0
  45. media2md-0.9.1/STRICT_ACCEPTANCE_V083.md +179 -0
  46. media2md-0.9.1/STRICT_ACCEPTANCE_V084.md +192 -0
  47. media2md-0.9.1/STRICT_ACCEPTANCE_V085.md +28 -0
  48. media2md-0.9.1/STRICT_ACCEPTANCE_V086.md +26 -0
  49. media2md-0.9.1/STRICT_ACCEPTANCE_V090_CUMULATIVE_172.md +214 -0
  50. media2md-0.9.1/STRICT_ACCEPTANCE_V091_CUMULATIVE_176.md +230 -0
  51. media2md-0.9.1/bin/media2md +6 -0
  52. media2md-0.9.1/bin/social2md +6 -0
  53. media2md-0.9.1/docs/ACCEPTANCE_AUDIT_V091_20260626.md +182 -0
  54. media2md-0.9.1/docs/PYPI_RELEASE_CHECKLIST_V091.md +47 -0
  55. media2md-0.9.1/docs/RELEASE_NOTES_V091_PYPI.md +26 -0
  56. media2md-0.9.1/docs/RUFF_MYPY_DEBT_PLAN_V091.md +35 -0
  57. media2md-0.9.1/install.sh +9 -0
  58. media2md-0.9.1/install_media2md_v074.py +111 -0
  59. media2md-0.9.1/install_media2md_v075.py +136 -0
  60. media2md-0.9.1/install_media2md_v076.py +136 -0
  61. media2md-0.9.1/install_media2md_v077.py +136 -0
  62. media2md-0.9.1/install_media2md_v078.py +136 -0
  63. media2md-0.9.1/install_media2md_v079.py +136 -0
  64. media2md-0.9.1/install_media2md_v080.py +136 -0
  65. media2md-0.9.1/install_media2md_v081.py +136 -0
  66. media2md-0.9.1/install_media2md_v083.py +160 -0
  67. media2md-0.9.1/install_media2md_v084.py +203 -0
  68. media2md-0.9.1/install_media2md_v085.py +203 -0
  69. media2md-0.9.1/install_media2md_v086.py +203 -0
  70. media2md-0.9.1/install_media2md_v090.py +207 -0
  71. media2md-0.9.1/install_media2md_v091.py +207 -0
  72. media2md-0.9.1/pyproject.toml +46 -0
  73. media2md-0.9.1/src/media2md/__init__.py +1 -0
  74. media2md-0.9.1/src/media2md/bootstrap.py +77 -0
  75. media2md-0.9.1/src/media2md/bundle/bin/media2md +6 -0
  76. media2md-0.9.1/src/media2md/bundle/bin/social2md +6 -0
  77. media2md-0.9.1/src/media2md/bundle/defaults/auth_profiles.json +1 -0
  78. media2md-0.9.1/src/media2md/bundle/defaults/creator_policies.json +1 -0
  79. media2md-0.9.1/src/media2md/bundle/defaults/creators.yaml +1 -0
  80. media2md-0.9.1/src/media2md/bundle/defaults/provider_policies.json +1 -0
  81. media2md-0.9.1/src/media2md/bundle/defaults/social2md.json +97 -0
  82. media2md-0.9.1/src/media2md/bundle/openclaw/SKILL.md +53 -0
  83. media2md-0.9.1/src/media2md/bundle/scripts/audit_pipeline.py +119 -0
  84. media2md-0.9.1/src/media2md/bundle/scripts/build_update_asset.py +94 -0
  85. media2md-0.9.1/src/media2md/bundle/scripts/creator_bulk.py +2334 -0
  86. media2md-0.9.1/src/media2md/bundle/scripts/creator_inventory.py +482 -0
  87. media2md-0.9.1/src/media2md/bundle/scripts/creator_run_shared.py +80 -0
  88. media2md-0.9.1/src/media2md/bundle/scripts/generic_media.py +1734 -0
  89. media2md-0.9.1/src/media2md/bundle/scripts/init_system.py +535 -0
  90. media2md-0.9.1/src/media2md/bundle/scripts/instagram_instaloader.py +188 -0
  91. media2md-0.9.1/src/media2md/bundle/scripts/manage_creators.py +567 -0
  92. media2md-0.9.1/src/media2md/bundle/scripts/manage_videos.py +839 -0
  93. media2md-0.9.1/src/media2md/bundle/scripts/media2md.py +732 -0
  94. media2md-0.9.1/src/media2md/bundle/scripts/media2md_auth.py +174 -0
  95. media2md-0.9.1/src/media2md/bundle/scripts/media2md_auth_shared.py +80 -0
  96. media2md-0.9.1/src/media2md/bundle/scripts/media2md_backup.py +298 -0
  97. media2md-0.9.1/src/media2md/bundle/scripts/media2md_doctor.py +482 -0
  98. media2md-0.9.1/src/media2md/bundle/scripts/media2md_registry.py +3523 -0
  99. media2md-0.9.1/src/media2md/bundle/scripts/media2md_runtime.py +364 -0
  100. media2md-0.9.1/src/media2md/bundle/scripts/media2md_types.py +187 -0
  101. media2md-0.9.1/src/media2md/bundle/scripts/media2md_update.py +363 -0
  102. media2md-0.9.1/src/media2md/bundle/scripts/media2md_urls.py +146 -0
  103. media2md-0.9.1/src/media2md/bundle/scripts/media2md_youtube_session.py +406 -0
  104. media2md-0.9.1/src/media2md/bundle/scripts/media2md_ytdlp.py +377 -0
  105. media2md-0.9.1/src/media2md/bundle/scripts/process_worker.py +159 -0
  106. media2md-0.9.1/src/media2md/bundle/scripts/process_worker_impl.py +725 -0
  107. media2md-0.9.1/src/media2md/bundle/scripts/queue_admin.py +308 -0
  108. media2md-0.9.1/src/media2md/bundle/scripts/reconcile_storage.py +155 -0
  109. media2md-0.9.1/src/media2md/bundle/scripts/run_pipeline.py +466 -0
  110. media2md-0.9.1/src/media2md/bundle/scripts/scan_creators.py +859 -0
  111. media2md-0.9.1/src/media2md/bundle/scripts/scan_gallery.py +116 -0
  112. media2md-0.9.1/src/media2md/bundle/scripts/scan_gallery_impl.py +1059 -0
  113. media2md-0.9.1/src/media2md/bundle/scripts/social2md.py +703 -0
  114. media2md-0.9.1/src/media2md/bundle/scripts/social2md_core.py +1564 -0
  115. media2md-0.9.1/src/media2md/cli.py +30 -0
  116. media2md-0.9.1/src/media2md/providers.py +26 -0
  117. media2md-0.9.1/src/media2md/urls.py +147 -0
  118. media2md-0.9.1/tests/conftest.py +8 -0
  119. media2md-0.9.1/tests/test_package.py +31 -0
  120. media2md-0.9.1/tests/test_v067_regressions.py +385 -0
  121. media2md-0.9.1/tests/test_v070_release.py +73 -0
  122. media2md-0.9.1/tests/test_v071_youtube_types.py +193 -0
  123. media2md-0.9.1/tests/test_v072_realworld_regressions.py +99 -0
  124. media2md-0.9.1/tests/test_v073_transport_observability.py +228 -0
  125. media2md-0.9.1/tests/test_v074_terminal_and_failure_observability.py +61 -0
  126. media2md-0.9.1/tests/test_v075_instagram_contract_and_bounded_tiktok.py +138 -0
  127. media2md-0.9.1/tests/test_v076_regression_reversal.py +131 -0
  128. media2md-0.9.1/tests/test_v077_bounded_tiktok_sync.py +123 -0
  129. media2md-0.9.1/tests/test_v078_stable_id_and_clean_pause.py +122 -0
  130. media2md-0.9.1/tests/test_v079_transport_memory_and_deadline.py +198 -0
  131. media2md-0.9.1/tests/test_v080_cursor_catalog.py +165 -0
  132. media2md-0.9.1/tests/test_v081_batch_transport_and_reporting.py +159 -0
  133. media2md-0.9.1/tests/test_v082_public_cli_creator_run.py +244 -0
  134. media2md-0.9.1/tests/test_v083_exact_catalog_lifecycle.py +174 -0
  135. media2md-0.9.1/tests/test_v084_staged_exact_rebuild.py +260 -0
  136. media2md-0.9.1/tests/test_v085_production_safety.py +118 -0
  137. media2md-0.9.1/tests/test_v086_backup_live_regression.py +61 -0
  138. media2md-0.9.1/tests/test_v090_one_shot_regressions.py +316 -0
  139. media2md-0.9.1/tests/test_v091_tiktok_convergence.py +146 -0
  140. media2md-0.9.1/tools/build_release_assets.py +48 -0
@@ -0,0 +1,25 @@
1
+ name: release-pypi
2
+ on:
3
+ workflow_dispatch:
4
+
5
+ permissions:
6
+ contents: read
7
+ id-token: write
8
+
9
+ jobs:
10
+ publish:
11
+ environment: pypi
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+ - uses: actions/setup-python@v5
16
+ with:
17
+ python-version: "3.12"
18
+ - run: python -m pip install --upgrade pip build twine
19
+ - run: python -m build
20
+ - run: python -m twine check dist/*.whl dist/*.tar.gz
21
+ - uses: actions/upload-artifact@v4
22
+ with:
23
+ name: pypi-distributions
24
+ path: dist/
25
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,27 @@
1
+ name: release-testpypi
2
+ on:
3
+ workflow_dispatch:
4
+
5
+ permissions:
6
+ contents: read
7
+ id-token: write
8
+
9
+ jobs:
10
+ publish:
11
+ environment: testpypi
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+ - uses: actions/setup-python@v5
16
+ with:
17
+ python-version: "3.12"
18
+ - run: python -m pip install --upgrade pip build twine
19
+ - run: python -m build
20
+ - run: python -m twine check dist/*.whl dist/*.tar.gz
21
+ - uses: actions/upload-artifact@v4
22
+ with:
23
+ name: testpypi-distributions
24
+ path: dist/
25
+ - uses: pypa/gh-action-pypi-publish@release/v1
26
+ with:
27
+ repository-url: https://test.pypi.org/legacy/
@@ -0,0 +1,14 @@
1
+ name: security
2
+ on:
3
+ schedule: [{cron: '17 3 * * 1'}]
4
+ workflow_dispatch:
5
+ jobs:
6
+ audit:
7
+ runs-on: ubuntu-latest
8
+ steps:
9
+ - uses: actions/checkout@v4
10
+ - uses: actions/setup-python@v5
11
+ with: {python-version: '3.12'}
12
+ - run: python -m pip install '.[dev]' pip-audit
13
+ - run: pip-audit
14
+ - run: python -m compileall -q src
@@ -0,0 +1,19 @@
1
+ name: tests
2
+ on: [push, pull_request, workflow_dispatch]
3
+ jobs:
4
+ test:
5
+ strategy:
6
+ matrix:
7
+ os: [ubuntu-latest, macos-14]
8
+ python: ['3.11', '3.12']
9
+ runs-on: ${{ matrix.os }}
10
+ steps:
11
+ - uses: actions/checkout@v4
12
+ - uses: actions/setup-python@v5
13
+ with: {python-version: '${{ matrix.python }}'}
14
+ - run: python -m pip install --upgrade pip
15
+ - run: python -m pip install '.[dev]'
16
+ - run: pytest
17
+ - run: python -m compileall -q src bin tests tools
18
+ - run: python -m build
19
+ - run: python -m twine check dist/*.whl dist/*.tar.gz
@@ -0,0 +1,22 @@
1
+ .venv/
2
+ .audit-venv/
3
+ __pycache__/
4
+ *.py[cod]
5
+ dist/
6
+ build/
7
+ *.egg-info/
8
+ .pytest_cache/
9
+ .mypy_cache/
10
+ .ruff_cache/
11
+ config/
12
+ data/
13
+ logs/
14
+ workspace/
15
+ markdown/
16
+ downloads/
17
+ transcripts/
18
+ .media2md-quarantine/
19
+ .DS_Store
20
+
21
+ # Runtime state must never be packaged
22
+ src/media2md/bundle/data/
@@ -0,0 +1,177 @@
1
+ # Changelog
2
+
3
+ ## 0.9.1 - 2026-06-25
4
+
5
+ - Treat HTTP 200 on TikTok's authenticated `/setting` endpoint as authenticated even when generic captcha strings appear in application JavaScript.
6
+ - Add deterministic TikTok metadata fallbacks: the bounded live transport cascade remains first, followed by verified local Registry/processing metadata and a direct no-proxy oEmbed fallback.
7
+ - Make TikTok Doctor reuse the real processing cascade and report a truthful degraded-ready state when a transient live probe fails but a recent completed Markdown artifact proves end-to-end operation.
8
+ - Add live-evidence regressions for TikTok auth, metadata fallback, and degraded Doctor semantics.
9
+
10
+ ## 0.9.0 - 2026-06-25
11
+
12
+ - Consolidate every product defect found by the complete v0.8.6 one-shot evidence run into one private-production candidate.
13
+ - Fix valid Instagram sessions being misclassified as `platform_challenge` when the authenticated `/accounts/edit/` application bundle contains the word `checkpoint`.
14
+ - Route TikTok metadata inspection through the same bounded transport/authentication cascade as media processing and persist the winning strategy.
15
+ - Treat an absent YouTube Videos, Shorts, or Streams tab as an empty exact surface, allowing Shorts-only channels to Full Sync successfully.
16
+ - Prevent resumed TikTok staged checkpoints from publishing partial items and downgrading a proven exact active catalog before cursor continuation.
17
+ - Preserve creator exactness when manually reprocessing a media item already present in the current exact catalog.
18
+ - Default isolated OpenClaw Cron installation to `--no-deliver`; require an explicit channel and recipient for announcement delivery.
19
+ - Make GitHub Release discovery advisory so 404/no-release and transient network errors cannot poison a successful scheduler tick.
20
+ - Extend upgrade migration to repair a matching downgraded TikTok exact state and stage resumable cursor checkpoints that already contain items.
21
+ - Add evidence-derived regression coverage for all fixes and retain historical v0.8.1, v0.8.3, v0.8.5, and v0.8.6 failures in cumulative acceptance.
22
+
23
+ ## 0.8.5 - 2026-06-25
24
+
25
+ - Promote the v0.8.4 TikTok staged-rebuild fix after the live StartupBell gate preserved the exact 1,159-item baseline through a 12-page pause and completed a 5/5 Batch.
26
+ - Add per-creator Sync and Run locks so duplicate scheduler/manual invocations cannot process the same creator concurrently.
27
+ - Add per-media processing locks to prevent direct URL processing and Creator Run from downloading or transcribing the same media simultaneously.
28
+ - Add a shared/exclusive maintenance lock: live work may run concurrently across unrelated creators, while backup and destructive maintenance require an idle, consistent state.
29
+ - Serialize the shared TikTok cursor-device state writer and increase SQLite busy timeouts for long-running local workloads.
30
+ - Add `media2md data backup` and `media2md data verify-backup` with SQLite online snapshots, SHA-256 manifests, integrity checks, atomic archive replacement, and deliberate exclusion of browser/session secrets.
31
+ - Add production-safety regressions for lock ownership, duplicate-run rejection, backup verification, database integrity, and secret exclusion.
32
+
33
+ ## 0.8.4 - 2026-06-25
34
+
35
+ - Stage TikTok Full rebuilds in the cursor checkpoint while preserving the last exact catalog as the active processing baseline until the rebuild completes.
36
+ - Keep `current_total_exact` and `media_type_totals_exact.tiktok_video` true when a rebuild pauses or its first cursor request returns 403.
37
+ - Report staged rebuild state with `baseline_preserved`, `rebuild_in_progress`, and `staged_total` instead of publishing a partial replacement.
38
+ - Persist the last successful TikTok cursor device ID independently of the transient checkpoint and reuse it after a completed Full Sync removes the checkpoint.
39
+ - Migrate v0.8.3 failed-rebuild checkpoints and safely repair matching exact-state regressions during upgrade.
40
+ - Count retryable failed media in the actual remaining queue when `--max-failures` stops a Creator Run.
41
+ - Add regression tests for zero-page failure, partial staged rebuilds, cursor device reuse, installer migration, and retryable remaining counts.
42
+
43
+ ## 0.8.3 - 2026-06-25
44
+
45
+ - Preserve a proven TikTok exact catalog across bounded Quick Sync merges instead of downgrading `current_total_exact` to false.
46
+ - Skip hidden TikTok pre-run sync for both partial and exact cached catalogs; processing no longer mutates catalog exactness.
47
+ - Add registry-backed fresh cursor bootstrap after a completed Full Sync deletes its checkpoint, so the next explicit `--force-full` starts a new cursor rebuild rather than legacy playlist pagination.
48
+ - Restore exact state during upgrade only when `current_total == last_full_exact_total` and a completed Full Sync timestamp exists.
49
+ - Report `media_type_totals_exact.tiktok_video` and `last_full_media_type_totals.tiktok_video` consistently.
50
+ - Add public CLI and registry lifecycle regressions for exact catalog preservation, exact-catalog skip, idempotent cursor rebuild, and safe installer repair.
51
+
52
+ ## 0.8.1 - 2026-06-24
53
+
54
+ - Preserve the command-start TikTok total before cursor pages update the Registry, so `previous_current_total` and `new_since_last_sync` report the actual run delta.
55
+ - Emit `SYNC_CURSOR_ATTEMPT_RESULT` for failed public, authenticated, timeout, invalid-JSON, and API-status attempts.
56
+ - Skip the legacy TikTok Quick Sync before Batch while a resumable cursor Full Sync is still incomplete; known catalog items are used directly.
57
+ - Add a bounded per-item TikTok download transport cascade with direct no-proxy public/authenticated attempts before curl-cffi impersonation.
58
+ - Persist the last successful TikTok media-download strategy separately from the catalog transport hint and load it on later items/runs.
59
+ - Share a finite per-item download budget and emit explicit attempt/result telemetry.
60
+ - Always emit `CREATOR_RUN_COMPLETED` when `--max-failures` or stop-on-failure ends a batch early.
61
+ - Preserve stored TikTok `sec_uid`/`user_id` in Quick and Partial summaries.
62
+ - Keep the v0.8.0 native cursor Catalog engine and live-passing Instagram/YouTube paths unchanged.
63
+
64
+ ## 0.8.0 - 2026-06-24
65
+
66
+ - Replace resumed TikTok `--playlist-start` deep pagination with a persistent `creator/item_list` cursor backend.
67
+ - Recover an initial cursor from the oldest normalized checkpoint timestamp and persist `tiktok_cursor` plus a stable `tiktok_device_id` in checkpoint schema 5.
68
+ - Fetch one bounded cursor page at a time with native macOS curl, `--noproxy *`, and a proxy-cleared environment.
69
+ - Atomically save every successful cursor page before requesting the next page.
70
+ - Establish the exact TikTok total when `hasMorePrevious=false`; otherwise pause cleanly on runtime/page-count/request failure.
71
+ - Retain the v0.7.x bounded yt-dlp page extractor only as a bootstrap/diagnostic fallback for creators without a recovered secUid.
72
+ - Keep the live-passing Instagram, YouTube, typed-batch, and installer paths unchanged.
73
+
74
+ ## 0.7.9
75
+
76
+ - Persist the last successful TikTok transport/auth pair in checkpoint schema 4 and reload it across CLI invocations.
77
+ - Prefer isolated direct transport when an old checkpoint has no hint and macOS system proxies are enabled.
78
+ - Share one TLS circuit breaker across stable-ID and handle candidates for the entire page.
79
+ - Stop before launching another extractor when less than five seconds remain in the page budget.
80
+ - Preserve `creator_identifiers.sec_uid` in partial, paused, and completed TikTok summaries.
81
+ - Report `max_pages_per_run` when the configured page-count cap pauses a run.
82
+ - Keep Instagram and YouTube execution paths unchanged.
83
+
84
+
85
+ ## 0.7.8
86
+
87
+ - Fix TikTok stable-ID catalog pages that successfully return JSON but omit a human-readable handle. The existing normalized creator handle is now reused as metadata context.
88
+ - Stop the duplicate handle-profile fetch after a stable-ID page succeeds.
89
+ - Add `SYNC_STABLE_ID_HANDLE_REUSED ... second_profile_fetch=false` evidence.
90
+ - Convert bounded TikTok page exhaustion from a hard error into a clean resumable `SYNC_RUN_PAUSED reason=page_budget_exhausted`.
91
+ - Preserve checkpoint item count and `next_start` exactly on clean pause.
92
+ - Remove a duplicate set of yt-dlp flat-playlist flags.
93
+ - Add live-regression tests for the item 376–400 StartupBell failure.
94
+
95
+ ## 0.7.7 - 2026-06-24
96
+
97
+ - Replaced per-transport TikTok timeout multiplication with one shared deadline per catalog page.
98
+ - Removed nested TikTok fallback: a handle candidate no longer invokes a second stable-ID fallback ladder.
99
+ - Limited each page to at most one recovered stable ID plus the human handle.
100
+ - Remember the last successful transport and authentication mode and try it first on the next page.
101
+ - Replaced the repeatedly restarting `SYNC_HEARTBEAT` label with contextual `SYNC_WAITING` output, defaulting to 30-second intervals.
102
+ - Added `SYNC_ATTEMPT_RESULT`, per-page budget telemetry, and overall sync progress.
103
+ - Added a total TikTok sync runtime budget and optional page-count budget; exhaustion pauses cleanly with an exact-false checkpoint instead of running indefinitely.
104
+ - Added regression tests for shared deadlines, absence of nested fallback, resumable run budgets, and concise waiting telemetry.
105
+ - Preserved the v0.7.6 Instagram path, which completed 30 real Reels with zero failures.
106
+
107
+ ## 0.7.6 - 2026-06-24
108
+
109
+ - Restored the proven Instagram worker-side cookie resolution path used by v0.6.x. Creator Batch no longer forces `--cookies-file` unless a human explicitly supplies an override.
110
+ - Added `--retry-failed` to the public `media2md creator run` CLI and forwards it to the Instagram engine, fixing the v0.7.5 documentation/CLI mismatch.
111
+ - Added end-to-end regression tests covering the public CLI, creator caller, worker command and optional cookie override.
112
+ - TikTok direct fallback now passes the official yt-dlp direct-connection form `--proxy ""`, in addition to ignoring config and removing proxy environment variables.
113
+ - Added safe macOS system-proxy detection that reports only enabled proxy classes, never proxy hosts or credentials.
114
+ - Recover missing TikTok secUid/user IDs from existing checkpoint media before requesting the next page.
115
+ - Persist checkpoint-discovered TikTok media as a non-exact partial catalog, so later page failures do not make the first 200 known items unusable.
116
+ - Preserve retry position and expose an explicit `--allow-stale-catalog` processing path for known TikTok items when exact enumeration remains blocked.
117
+
118
+ ## 0.7.5 - 2026-06-24
119
+
120
+ - Restored the Instagram caller/worker cookie contract by adding supported `--cookies-file` handling to `process_worker.py` and passing the selected file to gallery-dl.
121
+ - Automatically requeue only items that failed because of the historical `--cookies-file` argument mismatch; unrelated failures remain untouched.
122
+ - Replaced TikTok's unbounded all-target curl-cffi sweep with at most four strategies: configured, latest Chrome, latest Safari, and direct plain.
123
+ - Added a repeated-TLS circuit breaker that skips remaining impersonation strategies after two matching TLS failures.
124
+ - Added a direct TikTok fallback that ignores user yt-dlp config and removes inherited proxy environment variables.
125
+ - Surface proxy presence without printing proxy secrets, preserve transport root causes, and prevent secUid fallback text from hiding TLS/proxy errors.
126
+ - Separated TikTok catalog page size (`MEDIA2MD_TIKTOK_SYNC_PAGE_SIZE`) from media processing batch size.
127
+ - Added regression tests for the Instagram CLI contract, installer requeue migration, bounded TikTok fallback, circuit breaking, direct proxy isolation, and sync-page sizing.
128
+
129
+ ## 0.7.4 - 2026-06-24
130
+
131
+ - Fixed stale timestamp-based Python bytecode causing a successful 0.7.3 pip install to execute the old 0.7.2 CLI.
132
+ - Project wrapper now executes the installed project script directly and upgrade removes all stale `__pycache__`, `.pyc`, `.pyo`, and editable metadata before verification.
133
+ - Installation guide runs strict mode in a child subshell so a failed upgrade returns to the existing terminal instead of terminating the interactive shell.
134
+ - Added TikTok extractor heartbeat, finite per-strategy timeout, explicit interrupt telemetry, and paste-safe one-line validation commands.
135
+ - Instagram progress now distinguishes attempted, completed, and failed items and exposes each failed item root cause.
136
+ - Instagram enforces the configured max-failure threshold inside a batch and emits report/log/required-action diagnostics.
137
+ - Added regression coverage for v0.7.2→v0.7.4 stale-bytecode upgrade, shell survival, TikTok heartbeat, and Instagram all-failed batches.
138
+
139
+
140
+ ## 0.7.3 - 2026-06-24
141
+
142
+ - Classify curl error 35, TLS handshake failures, `SSLError`, and `OPENSSL_internal` failures as transient TikTok network errors.
143
+ - Add deterministic TikTok transport fallback across configured impersonation, available Chrome/Safari/Edge targets, and plain yt-dlp.
144
+ - Run catalog extractors in their own process groups and terminate the full process tree on timeout or Ctrl+C.
145
+ - Preserve TikTok pagination checkpoints and stable identifiers when a later page fails.
146
+ - Print Instagram creator-run completion summaries with processed, completed, failed, and remaining counts.
147
+ - Include selected media IDs in YouTube/TikTok batch-start output and NDJSON.
148
+ - Display complete typed batch limits in creator status without truncation.
149
+ - Preserve the last exact Full Sync total and per-type YouTube totals across Quick Sync runs.
150
+ - Import Instagram catalog exact totals into the unified registry.
151
+
152
+ ## 0.7.2 - 2026-06-24
153
+
154
+ - Make upgrade instructions fail fast when the downloaded source archive is missing, preventing a silent reinstall of the old local version.
155
+ - Add installer source-version and post-install CLI-version verification.
156
+ - Normalize Instagram profile and `/reels/` URLs before calling the username-only legacy creator manager.
157
+ - Preserve TikTok secUid/user ID learned on the first successful catalog page and reuse `tiktokuser:<id>` for later pages and checkpoint resume.
158
+ - Add live-regression coverage for the exact failures reported during the first v0.7.1 attempt.
159
+
160
+ ## 0.7.1 - 2026-06-24
161
+
162
+ - Added YouTube multi-surface catalog sync for `/videos` and `/shorts`.
163
+ - Added media type and processing class fields, per-type creator totals, typed output folders, and duplicate-ID reconciliation.
164
+ - Added per-type batch policies with defaults: TikTok 100, Instagram Reels 30, YouTube Shorts 30, videos 5, long videos 1.
165
+ - Long YouTube videos are isolated into single-item batches; unknown durations are hydrated before selection.
166
+ - Manual Shorts now attach to the canonical channel identity and invalidate stale exact totals until the next full sync.
167
+
168
+ ## 0.7.0 - 2026-06-24
169
+ - First standalone canonical package with managed runtime and persistent state.
170
+ - Clean install from wheel or source archive.
171
+ - Base package plus Instagram, YouTube, TikTok, MLX, and OpenClaw extras.
172
+ - Unified explicit browser-profile connection and verification for all three platforms.
173
+ - Live browser cookie refresh without automatic browser launch.
174
+ - Preserved YouTube caption-first, multi-strategy audio, long-video chunking, checkpoint resume, and safe artifact names.
175
+ - Secure update extraction and mandatory SHA-256 verification.
176
+ - GitHub, PyPI, Homebrew Tap, and optional npm bootstrap release scaffolding.
177
+ - Updated OpenClaw agent contract and cron instructions.
@@ -0,0 +1,3 @@
1
+ # Contributing
2
+
3
+ Create a virtual environment, install `.[dev,all]`, run `pytest`, and keep platform integrations non-interactive by default. New authentication code must never store passwords or bypass 2FA/CAPTCHA. Add regression tests for every platform-specific change.
media2md-0.9.1/LICENSE ADDED
@@ -0,0 +1,9 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Daniel Huang
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,61 @@
1
+ # Media2MD v0.7.0 Installation
2
+
3
+ ## Upgrade Daniel's existing project
4
+
5
+ ```bash
6
+ cd ~/instagram-to-md
7
+ source .venv/bin/activate
8
+
9
+ unzip -o ~/Downloads/media2md-v0.7.0-source.zip -d /tmp/media2md-v070
10
+ python /tmp/media2md-v070/install_media2md_v070.py \
11
+ --target ~/instagram-to-md
12
+
13
+ python -m pip install -U -e \
14
+ "$HOME/instagram-to-md[all]"
15
+
16
+ ./bin/media2md version
17
+ ./bin/media2md doctor all
18
+ ```
19
+
20
+ The installer preserves `config/`, `data/`, `logs/`, `workspace/`, `markdown/`, `downloads/`, and `transcripts/`. A rollback archive is created under `~/.cache/media2md/updates/`.
21
+
22
+ ## New installation from PyPI or wheel
23
+
24
+ Base package:
25
+
26
+ ```bash
27
+ python3 -m venv .venv
28
+ source .venv/bin/activate
29
+ python -m pip install media2md
30
+ media2md runtime install
31
+ media2md init --language zh-TW --markdown-language zh-TW --timezone Asia/Tokyo --non-interactive
32
+ ```
33
+
34
+ Optional modules:
35
+
36
+ ```bash
37
+ python -m pip install "media2md[instagram]"
38
+ python -m pip install "media2md[youtube,mlx]"
39
+ python -m pip install "media2md[tiktok]"
40
+ python -m pip install "media2md[all]"
41
+ ```
42
+
43
+ ## Authentication
44
+
45
+ ```bash
46
+ media2md auth profiles youtube --browser chrome
47
+ media2md auth connect youtube --browser chrome --profile Default
48
+ media2md auth verify youtube
49
+ ```
50
+
51
+ Use the same flow for `instagram` and `tiktok`.
52
+
53
+ Media2MD can refresh cookies already renewed by the selected browser profile without opening the browser. It cannot type passwords or bypass 2FA, CAPTCHA, or platform challenges. When those occur, the command returns `required_action` and waits for the user.
54
+
55
+ ## OpenClaw
56
+
57
+ ```bash
58
+ media2md openclaw install
59
+ media2md openclaw status
60
+ media2md scheduler tick --non-interactive --output ndjson
61
+ ```
@@ -0,0 +1,102 @@
1
+ # Media2MD v0.7.1 Installation
2
+
3
+ ## Upgrade Daniel's existing project
4
+
5
+ ```bash
6
+ cd ~/instagram-to-md
7
+ source .venv/bin/activate
8
+
9
+ rm -rf /tmp/media2md-v071
10
+ mkdir -p /tmp/media2md-v071
11
+ unzip -o ~/Downloads/media2md-v0.7.1-source.zip -d /tmp/media2md-v071
12
+ python /tmp/media2md-v071/install_media2md_v071.py \
13
+ --target ~/instagram-to-md
14
+
15
+ python -m pip install -U -e \
16
+ "$HOME/instagram-to-md[all]"
17
+
18
+ ./bin/media2md version
19
+ ./bin/media2md doctor all
20
+ ```
21
+
22
+ The installer preserves `config/`, `data/`, `logs/`, `workspace/`, `markdown/`, `downloads/`, and `transcripts/`. A rollback archive is created under `~/.cache/media2md/updates/`.
23
+
24
+ ## New installation from PyPI or wheel
25
+
26
+ Base package:
27
+
28
+ ```bash
29
+ python3 -m venv .venv
30
+ source .venv/bin/activate
31
+ python -m pip install media2md
32
+ media2md runtime install
33
+ media2md init --language zh-TW --markdown-language zh-TW --timezone Asia/Tokyo --non-interactive
34
+ ```
35
+
36
+ Optional modules:
37
+
38
+ ```bash
39
+ python -m pip install "media2md[instagram]"
40
+ python -m pip install "media2md[youtube,mlx]"
41
+ python -m pip install "media2md[tiktok]"
42
+ python -m pip install "media2md[all]"
43
+ ```
44
+
45
+ ## Authentication
46
+
47
+ ```bash
48
+ media2md auth profiles youtube --browser chrome
49
+ media2md auth connect youtube --browser chrome --profile Default
50
+ media2md auth verify youtube
51
+ ```
52
+
53
+ Use the same flow for `instagram` and `tiktok`.
54
+
55
+ Media2MD can refresh cookies already renewed by the selected browser profile without opening the browser. It cannot type passwords or bypass 2FA, CAPTCHA, or platform challenges. When those occur, the command returns `required_action` and waits for the user.
56
+
57
+ ## OpenClaw
58
+
59
+ ```bash
60
+ media2md openclaw install
61
+ media2md openclaw status
62
+ media2md scheduler tick --non-interactive --output ndjson
63
+ ```
64
+
65
+ ## v0.7.1 typed YouTube catalog verification
66
+
67
+ ```bash
68
+ ./bin/media2md creator add https://www.youtube.com/@TheProductFolks/videos --provider youtube
69
+ ./bin/media2md creator sync @TheProductFolks --provider youtube --force-full
70
+ ./bin/media2md creator policy set @TheProductFolks --provider youtube \
71
+ --batch-size-type youtube_short=30 \
72
+ --batch-size-type youtube_video=5 \
73
+ --batch-size-type youtube_long=1
74
+ ./bin/media2md creator status --provider youtube --creator @TheProductFolks
75
+ ```
76
+
77
+ `current_total` is a snapshot. A full sync produces exact per-type totals; a quick sync discovers new items but marks totals non-exact until the next full sync.
78
+
79
+ ## Requested live validation fixtures
80
+
81
+ ```bash
82
+ # YouTube Videos + Shorts catalog
83
+ ./bin/media2md creator add https://www.youtube.com/@TheProductFolks/videos --provider youtube
84
+ ./bin/media2md creator sync @TheProductFolks --provider youtube --force-full
85
+ ./bin/media2md creator status --provider youtube --creator @TheProductFolks
86
+
87
+ # One Short
88
+ ./bin/media2md media add https://www.youtube.com/shorts/0jttCFj5ZWM --process-now
89
+
90
+ # Long YouTube video
91
+ ./bin/media2md media add https://www.youtube.com/watch?v=J92OMF6HUaM --process-now
92
+
93
+ # TikTok full catalog and batch policy
94
+ ./bin/media2md creator add https://www.tiktok.com/@startupbell --provider tiktok
95
+ ./bin/media2md creator policy set @startupbell --provider tiktok --batch-size-type tiktok_video=100
96
+
97
+ # Instagram full Reels catalog and batch policy
98
+ ./bin/media2md creator add https://www.instagram.com/career_cleo/reels/ --provider instagram
99
+ ./bin/media2md creator policy set career_cleo --provider instagram --batch-size-type instagram_reel=30
100
+ ```
101
+
102
+ Run platform authentication verification and `doctor` before starting the large processing runs. Items 11 and 12 are intentionally pending.
@@ -0,0 +1,181 @@
1
+ # Media2MD v0.7.2 Installation and Live Regression Validation
2
+
3
+ v0.7.2 is a corrective release for three issues found in the first v0.7.1 live attempt:
4
+
5
+ 1. The v0.7.1 archive was not present in `~/Downloads`, but the shell continued and silently reinstalled v0.6.7.
6
+ 2. TikTok full sync could lose the secUid/user ID after the first pages and fail around page 3.
7
+ 3. Instagram `/reels/` creator URLs were passed to a legacy username-only manager.
8
+
9
+ ## Upgrade an existing project safely
10
+
11
+ Download **`media2md-v0.7.2-source.zip`** first, then run this block exactly. It is fail-fast: if the archive is missing or the version is wrong, later commands do not run.
12
+
13
+ ```bash
14
+ set -euo pipefail
15
+
16
+ cd "$HOME/instagram-to-md"
17
+ source .venv/bin/activate
18
+
19
+ ZIP="$HOME/Downloads/media2md-v0.7.2-source.zip"
20
+ test -f "$ZIP" || {
21
+ echo "ERROR: missing $ZIP"
22
+ echo "Download media2md-v0.7.2-source.zip before continuing."
23
+ exit 1
24
+ }
25
+
26
+ rm -rf /tmp/media2md-v072
27
+ mkdir -p /tmp/media2md-v072
28
+ unzip -q "$ZIP" -d /tmp/media2md-v072
29
+
30
+ test -f /tmp/media2md-v072/install_media2md_v072.py || {
31
+ echo "ERROR: archive does not contain install_media2md_v072.py"
32
+ exit 1
33
+ }
34
+
35
+ python /tmp/media2md-v072/install_media2md_v072.py \
36
+ --target "$HOME/instagram-to-md"
37
+
38
+ ./bin/media2md version | grep -F "media2md 0.7.2"
39
+ ```
40
+
41
+ The installer performs the editable package installation itself, creates `TARGET/.venv` when absent, and verifies the installed CLI version. Do not run a separate `pip install -e` command unless the installer reports an error.
42
+
43
+ The following directories are preserved:
44
+
45
+ ```text
46
+ config/
47
+ data/
48
+ logs/
49
+ workspace/
50
+ markdown/
51
+ downloads/
52
+ transcripts/
53
+ ```
54
+
55
+ A rollback archive is created under:
56
+
57
+ ```text
58
+ ~/.cache/media2md/updates/rollback-before-v072-*.zip
59
+ ```
60
+
61
+ ## New installation from a local wheel
62
+
63
+ PyPI publication remains pending. Install the local wheel instead:
64
+
65
+ ```bash
66
+ python3 -m venv .venv
67
+ source .venv/bin/activate
68
+ python -m pip install \
69
+ "$HOME/Downloads/media2md-0.7.2-py3-none-any.whl[all]"
70
+ media2md runtime install
71
+ media2md init \
72
+ --language zh-TW \
73
+ --markdown-language zh-TW \
74
+ --timezone Asia/Tokyo \
75
+ --non-interactive
76
+ media2md version
77
+ ```
78
+
79
+ ## Authentication
80
+
81
+ ```bash
82
+ ./bin/media2md auth profiles youtube --browser chrome
83
+ ./bin/media2md auth connect youtube --browser chrome --profile Default
84
+ ./bin/media2md auth verify youtube
85
+ ```
86
+
87
+ Use the same profile/connect/verify flow for Instagram and TikTok. Browser-renewed cookies are re-read automatically. Password, 2FA, CAPTCHA and platform challenges still require the user.
88
+
89
+ ## Typed batch policies
90
+
91
+ These commands only work after `./bin/media2md version` reports `0.7.2`:
92
+
93
+ ```bash
94
+ ./bin/media2md creator policy set \
95
+ @TheProductFolks \
96
+ --provider youtube \
97
+ --batch-size-type youtube_short=30 \
98
+ --batch-size-type youtube_video=5 \
99
+ --batch-size-type youtube_long=1
100
+
101
+ ./bin/media2md creator policy set \
102
+ @startupbell \
103
+ --provider tiktok \
104
+ --batch-size-type tiktok_video=100
105
+
106
+ ./bin/media2md creator policy set \
107
+ career_cleo \
108
+ --provider instagram \
109
+ --batch-size-type instagram_reel=30
110
+ ```
111
+
112
+ ## Live regression sequence
113
+
114
+ ### 1. YouTube Videos + Shorts
115
+
116
+ ```bash
117
+ ./bin/media2md creator add \
118
+ "https://www.youtube.com/@TheProductFolks/videos" \
119
+ --provider youtube
120
+
121
+ ./bin/media2md creator sync \
122
+ @TheProductFolks \
123
+ --provider youtube \
124
+ --force-full
125
+
126
+ ./bin/media2md creator status \
127
+ --provider youtube \
128
+ --creator @TheProductFolks
129
+ ```
130
+
131
+ Expected: separate `videos` and `shorts` totals, exact flags after full sync, and a combined de-duplicated total.
132
+
133
+ ### 2. Single YouTube Short
134
+
135
+ ```bash
136
+ ./bin/media2md media add \
137
+ "https://www.youtube.com/shorts/0jttCFj5ZWM" \
138
+ --process-now
139
+ ```
140
+
141
+ Expected output path includes `markdown/youtube/<creator>/shorts/`.
142
+
143
+ ### 3. Long YouTube video
144
+
145
+ ```bash
146
+ ./bin/media2md media add \
147
+ "https://www.youtube.com/watch?v=J92OMF6HUaM" \
148
+ --process-now
149
+ ```
150
+
151
+ Expected: long-video classification, chunk checkpointing when duration exceeds the configured threshold, and a merged Markdown result.
152
+
153
+ ### 4. TikTok full pagination
154
+
155
+ ```bash
156
+ ./bin/media2md creator add \
157
+ "https://www.tiktok.com/@startupbell" \
158
+ --provider tiktok
159
+ ```
160
+
161
+ Expected: page 2 and later use a stable `tiktokuser:<secUid/user_id>` catalog source learned from the first successful page. The sync must not fail merely because the handle endpoint stops exposing a secondary user ID.
162
+
163
+ ### 5. Instagram creator URL
164
+
165
+ ```bash
166
+ ./bin/media2md creator add \
167
+ "https://www.instagram.com/career_cleo/reels/" \
168
+ --provider instagram
169
+ ```
170
+
171
+ Expected: the URL is normalized to `career_cleo` before entering the legacy Instagram manager.
172
+
173
+ ## OpenClaw
174
+
175
+ ```bash
176
+ ./bin/media2md openclaw install
177
+ ./bin/media2md openclaw status
178
+ ./bin/media2md scheduler tick --non-interactive --output ndjson
179
+ ```
180
+
181
+ Items 11 and 12 in the strict acceptance table remain intentionally pending.