factorio-mod 0.6.0 → 0.7.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: e8417b98fa7593e0defd4c676d400840e998ab87fd5a63e2c625df220bb8be24
4
- data.tar.gz: ecd77d7c281591a9642d193d135552d6b4ac08079b070ce2c53728e8ed6c7160
3
+ metadata.gz: 2499144d6520545aead798fd61a95fd8ed40a3ee57cfcfdf271dcb4a2a752cf0
4
+ data.tar.gz: f63270dbc3eb0694861c72c9b57732b0caecb7c2bfa39eb581dc9def5fa3577a
5
5
  SHA512:
6
- metadata.gz: 95279289b28a0d647187119ae06da9af3c4b334d105f491e6dd85ffe7c30b24fe30d0d64e140b1d7be90cca1a30aae38105292c286637676e199b0b8c6caaf26
7
- data.tar.gz: 27b3e5dd78066ef18f123407130598c6a37d1b33f5f3b145f855008e38c64437eb68591264daf5d1d97146f65abe3c87177cfe2df0bff037c4705289d2776e32
6
+ metadata.gz: 0bc79117a850a53d01518aa0a4f928675ed8c9dae509a458dcbcb9cd8ddc0ff04bad444d298a6a88cbbcac8d451868fe5cee2e2c32d3062d3925a2ff977d9b3c
7
+ data.tar.gz: 7d926df0ea9cd9ccdc79824a8e7b6fe311c72889f637c819084a72f9f916f98b6e01e0d928d9dba15344fdf741408a5ac7f13d49e3cf47125da6e2fad2b3dd67
@@ -1,3 +1,4 @@
1
+ image: ruby:2.6.0
1
2
  before_script:
2
3
  - ruby -v
3
4
  - which ruby
@@ -1,2 +1,4 @@
1
1
  AllCops:
2
2
  TargetRubyVersion: '2.6.0'
3
+ Metrics/ClassLength:
4
+ Enabled: false
@@ -1,8 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- factorio-mod (0.6.0)
4
+ factorio-mod (0.7.0)
5
5
  activesupport (~> 5.2)
6
+ addressable (~> 2.6)
6
7
  nokogiri (~> 1.8)
7
8
 
8
9
  GEM
@@ -13,13 +14,15 @@ GEM
13
14
  i18n (>= 0.7, < 2)
14
15
  minitest (~> 5.1)
15
16
  tzinfo (~> 1.1)
17
+ addressable (2.6.0)
18
+ public_suffix (>= 2.0.2, < 4.0)
16
19
  ast (2.4.0)
17
20
  bump (0.7.0)
18
21
  coco (0.15.0)
19
22
  coderay (1.1.2)
20
23
  concurrent-ruby (1.1.4)
21
24
  diff-lcs (1.3)
22
- i18n (1.5.2)
25
+ i18n (1.5.3)
23
26
  concurrent-ruby (~> 1.0)
24
27
  jaro_winkler (1.5.2)
25
28
  method_source (0.9.2)
@@ -34,6 +37,7 @@ GEM
34
37
  pry (0.12.2)
35
38
  coderay (~> 1.1.0)
36
39
  method_source (~> 0.9.0)
40
+ public_suffix (3.0.3)
37
41
  rainbow (3.0.0)
38
42
  rake (10.5.0)
39
43
  rspec (3.8.0)
@@ -34,5 +34,6 @@ Gem::Specification.new do |spec|
34
34
  spec.add_development_dependency 'rubocop'
35
35
 
36
36
  spec.add_dependency 'activesupport', '~> 5.2'
37
+ spec.add_dependency 'addressable', '~> 2.6'
37
38
  spec.add_dependency 'nokogiri', '~> 1.8'
38
39
  end
@@ -12,7 +12,7 @@ require 'factorio/mod/cache'
12
12
  require 'open-uri'
13
13
  require 'net/http'
14
14
  require 'nokogiri'
15
- require 'erb' # for uri encode
15
+ require 'addressable'
16
16
 
17
17
  require 'active_support'
18
18
  require 'active_support/core_ext/object/blank.rb'
@@ -7,9 +7,10 @@ module Factorio
7
7
 
8
8
  attr_reader :cache
9
9
 
10
- # @param uri [String] Mod URI like `https://mods.factorio.com/mod/LTN-easier`
11
- def initialize(uri, cookie = '')
12
- @uri = uri
10
+ # @param name [String] Mod name
11
+ def initialize(name, cookie = '')
12
+ @name = name
13
+ @uri = Addressable::URI.encode("mod/#{@name}")
13
14
  @cookie = cookie
