factorio-mod 0.2.2 → 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: eab89026d714d5fe2035918a550368313b0d4f03214e0df9bfa87c9689891b51
4
- data.tar.gz: 8bdf056b0f5b5435ac4d4207c06172e835d4c1767c9464af988dfaec2a6c90bf
3
+ metadata.gz: adcb31d23a6438f33528e0690b06f8134759979b6d4fc7fbce2f9fb25f3cbc13
4
+ data.tar.gz: 07df7cc9b6882fe8248f123b9f88896041099c6cc2d55964473a8d5aebf71b44
5
5
  SHA512:
6
- metadata.gz: 19ba0055879c601bda30be33d49064ee947e84d37da76a75ee480fb285f85f61b5da82b0d1ad2d755633c1e263902af6bba735de443a6ec1e62de9f8a6525936
7
- data.tar.gz: e8fd3a9596712a8d580eeb38046d995bd66db2a400f9b80bd4356e33a2f8182cc6a01a562c969d1fc6033ff6532506a298d5229670497157ab955937525a8712
6
+ metadata.gz: 8039d46e1b26cc7241af59ad447ed76b10e9975e72875da517d1d24342dbebf9c866af9a9aaa287393892b1cc62b3a9b6b97531be2620934d97f7ac611482632
7
+ data.tar.gz: a3860020ad29e8e513c02b30a1e77ce6829ffab221f35a7d142c0ded64bc15001fa252ee4ac9c8a7a0326d1992447ba2c2f67fb703661bf65542e3fea5b4640d
@@ -5,11 +5,11 @@ before_script:
5
5
  - ruby -v
6
6
  - which ruby
7
7
  - gem install bundler --no-ri --no-rdoc
8
- - bundle install --jobs $(nproc) "${FLAGS[@]}"
8
+ - bin/setup
9
9
 
10
10
  rspec:
11
11
  script:
12
- - bundle exec rspec
12
+ - bundle exec rake spec
13
13
 
14
14
  rubocop:
15
15
  script:
@@ -0,0 +1 @@
1
+ --markup markdown
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- factorio-mod (0.2.2)
4
+ factorio-mod (0.3.0)
5
5
  nokogiri (~> 1.8)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -21,13 +21,13 @@ Or install it yourself as:
21
21
 
22
22
  ## Usage
23
23
 
24
- See `spec` directory
24
+ See `spec` directory or https://www.rubydoc.info/gems/factorio-mod
25
25
 
26
26
  ## Development
27
27
 
28
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
28
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
29
29
 
30
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version by `rake bump`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
30
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version by `bundle exec rake bump`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
31
31
 
32
32
  ## Contributing
33
33
 
@@ -1,6 +1,7 @@
1
1
  require 'factorio/mod/version'
2
2
 
3
3
  require 'factorio/mod/mod'
4
+ require 'factorio/mod/download'
4
5
  require 'factorio/mod/exception'
5
6
  require 'factorio/mod/cache'
6
7
 
@@ -1,43 +1,48 @@
1
1
  module Factorio
2
- # cache mod info
2
+ # Cache mod info
3
3
  class Cache
4
- attr_reader :gotten
4
+ attr_reader :cache
5
5
 
6
+ # @param uri [String] Mod URI like `https://mods.factorio.com/mod/LTN-easier`
6
7
  def initialize(uri, cookie = '')
7
8
  @uri = uri
8
9
  @cookie = cookie
9
- @gotten = {}
10
- @gotten.default = false
10
+ @cache = {}
11
11
  end
12
12
 
13
- def mod
14
- get :mod, @uri
13
+ # Get the `Information` page.
14
+ # @return [Nokogiri::HTML]
15
+ def information
16
+ get :information, @uri
15
17
  end
16
18
 
17
- def download
18
- get :download, "#{@uri}/downloads"
19
+ # Get the `Downloads` page.
20
+ # @return [Nokogiri::HTML]
21
+ def downloads
22
+ get :downloads, "#{@uri}/downloads"
19
23
  end
20
24
 
21
- def any
22
- if gotten[:mod]
23
- mod
24
- elsif gotten[:download]
25
- download
25
+ # Get any page that already downloads.
26
+ # Get _better_(default information) mod page if none of the pages exist.
27
+ # @param better [Symbol] get which page if none of the pages exist.
28
+ # @return [Nokogiri::HTML]
29
+ def any(better = :information)
30
+ if @cache.key? :information
31
+ information
32
+ elsif @cache.key? :downloads
33
+ downloads
26
34
  else
27
- send %i[mod download][rand(2)]
35
+ send better
28
36
  end
29
37
  end
30
38
 
31
39
  private
32
40
 
41
+ # Get from cache or download page
33
42
  def get(symbol, uri)
34
43
  symbol = symbol.to_sym
35
- return instance_variable_get "@#{symbol}" if @gotten[symbol]
36
- instance_variable_set "@#{symbol}", Nokogiri::HTML(
37
- URI.open(uri, 'Cookie' => @cookie)
38
- )
39
- @gotten[symbol] = true
40
- instance_variable_get "@#{symbol}"
44
+ return @cache[symbol] if @cache.key? symbol
45
+ @cache[symbol] = Nokogiri::HTML(URI.open(uri, 'Cookie' => @cookie))
41
46
  rescue OpenURI::HTTPError => e
