monopyly 1.5.0__py3-none-any.whl → 1.5.2__py3-none-any.whl

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 (47) hide show
  1. monopyly/CHANGELOG.md +23 -0
  2. monopyly/README.md +2 -2
  3. monopyly/__init__.py +22 -27
  4. monopyly/_version.py +14 -2
  5. monopyly/auth/actions.py +12 -0
  6. monopyly/auth/routes.py +31 -22
  7. monopyly/auth/tools.py +1 -2
  8. monopyly/banking/accounts.py +3 -3
  9. monopyly/banking/banks.py +1 -1
  10. monopyly/banking/routes.py +1 -1
  11. monopyly/banking/transactions.py +14 -5
  12. monopyly/common/forms/utils.py +1 -2
  13. monopyly/common/transactions.py +17 -7
  14. monopyly/core/actions.py +0 -7
  15. monopyly/core/routes.py +0 -6
  16. monopyly/credit/accounts.py +1 -1
  17. monopyly/credit/cards.py +7 -3
  18. monopyly/credit/forms.py +1 -1
  19. monopyly/credit/routes.py +46 -25
  20. monopyly/credit/statements.py +1 -1
  21. monopyly/credit/transactions/_transactions.py +18 -5
  22. monopyly/credit/transactions/activity/parser.py +14 -6
  23. monopyly/credit/transactions/activity/reconciliation.py +20 -1
  24. monopyly/database/__init__.py +1 -56
  25. monopyly/database/models.py +181 -273
  26. monopyly/static/css/style.css +191 -11
  27. monopyly/static/js/create-balance-chart.js +1 -1
  28. monopyly/templates/auth/change_password.html +21 -0
  29. monopyly/templates/auth/login.html +3 -1
  30. monopyly/templates/auth/register.html +17 -7
  31. monopyly/templates/core/profile.html +2 -2
  32. monopyly/templates/credit/statement_reconciliation/statement_reconciliation_inquiry.html +1 -1
  33. monopyly/templates/credit/transaction_submission_page.html +64 -71
  34. monopyly/templates/credit/transactions_table/condensed_row_content.html +0 -1
  35. monopyly/templates/layout.html +2 -2
  36. {monopyly-1.5.0.dist-info → monopyly-1.5.2.dist-info}/METADATA +12 -13
  37. {monopyly-1.5.0.dist-info → monopyly-1.5.2.dist-info}/RECORD +41 -45
  38. {monopyly-1.5.0.dist-info → monopyly-1.5.2.dist-info}/WHEEL +1 -1
  39. monopyly-1.5.2.dist-info/entry_points.txt +2 -0
  40. monopyly/cli/apps.py +0 -108
  41. monopyly/cli/launch.py +0 -135
  42. monopyly/config/__init__.py +0 -1
  43. monopyly/config/default_settings.py +0 -56
  44. monopyly/config/settings.py +0 -59
  45. monopyly-1.5.0.dist-info/entry_points.txt +0 -2
  46. {monopyly-1.5.0.dist-info → monopyly-1.5.2.dist-info}/licenses/COPYING +0 -0
  47. {monopyly-1.5.0.dist-info → monopyly-1.5.2.dist-info}/licenses/LICENSE +0 -0
@@ -1,58 +1,53 @@
1
- monopyly/CHANGELOG.md,sha256=Jk6ffjpSKjzEAD-g3u9U6Iwo4Ip7XayERdLQCQdcyP0,7680
2
- monopyly/README.md,sha256=cm1wli7E-xybYoJr-tsrNgfIO6TPrLsraMUSO26D6xk,9028
3
- monopyly/__init__.py,sha256=2UPhNvpvhuafUZwgSGJEIaOj9LIXzrRO-S8dfB4-FeQ,2203
4
- monopyly/_version.py,sha256=PJLsF_U86F0-FKJiqQYvlSYbBBNG6Ou_GDrNAk-8CDw,160
5
- monopyly/auth/actions.py,sha256=zFDb_EATufsJMzQ4rX0bzlme8e62mXFpYtQvc_k0jEc,375
1
+ monopyly/CHANGELOG.md,sha256=n8WvbwwvHWzmOzhiSYAIAHzk_E7Tb0zqWkrbVfrKFWI,8802
2
+ monopyly/README.md,sha256=zmgiCKvJWPTQManbRHiKU9mcDz8FCMu5vYDZLbRIcUE,9038
3
+ monopyly/__init__.py,sha256=2VZ89v-CbtDbuIL6TnvXxgUm3CcANWTEwO91GHGwV_U,2027
4
+ monopyly/_version.py,sha256=P-JlE1bO3FGbbntvKHqxjgKk7ORvjFhybkK-h8R2s5g,411
5
+ monopyly/auth/actions.py,sha256=uwXg0LVz3QVJxKkiI-YCJMT8OSjUK7R-aEy-XTM0Ghs,702
6
6
  monopyly/auth/blueprint.py,sha256=sFbmTvSBhjv1pn2gJLH5J6zanPLuemmWbgEj5ZKCiTY,244
