article-cli 1.0.0__tar.gz → 1.0.3__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.
- {article_cli-1.0.0 → article_cli-1.0.3}/PKG-INFO +4 -2
- {article_cli-1.0.0 → article_cli-1.0.3}/README.md +1 -1
- {article_cli-1.0.0 → article_cli-1.0.3}/pyproject.toml +13 -6
- {article_cli-1.0.0 → article_cli-1.0.3}/src/article_cli/__init__.py +1 -1
- {article_cli-1.0.0 → article_cli-1.0.3}/src/article_cli/__main__.py +1 -1
- {article_cli-1.0.0 → article_cli-1.0.3}/src/article_cli/config.py +1 -1
- {article_cli-1.0.0 → article_cli-1.0.3}/src/article_cli/zotero.py +22 -12
- {article_cli-1.0.0 → article_cli-1.0.3}/.gitignore +0 -0
- {article_cli-1.0.0 → article_cli-1.0.3}/LICENSE +0 -0
- {article_cli-1.0.0 → article_cli-1.0.3}/src/article_cli/cli.py +0 -0
- {article_cli-1.0.0 → article_cli-1.0.3}/src/article_cli/git_manager.py +0 -0
- {article_cli-1.0.0 → article_cli-1.0.3}/tests/__init__.py +0 -0
- {article_cli-1.0.0 → article_cli-1.0.3}/tests/test_config.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: article-cli
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.3
|
|
4
4
|
Summary: CLI tool for managing LaTeX articles with git integration and Zotero bibliography
|
|
5
5
|
Project-URL: Homepage, https://github.com/feelpp/article.cli
|
|
6
6
|
Project-URL: Documentation, https://github.com/feelpp/article.cli#readme
|
|
@@ -47,8 +47,10 @@ Requires-Dist: requests>=2.28.0
|
|
|
47
47
|
Provides-Extra: dev
|
|
48
48
|
Requires-Dist: black>=23.0; extra == 'dev'
|
|
49
49
|
Requires-Dist: flake8>=6.0; extra == 'dev'
|
|
50
|
+
Requires-Dist: mypy>=1.0; extra == 'dev'
|
|
50
51
|
Requires-Dist: pytest-cov; extra == 'dev'
|
|
51
52
|
Requires-Dist: pytest>=7.0; extra == 'dev'
|
|
53
|
+
Requires-Dist: types-requests; extra == 'dev'
|
|
52
54
|
Description-Content-Type: text/markdown
|
|
53
55
|
|
|
54
56
|
# Article CLI
|
|
@@ -121,7 +123,7 @@ Create a `.article-cli.toml` file in your project root for project-specific sett
|
|
|
121
123
|
```toml
|
|
122
124
|
[zotero]
|
|
123
125
|
api_key = "your_api_key_here"
|
|
124
|
-
group_id = "
|
|
126
|
+
group_id = "4678293" # Default for article.template
|
|
125
127
|
# user_id = "your_user_id" # alternative to group_id
|
|
126
128
|
output_file = "references.bib"
|
|
127
129
|
|
|
@@ -68,7 +68,7 @@ Create a `.article-cli.toml` file in your project root for project-specific sett
|
|
|
68
68
|
```toml
|
|
69
69
|
[zotero]
|
|
70
70
|
api_key = "your_api_key_here"
|
|
71
|
-
group_id = "
|
|
71
|
+
group_id = "4678293" # Default for article.template
|
|
72
72
|
# user_id = "your_user_id" # alternative to group_id
|
|
73
73
|
output_file = "references.bib"
|
|
74
74
|
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "article-cli"
|
|
7
|
-
version = "1.0.
|
|
7
|
+
version = "1.0.3"
|
|
8
8
|
authors = [
|
|
9
9
|
{name = "Christophe Prud'homme", email = "prudhomm@cemosis.fr"},
|
|
10
10
|
]
|
|
@@ -37,6 +37,8 @@ dev = [
|
|
|
37
37
|
"pytest-cov",
|
|
38
38
|
"black>=23.0",
|
|
39
39
|
"flake8>=6.0",
|
|
40
|
+
"mypy>=1.0",
|
|
41
|
+
"types-requests",
|
|
40
42
|
]
|
|
41
43
|
|
|
42
44
|
[project.urls]
|
|
@@ -78,19 +80,24 @@ extend-exclude = '''
|
|
|
78
80
|
'''
|
|
79
81
|
|
|
80
82
|
[tool.mypy]
|
|
81
|
-
python_version = "3.
|
|
83
|
+
python_version = "3.9"
|
|
82
84
|
warn_return_any = true
|
|
83
85
|
warn_unused_configs = true
|
|
84
|
-
disallow_untyped_defs =
|
|
85
|
-
disallow_incomplete_defs =
|
|
86
|
+
disallow_untyped_defs = false # Relax for now to avoid breaking changes
|
|
87
|
+
disallow_incomplete_defs = false
|
|
86
88
|
check_untyped_defs = true
|
|
87
|
-
disallow_untyped_decorators =
|
|
89
|
+
disallow_untyped_decorators = false
|
|
88
90
|
no_implicit_optional = true
|
|
89
91
|
warn_redundant_casts = true
|
|
90
92
|
warn_unused_ignores = true
|
|
91
|
-
warn_no_return = true
|
|
93
|
+
warn_no_return = true
|
|
92
94
|
warn_unreachable = true
|
|
93
95
|
strict_equality = true
|
|
96
|
+
ignore_missing_imports = true
|
|
97
|
+
|
|
98
|
+
[[tool.mypy.overrides]]
|
|
99
|
+
module = "requests.*"
|
|
100
|
+
ignore_missing_imports = true
|
|
94
101
|
|
|
95
102
|
[tool.pytest.ini_options]
|
|
96
103
|
testpaths = ["tests"]
|
|
@@ -239,7 +239,7 @@ api_key = "your_api_key_here"
|
|
|
239
239
|
|
|
240
240
|
# Either user_id OR group_id (not both)
|
|
241
241
|
# user_id = "your_user_id"
|
|
242
|
-
group_id = "
|
|
242
|
+
group_id = "4678293" # Default group ID for article.template
|
|
243
243
|
|
|
244
244
|
# Output file for bibliography
|
|
245
245
|
output_file = "references.bib"
|
|
@@ -7,7 +7,7 @@ error handling, and rate limiting.
|
|
|
7
7
|
|
|
8
8
|
import os
|
|
9
9
|
import sys
|
|
10
|
-
from typing import Optional, Tuple, List
|
|
10
|
+
from typing import Optional, Tuple, List, Dict, Any
|
|
11
11
|
import time
|
|
12
12
|
|
|
13
13
|
try:
|
|
@@ -31,22 +31,22 @@ class Colors:
|
|
|
31
31
|
UNDERLINE = "\033[4m"
|
|
32
32
|
|
|
33
33
|
|
|
34
|
-
def print_success(msg: str):
|
|
34
|
+
def print_success(msg: str) -> None:
|
|
35
35
|
"""Print success message in green"""
|
|
36
36
|
print(f"{Colors.OKGREEN}✓ {msg}{Colors.ENDC}")
|
|
37
37
|
|
|
38
38
|
|
|
39
|
-
def print_error(msg: str):
|
|
39
|
+
def print_error(msg: str) -> None:
|
|
40
40
|
"""Print error message in red"""
|
|
41
41
|
print(f"{Colors.FAIL}✗ Error: {msg}{Colors.ENDC}", file=sys.stderr)
|
|
42
42
|
|
|
43
43
|
|
|
44
|
-
def print_warning(msg: str):
|
|
44
|
+
def print_warning(msg: str) -> None:
|
|
45
45
|
"""Print warning message in yellow"""
|
|
46
46
|
print(f"{Colors.WARNING}⚠ Warning: {msg}{Colors.ENDC}")
|
|
47
47
|
|
|
48
48
|
|
|
49
|
-
def print_info(msg: str):
|
|
49
|
+
def print_info(msg: str) -> None:
|
|
50
50
|
"""Print info message in cyan"""
|
|
51
51
|
print(f"{Colors.OKCYAN}ℹ {msg}{Colors.ENDC}")
|
|
52
52
|
|
|
@@ -56,15 +56,21 @@ class ZoteroBibTexUpdater:
|
|
|
56
56
|
|
|
57
57
|
def __init__(
|
|
58
58
|
self,
|
|
59
|
-
api_key: str,
|
|
59
|
+
api_key: Optional[str],
|
|
60
60
|
user_id: Optional[str] = None,
|
|
61
61
|
group_id: Optional[str] = None,
|
|
62
|
-
output_file: str =
|
|
62
|
+
output_file: Optional[str] = None,
|
|
63
63
|
):
|
|
64
|
+
# Validate required parameters
|
|
65
|
+
if not api_key:
|
|
66
|
+
raise ValueError("API key is required")
|
|
67
|
+
if not user_id and not group_id:
|
|
68
|
+
raise ValueError("Either user_id or group_id is required")
|
|
69
|
+
|
|
64
70
|
self.api_key = api_key
|
|
65
71
|
self.user_id = user_id
|
|
66
72
|
self.group_id = group_id
|
|
67
|
-
self.output_file = output_file
|
|
73
|
+
self.output_file = output_file or "references.bib"
|
|
68
74
|
self.base_url = "https://api.zotero.org"
|
|
69
75
|
self.limit = 100
|
|
70
76
|
self._group_name: Optional[str] = None
|
|
@@ -88,7 +94,7 @@ class ZoteroBibTexUpdater:
|
|
|
88
94
|
else:
|
|
89
95
|
raise ValueError("Either user_id or group_id must be provided")
|
|
90
96
|
|
|
91
|
-
def _get_group_info(self) -> Optional[
|
|
97
|
+
def _get_group_info(self) -> Optional[Dict[str, Any]]:
|
|
92
98
|
"""Get group information including name"""
|
|
93
99
|
if not self.group_id:
|
|
94
100
|
return None
|
|
@@ -97,7 +103,7 @@ class ZoteroBibTexUpdater:
|
|
|
97
103
|
url = f"{self.base_url}/groups/{self.group_id}"
|
|
98
104
|
response = self.session.get(url, timeout=10)
|
|
99
105
|
response.raise_for_status()
|
|
100
|
-
return response.json()
|
|
106
|
+
return response.json() # type: ignore
|
|
101
107
|
except Exception as e:
|
|
102
108
|
print_warning(f"Could not fetch group info: {e}")
|
|
103
109
|
return None
|
|
@@ -128,7 +134,11 @@ class ZoteroBibTexUpdater:
|
|
|
128
134
|
Returns:
|
|
129
135
|
Tuple of (response_content, headers_dict)
|
|
130
136
|
"""
|
|
131
|
-
params
|
|
137
|
+
params: Dict[str, str] = {
|
|
138
|
+
"format": "bibtex",
|
|
139
|
+
"start": str(start),
|
|
140
|
+
"limit": str(self.limit),
|
|
141
|
+
}
|
|
132
142
|
|
|
133
143
|
try:
|
|
134
144
|
response = self.session.get(url, params=params, timeout=30)
|
|
@@ -209,7 +219,7 @@ class ZoteroBibTexUpdater:
|
|
|
209
219
|
|
|
210
220
|
return filtered_content, len(empty_entries)
|
|
211
221
|
|
|
212
|
-
def _backup_existing_file(self):
|
|
222
|
+
def _backup_existing_file(self) -> None:
|
|
213
223
|
"""Create a backup of the existing BibTeX file"""
|
|
214
224
|
if os.path.exists(self.output_file):
|
|
215
225
|
backup_file = f"{self.output_file}.backup"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|