42
47
  raise NoMODError.new @name, e.io
43
48
  end
@@ -0,0 +1,20 @@
1
+ module Factorio
2
+ class Mod
3
+ # store the entry of the _download_
4
+ Download = Struct.new(:version, :game_version, :uri, :date, :times) do
5
+ # `Download` page table header to attribute symbol
6
+ TABLE_HEADER_TO_SYM = {
7
+ 'Version' => :version,
8
+ 'Game Version' => :game_version,
9
+ 'Download' => :uri,
10
+ 'Release Date' => :date,
11
+ 'Downloads' => :times
12
+ }.freeze
13
+
14
+ # set value by String name
15
+ def set(name, value)
16
+ self[TABLE_HEADER_TO_SYM[name]] = value
17
+ end
18
+ end
19
+ end
20
+ end
@@ -1,5 +1,5 @@
1
1
  module Factorio
2
- # The Exception for can't find MOD
2
+ # The Exception that can't find MOD
3
3
  class NoMODError < StandardError
4
4
  attr_reader :io
5
5
  def initialize(msg, io)
@@ -8,14 +8,14 @@ module Factorio
8
8
  end
9
9
  end
10
10
 
11
- # The Exception for not logged in
11
+ # The Exception that not logged in
12
12
  class NotLoginError < StandardError
13
13
  def initialize(msg = 'Not logged in')
14
14
  super
15
15
  end
16
16
  end
17
17
 
18
- # The Exception for can't find download
18
+ # The Exception that can't find download
19
19
  class NoDownloadError < StandardError
20
20
  def initialize(msg)
21
21
  super
@@ -1,22 +1,25 @@
1
1
  module Factorio
2
- # Main class
2
+ # Info interface
3
+ #
4
+ # example:
5
+ #
6
+ # ```
7
+ # mod = Factorio::Mod.new 'LTN-easier'
8
+ # puts "The author of #{mod.title} is #{mod.author}"
9
+ # puts "The #{mod.title} is under #{mod.license}"
10
+ # puts "It latest version can download at #{mod.latest_download[:uri]}"
11
+ # puts "It latest version for factorio 0.16 can download at " \
12
+ # "#{mod.latest_download('0.16')[:uri]}"
13
+ # ```
3
14
  class Mod
15
+ # factorio Mod portal website URI
4
16
  MOD_URI = 'https://mods.factorio.com'.freeze
5
17
 
6
- TABLE_HEAD_TO_GOOD_NAME = {
7
- 'Version' => :version,
8
- 'Game Version' => :game_version,
9
- 'Release Date' => :date,
10
- 'Downloads' => :download_times
11
- }.freeze
12
- private_constant :TABLE_HEAD_TO_GOOD_NAME
13
-
14
- # Get the mod name
15
18
  attr_reader :name
16
19
  alias id name
17
20
  alias string_id name
18
21
 
19
- # @param name [String] name of mod
22
+ # @param name [String] name of the Mod
20
23
  # @param cookie [String] logged in cookie
21
24
  def initialize(name, cookie = '')
22
25
  @name = name
@@ -25,14 +28,15 @@ module Factorio
25
28
 
26
29
  private
27
30
 
31
+ # Get the meta table from Information page.
28
32
  def data_table(key = '')
29
- table = @mod.mod.xpath("//div[@class='mod-page-data-table']")
33
+ table = @mod.information.xpath("//div[@class='mod-page-data-table']")
30
34
  return table if key == ''
31
35
  xpath = "//td[../td[@class='data-name'][.='#{key}:']]"
32
36
  table.xpath xpath
33
37
  end
34
38
 
35
- # @return [String, String] csrf_token and cookie
39
+ # @return [String, String] `csrf_token` and cookie
36
40
  def self.csrf_and_cookie
37
41
  resp = open 'https://mods.factorio.com/login'
38
42
  cookie = resp.meta['set-cookie'].split('; ')[0]
@@ -44,25 +48,31 @@ module Factorio
44
48
  public
45
49
 
46
50
  # rubocop:disable MethodLength
47
- def self.bind_td_to_th(table_head, line)
48
- line.css('td').each_with_index.each_with_object({}) \
51
+
52
+ # Map each value with table header.
53
+ # @param table_header [Array] table header in order
54
+ # @param line [Nokogiri::HTML] `<tr>`
55
+ # @return [Hash] table with the table header as key
56
+ def self.bind_td_to_th(table_header, line)
57
+ line.css('td').each_with_index.each_with_object(Download.new) \
49
58
  do |(item, index), obj|
50
- key = table_head[index]
59
+ key = table_header[index]
51
60
  if key == 'Download'
52
61
  href = item.xpath('a/@href').to_s
53
62
  raise NotLoginError if href =~ %r{^/login}
54
- obj[:uri] = MOD_URI + href
63
+ obj.uri = MOD_URI + href
55
64
  else