7
- monopyly/auth/routes.py,sha256=mODJHrdFhffusfbYwQ_wpIY7eAE7Gh7irosIef4Mluc,2902
8
- monopyly/auth/tools.py,sha256=hifCHBN06Ht-FnMhJPzzj-xjMN8uwbeJ-azRVjnT99c,801
9
- monopyly/banking/accounts.py,sha256=yYlXvyhLBQoBZYr_WMk6_3nxlhwU4NEkCYKv5hHFjcM,9828
7
+ monopyly/auth/routes.py,sha256=b2heNwtDe91aJEEEQh1ucWXmJhJECB-qAYO-GfQQiVc,3383
8
+ monopyly/auth/tools.py,sha256=CDMcvRY0A-cJxvKUKOUkDzZHDxveHl-8TzhKyOzsXEs,792
9
+ monopyly/banking/accounts.py,sha256=guOC-yBcTCr74vvxTFZyY7oeBDizKV6UDGTpxayvUL4,9864
10
10
  monopyly/banking/actions.py,sha256=NvButozWJNRuNIiyM-Gy88XLTpIjNcEGSQcLMfEwOUg,3258
11
- monopyly/banking/banks.py,sha256=X1seKJrec-o8z-bM0wVTR42vMx1q5A9Lf2jNUtINlrQ,1745
11
+ monopyly/banking/banks.py,sha256=a-GaBtLu2v-8Bl5Q3lOVKUhK9dgpHdsr1sMs0uYcLOg,1751
12
12
  monopyly/banking/blueprint.py,sha256=PDsqe4DmiT7cDYW9IxxTfizu9Lqol1Lhp7ajMK6fUuI,255
13
13
  monopyly/banking/filters.py,sha256=wCsAUh592B5BmGFC9NqmrJZ0NdQZi21hvy0QsKqhgLg,685
14
14
  monopyly/banking/forms.py,sha256=p-YGZgdKugk3VKILLiQNEH5KQmXop5G8P1Bs4sUqbK0,10506
15
- monopyly/banking/routes.py,sha256=mykWVtV_4f096-NWDWE5aPYoBvGjeNpBSyY9Kb_nQGc,8232
16
- monopyly/banking/transactions.py,sha256=2_wFXl4ZrHzLoFGz72ksYA2_8UvB0N1wtBFd8kTwTyQ,8454
17
- monopyly/cli/apps.py,sha256=4oqsrDUsD3aX90YCHIsdHQy9OHaUxkstgvR6sIDw-AY,3459
18
- monopyly/cli/launch.py,sha256=nPCW3Yx4e35sAQ_K6YH3pqmWCdvnt-NHG90hUV7QKPg,4103
19
- monopyly/common/transactions.py,sha256=AEe86_XoDHzTaGEN5ByzPo0dQD6tA9dq3M9TCHMYPvE,18080
15
+ monopyly/banking/routes.py,sha256=pjIKqflTaOHA4jkZRBQdvVOnCyLR-s-qPZvr0xiilXI,8240
16
+ monopyly/banking/transactions.py,sha256=_jZFKuY9zIus1yao_Y31lg30u3-7uvv2z7EDjKLSioY,8886
17
+ monopyly/common/transactions.py,sha256=V7YcFY0r8kl1tdy9oFSGPsQ-C3P9k3m-k_D-NiChXGI,18321
20
18
  monopyly/common/utils.py,sha256=BjXhfNXGWkAPt-ebldvmZ2z00P8MhKJzjxrJJ6mzRQY,5867
21
19
  monopyly/common/forms/__init__.py,sha256=6iFTlcoaQmCbrjS1KfFhWXQUfyqnA-vKPMVxLyJMlXY,120
22
20
  monopyly/common/forms/_forms.py,sha256=wlLY9pBtFYcOEnFL_dnt62JFtbs88u_B9LXN2eTe_PA,10130
23
21
  monopyly/common/forms/fields.py,sha256=XgvkfszpUAZyIs-osHGFADmzuo0Ni_e78NXtG-grBdI,4082
24
- monopyly/common/forms/utils.py,sha256=awZOtWaohzSW_SZrXhUpJBY1AXPnKBFTG2cqim22Db0,5676
22
+ monopyly/common/forms/utils.py,sha256=QbA6253xL4J01DQNQXL-BM13MgAr_HAM93H8a9Nwh6k,5660
25
23
  monopyly/common/forms/validators.py,sha256=C5_NN8ktvBw6MrSXwv_x9_SQohCNmnp4brNQFELHBlI,1205
26
- monopyly/config/__init__.py,sha256=pW2lHNhsdM2gRjLAWumnLUHZMAOEdprX4aXaONwo6AY,73
27
- monopyly/config/default_settings.py,sha256=jtWz4ElasnAbfBCiRfbsYyy--L6N6jTOGRh3PNWnVj4,1829
28
- monopyly/config/settings.py,sha256=YEctSb8mRDvuMA1tTs1N7862Z2bMY7DPf0xo4Ist2pg,1984
29
- monopyly/core/actions.py,sha256=jkrR5bBN1RG1S4Gtumnk51TkCNf4gfsUZkTi8LKHVHA,4172
24
+ monopyly/core/actions.py,sha256=M0guQPwGacA7aHBhYh8FRN6kXdi6wK2VSsiLoWWTsjU,4018
30
25
  monopyly/core/blueprint.py,sha256=pZyK8ly0UR1BbHx4xwYk1UzakzkVCS8wiMSM8XdCG2U,260
31
26
  monopyly/core/context_processors.py,sha256=ByQGQpOJIpxG3WM3Kv34LbBY0H8HVeR81TDYkdOwJgs,1166
