ynab-cli 0.3.0__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 (206) hide show
  1. ynab_cli/__init__.py +0 -0
  2. ynab_cli/adapters/__init__.py +0 -0
  3. ynab_cli/adapters/rich/__init__.py +0 -0
  4. ynab_cli/adapters/rich/io.py +38 -0
  5. ynab_cli/adapters/textual/__init__.py +0 -0
  6. ynab_cli/adapters/textual/io.py +62 -0
  7. ynab_cli/adapters/ynab/__init__.py +8 -0
  8. ynab_cli/adapters/ynab/api/__init__.py +1 -0
  9. ynab_cli/adapters/ynab/api/accounts/__init__.py +1 -0
  10. ynab_cli/adapters/ynab/api/accounts/create_account.py +186 -0
  11. ynab_cli/adapters/ynab/api/accounts/get_account_by_id.py +177 -0
  12. ynab_cli/adapters/ynab/api/accounts/get_accounts.py +184 -0
  13. ynab_cli/adapters/ynab/api/budgets/__init__.py +1 -0
  14. ynab_cli/adapters/ynab/api/budgets/get_budget_by_id.py +188 -0
  15. ynab_cli/adapters/ynab/api/budgets/get_budget_settings_by_id.py +163 -0
  16. ynab_cli/adapters/ynab/api/budgets/get_budgets.py +171 -0
  17. ynab_cli/adapters/ynab/api/categories/__init__.py +1 -0
  18. ynab_cli/adapters/ynab/api/categories/get_categories.py +188 -0
  19. ynab_cli/adapters/ynab/api/categories/get_category_by_id.py +180 -0
  20. ynab_cli/adapters/ynab/api/categories/get_month_category_by_id.py +194 -0
  21. ynab_cli/adapters/ynab/api/categories/update_category.py +199 -0
  22. ynab_cli/adapters/ynab/api/categories/update_month_category.py +213 -0
  23. ynab_cli/adapters/ynab/api/months/__init__.py +1 -0
  24. ynab_cli/adapters/ynab/api/months/get_budget_month.py +177 -0
  25. ynab_cli/adapters/ynab/api/months/get_budget_months.py +184 -0
  26. ynab_cli/adapters/ynab/api/payee_locations/__init__.py +1 -0
  27. ynab_cli/adapters/ynab/api/payee_locations/get_payee_location_by_id.py +176 -0
  28. ynab_cli/adapters/ynab/api/payee_locations/get_payee_locations.py +163 -0
  29. ynab_cli/adapters/ynab/api/payee_locations/get_payee_locations_by_payee.py +176 -0
  30. ynab_cli/adapters/ynab/api/payees/__init__.py +1 -0
  31. ynab_cli/adapters/ynab/api/payees/get_payee_by_id.py +176 -0
  32. ynab_cli/adapters/ynab/api/payees/get_payees.py +184 -0
  33. ynab_cli/adapters/ynab/api/payees/update_payee.py +199 -0
  34. ynab_cli/adapters/ynab/api/scheduled_transactions/__init__.py +1 -0
  35. ynab_cli/adapters/ynab/api/scheduled_transactions/create_scheduled_transaction.py +186 -0
  36. ynab_cli/adapters/ynab/api/scheduled_transactions/delete_scheduled_transaction.py +176 -0
  37. ynab_cli/adapters/ynab/api/scheduled_transactions/get_scheduled_transaction_by_id.py +176 -0
  38. ynab_cli/adapters/ynab/api/scheduled_transactions/get_scheduled_transactions.py +184 -0
  39. ynab_cli/adapters/ynab/api/scheduled_transactions/update_scheduled_transaction.py +199 -0
  40. ynab_cli/adapters/ynab/api/transactions/__init__.py +1 -0
  41. ynab_cli/adapters/ynab/api/transactions/create_transaction.py +202 -0
  42. ynab_cli/adapters/ynab/api/transactions/delete_transaction.py +176 -0
  43. ynab_cli/adapters/ynab/api/transactions/get_transaction_by_id.py +176 -0
  44. ynab_cli/adapters/ynab/api/transactions/get_transactions.py +227 -0
  45. ynab_cli/adapters/ynab/api/transactions/get_transactions_by_account.py +236 -0
  46. ynab_cli/adapters/ynab/api/transactions/get_transactions_by_category.py +236 -0
  47. ynab_cli/adapters/ynab/api/transactions/get_transactions_by_month.py +236 -0
  48. ynab_cli/adapters/ynab/api/transactions/get_transactions_by_payee.py +236 -0
  49. ynab_cli/adapters/ynab/api/transactions/import_transactions.py +183 -0
  50. ynab_cli/adapters/ynab/api/transactions/update_transaction.py +199 -0
  51. ynab_cli/adapters/ynab/api/transactions/update_transactions.py +177 -0
  52. ynab_cli/adapters/ynab/api/user/__init__.py +1 -0
  53. ynab_cli/adapters/ynab/api/user/get_user.py +130 -0
  54. ynab_cli/adapters/ynab/client.py +268 -0
  55. ynab_cli/adapters/ynab/errors.py +16 -0
  56. ynab_cli/adapters/ynab/models/__init__.py +229 -0
  57. ynab_cli/adapters/ynab/models/account.py +345 -0
  58. ynab_cli/adapters/ynab/models/account_response.py +65 -0
  59. ynab_cli/adapters/ynab/models/account_response_data.py +65 -0
  60. ynab_cli/adapters/ynab/models/account_type.py +23 -0
  61. ynab_cli/adapters/ynab/models/accounts_response.py +65 -0
  62. ynab_cli/adapters/ynab/models/accounts_response_data.py +81 -0
  63. ynab_cli/adapters/ynab/models/budget_detail.py +405 -0
  64. ynab_cli/adapters/ynab/models/budget_detail_response.py +65 -0
  65. ynab_cli/adapters/ynab/models/budget_detail_response_data.py +73 -0
  66. ynab_cli/adapters/ynab/models/budget_settings.py +115 -0
  67. ynab_cli/adapters/ynab/models/budget_settings_response.py +65 -0
  68. ynab_cli/adapters/ynab/models/budget_settings_response_data.py +65 -0
  69. ynab_cli/adapters/ynab/models/budget_summary.py +216 -0
  70. ynab_cli/adapters/ynab/models/budget_summary_response.py +65 -0
  71. ynab_cli/adapters/ynab/models/budget_summary_response_data.py +91 -0
  72. ynab_cli/adapters/ynab/models/bulk_response.py +65 -0
  73. ynab_cli/adapters/ynab/models/bulk_response_data.py +65 -0
  74. ynab_cli/adapters/ynab/models/bulk_response_data_bulk.py +68 -0
  75. ynab_cli/adapters/ynab/models/bulk_transactions.py +75 -0
  76. ynab_cli/adapters/ynab/models/categories_response.py +65 -0
  77. ynab_cli/adapters/ynab/models/categories_response_data.py +81 -0
  78. ynab_cli/adapters/ynab/models/category.py +519 -0
  79. ynab_cli/adapters/ynab/models/category_goal_type_type_1.py +15 -0
  80. ynab_cli/adapters/ynab/models/category_goal_type_type_2_type_1.py +15 -0
  81. ynab_cli/adapters/ynab/models/category_goal_type_type_3_type_1.py +15 -0
  82. ynab_cli/adapters/ynab/models/category_group.py +85 -0
  83. ynab_cli/adapters/ynab/models/category_group_with_categories.py +108 -0
  84. ynab_cli/adapters/ynab/models/category_response.py +65 -0
  85. ynab_cli/adapters/ynab/models/category_response_data.py +65 -0
  86. ynab_cli/adapters/ynab/models/currency_format_type_0.py +117 -0
  87. ynab_cli/adapters/ynab/models/date_format_type_0.py +61 -0
  88. ynab_cli/adapters/ynab/models/error_detail.py +75 -0
  89. ynab_cli/adapters/ynab/models/error_response.py +65 -0
  90. ynab_cli/adapters/ynab/models/existing_transaction.py +322 -0
  91. ynab_cli/adapters/ynab/models/get_transactions_by_account_type.py +12 -0
  92. ynab_cli/adapters/ynab/models/get_transactions_by_category_type.py +12 -0
  93. ynab_cli/adapters/ynab/models/get_transactions_by_month_type.py +12 -0
  94. ynab_cli/adapters/ynab/models/get_transactions_by_payee_type.py +12 -0
  95. ynab_cli/adapters/ynab/models/get_transactions_type.py +12 -0
  96. ynab_cli/adapters/ynab/models/hybrid_transaction.py +567 -0
  97. ynab_cli/adapters/ynab/models/hybrid_transaction_type.py +12 -0
  98. ynab_cli/adapters/ynab/models/hybrid_transactions_response.py +65 -0
  99. ynab_cli/adapters/ynab/models/hybrid_transactions_response_data.py +84 -0
  100. ynab_cli/adapters/ynab/models/loan_account_periodic_value_type_0.py +44 -0
  101. ynab_cli/adapters/ynab/models/month_detail.py +168 -0
  102. ynab_cli/adapters/ynab/models/month_detail_response.py +65 -0
  103. ynab_cli/adapters/ynab/models/month_detail_response_data.py +65 -0
  104. ynab_cli/adapters/ynab/models/month_summaries_response.py +65 -0
  105. ynab_cli/adapters/ynab/models/month_summaries_response_data.py +81 -0
  106. ynab_cli/adapters/ynab/models/month_summary.py +145 -0
  107. ynab_cli/adapters/ynab/models/new_transaction.py +352 -0
  108. ynab_cli/adapters/ynab/models/patch_category_wrapper.py +65 -0
  109. ynab_cli/adapters/ynab/models/patch_month_category_wrapper.py +65 -0
  110. ynab_cli/adapters/ynab/models/patch_payee_wrapper.py +65 -0
  111. ynab_cli/adapters/ynab/models/patch_transactions_wrapper.py +73 -0
  112. ynab_cli/adapters/ynab/models/payee.py +100 -0
  113. ynab_cli/adapters/ynab/models/payee_location.py +93 -0
  114. ynab_cli/adapters/ynab/models/payee_location_response.py +65 -0
  115. ynab_cli/adapters/ynab/models/payee_location_response_data.py +65 -0
  116. ynab_cli/adapters/ynab/models/payee_locations_response.py +65 -0
  117. ynab_cli/adapters/ynab/models/payee_locations_response_data.py +73 -0
  118. ynab_cli/adapters/ynab/models/payee_response.py +65 -0
  119. ynab_cli/adapters/ynab/models/payee_response_data.py +65 -0
  120. ynab_cli/adapters/ynab/models/payees_response.py +65 -0
  121. ynab_cli/adapters/ynab/models/payees_response_data.py +81 -0
  122. ynab_cli/adapters/ynab/models/post_account_wrapper.py +65 -0
  123. ynab_cli/adapters/ynab/models/post_scheduled_transaction_wrapper.py +65 -0
  124. ynab_cli/adapters/ynab/models/post_transactions_wrapper.py +91 -0
  125. ynab_cli/adapters/ynab/models/put_scheduled_transaction_wrapper.py +65 -0
  126. ynab_cli/adapters/ynab/models/put_transaction_wrapper.py +65 -0
  127. ynab_cli/adapters/ynab/models/save_account.py +77 -0
  128. ynab_cli/adapters/ynab/models/save_category.py +129 -0
  129. ynab_cli/adapters/ynab/models/save_category_response.py +65 -0
  130. ynab_cli/adapters/ynab/models/save_category_response_data.py +73 -0
  131. ynab_cli/adapters/ynab/models/save_month_category.py +59 -0
  132. ynab_cli/adapters/ynab/models/save_payee.py +59 -0
  133. ynab_cli/adapters/ynab/models/save_payee_response.py +65 -0
  134. ynab_cli/adapters/ynab/models/save_payee_response_data.py +73 -0
  135. ynab_cli/adapters/ynab/models/save_scheduled_transaction.py +269 -0
  136. ynab_cli/adapters/ynab/models/save_sub_transaction.py +166 -0
  137. ynab_cli/adapters/ynab/models/save_transaction_with_id_or_import_id.py +366 -0
  138. ynab_cli/adapters/ynab/models/save_transaction_with_optional_fields.py +322 -0
  139. ynab_cli/adapters/ynab/models/save_transactions_response.py +65 -0
  140. ynab_cli/adapters/ynab/models/save_transactions_response_data.py +123 -0
  141. ynab_cli/adapters/ynab/models/scheduled_sub_transaction.py +238 -0
  142. ynab_cli/adapters/ynab/models/scheduled_transaction_detail.py +381 -0
  143. ynab_cli/adapters/ynab/models/scheduled_transaction_frequency.py +23 -0
  144. ynab_cli/adapters/ynab/models/scheduled_transaction_response.py +65 -0
  145. ynab_cli/adapters/ynab/models/scheduled_transaction_response_data.py +65 -0
  146. ynab_cli/adapters/ynab/models/scheduled_transaction_summary.py +310 -0
  147. ynab_cli/adapters/ynab/models/scheduled_transaction_summary_frequency.py +23 -0
  148. ynab_cli/adapters/ynab/models/scheduled_transactions_response.py +65 -0
  149. ynab_cli/adapters/ynab/models/scheduled_transactions_response_data.py +81 -0
  150. ynab_cli/adapters/ynab/models/sub_transaction.py +259 -0
  151. ynab_cli/adapters/ynab/models/transaction_cleared_status.py +13 -0
  152. ynab_cli/adapters/ynab/models/transaction_detail.py +570 -0
  153. ynab_cli/adapters/ynab/models/transaction_flag_color_type_1.py +16 -0
  154. ynab_cli/adapters/ynab/models/transaction_flag_color_type_2_type_1.py +16 -0
  155. ynab_cli/adapters/ynab/models/transaction_flag_color_type_3_type_1.py +16 -0
  156. ynab_cli/adapters/ynab/models/transaction_response.py +65 -0
  157. ynab_cli/adapters/ynab/models/transaction_response_data.py +65 -0
  158. ynab_cli/adapters/ynab/models/transaction_summary.py +499 -0
  159. ynab_cli/adapters/ynab/models/transaction_summary_debt_transaction_type_type_1.py +18 -0
  160. ynab_cli/adapters/ynab/models/transaction_summary_debt_transaction_type_type_2_type_1.py +18 -0
  161. ynab_cli/adapters/ynab/models/transaction_summary_debt_transaction_type_type_3_type_1.py +18 -0
  162. ynab_cli/adapters/ynab/models/transactions_import_response.py +65 -0
  163. ynab_cli/adapters/ynab/models/transactions_import_response_data.py +59 -0
  164. ynab_cli/adapters/ynab/models/transactions_response.py +65 -0
  165. ynab_cli/adapters/ynab/models/transactions_response_data.py +81 -0
  166. ynab_cli/adapters/ynab/models/user.py +60 -0
  167. ynab_cli/adapters/ynab/models/user_response.py +65 -0
  168. ynab_cli/adapters/ynab/models/user_response_data.py +65 -0
  169. ynab_cli/adapters/ynab/types.py +46 -0
  170. ynab_cli/adapters/ynab/util.py +78 -0
  171. ynab_cli/domain/__init__.py +0 -0
  172. ynab_cli/domain/constants.py +3 -0
  173. ynab_cli/domain/models/__init__.py +0 -0
  174. ynab_cli/domain/models/rules.py +37 -0
  175. ynab_cli/domain/ports/__init__.py +5 -0
  176. ynab_cli/domain/ports/io.py +63 -0
  177. ynab_cli/domain/settings.py +16 -0
  178. ynab_cli/domain/use_cases/__init__.py +0 -0
  179. ynab_cli/domain/use_cases/categories.py +105 -0
  180. ynab_cli/domain/use_cases/payees.py +232 -0
  181. ynab_cli/domain/use_cases/transactions.py +93 -0
  182. ynab_cli/host/__init__.py +14 -0
  183. ynab_cli/host/cli.py +37 -0
  184. ynab_cli/host/click/__init__.py +0 -0
  185. ynab_cli/host/click/cli.py +44 -0
  186. ynab_cli/host/click/commands/__init__.py +0 -0
  187. ynab_cli/host/click/commands/categories.py +92 -0
  188. ynab_cli/host/click/commands/payees.py +157 -0
  189. ynab_cli/host/click/commands/rich/__init__.py +0 -0
  190. ynab_cli/host/click/commands/rich/progress_table.py +37 -0
  191. ynab_cli/host/click/commands/transactions.py +76 -0
  192. ynab_cli/host/constants.py +3 -0
  193. ynab_cli/host/textual/__init__.py +0 -0
  194. ynab_cli/host/textual/app.py +98 -0
  195. ynab_cli/host/textual/app.tcss +47 -0
  196. ynab_cli/host/textual/cli.py +42 -0
  197. ynab_cli/host/textual/widgets/__init__.py +58 -0
  198. ynab_cli/host/textual/widgets/categories.py +90 -0
  199. ynab_cli/host/textual/widgets/payees.py +154 -0
  200. ynab_cli/host/textual/widgets/transactions.py +89 -0
  201. ynab_cli/py.typed +0 -0
  202. ynab_cli-0.3.0.dist-info/METADATA +102 -0
  203. ynab_cli-0.3.0.dist-info/RECORD +206 -0
  204. ynab_cli-0.3.0.dist-info/WHEEL +4 -0
  205. ynab_cli-0.3.0.dist-info/entry_points.txt +2 -0
  206. ynab_cli-0.3.0.dist-info/licenses/LICENSE.md +21 -0
