overleaf-comments-export 0.2.0__tar.gz → 0.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. {overleaf_comments_export-0.2.0 → overleaf_comments_export-0.4.0}/PKG-INFO +74 -11
  2. {overleaf_comments_export-0.2.0 → overleaf_comments_export-0.4.0}/README.md +72 -10
  3. overleaf_comments_export-0.4.0/overleaf_comments_export/__init__.py +8 -0
  4. overleaf_comments_export-0.4.0/overleaf_comments_export/__main__.py +239 -0
  5. {overleaf_comments_export-0.2.0 → overleaf_comments_export-0.4.0}/overleaf_comments_export/client.py +179 -19
  6. {overleaf_comments_export-0.2.0 → overleaf_comments_export-0.4.0}/overleaf_comments_export/export.py +82 -14
  7. {overleaf_comments_export-0.2.0 → overleaf_comments_export-0.4.0}/overleaf_comments_export/gui.py +159 -23
  8. {overleaf_comments_export-0.2.0 → overleaf_comments_export-0.4.0}/overleaf_comments_export/render.py +120 -7
  9. {overleaf_comments_export-0.2.0 → overleaf_comments_export-0.4.0}/overleaf_comments_export.egg-info/PKG-INFO +74 -11
  10. {overleaf_comments_export-0.2.0 → overleaf_comments_export-0.4.0}/overleaf_comments_export.egg-info/SOURCES.txt +4 -1
  11. {overleaf_comments_export-0.2.0 → overleaf_comments_export-0.4.0}/pyproject.toml +6 -2
  12. overleaf_comments_export-0.4.0/tests/test_errors_and_auth.py +157 -0
  13. overleaf_comments_export-0.4.0/tests/test_replies_and_changes.py +156 -0
  14. overleaf_comments_export-0.4.0/tests/test_response_letter.py +111 -0
  15. overleaf_comments_export-0.2.0/overleaf_comments_export/__init__.py +0 -1
  16. overleaf_comments_export-0.2.0/overleaf_comments_export/__main__.py +0 -143
  17. {overleaf_comments_export-0.2.0 → overleaf_comments_export-0.4.0}/LICENSE +0 -0
  18. {overleaf_comments_export-0.2.0 → overleaf_comments_export-0.4.0}/overleaf_comments_export/anchors.py +0 -0
  19. {overleaf_comments_export-0.2.0 → overleaf_comments_export-0.4.0}/overleaf_comments_export/model.py +0 -0
  20. {overleaf_comments_export-0.2.0 → overleaf_comments_export-0.4.0}/overleaf_comments_export/sections.py +0 -0
  21. {overleaf_comments_export-0.2.0 → overleaf_comments_export-0.4.0}/overleaf_comments_export.egg-info/dependency_links.txt +0 -0
  22. {overleaf_comments_export-0.2.0 → overleaf_comments_export-0.4.0}/overleaf_comments_export.egg-info/entry_points.txt +0 -0
  23. {overleaf_comments_export-0.2.0 → overleaf_comments_export-0.4.0}/overleaf_comments_export.egg-info/requires.txt +0 -0
  24. {overleaf_comments_export-0.2.0 → overleaf_comments_export-0.4.0}/overleaf_comments_export.egg-info/top_level.txt +0 -0
  25. {overleaf_comments_export-0.2.0 → overleaf_comments_export-0.4.0}/setup.cfg +0 -0
  26. {overleaf_comments_export-0.2.0 → overleaf_comments_export-0.4.0}/tests/test_anchors_sections.py +0 -0
  27. {overleaf_comments_export-0.2.0 → overleaf_comments_export-0.4.0}/tests/test_client.py +0 -0
  28. {overleaf_comments_export-0.2.0 → overleaf_comments_export-0.4.0}/tests/test_export.py +0 -0
  29. {overleaf_comments_export-0.2.0 → overleaf_comments_export-0.4.0}/tests/test_render.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: overleaf-comments-export