32
27
  monopyly/core/errors.py,sha256=xF4gA3Hv99op3EMV_f2CskHWVLrV-9ckaHKJMWR2h7o,200
33
28
  monopyly/core/filters.py,sha256=uBkNjQyqW-9RkiQG23vngnI1MZXFeh4Rhe5MQqklAEQ,1284
34
29
  monopyly/core/internal_transactions.py,sha256=PImeViMU9rdDDPLXld1xC6bdAoulzRDr0zci4pUQY8I,459
35
- monopyly/core/routes.py,sha256=ADF7LB3hhvwPwIqc5l46sliziM7ZgGXh5vFwKzxlkGA,2747
36
- monopyly/credit/accounts.py,sha256=otQmuTDJZYX868EZl80n89XlzfiwlnBkfSXZa65rSqI,1898
30
+ monopyly/core/routes.py,sha256=FhXL8JrqsumxdUiGsmzSG7fim4Kz5rDxr0Az-3SmI90,2639
31
+ monopyly/credit/accounts.py,sha256=6BvQiPvFMWqdDHp-heYXmcjgzzaGMvrHmwCoNQ3CcvM,1904
37
32
  monopyly/credit/actions.py,sha256=eNtowA16zfP8gmo93H9_LbARJ0JKxhihqy3OhX0bwpQ,7211
38
33
  monopyly/credit/blueprint.py,sha256=XbrMhtyCp2732uWPB2kjn_W8P8pH8RVTwo9P8Pt--Is,251
39
- monopyly/credit/cards.py,sha256=9Ug51aY2-G8SzooLC-FemRNeTBLd9JOpXHFW74EcdLU,5614
40
- monopyly/credit/forms.py,sha256=cs7-uL8Q9mUPUCsPVGo32gYwJpF3wfsHwmDfLBQWNnI,13636
41
- monopyly/credit/routes.py,sha256=qghi2_rx-IHFsVN99Ovd2hjCxC89vmE-eSTiCnjqJ44,21408
42
- monopyly/credit/statements.py,sha256=lRcAgcr9kPnh5GCE6McWfOdY8uCgmg2j2bikSioR3HI,7219
34
+ monopyly/credit/cards.py,sha256=8fOK_Wpgdn484OV95_JJ7hX_oyFDTHkDhETuRdKfVWU,5709
35
+ monopyly/credit/forms.py,sha256=aGARysyBNY04hF43IgbwZfBB6ByG51oqbOivmBXOxsk,13614
36
+ monopyly/credit/routes.py,sha256=LZznSwjmyaHFaeHrKAq4zNePixRXn9dLBpy1LUQi2bk,22262
37
+ monopyly/credit/statements.py,sha256=_kJDqF8WT_bFaVcuklSXiqaLUtP7XSCtVmCfCEILo34,7225
43
38
  monopyly/credit/transactions/__init__.py,sha256=1Exn6T--HtwNCHzS_hDJ0ba7qCB7w_8C-yY3KSxvFKg,165
44
- monopyly/credit/transactions/_transactions.py,sha256=V4gLI6HpiuNppNV5xmJBsPU1YL59HyiNLbh3U2LAvbU,9222
39
+ monopyly/credit/transactions/_transactions.py,sha256=cdatQbL2bUtUjnuoRgdcSXvyG8t0hA4YoDstpk83XEE,9692
45
40
  monopyly/credit/transactions/activity/__init__.py,sha256=Iq5KLXdCf1UCfM9qDRXbYCaz1NmgJMCApK4kGDNJISo,139
46
41
  monopyly/credit/transactions/activity/data.py,sha256=6ND7fz5L1aH2g_2drGz2Xf7maUaJ6RyItLdBeWXBIlA,5849
47
- monopyly/credit/transactions/activity/parser.py,sha256=mvDq6jpLs1Bbma0G-YP1G5prpAltgMd3YTzKg46TNc0,11166
48
- monopyly/credit/transactions/activity/reconciliation.py,sha256=cHcqXAp63hHrNkeb3WoX0bGnJbzrOfe6uKF6L2CF9y0,18798
49
- monopyly/database/__init__.py,sha256=tlZsXmzH8hB5m_RASbKTjPRqLel-xbymqrzo0TPoFCk,3402
50
- monopyly/database/models.py,sha256=nnO6dyf7IJOp3dwIoPrWECnWlRPdocfrMqSD_tT1OSg,15319
42
+ monopyly/credit/transactions/activity/parser.py,sha256=yBEP3jG36iixhA0KN8TXdvE55Jp54L6TMR8xlOjqJMY,11624
43
+ monopyly/credit/transactions/activity/reconciliation.py,sha256=Fs6cQfEbzzYD_PkEBSyHUHJRD4flgOViQGMEOtBidSs,19374
44
+ monopyly/database/__init__.py,sha256=I3iWKiK-3o6uODwFeLOeDO4nGCfNiwvooth9qZfJ5Ok,1639
45
+ monopyly/database/models.py,sha256=O51vxQ_bexli0YTylMqaePOUy_EglFkrk78MSJMTzo8,14046
51
46
  monopyly/database/preloads.sql,sha256=KBS_WYRofFdOVN-IgHzZhfyJrY6ZOwHeExN-fQr3htU,363
