mfynab 0.2.0 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1d0ef3ce6051c500eb5a269c3763ff18ae129fbbef15693eb8413fa6e3c788ef
4
- data.tar.gz: d9788544bc9aaa518c8ad47d3abfe526fb8686fe676b49fe30358930e91dca75
3
+ metadata.gz: dfe614bd0fee4c3bd2c60de5b1fb18105f0aaa58b889ffd12fcdbd63c1144bcb
4
+ data.tar.gz: 07420fe5903a4ab62d99ac5feb644d731976ea0af21b9ea8e0e60e6c36ee5b45
5
5
  SHA512:
6
- metadata.gz: 7a6ae839f41a31c0615561ebf08c57df799ff576ef4cfde32e30eab5373e8289ca053887c272c8c2d0bc44c0643b29a41fe45a54e6f278514b6e05eecb6c8816
7
- data.tar.gz: 7dd19ed30d13acaef9ed75649098611f36af8c19f314c4366e829e587c67a2f057ad88e9028c8058c66263b72384ff1e8cc481a48725a3e9924d7687b5edfe74
6
+ metadata.gz: 1b2085738c14c7615632c38d3423c6fdf55c2c21a91c174e01b0fa04e32674721b5f87bbe65a1a50661b34c1dd36b223994a98b6a580691579da10b38a82193b
7
+ data.tar.gz: 90afb5a30ecdff9033fe954c79f58e6a9776a56458a4f08ffbb340b4621e0a4235ce729a65ebe0b0e08a5628a3a84fa26c95c215bb36e2adc73622447b676f13
data/lib/mfynab/cli.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "yaml"
4
+ require "mfynab/config"
4
5
  require "mfynab/money_forward"
5
6
  require "mfynab/money_forward/session"
6
7
  require "mfynab/money_forward_data"
@@ -18,20 +19,9 @@ module MFYNAB
18
19
 
19
20
  def start
20
21
  logger.info("Running...")
21
-
22
22
  money_forward.update_accounts(money_forward_account_names)
23
-
24
- Dir.mktmpdir("mfynab") do |save_path|
25
- money_forward.download_csv(
26
- path: save_path,
27
- months: months_to_sync,
28
- )
29
-
30
- data = MoneyForwardData.new(logger: logger)
31
- data.read_all_csv(save_path)
32
- ynab_transaction_importer.run(data.to_h)
33
- end
34
-
23
+ data = money_forward.fetch_data(config.months_to_sync)
24
+ ynab_transaction_importer.run(data.to_h)
35
25
  logger.info("Done!")
36
26
  end
37
27
 
@@ -40,30 +30,26 @@ module MFYNAB
40
30
  attr_reader :argv
41
31
 
42
32
  def money_forward_account_names
43
- @_money_forward_account_names = config["accounts"].map { _1["money_forward_name"] }
33
+ @_money_forward_account_names = config.accounts.map { _1["money_forward_name"] }
44
34
  end
45
35
 
46
36
  def ynab_transaction_importer
47
37
  @_ynab_transaction_importer ||= YnabTransactionImporter.new(
48
- config["ynab_access_token"],
49
- config["ynab_budget"],
50
- config["accounts"],
38
+ config.credentials["ynab_access_token"],
39
+ config.ynab_budget,
40
+ config.accounts,
51
41
  logger: logger,
52
42
  )
53
43
  end
54
44
 
55
- def months_to_sync
56
- config.fetch("months_to_sync", 3)
57
- end
58
-
59
45
  def money_forward
60
46
  @_money_forward ||= MoneyForward.new(session, logger: logger)
61
47
  end
62
48
 
63
49
  def session
64
50
  @_session ||= MoneyForward::Session.new(
65
- username: config["moneyforward_username"],
66
- password: config["moneyforward_password"],
51
+ username: config.credentials["moneyforward_username"],
52
+ password: config.credentials["moneyforward_password"],
67
53
  logger: logger,
68
54
  )
69
55
  end
@@ -75,15 +61,7 @@ module MFYNAB
75
61
  end
76
62
 
77
63
  def config
78
- @_config ||= YAML
79
- .load_file(config_file)
80
- .values
81
- .first
82
- .merge(
83
- "ynab_access_token" => ENV.fetch("YNAB_ACCESS_TOKEN"),
84
- "moneyforward_username" => ENV.fetch("MONEYFORWARD_USERNAME"),
85
- "moneyforward_password" => ENV.fetch("MONEYFORWARD_PASSWORD"),
86
- )
64
+ @_config ||= Config.from_yaml(config_file, logger)
87
65
  end
