instapaper-scraper 1.1.0__tar.gz → 1.1.0rc1__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 (24) hide show
  1. {instapaper_scraper-1.1.0/src/instapaper_scraper.egg-info → instapaper_scraper-1.1.0rc1}/PKG-INFO +47 -106
  2. {instapaper_scraper-1.1.0 → instapaper_scraper-1.1.0rc1}/README.md +45 -103
  3. {instapaper_scraper-1.1.0 → instapaper_scraper-1.1.0rc1}/pyproject.toml +6 -18
  4. {instapaper_scraper-1.1.0 → instapaper_scraper-1.1.0rc1}/src/instapaper_scraper/api.py +14 -34
  5. {instapaper_scraper-1.1.0 → instapaper_scraper-1.1.0rc1}/src/instapaper_scraper/auth.py +4 -5
  6. {instapaper_scraper-1.1.0 → instapaper_scraper-1.1.0rc1}/src/instapaper_scraper/cli.py +6 -6
  7. {instapaper_scraper-1.1.0 → instapaper_scraper-1.1.0rc1}/src/instapaper_scraper/output.py +4 -4
  8. {instapaper_scraper-1.1.0 → instapaper_scraper-1.1.0rc1/src/instapaper_scraper.egg-info}/PKG-INFO +47 -106
  9. {instapaper_scraper-1.1.0 → instapaper_scraper-1.1.0rc1}/src/instapaper_scraper.egg-info/requires.txt +1 -2
  10. {instapaper_scraper-1.1.0 → instapaper_scraper-1.1.0rc1}/tests/test_api.py +0 -57
  11. {instapaper_scraper-1.1.0 → instapaper_scraper-1.1.0rc1}/tests/test_auth.py +0 -44
  12. {instapaper_scraper-1.1.0 → instapaper_scraper-1.1.0rc1}/tests/test_cli.py +10 -5
  13. {instapaper_scraper-1.1.0 → instapaper_scraper-1.1.0rc1}/tests/test_output.py +0 -9
  14. {instapaper_scraper-1.1.0 → instapaper_scraper-1.1.0rc1}/LICENSE +0 -0
  15. {instapaper_scraper-1.1.0 → instapaper_scraper-1.1.0rc1}/setup.cfg +0 -0
  16. {instapaper_scraper-1.1.0 → instapaper_scraper-1.1.0rc1}/src/instapaper_scraper/__init__.py +0 -0
  17. {instapaper_scraper-1.1.0 → instapaper_scraper-1.1.0rc1}/src/instapaper_scraper/constants.py +0 -0
  18. {instapaper_scraper-1.1.0 → instapaper_scraper-1.1.0rc1}/src/instapaper_scraper/exceptions.py +0 -0
  19. {instapaper_scraper-1.1.0 → instapaper_scraper-1.1.0rc1}/src/instapaper_scraper.egg-info/SOURCES.txt +0 -0
  20. {instapaper_scraper-1.1.0 → instapaper_scraper-1.1.0rc1}/src/instapaper_scraper.egg-info/dependency_links.txt +0 -0
  21. {instapaper_scraper-1.1.0 → instapaper_scraper-1.1.0rc1}/src/instapaper_scraper.egg-info/entry_points.txt +0 -0
  22. {instapaper_scraper-1.1.0 → instapaper_scraper-1.1.0rc1}/src/instapaper_scraper.egg-info/top_level.txt +0 -0
  23. {instapaper_scraper-1.1.0 → instapaper_scraper-1.1.0rc1}/tests/test_cli_priority.py +0 -0
  24. {instapaper_scraper-1.1.0 → instapaper_scraper-1.1.0rc1}/tests/test_init.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: instapaper-scraper
3
- Version: 1.1.0
3
+ Version: 1.1.0rc1
4
4
  Summary: A tool to scrape articles from Instapaper.
5
5
  Project-URL: Homepage, https://github.com/chriskyfung/InstapaperScraper
6
6
  Project-URL: Source, https://github.com/chriskyfung/InstapaperScraper
@@ -35,52 +35,30 @@ Requires-Dist: tomli~=2.0.1; python_version < "3.11"
35
35
  Provides-Extra: dev
36
36
  Requires-Dist: pytest; extra == "dev"
37
37
  Requires-Dist: pytest-cov; extra == "dev"
38
+ Requires-Dist: black; extra == "dev"
38
39
  Requires-Dist: ruff; extra == "dev"
39
40
  Requires-Dist: types-requests; extra == "dev"
40
41
  Requires-Dist: types-beautifulsoup4; extra == "dev"
41
42
  Requires-Dist: requests-mock; extra == "dev"
42
43
  Requires-Dist: build; extra == "dev"
43
44
  Requires-Dist: twine; extra == "dev"