52
47
  monopyly/database/schema.sql,sha256=cdl9b5CnYrnQ-lck147GtwArx_JJbX1vF9YYLivTeyw,4660
53
48
  monopyly/database/views.sql,sha256=UTO2QRkVTfQ12bMVkR-O6Qv80DvYo8hngPHn2A1_1F8,3853
54
49
  monopyly/static/jquery-3.7.0.min.js,sha256=2Pmvv0kuTBOenSvLm6bvfBSSHrUJ-3A7x6P5Ebd07_g,87462
55
- monopyly/static/css/style.css,sha256=umkVrUYseu8cPuf2Btt9vs-rTJjeIRo7XcQA2WUs2iM,70040
50
+ monopyly/static/css/style.css,sha256=_XOOIINtBFXZXFZZD1SKcTZkvsHegkBDdlX9zNew7ZQ,73560
56
51
  monopyly/static/favicon/browserconfig.xml,sha256=Zt_AVOxiritWWXoUwPsHpx4vu4kM_butdFVzoYCYbM8,315
57
52
  monopyly/static/favicon/favicon-114.png,sha256=kjElVFiix-kFCMdADkLpJsi8kL3GDsFm85oJhyCH-C0,20601
58
53
  monopyly/static/favicon/favicon-120.png,sha256=g4uzHMdW0MlJhcgWfrOsj2MB2D-HdLa4t60_hvyICkM,22077
@@ -113,7 +108,7 @@ monopyly/static/js/add-subtransaction.js,sha256=BoLvpahd__YHOwodqJXg10OCY7CJJX0k
113
108
  monopyly/static/js/add-transfer.js,sha256=_ywQju13wGWTeZMqJXJzVbfquQJhcbDnJQ9EC3R01xM,1384
114
109
  monopyly/static/js/autocomplete-transaction.js,sha256=pZQ7v04WEHcJ7riPparhdF70W3ZDSz9Z0j0N_OVgZ9k,2753
115
110
  monopyly/static/js/bind-tag-actions.js,sha256=ReOHoY9Ngsqe7rvH0x0TvgNNbmEuAOKx3HIdLSYXMhk,3619
116
- monopyly/static/js/create-balance-chart.js,sha256=xaRxJvPSL0j5JKG1uYI7deYfqfc2Tw4mUdJk3rSlk3I,2446
111
+ monopyly/static/js/create-balance-chart.js,sha256=tQasqDQBJFmK5KdLXEz3hdXMRvldBMhZGKGaBRigZiY,2447
117
112
  monopyly/static/js/create-category-chart.js,sha256=h17FlFj2eo1MK2VXwuw7U58dWDj4iukYuLnllMOuGhU,514
118
113
  monopyly/static/js/define-filter.js,sha256=nz64sha6G9QXOyVEqxd_xYK0F_fXxzXxIHiQfpvUo7A,1133
119
114
  monopyly/static/js/display-new-account-type-inputs.js,sha256=iHh7zSnyHc_-FIPO1Uuffjd8mFvfqfECMzO34FB_WF4,555
@@ -149,9 +144,10 @@ monopyly/static/js/modules/manage-overlays.js,sha256=nl-UlmZh22RnX648Nb_ybpt0Wfi
149
144
  monopyly/static/js/modules/manage-subforms.js,sha256=-yKA7l8ZI0294auTI307LrKkw_Bl6I8suwK4VLuLhMc,2197
150
145
  monopyly/static/js/modules/update-database-widget.js,sha256=S67hmqaGwzbPy94IjYrag0ZPOur4r5y_tb3_5t7xuYI,1581
151
146
  monopyly/static/js/modules/update-display-ajax.js,sha256=MJBiRMmeIHRG7lLbqIcXkUecKNNMFFVJXwhs_N8LKl0,878
152
- monopyly/templates/layout.html,sha256=DyjxrIt5iz2LYHebaU1p1Y6NPEhMsGY-BVBjg8quUBY,5734
153
- monopyly/templates/auth/login.html,sha256=aZwaHBiKtQa_ZkVBqLUQIbwQdEAJNwcyYNjFQcRp-k0,443
154
- monopyly/templates/auth/register.html,sha256=G6VxfYPIbXQco6Z_1PVQQ40vNWgG3PScmN20npx88yQ,447
147
+ monopyly/templates/layout.html,sha256=a1JQCOvlOHP1zNd64EmXrUaGQuhmrajeQCBPEVZgopE,5779
148
+ monopyly/templates/auth/change_password.html,sha256=yf8Zg2QYmBd9U-MHQXoI8d6pwrnWokDRjbVMxMIJTdU,652
149
+ monopyly/templates/auth/login.html,sha256=Cr16HB8FkYb7jT4ueCsEoOtSM84Lh4e9Jombsb6UPr8,457
150
+ monopyly/templates/auth/register.html,sha256=rZh1IUhCN_67vcSHPHm4LS1rJTo8kcaNc2EEnCTrmoQ,774
155
151
  monopyly/templates/banking/account_page.html,sha256=Y2lZrzXFdykDkkPK9-FktGPq6i-94hV_Me1BM-MzxXU,2002
156
152
  monopyly/templates/banking/account_summaries.html,sha256=GCMIFF6bYOwzPyw8gxKo8mAJ7QzmvyB2d8moEgzqki4,1139
