romloader 1.0.0 → 1.1.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
  SHA1:
3
- metadata.gz: eb0581eebe31d910a5866868c6767f86e59f90c1
4
- data.tar.gz: b2ba39f821db26cbad47104292155e813a772d03
3
+ metadata.gz: 87a10ca23bd4fc1e499ef4240027008cc2a4d911
4
+ data.tar.gz: 953fe06a0b401c28467d65a00acbb7818f84c6ae
5
5
  SHA512:
6
- metadata.gz: c8fef42a55aff86ac56bf4626c8d442d1d22399068b3ea2e156575c9dcca6a6c1d69e3fd686ab0d61f3b28e3de1e94756242c0ef766290ae9088e991153d991b
7
- data.tar.gz: 17d045707749160b27a5c425ed247ef69f75dde87253731bed178d264ff6329f4d21bf61c03e593b55563dd86705a7f6029d29173d9306e338ea872ae587f6ac
6
+ metadata.gz: 0c3b71b8b3319c7d2f5a8ec434b87981d7307a36c4e968188f373b66ca1543b1b8fcb47012a13cb4ed38f3f5ffdfd48d159aab3800ea524490d4ff8b47571c1d
7
+ data.tar.gz: ac72b823b59ca07ac9677116f02264ce8343dc03cefc2aa11765be4e936f73bd2900459d4bf21d27eac81fd97344ce4c2a7a228d5fdc4a87ca758a67dc92da22
data/README.md CHANGED
@@ -27,6 +27,8 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/jinstr
27
27
 
28
28
  ## Version Changes
29
29
 
30
+ v. 1.1: Added basic rom download capability for Windows (requires Powershell v 3.0 or higher)
31
+
30
32
  v. 1.0: Changed the namespacing of classes, added zip/7-zip extraction and rom download directory management. Also, added the ability to open the newly downloaded game from the command line (requires a emulator)
31
33
 
32
34
  v. 0.0: Basic rom listing from Freeroms.com, and rom download feature
data/lib/romloader.rb CHANGED
@@ -5,8 +5,10 @@ end
5
5
  require 'open-uri'
6
6
  require 'nokogiri'
7
7
  require 'cgi'
8
- require 'zip'
9
- require 'seven_zip_ruby'
8
+ unless /cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM
9
+ require 'zip'
10
+ require 'seven_zip_ruby'
11
+ end
10
12
  require 'fileutils'
11
13
  require_relative 'romloader/game_rom.rb'
12
14
  require_relative 'romloader/game_system.rb'
@@ -3,53 +3,57 @@ class RomLoader::ArchiveExtractor
3
3
 
4
4
  #Extracts zip or 7-zip rom files, manages the extracted dirs, then deletes archive files
5
5
  def self.extract(dir,game_obj)
6
- file_or_dir_to_open = ""
7
- /(?<=\().+(?=\))/.match(game_obj.system.name) ? system_dir = /(?<=\().+(?=\))/.match(game_obj.system.name)[0] : system_dir = nil
8
- system_dir ||= game_obj.system.name
9
- system_dir = system_dir.rstrip.gsub(/[[[:space:]]\/]/, "_").downcase
10
- Dir.mkdir(File.join(Dir.home,"videogame_roms",system_dir)) unless Dir.exist?(File.join(Dir.home,"videogame_roms",system_dir))
6
+ file_or_dir_to_open = nil
7
+ /(?<=\().+(?=\))/.match(game_obj.system.name) ? system_name = /(?<=\().+(?=\))/.match(game_obj.system.name)[0] : system_name = nil
8
+ system_name ||= game_obj.system.name
9
+ system_name = system_name.rstrip.gsub(/[[[:space:]]\/]/, "_").downcase
10
+ dir_w_system = File.join(Dir.home,"videogame_roms",system_name)
11
+ dir_game_name = game_obj.filename.split(game_obj.file_ext)[0]
12
+
13
+ Dir.mkdir(dir_w_system) unless Dir.exist?(dir_w_system)
11
14
 
