pdfh 3.1.0 → 3.3.0
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.
- checksums.yaml +4 -4
- data/.gitignore +0 -1
- data/.pre-commit-config.yaml +36 -0
- data/.rubocop.yml +4 -3
- data/.rubocop_todo.yml +15 -36
- data/Gemfile.lock +81 -61
- data/README.md +56 -18
- data/bin/run +3 -1
- data/exe/pdfh +2 -16
- data/lib/pdfh/concerns/password_decodable.rb +31 -0
- data/lib/pdfh/main.rb +66 -16
- data/lib/pdfh/models/document.rb +12 -16
- data/lib/pdfh/models/document_sub_type.rb +1 -1
- data/lib/pdfh/models/document_type.rb +46 -28
- data/lib/pdfh/models/settings.rb +28 -4
- data/lib/pdfh/models/zip_types.rb +17 -0
- data/lib/pdfh/utils/console.rb +8 -0
- data/lib/pdfh/utils/dependency_validator.rb +35 -0
- data/lib/pdfh/utils/opt_parser.rb +61 -46
- data/lib/pdfh/utils/pdf_file_handler.rb +2 -1
- data/lib/pdfh/utils/settings_builder.rb +8 -3
- data/lib/pdfh/version.rb +1 -1
- data/lib/pdfh.rb +9 -1
- data/mise.toml +2 -0
- metadata +8 -7
- data/.tool-versions +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 29f90e2cbc737c2ea6f15b58f6a46513d90ac68053c770018a5a2549b76adcc6
|
4
|
+
data.tar.gz: 476440f76e4cd8eb0cdc248d9040cbf75fc510656ff1129d83d18bc1f9edf8ec
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 10672062c7041f020920bf4c51a9af88d82130d4db59f8a332a5b05df055bf6079c127b4c8d7d31fb145f9fc88b9527bc330a83f23d2f0dc69c92e843c8246ba
|
7
|
+
data.tar.gz: 606afc6611bb8036cd073c8a5a031dbc0812d2385de77d1b774c2c49b42673f266e4020c679a558dc3d709b3309e1e9d8708d2a8a7b6808f66b4d1ae770da780
|
data/.gitignore
CHANGED
@@ -0,0 +1,36 @@
|
|
1
|
+
# See https://pre-commit.com for more information
|
2
|
+
# See https://pre-commit.com/hooks.html for more hooks
|
3
|
+
default_install_hook_types:
|
4
|
+
- pre-commit
|
5
|
+
- commit-msg
|
6
|
+
|
7
|
+
repos:
|
8
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
9
|
+
rev: v5.0.0
|
10
|
+
hooks:
|
11
|
+
- id: trailing-whitespace
|
12
|
+
- id: end-of-file-fixer
|
13
|
+
exclude: ^.idea/
|
14
|
+
- id: check-yaml
|
15
|
+
- id: check-added-large-files
|
16
|
+
- id: check-executables-have-shebangs
|
17
|
+
- id: check-shebang-scripts-are-executable
|
18
|
+
- id: mixed-line-ending
|
19
|
+
- repo: https://github.com/gitleaks/gitleaks
|
20
|
+
rev: v8.25.0
|
21
|
+
hooks:
|
22
|
+
- id: gitleaks
|
23
|
+
- repo: https://github.com/rubocop/rubocop
|
24
|
+
rev: v1.75.4
|
25
|
+
hooks:
|
26
|
+
- id: rubocop
|
27
|
+
- repo: https://github.com/compilerla/conventional-pre-commit
|
28
|
+
rev: v4.1.0
|
29
|
+
hooks:
|
30
|
+
- id: conventional-pre-commit
|
31
|
+
stages: [commit-msg]
|
32
|
+
args: []
|
33
|
+
- repo: https://github.com/codespell-project/codespell
|
34
|
+
rev: v2.4.1
|
35
|
+
hooks:
|
36
|
+
- id: codespell
|
data/.rubocop.yml
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
inherit_from: .rubocop_todo.yml
|
2
2
|
|
3
|
-
|
4
|
-
- rubocop-factory_bot
|
3
|
+
plugins:
|
5
4
|
- rubocop-performance
|
5
|
+
- rubocop-factory_bot
|
6
6
|
- rubocop-rake
|
7
|
-
- rubocop-rspec
|
8
7
|
|
9
8
|
AllCops:
|
10
9
|
NewCops: enable
|
@@ -14,6 +13,8 @@ AllCops:
|
|
14
13
|
- pkg/**/*
|
15
14
|
- tmp/**/*
|
16
15
|
- vendor/**/*
|
16
|
+
SuggestExtensions:
|
17
|
+
rubocop-rspec: false
|
17
18
|
|
18
19
|
Layout/LineLength:
|
19
20
|
Max: 120
|
data/.rubocop_todo.yml
CHANGED
@@ -1,54 +1,33 @@
|
|
1
1
|
# This configuration was generated by
|
2
2
|
# `rubocop --auto-gen-config`
|
3
|
-
# on
|
3
|
+
# on 2025-04-19 20:15:39 UTC using RuboCop version 1.75.2.
|
4
4
|
# The point is for the user to remove these configuration records
|
5
5
|
# one by one as the offenses are removed from the code base.
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
7
7
|
# versions of RuboCop, may require this file to be generated again.
|
8
8
|
|
9
|
-
# Offense count:
|
9
|
+
# Offense count: 10
|
10
10
|
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
|
11
11
|
Metrics/AbcSize:
|
12
|
-
Max:
|
12
|
+
Max: 38
|
13
|
+
|
14
|
+
# Offense count: 16
|
15
|
+
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
|
16
|
+
# AllowedMethods: refine
|
17
|
+
Metrics/BlockLength:
|
18
|
+
Max: 131
|
13
19
|
|
14
20
|
# Offense count: 6
|
15
21
|
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
|
16
22
|
Metrics/MethodLength:
|
17
|
-
Max:
|
18
|
-
|
19
|
-
# Offense count: 2
|
20
|
-
RSpec/AnyInstance:
|
21
|
-
Exclude:
|
22
|
-
- 'spec/pdfh/main_spec.rb'
|
23
|
-
|
24
|
-
# Offense count: 8
|
25
|
-
# Configuration parameters: Include, CustomTransform, IgnoreMethods, SpecSuffixOnly.
|
26
|
-
# Include: **/*_spec*rb*, **/spec/**/*
|
27
|
-
RSpec/FilePath:
|
28
|
-
Exclude:
|
29
|
-
- 'spec/pdfh/models/document_period_spec.rb'
|
30
|
-
- 'spec/pdfh/models/document_spec.rb'
|
31
|
-
- 'spec/pdfh/utils/console_spec.rb'
|
32
|
-
- 'spec/pdfh/utils/month_spec.rb'
|
33
|
-
- 'spec/pdfh/utils/opt_parser_spec.rb'
|
34
|
-
- 'spec/pdfh/utils/pdf_file_handler_spec.rb'
|
35
|
-
- 'spec/pdfh/utils/rename_validator_spec.rb'
|
36
|
-
- 'spec/pdfh/utils/settings_builder_spec.rb'
|
23
|
+
Max: 33
|
37
24
|
|
38
|
-
# Offense count:
|
39
|
-
# Configuration parameters:
|
40
|
-
#
|
41
|
-
|
25
|
+
# Offense count: 1
|
26
|
+
# Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames.
|
27
|
+
# AllowedNames: as, at, by, cc, db, id, if, in, io, ip, of, on, os, pp, to
|
28
|
+
Naming/MethodParameterName:
|
42
29
|
Exclude:
|
43
|
-
- '
|
44
|
-
- 'spec/pdfh/models/document_period_spec.rb'
|
45
|
-
- 'spec/pdfh/models/document_spec.rb'
|
46
|
-
- 'spec/pdfh/utils/console_spec.rb'
|
47
|
-
- 'spec/pdfh/utils/month_spec.rb'
|
48
|
-
- 'spec/pdfh/utils/opt_parser_spec.rb'
|
49
|
-
- 'spec/pdfh/utils/pdf_file_handler_spec.rb'
|
50
|
-
- 'spec/pdfh/utils/rename_validator_spec.rb'
|
51
|
-
- 'spec/pdfh/utils/settings_builder_spec.rb'
|
30
|
+
- 'lib/pdfh/utils/console.rb'
|
52
31
|
|
53
32
|
# Offense count: 3
|
54
33
|
# This cop supports safe autocorrection (--autocorrect).
|
data/Gemfile.lock
CHANGED
@@ -1,131 +1,151 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
pdfh (3.
|
4
|
+
pdfh (3.3.0)
|
5
5
|
colorize (~> 1.1.0)
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
|
-
activesupport (
|
10
|
+
activesupport (8.0.2)
|
11
11
|
base64
|
12
|
+
benchmark (>= 0.3)
|
12
13
|
bigdecimal
|
13
|
-
concurrent-ruby (~> 1.0, >= 1.
|
14
|
+
concurrent-ruby (~> 1.0, >= 1.3.1)
|
14
15
|
connection_pool (>= 2.2.5)
|
15
16
|
drb
|
16
17
|
i18n (>= 1.6, < 2)
|
18
|
+
logger (>= 1.4.2)
|
17
19
|
minitest (>= 5.1)
|
18
|
-
|
19
|
-
tzinfo (~> 2.0)
|
20
|
+
securerandom (>= 0.3)
|
21
|
+
tzinfo (~> 2.0, >= 2.0.5)
|
22
|
+
uri (>= 0.13.1)
|
20
23
|
ansi (1.5.0)
|
21
|
-
ast (2.4.
|
24
|
+
ast (2.4.3)
|
22
25
|
base64 (0.2.0)
|
23
|
-
|
26
|
+
benchmark (0.4.0)
|
27
|
+
bigdecimal (3.1.9)
|
24
28
|
blockenspiel (0.5.0)
|
25
29
|
code-scanning-rubocop (0.6.1)
|
26
30
|
rubocop (~> 1.0)
|
27
31
|
coderay (1.1.3)
|
28
32
|
colorize (1.1.0)
|
29
|
-
concurrent-ruby (1.
|
30
|
-
connection_pool (2.
|
31
|
-
|
33
|
+
concurrent-ruby (1.3.5)
|
34
|
+
connection_pool (2.5.3)
|
35
|
+
date (3.4.1)
|
36
|
+
debug (1.10.0)
|
32
37
|
irb (~> 1.10)
|
33
38
|
reline (>= 0.3.8)
|
34
|
-
diff-lcs (1.
|
35
|
-
docile (1.4.
|
39
|
+
diff-lcs (1.6.1)
|
40
|
+
docile (1.4.1)
|
36
41
|
drb (2.2.1)
|
37
|
-
factory_bot (6.
|
38
|
-
activesupport (>=
|
39
|
-
i18n (1.14.
|
42
|
+
factory_bot (6.5.1)
|
43
|
+
activesupport (>= 6.1.0)
|
44
|
+
i18n (1.14.7)
|
40
45
|
concurrent-ruby (~> 1.0)
|
41
|
-
io-console (0.
|
42
|
-
irb (1.
|
46
|
+
io-console (0.8.0)
|
47
|
+
irb (1.15.2)
|
48
|
+
pp (>= 0.6.0)
|
43
49
|
rdoc (>= 4.0.0)
|
44
50
|
reline (>= 0.4.2)
|
45
|
-
json (2.
|
46
|
-
language_server-protocol (3.17.0.
|
51
|
+
json (2.11.3)
|
52
|
+
language_server-protocol (3.17.0.4)
|
53
|
+
lint_roller (1.1.0)
|
54
|
+
logger (1.7.0)
|
47
55
|
method_source (1.1.0)
|
48
|
-
minitest (5.
|
49
|
-
|
50
|
-
|
51
|
-
parser (3.3.1.0)
|
56
|
+
minitest (5.25.5)
|
57
|
+
parallel (1.27.0)
|
58
|
+
parser (3.3.8.0)
|
52
59
|
ast (~> 2.4.1)
|
53
60
|
racc
|
54
|
-
|
61
|
+
pp (0.6.2)
|
62
|
+
prettyprint
|
63
|
+
prettyprint (0.2.0)
|
64
|
+
prism (1.4.0)
|
65
|
+
pry (0.15.2)
|
55
66
|
coderay (~> 1.1)
|
56
67
|
method_source (~> 1.0)
|
57
|
-
psych (5.
|
68
|
+
psych (5.2.4)
|
69
|
+
date
|
58
70
|
stringio
|
59
|
-
racc (1.
|
71
|
+
racc (1.8.1)
|
60
72
|
rainbow (3.1.1)
|
61
73
|
rake (13.2.1)
|
62
|
-
rdoc (6.
|
74
|
+
rdoc (6.13.1)
|
63
75
|
psych (>= 4.0.0)
|
64
|
-
regexp_parser (2.
|
65
|
-
reline (0.
|
76
|
+
regexp_parser (2.10.0)
|
77
|
+
reline (0.6.1)
|
66
78
|
io-console (~> 0.5)
|
67
|
-
rexml (3.2.6)
|
68
79
|
rspec (3.13.0)
|
69
80
|
rspec-core (~> 3.13.0)
|
70
81
|
rspec-expectations (~> 3.13.0)
|
71
82
|
rspec-mocks (~> 3.13.0)
|
72
|
-
rspec-core (3.13.
|
83
|
+
rspec-core (3.13.3)
|
73
84
|
rspec-support (~> 3.13.0)
|
74
|
-
rspec-expectations (3.13.
|
85
|
+
rspec-expectations (3.13.4)
|
75
86
|
diff-lcs (>= 1.2.0, < 2.0)
|
76
87
|
rspec-support (~> 3.13.0)
|
77
|
-
rspec-mocks (3.13.
|
88
|
+
rspec-mocks (3.13.4)
|
78
89
|
diff-lcs (>= 1.2.0, < 2.0)
|
79
90
|
rspec-support (~> 3.13.0)
|
80
|
-
rspec-support (3.13.
|
91
|
+
rspec-support (3.13.3)
|
81
92
|
rspec_junit_formatter (0.6.0)
|
82
93
|
rspec-core (>= 2, < 4, != 2.12.0)
|
83
|
-
rubocop (1.
|
94
|
+
rubocop (1.75.5)
|
84
95
|
json (~> 2.3)
|
85
|
-
language_server-protocol (
|
96
|
+
language_server-protocol (~> 3.17.0.2)
|
97
|
+
lint_roller (~> 1.1.0)
|
86
98
|
parallel (~> 1.10)
|
87
99
|
parser (>= 3.3.0.2)
|
88
100
|
rainbow (>= 2.2.2, < 4.0)
|
89
|
-
regexp_parser (>=
|
90
|
-
|
91
|
-
rubocop-ast (>= 1.31.1, < 2.0)
|
101
|
+
regexp_parser (>= 2.9.3, < 3.0)
|
102
|
+
rubocop-ast (>= 1.44.0, < 2.0)
|
92
103
|
ruby-progressbar (~> 1.7)
|
93
|
-
unicode-display_width (>= 2.4.0, <
|
94
|
-
rubocop-ast (1.
|
95
|
-
parser (>= 3.3.
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
rubocop (~> 1.
|
100
|
-
rubocop-
|
101
|
-
|
102
|
-
rubocop
|
103
|
-
rubocop-
|
104
|
-
|
105
|
-
|
104
|
+
unicode-display_width (>= 2.4.0, < 4.0)
|
105
|
+
rubocop-ast (1.44.1)
|
106
|
+
parser (>= 3.3.7.2)
|
107
|
+
prism (~> 1.4)
|
108
|
+
rubocop-capybara (2.22.1)
|
109
|
+
lint_roller (~> 1.1)
|
110
|
+
rubocop (~> 1.72, >= 1.72.1)
|
111
|
+
rubocop-factory_bot (2.27.1)
|
112
|
+
lint_roller (~> 1.1)
|
113
|
+
rubocop (~> 1.72, >= 1.72.1)
|
114
|
+
rubocop-performance (1.25.0)
|
115
|
+
lint_roller (~> 1.1)
|
116
|
+
rubocop (>= 1.75.0, < 2.0)
|
117
|
+
rubocop-ast (>= 1.38.0, < 2.0)
|
118
|
+
rubocop-rake (0.7.1)
|
119
|
+
lint_roller (~> 1.1)
|
120
|
+
rubocop (>= 1.72.1)
|
121
|
+
rubocop-rspec (2.31.0)
|
106
122
|
rubocop (~> 1.40)
|
107
123
|
rubocop-capybara (~> 2.17)
|
108
124
|
rubocop-factory_bot (~> 2.22)
|
109
125
|
rubocop-rspec_rails (~> 2.28)
|
110
|
-
rubocop-rspec_rails (2.
|
111
|
-
rubocop (~> 1.
|
126
|
+
rubocop-rspec_rails (2.29.1)
|
127
|
+
rubocop (~> 1.61)
|
112
128
|
ruby-progressbar (1.13.0)
|
129
|
+
securerandom (0.4.1)
|
113
130
|
simplecov (0.22.0)
|
114
131
|
docile (~> 1.1)
|
115
132
|
simplecov-html (~> 0.11)
|
116
133
|
simplecov_json_formatter (~> 0.1)
|
117
|
-
simplecov-console (0.9.
|
134
|
+
simplecov-console (0.9.3)
|
118
135
|
ansi
|
119
136
|
simplecov
|
120
137
|
terminal-table
|
121
|
-
simplecov-html (0.
|
138
|
+
simplecov-html (0.13.1)
|
122
139
|
simplecov_json_formatter (0.1.4)
|
123
|
-
stringio (3.1.
|
124
|
-
terminal-table (
|
125
|
-
unicode-display_width (>= 1.1.1, <
|
140
|
+
stringio (3.1.7)
|
141
|
+
terminal-table (4.0.0)
|
142
|
+
unicode-display_width (>= 1.1.1, < 4)
|
126
143
|
tzinfo (2.0.6)
|
127
144
|
concurrent-ruby (~> 1.0)
|
128
|
-
unicode-display_width (
|
145
|
+
unicode-display_width (3.1.4)
|
146
|
+
unicode-emoji (~> 4.0, >= 4.0.4)
|
147
|
+
unicode-emoji (4.0.4)
|
148
|
+
uri (1.0.3)
|
129
149
|
versionomy (0.5.0)
|
130
150
|
blockenspiel (~> 0.5)
|
131
151
|
|
@@ -151,4 +171,4 @@ DEPENDENCIES
|
|
151
171
|
versionomy (~> 0.5)
|
152
172
|
|
153
173
|
BUNDLED WITH
|
154
|
-
2.
|
174
|
+
2.6.8
|
data/README.md
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
[![Conventional Commits][cc-img]][cc-url]
|
6
6
|
[![Current version][gem-img]][gem-url]
|
7
7
|
|
8
|
-
Examine all PDF files in
|
8
|
+
Examine all PDF files in lookup directories, remove passwords (if present), rename them, and copy them to a new directory using regular expressions.
|
9
9
|
|
10
10
|
## Installation
|
11
11
|
|
@@ -20,8 +20,7 @@ You need to install pdf handling dependencies in order to use this gem.
|
|
20
20
|
#### macOS
|
21
21
|
|
22
22
|
```bash
|
23
|
-
brew install qpdf # for
|
24
|
-
brew install xpdf # for pdftotext
|
23
|
+
brew install qpdf xpdf # < for pdftotext
|
25
24
|
```
|
26
25
|
|
27
26
|
#### Fedora
|
@@ -30,36 +29,66 @@ brew install xpdf # for pdftotext
|
|
30
29
|
sudo dnf install -y qpdf poppler-utils
|
31
30
|
```
|
32
31
|
|
32
|
+
#### Arch
|
33
|
+
|
34
|
+
```bash
|
35
|
+
sudo pacman -S qpdf poppler
|
36
|
+
```
|
37
|
+
|
33
38
|
## Usage
|
34
39
|
|
35
|
-
After installing this gem
|
40
|
+
After installing this gem, create your configuration file in one of the following directories:
|
41
|
+
- `~/.config/pdfh.yml`
|
42
|
+
- `~/pdfh.yml`
|
43
|
+
- or configure the `PDFH_CONFIG_FILE` environment variable
|
36
44
|
|
45
|
+
Example configuration:
|
37
46
|
```yaml
|
38
47
|
---
|
39
|
-
lookup_dirs:
|
48
|
+
lookup_dirs: # Directories where all PDFs will be analyzed
|
40
49
|
- ~/Downloads
|
41
50
|
destination_base_path: ~/PDFs # Directory where all matching documents will be copied (MUST exist)
|
42
51
|
document_types:
|
43
|
-
- name:
|
52
|
+
- name: My Bank # Description (type)
|
44
53
|
re_file: '.*MyBankReg\.pdf' # Regular expression to match its filename
|
45
|
-
re_date: '
|
46
|
-
pwd:
|
54
|
+
re_date: '\d{1,2} de (\w+) de (\d+)' # Date regular expression
|
55
|
+
pwd: base64_encoded # [OPTIONAL] Password if the document is protected
|
47
56
|
store_path: "{year}/bank_docs" # Relative path to copy this document
|
48
57
|
name_template: '{period} {subtype}' # Template for new filename when copied
|
49
58
|
sub_types: # [OPTIONAL] In case your need an extra category
|
50
|
-
- name:
|
59
|
+
- name: AccountX # Regular expression to match this subtype
|
60
|
+
re_date: '\d{1,2} de (\w+)' # [OPTIONAL] Date regular expression
|
51
61
|
month_offset: -1 # [OPTIONAL] Integer (signed) value to adjust month
|
62
|
+
zip_types: # [OPTIONAL] Zip files to be processed BEFORE the PDFs
|
63
|
+
- name: My Bank 2 # Description
|
64
|
+
re_file: 'Document_MR5664_\d+_\d+.zip' # Regular expression to match its filename
|
65
|
+
pwd: base64_encoded # [OPTIONAL] Password if the document is protected
|
52
66
|
```
|
53
67
|
|
68
|
+
> [!CAUTION]
|
69
|
+
> `pwd` is not encrypted, so be careful with this option. It is stored as a base64 string as a very thin layer of obfuscation.
|
70
|
+
> You can use `echo -n 'password' | base64` to encode your password.
|
71
|
+
|
54
72
|
**Store Path** and **Name Template** supported placeholders:
|
55
73
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
74
|
+
Placeholder | Description | Example
|
75
|
+
--- |---------------------------| ---
|
76
|
+
`{original}` | Original filename | MyBankDocument2.pdf
|
77
|
+
`{period}` | Year-Month | 2022-01
|
78
|
+
`{year}` | Year | 2022
|
79
|
+
`{month}` | Month | 01
|
80
|
+
`{type}` | Document type **name** | My Bank
|
81
|
+
`{subtype}` | Sub type **name** | AccountX
|
82
|
+
`{extra}` | day if captured/matched | 01
|
83
|
+
|
84
|
+
`period`, `year`, `month` and `{extra}` are calculated from the date captured by the regular expression.
|
85
|
+
|
86
|
+
### Examples
|
87
|
+
|
88
|
+
Date text | RegEx | Captured
|
89
|
+
--- | --- | ---
|
90
|
+
`01/02/2025` | `(?<d>\d{2}\/(?<m>\d{2})\/(?<y>\d{4})` | d: `01` m: `02` y: `2025`
|
91
|
+
`072025 - ` | `(?<m>\d{2})(?<y>\d{4}) -` | m: `07` y: `2025`
|
63
92
|
|
64
93
|
## Development
|
65
94
|
|
@@ -75,6 +104,15 @@ build pdfh.gemspec
|
|
75
104
|
gem install pdfh-*
|
76
105
|
```
|
77
106
|
|
107
|
+
To release a new version, run:
|
108
|
+
|
109
|
+
```bash
|
110
|
+
rake bump
|
111
|
+
rake release
|
112
|
+
```
|
113
|
+
|
114
|
+
This will create a git tag for the version, push git commits and tags, and upload the `.gem` file to rubygems.org.
|
115
|
+
|
78
116
|
### Conventional Commits
|
79
117
|
|
80
118
|
```bash
|
@@ -84,7 +122,7 @@ commitlint --from origin --to @
|
|
84
122
|
|
85
123
|
## Contributing
|
86
124
|
|
87
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/iax7/pdfh
|
125
|
+
Bug reports and pull requests are welcome on GitHub at <https://github.com/iax7/pdfh>. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
88
126
|
|
89
127
|
## License
|
90
128
|
|
@@ -97,7 +135,7 @@ Everyone interacting in the Pdfh project’s codebases, issue trackers, chat roo
|
|
97
135
|
<!-- Links -->
|
98
136
|
[rubocop-img]: https://github.com/iax7/pdfh/actions/workflows/rubocop-analysis.yml/badge.svg
|
99
137
|
[rubocop-url]: https://github.com/iax7/pdfh/actions/workflows/rubocop-analysis.yml
|
100
|
-
[ruby-img]: https://img.shields.io/badge/ruby-3.
|
138
|
+
[ruby-img]: https://img.shields.io/badge/ruby-3.4-blue?style=flat&logo=ruby&logoColor=CC342D&labelColor=white
|
101
139
|
[ruby-url]: https://www.ruby-lang.org/en/
|
102
140
|
[cc-img]: https://img.shields.io/badge/Conventional%20Commits-1.0.0-%23FE5196?logo=conventionalcommits&logoColor=00&labelColor=fff
|
103
141
|
[cc-url]: https://conventionalcommits.org
|
data/bin/run
CHANGED
data/exe/pdfh
CHANGED
@@ -1,26 +1,12 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require "open3"
|
5
4
|
require "pdfh"
|
6
5
|
|
7
|
-
|
8
|
-
# @return [Boolean]
|
9
|
-
def validate_installed(*apps)
|
10
|
-
found_app = []
|
11
|
-
apps.each_with_object(found_app) do |app, result|
|
12
|
-
_stdout, _stderr, status = Open3.capture3("command -v #{app}")
|
13
|
-
puts "Missing #{app} command." unless status.success?
|
14
|
-
result << status.success?
|
15
|
-
end
|
16
|
-
|
17
|
-
found_app.all?
|
18
|
-
end
|
19
|
-
|
20
|
-
exit(1) unless validate_installed("qpdf", "pdftotext")
|
6
|
+
exit(1) if Pdfh::Utils::DependencyValidator.missing?(*Pdfh::REQUIRED_CMDS)
|
21
7
|
|
22
8
|
begin
|
23
|
-
Pdfh::Main.start
|
9
|
+
Pdfh::Main.start(argv: ARGV)
|
24
10
|
rescue StandardError => e
|
25
11
|
Pdfh.error_print e.message
|
26
12
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Pdfh
|
4
|
+
module Concerns
|
5
|
+
# Module that provides password handling capabilities for classes that contain
|
6
|
+
# password attributes. It handles Base64-encoded passwords by automatically
|
7
|
+
# detecting and decoding them when accessed through the password method.
|
8
|
+
module PasswordDecodable
|
9
|
+
# Returns the decoded password if it's Base64 encoded, otherwise returns it as is
|
10
|
+
# @return [String]
|
11
|
+
def password
|
12
|
+
return Base64.decode64(pwd) if base64?
|
13
|
+
|
14
|
+
pwd
|
15
|
+
end
|
16
|
+
|
17
|
+
# @return [Boolean]
|
18
|
+
def password?
|
19
|
+
base64?
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
# @return [boolean]
|
25
|
+
def base64?
|
26
|
+
pwd.is_a?(String) && pwd.size.positive? &&
|
27
|
+
Base64.strict_encode64(Base64.decode64(pwd)) == pwd
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|