14
15
  @cache = {}
15
16
  end
@@ -17,13 +18,13 @@ module Factorio
17
18
  # Get the `Information` page.
18
19
  # @return [Nokogiri::HTML]
19
20
  def information
20
- get :information, @uri
21
+ get :information, Addressable::URI.join(Mod::MOD_URI, @uri)
21
22
  end
22
23
 
23
24
  # Get the `Downloads` page.
24
25
  # @return [Nokogiri::HTML]
25
26
  def downloads
26
- get :downloads, "#{@uri}/downloads"
27
+ get :downloads, Addressable::URI.join(Mod::MOD_URI, "#{@uri}/downloads")
27
28
  end
28
29
 
29
30
  # Get any page that already downloads.
@@ -51,7 +52,7 @@ module Factorio
51
52
  symbol = symbol.to_sym
52
53
  @cache[symbol] ||= Nokogiri::HTML(URI.open(uri, 'Cookie' => @cookie))
53
54
  rescue OpenURI::HTTPError => e
54
- raise NoMODError.new "MOD #{@uri.split('/').last} not found", e.io
55
+ raise NoModError.new "MOD #{@name} not found", e.io
55
56
  end
56
57
  end
57
58
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Factorio
4
- # The Exception that can't find MOD
5
- class NoMODError < StandardError
4
+ # The Exception that can't find Mod
5
+ class NoModError < StandardError
6
6
  attr_reader :io
7
7
  def initialize(msg, io)
8
8
  @io = io
@@ -25,17 +25,17 @@ module Factorio
25
25
  # @param cookie [String] logged in cookie
26
26
  def initialize(name, cookie = '')
27
27
  @name = name
28
- @mod = Cache.new "#{MOD_URI}/mod/#{ERB::Util.url_encode @name}", cookie
28
+ @mod = Cache.new name, cookie
29
29
  end
30
30
 
31
31
  private
32
32
 
33
33
  # Get the meta table from Information page.
34
34
  def data_table(key = nil)
35
- table = @mod.information.xpath("//div[@class='mod-page-data-table']")
35
+ table = @mod.information.xpath(".//div[@class='mod-page-data-table']")
36
36
  return table if key.blank?
37
37
 
38
- table.xpath "//td[../td[@class='data-name'][.='#{key}:']]"
38
+ table.xpath ".//td[../td[@class='data-name'][.='#{key}:']]"
39
39
  end
40
40
 
41
41
  public
@@ -98,26 +98,68 @@ module Factorio
98
98
  # @return [String] The logged in cookie
99
99
  def self.login_cookie(username, password)
100
100
  csrf_token, cookie = csrf_and_cookie