12
15
  if game_obj.system.name != "MAME"
13
16
  puts "Extracting #{game_obj.filename}"
14
17
  if game_obj.file_ext == ".zip"
15
18
  Zip::File.open(dir) do |zip_archive|
16
19
  zip_archive.glob("*htm").each { |entry| zip_archive.remove(entry) }
17
- Dir.mkdir(File.join(Dir.home,"videogame_roms",system_dir,game_obj.filename.split(game_obj.file_ext)[0])) if zip_archive.size > 1 && !Dir.exist?(File.join(Dir.home,"videogame_roms",system_dir,game_obj.filename.split(game_obj.file_ext)[0]))
20
+ Dir.mkdir(File.join(dir_w_system,dir_game_name)) if zip_archive.size > 1 && !Dir.exist?(File.join(dir_w_system,dir_game_name))
18
21
  zip_archive.each_entry do |rom|
19
- if Dir.exist?(File.join(Dir.home,"videogame_roms",system_dir,game_obj.filename.split(game_obj.file_ext)[0]))
20
- rom.extract(File.join(Dir.home,"videogame_roms",system_dir,game_obj.filename.split(game_obj.file_ext)[0],rom.name)) unless File.exist?(File.join(Dir.home,"videogame_roms",system_dir,game_obj.filename.split(game_obj.file_ext)[0],rom.name))
22
+ if Dir.exist?(File.join(dir_w_system,dir_game_name))
23
+ rom.extract(File.join(dir_w_system,dir_game_name,rom.name)) unless File.exist?(File.join(dir_w_system,dir_game_name,rom.name))
21
24
  else
22
- rom.extract(File.join(Dir.home,"videogame_roms",system_dir,rom.name)) unless File.exist?(File.join(Dir.home,"videogame_roms",system_dir,rom.name))
25
+ rom.extract(File.join(dir_w_system,rom.name)) unless File.exist?(File.join(dir_w_system,rom.name))
23
26
  end
24
- zip_archive.size == 1 ? file_or_dir_to_open = File.join(Dir.home,"videogame_roms",system_dir,"\"#{rom.name}\"") : file_or_dir_to_open = File.join(Dir.home,"videogame_roms",system_dir,game_obj.filename.split(game_obj.file_ext)[0])
27
+ zip_archive.size == 1 ? file_or_dir_to_open = File.join(dir_w_system,"\"#{rom.name}\"") : file_or_dir_to_open = File.join(dir_w_system,dir_game_name)
25
28
  end
26
29
  end
27
- else
30
+ elsif game_obj.file_ext == ".7z"
28
31
  File.open(dir, "rb") do |seven_zip_archive|
29
- Dir.mkdir(File.join(Dir.home,"videogame_roms",system_dir,game_obj.filename.split(game_obj.file_ext)[0])) unless Dir.exist?(File.join(Dir.home,"videogame_roms",system_dir,game_obj.filename.split(game_obj.file_ext)[0]))
30
32
  SevenZipRuby::Reader.open(seven_zip_archive) do |szr|
31
- files_already_in_dir = Dir.entries(File.join(Dir.home,"videogame_roms",system_dir,game_obj.filename.split(game_obj.file_ext)[0]))
32
- if files_already_in_dir.size > 0
33
- files_to_be_extracted = szr.entries.select do |entry|
34
- file_match = /(file, |dir, |anti, )[.[^\.]]+\..+(?=>)/.match(entry.inspect)
35
- file_match ? file_name = file_match[0].split(file_match[1])[1] : file_name = nil
36
- !files_already_in_dir.any? { |file| file == file_name || file_name =~ /\.htm/}
37
- end
38
- szr.extract(files_to_be_extracted, File.join(Dir.home,"videogame_roms",system_dir,game_obj.filename.split(game_obj.file_ext)[0]))
33
+ if szr.entries.size > 2
34
+ Dir.mkdir(File.join(dir_w_system,dir_game_name)) unless Dir.exist?(File.join(dir_w_system,dir_game_name))
35
+ szr.extract_if(File.join(dir_w_system,dir_game_name)) { |entry| !/\.htm/.match(entry.inspect) }
36
+ file_or_dir_to_open = File.join(dir_w_system,dir_game_name)
39
37
  else