157
153
  monopyly/templates/banking/account_summaries_page.html,sha256=puBlB52WMZR_Dhz6_rSLomNa9QSChsItsshrKT5Aixs,1113
@@ -182,7 +178,7 @@ monopyly/templates/common/transactions_table/transaction_expanded.html,sha256=mL
182
178
  monopyly/templates/common/transactions_table/transactions.html,sha256=a0kUH1tZB9Ilsvf1MpOtRJiHB9ddFJq7q_-zPtpO4Is,531
183
179
  monopyly/templates/core/credits.html,sha256=5XO5foZ_J1RA42BEOzN20bZRcWm9xhZe125BCKudoUc,1166
184
180
  monopyly/templates/core/index.html,sha256=02iQ1feV47EIG2nPGR4n2ANp8L1Jg1DEC52ievARnm8,4684
185
- monopyly/templates/core/profile.html,sha256=26DZ0fXogpZ9XEpXo5ChaRen6sMiKkVh8lN_Xd2Ffcc,2363
181
+ monopyly/templates/core/profile.html,sha256=uxHMs3hOta_ms3ZZ8JdariobFlvq4SU_cLNbhYsXJ78,2349
186
182
  monopyly/templates/core/story.html,sha256=iEKfX1aHxXrstAeeQ6J8Gnvg1zGt95c-iLELUhG-AtE,3331
187
183
  monopyly/templates/core/errors/400.html,sha256=whUYO3b6UIQWfN8y563umccU8GLxqXu0A5nb5uNM-XY,152
188
184
  monopyly/templates/core/errors/401.html,sha256=3HH9TSDZfhyxZVcVnT0PNe524ADvEHIj6BsllQYFFOQ,154
@@ -203,7 +199,7 @@ monopyly/templates/credit/statement_summary.html,sha256=4DkqlN1yKIhFYFUSxmbf997J
203
199
  monopyly/templates/credit/statements.html,sha256=ndCGe4xEj9aFfKPSrr1fnTyKKU-KxGRLq0iJTeJnDvc,1783
204
200
  monopyly/templates/credit/statements_page.html,sha256=s_CSiRO8iTcCoEPVRF2TEOG2XNOeuGF1BSiJGhrH5O0,1458
205
201
  monopyly/templates/credit/tags_page.html,sha256=mKm-QxuicO5MO12JOQy7tuc8Bd9fnnKiTSHDmMP5mTI,662
206
- monopyly/templates/credit/transaction_submission_page.html,sha256=2N9oycKIPrXWXBOkzXcaRhiSsj46l1KEsRUyJjknm8o,2289
202
+ monopyly/templates/credit/transaction_submission_page.html,sha256=FNqvt0WB59_80GhsUrPTEbPs_ydGF0G_fnE1T13_g_A,3136
207
203
  monopyly/templates/credit/transactions_page.html,sha256=4Tx2yUGPUIRfz0M3vAQqjcfHAPvsVXdiD0k9N1O3B0Q,2391
208
204
  monopyly/templates/credit/card_form/card_form.html,sha256=xF7x1RBQyAfKYuW_cRxwhKhug4tum-3s0YHyP0ovhFs,1666
209
205
  monopyly/templates/credit/card_form/card_form_page_new.html,sha256=9ayX0dUEAbSSPVL3vIKIBJYkN8odL_KHOfq3fl6C8yw,525
@@ -211,7 +207,7 @@ monopyly/templates/credit/card_form/transfer_statement_inquiry.html,sha256=Luxie
211
207
  monopyly/templates/credit/card_graphic/card_back.html,sha256=gfr3975mziF0PCd_f2Jy83Y4ktFeFnZ1icVVpiVwoQA,889
212
208
  monopyly/templates/credit/card_graphic/card_front.html,sha256=I53u0WvrQj-m2D-fkcga0GRketfpMuMXNM6Rs0e5CNA,679
213
209
  monopyly/templates/credit/statement_reconciliation/discrepant_records.html,sha256=IMnLShpED8CcXYA3jrQoz4Fc2v0s6i1Fl1OAUY9pjGw,837
214
- monopyly/templates/credit/statement_reconciliation/statement_reconciliation_inquiry.html,sha256=a1fpLfQWSDjmwx_1k71lpH-QN8xAnZsW0VNc7ODrizs,895
210
+ monopyly/templates/credit/statement_reconciliation/statement_reconciliation_inquiry.html,sha256=4c8kZXF6-A2Q5wVgr0rjLjfoEXTIl646QpoVJ99DfLw,785
215
211
  monopyly/templates/credit/statement_reconciliation/statement_reconciliation_page.html,sha256=B1mWqXvLIc9tPod-24HsVWVCsIKp6vBp71a5Mo322gA,2779
216
212
  monopyly/templates/credit/statement_reconciliation/summary.html,sha256=yDNREcWbCbvmVRSbMVst2YnyLoLrd-5sgG2bWzsNAF4,1804
217
213
  monopyly/templates/credit/statement_reconciliation/unrecorded_activities.html,sha256=wCgqgaih413A9RkyARGIQ9OMqaA2POkL57P-wkfG47k,836
@@ -221,13 +217,13 @@ monopyly/templates/credit/transaction_form/transaction_form.html,sha256=_2tYKMqm
221
217
  monopyly/templates/credit/transaction_form/transaction_form_page.html,sha256=x_gwHkqWVuiVIm2Ol_Cv7ce2EODJS1Ktn5S2kI4gG1o,795
