pypaperless-cli2 0.1.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 (30) hide show
  1. pypaperless_cli2-0.1.0/LICENSE +22 -0
  2. pypaperless_cli2-0.1.0/PKG-INFO +174 -0
  3. pypaperless_cli2-0.1.0/README.md +151 -0
  4. pypaperless_cli2-0.1.0/pyproject.toml +31 -0
  5. pypaperless_cli2-0.1.0/src/pypaperless_cli/__init__.py +0 -0
  6. pypaperless_cli2-0.1.0/src/pypaperless_cli/api.py +16 -0
  7. pypaperless_cli2-0.1.0/src/pypaperless_cli/app.py +186 -0
  8. pypaperless_cli2-0.1.0/src/pypaperless_cli/commands/__init__.py +6 -0
  9. pypaperless_cli2-0.1.0/src/pypaperless_cli/commands/auth.py +166 -0
  10. pypaperless_cli2-0.1.0/src/pypaperless_cli/commands/document/__init__.py +14 -0
  11. pypaperless_cli2-0.1.0/src/pypaperless_cli/commands/document/edit.py +159 -0
  12. pypaperless_cli2-0.1.0/src/pypaperless_cli/commands/document/show.py +120 -0
  13. pypaperless_cli2-0.1.0/src/pypaperless_cli/config/__init__.py +2 -0
  14. pypaperless_cli2-0.1.0/src/pypaperless_cli/config/account.py +50 -0
  15. pypaperless_cli2-0.1.0/src/pypaperless_cli/config/config.py +274 -0
  16. pypaperless_cli2-0.1.0/src/pypaperless_cli/const.py +7 -0
  17. pypaperless_cli2-0.1.0/src/pypaperless_cli/py.typed +0 -0
  18. pypaperless_cli2-0.1.0/src/pypaperless_cli/utils/__init__.py +1 -0
  19. pypaperless_cli2-0.1.0/src/pypaperless_cli/utils/converters/__init__.py +22 -0
  20. pypaperless_cli2-0.1.0/src/pypaperless_cli/utils/converters/custom_field.py +66 -0
  21. pypaperless_cli2-0.1.0/src/pypaperless_cli/utils/converters/helpers/__init__.py +3 -0
  22. pypaperless_cli2-0.1.0/src/pypaperless_cli/utils/converters/helpers/strtobool.py +19 -0
  23. pypaperless_cli2-0.1.0/src/pypaperless_cli/utils/converters/tag.py +32 -0
  24. pypaperless_cli2-0.1.0/src/pypaperless_cli/utils/groups.py +39 -0
  25. pypaperless_cli2-0.1.0/src/pypaperless_cli/utils/highlighter.py +11 -0
  26. pypaperless_cli2-0.1.0/src/pypaperless_cli/utils/types.py +27 -0
  27. pypaperless_cli2-0.1.0/src/pypaperless_cli/utils/validators/__init__.py +42 -0
  28. pypaperless_cli2-0.1.0/src/pypaperless_cli/utils/validators/custom_field.py +32 -0
  29. pypaperless_cli2-0.1.0/src/pypaperless_cli/utils/validators/document.py +27 -0
  30. pypaperless_cli2-0.1.0/src/pypaperless_cli/utils/validators/tag.py +31 -0
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Marcel Brückner
4
+ Copyright (c) 2026 Julian Pirner (pypaperless-cli2 fork)
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
@@ -0,0 +1,174 @@
1
+ Metadata-Version: 2.4
2
+ Name: pypaperless-cli2
3
+ Version: 0.1.0
4
+ Summary: Command-line interface for Paperless-ngx (fork of pypaperless-cli, updated for pypaperless 5.x / Paperless-ngx 3.x)
5
+ License-File: LICENSE
6
+ Author: Marcel Brückner
7
+ Author-email: marcelbrueckner@users.noreply.github.com
8
+ Requires-Python: >=3.12,<4.0
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: 3.12
11
+ Classifier: Programming Language :: Python :: 3.13
12
+ Classifier: Programming Language :: Python :: 3.14
13
+ Requires-Dist: arrow (>=1.3.0,<2.0.0)
14
+ Requires-Dist: cyclopts (>=2.5.0,<3.0.0)
15
+ Requires-Dist: httpx (>=0.27.0,<0.28.0)
16
+ Requires-Dist: pypaperless (>=5.1.0,<6.0.0)
17
+ Requires-Dist: tomlkit (>=0.12.4,<0.13.0)
18
+ Requires-Dist: xdg-base-dirs (>=6.0.1,<7.0.0)
19
+ Project-URL: Homepage, https://gitlab.jpi-it.com/j.pirner/pypaperless-cli2
20
+ Project-URL: Repository, https://gitlab.jpi-it.com/j.pirner/pypaperless-cli2
21
+ Description-Content-Type: text/markdown
22
+
23
+ # paperless-ngx-cli (pypaperless-cli2)
24
+
25
+ Paperless-ngx Command-Line Interface
26
+
27
+ This is a fork of [Marcel Brückner's `pypaperless-cli`](https://github.com/marcelbrueckner/paperless-ngx-cli), republished as `pypaperless-cli2` with the `pypaperless` dependency updated to `^5.1.0` for compatibility with Paperless-ngx ≥3.0 (which rejects the older API versions requested by `pypaperless` 4.x with `406 Not Acceptable`). The `pngx` command and all usage below are unchanged from upstream.
28
+
29
+ I've recently started a project to collect scripts around Paperless-ngx ([paperless.sh](https://paperless.sh)). It turned out - surprise - to be very tedious to write a separate [script](https://github.com/marcelbrueckner/paperless.sh/blob/6cc85b20482e0281d9e26ab82fcaccf34e27a276/scripts/post-consumption/content-matching/pngx-update-document.py) [each](https://github.com/marcelbrueckner/paperless.sh/blob/6cc85b20482e0281d9e26ab82fcaccf34e27a276/scripts/api/custom-field-sum/custom-field-sum.py) [time](https://github.com/marcelbrueckner/paperless.sh/blob/6cc85b20482e0281d9e26ab82fcaccf34e27a276/scripts/api/custom-field-sum/custom-field-sum-of-differences.py) I need to work with Paperless-ngx's API.
30
+ I was looking for a way to easily update certain fields of my documents but without the overhead of "manually" calling API endpoints each time.
31
+ I wrapped things in simple python scripts which eventually became this tool which essentially ~~is~~ will become Paperless-ngx at your command-line.
32
+
33
+ ## Usage
34
+
35
+ This very first public release currently only allows you to retrieve information or update certain fields of your existing documents (with more to come in the future).
36
+
37
+ ```bash
38
+ # Run pngx -h for help
39
+ $ pngx [ command ] [ subcommand ] [ arguments and parameters ]
40
+ ```
41
+
42
+ Log in to your Paperless-ngx instance which will be used in subsequent commands.
43
+
44
+ ```bash
45
+ # Log in to the given host and save account credentials as default
46
+ $ pngx auth login https://paperless.example.com --ask-token
47
+ # Delete saved credentials from disk
48
+ $ pngx auth logout
49
+ ```
50
+
51
+ Show details of a document with specific ID
52
+
53
+ ```bash
54
+ # Run pngx document show -h for help
55
+ $ pngx document show <ID>
56
+ Title 2024-01-10_RE12345678
57
+ ID 400
58
+ ASN None
59
+ Created 2024-01-10
60
+ ...
61
+ ```
62
+
63
+ Update a document's title and correspondent.
64
+
65
+ ```bash
66
+ # Set document title to "My new document title" and set specific correspondent
67
+ $ pngx document edit <ID> --title "My new document title" --correspondent <CORRESPONDENT_ID>
68
+ ```
69
+
70
+ Assign or unassign a document's tags.
71
+
72
+ Tags can be specified by ID or the *exact* name. If your tag name contains spaces, wrap it in quotes.
73
+
74
+ You can add and remove multiple tags at once, separated by space.
75
+
76
+ ```bash
77
+ # Add or remove one or multiple tags to/from a document given the ID or _exact_ name
78
+ $ pngx document edit <ID> --add-tags <ID|EXACT_NAME> [ID|EXACT_NAME]
79
+ $ pngx document edit <ID> --remove-tags <ID|EXACT_NAME> [ID|EXACT_NAME]
80
+ ```
81
+
82
+ Add, update or remove custom fields.
83
+
84
+ Similar to tags, custom fields can be specified by ID or the *exact* name, which must be quoted if it contains spaces.
85
+ In addition, custom fields can have a value that can be passed in a KEY=VALUE style. Make sure your value adheres to the custom field's type. If your custom field name contains an equal sign, refer to it by its ID.
86
+
87
+ You can add and remove multiple custom fields at once, separated by space.
88
+
89
+ ```bash
90
+ # Add/Update or remove custom field given the ID or _exact_ name
91
+ $ pngx document edit <ID> --add-custom-fields <ID|EXACT_NAME>[=VALUE] [<ID|EXACT_NAME>[=VALUE]]
92
+ $ pngx document edit <ID> --remove-custom-fields <ID|EXACT_NAME> [<ID|EXACT_NAME>]
93
+ ```
94
+
95
+ ## Configuration
96
+
97
+ The Paperless-ngx CLI client can be configured in a variety of ways.
98
+ In order of precedence from lowest (most easily overridden) to highest (overrides all others), it offers the following configuration sources:
99
+
100
+ * applications defaults
101
+ * configuration file
102
+ * environment variables
103
+ * command-line parameters
104
+
105
+ ### Application defaults
106
+
107
+ There's only one application default:
108
+
109
+ * the CLI client configuration file (which defaults to `$XDG_CONFIG_HOME/pngx/pngx.toml`[^1])
110
+
111
+ [^1]: In case you don't know about the *XDG Base Directory Specification*, check out [their docs](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html).
112
+
113
+ ### Configuration file
114
+
115
+ The Paperless-ngx CLI client can read all basic configuration (the Paperless-ngx server's authentication information) from its configuration file (`pngx.toml`). A custom file path can be specified via:
116
+
117
+ * command-line parameter (`--config`)
118
+ * environment variable (`$PNGX_CONFIG`)
119
+
120
+ If both are specified, the command-line parameter takes precedence. Otherwise, it uses the first `pngx.toml` file found at these locations in order:
121
+
122
+ * `$PWD/pngx.toml`
123
+ * `$XDG_CONFIG_HOME/pngx/pngx.toml` (application default)
124
+
125
+ If no configuration file can be found, it will be created at the application default location.
126
+
127
+ Run `pngx --show-config` to get the configuration file path in use.
128
+
129
+ ```bash
130
+ # Default configuration path if no pngx.toml exists in current working directory
131
+ $ pngx --show-config
132
+ /Users/marcelbrueckner/.config/pngx/pngx.toml
133
+ ```
134
+
135
+ Obviously, you can't specify a configuration path within the configuration file itself.
136
+
137
+ ### Environment variables
138
+
139
+ If you don't want your credentials to be stored on disk, you can use environment variables or ad-hoc session parameters (see command-line below)
140
+
141
+ Environment variables have a higher precedence than entries in `pngx.toml`. Existing environment variables override corresponding values in your configuration file. If you can't connect to your Paperless-ngx instance, make sure you don't have accidentially mixed values from your configuration file and environment.
142
+
143
+ * `PNGX_HOST`
144
+ * `PNGX_USER`
145
+ * `PNGX_TOKEN`
146
+
147
+ * `PNGX_CONFIG`
148
+
149
+ ### Command-line parameters
150
+
151
+ You can use the command-line to log in to your Paperless-ngx instance. The credentials provided will be saved to your configuration file.
152
+
153
+ ```bash
154
+ # Store your credentials for subsequent usage
155
+ # Your credentials might end up in your shell history, so be cautious!
156
+
157
+ # Don't do that
158
+ $ pngx auth login --host=https://paperless.example.com --user=username --password=password
159
+ # Use this instead
160
+ $ pngx auth login --host=https://paperless.example.com --user=username --ask-password|--ask-token
161
+ ```
162
+
163
+ If you don't want your credentials saved to file, use them as ad-hoc session parameters.
164
+
165
+ ```bash
166
+ $ pngx --host=https://paperless.example.com --user=username --ask-password|--ask-token auth show
167
+ ```
168
+
169
+ ## Caveats
170
+
171
+ Paperless-ngx CLI allows you to add servers whose API can be accessed without authentication. However, the underlying `pypaperless` library this CLI is using doesn't look like it supports anything else than token authentication. I guess that you will likely run into errors if you don't use token authentication on your Paperless-ngx server instance. Maybe a token can be generated while using remote user auth, but it's untested at this point.
172
+
173
+ This fork has been checked against Paperless-ngx 3.0.5; the upstream project was tested against v2.5.3. As with upstream, compatibility depends on the `pypaperless` library tracking whatever HTTP API version Paperless-ngx currently requires.
174
+
@@ -0,0 +1,151 @@
1
+ # paperless-ngx-cli (pypaperless-cli2)
2
+
3
+ Paperless-ngx Command-Line Interface
4
+
5
+ This is a fork of [Marcel Brückner's `pypaperless-cli`](https://github.com/marcelbrueckner/paperless-ngx-cli), republished as `pypaperless-cli2` with the `pypaperless` dependency updated to `^5.1.0` for compatibility with Paperless-ngx ≥3.0 (which rejects the older API versions requested by `pypaperless` 4.x with `406 Not Acceptable`). The `pngx` command and all usage below are unchanged from upstream.
6
+
7
+ I've recently started a project to collect scripts around Paperless-ngx ([paperless.sh](https://paperless.sh)). It turned out - surprise - to be very tedious to write a separate [script](https://github.com/marcelbrueckner/paperless.sh/blob/6cc85b20482e0281d9e26ab82fcaccf34e27a276/scripts/post-consumption/content-matching/pngx-update-document.py) [each](https://github.com/marcelbrueckner/paperless.sh/blob/6cc85b20482e0281d9e26ab82fcaccf34e27a276/scripts/api/custom-field-sum/custom-field-sum.py) [time](https://github.com/marcelbrueckner/paperless.sh/blob/6cc85b20482e0281d9e26ab82fcaccf34e27a276/scripts/api/custom-field-sum/custom-field-sum-of-differences.py) I need to work with Paperless-ngx's API.
8
+ I was looking for a way to easily update certain fields of my documents but without the overhead of "manually" calling API endpoints each time.
9
+ I wrapped things in simple python scripts which eventually became this tool which essentially ~~is~~ will become Paperless-ngx at your command-line.
10
+
11
+ ## Usage
12
+
13
+ This very first public release currently only allows you to retrieve information or update certain fields of your existing documents (with more to come in the future).
14
+
15
+ ```bash
16
+ # Run pngx -h for help
17
+ $ pngx [ command ] [ subcommand ] [ arguments and parameters ]
18
+ ```
19
+
20
+ Log in to your Paperless-ngx instance which will be used in subsequent commands.
21
+
22
+ ```bash
23
+ # Log in to the given host and save account credentials as default
24
+ $ pngx auth login https://paperless.example.com --ask-token
25
+ # Delete saved credentials from disk
26
+ $ pngx auth logout
27
+ ```
28
+
29
+ Show details of a document with specific ID
30
+
31
+ ```bash
32
+ # Run pngx document show -h for help
33
+ $ pngx document show <ID>
34
+ Title 2024-01-10_RE12345678
35
+ ID 400
36
+ ASN None
37
+ Created 2024-01-10
38
+ ...
39
+ ```
40
+
41
+ Update a document's title and correspondent.
42
+
43
+ ```bash
44
+ # Set document title to "My new document title" and set specific correspondent
45
+ $ pngx document edit <ID> --title "My new document title" --correspondent <CORRESPONDENT_ID>
46
+ ```
47
+
48
+ Assign or unassign a document's tags.
49
+
50
+ Tags can be specified by ID or the *exact* name. If your tag name contains spaces, wrap it in quotes.
51
+
52
+ You can add and remove multiple tags at once, separated by space.
53
+
54
+ ```bash
55
+ # Add or remove one or multiple tags to/from a document given the ID or _exact_ name
56
+ $ pngx document edit <ID> --add-tags <ID|EXACT_NAME> [ID|EXACT_NAME]
57
+ $ pngx document edit <ID> --remove-tags <ID|EXACT_NAME> [ID|EXACT_NAME]
58
+ ```
59
+
60
+ Add, update or remove custom fields.
61
+
62
+ Similar to tags, custom fields can be specified by ID or the *exact* name, which must be quoted if it contains spaces.
63
+ In addition, custom fields can have a value that can be passed in a KEY=VALUE style. Make sure your value adheres to the custom field's type. If your custom field name contains an equal sign, refer to it by its ID.
64
+
65
+ You can add and remove multiple custom fields at once, separated by space.
66
+
67
+ ```bash
68
+ # Add/Update or remove custom field given the ID or _exact_ name
69
+ $ pngx document edit <ID> --add-custom-fields <ID|EXACT_NAME>[=VALUE] [<ID|EXACT_NAME>[=VALUE]]
70
+ $ pngx document edit <ID> --remove-custom-fields <ID|EXACT_NAME> [<ID|EXACT_NAME>]
71
+ ```
72
+
73
+ ## Configuration
74
+
75
+ The Paperless-ngx CLI client can be configured in a variety of ways.
76
+ In order of precedence from lowest (most easily overridden) to highest (overrides all others), it offers the following configuration sources:
77
+
78
+ * applications defaults
79
+ * configuration file
80
+ * environment variables
81
+ * command-line parameters
82
+
83
+ ### Application defaults
84
+
85
+ There's only one application default:
86
+
87
+ * the CLI client configuration file (which defaults to `$XDG_CONFIG_HOME/pngx/pngx.toml`[^1])
88
+
89
+ [^1]: In case you don't know about the *XDG Base Directory Specification*, check out [their docs](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html).
90
+
91
+ ### Configuration file
92
+
93
+ The Paperless-ngx CLI client can read all basic configuration (the Paperless-ngx server's authentication information) from its configuration file (`pngx.toml`). A custom file path can be specified via:
94
+
95
+ * command-line parameter (`--config`)
96
+ * environment variable (`$PNGX_CONFIG`)
97
+
98
+ If both are specified, the command-line parameter takes precedence. Otherwise, it uses the first `pngx.toml` file found at these locations in order:
99
+
100
+ * `$PWD/pngx.toml`
101
+ * `$XDG_CONFIG_HOME/pngx/pngx.toml` (application default)
102
+
103
+ If no configuration file can be found, it will be created at the application default location.
104
+
105
+ Run `pngx --show-config` to get the configuration file path in use.
106
+
107
+ ```bash
108
+ # Default configuration path if no pngx.toml exists in current working directory
109
+ $ pngx --show-config
110
+ /Users/marcelbrueckner/.config/pngx/pngx.toml
111
+ ```
112
+
113
+ Obviously, you can't specify a configuration path within the configuration file itself.
114
+
115
+ ### Environment variables
116
+
117
+ If you don't want your credentials to be stored on disk, you can use environment variables or ad-hoc session parameters (see command-line below)
118
+
119
+ Environment variables have a higher precedence than entries in `pngx.toml`. Existing environment variables override corresponding values in your configuration file. If you can't connect to your Paperless-ngx instance, make sure you don't have accidentially mixed values from your configuration file and environment.
120
+
121
+ * `PNGX_HOST`
122
+ * `PNGX_USER`
123
+ * `PNGX_TOKEN`
124
+
125
+ * `PNGX_CONFIG`
126
+
127
+ ### Command-line parameters
128
+
129
+ You can use the command-line to log in to your Paperless-ngx instance. The credentials provided will be saved to your configuration file.
130
+
131
+ ```bash
132
+ # Store your credentials for subsequent usage
133
+ # Your credentials might end up in your shell history, so be cautious!
134
+
135
+ # Don't do that
136
+ $ pngx auth login --host=https://paperless.example.com --user=username --password=password
137
+ # Use this instead
138
+ $ pngx auth login --host=https://paperless.example.com --user=username --ask-password|--ask-token
139
+ ```
140
+
141
+ If you don't want your credentials saved to file, use them as ad-hoc session parameters.
142
+
143
+ ```bash
144
+ $ pngx --host=https://paperless.example.com --user=username --ask-password|--ask-token auth show
145
+ ```
146
+
147
+ ## Caveats
148
+
149
+ Paperless-ngx CLI allows you to add servers whose API can be accessed without authentication. However, the underlying `pypaperless` library this CLI is using doesn't look like it supports anything else than token authentication. I guess that you will likely run into errors if you don't use token authentication on your Paperless-ngx server instance. Maybe a token can be generated while using remote user auth, but it's untested at this point.
150
+
151
+ This fork has been checked against Paperless-ngx 3.0.5; the upstream project was tested against v2.5.3. As with upstream, compatibility depends on the `pypaperless` library tracking whatever HTTP API version Paperless-ngx currently requires.
@@ -0,0 +1,31 @@
1
+ [tool.poetry]
2
+ name = "pypaperless-cli2"
3
+ version = "0.1.0"
4
+ description = "Command-line interface for Paperless-ngx (fork of pypaperless-cli, updated for pypaperless 5.x / Paperless-ngx 3.x)"
5
+ authors = ["Marcel Brückner <marcelbrueckner@users.noreply.github.com>"]
6
+ readme = "README.md"
7
+ homepage = "https://gitlab.jpi-it.com/j.pirner/pypaperless-cli2"
8
+ repository = "https://gitlab.jpi-it.com/j.pirner/pypaperless-cli2"
9
+ packages = [{include = "pypaperless_cli", from = "src"}]
10
+
11
+ [tool.poetry.scripts]
12
+ pngx = "pypaperless_cli.app:launch"
13
+
14
+ [tool.poetry.dependencies]
15
+ python = "^3.12"
16
+ arrow = "^1.3.0"
17
+ httpx = "^0.27.0"
18
+ cyclopts = "^2.5.0"
19
+ tomlkit = "^0.12.4"
20
+ xdg-base-dirs = "^6.0.1"
21
+ pypaperless = "^5.1.0"
22
+
23
+ [tool.poetry.group.dev.dependencies]
24
+ mypy = "^1.9.0"
25
+ pytest = "^8.1.1"
26
+ httpx = {extras = ["cli"], version = "^0.27.0"}
27
+
28
+
29
+ [build-system]
30
+ requires = ["poetry-core"]
31
+ build-backend = "poetry.core.masonry.api"
File without changes
@@ -0,0 +1,16 @@
1
+ """Paperless API client"""
2
+
3
+ from aiohttp import ClientSession
4
+ from pypaperless import Paperless
5
+
6
+ from pypaperless_cli.config import config as appconfig
7
+
8
+ class PaperlessAsyncAPI(Paperless):
9
+ """Represent the Paperless API"""
10
+
11
+ def __init__(self):
12
+ session = ClientSession(headers={"User-Agent": f"pypaperless-cli/0.1-dev (https://github.com/marcelbrueckner/paperless-ngx-cli)"})
13
+ super().__init__(appconfig.current.host, appconfig.current.token, session=session)
14
+
15
+ # Don't care about warnings
16
+ self.logger.setLevel("ERROR")
@@ -0,0 +1,186 @@
1
+ #!/usr/bin/env python
2
+
3
+ import sys
4
+ from typing import Annotated, Optional
5
+
6
+ from cyclopts import App, Parameter
7
+ from cyclopts.types import Path
8
+ from cyclopts.exceptions import format_cyclopts_error
9
+
10
+ from rich.prompt import Prompt
11
+ from rich.console import Console
12
+
13
+ from pypaperless_cli.config import config as appconfig
14
+ from pypaperless_cli.utils import groups, validators
15
+ from pypaperless_cli.commands import (
16
+ auth,
17
+ document,
18
+ )
19
+ from pypaperless_cli.utils.types import (
20
+ account_alias,
21
+ URL
22
+ )
23
+
24
+
25
+ # BASIC APP STRUCTURE
26
+ # Loosely based on the Paperless-ngx API and web interface structure
27
+ # https://cyclopts.readthedocs.io/en/latest/commands.html
28
+ # https://docs.paperless-ngx.com/api/
29
+
30
+ app = App(
31
+ name="pngx",
32
+ help="Command-line interface for Paperless-ngx 🌱",
33
+ group_commands=groups.commands,
34
+ version_flags=["--version", "-v"]
35
+ )
36
+
37
+ # Change the group of "--help" and "--version" to the implicit "Help" group.
38
+ app["--help"].group = "Help"
39
+ app["--version"].group = "Help"
40
+
41
+ app.command(auth)
42
+ app.command(document)
43
+
44
+
45
+ #
46
+ # CLI HELP
47
+ #
48
+
49
+ app.meta["--help"].group = "Help"
50
+ app.meta["--version"].group = "Help"
51
+
52
+
53
+ #
54
+ # CLI entry-point
55
+ #
56
+
57
+ # Set up configuration before running the actual application
58
+ @app.meta.default()
59
+ def main(
60
+ *tokens: Annotated[str, Parameter(show=False, allow_leading_hyphen=True)],
61
+ host: Annotated[Optional[URL], Parameter(
62
+ env_var=['PNGX_HOST'],
63
+ group = [groups.meta_parameters, groups.meta_parameters_adhoc],
64
+ )] = None,
65
+ user: Annotated[Optional[str], Parameter(
66
+ env_var = ['PNGX_USER'],
67
+ group = [groups.meta_parameters, groups.meta_parameters_adhoc],
68
+ validator = validators.not_empty,
69
+ )] = None,
70
+ password: Annotated[Optional[str], Parameter(
71
+ env_var = ['PNGX_PASSWORD'],
72
+ negative = "--ask-password",
73
+ group = [groups.meta_parameters, groups.meta_parameters_adhoc, groups.password_xor_token]
74
+ )] = None,
75
+ ask_password: Annotated[Optional[bool], Parameter(
76
+ show = False,
77
+ group = [groups.meta_parameters, groups.meta_parameters_adhoc, groups.password_xor_token]
78
+ )] = None,
79
+ token: Annotated[Optional[str], Parameter(
80
+ env_var = ['PNGX_TOKEN'],
81
+ negative = "--ask-token",
82
+ group = [groups.meta_parameters, groups.meta_parameters_adhoc, groups.password_xor_token],
83
+ )] = None,
84
+ ask_token: Annotated[Optional[bool], Parameter(
85
+ show = False,
86
+ group = [groups.meta_parameters, groups.meta_parameters_adhoc, groups.password_xor_token]
87
+ )] = None,
88
+ config_file: Annotated[Optional[Path], Parameter(
89
+ name = "--config",
90
+ env_var = ['PNGX_CONFIG'],
91
+ group = [groups.meta_parameters, groups.meta_parameters_specific]
92
+ )] = None,
93
+ use_account: Annotated[Optional[account_alias], Parameter(
94
+ name = "--use",
95
+ group = [groups.meta_parameters, groups.meta_parameters_specific],
96
+ validator = validators.starts_with_ascii_letters
97
+ )] = None,
98
+ show_config: Annotated[Optional[bool], Parameter(
99
+ group = [groups.meta_parameters, "Help"],
100
+ negative = [],
101
+ show_default = False
102
+ )] = False,
103
+ ) -> None:
104
+
105
+ """Initiate CLI
106
+
107
+ Parameters
108
+ ----------
109
+ host: str
110
+ The URL of your Paperless-ngx host, possibly including a custom port and/or script path.
111
+ user: str
112
+ Username
113
+ password: str
114
+ Password. Will be used to request an API token only.
115
+ token: str
116
+ API token.
117
+ config_file: Path
118
+ Path to configuration file.
119
+ use_account: str
120
+ Name (alias) of an account that should be used.
121
+
122
+ If an account with the given alias exists, its credentials will be re-used.
123
+ If not specified, the default account will be used (if any).
124
+ show_config: bool
125
+ Show path of the configuration file in use.
126
+ """
127
+
128
+
129
+ if ask_password:
130
+ password = Prompt.ask("What's your password?", password=True)
131
+
132
+ elif ask_token:
133
+ token = Prompt.ask("What's your API token?", password=True)
134
+
135
+ # Parse configuration
136
+ try:
137
+ appconfig.load(config_file, use_account)
138
+ except ValueError as e:
139
+ Console().print(format_cyclopts_error(e))
140
+ sys.exit(1)
141
+
142
+ if show_config:
143
+ print(appconfig.filepath.absolute())
144
+ sys.exit(0)
145
+
146
+ # Add ad-hoc configuration
147
+ if host and not tokens[:2] == ('auth', 'login'):
148
+ try:
149
+ appconfig.add_account(
150
+ host = host,
151
+ user = user,
152
+ password = password,
153
+ token = token,
154
+ alias = "__adhoc__"
155
+ )
156
+ except ValueError as e:
157
+ Console().print(format_cyclopts_error(e))
158
+ sys.exit(1)
159
+
160
+ elif tokens[:2] == ('auth', 'login'):
161
+ # Pass credentials to login function
162
+ if host:
163
+ tokens += (host,)
164
+ if user:
165
+ tokens += ("--user", user)
166
+ if password:
167
+ tokens += ("--password", password)
168
+ if token:
169
+ tokens += ("--token", token)
170
+
171
+ elif not appconfig.list():
172
+ Console().print(format_cyclopts_error("No accounts configured that can be used."))
173
+ sys.exit(1)
174
+
175
+ # Now run the actual app
176
+ try:
177
+ app(tokens)
178
+ except ValueError as e:
179
+ Console().print(format_cyclopts_error(e))
180
+ sys.exit(1)
181
+
182
+
183
+ def launch() -> None:
184
+ """Run commands."""
185
+
186
+ app.meta()
@@ -0,0 +1,6 @@
1
+ """
2
+ Exports for CLI commands.
3
+ """
4
+
5
+ from pypaperless_cli.commands.auth import auth
6
+ from pypaperless_cli.commands.document import document