quickpep 0.2.2 → 0.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
- checksums.yaml.gz.sig +0 -0
- data/data/quickpep.txt +68 -0
- data/lib/quickpep.rb +35 -73
- data.tar.gz.sig +0 -0
- metadata +32 -11
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f0d1b3c004df060369924eb015bd4cac73499aafba8c3c25581a3b2c8c312a44
|
4
|
+
data.tar.gz: a1c8a217a427f3349075ba5c33663f1671de4f2c2f940be542c8fff58b20dd8c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2ec0298bcb429c452ed027a30713297dcf89cd02f32f12b0205424d7696303e97d12dd6685ee0a34a129b64eee993e3e2193f17e7d22a1d14aeb4c8a6a311c68
|
7
|
+
data.tar.gz: 64bf55da82c6c51ffbfd36b3bbc180aecb90ab2e76eeaea1746e5e546c6311358a84e36ba8b8d2335a9634180c745c640ddfe93cf84385434e0f9c3f79772926
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/data/quickpep.txt
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
:html
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta name='viewport' content='width=device-width, initial-scale=1'>
|
5
|
+
<title>#{title}</title>
|
6
|
+
<style>
|
7
|
+
table {border-collapse: collapse; width: 700px}
|
8
|
+
tr:nth-child(even) {
|
9
|
+
background-color: #aca;
|
10
|
+
}
|
11
|
+
@media print {
|
12
|
+
|
13
|
+
tr:nth-child(even) {
|
14
|
+
background-color: #ccc;
|
15
|
+
}
|
16
|
+
|
17
|
+
}
|
18
|
+
table tr td, table thead th {padding: 0.3em; margin: 0.1em}
|
19
|
+
#input table {border: 4px; background-color: #d3a;}
|
20
|
+
#input table thead {color: #131;}
|
21
|
+
#input table tr, #input table td {border: 1px solid green; padding: 3px; background-color: #dea;}
|
22
|
+
#input table tr td {
|
23
|
+
text-align: center;
|
24
|
+
}
|
25
|
+
#summary div {background-color: transparent; float: left; margin: 0.3em; padding: 1.2em; border: 1px solid #18e}
|
26
|
+
|
27
|
+
#breakdown table {background-color: transparent; width: 190px}
|
28
|
+
#breakdown table tr {background-color: transparent;}
|
29
|
+
#costsum table {background-color: transparent; width: 400px}
|
30
|
+
#costsum table tr {background-color: transparent; border-bottom: 1px solid #888;}
|
31
|
+
#costsum table tr td {background-color: transparent; padding: 1.0em 0.5em; margin: 0.4em 0.2em}
|
32
|
+
#summary div ul {list-style-type: none; background-color: transparent; padding: 0.5em; }
|
33
|
+
.break {page-break-before: always}
|
34
|
+
#input {clear: both;}
|
35
|
+
footer {font-size: 0.8em; color: #888;}
|
36
|
+
</style>
|
37
|
+
|
38
|
+
</head>
|
39
|
+
<body>
|
40
|
+
<h1>#{title}</h1>
|
41
|
+
#{html_table}
|
42
|
+
<div id='summary' class='break'>
|
43
|
+
<h2>Summary</h2>
|
44
|
+
|
45
|
+
<div id='breakdown'>
|
46
|
+
<h3>Breakdown</h3>
|
47
|
+
#{html_breakdown}
|
48
|
+
</div>
|
49
|
+
|
50
|
+
<div id='costsum'>
|
51
|
+
<h3>Expense per item</h3>
|
52
|
+
#{html_cs}
|
53
|
+
</div>
|
54
|
+
<div>
|
55
|
+
<h3>Running expense</h3>
|
56
|
+
|
57
|
+
#{html_cpi}
|
58
|
+
</div>
|
59
|
+
</div>
|
60
|
+
<div id='input' class='break'>
|
61
|
+
<h3>Input</h3>
|
62
|
+
|
63
|
+
#{html_table2}
|
64
|
+
</div>
|
65
|
+
<hr/>
|
66
|
+
<footer>Generated by QuickPEP; #{time_now}</footer>
|
67
|
+
</body>
|
68
|
+
</html>
|
data/lib/quickpep.rb
CHANGED
@@ -4,24 +4,38 @@
|
|
4
4
|
|
5
5
|
require 'dynarex'
|
6
6
|
require 'event_nlp'
|
7
|
+
require 'quickpep'
|
8
|
+
|
7
9
|
|
8
10
|
# Quick Personal Expenses Planner - for people too lazy to use a
|
9
|
-
# spreadsheet or
|
11
|
+
# spreadsheet or finance app
|
10
12
|
#
|
11
13
|
class QuickPep
|
12
14
|
using ColouredText
|
13
15
|
|
14
16
|
attr_reader :to_s, :to_dx, :input
|
15
17
|
|
18
|
+
# end_date: should be in natural english format e.g. 2nd October
|
19
|
+
#
|
16
20
|
def initialize(s, balance: 0, currency: '', today: Date.today,
|
17
|
-
ignorewarnings: false, debug: false)
|
21
|
+
ignorewarnings: false, end_date: nil, debug: false)
|
18
22
|
|
19
23
|
@balance, @currency, @debug = balance, currency, debug
|
20
|
-
|
24
|
+
|
25
|
+
@today = if today.is_a?(String) then
|
26
|
+
Chronic.parse(today).to_date
|
27
|
+
else
|
28
|
+
today
|
29
|
+
end
|
30
|
+
|
31
|
+
@end_date = end_date
|
21
32
|
@warnings = []
|
22
33
|
@to_s = calc_expenses(s)
|
23
34
|
|
24
35
|
warnings() if @warnings.any? and not ignorewarnings
|
36
|
+
|
37
|
+
@weblet_file = weblet_file ||= File.join(File.dirname(__FILE__), '..', 'data',
|
38
|
+
'quickpep.txt')
|
25
39
|
|
26
40
|
end
|
27
41
|
|
@@ -67,7 +81,8 @@ class QuickPep
|
|
67
81
|
|
68
82
|
tot = total_expenses().abs
|
69
83
|
r = annual_costs()
|
70
|
-
a = r.
|
84
|
+
a = r.select {| _, cost | cost < 0 }\
|
85
|
+
.map {|title, cost| [title, (100 / (tot / cost.abs)).round] }
|
71
86
|
|
72
87
|
def a.to_table()
|
73
88
|
TableFormatter.new(source: self,
|
@@ -94,7 +109,7 @@ class QuickPep
|
|
94
109
|
t.labels = %w(date: title debit: credit: balance: uid:)
|
95
110
|
table = t.display markdown: true
|
96
111
|
|
97
|
-
tot =
|
112
|
+
tot = total_expenses().abs
|
98
113
|
costs_per_interval = "
|
99
114
|
* daily: #{"%s%0.2f" % [@currency, (tot / 365.0)]}
|
100
115
|
* weekly: #{"%s%0.2f" % [@currency, (tot / 52.0)]}
|
@@ -106,73 +121,17 @@ class QuickPep
|
|
106
121
|
t2.labels = %w(Title Amount: :Day: :Recurring: :Notes:)
|
107
122
|
table2 = t2.display markdown: true
|
108
123
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
tr:nth-child(even) {
|
121
|
-
background-color: #ccc;
|
122
|
-
}
|
123
|
-
|
124
|
-
}
|
125
|
-
table tr td, table thead th {padding: 0.3em; margin: 0.1em}
|
126
|
-
#input table {border: 4px; background-color: #d3a;}
|
127
|
-
#input table thead {color: #131;}
|
128
|
-
#input table tr, #input table td {border: 1px solid green; padding: 3px; background-color: #dea;}
|
129
|
-
#input table tr td {
|
130
|
-
text-align: center;
|
131
|
-
}
|
132
|
-
#summary div {background-color: transparent; float: left; margin: 0.3em; padding: 1.2em; border: 1px solid #18e}
|
133
|
-
|
134
|
-
#breakdown table {background-color: transparent; width: 190px}
|
135
|
-
#breakdown table tr {background-color: transparent;}
|
136
|
-
#costsum table {background-color: transparent; width: 400px}
|
137
|
-
#costsum table tr {background-color: transparent; border-bottom: 1px solid #888;}
|
138
|
-
#costsum table tr td {background-color: transparent; padding: 1.0em 0.5em; margin: 0.4em 0.2em}
|
139
|
-
#summary div ul {list-style-type: none; background-color: transparent; padding: 0.5em; }
|
140
|
-
.break {page-break-before: always}
|
141
|
-
#input {clear: both;}
|
142
|
-
footer {font-size: 0.8em; color: #888;}
|
143
|
-
</style>
|
144
|
-
|
145
|
-
</head>
|
146
|
-
<body>
|
147
|
-
<h1>#{title}</h1>
|
148
|
-
#{RDiscount.new(table).to_html}
|
149
|
-
<div id='summary'>
|
150
|
-
<h2>Summary</h2>
|
151
|
-
|
152
|
-
<div id='breakdown'>
|
153
|
-
<h3>Breakdown</h3>
|
154
|
-
#{RDiscount.new(breakdown().to_table()).to_html}
|
155
|
-
</div>
|
156
|
-
|
157
|
-
<div id='costsum'>
|
158
|
-
<h3>Expense per item</h3>
|
159
|
-
#{RDiscount.new(costs_summary()).to_html}
|
160
|
-
</div>
|
161
|
-
<div>
|
162
|
-
<h3>Running expense</h3>
|
163
|
-
|
164
|
-
#{RDiscount.new(costs_per_interval).to_html}
|
165
|
-
</div>
|
166
|
-
</div>
|
167
|
-
<div id='input'>
|
168
|
-
<h3>Input</h3>
|
169
|
-
|
170
|
-
#{RDiscount.new(table2).to_html}
|
171
|
-
</div>
|
172
|
-
<hr/>
|
173
|
-
<footer>Generated by QuickPEP; #{Time.now.strftime("%d %b %Y")}</footer>
|
174
|
-
</body>
|
175
|
-
</html>"
|
124
|
+
html_table = RDiscount.new(table).to_html
|
125
|
+
html_breakdown = RDiscount.new(breakdown().to_table()).to_html
|
126
|
+
html_cs = RDiscount.new(costs_summary()).to_html
|
127
|
+
html_cpi = RDiscount.new(costs_per_interval).to_html
|
128
|
+
html_table2 = RDiscount.new(table2).to_html
|
129
|
+
time_now = Time.now.strftime("%d %b %Y")
|
130
|
+
|
131
|
+
w = Weblet.new(@weblet_file)
|
132
|
+
|
133
|
+
w.render :html, binding
|
134
|
+
|
176
135
|
end
|
177
136
|
|
178
137
|
def total_expenses()
|
@@ -202,7 +161,10 @@ class QuickPep
|
|
202
161
|
title = [rx.title, rx.day, recurring].join(' ')
|
203
162
|
puts '1. title: ' + title.inspect if @debug
|
204
163
|
e = EventNlp.new(@today.to_time)
|
205
|
-
|
164
|
+
title2 = @end_date ? (title + ' until ' + @end_date) : title
|
165
|
+
puts 'title2: ' + title2.inspect if @debug
|
166
|
+
#exit
|
167
|
+
e.project(title2).map {|x| [x.to_date, e.parse(title).title]}
|
206
168
|
|
207
169
|
end.clone.sort_by(&:first)
|
208
170
|
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: quickpep
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Robertson
|
@@ -35,7 +35,7 @@ cert_chain:
|
|
35
35
|
kmcJnzHNiVwSBry7rnILYU3ouLJeHEtQY1v/S4KqPXGNS1FPvas3Wb429Cui2LtB
|
36
36
|
CkYfvLZCZS1SZGB2dGilreNS
|
37
37
|
-----END CERTIFICATE-----
|
38
|
-
date:
|
38
|
+
date: 2023-03-30 00:00:00.000000000 Z
|
39
39
|
dependencies:
|
40
40
|
- !ruby/object:Gem::Dependency
|
41
41
|
name: event_nlp
|
@@ -43,46 +43,67 @@ dependencies:
|
|
43
43
|
requirements:
|
44
44
|
- - "~>"
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: '0.
|
46
|
+
version: '0.8'
|
47
47
|
- - ">="
|
48
48
|
- !ruby/object:Gem::Version
|
49
|
-
version: 0.
|
49
|
+
version: 0.8.1
|
50
50
|
type: :runtime
|
51
51
|
prerelease: false
|
52
52
|
version_requirements: !ruby/object:Gem::Requirement
|
53
53
|
requirements:
|
54
54
|
- - "~>"
|
55
55
|
- !ruby/object:Gem::Version
|
56
|
-
version: '0.
|
56
|
+
version: '0.8'
|
57
57
|
- - ">="
|
58
58
|
- !ruby/object:Gem::Version
|
59
|
-
version: 0.
|
59
|
+
version: 0.8.1
|
60
60
|
- !ruby/object:Gem::Dependency
|
61
61
|
name: dynarex
|
62
62
|
requirement: !ruby/object:Gem::Requirement
|
63
63
|
requirements:
|
64
64
|
- - "~>"
|
65
65
|
- !ruby/object:Gem::Version
|
66
|
-
version: '1.
|
66
|
+
version: '1.10'
|
67
67
|
- - ">="
|
68
68
|
- !ruby/object:Gem::Version
|
69
|
-
version: 1.
|
69
|
+
version: 1.10.0
|
70
70
|
type: :runtime
|
71
71
|
prerelease: false
|
72
72
|
version_requirements: !ruby/object:Gem::Requirement
|
73
73
|
requirements:
|
74
74
|
- - "~>"
|
75
75
|
- !ruby/object:Gem::Version
|
76
|
-
version: '1.
|
76
|
+
version: '1.10'
|
77
77
|
- - ">="
|
78
78
|
- !ruby/object:Gem::Version
|
79
|
-
version: 1.
|
79
|
+
version: 1.10.0
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: weblet
|
82
|
+
requirement: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - "~>"
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '0.4'
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.4.1
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0.4'
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: 0.4.1
|
80
100
|
description:
|
81
101
|
email: digital.robertson@gmail.com
|
82
102
|
executables: []
|
83
103
|
extensions: []
|
84
104
|
extra_rdoc_files: []
|
85
105
|
files:
|
106
|
+
- data/quickpep.txt
|
86
107
|
- lib/quickpep.rb
|
87
108
|
homepage: https://github.com/jrobertson/quickpep
|
88
109
|
licenses:
|
@@ -103,7 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
103
124
|
- !ruby/object:Gem::Version
|
104
125
|
version: '0'
|
105
126
|
requirements: []
|
106
|
-
rubygems_version: 3.
|
127
|
+
rubygems_version: 3.4.4
|
107
128
|
signing_key:
|
108
129
|
specification_version: 4
|
109
130
|
summary: Quick Personal Expenses Planner - for people too lazy to use a spreadsheet
|
metadata.gz.sig
CHANGED
Binary file
|