222
218
  monopyly/templates/credit/transaction_form/transaction_form_page_new.html,sha256=zIKYO4NyuzxFQltbyJg2FnfOinMHessSdaMpuBTbNxI,312
223
219
  monopyly/templates/credit/transaction_form/transaction_form_page_update.html,sha256=VDlNFZPvuwNOfD53iPkpoi4WOyZYRHeIVy_7gpTJuew,513
224
- monopyly/templates/credit/transactions_table/condensed_row_content.html,sha256=TC2CNP30qwPYdn2Urv7B1hm1-oTSd9bpVWLRpEppJwM,639
220
+ monopyly/templates/credit/transactions_table/condensed_row_content.html,sha256=-VVTlxkMZg2r0hIb3gnsX6bbO_Gn70mh1qXoKD0izvM,638
225
221
  monopyly/templates/credit/transactions_table/expanded_row_content.html,sha256=SwS-YVDQDv0rHK2g_vLs0RWePKKo5972UEOG1JwuSVI,2061
226
222
  monopyly/templates/credit/transactions_table/transaction_field_titles.html,sha256=km-3YEDJaygwcKV-rwYnrE7xF8u4Z7jCBsk0Ia-LO-M,758
227
223
  monopyly/templates/credit/transactions_table/transactions.html,sha256=tcppv0qNV-Qq6U5jfxoNyGKPXmyV9h9nR6rw4jXfBsY,481