101
- data = URI.encode_www_form(
101
+ data = Addressable::URI.form_encode(
102
102
  'csrf_token' => csrf_token,
103
103
  'username' => username,
104
104
  'password' => password
105
105
  )
106
- Net::HTTP.post(URI(MOD_URI + '/login'), data, 'Cookie' => cookie) \
106
+ Net::HTTP.post(Addressable::URI.join(MOD_URI, '/login'),
107
+ data, 'Cookie' => cookie) \
107
108
  .response['set-cookie'].split('; ').first
108
109
  end
109
110
 
111
+ # Get mod name from mod card.
112
+ #
113
+ # @param card [Nokogiri::HTML]
114
+ # @return [String] The name in
115
+ def self.name_from_card(card)
116
+ card.xpath('.//h2[@class="mod-card-title"]/a/@href').text \
117
+ .split('/').last.then(&Addressable::URI.method(:unencode))
118
+ end
119
+
120
+ # Search mod.
121
+ #
122
+ # @param keyword [String] search keyword
123
+ # @param cookie [String] cookie
124
+ # @param version [String] factorio version, `any` for any version
125
+ # @return [Array<Mod>] all mod searched on the first page with card cache
126
+ def self.search(keyword, cookie = '', version: 'any')
127
+ uri = Addressable::URI.join(
128
+ MOD_URI, "/query/#{Addressable::URI.encode keyword}?version=#{version}"
129
+ )
130
+ Nokogiri::HTML(URI.open(uri, 'Cookie' => cookie)) \
131
+ .css('.mod-card').map do |card|
132
+ Mod.new(name_from_card(card), cookie).tap do |mod|
133
+ mod.instance_eval { @mod.cache[:card] = card.clone }
134
+ end
135
+ end
136
+ end
137
+
138
+ # Get mod if exist.
139
+ #
140
+ # @param name [String] name of the mod
141
+ # @return [Bool] is exist
142
+ def self.exist?(name)
143
+ uri = Addressable::URI.encode("mod/#{name}")
144
+ URI.open(Addressable::URI.join(MOD_URI, uri))
145
+ true
146
+ rescue OpenURI::HTTPError
147
+ false
148
+ end
149
+
110
150
  # Extend relative links to absolute links
111
151
  # @param rel [String] relative link
112
152
  # @return [String] absolute link
113
153
  # @raise [NotLoginError]
114
154
  def self.extend_uri(rel)
115
- MOD_URI + rel.tap { |a| raise NotLoginError if a =~ %r{^/login} }
155
+ raise NotLoginError if rel =~ %r{^/login}
156
+
157
+ Addressable::URI.join(MOD_URI, rel)
116
158
  end
117
159
 
118
160
  # Get href in Nokogiri node
119
161
  # @param item [Nokogiri::HTML]
120
- # @return [String] relative link
162
+ # @return [Addressable::URI] relative link
121
163
  def self.get_href(item)
122
164
  extend_uri(item.xpath('a/@href').text)
123
165
  end
@@ -136,15 +178,16 @@ module Factorio
136
178
  end
137
179
 
138
180
  # Get the GitHub URI.
139
- # @return [String] GitHub URI
181
+ # @return [Addressable::URI] GitHub URI
140
182
  def github
141
- @mod.any.xpath('//a[@class="source-code-link"]/@href').text.presence
183
+ @mod.any.xpath('.//a[@class="source-code-link"]/@href').text.presence \
184
+ &.then(&Addressable::URI.method(:parse))
142
185
  end
143
186
 
144
187
  # Get the git repo URI that can be cloned.
145
- # @return [String] git URI
188
+ # @return [Addressable::URI] git URI
146
189
  def git
147
- github &.+ '.git'
190
+ github&.to_s&.+('.git')&.then(&Addressable::URI.method(:parse))
148
191
  end
149
192
 
150
193
  # Get the license that the Mod use.
@@ -154,28 +197,28 @@ module Factorio
154
197
  end
155
198
 
156
199
  # Get the license URI.
157
- # @return [String] license URI
200
+ # @return [Addressable::URI] license URI
158
201
  def license_uri
159
- data_table('License').xpath('a/@href').to_s
202
+ Addressable::URI.parse(data_table('License').xpath('a/@href').text)
160
203
  end
161
204
  alias license_link license_uri
162
205
 
163
206
  # Get the author of the Mod.
164
207
  # @return [String] author
165
208
  def author
166
- @mod.any.xpath('//div[@class="mod-card-author"]/a').text
209
+ @mod.any.xpath('.//div[@class="mod-card-author"]/a').text
167
210
  end
168
211
 
169
212
  # Whether Mod is deprecated
170
213
  # @return [Bool] is deprecated
171
214
  def deprecated?
172
- @mod.any.xpath('//span[@class="mod-card-title-deprecated"]').any?
215
+ @mod.any.xpath('.//span[@class="mod-card-title-deprecated"]').any?
173
216
  end
174
217
 
175
218
  # Get the totle number of downloads of Mod.
176
219
  # @return [Integer] number of downloads
177
220
  def download_times
178
- xpath = "//span[@class='mod-card-info-tag'][@title='Downloads']/div"
221
+ xpath = ".//span[@class='mod-card-info-tag'][@title='Downloads']/div"
179
222
  @mod.any.xpath(xpath).text.to_i
180
223
  end
181
224
 
@@ -196,7 +239,7 @@ module Factorio
196
239
  end
197
240
 
198
241
  # Get latest download uri by download button in card
199
- # @return [String] download uri
242
+ # @return [Addressable::URI] download uri
200
243
  def latest_download_uri
201
244
  Mod.get_href(@mod.any.css('.mod-download-button'))
202
245
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Factorio
4
4
  class Mod
5
- VERSION = '0.6.0'
5
+ VERSION = '0.7.0'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: factorio-mod
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - 71e6fd52
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-01-16 00:00:00.000000000 Z
11
+ date: 2019-01-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -122,6 +122,20 @@ dependencies:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
124
  version: '5.2'
125
+ - !ruby/object:Gem::Dependency
126
+ name: addressable
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '2.6'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '2.6'
125
139
  - !ruby/object:Gem::Dependency
126
140
  name: nokogiri
127
141
  requirement: !ruby/object:Gem::Requirement