56
- obj[TABLE_HEAD_TO_GOOD_NAME[key]] = item.text
65
+ obj.set(key, item.text)
57
66
  end
58
67
  end
59
68
  end
69
+
60
70
  # rubocop:enable MethodLength
61
71
 
62
- # Get logged in cookie
72
+ # Get the logged in cookie.
63
73
  # @param username [String]
64
74
  # @param password [String]
65
- # @return [String] cookie
75
+ # @return [String] The logged in cookie
66
76
  def self.login_cookie(username, password)
67
77
  csrf_token, cookie = csrf_and_cookie
68
78
  data = URI.encode_www_form(
@@ -74,74 +84,74 @@ module Factorio
74
84
  resp.response['set-cookie'].split('; ')[0]
75
85
  end
76
86
 
77
- # Get the title (or display name) of MOD
78
- # @return [String] mod title
87
+ # Get the title (also known as _display name_) of the Mod
88
+ # @return [String] title
79
89
  def title
80
90
  @mod.any.css('.mod-card-title *').text
81
91
  end
82
92
  alias display_name title
83
93
 
84
- # Get the summary of MOD
85
- # @return [String] mod summary
94
+ # Get the summary of the Mod
95
+ # @return [String] summary
86
96
  def summary
87
97
  @mod.any.css('.mod-card-summary').text
88
98
  end
89
99
 
90
- # Get github uri
91
- # @return [String] github uri
100
+ # Get the GitHub URI.
101
+ # @return [String] GitHub URI
92
102
  def github
93
103
  uri = data_table('Source').xpath('a/@href').to_s
94
104
  return if uri.empty?
95
105
  uri
96
106
  end
97
107
 
98
- # Get git repo uri
99
- # @return [String] git uri
108
+ # Get the git repo URI that can be cloned.
109
+ # @return [String] git URI
100
110
  def git
101
111
  return if github.nil?
102
112
  github + '.git'
103
113
  end
104
114
 
105
- # Get license
115
+ # Get the license that the Mod use.
106
116
  # @return [String] license name
107
117
  def license
108
118
  data_table('License').xpath('a').text
109
119
  end
110
120
 
111
- # Get license uri
112
- # @return [String] license uri
121
+ # Get the license URI.
122
+ # @return [String] license URI
113
123
  def license_uri
114
124
  data_table('License').xpath('a/@href').to_s
115
125
  end
116
126
 
117
- # Get author
127
+ # Get the author of the Mod.
118
128
  # @return [String] author
119
129
  def author
120
130
  data_table('Owner').xpath('a').text
121
131
  end
122
132
 
123
- # Get download times
124
- # @return [Integer] download times
133
+ # Get the totle number of downloads of Mod.
134
+ # @return [Integer] number of downloads
125
135
  def download_times
126
136
  xpath = "//span[@class='mod-card-info-tag'][@title='Downloads']/div"
127
137
  @mod.any.xpath(xpath).text.to_i
128
138
  end
129
139
 
130
- # Ge latest download
140
+ # Get the latest _download_ of the Mod.
131
141
  # @param version [String] factorio version
132
- # @return [Hash] with version game_version date download_times uri
142
+ # @return [Download]
133
143
  def latest_download(version = '')
134
144
  return download_list.last if version == ''
135
145
  download_list.each do |download|
136
- return download if download[:game_version] == version.to_s
146
+ return download if download.game_version == version.to_s
137
147
  end
138
148
  raise NoDownloadError, "Can't found #{name} for factorio #{version}"
139
149
  end
140
150
 
141
- # Get all version info
142
- # @return [Array<Hash>] with version game_version date download_times uri
151
+ # Get the _download_ for all of version.
152
+ # @return [Array<Download>]
143
153
  def download_list
144
- table = @mod.download.css 'table.mod-page-downloads-table'
154
+ table = @mod.downloads.css 'table.mod-page-downloads-table'
145
155
  head = table.css('thead tr th').map(&:text)
146
156
  table.css('tbody tr').map do |line|
147
157
  Mod.bind_td_to_th head, line
@@ -1,5 +1,5 @@
1
1
  module Factorio
2
2
  class Mod
3
- VERSION = '0.2.2'.freeze
3
+ VERSION = '0.3.0'.freeze
4
4
  end
5
5
  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.2.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - 71e6fd52
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-09-03 00:00:00.000000000 Z
11
+ date: 2018-09-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -119,6 +119,7 @@ files:
119
119
  - ".gitignore"
120
120
  - ".gitlab-ci.yml"
121
121
  - ".rspec"
122
+ - ".yardopts"
122
123
  - Gemfile
123
124
  - Gemfile.lock
124
125
  - LICENSE
@@ -129,6 +130,7 @@ files:
129
130
  - factorio-mod.gemspec
130
131
  - lib/factorio/mod.rb
131
132
  - lib/factorio/mod/cache.rb
133
+ - lib/factorio/mod/download.rb
132
134
  - lib/factorio/mod/exception.rb
133
135
  - lib/factorio/mod/mod.rb
134
136
  - lib/factorio/mod/version.rb