88
66
 
89
67
  def logger
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "mfynab/credentials_normalizer"
4
+
5
+ module MFYNAB
6
+ class Config
7
+ DEFAULT_MONTHS_TO_SYNC = 3
8
+
9
+ def initialize(hash_config, logger)
10
+ @hash_config = hash_config
11
+ @logger = logger
12
+ end
13
+
14
+ def self.from_yaml(file, logger)
15
+ yaml_data = YAML.load_file(file)
16
+ # Backwards compatibility: support old config files that still have a top-level key.
17
+ # TODO: at some point (major version bump), we should probably remove this.
18
+ unless yaml_data.key?("accounts")
19
+ logger.warn("Top-level key in configuration file is deprecated. Please remove it.")
20
+ yaml_data = yaml_data.values.first
21
+ end
22
+
23
+ raise "Invalid configuration file" unless yaml_data.key?("accounts")
24
+
25
+ new(yaml_data, logger)
26
+ end
27
+
28
+ def ynab_budget
29
+ hash_config.fetch("ynab_budget")
30
+ end
31
+
32
+ def months_to_sync
33
+ hash_config.fetch("months_to_sync", DEFAULT_MONTHS_TO_SYNC)
34
+ end
35
+
36
+ def accounts
37
+ hash_config.fetch("accounts", [])
38
+ end
39
+
40
+ def credentials
41
+ @_credentials ||= CredentialsNormalizer.new(hash_config, logger).normalize
42
+ end
43
+
44
+ private
45
+
46
+ attr_reader :hash_config, :logger
47
+ end
48
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MFYNAB
4
+ class CredentialsNormalizer
5
+ def initialize(hash_config, logger)
6
+ @hash_config = hash_config
7
+ @logger = logger
8
+ end
9
+
10
+ def normalize
11
+ config = hash_config["credentials"]
12
+ if config.nil?
13
+ logger.warn("No credentials found in configuration file. Please update your configuration file.")
14
+ # This provides backwards compatibility with old configuration files
15
+ # that did not include the new credentials.
16
+ # TODO: at some point (major version bump), we should probably remove this.
17
+ return {
18
+ "ynab_access_token" => ENV.fetch("YNAB_ACCESS_TOKEN"),
19
+ "moneyforward_username" => ENV.fetch("MONEYFORWARD_USERNAME"),
20
+ "moneyforward_password" => ENV.fetch("MONEYFORWARD_PASSWORD"),
21
+ }
22
+ end
23
+
24
+ config.transform_values { normalize_credential(_1) }
25
+ end
26
+
27
+ private
28
+
29
+ attr_reader :hash_config, :logger
30
+
31
+ def normalize_credential(value)
32
+ case value
33
+ when String
34
+ value
35
+ when Hash
36
+ if !value.key?("type") || value["type"] == "literal"
37
+ value.fetch("value")
38
+ elsif value["type"] == "env"
39
+ ENV.fetch(value.fetch("value"))
40
+ else
41
+ raise "Unknown credential type: #{value['type']}"
42
+ end
43
+ else
44
+ raise "Unknown credential type: #{value.class}"
45
+ end
46
+ end
47
+ end
48
+ end
@@ -32,6 +32,19 @@ module MFYNAB
32
32
  update_accounts(account_names, update_invalid: false)
33
33
  end
34
34
 
35
+ def fetch_data(months)
36
+ Dir.mktmpdir("mfynab") do |save_path|
37
+ download_csv(
38
+ path: save_path,
39
+ months: months,
40
+ )
41
+
42
+ MoneyForwardData.new(logger: logger).tap do |data|
43
+ data.read_all_csv(save_path)
44
+ end
45
+ end
46
+ end
47
+
35
48
  def download_csv(path:, months:)
36
49
  month = Date.today
37
50
  month -= month.day - 1 # First day of month
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MFYNAB
4
- VERSION = "0.2.0"
4
+ VERSION = "0.3.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mfynab
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Stosik
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-03-25 00:00:00.000000000 Z
11
+ date: 2025-03-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: csv
@@ -90,6 +90,8 @@ extra_rdoc_files: []
90
90
  files:
91
91
  - exe/mfynab
92
92
  - lib/mfynab/cli.rb
93
+ - lib/mfynab/config.rb
94
+ - lib/mfynab/credentials_normalizer.rb
93
95
  - lib/mfynab/money_forward.rb
94
96
  - lib/mfynab/money_forward/account_status.rb
95
97
  - lib/mfynab/money_forward/session.rb