40
- szr.extract_all(File.join(Dir.home,"videogame_roms",system_dir,game_obj.filename.split(game_obj.file_ext)[0]))
38
+ szr.extract_if(dir_w_system) do |entry|
39
+ game_name = /(?<=file, |dir, |anti, )[.[^\.]]+\..+(?=>)/.match(entry.inspect)[0] unless /\.htm/.match(entry.inspect)
40
+ !/\.htm/.match(entry.inspect)
41
+ end
42
+ file_or_dir_to_open = File.join(dir_w_system,"\"#{game_name}\"")
41
43
  end
42
44
  end
43
- Dir.chdir(File.join(Dir.home,"videogame_roms",system_dir,game_obj.filename.split(game_obj.file_ext)[0])) do
44
- Dir.entries(".").size == 1 ? file_or_dir_to_open = File.join(Dir.pwd,"\"#{Dir.entries(".").first}\"") : file_or_dir_to_open = Dir.pwd
45
- end
46
45
  end
47
46
  end
48
47
  File.delete(dir)
49
48
  file_or_dir_to_open
50
49
  else
51
- FileUtils.move "#{dir}", "#{File.join(Dir.home,"videogame_roms",system_dir)}"
52
- file_or_dir_to_open = File.join(Dir.home,"videogame_roms",system_dir)
50
+ if game_obj.system.name == "MAME"
51
+ puts "NOTE: No archive extraction. MAME roms must remain zipped to play."
52
+ else
53
+ puts "NOTE: No archive extraction. Only Zip and 7-Zip extraction is supported."
54
+ end
55
+ FileUtils.move dir, dir_w_system
56
+ file_or_dir_to_open = dir_w_system
53
57
  end
54
58
  end
55
59
 
@@ -12,7 +12,7 @@ class RomLoader::FreeromsScraper
12
12
  begin
13
13
  system_rom_url = system_info.attribute("href").value
14
14
  rescue NoMethodError
15
- #Do Nothing, catch the error and move on. This is fine, because the hash will not be added to the array being compiled.
15
+
16
16
  else
17
17
  game_system << {name: system_name, rom_index_url: system_rom_url}
18
18
  end
@@ -21,7 +21,8 @@ class RomLoader::FreeromsScraper
21
21
  end
22
22
  end
23
23
 
24
- # To retrieve the names and main rom urls of the individual games currently begin served by freeroms.com. Returns this information in the form of an array of hashes
24
+ # To retrieve the names and main rom urls of the individual games currently begin served by freeroms.com.
25
+ # Returns this information in the form of an array of hashes
25
26
  def self.rom_scrape(url)
26
27
 
27
28
  game_list = Nokogiri::HTML(open(url)).css("tr[class^=\"game\"] > td[align=\"left\"]")
@@ -30,7 +31,7 @@ class RomLoader::FreeromsScraper
30
31
  begin
31
32
  download_link = game_info.css("a").attribute("href").value
32
33
  rescue NoMethodError
33
- #Do Nothing, catch the error and move on. This is fine, because the hash will not be added to the array being compiled.
34
+
34
35
  else
35
36
  game_name = game_info.css("span").text
36
37
  unless game_name == ""
@@ -43,7 +44,8 @@ class RomLoader::FreeromsScraper
43
44
  end
44
45
  end
45
46
 
46
- # To retrieve the detailed information of individual games currently begin served by freeroms.com. Returns this information in the form of a hash
47
+ # To retrieve the detailed information of individual games currently begin served by freeroms.com.
48
+ # Returns this information in the form of a hash
47
49
  def self.rom_details(url)
48
50
 
