Icarus-Mod-Tools 1.7.1 → 1.8.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: fd3e0ae69c6ef23c28a6f91e0ea2bef191fb23cb497624c4a6861542f0d55529
4
- data.tar.gz: 74f1b174266c581ab857fd8079bc08345e055c12de0df175a24b84d5cf943c0b
3
+ metadata.gz: e89daa8f362dd79f861a471ca6793f767e753fd2627d0ba8e1845fedaace7d12
4
+ data.tar.gz: a47625e44ac934097f21f17303068728926b9a32e814c81d09736bc49d08cefd
5
5
  SHA512:
6
- metadata.gz: 3e2065dcd3968f5e692db72955f6c898e16c442c47cca55681586fb6c9b07c1ba7ed19c48b402b73b02004f70fb6c25def55d4f9daa4a46b1316ec5a2489e019
7
- data.tar.gz: e56b480e1bd28fe040e0cd7a561f848596a654bb492457c92244902dbc046fe8a5ce8634f49455322ef03587c2762dc4003eb38e2b9c1fea5a7681562572a700
6
+ metadata.gz: dd9a8c3c7d816b49d5e5f5828b66f87646b0fa9f8d01cd11ab8034a3572c0a1942e5459f51d22a518d70433b938d4041bfd8dfba0ea3943fa0dd82747a2980f2
7
+ data.tar.gz: 2f82e939d00a943115b2c32432883fe6086a62da45e2749eb6db6d86f6bd73298c79d45ae808a23dbf4d612729d5510387b04159915a92ec43984f4e3239f3c6
data/.rubocop.yml CHANGED
@@ -38,6 +38,9 @@ Metrics/AbcSize:
38
38
  Exclude:
39
39
  - lib/icarus/mod/cli/*.rb # Thor command files
40
40
 
41
+ Metrics/ClassLength:
42
+ Enabled: false
43
+
41
44
  Metrics/MethodLength:
42
45
  Max: 50
43
46
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- Icarus-Mod-Tools (1.7.1)
4
+ Icarus-Mod-Tools (1.8.0)
5
5
  google-cloud-firestore (~> 2.7)
6
6
  octokit (~> 6.0)
7
7
  paint (~> 2.3)
@@ -16,7 +16,7 @@ GEM
16
16
  coderay (1.1.3)
17
17
  concurrent-ruby (1.1.10)
18
18
  diff-lcs (1.5.0)
19
- faraday (2.7.3)
19
+ faraday (2.7.4)
20
20
  faraday-net_http (>= 2.0, < 3.1)
21
21
  ruby2_keywords (>= 0.0.4)
22
22
  faraday-net_http (3.0.2)
@@ -51,6 +51,7 @@ GEM
51
51
  gapic-common (>= 0.16.0, < 2.a)
52
52
  google-cloud-errors (~> 1.0)
53
53
  google-protobuf (3.21.12-x86_64-darwin)
54
+ google-protobuf (3.21.12-x86_64-linux)
54
55
  googleapis-common-protos (1.4.0)
55
56
  google-protobuf (~> 3.14)
56
57
  googleapis-common-protos-types (~> 1.2)
@@ -67,6 +68,9 @@ GEM
67
68
  grpc (1.50.0-x86_64-darwin)
68
69
  google-protobuf (~> 3.21)
69
70
  googleapis-common-protos-types (~> 1.0)
71
+ grpc (1.50.0-x86_64-linux)
72
+ google-protobuf (~> 3.21)
73
+ googleapis-common-protos-types (~> 1.0)
70
74
  guard (2.18.0)
71
75
  formatador (>= 0.2.4)
72
76
  listen (>= 2.7, < 4.0)
@@ -112,7 +116,7 @@ GEM
112
116
  rb-inotify (0.10.1)
113
117
  ffi (~> 1.0)
114
118
  rbtree (0.4.6)
115
- regexp_parser (2.6.1)
119
+ regexp_parser (2.6.2)
116
120
  rexml (3.2.5)
117
121
  rspec (3.12.0)
118
122
  rspec-core (~> 3.12.0)
@@ -123,7 +127,7 @@ GEM
123
127
  rspec-expectations (3.12.2)
124
128
  diff-lcs (>= 1.2.0, < 2.0)
125
129
  rspec-support (~> 3.12.0)
126
- rspec-mocks (3.12.2)
130
+ rspec-mocks (3.12.3)
127
131
  diff-lcs (>= 1.2.0, < 2.0)
128
132
  rspec-support (~> 3.12.0)
129
133
  rspec-support (3.12.0)
@@ -139,8 +143,11 @@ GEM
139
143
  unicode-display_width (>= 2.4.0, < 3.0)
140
144
  rubocop-ast (1.24.1)
141
145
  parser (>= 3.1.1.0)
142
- rubocop-rspec (2.17.0)
146
+ rubocop-capybara (2.17.0)
147
+ rubocop (~> 1.41)
148
+ rubocop-rspec (2.18.1)
143
149
  rubocop (~> 1.33)
150
+ rubocop-capybara (~> 2.17)
144
151
  ruby-progressbar (1.11.0)
145
152
  ruby2_keywords (0.0.5)
146
153
  sawyer (0.9.2)
@@ -14,8 +14,10 @@
14
14
  },
15
15
  "collections": {
16
16
  "modinfo": "meta/modinfo",
17
+ "proginfo": "meta/proginfo",
17
18
  "repositories": "meta/repos",
18
- "mods": "mods"
19
+ "mods": "mods",
20
+ "progs": "progs"
19
21
  }
20
22
  },
21
23
  "github": {
@@ -10,9 +10,16 @@ module Icarus
10
10
  class List < SubcommandBase
11
11
  desc "modinfo", "Displays data from 'meta/modinfo/list'"
12
12
  def modinfo
13
- modinfos = Firestore.new.list(:modinfo)
14
- puts modinfos
15
- puts "Total: #{modinfos.count}" if verbose > 1
13
+ modinfo_array = Firestore.new.list(:modinfo)
14
+ puts modinfo_array
15
+ puts "Total: #{modinfo_array.count}" if verbose > 1
16
+ end
17
+
18
+ desc "proginfo", "Displays data from 'meta/proginfo/list'"
19
+ def proginfo
20
+ proginfo_array = Firestore.new.list(:proginfo)
21
+ puts proginfo_array
22
+ puts "Total: #{proginfo_array.count}" if verbose > 1
16
23
  end
17
24
 
18
25
  desc "repos", "Displays data from 'meta/repos/list'"
@@ -1,13 +1,25 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "tools/modinfo_sync"
4
+ require "tools/proginfo_sync"
4
5
  require "tools/mod_sync"
6
+ require "tools/prog_sync"
5
7
 
6
8
  module Icarus
7
9
  module Mod
8
10
  module CLI
9
11
  # Sync CLI command definitions
10
12
  class Sync < SubcommandBase
13
+ class_option :dry_run, type: :boolean, default: false, desc: "Dry run (no changes will be made)"
14
+
15
+ desc "all", "Run all sync jobs"
16
+ def all
17
+ invoke :proginfo
18
+ invoke :progs
19
+ invoke :modinfo
20
+ invoke :mods
21
+ end
22
+
11
23
  desc "modinfo", "Reads from 'meta/repos/list' and Syncs any modinfo files we find (github only for now)"
12
24
  def modinfo
13
25
  modinfo_sync = Icarus::Mod::Tools::ModinfoSync.new
@@ -20,11 +32,44 @@ module Icarus
20
32
  puts "Retrieving modinfo Array..." if verbose?
21
33
  modinfo_array = modinfo_sync.modinfo_data(repositories, verbose: verbose > 1)&.map(&:download_url)&.compact
22
34
 
23
- raise Icarus::Mod::Tools::Error, "Unable to find any modinfo.json files!" unless modinfo_array&.any?
35
+ raise Icarus::Mod::Tools::Error, "No modinfo.json files found" unless modinfo_array&.any?
36
+
37
+ if options[:dry_run]
38
+ puts "Dry run; no changes will be made"
39
+ return
40
+ end
24
41
 
25
42
  puts "Saving to Firestore..." if verbose?
26
43
  response = modinfo_sync.update(modinfo_array)
27
44
  puts response ? "Success" : "Failure (may be no changes)" if verbose?
45
+ rescue Icarus::Mod::Tools::Error => e
46
+ warn e.message
47
+ end
48
+
49
+ desc "proginfo", "Reads from 'meta/repos/list' and Syncs any proginfo files we find (github only for now)"
50
+ def proginfo
51
+ proginfo_sync = Icarus::Mod::Tools::ProginfoSync.new
52
+
53
+ puts "Retrieving repository Data..." if verbose?
54
+ repositories = proginfo_sync.repositories
55
+
56
+ raise Icarus::Mod::Tools::Error, "Unable to find any repositories!" unless repositories.any?
57
+
58
+ puts "Retrieving proginfo Array..." if verbose?
59
+ proginfo_array = proginfo_sync.proginfo_data(repositories, verbose: verbose > 1)&.map(&:download_url)&.compact
60
+
61
+ raise Icarus::Mod::Tools::Error, "no proginfo.json files found" unless proginfo_array&.any?
62
+
63
+ if options[:dry_run]
64
+ puts "Dry run; no changes will be made"
65
+ return
66
+ end
67
+
68
+ puts "Saving to Firestore..." if verbose?
69
+ response = proginfo_sync.update(proginfo_array)
70
+ puts response ? "Success" : "Failure (may be no changes)" if verbose?
71
+ rescue Icarus::Mod::Tools::Error => e
72
+ warn e.message
28
73
  end
29
74
 
30
75
  desc "mods", "Reads from 'meta/modinfo/list' and updates the 'mods' database accordingly"
@@ -55,10 +100,21 @@ module Icarus
55
100
  end
56
101
 
57
102
  print format("#{verb} %-<name>60s", name: "'#{mod.author || "NoOne"}/#{mod.name || "Unnamed"}'") if verbose > 1
103
+
104
+ if options[:dry_run]
105
+ puts "Dry run; no changes will be made" if verbose > 1
106
+ next
107
+ end
108
+
58
109
  response = modsync.update(mod)
59
110
  puts format("%<status>10s", status: response ? "Success" : "Failure") if verbose > 1
60
111
  end
61
112
 
113
+ if options[:dry_run]
114
+ puts "Dry run; no changes will be made" if verbose?
115
+ return
116
+ end
117
+
62
118
  puts "Created/Updated #{modinfo_array.count} mods" if verbose?
63
119
 
64
120
  delete_array = mod_array.filter { |mod| modsync.find_modinfo(mod).nil? }
@@ -75,7 +131,67 @@ module Icarus
75
131
  puts "Deleted #{delete_array.count} outdated mods" if verbose?
76
132
  rescue Icarus::Mod::Tools::Error => e
77
133
  warn e.message
78
- exit 1
134
+ end
135
+
136
+ desc "progs", "Reads from 'meta/proginfo/list' and updates the 'progs' database accordingly"
137
+ method_option :check, type: :boolean, default: false, desc: "Validate proginfo without applying changes"
138
+ def progs
139
+ progsync = Icarus::Mod::Tools::ProgSync.new
140
+
141
+ puts "Retrieving proginfo Data..." if verbose?
142
+ proginfo_array = progsync.proginfo_array
143
+
144
+ puts "Retrieving progs Data..." if verbose?
145
+ prog_array = progsync.progs
146
+
147
+ return if options[:check]
148
+
149
+ puts "Updating Program Data..." if verbose?
150
+ proginfo_array.each do |prog|
151
+ verb = "Creating"
152
+
153
+ puts "Validating proginfo Data for #{prog.uniq_name}..." if verbose > 2
154
+ warn "Skipping program #{prog.uniq_name} due to validation errors" && next unless prog.validate
155
+
156
+ doc_id = progsync.find_prog(prog)
157
+ if doc_id
158
+ puts "Found existing program #{prog.name} at #{doc_id}" if verbose > 2
159
+ prog.id = doc_id
160
+ verb = "Updating"
161
+ end
162
+
163
+ print format("#{verb} %-<name>60s", name: "'#{prog.author || "NoOne"}/#{prog.name || "Unnamed"}'") if verbose > 1
164
+
165
+ if options[:dry_run]
166
+ puts "Dry run; no changes will be made" if verbose > 1
167
+ next
168
+ end
169
+
170
+ response = progsync.update(prog)
171
+ puts format("%<status>10s", status: response ? "Success" : "Failure") if verbose > 1
172
+ end
173
+
174
+ if options[:dry_run]
175
+ puts "Dry run; no changes will be made" if verbose?
176
+ return
177
+ end
178
+
179
+ puts "Created/Updated #{proginfo_array.count} Programs" if verbose?
180
+
181
+ delete_array = prog_array.filter { |prog| progsync.find_proginfo(prog).nil? }
182
+
183
+ return unless delete_array.any?
184
+
185
+ puts "Deleting outdated programs..." if verbose?
186
+ delete_array.each do |prog|
187
+ print format("Deleting %-<name>60s", name: "'#{prog.author || "NoOne"}/#{prog.name || "Unnamed'"}") if verbose > 1
188
+ response = progsync.delete(prog)
189
+ puts format("%<status>10s", status: response ? "Success" : "Failure") if verbose > 1
190
+ end
191
+
192
+ puts "Deleted #{delete_array.count} outdated programs" if verbose?
193
+ rescue Icarus::Mod::Tools::Error => e
194
+ warn e.message
79
195
  end
80
196
  end
81
197
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "google/cloud/firestore"
4
4
  require "tools/modinfo"
5
+ require "tools/proginfo"
5
6
 
6
7
  module Icarus
7
8
  module Mod
@@ -18,52 +19,65 @@ module Icarus
18
19
  @repos ||= list(:repositories)
19
20
  end
20
21
 
21
- def modinfo_array
22
- @modinfo_array ||= list(:modinfo)
22
+ def modinfo_list
23
+ @modinfo_list ||= list(:modinfo)
24
+ end
25
+
26
+ def proginfo_list
27
+ @proginfo_list ||= list(:proginfo)
23
28
  end
24
29
 
25
30
  def mods
26
31
  @mods ||= list(:mods)
27
32
  end
28
33
 
29
- def find_mod(name:, author:)
30
- mods.find { |mod| mod.name == name && mod.author == author }
34
+ def progs
35
+ @progs ||= list(:progs)
36
+ end
37
+
38
+ def find_by_type(type:, name:, author:)
39
+ list(type).find { |obj| obj.name == name && obj.author == author }
40
+ end
41
+
42
+ def get_list(type)
43
+ raise "Invalid type: #{type} - unknown collection" unless collections.respond_to?(type)
44
+
45
+ @client.doc(collections.send(type)).get[:list]
31
46
  end
32
47
 
33
48
  def list(type)
34
- case type
35
- when :modinfo
36
- @client.doc(collections.modinfo).get[:list]
37
- when :repositories
38
- @client.doc(collections.repositories).get[:list]
39
- when :mods
40
- @client.col(collections.mods).get.map do |doc|
41
- Icarus::Mod::Tools::Modinfo.new(doc.data, id: doc.document_id, created: doc.create_time, updated: doc.update_time)
49
+ case type.to_sym
50
+ when :modinfo, :proginfo, :repositories
51
+ get_list(type)
52
+ when :mods, :progs
53
+ @client.col(collections.send(type)).get.map do |doc|
54
+ klass = type == :mods ? Icarus::Mod::Tools::Modinfo : Icarus::Mod::Tools::Proginfo
55
+ klass.new(doc.data, id: doc.document_id, created: doc.create_time, updated: doc.update_time)
42
56
  end
43
57
  else
44
58
  raise "Invalid type: #{type}"
45
59
  end
46
60
  end
47
61
 
48
- def update_or_create_mod(payload, merge:)
49
- doc_id = payload.id || find_mod(name: payload.name, author: payload.author)&.id
62
+ def update_or_create(type, payload, merge:)
63
+ doc_id = payload.id || find_by_type(type:, name: payload.name, author: payload.author)&.id
50
64
 
51
- return @client.doc("#{collections.mods}/#{doc_id}").set(payload.to_h, merge:) if doc_id
65
+ return @client.doc("#{collections.send(type)}/#{doc_id}").set(payload.to_h, merge:) if doc_id
52
66
 
53
- @client.col(collections.mods).add(payload.to_h)
67
+ @client.col(collections.send(type)).add(payload.to_h)
54
68
  end
55
69
 
56
70
  def update(type, payload, merge: false)
57
71
  raise "You must specify a payload to update" if payload&.empty? || payload.nil?
58
72
 
59
- case type
60
- when :modinfo
61
- update_array = (modinfo_array + [payload]).flatten.uniq
62
- response = @client.doc(collections.modinfo).set({ list: update_array }, merge:) if update_array.any?
73
+ case type.to_sym
74
+ when :modinfo, :proginfo
75
+ update_array = (send("#{type}_list") + [payload]).flatten.uniq
76
+ response = @client.doc(collections.send(type)).set({ list: update_array }, merge:) if update_array.any?
63
77
  when :repositories
64
78
  response = @client.doc(collections.repositories).set({ list: payload }, merge:)
65
- when :mod
66
- response = update_or_create_mod(payload, merge:)
79
+ when :mod, :prog
80
+ response = update_or_create(pluralize(type), payload, merge:)
67
81
  else
68
82
  raise "Invalid type: #{type}"
69
83
  end
@@ -72,15 +86,21 @@ module Icarus
72
86
  end
73
87
 
74
88
  def delete(type, payload)
75
- case type
76
- when :mod
77
- response = @client.doc("#{collections.mods}/#{payload.id}").delete
89
+ case type.to_sym
90
+ when :mod, :prog
91
+ response = @client.doc("#{collections.send(pluralize(type))}/#{payload.id}").delete
78
92
  else
79
93
  raise "Invalid type: #{type}"
80
94
  end
81
95
 
82
96
  response.is_a?(Google::Cloud::Firestore::CommitResponse::WriteResult)
83
97
  end
98
+
99
+ private
100
+
101
+ def pluralize(type)
102
+ type.to_s.end_with?("s") ? type.to_s : "#{type}s"
103
+ end
84
104
  end
85
105
  end
86
106
  end
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Icarus
4
+ module Mod
5
+ module Tools
6
+ # Base class for Modinfo and Proginfo
7
+ class Baseinfo
8
+ attr_reader :data, :errors, :id, :created_at, :updated_at, :warnings
9
+
10
+ HASHKEYS = %i[name author version compatibility description fileType fileURL imageURL readmeURL].freeze
11
+
12
+ def initialize(data, id: nil, created: nil, updated: nil)
13
+ @id = id
14
+ @created_at = created
15
+ @updated_at = updated
16
+ @errors = []
17
+ @warnings = []
18
+
19
+ read(data)
20
+ end
21
+
22
+ def read(data)
23
+ @data = data.is_a?(String) ? JSON.parse(data, symbolize_names: true) : data
24
+ end
25
+
26
+ def uniq_name
27
+ "#{author}/#{name}"
28
+ end
29
+
30
+ def to_json(*args)
31
+ JSON.generate(@data, *args)
32
+ end
33
+
34
+ def to_h
35
+ HASHKEYS.each_with_object({}) { |key, hash| hash[key] = @data[key] }
36
+ end
37
+
38
+ def validate
39
+ @warnings << "Version should be a version string" unless validate_version(version)
40
+
41
+ %w[name author description].each do |key|
42
+ @errors << "#{key.capitalize} cannot be blank" unless validate_string(@data[key.to_sym])
43
+ end
44
+
45
+ @errors << "Invalid fileType: #{fileType || "blank"}" unless validate_filetype(fileType)
46
+
47
+ %w[fileURL imageURL readmeURL].each do |key|
48
+ @errors << "Invalid URL #{key.capitalize}: #{@data[key.to_sym] || "blank"}" unless validate_url(@data[key.to_sym])
49
+ end
50
+
51
+ @errors.empty?
52
+ end
53
+
54
+ def method_missing(method_name, *_args, &)
55
+ @data[method_name.to_sym]&.strip
56
+ end
57
+
58
+ def respond_to_missing?(method_name, include_private = false)
59
+ HASHKEYS.include?(method_name.to_sym) || super
60
+ end
61
+
62
+ private
63
+
64
+ def validate_url(url)
65
+ return true if url.nil? || url.empty?
66
+
67
+ url =~ URI::DEFAULT_PARSER.make_regexp
68
+ end
69
+
70
+ def validate_filetype(filetype)
71
+ %w[pak zip exmod].include?(filetype.downcase)
72
+ end
73
+
74
+ def validate_string(string)
75
+ !(string.nil? || string.empty?)
76
+ end
77
+
78
+ def validate_version(version)
79
+ version =~ /\d+\.\d+[.\d+]?/
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -19,7 +19,7 @@ module Icarus
19
19
  end
20
20
 
21
21
  def modinfo_array
22
- @modinfo_array ||= @firestore.modinfo_array.map do |url|
22
+ @modinfo_array ||= @firestore.modinfo_list.map do |url|
23
23
  retrieve_from_url(url)[:mods].map { |mod| Modinfo.new(mod) if mod[:name] =~ /[a-z0-9]+/i }
24
24
  rescue Icarus::Mod::Tools::RequestFailed
25
25
  warn "Skipped; Failed to retrieve #{url}"
@@ -31,7 +31,7 @@ module Icarus
31
31
  end
32
32
 
33
33
  def find_mod(modinfo)
34
- @firestore.find_mod(name: modinfo.name, author: modinfo.author)&.id
34
+ @firestore.find_by_type(type: "mods", name: modinfo.name, author: modinfo.author)&.id
35
35
  end
36
36
 
37
37
  def find_modinfo(modinfo)
@@ -1,100 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "tools/baseinfo"
4
+
3
5
  module Icarus
4
6
  module Mod
5
7
  module Tools
6
8
  # Sync methods
7
- class Modinfo
8
- attr_reader :data, :errors, :id, :created_at, :updated_at, :warnings
9
-
9
+ class Modinfo < Baseinfo
10
10
  HASHKEYS = %i[name author version compatibility description long_description fileType fileURL imageURL readmeURL].freeze
11
11
 
12
- def initialize(data, id: nil, created: nil, updated: nil)
13
- @id = id
14
- @created_at = created
15
- @updated_at = updated
16
- @errors = []
17
- @warnings = []
18
-
19
- read(data)
20
- end
21
-
22
- def read(data)
23
- @data = data.is_a?(String) ? JSON.parse(data, symbolize_names: true) : data
24
- end
25
-
26
- def uniq_name
27
- "#{author}/#{name}"
28
- end
29
-
30
12
  # rubocop:disable Naming/MethodName
31
13
  def fileType
32
14
  @data[:fileType] || "pak"
33
15
  end
34
16
  # rubocop:enable Naming/MethodName
35
-
36
- def to_json(*args)
37
- JSON.generate(@data, *args)
38
- end
39
-
40
- def to_h
41
- {
42
- name:,
43
- author:,
44
- version:,
45
- compatibility:,
46
- description:,
47
- long_description:,
48
- fileType:,
49
- fileURL:,
50
- imageURL:,
51
- readmeURL:
52
- }
53
- end
54
-
55
- def validate
56
- @warnings << "Version should be a version string" unless validate_version(version)
57
-
58
- %w[name author description].each do |key|
59
- @errors << "#{key.capitalize} cannot be blank" unless validate_string(@data[key.to_sym])
60
- end
61
-
62
- @errors << "Invalid fileType: #{fileType || "blank"}" unless validate_filetype(fileType)
63
-
64
- %w[fileURL imageURL readmeURL].each do |key|
65
- @errors << "Invalid URL #{key.capitalize}: #{@data[key.to_sym] || "blank"}" unless validate_url(@data[key.to_sym])
66
- end
67
-
68
- @errors.empty?
69
- end
70
-
71
- def method_missing(method_name, *_args, &)
72
- @data[method_name.to_sym]&.strip
73
- end
74
-
75
- def respond_to_missing?(method_name, include_private = false)
76
- HASHKEYS.include?(method_name.to_sym) || super
77
- end
78
-
79
- private
80
-
81
- def validate_url(url)
82
- return true if url.nil? || url.empty?
83
-
84
- url =~ URI::DEFAULT_PARSER.make_regexp
85
- end
86
-
87
- def validate_filetype(filetype)
88
- %w[pak zip exmod].include?(filetype.downcase)
89
- end
90
-
91
- def validate_string(string)
92
- !(string.nil? || string.empty?)
93
- end
94
-
95
- def validate_version(version)
96
- version =~ /\d+\.\d+[.\d+]?/
97
- end
98
17
  end
99
18
  end
100
19
  end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "firestore"
4
+ require "tools/sync_helpers"
5
+
6
+ module Icarus
7
+ module Mod
8
+ module Tools
9
+ # Sync methods
10
+ class ProgSync
11
+ include SyncHelpers
12
+
13
+ def initialize
14
+ @firestore = Firestore.new
15
+ end
16
+
17
+ def progs
18
+ @firestore.progs
19
+ end
20
+
21
+ def proginfo_array
22
+ @proginfo_array ||= @firestore.proginfo_list.map do |url|
23
+ retrieve_from_url(url)[:programs].map { |prog| Proginfo.new(prog) if prog[:name] =~ /[a-z0-9]+/i }
24
+ rescue Icarus::Mod::Tools::RequestFailed
25
+ warn "Skipped; Failed to retrieve #{url}"
26
+ next
27
+ rescue JSON::ParserError => e
28
+ warn "Skipped; Invalid JSON: #{e.full_message}"
29
+ next
30
+ end.flatten.compact
31
+ end
32
+
33
+ def find_prog(proginfo)
34
+ @firestore.find_by_type(type: "progs", name: proginfo.name, author: proginfo.author)&.id
35
+ end
36
+
37
+ def find_proginfo(proginfo)
38
+ @proginfo_array.find { |prog| prog.name == proginfo.name }
39
+ end
40
+
41
+ def update(proginfo)
42
+ @firestore.update(:prog, proginfo, merge: false)
43
+ end
44
+
45
+ def delete(proginfo)
46
+ @firestore.delete(:prog, proginfo)
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "tools/baseinfo"
4
+
5
+ module Icarus
6
+ module Mod
7
+ module Tools
8
+ # Sync methods
9
+ class Proginfo < Baseinfo
10
+ # rubocop:disable Naming/MethodName
11
+ def fileType
12
+ @data[:fileType] || "zip"
13
+ end
14
+ # rubocop:enable Naming/MethodName
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "firestore"
4
+ require "github"
5
+ require "tools/sync_helpers"
6
+
7
+ module Icarus
8
+ module Mod
9
+ module Tools
10
+ # Sync methods
11
+ class ProginfoSync
12
+ include SyncHelpers
13
+
14
+ def initialize
15
+ @firestore = Firestore.new
16
+ @github = Github.new
17
+ @repositories = []
18
+ end
19
+
20
+ def repositories
21
+ @firestore.repos
22
+ end
23
+
24
+ def update(proginfo_array)
25
+ @firestore.update(:proginfo, proginfo_array)
26
+ end
27
+
28
+ def proginfo(url)
29
+ retrieve_from_url(url)
30
+ end
31
+
32
+ def proginfo_data(repositories, verbose: false)
33
+ repositories.map do |repo|
34
+ print "searching #{repo}..." if verbose
35
+
36
+ case repo
37
+ when /github/
38
+ @github.repository = repo
39
+ proginfo_url = @github.find("proginfo.json")
40
+
41
+ unless proginfo_url
42
+ puts "Skipped...no proginfo.json" if verbose
43
+ next
44
+ end
45
+
46
+ puts "Found!" if verbose
47
+ proginfo_url
48
+ else
49
+ puts "Skipped...repository type not supported yet" if verbose
50
+ end
51
+ end.compact
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Icarus
4
4
  module Mod
5
- VERSION = "1.7.1"
5
+ VERSION = "1.8.0"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: Icarus-Mod-Tools
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.1
4
+ version: 1.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Donovan Young
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-01-21 00:00:00.000000000 Z
11
+ date: 2023-01-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: google-cloud-firestore
@@ -97,10 +97,14 @@ files:
97
97
  - lib/icarus/mod/firestore.rb
98
98
  - lib/icarus/mod/github.rb
99
99
  - lib/icarus/mod/tools.rb
100
+ - lib/icarus/mod/tools/baseinfo.rb
100
101
  - lib/icarus/mod/tools/mod_sync.rb
101
102
  - lib/icarus/mod/tools/modinfo.rb
102
103
  - lib/icarus/mod/tools/modinfo_sync.rb
103
104
  - lib/icarus/mod/tools/modinfo_validate.rb
105
+ - lib/icarus/mod/tools/prog_sync.rb
106
+ - lib/icarus/mod/tools/proginfo.rb
107
+ - lib/icarus/mod/tools/proginfo_sync.rb
104
108
  - lib/icarus/mod/tools/sync_helpers.rb
105
109
  - lib/icarus/mod/version.rb
106
110
  - sig/database/sync/sync.rbs