3
- Version: 0.2.0
3
+ Version: 0.4.0
4
4
  Summary: Export comment threads and tracked changes from an Overleaf project to Markdown + JSON, optimized for AI-agent consumption.
5
5
  Author: Shivang
6
6
  License: MIT
@@ -19,6 +19,7 @@ Classifier: Programming Language :: Python :: 3.10
19
19
  Classifier: Programming Language :: Python :: 3.11
20
20
  Classifier: Programming Language :: Python :: 3.12
21
21
  Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Programming Language :: Python :: 3.14
22
23
  Classifier: Topic :: Text Processing :: Markup :: LaTeX
23
24
  Classifier: Topic :: Scientific/Engineering
24
25
  Requires-Python: >=3.10
@@ -69,7 +70,13 @@ an Overleaf project URL and a logged-in browser session.
69
70
  pip install overleaf-comments-export
70
71
  ```
71
72
 
72
- Requires Python 3.10+. Works on macOS, Linux, and Windows.
73
+ Requires Python 3.10 or newer (tested up to 3.14). Works on macOS, Linux, and
74
+ Windows.
75
+
76
+ The graphical window needs Python's Tk toolkit, which most Linux distributions
77
+ package separately (`sudo apt install python3-tk` on Debian/Ubuntu). The
78
+ command line never needs it, and `--gui` tells you what to install if it is
79
+ missing.
73
80
 
74
81
  ## Quick start
75
82
 
@@ -104,6 +111,7 @@ In your output folder, by default:
104
111
  | `comments.json` | Structured data — `summary`, top-level `threads`, `files`, `comments`, `tracked_changes`, etc. Schema described in `agents.md`. |
105
112
  | `comments.jsonl` | One self-contained JSON record per comment for streaming/pipelines. |
106
113
  | `agents.md` | A brief instruction file telling an AI agent how to consume the batch. |
114
+ | `response-letter.md` | (Optional, `--response-letter`) A point-by-point reply document, pre-filled with every open comment grouped by who raised it, with blanks for your response. |
107
115
  | `by-reviewer/<name>.md` | (Optional, `--per-reviewer`) One Markdown per reviewer with only their threads. |
108
116
  | `comments.log` | Diagnostic log for the run. |
109
117
 
@@ -121,6 +129,9 @@ overleaf-comments-export --project-url … --out ./out --render-mode detailed
121
129
 
122
130
  # Per-reviewer sub-reports under ./out/by-reviewer/
123
131
  overleaf-comments-export --project-url … --out ./out --per-reviewer
132
+
133
+ # Draft a point-by-point response letter for the open comments
134
+ overleaf-comments-export --project-url … --out ./out --response-letter
124
135
  ```
125
136
 
126
137
  Full flag reference: `overleaf-comments-export --help`.
@@ -137,19 +148,71 @@ by browser on macOS:
137
148
  | Chrome / Edge / Brave | Cookies are AES-encrypted with a Keychain-stored key; **you'll get a Keychain password prompt every run.** Hidden behind an opt-in in the GUI. |
138
149
 
139
150
  On Windows, Chrome 127+ uses App-Bound Encryption that `browser-cookie3`
140
- doesn't fully decrypt yet — prefer Firefox or Edge on Windows.
151
+ can't decrypt. On Linux, snap-packaged browsers sandbox their cookie stores.
141
152
 
142
- On Linux, snap-packaged browsers sandbox their cookies — install browsers as
143
- native packages if you can.
153
+ **If reading the cookie from your browser fails, paste it instead** — this
154
+ works on every OS and browser:
144
155
 
145
- ## Status & maintenance
156
+ ```bash
157
+ overleaf-comments-export --project-url <url> --out ./out --cookie "PASTE_HERE"
158
+ ```
146
159
 