228
- monopyly-1.5.0.dist-info/METADATA,sha256=8DXxPJ5UuS1duTBFPb0qJiRcEYRpx4AOG9ETPEglz8U,10980
229
- monopyly-1.5.0.dist-info/WHEEL,sha256=Fd6mP6ydyRguakwUJ05oBE7fh2IPxgtDN9IwHJ9OqJQ,87
230
- monopyly-1.5.0.dist-info/entry_points.txt,sha256=_GmCja7NEqYHlGlVbz4rThqk0SIOmFUkiE8mN1dwgdY,58
231
- monopyly-1.5.0.dist-info/licenses/COPYING,sha256=5X8cMguM-HmKfS_4Om-eBqM6A1hfbgZf6pfx2G24QFI,35150
232
- monopyly-1.5.0.dist-info/licenses/LICENSE,sha256=94rIicMccmTPhqXiRLV9JsU8P2ocMuEUUtUpp6LPKiE,253
233
- monopyly-1.5.0.dist-info/RECORD,,
224
+ monopyly-1.5.2.dist-info/METADATA,sha256=rmlxVy7c1jVhghQgY0YrsJqNnIMY_bMzKncgXfVRzko,10967
225
+ monopyly-1.5.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
226
+ monopyly-1.5.2.dist-info/entry_points.txt,sha256=RdDBtx_pqZDsQR8T5RmdWgrjfplhsEMz-sOaRkgiBDo,43
227
+ monopyly-1.5.2.dist-info/licenses/COPYING,sha256=5X8cMguM-HmKfS_4Om-eBqM6A1hfbgZf6pfx2G24QFI,35150
228
+ monopyly-1.5.2.dist-info/licenses/LICENSE,sha256=94rIicMccmTPhqXiRLV9JsU8P2ocMuEUUtUpp6LPKiE,253
229
+ monopyly-1.5.2.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.13.0
2
+ Generator: hatchling 1.27.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ monopyly = monopyly:main
monopyly/cli/apps.py DELETED
@@ -1,108 +0,0 @@
1
- """Application objects for running the app via the CLI."""
2
-
3
- import multiprocessing
4
- import subprocess
5
-
6
- from gunicorn.app.base import BaseApplication
7
-
8
- from .. import create_app
9
-
10
-
11
- class LocalApplication:
12
- """
13
- An object for running the application locally.
14
-
15
- This application object will run the Flask application using the
16
- built-in Python server on localhost, just like the Flask development
17
- mode. However, it will launch from port 5001 to avoid conflicting
18
- with other Python servers that may attempt to run on the default
19
- port 5000.
20
- """
21
-
22
- mode_name = "local"
23
- default_port = "5001"
24
- _debug = None
25
-
26
- def __init__(self, host=None, port=None, **options):
27
- """Initialize the application in development mode."""
28
- self._host = host
29
- self._port = port or self.default_port
30
- if options:
31
- raise NotImplementedError(
32
- f"Options besides `host` and `port` are not handled in {self.mode_name} mode."
33
- )
34
- self.application = create_app(debug=self._debug)
35
-
36
- def run(self):
37
- """Run the Monopyly application in development mode."""
38
- self.application.run(
39
- host=self._host,
40
- port=self._port,
41
- debug=self._debug,
42
- )
43
-
44
-
45
- class DevelopmentApplication(LocalApplication):
46
- """
47
- An object for running the application in development mode.
48
-
49
- This application object will run the Flask application using the
50
- built-in Python server on localhost, just like the Flask development
51
- mode.
52
- """
53
-
54
- mode_name = "development"
55
- default_port = None # traditionally 5000
56
- _debug = True
57
-
58
-
59
- class ProductionApplication(BaseApplication):
60
- """
61
- An object for running the application in production mode (via Gunicorn).
62
-
63
- This application object will run the Flask application using a
64
- Gunicorn server instead of the built-in Python server.
65
- """
66
-
67
- default_port = None # traditionally 8000
68
- _default_worker_count = (multiprocessing.cpu_count() * 2) + 1
69
-
70
- def __init__(self, host=None, port=None, **options):
71
- """Initialize the application in production mode."""
72
- if port and not host:
73
- raise ValueError("A host must be specified when the port is given.")
74
- self._host = host
75
- self._port = port or self.default_port
76
- self.options = options
77
- self.options["bind"] = self._determine_binding(options.get("bind"))
78
- self.options.setdefault("workers", self._default_worker_count)
79
- self.application = create_app()
80
- super().__init__()
81
-
82
- def _determine_binding(self, bind_option):
83
- # Parse any socket binding options
84
- if self._host and bind_option:
85
- raise ValueError(
86
- "The `host` may not be specified directly if the `bind` option is used."
87
- )
88
- if self._host:
89
- bind_values = [self._host]
90
- if self._port:
91
- bind_values.append(self._port)
92
- bind_option = ":".join(bind_values)
93
- return bind_option
94
-
95
- def load_config(self):
96
- config = {
97
- key: value
98
- for key, value in self.options.items()
99
- if key in self.cfg.settings and value is not None
100
- }
101
- for key, value in config.items():
102
- self.cfg.set(key.lower(), value)
103
-
104
- def load(self):
105
- return self.application
106
-
107
- def run(self, *args, **kwargs):
108
- return super().run(*args, **kwargs)
monopyly/cli/launch.py DELETED
@@ -1,135 +0,0 @@
1
- #!/usr/bin/env python
2
- """
3
- A script (entry point) to launch the Monopyly application.
4
- """
5
- import argparse
6
- import os
7
- import signal
8
- import subprocess
9
- import time
10
- import webbrowser
11
- from pathlib import Path
12
- from threading import Event
13
-
14
- from flask import current_app
15
- from rich.console import Console
16
-
17
- from .apps import DevelopmentApplication, LocalApplication, ProductionApplication
18
-
19
- # Set the Flask environment variable (to specify the app to use)
20
- os.environ["FLASK_APP"] = "monopyly"
21
-
22
-
23
- def main(mode, host=None, port=None, backup=False, browser=False):
24
- app_launcher = Launcher(mode, host=host, port=port)
25
- # Initialize the database and run the app
26
- app_launcher.initialize_database()
27
- if backup:
28
- app_launcher.backup_database()
29
- app_launcher.launch()
30
- if mode in ("development", "local"):
31
- # Enable browser viewing in development mode
32
- if browser:
33
- app_launcher.open_browser(delay=1)
34
- # Wait for the exit command to stop
35
- app_launcher.wait_for_exit()
36
-
37
-
38
- def main_cli():
39
- """Run the app as a command line program."""
40
- args = parse_arguments()
41
- main(
42
- args.mode,
43
- host=args.host,
44
- port=args.port,
45
- backup=args.backup,
46
- browser=args.browser,
47
- )
48
-
49
-
50
- def parse_arguments():
51
- parser = argparse.ArgumentParser(description=__doc__)
52
- parser.add_argument("--host", help="the host address where the app will be run")
53
- parser.add_argument("--port", help="the port where the app will be accessible")
54
- parser.add_argument(
55
- "--backup",
56
- action="store_true",
57
- help="a flag indicating if the database should be backed up",
58
- )
59
- parser.add_argument(
60
- "--browser",
61
- action="store_true",
62
- help=(
63
- "a flag indicating if a new browser window should be opened (development "
64
- "and local modes only)"
65
- ),
66
- )
67
- parser.add_argument(
68
- "mode",
69
- help="the runtime mode for the app",
70
- choices=["development", "local", "production"],
71
- )
72
- return parser.parse_args()
73
-
74
-
75
- class Launcher:
76
- """A tool to build and execute Flask commands."""
77
-
78
- _application_types = {
79
- "development": DevelopmentApplication,
80
- "local": LocalApplication,
81
- "production": ProductionApplication,
82
- }
83
- _console = Console()
84
- _exit = Event()
85
- command = ["flask"]
86
-
87
- def __init__(self, mode, host=None, port=None):
88
- app_type = self._application_types[mode]
89
- if mode == "development":
90
- self.command = self.command + ["--debug"]
91
- self.host = host if host else "127.0.0.1"
92
- self.port = port if port else app_type.default_port
93
- self.app = app_type(host=self.host, port=self.port)
94
-
95
- def initialize_database(self):
96
- """Run the database initializer."""
97
- instruction = self.command + ["init-db"]
98
- self._console.print("[deep_sky_blue1]Initializing the database...")
99
- subprocess.run(instruction)
100
- print("\n")
101
-
102
- def backup_database(self):
103
- """Back up the app database."""
104
- self._console.print("[deep_sky_blue1]Backing up the database...")
105
- instruction = self.command + ["back-up-db"]
106
- subprocess.run(instruction)
107
- print("\n")
108
-
109
- def launch(self):
110
- """Launch the Monopyly application."""
111
- self._console.print("[deep_sky_blue1]Running the Monopyly application...\n")
112
- self.app.run()
113
-
114
- def open_browser(self, delay=0):
115
- """Open the default web browser."""
116
- time.sleep(delay)
117
- webbrowser.open(f"http://{self.host}:{self.port}/")
118
-
119
- @classmethod
120
- def wait_for_exit(cls):
121
- """Wait for the exit command (e.g., keyboard interrupt) to be issued."""
122
- for sig in ("TERM", "HUP", "INT"):
123
- signal.signal(getattr(signal, "SIG" + sig), cls._quit)
124
- while not cls._exit.is_set():
125
- cls._exit.wait(1)
126
-
127
- @classmethod
128
- def _quit(cls, signo, _frame):
129
- """Send the signal to quit the app."""
130
- print("\nClosing the Monopyly app...")
131
- cls._exit.set()
132
-
133
-
134
- if __name__ == "__main__":
135
- main_cli()
@@ -1 +0,0 @@
1
- from .settings import DevelopmentConfig, ProductionConfig, TestingConfig
@@ -1,56 +0,0 @@
1
- """Default configuration settings."""
2
-
3
- import json
4
- from pathlib import Path
5
-
6
- CONFIG_FILENAME = f"monopyly-config.json"
7
- DEFAULT_CONFIG_PATH = Path("/etc", CONFIG_FILENAME)
8
-
9
-
10
- class Config:
11
- """A base configuration object with some default settings."""
12
-
13
- config_filepaths = [DEFAULT_CONFIG_PATH]
14
- REGISTRATION = True
15
-
16
- def __init__(self, db_path=None):
17
- # Read parameters from the configuration files in order of specificity
18
- for config_filepath in filter(lambda p: p.exists(), self.config_filepaths):
19
- self._read_config_json(config_filepath)
20
- if db_path:
21
- self.DATABASE = db_path
22
-
23
- @property
24
- def DATABASE(self):
25
- return self._database
26
-
27
- @DATABASE.setter
28
- def DATABASE(self, value):
29
- # Ensure that the database path is always set as a `pathlib.Path` object
30
- self._database = Path(value)
31
-
32
- def _read_config_json(self, config_path):
33
- # Read keys and values from a configuration JSON
34
- with config_path.open() as config_json:
35
- config_mapping = json.load(config_json)
36
- for key, value in config_mapping.items():
37
- setattr(self, key, value)
38
-
39
-
40
- class InstanceBasedConfig(Config):
41
- """A base configuration object for app modes using instance directories."""
42
-
43
- TESTING = False
44
- db_name = None
45
-
46
- @classmethod
47
- def configure_for_instance(cls, instance_path, **kwargs):
48
- """Instantiate the app based out of the given instance directory."""
49
- instance_path = Path(instance_path)
50
- instance_path.mkdir(parents=True, exist_ok=True)
51
- cls.config_filepaths = [
52
- *super().config_filepaths,
53
- instance_path / CONFIG_FILENAME,
54
- ]
55
- db_path = Path(instance_path, cls.db_name) if cls.db_name else None
56
- return cls(db_path=db_path, **kwargs)
@@ -1,59 +0,0 @@
1
- """A module containing objects with various configuration settings."""
2
-
3
- import warnings
4
- from pathlib import Path
5
-
6
- from ..database import BASE_DB_NAME
7
- from .default_settings import Config, InstanceBasedConfig
8
-
9
-
10
- class ProductionConfig(InstanceBasedConfig):
11
- """A configuration object with settings for production."""
12
-
13
- SECRET_KEY = "INSECURE"
14
- db_name = BASE_DB_NAME
15
-
16
- def __init__(self, db_path=None):
17
- super().__init__(db_path=db_path)
18
- if self.SECRET_KEY == "INSECURE":
19
- # Give an alert while the secret key remains insecure
20
- warnings.formatwarning = lambda msg, *args, **kwargs: f"\n{msg}\n"
21
- warnings.warn(
22
- "INSECURE: Production mode has not yet been fully configured; "
23
- "a secret key is required."
24
- )
25
-
26
-
27
- class DevelopmentConfig(InstanceBasedConfig):
28
- """A configuration object with settings for development."""
29
-
30
- DEBUG = True
31
- SECRET_KEY = "development key"
32
- db_name = f"dev-{BASE_DB_NAME}"
33
-
34
- def __init__(self, db_path=None, preload_data_path=None):
35
- super().__init__(db_path=db_path)
36
- self.PRELOAD_DATA_PATH = preload_data_path
37
-
38
- @classmethod
39
- def configure_for_instance(cls, instance_path, **kwargs):
40
- """Instantiate the app based out of the given instance directory."""
41
- dev_data_path = Path(instance_path, "dev_data.sql")
42
- preload_data_path = dev_data_path if dev_data_path.exists() else None
43
- return super().configure_for_instance(
44
- instance_path, preload_data_path=preload_data_path, **kwargs
45
- )
46
-
47
-
48
- class TestingConfig(Config):
49
- """A configuration object with settings for testing."""
50
-
51
- TESTING = True
52
- SECRET_KEY = "testing key"
53
- DATABASE_INTERFACE_ARGS = ()
54
- DATABASE_INTERFACE_KWARGS = {}
55
- WTF_CSRF_ENABLED = False
56
-
57
- def __init__(self, db_path=None, preload_data_path=None):
58
- super().__init__(db_path=db_path)
59
- self.PRELOAD_DATA_PATH = preload_data_path
@@ -1,2 +0,0 @@
1
- [console_scripts]
2
- monopyly = monopyly.cli.launch:main_cli