44
- Requires-Dist: mypy; extra == "dev"
45
- Requires-Dist: pre-commit; extra == "dev"
46
45
  Dynamic: license-file
47
46
 
48
47
  # Instapaper Scraper
49
48
 
50
- <!-- Badges -->
51
- <p align="center">
52
- <a href="https://github.com/chriskyfung/InstapaperScraper">
53
- <img src="https://img.shields.io/python/required-version-toml?tomlFilePath=https%3A%2F%2Fraw.githubusercontent.com%2Fchriskyfung%2FInstapaperScraper%2Frefs%2Fheads%2Fmaster%2Fpyproject.toml" alt="Python Version from PEP 621 TOML">
54
- </a>
55
- <a href="https://github.com/astral-sh/ruff">
56
- <img src="https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2Fastral-sh%2Fruff%2Fmain%2Fassets%2Fbadge%2Fv2.json" alt="Ruff">
57
- </a>
58
- <a href="https://codecov.io/gh/chriskyfung/InstapaperScraper">
59
- <img src="https://codecov.io/gh/chriskyfung/InstapaperScraper/graph/badge.svg" alt="Code Coverage">
60
- </a>
61
- <a href="https://github.com/chriskyfung/InstapaperScraper/actions/workflows/ci.yml">
62
- <img src="https://github.com/chriskyfung/InstapaperScraper/actions/workflows/ci.yml/badge.svg" alt="CI Status">
63
- </a>
64
- <a href="https://pypi.org/project/instapaper-scraper/">
65
- <img src="https://img.shields.io/pypi/v/instapaper-scraper.svg" alt="PyPI version">
66
- </a>
67
- <a href="https://pepy.tech/projects/instapaper-scraper">
68
- <img src="https://static.pepy.tech/personalized-badge/instapaper-scraper?period=total&left_text=downloads" alt="PyPI Downloads">
69
- </a>
70
- <a href="https://www.gnu.org/licenses/gpl-3.0.en.html">
71
- <img src="https://img.shields.io/github/license/chriskyfung/InstapaperScraper" alt="GitHub License">
72
- </a>
73
- <a href="https://github.com/sponsors/chriskyfung" title="Sponsor on GitHub">
74
- <img src="https://img.shields.io/badge/Sponsor-GitHub-purple?logo=github" alt="GitHub Sponsors Default">
75
- </a>
76
- <a href="https://www.buymeacoffee.com/chriskyfung" title="Buy Me A Coffee">
77
- <img src="https://img.shields.io/badge/Support%20Me-Coffee-ffdd00?logo=buy-me-a-coffee&logoColor=white" alt="Buy Me A Coffee">
78
- </a>
79
- </p>
80
-
81
- A powerful and reliable Python tool to automate the export of all your saved Instapaper bookmarks into various formats, giving you full ownership of your data.
82
-
83
- ## ✨ Features
49
+ ![Python Version from PEP 621 TOML](https://img.shields.io/python/required-version-toml?tomlFilePath=https%3A%2F%2Fraw.githubusercontent.com%2Fchriskyfung%2FInstapaperScraper%2Frefs%2Fheads%2Fmaster%2Fpyproject.toml)
50
+ [![CI](https://github.com/chriskyfung/InstapaperScraper/actions/workflows/ci.yml/badge.svg)](https://github.com/chriskyfung/InstapaperScraper/actions/workflows/ci.yml)
51
+ [![PyPI version](https://img.shields.io/pypi/v/instapaper-scraper.svg)](https://pypi.org/project/instapaper-scraper/)
52
+ [![PyPI Downloads](https://static.pepy.tech/personalized-badge/instapaper-scraper?period=total&left_text=downloads)](https://pepy.tech/projects/instapaper-scraper)
53
+ [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
54
+ [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
55
+ [![GitHub License](https://img.shields.io/github/license/chriskyfung/InstapaperScraper)
56
+ ](https://www.gnu.org/licenses/gpl-3.0.en.html)
57
+ [![codecov](https://codecov.io/gh/chriskyfung/InstapaperScraper/graph/badge.svg)](https://codecov.io/gh/chriskyfung/InstapaperScraper)
58
+
59
+ A Python tool to scrape all your saved Instapaper bookmarks and export them to various formats.
60
+
61
+ ## Features
84
62
 
85
63
  - Scrapes all bookmarks from your Instapaper account.
86
64
  - Supports scraping from specific folders.
@@ -88,13 +66,13 @@ A powerful and reliable Python tool to automate the export of all your saved Ins
88
66
  - Securely stores your session for future runs.
89
67
  - Modern, modular, and tested architecture.
90
68
 
91
- ## 🚀 Getting Started
69
+ ## Getting Started
92
70
 
93
- ### 📋 1. Requirements
71
+ ### 1. Requirements
94
72
 
95
73
  - Python 3.9+
96
74
 
97
- ### 📦 2. Installation
75
+ ### 2. Installation
98
76
 
99
77
  This package is available on PyPI and can be installed with pip:
100
78
 
@@ -102,7 +80,7 @@ This package is available on PyPI and can be installed with pip:
102
80
  pip install instapaper-scraper
103
81
  ```
104
82
 
105
- ### 💻 3. Usage
83
+ ### 3. Usage
106
84
 
107
85
  Run the tool from the command line, specifying your desired output format:
108
86
 
@@ -117,35 +95,35 @@ instapaper-scraper --format json
117
95
  instapaper-scraper --format sqlite --output my_articles.db
118
96
  ```
119
97
 
120
- ## ⚙️ Configuration
98
+ ## Configuration
121
99
 
122
- ### 🔐 Authentication
100
+ ### Authentication
123
101
 
124
102
  The script authenticates using one of the following methods, in order of priority:
125
103
 
126
- 1. **Command-line Arguments**: Provide your username and password directly when running the script:
104
+ 1. **Command-line Arguments**: Provide your username and password directly when running the script:
127
105
 
128
106
  ```sh
129
107
  instapaper-scraper --username your_username --password your_password
130
108
  ```
131
109
 
132
- 2. **Session Files (`.session_key`, `.instapaper_session`)**: The script attempts to load these files in the following order:
110
+ 2. **Session Files (`.session_key`, `.instapaper_session`)**: The script attempts to load these files in the following order:
133
111
  a. Path specified by `--session-file` or `--key-file` arguments.
134
112
  b. Files in the current working directory (e.g., `./.session_key`).
135
113
  c. Files in the user's configuration directory (`~/.config/instapaper-scraper/`).
136
114
  After the first successful login, the script creates an encrypted `.instapaper_session` file and a `.session_key` file to reuse your session securely.
137
115
 
138
- 3. **Interactive Prompt**: If no other method is available, the script will prompt you for your username and password.
116
+ 3. **Interactive Prompt**: If no other method is available, the script will prompt you for your username and password.
139
117
 
140
118
  > **Note on Security:** Your session file (`.instapaper_session`) and the encryption key (`.session_key`) are stored with secure permissions (read/write for the owner only) to protect your credentials.
141
119
 
142
- ### 📁 Folder Configuration
120
+ ### Folder Configuration
143
121
 
144
122
  You can define and quickly access your Instapaper folders using a `config.toml` file. The scraper will look for this file in the following locations (in order of precedence):
145
123
 
146
- 1. The path specified by the `--config-path` argument.
147
- 2. `config.toml` in the current working directory.
148
- 3. `~/.config/instapaper-scraper/config.toml`
124
+ 1. The path specified by the `--config-path` argument.
125
+ 2. `config.toml` in the current working directory.
126
+ 3. `~/.config/instapaper-scraper/config.toml`
149
127
 
150
128
  Here is an example of `config.toml`:
151
129
 
@@ -174,7 +152,7 @@ output_filename = "python-articles.db"
174
152
 
175
153
  When a `config.toml` file is present and no `--folder` argument is provided, the scraper will prompt you to select a folder. You can also specify a folder directly using the `--folder` argument with its key, ID, or slug. Use `--folder=none` to explicitly disable folder mode and scrape all articles.
176
154
 
177
- ### 💻 Command-line Arguments
155
+ ### Command-line Arguments
178
156
 
179
157
  | Argument | Description |
180
158
  | --- | --- |
@@ -186,7 +164,7 @@ When a `config.toml` file is present and no `--folder` argument is provided, the
186
164
  | `--password <pass>` | Your Instapaper account password. |
187
165
  | `--add-instapaper-url` | Adds a `instapaper_url` column to the output, containing a full, clickable URL for each article. |
188
166
 
189
- ### 📄 Output Formats
167
+ ### Output Formats
190
168
 
191
169
  You can control the output format using the `--format` argument. The supported formats are:
192
170
 
@@ -198,7 +176,7 @@ If the `--format` flag is omitted, the script will default to `csv`.
198
176
 
199
177
  When using `--output <filename>`, the file extension is automatically corrected to match the chosen format. For example, `instapaper-scraper --format json --output my_articles.txt` will create `my_articles.json`.
200
178
 
201
- #### 📖 Opening Articles in Instapaper
179
+ #### Opening Articles in Instapaper
202
180
 
203
181
  The output data includes a unique `id` for each article. You can use this ID to construct a URL to the article's reader view: `https://www.instapaper.com/read/<article_id>`.
204
182
 
@@ -210,7 +188,7 @@ instapaper-scraper --add-instapaper-url
210
188
 
211
189
  This adds a `instapaper_url` field to each article in the JSON output and a `instapaper_url` column in the CSV and SQLite outputs. The original `id` field is preserved.
212
190
 
213
- ## 🛠️ How It Works
191
+ ## How It Works
214
192
 
215
193
  The tool is designed with a modular architecture for reliability and maintainability.
216
194
 
@@ -219,9 +197,9 @@ The tool is designed with a modular architecture for reliability and maintainabi
219
197
  3. **Data Collection**: All fetched articles are aggregated into a single list.
220
198
  4. **Export**: Finally, the collected data is written to a file in your chosen format (`.csv`, `.json`, or `.db`).
221
199
 
222
- ## 📊 Example Output
200
+ ## Example Output
223
201
 
224
- ### 📄 CSV (`output/bookmarks.csv`) (with --add-instapaper-url)
202
+ ### CSV (`output/bookmarks.csv`) (with --add-instapaper-url)
225
203
 
226
204
  ```csv
227
205
  "id","instapaper_url","title","url"
@@ -229,7 +207,7 @@ The tool is designed with a modular architecture for reliability and maintainabi
229
207
  "999002345","https://www.instapaper.com/read/999002345","Article 2","https://www.example.com/page-2/"
230
208
  ```
231
209
 
232
- ### 📄 JSON (`output/bookmarks.json`) (with --add-instapaper-url)
210
+ ### JSON (`output/bookmarks.json`) (with --add-instapaper-url)
233
211
 
234
212
  ```json
235
213
  [
@@ -248,33 +226,15 @@ The tool is designed with a modular architecture for reliability and maintainabi
248
226
  ]
249
227
  ```
250
228
 
251
- ### 🗄️ SQLite (`output/bookmarks.db`)
229
+ ### SQLite (`output/bookmarks.db`)
252
230
 
253
231
  A SQLite database file is created with an `articles` table. The table includes `id`, `title`, and `url` columns. If the `--add-instapaper-url` flag is used, a `instapaper_url` column is also included. This feature is fully backward-compatible and will automatically adapt to the user's installed SQLite version, using an efficient generated column on modern versions (3.31.0+) and a fallback for older versions.
254
232
 
255
- ## 🤗 Support and Community
256
-
257
- - **🐛 Bug Reports:** For any bugs or unexpected behavior, please [open an issue on GitHub](https://github.com/chriskyfung/InstapaperScraper/issues).
258
- - **💬 Questions & General Discussion:** For questions, feature requests, or general discussion, please use our [GitHub Discussions](https://github.com/chriskyfung/InstapaperScraper/discussions).
259
-
260
- ## 🙏 Support the Project
261
-
262
- `Instapaper Scraper` is a free and open-source project that requires significant time and effort to maintain and improve. If you find this tool useful, please consider supporting its development. Your contribution helps ensure the project stays healthy, active, and continuously updated.
263
-
264
- - **[Sponsor on GitHub](https://github.com/sponsors/chriskyfung):** The best way to support the project with recurring monthly donations. Tiers with special rewards like priority support are available!
265
- - **[Buy Me a Coffee](https://www.buymeacoffee.com/chriskyfung):** Perfect for a one-time thank you.
233
+ ## Development & Testing
266
234
 
267
- ## 🤝 Contributing
235
+ This project uses `pytest` for testing, `black` for code formatting, and `ruff` for linting.
268
236
 
269
- Contributions are welcome! Whether it's a bug fix, a new feature, or documentation improvements, please feel free to open a pull request.
270
-
271
- Please read the **[Contribution Guidelines](CONTRIBUTING.md)** before you start.
272
-
273
- ## 🧑‍💻 Development & Testing
274
-
275
- This project uses `pytest` for testing, `ruff` for code formatting and linting, and `mypy` for static type checking.
276
-
277
- ### 🔧 Setup
237
+ ### Setup
278
238
 
279
239
  To install the development dependencies:
280
240
 
@@ -282,13 +242,7 @@ To install the development dependencies:
282
242
  pip install -e .[dev]
283
243
  ```
284
244
 
285
- To set up the pre-commit hooks:
286
-
287
- ```sh
288
- pre-commit install
289
- ```
290
-
291
- ### ▶️ Running the Scraper
245
+ ### Running the Scraper
292
246
 
293
247
  To run the scraper directly without installing the package:
294
248
 
@@ -296,7 +250,7 @@ To run the scraper directly without installing the package:
296
250
  python -m src.instapaper_scraper.cli
297
251
  ```
298
252
 
299
- ### Testing
253
+ ### Testing
300
254
 
301
255
  To run the tests, execute the following command from the project root:
302
256
 
@@ -310,12 +264,12 @@ To check test coverage:
310
264
  pytest --cov=src/instapaper_scraper --cov-report=term-missing
311
265
  ```
312
266
 
313
- ### Code Quality
267
+ ### Code Quality
314
268
 
315
- To format the code with `ruff`:
269
+ To format the code with `black`:
316
270
 
317
271
  ```sh
318
- ruff format .
272
+ black .
319
273
  ```
320
274
 
321
275
  To check for linting errors with `ruff`:
@@ -330,23 +284,10 @@ To automatically fix linting errors:
330
284
  ruff check . --fix
331
285
  ```
332
286
 
333
- To run static type checking with `mypy`:
334
-
335
- ```sh
336
- mypy src
337
- ```
338
-
339
- ## 📜 Disclaimer
287
+ ## Disclaimer
340
288
 
341
289
  This script requires valid Instapaper credentials. Use it responsibly and in accordance with Instapaper’s Terms of Service.
342
290
 
343
- ## 📄 License
344
-
345
- This project is licensed under the terms of the **GNU General Public License v3.0**. See the [LICENSE](LICENSE) file for the full license text.
346
-
347
- ## 🙏 Support the Project
348
-
349
- `Instapaper Scraper` is a free and open-source project that requires significant time and effort to maintain and improve. If you find this tool useful, please consider supporting its development. Your contribution helps ensure the project stays healthy, active, and continuously updated.
291
+ ## License
350
292
 
351
- - **[Sponsor on GitHub](https://github.com/sponsors/chriskyfung):** The best way to support the project with recurring monthly donations. Tiers with special rewards like priority support are available!
352
- - **[Buy Me a Coffee](https://www.buymeacoffee.com/chriskyfung):** Perfect for a one-time thank you.
293
+ This project is licensed under the terms of the GNU General Public License v3.0. See the [LICENSE](LICENSE) file for the full license text.
@@ -1,39 +1,18 @@
1
1
  # Instapaper Scraper
2
2
 
3
- <!-- Badges -->
4
- <p align="center">
5
- <a href="https://github.com/chriskyfung/InstapaperScraper">
6
- <img src="https://img.shields.io/python/required-version-toml?tomlFilePath=https%3A%2F%2Fraw.githubusercontent.com%2Fchriskyfung%2FInstapaperScraper%2Frefs%2Fheads%2Fmaster%2Fpyproject.toml" alt="Python Version from PEP 621 TOML">
7
- </a>
8
- <a href="https://github.com/astral-sh/ruff">
9
- <img src="https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2Fastral-sh%2Fruff%2Fmain%2Fassets%2Fbadge%2Fv2.json" alt="Ruff">
10
- </a>
11
- <a href="https://codecov.io/gh/chriskyfung/InstapaperScraper">
12
- <img src="https://codecov.io/gh/chriskyfung/InstapaperScraper/graph/badge.svg" alt="Code Coverage">
13
- </a>
14
- <a href="https://github.com/chriskyfung/InstapaperScraper/actions/workflows/ci.yml">
15
- <img src="https://github.com/chriskyfung/InstapaperScraper/actions/workflows/ci.yml/badge.svg" alt="CI Status">
16
- </a>
17
- <a href="https://pypi.org/project/instapaper-scraper/">
18
- <img src="https://img.shields.io/pypi/v/instapaper-scraper.svg" alt="PyPI version">
19
- </a>
20
- <a href="https://pepy.tech/projects/instapaper-scraper">
21
- <img src="https://static.pepy.tech/personalized-badge/instapaper-scraper?period=total&left_text=downloads" alt="PyPI Downloads">
22
- </a>
23
- <a href="https://www.gnu.org/licenses/gpl-3.0.en.html">
24
- <img src="https://img.shields.io/github/license/chriskyfung/InstapaperScraper" alt="GitHub License">
25
- </a>
26
- <a href="https://github.com/sponsors/chriskyfung" title="Sponsor on GitHub">
27
- <img src="https://img.shields.io/badge/Sponsor-GitHub-purple?logo=github" alt="GitHub Sponsors Default">
28
- </a>
29
- <a href="https://www.buymeacoffee.com/chriskyfung" title="Buy Me A Coffee">
30
- <img src="https://img.shields.io/badge/Support%20Me-Coffee-ffdd00?logo=buy-me-a-coffee&logoColor=white" alt="Buy Me A Coffee">
31
- </a>
32
- </p>
33
-
34
- A powerful and reliable Python tool to automate the export of all your saved Instapaper bookmarks into various formats, giving you full ownership of your data.
35
-
36
- ## ✨ Features
3
+ ![Python Version from PEP 621 TOML](https://img.shields.io/python/required-version-toml?tomlFilePath=https%3A%2F%2Fraw.githubusercontent.com%2Fchriskyfung%2FInstapaperScraper%2Frefs%2Fheads%2Fmaster%2Fpyproject.toml)
4
+ [![CI](https://github.com/chriskyfung/InstapaperScraper/actions/workflows/ci.yml/badge.svg)](https://github.com/chriskyfung/InstapaperScraper/actions/workflows/ci.yml)
5
+ [![PyPI version](https://img.shields.io/pypi/v/instapaper-scraper.svg)](https://pypi.org/project/instapaper-scraper/)
6
+ [![PyPI Downloads](https://static.pepy.tech/personalized-badge/instapaper-scraper?period=total&left_text=downloads)](https://pepy.tech/projects/instapaper-scraper)
7
+ [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
8
+ [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
9
+ [![GitHub License](https://img.shields.io/github/license/chriskyfung/InstapaperScraper)
10
+ ](https://www.gnu.org/licenses/gpl-3.0.en.html)
11
+ [![codecov](https://codecov.io/gh/chriskyfung/InstapaperScraper/graph/badge.svg)](https://codecov.io/gh/chriskyfung/InstapaperScraper)
12
+
13
+ A Python tool to scrape all your saved Instapaper bookmarks and export them to various formats.
14
+
15
+ ## Features
37
16
 
38
17
  - Scrapes all bookmarks from your Instapaper account.
39
18
  - Supports scraping from specific folders.
@@ -41,13 +20,13 @@ A powerful and reliable Python tool to automate the export of all your saved Ins
41
20
  - Securely stores your session for future runs.
42
21
  - Modern, modular, and tested architecture.
43
22
 
44
- ## 🚀 Getting Started
23
+ ## Getting Started
45
24
 
46
- ### 📋 1. Requirements
25
+ ### 1. Requirements
47
26
 
48
27
  - Python 3.9+
49
28
 
50
- ### 📦 2. Installation
29
+ ### 2. Installation
51
30
 
52
31
  This package is available on PyPI and can be installed with pip:
53
32
 
@@ -55,7 +34,7 @@ This package is available on PyPI and can be installed with pip:
55
34
  pip install instapaper-scraper
56
35
  ```
57
36
 
58
- ### 💻 3. Usage
37
+ ### 3. Usage
59
38
 
60
39
  Run the tool from the command line, specifying your desired output format:
61
40
 
@@ -70,35 +49,35 @@ instapaper-scraper --format json
70
49
  instapaper-scraper --format sqlite --output my_articles.db
71
50
  ```
72
51
 
73
- ## ⚙️ Configuration
52
+ ## Configuration
74
53
 
75
- ### 🔐 Authentication
54
+ ### Authentication
76
55
 
77
56
  The script authenticates using one of the following methods, in order of priority:
78
57
 
79
- 1. **Command-line Arguments**: Provide your username and password directly when running the script:
58
+ 1. **Command-line Arguments**: Provide your username and password directly when running the script:
80
59
 
81
60
  ```sh
82
61
  instapaper-scraper --username your_username --password your_password
83
62
  ```
84
63
 
85
- 2. **Session Files (`.session_key`, `.instapaper_session`)**: The script attempts to load these files in the following order:
64
+ 2. **Session Files (`.session_key`, `.instapaper_session`)**: The script attempts to load these files in the following order:
86
65
  a. Path specified by `--session-file` or `--key-file` arguments.
87
66
  b. Files in the current working directory (e.g., `./.session_key`).
88
67
  c. Files in the user's configuration directory (`~/.config/instapaper-scraper/`).
89
68
  After the first successful login, the script creates an encrypted `.instapaper_session` file and a `.session_key` file to reuse your session securely.
90
69
 
91
- 3. **Interactive Prompt**: If no other method is available, the script will prompt you for your username and password.
70
+ 3. **Interactive Prompt**: If no other method is available, the script will prompt you for your username and password.
92
71
 
93
72
  > **Note on Security:** Your session file (`.instapaper_session`) and the encryption key (`.session_key`) are stored with secure permissions (read/write for the owner only) to protect your credentials.
94
73
 
95
- ### 📁 Folder Configuration
74
+ ### Folder Configuration
96
75
 
97
76
  You can define and quickly access your Instapaper folders using a `config.toml` file. The scraper will look for this file in the following locations (in order of precedence):
98
77
 
99
- 1. The path specified by the `--config-path` argument.
100
- 2. `config.toml` in the current working directory.
101
- 3. `~/.config/instapaper-scraper/config.toml`
78
+ 1. The path specified by the `--config-path` argument.
79
+ 2. `config.toml` in the current working directory.
80
+ 3. `~/.config/instapaper-scraper/config.toml`
102
81
 
103
82
  Here is an example of `config.toml`:
104
83
 
@@ -127,7 +106,7 @@ output_filename = "python-articles.db"
127
106
 
128
107
  When a `config.toml` file is present and no `--folder` argument is provided, the scraper will prompt you to select a folder. You can also specify a folder directly using the `--folder` argument with its key, ID, or slug. Use `--folder=none` to explicitly disable folder mode and scrape all articles.
129
108
 
130
- ### 💻 Command-line Arguments
109
+ ### Command-line Arguments
131
110
 
132
111
  | Argument | Description |
133
112
  | --- | --- |
@@ -139,7 +118,7 @@ When a `config.toml` file is present and no `--folder` argument is provided, the
139
118
  | `--password <pass>` | Your Instapaper account password. |
140
119
  | `--add-instapaper-url` | Adds a `instapaper_url` column to the output, containing a full, clickable URL for each article. |
141
120
 
142
- ### 📄 Output Formats
121
+ ### Output Formats
143
122
 
144
123
  You can control the output format using the `--format` argument. The supported formats are:
145
124
 
@@ -151,7 +130,7 @@ If the `--format` flag is omitted, the script will default to `csv`.
151
130
 
152
131
  When using `--output <filename>`, the file extension is automatically corrected to match the chosen format. For example, `instapaper-scraper --format json --output my_articles.txt` will create `my_articles.json`.
153
132
 
154
- #### 📖 Opening Articles in Instapaper
133
+ #### Opening Articles in Instapaper
155
134
 
156
135
  The output data includes a unique `id` for each article. You can use this ID to construct a URL to the article's reader view: `https://www.instapaper.com/read/<article_id>`.
157
136
 
@@ -163,7 +142,7 @@ instapaper-scraper --add-instapaper-url
163
142
 
164
143
  This adds a `instapaper_url` field to each article in the JSON output and a `instapaper_url` column in the CSV and SQLite outputs. The original `id` field is preserved.
165
144
 
166
- ## 🛠️ How It Works
145
+ ## How It Works
167
146
 
168
147
  The tool is designed with a modular architecture for reliability and maintainability.
169
148
 
@@ -172,9 +151,9 @@ The tool is designed with a modular architecture for reliability and maintainabi
172
151
  3. **Data Collection**: All fetched articles are aggregated into a single list.
173
152
  4. **Export**: Finally, the collected data is written to a file in your chosen format (`.csv`, `.json`, or `.db`).
174
153
 
175
- ## 📊 Example Output
154
+ ## Example Output
176
155
 
177
- ### 📄 CSV (`output/bookmarks.csv`) (with --add-instapaper-url)
156
+ ### CSV (`output/bookmarks.csv`) (with --add-instapaper-url)
178
157
 
179
158
  ```csv
180
159
  "id","instapaper_url","title","url"
@@ -182,7 +161,7 @@ The tool is designed with a modular architecture for reliability and maintainabi
182
161
  "999002345","https://www.instapaper.com/read/999002345","Article 2","https://www.example.com/page-2/"
183
162
  ```
184
163
 
185
- ### 📄 JSON (`output/bookmarks.json`) (with --add-instapaper-url)
164
+ ### JSON (`output/bookmarks.json`) (with --add-instapaper-url)
186
165
 
187
166
  ```json
188
167
  [
@@ -201,33 +180,15 @@ The tool is designed with a modular architecture for reliability and maintainabi
201
180
  ]
202
181
  ```
203
182
 
204
- ### 🗄️ SQLite (`output/bookmarks.db`)
183
+ ### SQLite (`output/bookmarks.db`)
205
184
 
206
185
  A SQLite database file is created with an `articles` table. The table includes `id`, `title`, and `url` columns. If the `--add-instapaper-url` flag is used, a `instapaper_url` column is also included. This feature is fully backward-compatible and will automatically adapt to the user's installed SQLite version, using an efficient generated column on modern versions (3.31.0+) and a fallback for older versions.
207
186
 
208
- ## 🤗 Support and Community
209
-
210
- - **🐛 Bug Reports:** For any bugs or unexpected behavior, please [open an issue on GitHub](https://github.com/chriskyfung/InstapaperScraper/issues).
211
- - **💬 Questions & General Discussion:** For questions, feature requests, or general discussion, please use our [GitHub Discussions](https://github.com/chriskyfung/InstapaperScraper/discussions).
212
-
213
- ## 🙏 Support the Project
214
-
215
- `Instapaper Scraper` is a free and open-source project that requires significant time and effort to maintain and improve. If you find this tool useful, please consider supporting its development. Your contribution helps ensure the project stays healthy, active, and continuously updated.
216
-
217
- - **[Sponsor on GitHub](https://github.com/sponsors/chriskyfung):** The best way to support the project with recurring monthly donations. Tiers with special rewards like priority support are available!
218
- - **[Buy Me a Coffee](https://www.buymeacoffee.com/chriskyfung):** Perfect for a one-time thank you.
187
+ ## Development & Testing
219
188
 
220
- ## 🤝 Contributing
189
+ This project uses `pytest` for testing, `black` for code formatting, and `ruff` for linting.
221
190
 
222
- Contributions are welcome! Whether it's a bug fix, a new feature, or documentation improvements, please feel free to open a pull request.
223
-
224
- Please read the **[Contribution Guidelines](CONTRIBUTING.md)** before you start.
225
-
226
- ## 🧑‍💻 Development & Testing
227
-
228
- This project uses `pytest` for testing, `ruff` for code formatting and linting, and `mypy` for static type checking.
229
-
230
- ### 🔧 Setup
191
+ ### Setup
231
192
 
232
193
  To install the development dependencies:
233
194
 
@@ -235,13 +196,7 @@ To install the development dependencies:
235
196
  pip install -e .[dev]
236
197
  ```
237
198
 
238
- To set up the pre-commit hooks:
239
-
240
- ```sh
241
- pre-commit install
242
- ```
243
-
244
- ### ▶️ Running the Scraper
199
+ ### Running the Scraper
245
200
 
246
201
  To run the scraper directly without installing the package:
247
202
 
@@ -249,7 +204,7 @@ To run the scraper directly without installing the package:
249
204
  python -m src.instapaper_scraper.cli
250
205
  ```
251
206
 
252
- ### Testing
207
+ ### Testing
253
208
 
254
209
  To run the tests, execute the following command from the project root:
255
210
 
@@ -263,12 +218,12 @@ To check test coverage:
263
218
  pytest --cov=src/instapaper_scraper --cov-report=term-missing
264
219
  ```
265
220
 
266
- ### Code Quality
221
+ ### Code Quality
267
222
 
268
- To format the code with `ruff`:
223
+ To format the code with `black`:
269
224
 
270
225
  ```sh
271
- ruff format .
226
+ black .
272
227
  ```
273
228
 
274
229
  To check for linting errors with `ruff`:
@@ -283,23 +238,10 @@ To automatically fix linting errors:
283
238
  ruff check . --fix
284
239
  ```
285
240
 
286
- To run static type checking with `mypy`:
287
-
288
- ```sh
289
- mypy src
290
- ```
291
-
292
- ## 📜 Disclaimer
241
+ ## Disclaimer
293
242
 
294
243
  This script requires valid Instapaper credentials. Use it responsibly and in accordance with Instapaper’s Terms of Service.
295
244
 
296
- ## 📄 License
297
-
298
- This project is licensed under the terms of the **GNU General Public License v3.0**. See the [LICENSE](LICENSE) file for the full license text.
299
-
300
- ## 🙏 Support the Project
301
-
302
- `Instapaper Scraper` is a free and open-source project that requires significant time and effort to maintain and improve. If you find this tool useful, please consider supporting its development. Your contribution helps ensure the project stays healthy, active, and continuously updated.
245
+ ## License
303
246
 
304
- - **[Sponsor on GitHub](https://github.com/sponsors/chriskyfung):** The best way to support the project with recurring monthly donations. Tiers with special rewards like priority support are available!
305
- - **[Buy Me a Coffee](https://www.buymeacoffee.com/chriskyfung):** Perfect for a one-time thank you.
247
+ This project is licensed under the terms of the GNU General Public License v3.0. See the [LICENSE](LICENSE) file for the full license text.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "instapaper-scraper"
7
- version = "1.1.0"
7
+ version = "1.1.0rc1"
8
8
  description = "A tool to scrape articles from Instapaper."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -49,33 +49,21 @@ instapaper-scraper = "instapaper_scraper.cli:main"
49
49
  [tool.pytest.ini_options]
50
50
  pythonpath = "src"
51
51
 
52
- [tool.ruff]
52
+ [tool.black]
53
53
  line-length = 88
54
54
 
55
- [tool.ruff.format]
56
- quote-style = "double"
57
-
58
- [tool.mypy]
59
- python_version = "3.9"
60
- warn_return_any = true
61
- warn_unused_configs = true
62
- ignore_missing_imports = true
63
- disallow_untyped_defs = true
64
-
65
- [[tool.mypy.overrides]]
66
- module = "tests.*"
67
- disallow_untyped_defs = false
55
+ [tool.ruff]
56
+ line-length = 88
68
57
 
69
58
  [project.optional-dependencies]
70
59
  dev = [
71
60
  "pytest",
72
61
  "pytest-cov",
62
+ "black",
73
63
  "ruff",
74
64
  "types-requests",
75
65
  "types-beautifulsoup4",
76
66
  "requests-mock",
77
67
  "build",
78
- "twine",
79
- "mypy",
80
- "pre-commit"
68
+ "twine"
81
69
  ]