147
- This is a personal research utility published in case it's useful to others.
148
- It is provided as-is, with no guaranteed maintenance, no SLA, and no roadmap.
149
- Pull requests are welcome; issues may or may not be acted upon.
160
+ Or set it once: `export OVERLEAF_SESSION="PASTE_HERE"`. In the GUI, choose
161
+ **"Paste the cookie myself"** and click **How?** for step-by-step instructions.
150
162
 
151
- If Overleaf changes their internal API, this tool may stop working until
152
- someone (you?) adapts it.
163
+ To find it: open Overleaf, press F12, go to Application (or Storage) →
164
+ Cookies → `https://www.overleaf.com`, and copy the Value of `overleaf_session2`.
165
+ Treat it like a password; it stops working when you sign out.
166
+
167
+ ## Troubleshooting
168
+
169
+ | What you see | What it means |
170
+ |---|---|
171
+ | "Could not look up www.overleaf.com" | This computer is offline, or a VPN/DNS problem. Not an Overleaf issue. |
172
+ | "Overleaf refused the request (not signed in)" | Your session expired. Sign in again in the browser, then re-run. |
173
+ | "Could not read Overleaf cookies from chrome" | Use the paste-the-cookie method above. |
174
+ | "Overleaf could not find that project" | Wrong link, or this account has no access. |
175
+
176
+ ## Feedback, questions, and contributing
177
+
178
+ This tool is actively maintained, and feedback shapes what gets built next.
179
+
180
+ - **Something broke, or the output was wrong?**
181
+ [Open an issue.](https://github.com/Mangluu/overleaf-comments-export/issues/new/choose)
182
+ You do not need to be a programmer — paste what the tool said and that is
183
+ plenty. If Overleaf changes something, everything here stops working at once,
184
+ and you may be the first person to notice.
185
+ - **Want it to do something it doesn't?**
186
+ [Suggest a feature.](https://github.com/Mangluu/overleaf-comments-export/issues/new/choose)
187
+ Tell me what you are trying to do, not just the feature — the real task
188
+ usually leads somewhere better.
189
+ - **Just a question, or want to show what you built with it?**
190
+ [Discussions.](https://github.com/Mangluu/overleaf-comments-export/discussions)
191
+ - **Want to contribute code?** See [CONTRIBUTING.md](CONTRIBUTING.md). It takes
192
+ about two minutes to get the tests running, and there are items marked
193
+ *help wanted* in [ROADMAP.md](ROADMAP.md).
194
+
195
+ Never include your session cookie in an issue — it is a password for your
196
+ Overleaf account, and nobody needs it to fix a bug.
197
+
198
+ Maintained by [Shivang Gupta](https://github.com/Mangluu), who wrote it to deal
199
+ with the review comments on his own papers.
200
+
201
+ ## What's coming next
202
+
203
+ See [ROADMAP.md](ROADMAP.md). Short version: a response-letter scaffold,
204
+ writing out the full source so an AI can see more than a snippet, and a diff
205
+ between two exports so you can work through review comments in waves.
206
+
207
+ Changes are recorded in [CHANGELOG.md](CHANGELOG.md).
208
+
209
+ ## A caution
210
+
211
+ This tool uses Overleaf's internal endpoints, which are undocumented and can
212
+ change without notice. It identifies itself honestly in every request, backs
213
+ off when asked to, and only ever reads — it cannot modify your project. Even
214
+ so, it may stop working the day Overleaf changes something. If that happens,
215
+ please say so in an issue.
153
216
 
154
217
  ## License
155
218
 
@@ -33,7 +33,13 @@ an Overleaf project URL and a logged-in browser session.
33
33
  pip install overleaf-comments-export
34
34
  ```
35
35
 
36
- Requires Python 3.10+. Works on macOS, Linux, and Windows.
36
+ Requires Python 3.10 or newer (tested up to 3.14). Works on macOS, Linux, and
37
+ Windows.
38
+
39
+ The graphical window needs Python's Tk toolkit, which most Linux distributions
40
+ package separately (`sudo apt install python3-tk` on Debian/Ubuntu). The
41
+ command line never needs it, and `--gui` tells you what to install if it is
42
+ missing.
37
43
 
38
44
  ## Quick start
39
45
 
@@ -68,6 +74,7 @@ In your output folder, by default:
68
74
  | `comments.json` | Structured data — `summary`, top-level `threads`, `files`, `comments`, `tracked_changes`, etc. Schema described in `agents.md`. |
69
75
  | `comments.jsonl` | One self-contained JSON record per comment for streaming/pipelines. |
70
76
  | `agents.md` | A brief instruction file telling an AI agent how to consume the batch. |
77
+ | `response-letter.md` | (Optional, `--response-letter`) A point-by-point reply document, pre-filled with every open comment grouped by who raised it, with blanks for your response. |
71
78
  | `by-reviewer/<name>.md` | (Optional, `--per-reviewer`) One Markdown per reviewer with only their threads. |
72
79
  | `comments.log` | Diagnostic log for the run. |
73
80
 
@@ -85,6 +92,9 @@ overleaf-comments-export --project-url … --out ./out --render-mode detailed
85
92
 
86
93
  # Per-reviewer sub-reports under ./out/by-reviewer/
87
94
  overleaf-comments-export --project-url … --out ./out --per-reviewer
95
+
96
+ # Draft a point-by-point response letter for the open comments
97
+ overleaf-comments-export --project-url … --out ./out --response-letter
88
98
  ```
89
99
 
90
100
  Full flag reference: `overleaf-comments-export --help`.
@@ -101,19 +111,71 @@ by browser on macOS:
101
111
  | Chrome / Edge / Brave | Cookies are AES-encrypted with a Keychain-stored key; **you'll get a Keychain password prompt every run.** Hidden behind an opt-in in the GUI. |
102
112
 
103
113
  On Windows, Chrome 127+ uses App-Bound Encryption that `browser-cookie3`
104
- doesn't fully decrypt yet — prefer Firefox or Edge on Windows.
114
+ can't decrypt. On Linux, snap-packaged browsers sandbox their cookie stores.
105
115
 
106
- On Linux, snap-packaged browsers sandbox their cookies — install browsers as
107
- native packages if you can.
116
+ **If reading the cookie from your browser fails, paste it instead** — this
117
+ works on every OS and browser:
108
118
 
109
- ## Status & maintenance
119
+ ```bash
120
+ overleaf-comments-export --project-url <url> --out ./out --cookie "PASTE_HERE"
121
+ ```
110
122
 
111
- This is a personal research utility published in case it's useful to others.
112
- It is provided as-is, with no guaranteed maintenance, no SLA, and no roadmap.
113
- Pull requests are welcome; issues may or may not be acted upon.
123
+ Or set it once: `export OVERLEAF_SESSION="PASTE_HERE"`. In the GUI, choose
124
+ **"Paste the cookie myself"** and click **How?** for step-by-step instructions.
114
125
 
115
- If Overleaf changes their internal API, this tool may stop working until
116
- someone (you?) adapts it.
126
+ To find it: open Overleaf, press F12, go to Application (or Storage) →
127
+ Cookies → `https://www.overleaf.com`, and copy the Value of `overleaf_session2`.
128
+ Treat it like a password; it stops working when you sign out.
129
+
130
+ ## Troubleshooting
131
+
132
+ | What you see | What it means |
133
+ |---|---|
134
+ | "Could not look up www.overleaf.com" | This computer is offline, or a VPN/DNS problem. Not an Overleaf issue. |
135
+ | "Overleaf refused the request (not signed in)" | Your session expired. Sign in again in the browser, then re-run. |
136
+ | "Could not read Overleaf cookies from chrome" | Use the paste-the-cookie method above. |
137
+ | "Overleaf could not find that project" | Wrong link, or this account has no access. |
138
+
139
+ ## Feedback, questions, and contributing
140
+
141
+ This tool is actively maintained, and feedback shapes what gets built next.
142
+
143
+ - **Something broke, or the output was wrong?**
144
+ [Open an issue.](https://github.com/Mangluu/overleaf-comments-export/issues/new/choose)
145
+ You do not need to be a programmer — paste what the tool said and that is
146
+ plenty. If Overleaf changes something, everything here stops working at once,
147
+ and you may be the first person to notice.
148
+ - **Want it to do something it doesn't?**
149
+ [Suggest a feature.](https://github.com/Mangluu/overleaf-comments-export/issues/new/choose)
150
+ Tell me what you are trying to do, not just the feature — the real task
151
+ usually leads somewhere better.
152
+ - **Just a question, or want to show what you built with it?**
153
+ [Discussions.](https://github.com/Mangluu/overleaf-comments-export/discussions)
154
+ - **Want to contribute code?** See [CONTRIBUTING.md](CONTRIBUTING.md). It takes
155
+ about two minutes to get the tests running, and there are items marked
156
+ *help wanted* in [ROADMAP.md](ROADMAP.md).
157
+
158
+ Never include your session cookie in an issue — it is a password for your
159
+ Overleaf account, and nobody needs it to fix a bug.
160
+
161
+ Maintained by [Shivang Gupta](https://github.com/Mangluu), who wrote it to deal
162
+ with the review comments on his own papers.
163
+
164
+ ## What's coming next
165
+
166
+ See [ROADMAP.md](ROADMAP.md). Short version: a response-letter scaffold,
167
+ writing out the full source so an AI can see more than a snippet, and a diff
168
+ between two exports so you can work through review comments in waves.
169
+
170
+ Changes are recorded in [CHANGELOG.md](CHANGELOG.md).
171
+
172
+ ## A caution
173
+
174
+ This tool uses Overleaf's internal endpoints, which are undocumented and can
175
+ change without notice. It identifies itself honestly in every request, backs
176
+ off when asked to, and only ever reads — it cannot modify your project. Even
177
+ so, it may stop working the day Overleaf changes something. If that happens,
178
+ please say so in an issue.
117
179
 
118
180
  ## License
119
181
 
@@ -0,0 +1,8 @@
1
+ """Export Overleaf comment threads and tracked changes."""
2
+
3
+ from importlib.metadata import PackageNotFoundError, version
4
+
5
+ try:
6
+ __version__ = version("overleaf-comments-export")
7
+ except PackageNotFoundError: # running from a source checkout
8
+ __version__ = "0.0.0-dev"
@@ -0,0 +1,239 @@
1
+ from __future__ import annotations
2
+
3
+ import argparse
4
+ import logging
5
+ import os
6
+ import sys
7
+ import traceback
8
+ from pathlib import Path
9
+
10
+ from . import __version__
11
+ from .client import OverleafClient, UserFacingError
12
+ from .export import ExportResult, run_export
13
+
14
+
15
+ def _no_tkinter_message() -> str:
16
+ """Platform-specific instructions for installing Python's GUI toolkit."""
17
+ if sys.platform == "darwin":
18
+ fix = (
19
+ "Install Python from python.org (it includes the GUI toolkit), or\n"
20
+ "with Homebrew run:\n\n"
21
+ " brew install python-tk"
22
+ )
23
+ elif sys.platform.startswith("win"):
24
+ fix = (
25
+ "Re-run the Python installer from python.org, choose \"Modify\", and\n"
26
+ "tick \"tcl/tk and IDLE\"."
27
+ )
28
+ else:
29
+ fix = (
30
+ "Install it with your package manager, for example:\n\n"
31
+ " Debian/Ubuntu : sudo apt install python3-tk\n"
32
+ " Fedora : sudo dnf install python3-tkinter\n"
33
+ " Arch : sudo pacman -S tk"
34
+ )
35
+ return (
36
+ "The window cannot open because this Python has no GUI toolkit "
37
+ "installed.\n\n"
38
+ f"{fix}\n\n"
39
+ "Or skip the window entirely and use the command line:\n\n"
40
+ " overleaf-comments-export --project-url <your project link> --out ./comments"
41
+ )
42
+
43
+
44
+ def main(argv: list[str] | None = None) -> int:
45
+ parser = argparse.ArgumentParser(
46
+ prog="overleaf-comments-export",
47
+ description="Export Overleaf comment threads and tracked changes to Markdown.",
48
+ )
49
+ parser.add_argument(
50
+ "--gui",
51
+ action="store_true",
52
+ help="Launch the graphical interface (default if no other args).",
53
+ )
54
+ parser.add_argument(
55
+ "--project-url",
56
+ help="Full Overleaf project URL, e.g. https://www.overleaf.com/project/<24-hex-id>.",
57
+ )
58
+ parser.add_argument(
59
+ "--out",
60
+ type=Path,
61
+ help="Directory to write comments-<date>.md, comments.json, and comments.log into.",
62
+ )
63
+ parser.add_argument(
64
+ "--project-title",
65
+ default=None,
66
+ help="Optional human-readable title for the report header. Defaults to the project id.",
67
+ )
68
+ parser.add_argument(
69
+ "--browser",
70
+ default="auto",
71
+ choices=list(OverleafClient.SUPPORTED_BROWSERS),
72
+ help="Which browser to read cookies from. Default: auto-detect.",
73
+ )
74
+ parser.add_argument(
75
+ "--cookie",
76
+ default=None,
77
+ metavar="VALUE",
78
+ help="Overleaf session cookie, pasted from your browser (DevTools → "
79
+ "Application → Cookies → overleaf_session2). Use this when reading "
80
+ "cookies from the browser fails. Also read from the OVERLEAF_SESSION "
81
+ "environment variable.",
82
+ )
83
+ parser.add_argument(
84
+ "--base-url",
85
+ default="https://www.overleaf.com",
86
+ help="Override the Overleaf base URL (for self-hosted instances).",
87
+ )
88
+ parser.add_argument(
89
+ "-v", "--verbose", action="store_true", help="More logging."
90
+ )
91
+ parser.add_argument(
92
+ "--version", action="version", version=f"%(prog)s {__version__}"
93
+ )
94
+ parser.add_argument(
95
+ "--render-mode",
96
+ choices=["compact", "detailed"],
97
+ default="compact",
98
+ help="Markdown layout: 'compact' (one line per comment, default) or "
99
+ "'detailed' (multi-line code-fence with anchor highlighted).",
100
+ )
101
+ parser.add_argument(
102
+ "--no-open",
103
+ dest="include_open",
104
+ action="store_false",
105
+ help="Skip open (unresolved) comments.",
106
+ )
107
+ parser.add_argument(
108
+ "--no-resolved",
109
+ dest="include_resolved",
110
+ action="store_false",
111
+ help="Skip resolved comments.",
112
+ )
113
+ parser.add_argument(
114
+ "--no-changes",
115
+ dest="include_changes",
116
+ action="store_false",
117
+ help="Skip tracked changes.",
118
+ )
119
+ parser.add_argument(
120
+ "--reviewer",
121
+ action="append",
122
+ default=[],
123
+ metavar="NAME",
124
+ help="Only include threads/changes touching this reviewer "
125
+ "(case-insensitive substring match against name and email). "
126
+ "Pass multiple times for OR-of-reviewers.",
127
+ )
128
+ parser.add_argument(
129
+ "--include-raw",
130
+ action="store_true",
131
+ help="Embed the unprocessed Overleaf API payloads inside comments.json.",
132
+ )
133
+ parser.add_argument(
134
+ "--no-jsonl",
135
+ dest="write_jsonl",
136
+ action="store_false",
137
+ help="Skip writing comments.jsonl (the streaming-friendly companion).",
138
+ )
139
+ parser.add_argument(
140
+ "--response-letter",
141
+ action="store_true",
142
+ help="Also write response-letter.md: a point-by-point reply document "
143
+ "pre-filled with every open comment, grouped by who raised it, with "
144
+ "blanks for your response.",
145
+ )
146
+ parser.add_argument(
147
+ "--per-reviewer",
148
+ action="store_true",
149
+ help="Also write one Markdown per reviewer into by-reviewer/.",
150
+ )
151
+ parser.set_defaults(
152
+ include_open=True,
153
+ include_resolved=True,
154
+ include_changes=True,
155
+ write_jsonl=True,
156
+ )
157
+ args = parser.parse_args(argv)
158
+
159
+ if args.gui or (not args.project_url and not args.out):
160
+ try:
161
+ from .gui import launch_gui
162
+ except ImportError:
163
+ # tkinter is NOT bundled with Python everywhere — most Linux
164
+ # distributions ship it as a separate system package, and it is
165
+ # missing from some minimal/conda builds.
166
+ print(_no_tkinter_message(), file=sys.stderr)
167
+ return 1
168
+ try:
169
+ return launch_gui()
170
+ except Exception as e:
171
+ # Typically TclError on a headless machine (SSH, server, container).
172
+ if "display" in str(e).lower() or type(e).__name__ == "TclError":
173
+ print(
174
+ "There is no screen to open a window on.\n\n"
175
+ "This looks like a computer without a desktop (a server, or "
176
+ "a remote session). Use the command line instead, for "
177
+ "example:\n\n"
178
+ " overleaf-comments-export --project-url <your project link> "
179
+ "--out ./comments\n\n"
180
+ "Run with --help to see every option.",
181
+ file=sys.stderr,
182
+ )
183
+ return 1
184
+ raise
185
+
186
+ if not args.project_url or not args.out:
187
+ parser.error("--project-url and --out are required in CLI mode (or pass --gui).")
188
+
189
+ logging.basicConfig(
190
+ level=logging.DEBUG if args.verbose else logging.INFO,
191
+ format="%(asctime)s %(levelname)s %(name)s: %(message)s",
192
+ stream=sys.stderr,
193
+ )
194
+
195
+ cookie_value = args.cookie or os.environ.get("OVERLEAF_SESSION") or None
196
+
197
+ try:
198
+ result: ExportResult = run_export(
199
+ project_url=args.project_url,
200
+ out_dir=args.out,
201
+ project_title=args.project_title,
202
+ base_url=args.base_url,
203
+ browser=args.browser,
204
+ cookie_value=cookie_value,
205
+ verbose=args.verbose,
206
+ include_raw=args.include_raw,
207
+ include_open=args.include_open,
208
+ include_resolved=args.include_resolved,
209
+ include_changes=args.include_changes,
210
+ reviewer_filter=args.reviewer,
211
+ render_mode=args.render_mode,
212
+ write_jsonl=args.write_jsonl,
213
+ per_reviewer_reports=args.per_reviewer,
214
+ response_letter=args.response_letter,
215
+ progress=lambda msg: print(msg, file=sys.stderr),
216
+ )
217
+ except UserFacingError as e:
218
+ # Expected, explainable failures: no traceback, just what to do next.
219
+ print(f"\n{e}", file=sys.stderr)
220
+ return 1
221
+ except Exception:
222
+ # Unexpected: show the traceback, but also tell people where to send it.
223
+ # The moment something breaks is the only moment we have their attention.
224
+ traceback.print_exc()
225
+ print(
226
+ f"\nThat looks like a bug in overleaf-comments-export {__version__}.\n"
227
+ "Please report it (copy the lines above) at\n"
228
+ " https://github.com/Mangluu/overleaf-comments-export/issues/new/choose\n"
229
+ "It probably affects other people too, and it cannot be fixed if "
230
+ "nobody says anything.",
231
+ file=sys.stderr,
232
+ )
233
+ return 2
234
+ print(f"\nDone. Open: {result.markdown_path}")
235
+ return 0
236
+
237
+
238
+ if __name__ == "__main__":
239
+ sys.exit(main())