migrate project to uv
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -3,6 +3,8 @@ __pycache__/
|
|||||||
*.py[cod]
|
*.py[cod]
|
||||||
*$py.class
|
*$py.class
|
||||||
|
|
||||||
|
*.egg-info/
|
||||||
|
|
||||||
# C extensions
|
# C extensions
|
||||||
*.so
|
*.so
|
||||||
|
|
||||||
|
|||||||
57
README.md
57
README.md
@@ -1,3 +1,58 @@
|
|||||||
# Wallabag tools
|
# Wallabag tools
|
||||||
|
|
||||||
Python tools using the wallabag API.
|
Python tools using the Wallabag API.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install wallabag-tools
|
||||||
|
```
|
||||||
|
|
||||||
|
Or install in development mode:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
uv pip install -e .
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
Create a `config.ini` file with your Wallabag credentials:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[Wallabag Configuration]
|
||||||
|
host = https://your-wallabag-instance.com
|
||||||
|
grant_type = password
|
||||||
|
client_id = your_client_id
|
||||||
|
client_secret = your_client_secret
|
||||||
|
username = your_username
|
||||||
|
password = your_password
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Mass Import
|
||||||
|
|
||||||
|
Import articles from a JSON file:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
uv run wallabag-mass-import --config config.ini --articles articles.json
|
||||||
|
```
|
||||||
|
|
||||||
|
Options:
|
||||||
|
- `--config`: Path to config file (default: config.ini)
|
||||||
|
- `--articles`: Path to articles JSON file (default: articles.json)
|
||||||
|
- `--max-entries`: Maximum number of entries to import (default: 0 = all)
|
||||||
|
- `--max-requests`: Maximum concurrent requests (default: 20)
|
||||||
|
- `--delete-after-import`: Delete entries after import
|
||||||
|
|
||||||
|
### Explorer
|
||||||
|
|
||||||
|
Browse entries in your Wallabag:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
uv run wallabag-explorer --config config.ini --per-page 10
|
||||||
|
```
|
||||||
|
|
||||||
|
Options:
|
||||||
|
- `--config`: Path to config file (default: config.ini)
|
||||||
|
- `--per-page`: Entries per page (default: 10)
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
black==19.10b0
|
|
||||||
mypy==0.770
|
|
||||||
pylint==2.4.4
|
|
||||||
27
pyproject.toml
Normal file
27
pyproject.toml
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
[project]
|
||||||
|
name = "wallabag-tools"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "Python tools using the wallabag API"
|
||||||
|
requires-python = ">=3.10"
|
||||||
|
dependencies = [
|
||||||
|
"aiohttp>=3.9.0",
|
||||||
|
"wallabag-api"
|
||||||
|
]
|
||||||
|
|
||||||
|
[project.scripts]
|
||||||
|
wallabag-explorer = "wallabag_explorer:main"
|
||||||
|
wallabag-mass-import = "wallabag_mass_import:main"
|
||||||
|
|
||||||
|
[tool.setuptools]
|
||||||
|
py-modules = ["helpers", "wallabag_explorer", "wallabag_mass_import"]
|
||||||
|
|
||||||
|
[tool.uv]
|
||||||
|
package = true
|
||||||
|
sources = { wallabag-api = { git = "https://git.gasser.ovh/thib8956/wallabag-api-client.git" } }
|
||||||
|
|
||||||
|
[dependency-groups]
|
||||||
|
dev = [
|
||||||
|
"black>=24.0.0",
|
||||||
|
"mypy>=1.0.0",
|
||||||
|
"pylint>=3.0.0",
|
||||||
|
]
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
aiohttp==3.6.2
|
|
||||||
wallabag-api==1.2.3
|
|
||||||
@@ -1,20 +1,30 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
|
import argparse
|
||||||
import aiohttp
|
import aiohttp
|
||||||
from wallabag_api.wallabag import Wallabag
|
from wallabag_api.wallabag import Wallabag
|
||||||
from helpers import load_configuration, connect_to_wallabag
|
from helpers import load_configuration, connect_to_wallabag
|
||||||
|
|
||||||
|
|
||||||
async def get_paginated_entries(w_api: Wallabag, per_page: int, page: int):
|
async def get_paginated_entries(w_api: Wallabag, per_page: int, page: int):
|
||||||
return await w_api.get_entries(perPage=per_page, page=page)
|
return await w_api.get_entries(perPage=per_page, page=page)
|
||||||
|
|
||||||
|
|
||||||
async def main(path: str, per_page=10):
|
async def async_main(path: str = "config.ini", per_page: int = 10):
|
||||||
async with aiohttp.ClientSession(loop=asyncio.get_event_loop()) as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
configuration = dict(load_configuration(path))
|
configuration = dict(load_configuration(path))
|
||||||
w_api = await connect_to_wallabag(configuration, session)
|
w_api = await connect_to_wallabag(configuration, session)
|
||||||
|
|
||||||
for page in range(1, 10):
|
for page in range(1, 10):
|
||||||
entries = await get_paginated_entries(w_api, per_page, page)
|
entries = await get_paginated_entries(w_api, per_page, page)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument("--config", default="config.ini", help="Path to config file")
|
||||||
|
parser.add_argument("--per-page", type=int, default=10, help="Entries per page")
|
||||||
|
args = parser.parse_args()
|
||||||
|
asyncio.run(async_main(args.config, args.per_page))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
asyncio.run(main("config.ini"), debug=True)
|
main()
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
|
import argparse
|
||||||
import configparser
|
import configparser
|
||||||
import logging
|
import logging
|
||||||
import json
|
import json
|
||||||
@@ -12,8 +13,8 @@ from wallabag_api.wallabag import Wallabag
|
|||||||
logging.basicConfig(level=logging.DEBUG)
|
logging.basicConfig(level=logging.DEBUG)
|
||||||
|
|
||||||
ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
|
ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||||
CONFIG_PATH = os.path.join(ROOT_DIR, "config.ini")
|
DEFAULT_CONFIG_PATH = os.path.join(ROOT_DIR, "config.ini")
|
||||||
ARTICLES_PATH = os.path.join(ROOT_DIR, "articles.json")
|
DEFAULT_ARTICLES_PATH = os.path.join(ROOT_DIR, "articles.json")
|
||||||
|
|
||||||
|
|
||||||
async def post_entry(
|
async def post_entry(
|
||||||
@@ -25,7 +26,6 @@ async def post_entry(
|
|||||||
url=item["url"],
|
url=item["url"],
|
||||||
archive=item["is_archived"],
|
archive=item["is_archived"],
|
||||||
starred=item["is_starred"],
|
starred=item["is_starred"],
|
||||||
# original_url=item["origin_url"],
|
|
||||||
tags=",".join(item["tags"]),
|
tags=",".join(item["tags"]),
|
||||||
)
|
)
|
||||||
logging.info(
|
logging.info(
|
||||||
@@ -71,16 +71,56 @@ async def delete_all_entries(ids: List[int], w_api: Wallabag, max_requests=20):
|
|||||||
await asyncio.gather(*tasks)
|
await asyncio.gather(*tasks)
|
||||||
|
|
||||||
|
|
||||||
async def main():
|
async def async_main(
|
||||||
async with aiohttp.ClientSession(loop=asyncio.get_event_loop()) as session:
|
config_path: str = DEFAULT_CONFIG_PATH,
|
||||||
configuration = dict(load_configuration(CONFIG_PATH))
|
articles_path: str = DEFAULT_ARTICLES_PATH,
|
||||||
|
max_entries: int = 0,
|
||||||
|
max_requests: int = 20,
|
||||||
|
delete_after_import: bool = False,
|
||||||
|
):
|
||||||
|
async with aiohttp.ClientSession() as session:
|
||||||
|
configuration = dict(load_configuration(config_path))
|
||||||
w_api = await connect_to_wallabag(configuration, session)
|
w_api = await connect_to_wallabag(configuration, session)
|
||||||
|
|
||||||
# entry = await w_api.get_entry(62)
|
entries_id = await import_articles(
|
||||||
|
w_api, articles_path, max_entries, max_requests
|
||||||
|
)
|
||||||
|
|
||||||
entries_id = await import_articles(w_api, ARTICLES_PATH)
|
if delete_after_import:
|
||||||
await delete_all_entries(entries_id, w_api)
|
await delete_all_entries(entries_id, w_api, max_requests)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(description="Mass import articles to Wallabag")
|
||||||
|
parser.add_argument(
|
||||||
|
"--config", default=DEFAULT_CONFIG_PATH, help="Path to config file"
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--articles", default=DEFAULT_ARTICLES_PATH, help="Path to articles JSON file"
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--max-entries",
|
||||||
|
type=int,
|
||||||
|
default=0,
|
||||||
|
help="Maximum number of entries to import (0 = all)",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--max-requests", type=int, default=20, help="Maximum concurrent requests"
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--delete-after-import", action="store_true", help="Delete entries after import"
|
||||||
|
)
|
||||||
|
args = parser.parse_args()
|
||||||
|
asyncio.run(
|
||||||
|
async_main(
|
||||||
|
args.config,
|
||||||
|
args.articles,
|
||||||
|
args.max_entries,
|
||||||
|
args.max_requests,
|
||||||
|
args.delete_after_import,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
asyncio.run(main(), debug=True)
|
main()
|
||||||
|
|||||||
Reference in New Issue
Block a user