@@ -0,0 +1,154 @@
1
+ from textual.app import ComposeResult
2
+ from textual.widgets import DataTable, Log, ProgressBar, TabbedContent, TabPane
3
+ from typing_extensions import override
4
+
5
+ from ynab_cli.adapters.textual.io import TextualWorkerIO
6
+ from ynab_cli.domain.use_cases import payees as use_cases
7
+ from ynab_cli.host.textual.widgets import BaseCommand, RunnableWidget
8
+
9
+
10
+ class PayeesTabs(RunnableWidget):
11
+ @override
12
+ def compose(self) -> ComposeResult:
13
+ with TabbedContent():
14
+ with TabPane("Normalize", id="normalize"):
15
+ yield PayeesNormalizeNamesCommand().data_bind(settings=PayeesTabs.settings)
16
+ with TabPane("Duplicates", id="duplicates"):
17
+ yield PayeesListDuplicatesCommand().data_bind(settings=PayeesTabs.settings)
18
+ with TabPane("Unused", id="unused"):
19
+ yield PayeesListUnusedCommand().data_bind(settings=PayeesTabs.settings)
20
+ with TabPane("All", id="all"):
21
+ yield PayeesListAllCommand().data_bind(settings=PayeesTabs.settings)
22
+
23
+ @override
24
+ async def run_command(self) -> None:
25
+ tabbed_content = self.query_one(TabbedContent)
26
+ if tabbed_content.active_pane:
27
+ if tabbed_content.active_pane.id == "normalize":
28
+ await self.query_one(PayeesNormalizeNamesCommand).run_command()
29
+ elif tabbed_content.active_pane.id == "duplicates":
30
+ await self.query_one(PayeesListDuplicatesCommand).run_command()
31
+ elif tabbed_content.active_pane.id == "unused":
32
+ await self.query_one(PayeesListUnusedCommand).run_command()
33
+ elif tabbed_content.active_pane.id == "all":
34
+ await self.query_one(PayeesListAllCommand).run_command()
35
+
36
+
37
+ class PayeesNormalizeNamesCommand(BaseCommand[use_cases.NormalizeNamesParams]):
38
+ def on_mount(self) -> None:
39
+ table = self.query_one(DataTable)
40
+ table.add_columns(
41
+ "Payee Id",
42
+ "Payee Name",
43
+ "Normalized Name",
44
+ )
45
+
46
+ @override
47
+ async def run_command(self) -> None:
48
+ params: use_cases.NormalizeNamesParams = {}
49
+ self._run_command_worker(params)
50
+
51
+ @override
52
+ async def _run_command(self, use_case_params: use_cases.NormalizeNamesParams) -> None:
53
+ progress_bar = self.query_one(ProgressBar)
54
+ table = self.query_one(DataTable)
55
+ log = self.query_one(Log)
56
+
57
+ async for payee, normalized_name in use_cases.normalize_names(
58
+ self.settings, TextualWorkerIO(self.app, log, progress_bar), use_case_params
59
+ ):
60
+ table.add_row(
61
+ payee.id,
62
+ payee.name,
63
+ normalized_name,
64
+ )
65
+
66
+
67
+ class PayeesListDuplicatesCommand(BaseCommand[use_cases.ListDuplicatesParams]):
68
+ def on_mount(self) -> None:
69
+ table = self.query_one(DataTable)
70
+ table.add_columns(
71
+ "Payee Id",
72
+ "Payee Name",
73
+ "Duplicate Payee Id",
74
+ "Duplicate Payee Name",
75
+ )
76
+
77
+ @override
78
+ async def run_command(self) -> None:
79
+ params: use_cases.ListDuplicatesParams = {}
80
+ self._run_command_worker(params)
81
+
82
+ @override
83
+ async def _run_command(self, use_case_params: use_cases.ListDuplicatesParams) -> None:
84
+ progress_bar = self.query_one(ProgressBar)
85
+ table = self.query_one(DataTable)
86
+ log = self.query_one(Log)
87
+
88
+ async for payee, duplicate_payee in use_cases.list_duplicates(
89
+ self.settings, TextualWorkerIO(self.app, log, progress_bar), use_case_params
90
+ ):
91
+ table.add_row(
92
+ payee.id,
93
+ payee.name,
94
+ duplicate_payee.id,
95
+ duplicate_payee.name,
96
+ )
97
+
98
+
99
+ class PayeesListUnusedCommand(BaseCommand[use_cases.ListUnusedParams]):
100
+ def on_mount(self) -> None:
101
+ table = self.query_one(DataTable)
102
+ table.add_columns(
103
+ "Payee Id",
104
+ "Payee Name",
105
+ )
106
+
107
+ @override
108
+ async def run_command(self) -> None:
109
+ params: use_cases.ListUnusedParams = {
110
+ "prefix_unused": False, # Default to not prefixing unused payees
111
+ }
112
+ self._run_command_worker(params)
113
+
114
+ @override
115
+ async def _run_command(self, use_case_params: use_cases.ListUnusedParams) -> None:
116
+ progress_bar = self.query_one(ProgressBar)
117
+ table = self.query_one(DataTable)
118
+ log = self.query_one(Log)
119
+
120
+ async for payee in use_cases.list_unused(
121
+ self.settings, TextualWorkerIO(self.app, log, progress_bar), use_case_params
122
+ ):
123
+ table.add_row(
124
+ payee.id,
125
+ payee.name,
126
+ )
127
+
128
+
129
+ class PayeesListAllCommand(BaseCommand[use_cases.ListAllParams]):
130
+ def on_mount(self) -> None:
131
+ table = self.query_one(DataTable)
132
+ table.add_columns(
133
+ "Payee Id",
134
+ "Payee Name",
135
+ )
136
+
137
+ @override
138
+ async def run_command(self) -> None:
139
+ params: use_cases.ListAllParams = {}
140
+ self._run_command_worker(params)
141
+
142
+ @override
143
+ async def _run_command(self, use_case_params: use_cases.ListAllParams) -> None:
144
+ progress_bar = self.query_one(ProgressBar)
145
+ table = self.query_one(DataTable)
146
+ log = self.query_one(Log)
147
+
148
+ async for payee in use_cases.list_all(
149
+ self.settings, TextualWorkerIO(self.app, log, progress_bar), use_case_params
150
+ ):
151
+ table.add_row(
152
+ payee.id,
153
+ payee.name,
154
+ )
@@ -0,0 +1,89 @@
1
+ import json
2
+ from pathlib import Path
3
+
4
+ from textual import work
5
+ from textual.app import ComposeResult
6
+ from textual.widgets import DataTable, Log, ProgressBar, TabbedContent, TabPane
7
+ from textual_fspicker import FileOpen
8
+ from typing_extensions import override
9
+
10
+ from ynab_cli.adapters.textual.io import TextualWorkerIO
11
+ from ynab_cli.domain.models import rules
12
+ from ynab_cli.domain.use_cases import transactions as use_cases
13
+ from ynab_cli.host.textual.widgets import BaseCommand, RunnableWidget
14
+
15
+
16
+ class TransactionsTabs(RunnableWidget):
17
+ @override
18
+ def compose(self) -> ComposeResult:
19
+ with TabbedContent():
20
+ with TabPane("Transactions", id="transactions"):
21
+ yield TransactionsApplyRulesCommand().data_bind(settings=TransactionsTabs.settings)
22
+
23
+ @override
24
+ async def run_command(self) -> None:
25
+ tabbed_content = self.query_one(TabbedContent)
26
+ if tabbed_content.active_pane:
27
+ if tabbed_content.active_pane.id == "transactions":
28
+ await self.query_one(TransactionsApplyRulesCommand).run_command()
29
+
30
+
31
+ class TransactionsApplyRulesCommand(BaseCommand[use_cases.ApplyRulesParams]):
32
+ def __init__(self) -> None:
33
+ super().__init__()
34
+ self._transaction_rules_path: Path | None = None
35
+
36
+ def on_mount(self) -> None:
37
+ table = self.query_one(DataTable)
38
+ table.add_columns(
39
+ "Transaction Id",
40
+ "Transaction Date",
41
+ "Transaction Payee",
42
+ "Transaction Category",
43
+ "Transaction Memo",
44
+ "Transaction Amount",
45
+ "Transaction Changes",
46
+ )
47
+
48
+ @override
49
+ async def run_command(self) -> None:
50
+ self._select_rules_worker()
51
+
52
+ @work(exclusive=True)
53
+ async def _select_rules_worker(self) -> None:
54
+ self._transaction_rules_path = await self.app.push_screen_wait(
55
+ FileOpen(title="Select Transaction Rules JSON File", default_file=self._transaction_rules_path)
56
+ )
57
+ if not self._transaction_rules_path:
58
+ return
59
+
60
+ try:
61
+ transaction_rules_json = json.loads(self._transaction_rules_path.read_text())
62
+ transaction_rules = rules.TransactionRules.from_dict(transaction_rules_json)
63
+ except Exception as e:
64
+ self.query_one(Log).write_line(f"Error loading rules: {e}")
65
+ return
66
+
67
+ params: use_cases.ApplyRulesParams = {
68
+ "transaction_rules": transaction_rules,
69
+ }
70
+ self._run_command_worker(params)
71
+
72
+ @override
73
+ async def _run_command(self, use_case_params: use_cases.ApplyRulesParams) -> None:
74
+ progress_bar = self.query_one(ProgressBar)
75
+ table = self.query_one(DataTable)
76
+ log = self.query_one(Log)
77
+
78
+ async for transaction, save_transaction in use_cases.apply_rules(
79
+ self.settings, TextualWorkerIO(self.app, log, progress_bar), use_case_params
80
+ ):
81
+ table.add_row(
82
+ transaction.id,
83
+ transaction.date.isoformat(),
84
+ transaction.payee_name,
85
+ transaction.category_name,
86
+ transaction.memo,
87
+ str(transaction.amount),
88
+ str(save_transaction.to_dict()),
89
+ )
ynab_cli/py.typed ADDED
File without changes
@@ -0,0 +1,102 @@
1
+ Metadata-Version: 2.4
2
+ Name: ynab-cli
3
+ Version: 0.3.0
4
+ Summary: YNAB Command Line Interface
5
+ Author: Jeff Sawatzky
6
+ License-File: LICENSE.md
7
+ Requires-Python: >=3.11
8
+ Requires-Dist: attrs~=25.3
9
+ Requires-Dist: click-default-group~=1.2
10
+ Requires-Dist: click~=8.2
11
+ Requires-Dist: httpx~=0.28
12
+ Requires-Dist: python-dotenv~=1.1
13
+ Requires-Dist: rapidfuzz~=3.13
14
+ Requires-Dist: rich~=14.0
15
+ Requires-Dist: rule-engine~=4.5
16
+ Requires-Dist: textual-fspicker~=0.4
17
+ Requires-Dist: textual~=3.3
18
+ Requires-Dist: typing-extensions~=4.14
19
+ Description-Content-Type: text/markdown
20
+
21
+ # YNAB CLI
22
+
23
+ A command-line interface for interacting with YNAB (You Need A Budget).
24
+
25
+ ## Usage
26
+
27
+ Full user documentation available [here](http://jeffsawatzky.github.io/ynab-cli)
28
+
29
+ ## Project Structure
30
+
31
+ - `src/ynab_cli/`: Main source code
32
+ - `tests/`: Unit and integration tests
33
+ - `docs/`: Documentation (built with MkDocs)
34
+
35
+ ## Getting Started
36
+
37
+ ### Prerequisites
38
+ - Python 3.11+
39
+ - [uv](https://docs.astral.sh/uv/)
40
+
41
+ ### Installation
42
+
43
+ Clone the repository:
44
+ ```sh
45
+ $ git clone https://github.com/jeffsawatzky/ynab-cli.git
46
+ $ cd ynab-cli
47
+ ```
48
+
49
+ Install dependencies with uv:
50
+ ```sh
51
+ $ uv sync
52
+ ```
53
+
54
+ ### Running the CLI
55
+
56
+ With uv:
57
+ ```sh
58
+ $ uv run ynab-cli --help
59
+ ```
60
+
61
+ ## Development
62
+
63
+ - Source code is in `src/ynab_cli/`.
64
+ - Use feature branches for new work.
65
+ - Follow PEP8 and use type hints where possible.
66
+
67
+ ### Linting & Formatting
68
+
69
+ ```sh
70
+ $ make lint
71
+ ```
72
+
73
+ ### Running Tests
74
+
75
+ ```sh
76
+ $ make test
77
+ ```
78
+ Or directly with pytest:
79
+ ```sh
80
+ uv run pytest
81
+ ```
82
+
83
+ ## Documentation
84
+
85
+ - Docs are in `docs/` and built with MkDocs.
86
+ - To serve docs locally:
87
+ ```sh
88
+ $ uv run mkdocs serve
89
+ ```
90
+
91
+ ## Contributing
92
+
93
+ 1. Fork the repository
94
+ 2. Create a feature branch (`git checkout -b feature/your-feature`)
95
+ 3. Commit your changes. Commits should follow conventional commits. The repo is configured with [commitizen](https://commitizen-tools.github.io/commitizen/)
96
+ 4. Push to your fork and open a pull request
97
+
98
+ Please include tests for new features and bug fixes.
99
+
100
+ ## License
101
+
102
+ See [LICENSE.md](LICENSE.md)
@@ -0,0 +1,206 @@
1
+ ynab_cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ ynab_cli/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ ynab_cli/adapters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ ynab_cli/adapters/rich/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ ynab_cli/adapters/rich/io.py,sha256=ywCLewdzzSQRNP0TCU6lFVXjMkHdq_YzR5aHHrIh9d0,1391
6
+ ynab_cli/adapters/textual/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ ynab_cli/adapters/textual/io.py,sha256=Baiq-69jVx7bm7zHOCyosdmNrSKxT1y6n-p7qPZRjow,1951
8
+ ynab_cli/adapters/ynab/__init__.py,sha256=Gs2vKN7cGfg1G25LAV5bBF8bRcc_tUwtlRkbB7lNGPM,161
9
+ ynab_cli/adapters/ynab/client.py,sha256=2az9bGTJGpRH2_rgZ8OuNG6pTskz7oVK-4lsYhhZmEk,12384
10
+ ynab_cli/adapters/ynab/errors.py,sha256=QNuwzFuwTLgEzEeSl742A23VUdLIZFniK7CGdVF-SEI,556
11
+ ynab_cli/adapters/ynab/types.py,sha256=AMnEGrevZXdjrwmEF784jQGPdfyajY9UEcWK4HKuLps,980
12
+ ynab_cli/adapters/ynab/util.py,sha256=XFHntu6vChUQZndUImg5tKg3kfhzPAAgfEyDDU4ESNQ,2622
13
+ ynab_cli/adapters/ynab/api/__init__.py,sha256=zTSiG_ujSjAqWPyc435YXaX9XTlpMjiJWBbV-f-YtdA,45
14
+ ynab_cli/adapters/ynab/api/accounts/__init__.py,sha256=5vd9uJWAjRqa9xzxzYkLD1yoZ12Ld_bAaNB5WX4fbE8,56
15
+ ynab_cli/adapters/ynab/api/accounts/create_account.py,sha256=kZN5UxiWL0uwLKy-7LSHmhdMxTaP2BJ-ZTDA-eYLh4U,4846
16
+ ynab_cli/adapters/ynab/api/accounts/get_account_by_id.py,sha256=FO3rzTwNcgRcR0X5IW__Q9Llz8-IK3y25hdu39Oc8NY,4582
17
+ ynab_cli/adapters/ynab/api/accounts/get_accounts.py,sha256=-CttVoqKpzd-T_ZNsGrcEwqP5IVeEXRBqEkf1ANWX4Y,5132
18
+ ynab_cli/adapters/ynab/api/budgets/__init__.py,sha256=5vd9uJWAjRqa9xzxzYkLD1yoZ12Ld_bAaNB5WX4fbE8,56
19
+ ynab_cli/adapters/ynab/api/budgets/get_budget_by_id.py,sha256=WMqY8HafWFFgZKdWLb4VXsqZMmcN-gGIMq3fSUpiR9I,5524
20
+ ynab_cli/adapters/ynab/api/budgets/get_budget_settings_by_id.py,sha256=0t8GArJXrkZtgNoG6eBKxCxW2kowbCE1_YqL5ZtK_lU,4317
21
+ ynab_cli/adapters/ynab/api/budgets/get_budgets.py,sha256=f8lbQZpgeVssscRTwTwfLamxh_nV8NEVJw94x2j9yBI,4813
22
+ ynab_cli/adapters/ynab/api/categories/__init__.py,sha256=5vd9uJWAjRqa9xzxzYkLD1yoZ12Ld_bAaNB5WX4fbE8,56
23
+ ynab_cli/adapters/ynab/api/categories/get_categories.py,sha256=qRa-3d02P8A4LTDwDk_blcgP5lORR2CBnJ-8q1CeY-k,5676
24
+ ynab_cli/adapters/ynab/api/categories/get_category_by_id.py,sha256=PFCkAmYhAD2cJJgrcH5_gjxh2zR6b2JgIv8do4n6NZg,4984
25
+ ynab_cli/adapters/ynab/api/categories/get_month_category_by_id.py,sha256=oyU2aNdFv_EZPcVvoelde7tRgWYeZAuVFGl6Mdcuj20,5581
26
+ ynab_cli/adapters/ynab/api/categories/update_category.py,sha256=RRrj69AE5MQ9rnIu0fXA6nAQYvzY_snUqQvV5PJthqE,5277
27
+ ynab_cli/adapters/ynab/api/categories/update_month_category.py,sha256=bQfFVwA8jXbpFFU1mPKyOb8EkE46919obHF_DqNsKrQ,6038
28
+ ynab_cli/adapters/ynab/api/months/__init__.py,sha256=5vd9uJWAjRqa9xzxzYkLD1yoZ12Ld_bAaNB5WX4fbE8,56
29
+ ynab_cli/adapters/ynab/api/months/get_budget_month.py,sha256=wyRJ9kf_E-IKZUx1nLi06LUu9_McpyIQ4K2Ow2PahiQ,4658
30
+ ynab_cli/adapters/ynab/api/months/get_budget_months.py,sha256=QlffHGhOULtnEBGMNhT6JVs3K_VtztMlHsb_R2UvLxo,5253
31
+ ynab_cli/adapters/ynab/api/payee_locations/__init__.py,sha256=5vd9uJWAjRqa9xzxzYkLD1yoZ12Ld_bAaNB5WX4fbE8,56
32
+ ynab_cli/adapters/ynab/api/payee_locations/get_payee_location_by_id.py,sha256=ZBDem2jbxuHVnipBR4-Bl6LzwNW07UJA51_yHmyssgE,4819
33
+ ynab_cli/adapters/ynab/api/payee_locations/get_payee_locations.py,sha256=D76uVMXeDpezZ9U5hJoGWaX_u780A_NPwAr3-Er33Ys,4336
34
+ ynab_cli/adapters/ynab/api/payee_locations/get_payee_locations_by_payee.py,sha256=WHmgMq0q_wyvusAE34x1u9_KJkRsdqa9uwaFvGIAKa0,4769
35
+ ynab_cli/adapters/ynab/api/payees/__init__.py,sha256=5vd9uJWAjRqa9xzxzYkLD1yoZ12Ld_bAaNB5WX4fbE8,56
36
+ ynab_cli/adapters/ynab/api/payees/get_payee_by_id.py,sha256=2WzlntiHkrK3LvVwoH4KWwwEzxVCfnTvGasexDKyoPQ,4471
37
+ ynab_cli/adapters/ynab/api/payees/get_payees.py,sha256=8PLxQnBZbzcE_rIcSb1ErxoSc9SsPYN7NBj9fEQw3Ls,5092
38
+ ynab_cli/adapters/ynab/api/payees/update_payee.py,sha256=wukpKQ2YvOIRLjICvFeCT6p2xT9l7Xn07M2WKc-AdlA,5123
39
+ ynab_cli/adapters/ynab/api/scheduled_transactions/__init__.py,sha256=5vd9uJWAjRqa9xzxzYkLD1yoZ12Ld_bAaNB5WX4fbE8,56
40
+ ynab_cli/adapters/ynab/api/scheduled_transactions/create_scheduled_transaction.py,sha256=cgtpqncKpxM6qwvXm9q7hwnb003bA-vLQFmpFOKZJpA,5454
41
+ ynab_cli/adapters/ynab/api/scheduled_transactions/delete_scheduled_transaction.py,sha256=CEMsXaAmpV6UctDj5nhLWqWfXrjhCA6A9pexsYGGHN8,5126
42
+ ynab_cli/adapters/ynab/api/scheduled_transactions/get_scheduled_transaction_by_id.py,sha256=6zSpTXgmy5WTjSZPG-PKkmPyNHYHTw4iymSmlOObjB4,5099
43
+ ynab_cli/adapters/ynab/api/scheduled_transactions/get_scheduled_transactions.py,sha256=o7KJVqEmQqsVd8nhSUqT8LsejY-Z_IBd2j_gflfOPAc,5432
44
+ ynab_cli/adapters/ynab/api/scheduled_transactions/update_scheduled_transaction.py,sha256=9A6gBgc9g9he5KDUmID2sYmHitwndGWNRsOyBlFDJR4,5916
45
+ ynab_cli/adapters/ynab/api/transactions/__init__.py,sha256=5vd9uJWAjRqa9xzxzYkLD1yoZ12Ld_bAaNB5WX4fbE8,56
46
+ ynab_cli/adapters/ynab/api/transactions/create_transaction.py,sha256=ROlEz2UhSNkosJ5PakZjCLcud9MejY-C-JUh0x6YfnE,6616
47
+ ynab_cli/adapters/ynab/api/transactions/delete_transaction.py,sha256=avashCHT-kXjNJh-QM9V9e6HJUb7HdqhuoA6oV31rms,4738
48
+ ynab_cli/adapters/ynab/api/transactions/get_transaction_by_id.py,sha256=JAosH4V-d8pYWunbFNxI6nEn4fIJaaDI2yndtEiVzCU,4711
49
+ ynab_cli/adapters/ynab/api/transactions/get_transactions.py,sha256=ukUhE0iY4vv8BcBixuHfhTYAicUCGd53uCDPm-p5zjo,7020
50
+ ynab_cli/adapters/ynab/api/transactions/get_transactions_by_account.py,sha256=htkKEAnQa3rpTn2VwciSyNknL8uIETRnYqZz3LQrxZU,7467
51
+ ynab_cli/adapters/ynab/api/transactions/get_transactions_by_category.py,sha256=3FoCfPIiDijNcpKhJ26JXtF6QvualKx8f4iVNtXD9dI,7585
52
+ ynab_cli/adapters/ynab/api/transactions/get_transactions_by_month.py,sha256=EQwLXCs9htqFraYLrmPoh3m2jHx48OJPKIC6a8T948k,7428
53
+ ynab_cli/adapters/ynab/api/transactions/get_transactions_by_payee.py,sha256=RzPrDwNSE6vQaVeN4Xy4rbltxP1l_1BS8nuRLzCWHSE,7470
54
+ ynab_cli/adapters/ynab/api/transactions/import_transactions.py,sha256=Hl3HPvlqH3Pfb8tl0wgeQJZrutnCZyP6hMlitzNfwb8,6443
55
+ ynab_cli/adapters/ynab/api/transactions/update_transaction.py,sha256=FDSah2O7Z4IMBqg44Zhi593jAbvHayAVPXNl2UkE9Eg,5428
56
+ ynab_cli/adapters/ynab/api/transactions/update_transactions.py,sha256=S8jJaOiqlQET9znei40AUFcMmRJ09-LjasynVb0lF-I,4659
57
+ ynab_cli/adapters/ynab/api/user/__init__.py,sha256=5vd9uJWAjRqa9xzxzYkLD1yoZ12Ld_bAaNB5WX4fbE8,56
58
+ ynab_cli/adapters/ynab/api/user/get_user.py,sha256=5FVg_rnigqHsmvrkhG8kweo1E1QDUpc0MEzepSBbJ-k,3402
59
+ ynab_cli/adapters/ynab/models/__init__.py,sha256=3zovOfsfaBdGQVdVN4YZRO2orC0zLTvntJ_mDXWBbV4,10063
60
+ ynab_cli/adapters/ynab/models/account.py,sha256=OrVCk-WpkT8sA-KloqLbi9L0RElzDe_qLIT7AREXUA4,13406
61
+ ynab_cli/adapters/ynab/models/account_response.py,sha256=anKYE9exQqZ8OXJLBlUpYf3e_mNr8VDBb6ow0Q3vo1I,1748
62
+ ynab_cli/adapters/ynab/models/account_response_data.py,sha256=N4Q5GSUZC_aPH2YyPncwAchiFZktvgKvGYPpFRdFUOk,1713
63
+ ynab_cli/adapters/ynab/models/account_type.py,sha256=HRu-C-FxUsAqWdluXNCmLyPV3szSE99jr3JChO721eg,548
64
+ ynab_cli/adapters/ynab/models/accounts_response.py,sha256=TtDmdf0lahZ2gCeoR5BmgFQwaiXisZrOBNbV9bOdAeQ,1760
65
+ ynab_cli/adapters/ynab/models/accounts_response_data.py,sha256=aSGIajuJvm8Vpl4E_oIezmRl71LeFlKSmT9BhLLTbSw,2320
66
+ ynab_cli/adapters/ynab/models/budget_detail.py,sha256=2-h8M7nnh3bRVmf3QIKPl4fCXzqmFnOIQFg6SDVCBkI,17659
67
+ ynab_cli/adapters/ynab/models/budget_detail_response.py,sha256=tGlPxmWQb86hA6xh_IbCO2tbWHIFBPRRKdbL-3eRhZA,1813
68
+ ynab_cli/adapters/ynab/models/budget_detail_response_data.py,sha256=m2u8RQKRdRjreOe59S8adThpmpz9z02wgS9YJsMCbRI,2059
69
+ ynab_cli/adapters/ynab/models/budget_settings.py,sha256=oscAG2R7ZrXwccbKvMesMy3phzmOucwHRWTScuuILUE,4176
70
+ ynab_cli/adapters/ynab/models/budget_settings_response.py,sha256=2fftbbJoSnfbH0cUQYAa6fJYQFYY0h90dFStU0zG4bU,1837
71
+ ynab_cli/adapters/ynab/models/budget_settings_response_data.py,sha256=7hnfDEbWh1pvXGSozhPqlG71xq43aVt_voYtfsrNFYk,1812
72
+ ynab_cli/adapters/ynab/models/budget_summary.py,sha256=Svp4B4uZdl21jgj0ffvJOwOQARWsUUeHItfUTTUcV-c,8109
73
+ ynab_cli/adapters/ynab/models/budget_summary_response.py,sha256=wK-n-a0GX1aOTyK-Y2b0g8v6lYZuWQ-9SEau-dqJmy8,1825
74
+ ynab_cli/adapters/ynab/models/budget_summary_response_data.py,sha256=Xa6AxUlcOHBphX4I4Bn8W_WSr3-4kP01mxkZBLBjzq0,2834
75
+ ynab_cli/adapters/ynab/models/bulk_response.py,sha256=DKsRWzW1ODIqt72TR0Ew3ItwGBg4xwOPPlTkWZFwdLc,1712
76
+ ynab_cli/adapters/ynab/models/bulk_response_data.py,sha256=9dA61rdVwj7xz5KUPwP5YAb941F4dpIlRnOcqqqssVk,1765
77
+ ynab_cli/adapters/ynab/models/bulk_response_data_bulk.py,sha256=Z3IlKvS8dQeGVgaNf6sxB5VQIgsWCg6KHPFsy9oPh0c,2203
78
+ ynab_cli/adapters/ynab/models/bulk_transactions.py,sha256=BTYxOR0bPE6o5z9AJYYdf8dLUZBFZ3abgWnKU6HlwRE,2309
79
+ ynab_cli/adapters/ynab/models/categories_response.py,sha256=LAQrKFYB2w1CESdVnv1hVZEMgnJqrSqT-Pj-It3lQ5U,1784
80
+ ynab_cli/adapters/ynab/models/categories_response_data.py,sha256=Z05R4Taeoy4SwcHllQobxVC-r85-o_7YzfvDENO_HQI,2630
81
+ ynab_cli/adapters/ynab/models/category.py,sha256=VbT2mD0qXaVFkgUj5Yn_j5T5GiOF3oInnEOTYcwPHfw,21433
82
+ ynab_cli/adapters/ynab/models/category_goal_type_type_1.py,sha256=BxFzQ47Ob8-FGeo_92gvZ3gVBWKjjk0YoybeaWKp-fE,260
83
+ ynab_cli/adapters/ynab/models/category_goal_type_type_2_type_1.py,sha256=K4mpYZ-oLxsWoLWHZFHgv3ogPNCq-wobJ6V-r0KvAtc,265
84
+ ynab_cli/adapters/ynab/models/category_goal_type_type_3_type_1.py,sha256=uYYKDXqkVNK1r0JhsDqNmNzvJ5Oasz9Z7WB24R0dIBU,265
85
+ ynab_cli/adapters/ynab/models/category_group.py,sha256=WLqO84kel_iIVtjJlE_c_zICYla8zDt3sbUW2XW-RQo,2119
86
+ ynab_cli/adapters/ynab/models/category_group_with_categories.py,sha256=8WvSjhXkHQpwDyJdqA6viznoWZJuTHeDHWjAs-8H86Q,3065
87
+ ynab_cli/adapters/ynab/models/category_response.py,sha256=SREZSwJ2rfl7zASb63OCVjQ3TGNtE1ZnAuvNgodcYS0,1760
88
+ ynab_cli/adapters/ynab/models/category_response_data.py,sha256=AiKv3UAHkh0EeLte5_M4wJojDYgGzVx3qT_8dW0bCoQ,1735
89
+ ynab_cli/adapters/ynab/models/currency_format_type_0.py,sha256=iyNT_D_FWMASoZt576VWD9MgHRkfwr9KXQugrkcqNgw,3421
90
+ ynab_cli/adapters/ynab/models/date_format_type_0.py,sha256=ZX0G7Rc6i0b7WJ2cPTd8xEde-st5wh72rVfoV0FTqI8,1622
91
+ ynab_cli/adapters/ynab/models/error_detail.py,sha256=LcrVX9pwSHuBPngg7QrPl3kAYyTxfJuQOXmcA8l8NG0,1723
92
+ ynab_cli/adapters/ynab/models/error_response.py,sha256=CSpDCLuajcLyZn_HymVntBhLFXFDh_3YUaqipMqy3Z0,1690
93
+ ynab_cli/adapters/ynab/models/existing_transaction.py,sha256=j9mDIWbhOanyoSM6xZcDBmxiEbFept-j3ND_fsIDH8k,12711
94
+ ynab_cli/adapters/ynab/models/get_transactions_by_account_type.py,sha256=eQFbofOMedKtzNSZi9aEL53b1ybTN8qq94s7bAfM8Q0,253
95
+ ynab_cli/adapters/ynab/models/get_transactions_by_category_type.py,sha256=bH1skai0vSnQpGzyXU98FgR8AgfmNCmBWwP7ewHJ2HM,254
96
+ ynab_cli/adapters/ynab/models/get_transactions_by_month_type.py,sha256=IEzrenAnfUzj443WR-fHMwdcuB6-urYCcG3EDPBSyL8,251
97
+ ynab_cli/adapters/ynab/models/get_transactions_by_payee_type.py,sha256=a4cBZhBTDUOGNno0g7p2azWk_xTpAIz_p63cjv22vhM,251
98
+ ynab_cli/adapters/ynab/models/get_transactions_type.py,sha256=9C8WcMq3Xp3zIbchm0mBONDlt4Yll7l2SN9qYY2quhU,244
99
+ ynab_cli/adapters/ynab/models/hybrid_transaction.py,sha256=rA4xp8pcF3PnXfiJVXBN7o21W44hiXVrKdS-fatXV10,22370
100
+ ynab_cli/adapters/ynab/models/hybrid_transaction_type.py,sha256=9daVSG9fBaT58B_33SaxXeLP1uvMhWlTNdLf7NKtlWQ,250
101
+ ynab_cli/adapters/ynab/models/hybrid_transactions_response.py,sha256=Jbf_gbK1LrIeWeix8BY_0fFQwik33g_O2PlV2-_e5ws,1885
102
+ ynab_cli/adapters/ynab/models/hybrid_transactions_response_data.py,sha256=gCdblGbz8N9H7uKftYE4c7qRHL7xTYb0RG_0lwkU1mk,2675
103
+ ynab_cli/adapters/ynab/models/loan_account_periodic_value_type_0.py,sha256=Og7HevZHDycMl7Q50y7pI71dd1JfVopTeENynzjx47Y,1302
104
+ ynab_cli/adapters/ynab/models/month_detail.py,sha256=EVPRQ_9TA6BUW9qv-JZB7MgQlwjMbv2oI3z6qFwoGJw,5184
105
+ ynab_cli/adapters/ynab/models/month_detail_response.py,sha256=AnjLpBtx468CdDrEopgweJsZPgPtU6uVt2cErLPXa_o,1801
106
+ ynab_cli/adapters/ynab/models/month_detail_response_data.py,sha256=KOTcTReJRSPagGXRouiS7VZplqCCxlVlhJf05ieNbUc,1746
107
+ ynab_cli/adapters/ynab/models/month_summaries_response.py,sha256=4DfgaTO9id6iuYzGpBSrzXaGy9OgcrQ1BMogKNMyjco,1837
108
+ ynab_cli/adapters/ynab/models/month_summaries_response_data.py,sha256=4uPAqogfi3rWJ-SO-QT1e_BSwEbVxn1L1l434SWdcwc,2346
109
+ ynab_cli/adapters/ynab/models/month_summary.py,sha256=K9ZufHF1tfi-ZwI4AEtPUxjEcsT-l0J1JbdFud_QW74,4316
110
+ ynab_cli/adapters/ynab/models/new_transaction.py,sha256=Eyx6F7MD5aODIMWIaOyohecJY6acFCDuAMSCuY_cmWE,14570
111
+ ynab_cli/adapters/ynab/models/patch_category_wrapper.py,sha256=AH3Yi1b1BcLnG1pby4FfyMj4tDbZWsxcFb4_32lKd8U,1765
112
+ ynab_cli/adapters/ynab/models/patch_month_category_wrapper.py,sha256=wMsR8iOe3wxF3TUGePdZJTnPVtcF-0PiV2hmOAU0G-I,1830
113
+ ynab_cli/adapters/ynab/models/patch_payee_wrapper.py,sha256=pQy9kdDR5R3v5ipyNgiR-cZKJl8rjnJpJaJCyLc_4pU,1699
114
+ ynab_cli/adapters/ynab/models/patch_transactions_wrapper.py,sha256=liZFXBD-CpMMAxS0xO_JlBTkI82KtBJ7-cqSULtamSQ,2317
115
+ ynab_cli/adapters/ynab/models/payee.py,sha256=jqa-pcAA72LiDVRCU_HqOJLjAy2s7rXH5You0T7swJ8,2831
116
+ ynab_cli/adapters/ynab/models/payee_location.py,sha256=WZZmbI__BrLIL5cZsWRlWPPceq3WfEipZs2Uud97Ud4,2339
117
+ ynab_cli/adapters/ynab/models/payee_location_response.py,sha256=Iro5M6GVmbn7DeHsGp8Nsb6Vam9tdsMunilp8kow084,1825
118
+ ynab_cli/adapters/ynab/models/payee_location_response_data.py,sha256=pkK_uPOmWhK3MtnJJOzhT1VW8nt6HUrz9zuTbS9DutA,1860
119
+ ynab_cli/adapters/ynab/models/payee_locations_response.py,sha256=caVQB2aeFfsCo0yo7QboyVCH5Qma2DCuy1G6mgZ6slA,1837
120
+ ynab_cli/adapters/ynab/models/payee_locations_response_data.py,sha256=3s0lUoUkLraM1Ctoqe_DqNEvbIyVzbDTcbKLK970OCI,2260
121
+ ynab_cli/adapters/ynab/models/payee_response.py,sha256=oTgMgzDiKkaaQsa28tOmRF0VHAd21WhPt2cU-FlErNY,1724
122
+ ynab_cli/adapters/ynab/models/payee_response_data.py,sha256=ddta21ZJA9pNQX-U9Ipy5mO1WyztzobfpMMLkW6g6Ss,1669
123
+ ynab_cli/adapters/ynab/models/payees_response.py,sha256=KJZ9WB0BCj1S40pndWdshWDr4IRX9WBY9Y65qcU6q38,1736
124
+ ynab_cli/adapters/ynab/models/payees_response_data.py,sha256=KPjsMAc61Esle6vypnlO_5FKif0tdSYsHdKlYaoEHEA,2252
125
+ ynab_cli/adapters/ynab/models/post_account_wrapper.py,sha256=0TvUmHkzLSDxhNY1q8dpkg-Yu8uYfwJ5av9OfM7zS88,1738
126
+ ynab_cli/adapters/ynab/models/post_scheduled_transaction_wrapper.py,sha256=n5Jar7jzce5jsBBu0CuAhXM8flRSIcd4xkcX9Se55iQ,2039
127
+ ynab_cli/adapters/ynab/models/post_transactions_wrapper.py,sha256=HoCEECmNNOQKpn4ZyWXfm_L0lZE7E3V_OC359WLLePM,3070
128
+ ynab_cli/adapters/ynab/models/put_scheduled_transaction_wrapper.py,sha256=EyQh7fcxUef5ZxtHFymAwsLmKsOId28PALLR6RLtelA,2034
129
+ ynab_cli/adapters/ynab/models/put_transaction_wrapper.py,sha256=sJHOgXSyLtdRGenjcK8RuobPS7zRZ-50P3-h8EcJ6Fs,1849
130
+ ynab_cli/adapters/ynab/models/save_account.py,sha256=z1DH-FDh7yLV-Ofb7CsnoDod5EmunSBq01D9acAqw_s,1964
131
+ ynab_cli/adapters/ynab/models/save_category.py,sha256=Z57p8j2tL_oTfv5O6cd_svvR6WnQUamffXijm2knaSk,4088
132
+ ynab_cli/adapters/ynab/models/save_category_response.py,sha256=cjXC4ueGZFK8pZuOP-aWQCV8LopqRyZLFvi_K6BfWwE,1813
133
+ ynab_cli/adapters/ynab/models/save_category_response_data.py,sha256=T50M-Q8mt4gP-tghxkx6kE0LyEDZlKUi9ZQd8ACYAeY,2049
134
+ ynab_cli/adapters/ynab/models/save_month_category.py,sha256=60w6PnOcrHMNrDhI9-TALgBmNRd_FPP-Z3E1Jv7jdeo,1547
135
+ ynab_cli/adapters/ynab/models/save_payee.py,sha256=At23V8ovtIRTt19rLTGvXPHFw4wf505jAZNSJA8SoRM,1591
136
+ ynab_cli/adapters/ynab/models/save_payee_response.py,sha256=QKgRMT2hNDipLbyY-d1nAvlwNpw8C6Kkk0IRNRsuiDw,1777
137
+ ynab_cli/adapters/ynab/models/save_payee_response_data.py,sha256=V67u9NEyybP7KQNI9doAgXeCfN7UJKQdD4GOZrtQtYA,1983
138
+ ynab_cli/adapters/ynab/models/save_scheduled_transaction.py,sha256=z3tq4AuDzSrKVpZ25CAmSs2V-xID4hkU1TaH34B79PM,10089
139
+ ynab_cli/adapters/ynab/models/save_sub_transaction.py,sha256=uA4ck9UHabt7vES_jbnS6UU_U_A6cG7CqSuhZlReqss,5485
140
+ ynab_cli/adapters/ynab/models/save_transaction_with_id_or_import_id.py,sha256=zcbsAqUxTHwBDiu3cMlW93u6VVX5nRuTjrQ9U2cJfXk,14553
141
+ ynab_cli/adapters/ynab/models/save_transaction_with_optional_fields.py,sha256=zi_rbU79U3z7p3pAenBx0TmV3kbj_bKh-wH7mw2YdoM,12790
142
+ ynab_cli/adapters/ynab/models/save_transactions_response.py,sha256=JrOzWWmFQlzVTz37gNQqyHnU9Yh5daLCPGLjAC-eJis,1861
143
+ ynab_cli/adapters/ynab/models/save_transactions_response_data.py,sha256=jmShZUNpnsfH1gNb9Gs0x3cz8j5oheX0ZwCvlF2Mo7A,4568
144
+ ynab_cli/adapters/ynab/models/scheduled_sub_transaction.py,sha256=WxAS7g78GYpM89zYXeZAOaFsynyWO-CBxy1wDOjWLWY,7879
145
+ ynab_cli/adapters/ynab/models/scheduled_transaction_detail.py,sha256=-ZT_8Ch9O2ZmKHFSB6Yc3XvtVlcy4rQIJEAiMHp7KeA,13811
146
+ ynab_cli/adapters/ynab/models/scheduled_transaction_frequency.py,sha256=hkiAlLRmXkVMkDh2zEK-Ei7Fh2kcdOmD4zsFgRWUKno,574
147
+ ynab_cli/adapters/ynab/models/scheduled_transaction_response.py,sha256=QEJLvY1GC2GFt5E9GDbzICMMgMGLqeJ-vBKdFxjwOL8,1909
148
+ ynab_cli/adapters/ynab/models/scheduled_transaction_response_data.py,sha256=qaaLXHE25Nq2y0VBq42n2CznOz0DafAYze6sExMKQlA,2058
149
+ ynab_cli/adapters/ynab/models/scheduled_transaction_summary.py,sha256=t_VE06GrZuvUJH4eiOeUrNhzapr66bwtTyU3I4dAlvI,11050
150
+ ynab_cli/adapters/ynab/models/scheduled_transaction_summary_frequency.py,sha256=NWsVC4kzbWLgaErfxYvmvJnxS18cicLLoaphsKqGcoo,581
151
+ ynab_cli/adapters/ynab/models/scheduled_transactions_response.py,sha256=I34IIgL6Uwtd3t2J14vtBIKt5ZCKkrM6iT0KKtiw7lo,1921
152
+ ynab_cli/adapters/ynab/models/scheduled_transactions_response_data.py,sha256=S3l5YH87-HNmQ9roM9_MTqnoBq2iG1EpA4HM4THbntM,2833
153
+ ynab_cli/adapters/ynab/models/sub_transaction.py,sha256=iEPUycHmMF4qkwLqccOmRbsNPLLXicJxbnB9k7yC0XE,8651
154
+ ynab_cli/adapters/ynab/models/transaction_cleared_status.py,sha256=sG9hNTi-wdkO6XQO9yWtv_wFEAqYy81NQ96T-DIFrZo,265
155
+ ynab_cli/adapters/ynab/models/transaction_detail.py,sha256=oO2JU6cijlAMnJEeDKDAIxgw4_IZmE00CswzYvEOqiU,22338
156
+ ynab_cli/adapters/ynab/models/transaction_flag_color_type_1.py,sha256=0cXjF18mIJ7lWKPz3n90H3Xz-bujKMNGJiDcnQQonic,304
157
+ ynab_cli/adapters/ynab/models/transaction_flag_color_type_2_type_1.py,sha256=QJjiUHM0qioQD0bJehdvD69hU3FyJ45yKeddeNW3NMg,309
158
+ ynab_cli/adapters/ynab/models/transaction_flag_color_type_3_type_1.py,sha256=7J-WHulNj0Q0nUZD19N9bnHNGK44U8akA8CIzX-el6E,309
159
+ ynab_cli/adapters/ynab/models/transaction_response.py,sha256=bWk7fD-kROglW_iaDa06QjFI6XveKjIBY8QcE5x4Y6A,1796
160
+ ynab_cli/adapters/ynab/models/transaction_response_data.py,sha256=7bmuRPQ76NLwwgqyb5z8T4wCDf1U8fyhj7Y5Roehe_g,1845
161
+ ynab_cli/adapters/ynab/models/transaction_summary.py,sha256=Xy3P8GsMbj75CFM_zq4dbVR544iA3lFJ6zsjgha2lxc,19662
162
+ ynab_cli/adapters/ynab/models/transaction_summary_debt_transaction_type_type_1.py,sha256=W3MRfU2a0lRJpsYCJq9W9z_qadt9hVB5bVsxADoG2xU,399
163
+ ynab_cli/adapters/ynab/models/transaction_summary_debt_transaction_type_type_2_type_1.py,sha256=BAcrtQpUw-Pmdp27VHFveUuvnxTP4awbVc8Q-tEni_w,404
164
+ ynab_cli/adapters/ynab/models/transaction_summary_debt_transaction_type_type_3_type_1.py,sha256=P3q-gtU4YgfPKmHEbDuJJ8BCV4RWqYhqwBKnSWodtQ4,404
165
+ ynab_cli/adapters/ynab/models/transactions_import_response.py,sha256=LsRAfJp-Ljur2hEMuG6GVLA3r_kDHprSKK45suVBQus,1885
166
+ ynab_cli/adapters/ynab/models/transactions_import_response_data.py,sha256=jEKRboC7UdBIjMKsGnHwlLbwNsL9-VnTB4-RB5aDhlo,1731
167
+ ynab_cli/adapters/ynab/models/transactions_response.py,sha256=JVUMrNwpabEoOn11ZfSGieiir7hg0isirn5QiBPs9cM,1808
168
+ ynab_cli/adapters/ynab/models/transactions_response_data.py,sha256=esnnIGuE0yAAIM-lVRmeevygd4zOhDWxWELscDpm4zE,2500
169
+ ynab_cli/adapters/ynab/models/user.py,sha256=UYNUXru8Uk3Q0WUGqE7cDsfOqc7XOM-aD2LKlAkTSw4,1414
170
+ ynab_cli/adapters/ynab/models/user_response.py,sha256=wAKWBxMJcg98Ihdcp8sfYR5PbFNvvn86apHwBsZYZMc,1712
171
+ ynab_cli/adapters/ynab/models/user_response_data.py,sha256=E257i7rtw3IktAJuvgDCJNwuNHOMURc8gnhDm9ZZUUg,1647
172
+ ynab_cli/domain/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
173
+ ynab_cli/domain/constants.py,sha256=oizVJz_6wIArBvbyOhWB8SyZpMs5Q6--1i3BCI2z8ww,69
174
+ ynab_cli/domain/settings.py,sha256=hmFw7zbfTgfjzaBCth2OxARgG2eUBbtLIxeBlxj0LRo,291
175
+ ynab_cli/domain/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
176
+ ynab_cli/domain/models/rules.py,sha256=RoKo5bOI5G92weNGsctgt50yWWFIckQ6NKaqswoWzjw,1336
177
+ ynab_cli/domain/ports/__init__.py,sha256=1AHE4eKLn2NxJ7jqLnVxA0r_Oit7fBGnmziaulrRVG0,65
178
+ ynab_cli/domain/ports/io.py,sha256=--iAa5lSwqgCkn6MKQhAERhLpXAwDGPgwAPMoWwo4x8,1896
179
+ ynab_cli/domain/use_cases/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
180
+ ynab_cli/domain/use_cases/categories.py,sha256=I8Dj9EjwoEpbcdKRn_DlCe2WqAlxFCJKBh3okHeuNnQ,4297
181
+ ynab_cli/domain/use_cases/payees.py,sha256=vOd3oSxMBBAg673-8dt5XZWepKCompdy1jvNRyC1Nd4,8984
182
+ ynab_cli/domain/use_cases/transactions.py,sha256=K_ewGf7Bk1WqEvZqz8WBFMFLywyKP_WWgke17bUCpyE,3586
183
+ ynab_cli/host/__init__.py,sha256=FbIG98WKiwaYog1b5KC_gvO425NUBL2eGJLBvr4Pr9U,214
184
+ ynab_cli/host/cli.py,sha256=CdUFsD5u1FGKKIKgQAvLIPdLR_vtLRaDdNEiDW7uzww,961
185
+ ynab_cli/host/constants.py,sha256=T0-JaASOW0nmt8AEDn1MQtISrj0Z7efhwx_JG91_pX0,59
186
+ ynab_cli/host/click/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
187
+ ynab_cli/host/click/cli.py,sha256=rDr1JIzfMbVmbivVaRJfmMAW9vWWqS-RAPvge_xthpU,1302
188
+ ynab_cli/host/click/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
189
+ ynab_cli/host/click/commands/categories.py,sha256=psk91yQB1vxH1Fhinp2jbXxVfX5ww1gQOnlG1F2rwdM,2695
190
+ ynab_cli/host/click/commands/payees.py,sha256=oFzUGzrJvRkeM_WmVGgiWCl3LnjCgFgXfq6hvLWfX2U,4562
191
+ ynab_cli/host/click/commands/transactions.py,sha256=14E3NlyaB0i6HdqbiKu8B6eKuFlEX3dDVApC__UJnQU,2382
192
+ ynab_cli/host/click/commands/rich/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
193
+ ynab_cli/host/click/commands/rich/progress_table.py,sha256=Kxfib8L8rIV-iZJqf_TwRggKf-i1rJ_TbgI5tC3IWIQ,1090
194
+ ynab_cli/host/textual/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
195
+ ynab_cli/host/textual/app.py,sha256=BqyRW6aBv341lysBRA7ssHAC_i4U7KPjbk1lUyyUWW0,3938
196
+ ynab_cli/host/textual/app.tcss,sha256=J8vnq4oVp6R5SZbM7Y_jyIdU7SiZCgcnKL-HWviqezs,943
197
+ ynab_cli/host/textual/cli.py,sha256=yzGR7E_Hi8B-Am0YWVzmuAu2gLKVwMq9NXN67pUJVqA,1303
198
+ ynab_cli/host/textual/widgets/__init__.py,sha256=tzWZTk-AMo4UkwCFG4wbH8S5aPlzzTqY5yFmRdBe3Ls,1792
199
+ ynab_cli/host/textual/widgets/categories.py,sha256=7oaXJiWyJ5mV8mycuosqVH07bdXIXiB9wMn6gKrhdSA,3223
200
+ ynab_cli/host/textual/widgets/payees.py,sha256=uwtTufXXgbcOvFqJhsCHbMPw5zIgVLx9Rr0jPidhPGc,5499
201
+ ynab_cli/host/textual/widgets/transactions.py,sha256=q5f8mvtXkyovmoOIp5GYVLWhGCOrEnOmH_rNw975kj4,3233
202
+ ynab_cli-0.3.0.dist-info/METADATA,sha256=gNkcPXrWyGZLJc2YaBrgkjgZGtSV-ON1nDmX6lvQ4UY,2002
203
+ ynab_cli-0.3.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
204
+ ynab_cli-0.3.0.dist-info/entry_points.txt,sha256=uqDVP1zGtereOU44EiXTknifRxK3taH0cu1fgy4umd0,52
205
+ ynab_cli-0.3.0.dist-info/licenses/LICENSE.md,sha256=lhsrlEWLRKbWn8Kjw6kRc6DdJ4aAQyZCBTG7MoDJL3M,1070
206
+ ynab_cli-0.3.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.27.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ ynab-cli = ynab_cli.host.cli:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Jeff Sawatzky
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.