49
51
  direct_download = Nokogiri::HTML(open(url))
@@ -53,7 +55,7 @@ class RomLoader::FreeromsScraper
53
55
  begin
54
56
  game_url = /http:\/\/.+(\.zip|\.7z)/.match(direct_download.css("td#romss > script").first.children.first.text)
55
57
  rescue NoMethodError
56
- #Do Nothing, catch the error and move on. This is fine, because the hash will be empty, which can be handled by GameRom#set_rom_details
58
+
57
59
  else
58
60
  if game_url
59
61
  game[:download_url] = game_url[0]
@@ -70,7 +72,8 @@ class RomLoader::FreeromsScraper
70
72
  end
71
73
  end
72
74
 
73
- # Purpose: To retrieve the letter indices for the roms of the game systems currently begin served by freeroms.com. Returns this information in the form of a hash
75
+ # To retrieve the letter indices for the roms of the game systems currently begin served by freeroms.com.
76
+ # Returns this information in the form of a hash
74
77
  def self.rom_index_scrape(url)
75
78
 
76
79
  rom_letter_list = Nokogiri::HTML(open(url)).css("tr.letters > td[align=\"center\"] > font > a")
@@ -80,7 +83,7 @@ class RomLoader::FreeromsScraper
80
83
  begin
81
84
  letter_hash[letter] = letter_list.attribute("href").value if letter =~ /\A[A-Z#]\Z/
82
85
  rescue NoMethodError
83
- #Do Nothing, catch the error and move on. This is fine, because the hash pair will not added.
86
+
84
87
  end
85
88
  end
86
89
  end
@@ -1,11 +1,13 @@
1
1
 
2
- # The class whose instances represent an individual game rom (e.g. Chrono Trigger object)
2
+ # The class whose instances represent an individual game rom
3
+ # (e.g. Chrono Trigger object)
3
4
  class RomLoader::GameRom
4
5
 
5
6
  attr_accessor :name, :system
6
7
  attr_reader :rom_detail_url ,:download_url, :size, :file_ext, :filename
7
8
 
8
- # Create individual game rom objects from information scraped from freeroms.com, and sets the required name and rom_detail_url instance variables
9
+ # Create individual game rom objects from information scraped from freeroms.com,
10
+ # then sets the required name and rom_detail_url instance variables
9
11
  def initialize(name:, rom_detail_url:)
10
12
  @name = name
11
13
  @rom_detail_url = rom_detail_url
@@ -1,5 +1,6 @@
1
1
 
2
- # The class whose instances represent an individual game system (e.g. Sega Genesis object)
2
+ # The class whose instances represent an individual game system
3
+ # (e.g. Sega Genesis object)
3
4
  class RomLoader::GameSystem
4
5
 
5
6
  attr_accessor :name, :rom_index_url
@@ -27,22 +28,25 @@ class RomLoader::GameSystem
27
28
  @@all
28
29
  end
29
30
 
30
- # Retrieves an array of all GameRom objects starting which the provided letter index (e.g. [Sonic the Hedgehog, Streets of Rage,...])
31
+ # Retrieves an array of all GameRom objects starting which the provided letter index
32
+ # (e.g. [Sonic the Hedgehog, Streets of Rage,...])
31
33
  def get_roms_by_letter(letter_index)
32
34
  @roms[letter_index]
33
35
  end
34
36
 
35
- # Retrieves an array of the indicies for the roms (i.e. ["A","B","C"...])
37
+ # Retrieves an array of the indicies for the roms
38
+ # (i.e. ["A","B","C"...])
36
39
  def get_rom_indices
37
40
  @rom_indices.keys
38
41
  end
39
42
 
40
- # Retrieves the url for roms of a particular letter index (e.g. "A" => "http://freeroms.com/genesis_games_that_start_with_a.html")
43
+ # Retrieves the url for roms of a particular letter index
44
+ # (e.g. "A" => "http://freeroms.com/genesis_games_that_start_with_a.html")
41
45
  def get_rom_collection_url(letter_index)
42
46
  @rom_indices[letter_index]
43
47
  end
44
48
 
45
- # Add the game collection scraped from http://freeroms.com to the GameSystem object to the roms (Hash)
49
+ # Add the game collection scraped from http://freeroms.com to the GameSystem object to the roms Hash
46
50
  def add_roms_to_collection_by_letter(letter_index, game_obj_array)
47
51
 
48
52
  game_obj_array.each { |game| game.system = self }
@@ -12,7 +12,7 @@ class RomLoader::RomLoaderCli
12
12
  input_stack = []
13
13
  control_flow_level = 1
14
14
 
15
- puts "Thanks for using RomLoader, powered by freeroms.com!\nNOTE: To play these games, please download an emulator for the desired system.\nConnecting to freeroms.com and retrieving the systems index...\n\n"
15
+ puts "Thanks for using RomLoader, powered by freeroms.com!\nNOTE: To play the games, please download an emulator for the desired system.\nConnecting to freeroms.com and retrieving the systems index...\n\n"
16
16
  sleep 3
17
17
  while control_flow_level > 0
18
18
  case control_flow_level
@@ -67,13 +67,15 @@ class RomLoader::RomLoaderCli
67
67
  input = input_prompt("Download? (Y/n) [exit]:", /[yn]/, control_flow_level)
68
68
  if input == 'y' || input == ""
69
69
  file_or_dir_to_open = download_rom(game)
70
- if /\".+\"/.match(file_or_dir_to_open)
71
- game_file = /\".+\"/.match(file_or_dir_to_open)[0]
72
- input = input_prompt("Play #{game_file}? (Y/n) [exit]:", /[yn]/,control_flow_level)
73
- else
74
- input = input_prompt("Open #{file_or_dir_to_open}? (Y/n) [exit]:", /[yn]/,control_flow_level)
75
- end
76
- system("open #{file_or_dir_to_open}") if input == 'y' || input == ""
70
+ if file_or_dir_to_open
71
+ if /\".+\"/.match(file_or_dir_to_open)
72
+ game_file = /\".+\"/.match(file_or_dir_to_open)[0]
73
+ input = input_prompt("Play #{game_file}? (Y/n) [exit]:", /[yn]/,control_flow_level)
74
+ else
75
+ input = input_prompt("Open #{file_or_dir_to_open}? (Y/n) [exit]:", /[yn]/,control_flow_level)
76
+ end
77
+ system("open #{file_or_dir_to_open}") if input == 'y' || input == ""
78
+ end
77
79
  end
78
80
  input_stack.shift
79
81
  input == "exit" ? control_flow_level = 0 : control_flow_level -= 1
@@ -97,7 +99,8 @@ class RomLoader::RomLoaderCli
97
99
  end
98
100
  end
99
101
 
100
- # Lists the game systems scraped from http://freeroms.com and saved in Romloader::GameSystem.all (e.g. 1. Amiga, 2. Atari, etc...)
102
+ # Lists the game systems scraped from http://freeroms.com and saved in Romloader::GameSystem.all
103
+ # (e.g. 1. Amiga, 2. Atari, etc...)
101
104
  def list_systems
102
105
  RomLoader::GameSystem.all.each_with_index { |game_system, index| puts "#{index+1}. #{game_system.name}"}
103
106
  print "\n"
@@ -108,7 +111,8 @@ class RomLoader::RomLoaderCli
108
111
  RomLoader::GameSystem.all[index-1]
109
112
  end
110
113
 
111
- # List game index for the selected system by letter (e.g. A B C D...)
114
+ # List game index for the selected system by letter
115
+ # (e.g. A B C D...)
112
116
  def list_system_index(selected_system)
113
117
  if selected_system.get_rom_indices.empty?
114
118
  selected_system.rom_indices = RomLoader::FreeromsScraper.rom_index_scrape(selected_system.rom_index_url)
@@ -119,14 +123,16 @@ class RomLoader::RomLoaderCli
119
123
  puts "\n\n"
120
124
  end
121
125
 
122
- # Retrieves all the games available for the selected system under the selected index (e.g. NES,"G")
126
+ # Retrieves all the games available for the selected system under the selected index
127
+ # (e.g. NES,"G")
123
128
  def select_game_collection_by_index(system, letter)
124
129
  puts "Loading roms...\n"
125
130
  games_list = system.get_roms_by_letter(letter)
126
131
  games_list ||= system.add_roms_to_collection_by_letter(letter,RomLoader::GameRom.create_collection(RomLoader::FreeromsScraper.rom_scrape(system.get_rom_collection_url(letter))))
127
132
  end
128
133
 
129
- # List all the games available for the selected index (e.g. "S": 1. Super Castlevania, 2. Super Mario World, etc...)
134
+ # List all the games available for the selected index
135
+ # (e.g. "S": 1. Super Castlevania, 2. Super Mario World, etc...)
130
136
  def list_games(games)
131
137
  games.each_with_index {|game,index| puts "#{index+1}. #{game.name}"}
132
138
  print "\n"
@@ -138,7 +144,8 @@ class RomLoader::RomLoaderCli
138
144
  game_collection[index-1]
139
145
  end
140
146
 
141
- # List the details of the selected game (e.g. Chrono Trigger | 5.38 MB | .zip)
147
+ # List the details of the selected game
148
+ # (e.g. Chrono Trigger | SNES | 5.38 MB | .zip)
142
149
  def display_rom_details(game)
143
150
  puts "Rom details:"
144
151
  puts "#{game.name} | System: #{game.system.name} | File size: #{game.size} | File type: #{game.file_ext}"
@@ -167,19 +174,27 @@ class RomLoader::RomLoaderCli
167
174
  input
168
175
  end
169
176
 
177
+ def isWindows?
178
+ /cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM
179
+ end
180
+
170
181
  # Downloads the selected game to the local directory (~/videogame_roms)
171
182
  def download_rom(game)
172
- file_or_dir_to_open = ""
183
+ file_or_dir_to_open = nil
173
184
  puts "Downloading #{game.name} (#{game.size})..."
174
- result = Dir.chdir(File.join(Dir.home,"videogame_roms")) { system("curl -Og# \"#{game.download_url}\"") }
185
+ if isWindows?
186
+ result = Dir.chdir(File.join(Dir.home,"videogame_roms")) { system("powershell -command \"& { Invoke-WebRequest '#{game.download_url}' -OutFile '#{game.filename}' }\"") }
187
+ else
188
+ result = Dir.chdir(File.join(Dir.home,"videogame_roms")) { system("curl -Og# \"#{game.download_url}\"") }
189
+ end
190
+
175
191
  if result == true
176
192
  puts "Finished downloading #{game.filename} to #{File.join(Dir.home,"videogame_roms")}.\n"
177
- file_or_dir_to_open = RomLoader::ArchiveExtractor.extract(File.join(Dir.home,"videogame_roms",game.filename),game)
193
+ file_or_dir_to_open = RomLoader::ArchiveExtractor.extract(File.join(Dir.home,"videogame_roms",game.filename),game) unless isWindows?
178
194
  else
179
195
  puts "An error occured, the rom couldn't be downloaded.\n"
180
196
  end
181
- sleep 3
182
- puts "\n"
197
+ sleep 2
183
198
  file_or_dir_to_open
184
199
  end
185
200
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: romloader
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Efrain Perez Jr
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-10-07 00:00:00.000000000 Z
11
+ date: 2016-10-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -52,20 +52,6 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '1.2'
55
- - !ruby/object:Gem::Dependency
56
- name: fileutils
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: '0.7'
62
- type: :runtime
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: '0.7'
69
55
  - !ruby/object:Gem::Dependency
70
56
  name: bundler
71
57
  requirement: !ruby/object:Gem::Requirement