romloader 0.0.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +5 -0
- data/lib/romloader.rb +17 -3
- data/lib/romloader/archive_extractor.rb +56 -0
- data/lib/romloader/freeroms_scraper.rb +9 -31
- data/lib/romloader/game_rom.rb +8 -33
- data/lib/romloader/game_system.rb +9 -49
- data/lib/romloader/romloader_cli.rb +43 -103
- data/lib/romloader/scraping_error/errors.rb +8 -0
- metadata +46 -3
- data/lib/romloader/scraping_error/no_element_found.rb +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eb0581eebe31d910a5866868c6767f86e59f90c1
|
4
|
+
data.tar.gz: b2ba39f821db26cbad47104292155e813a772d03
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c8fef42a55aff86ac56bf4626c8d442d1d22399068b3ea2e156575c9dcca6a6c1d69e3fd686ab0d61f3b28e3de1e94756242c0ef766290ae9088e991153d991b
|
7
|
+
data.tar.gz: 17d045707749160b27a5c425ed247ef69f75dde87253731bed178d264ff6329f4d21bf61c03e593b55563dd86705a7f6029d29173d9306e338ea872ae587f6ac
|
data/README.md
CHANGED
@@ -25,6 +25,11 @@ This will download any dependencies for development. Rspec is among the dependen
|
|
25
25
|
|
26
26
|
Bug reports and pull requests are welcome on GitHub at https://github.com/jinstrider2000/romloader-cli-gem.
|
27
27
|
|
28
|
+
## Version Changes
|
29
|
+
|
30
|
+
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
|
+
|
32
|
+
v. 0.0: Basic rom listing from Freeroms.com, and rom download feature
|
28
33
|
|
29
34
|
## License
|
30
35
|
|
data/lib/romloader.rb
CHANGED
@@ -1,7 +1,21 @@
|
|
1
|
+
module RomLoader
|
2
|
+
|
3
|
+
end
|
4
|
+
|
5
|
+
require 'open-uri'
|
6
|
+
require 'nokogiri'
|
7
|
+
require 'cgi'
|
8
|
+
require 'zip'
|
9
|
+
require 'seven_zip_ruby'
|
10
|
+
require 'fileutils'
|
11
|
+
require_relative 'romloader/game_rom.rb'
|
12
|
+
require_relative 'romloader/game_system.rb'
|
13
|
+
require_relative 'romloader/archive_extractor.rb'
|
14
|
+
require_relative 'romloader/freeroms_scraper.rb'
|
15
|
+
require_relative 'romloader/scraping_error/errors.rb'
|
1
16
|
require_relative 'romloader/romloader_cli.rb'
|
2
17
|
|
3
18
|
def run
|
4
19
|
Dir.mkdir(File.join(Dir.home,"videogame_roms")) unless Dir.exist?(File.join(Dir.home,"videogame_roms"))
|
5
|
-
|
6
|
-
end
|
7
|
-
|
20
|
+
RomLoader::RomLoaderCli.new.start
|
21
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
|
2
|
+
class RomLoader::ArchiveExtractor
|
3
|
+
|
4
|
+
#Extracts zip or 7-zip rom files, manages the extracted dirs, then deletes archive files
|
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))
|
11
|
+
|
12
|
+
if game_obj.system.name != "MAME"
|
13
|
+
puts "Extracting #{game_obj.filename}"
|
14
|
+
if game_obj.file_ext == ".zip"
|
15
|
+
Zip::File.open(dir) do |zip_archive|
|
16
|
+
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]))
|
18
|
+
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))
|
21
|
+
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))
|
23
|
+
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])
|
25
|
+
end
|
26
|
+
end
|
27
|
+
else
|
28
|
+
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
|
+
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]))
|
39
|
+
else
|
40
|
+
szr.extract_all(File.join(Dir.home,"videogame_roms",system_dir,game_obj.filename.split(game_obj.file_ext)[0]))
|
41
|
+
end
|
42
|
+
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
|
+
end
|
47
|
+
end
|
48
|
+
File.delete(dir)
|
49
|
+
file_or_dir_to_open
|
50
|
+
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)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
@@ -1,20 +1,9 @@
|
|
1
|
-
require 'open-uri'
|
2
|
-
require 'nokogiri'
|
3
|
-
require 'cgi'
|
4
1
|
|
5
2
|
# The class which facilitates scraping freeroms.com. Uses the nokogiri gem to scrape the site
|
6
|
-
class FreeromsScraper
|
7
|
-
|
8
|
-
#
|
9
|
-
# Instance Variables: none
|
10
|
-
|
11
|
-
# Purpose: To retrieve the names and main rom urls of the game systems currently begin served by freeroms.com. Returns this information in the form of an array of hashes
|
3
|
+
class RomLoader::FreeromsScraper
|
4
|
+
|
12
5
|
def self.system_scrape(url)
|
13
|
-
|
14
|
-
# => 1. url (String): Contains the url "http://freeroms.com"
|
15
|
-
#
|
16
|
-
# Return:
|
17
|
-
# => Array<Hash>
|
6
|
+
|
18
7
|
system_list = Nokogiri::HTML(open(url)).css("dt.leftside > a")
|
19
8
|
[].tap do |game_system|
|
20
9
|
system_list.each do |system_info|
|
@@ -32,13 +21,9 @@ class FreeromsScraper
|
|
32
21
|
end
|
33
22
|
end
|
34
23
|
|
35
|
-
#
|
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
|
36
25
|
def self.rom_scrape(url)
|
37
|
-
|
38
|
-
# => 1. url (String): Contains the url for each game
|
39
|
-
#
|
40
|
-
# Return:
|
41
|
-
# => Array<Hash>
|
26
|
+
|
42
27
|
game_list = Nokogiri::HTML(open(url)).css("tr[class^=\"game\"] > td[align=\"left\"]")
|
43
28
|
[].tap do |rom_list|
|
44
29
|
game_list.each do |game_info|
|
@@ -58,13 +43,9 @@ class FreeromsScraper
|
|
58
43
|
end
|
59
44
|
end
|
60
45
|
|
61
|
-
#
|
46
|
+
# To retrieve the detailed information of individual games currently begin served by freeroms.com. Returns this information in the form of a hash
|
62
47
|
def self.rom_details(url)
|
63
|
-
|
64
|
-
# => 1. url (String): Contains the url for each game
|
65
|
-
#
|
66
|
-
# Return:
|
67
|
-
# => Hash
|
48
|
+
|
68
49
|
direct_download = Nokogiri::HTML(open(url))
|
69
50
|
{}.tap do |game|
|
70
51
|
unless direct_download.css("td#romss > script").empty?
|
@@ -77,6 +58,7 @@ class FreeromsScraper
|
|
77
58
|
if game_url
|
78
59
|
game[:download_url] = game_url[0]
|
79
60
|
game[:file_ext] = game_url[1]
|
61
|
+
game[:filename] = /[.[^\/]]+(\.zip|\.7z)\Z/.match(game_url[0])[0]
|
80
62
|
begin
|
81
63
|
game[:size] = direct_download.css("td#rom + td[colspan=\"2\"]").first.children.first.text.strip
|
82
64
|
rescue NoMethodError
|
@@ -90,11 +72,7 @@ class FreeromsScraper
|
|
90
72
|
|
91
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
|
92
74
|
def self.rom_index_scrape(url)
|
93
|
-
|
94
|
-
# => 1. url (String): Contains the url for the letter indices
|
95
|
-
#
|
96
|
-
# Return:
|
97
|
-
# => Hash
|
75
|
+
|
98
76
|
rom_letter_list = Nokogiri::HTML(open(url)).css("tr.letters > td[align=\"center\"] > font > a")
|
99
77
|
{}.tap do |letter_hash|
|
100
78
|
rom_letter_list.each do |letter_list|
|
data/lib/romloader/game_rom.rb
CHANGED
@@ -1,52 +1,27 @@
|
|
1
1
|
|
2
2
|
# The class whose instances represent an individual game rom (e.g. Chrono Trigger object)
|
3
|
-
class GameRom
|
4
|
-
|
5
|
-
#
|
6
|
-
# Instance Variables:
|
7
|
-
# => 1. name (String): Contains the system's name (e.g. "Sega Genesis")
|
8
|
-
# => 2. download_url (String): Contains a string with the url to download the game (e.g. "http://download.freeroms.com/genesis/a_roms/altered_beast.zip")
|
9
|
-
# => 3. rom_detail_url (String): Contains a string with the url to details of the game
|
10
|
-
# => 4. size (String): Contains a string with the size of download, as published on freeroms.com
|
11
|
-
# => 5. file_ext (String): Contains a string with the download file index (e.g. ".zip")
|
12
|
-
# => 6. system (GameSystem): Points to the GameSystem object that contains this GameRom instance
|
3
|
+
class RomLoader::GameRom
|
4
|
+
|
13
5
|
attr_accessor :name, :system
|
14
|
-
attr_reader :rom_detail_url ,:download_url, :size, :file_ext
|
6
|
+
attr_reader :rom_detail_url ,:download_url, :size, :file_ext, :filename
|
15
7
|
|
16
|
-
#
|
8
|
+
# Create individual game rom objects from information scraped from freeroms.com, and sets the required name and rom_detail_url instance variables
|
17
9
|
def initialize(name:, rom_detail_url:)
|
18
|
-
# Arguments:
|
19
|
-
# => 1. name (String): Contains the game's name (e.g. "Super Mario Bros 3")
|
20
|
-
# => 2. rom_detail_url (String): Contains a string with the url to details of the game
|
21
|
-
#
|
22
|
-
# Return:
|
23
|
-
# => GameRom object
|
24
10
|
@name = name
|
25
11
|
@rom_detail_url = rom_detail_url
|
26
12
|
end
|
27
13
|
|
28
|
-
#
|
14
|
+
# Creates an array of GameRom objects from an array
|
29
15
|
def self.create_collection(game_array)
|
30
|
-
# Arguments:
|
31
|
-
# => 1. game_array (Array<Hash>): Contains the game's information
|
32
|
-
#
|
33
|
-
# Return:
|
34
|
-
# => Array<GameRom>
|
35
16
|
game_array.collect {|game_details| self.new(game_details)}
|
36
17
|
end
|
37
18
|
|
38
|
-
#
|
39
|
-
def set_rom_details(download_url: nil, size: nil, file_ext: nil)
|
40
|
-
# Arguments:
|
41
|
-
# => 1. download_url [optional] (String): Contains a string with the url to download the game
|
42
|
-
# => 2. size [optional] (String): Contains a string with the size of download, as published on freeroms.com
|
43
|
-
# => 3. file_ext (String): Contains a string with the download file index (e.g. ".zip")
|
44
|
-
#
|
45
|
-
# Return:
|
46
|
-
# => nil
|
19
|
+
# Sets all additional, optional rom details
|
20
|
+
def set_rom_details(download_url: nil, size: nil, file_ext: nil, filename: nil)
|
47
21
|
@download_url = download_url
|
48
22
|
@size = size
|
49
23
|
@file_ext = file_ext
|
24
|
+
@filename = filename
|
50
25
|
nil
|
51
26
|
end
|
52
27
|
|
@@ -1,28 +1,14 @@
|
|
1
1
|
|
2
2
|
# The class whose instances represent an individual game system (e.g. Sega Genesis object)
|
3
|
-
class GameSystem
|
4
|
-
# Class Variables:
|
5
|
-
# => 1. all (Array<GameSystem>): Contains an array of all GameSystem objects that have been instantiated.
|
6
|
-
#
|
7
|
-
# Instance Variables:
|
8
|
-
# => 1. name (String): Contains the system's name (e.g. "Sega Genesis")
|
9
|
-
# => 2. rom_indices (Hash): Contains key/value pairs of a rom index letter and a url (e.g. {"A" => "http://freeroms.com/genesis_games_that_start_with_a.html"})
|
10
|
-
# => 3. roms (Hash): Contains key/value pairs of a rom index letter and an array of GameRom objects (e.g. {"S" => [Sonic the Hedgehog, Streets of Rage,...], "T" => [...], etc})
|
11
|
-
# => 4. rom_index_url (String): Contains the url that leads to the rom index for the given system on http://freeroms.com
|
3
|
+
class RomLoader::GameSystem
|
12
4
|
|
13
5
|
attr_accessor :name, :rom_index_url
|
14
6
|
attr_writer :rom_indices
|
15
7
|
|
16
8
|
@@all = []
|
17
9
|
|
18
|
-
#
|
10
|
+
# Create individual game system objects from information scraped from http://freeroms.com, sets all instance variables
|
19
11
|
def initialize(name:, rom_index_url:)
|
20
|
-
# Arguments:
|
21
|
-
# => 1. name (String): Contains the system's name (e.g. "Sega Genesis")
|
22
|
-
# => 2. rom_index_url (String): Contains the url that leads to the rom index for the given system on http://freeroms.com
|
23
|
-
#
|
24
|
-
# Return:
|
25
|
-
# => GameSystem object
|
26
12
|
@name = name
|
27
13
|
@rom_index_url = rom_index_url
|
28
14
|
@rom_indices = {}
|
@@ -30,61 +16,35 @@ class GameSystem
|
|
30
16
|
@@all << self
|
31
17
|
end
|
32
18
|
|
33
|
-
#
|
19
|
+
# Creates multiple GameSystem objects from information scraped from http://freeroms.com
|
34
20
|
def self.create_from_collection(system_array)
|
35
|
-
# Arguments:
|
36
|
-
# => 1. system_array (Array<Hash>): Contains an array of key/value pairs of the GameSystem instance variables and values (e.g. [{:name =>"NES"...},{:name => "SNES"..,},etc])
|
37
|
-
#
|
38
|
-
# Return:
|
39
|
-
# => nil
|
40
21
|
system_array.each { |system_details| self.new(system_details)}
|
41
22
|
nil
|
42
23
|
end
|
43
24
|
|
44
|
-
#
|
25
|
+
# Retrieves an array of all GameSystem objects
|
45
26
|
def self.all
|
46
|
-
# Arguments: None
|
47
|
-
#
|
48
|
-
# Return:
|
49
|
-
# => Array<GameSystem>
|
50
27
|
@@all
|
51
28
|
end
|
52
29
|
|
53
|
-
#
|
30
|
+
# Retrieves an array of all GameRom objects starting which the provided letter index (e.g. [Sonic the Hedgehog, Streets of Rage,...])
|
54
31
|
def get_roms_by_letter(letter_index)
|
55
|
-
# Arguments:
|
56
|
-
# => 1. letter_index (String): Letter used as key to retrieve array
|
57
|
-
# Return:
|
58
|
-
# => Array<GameRom>
|
59
32
|
@roms[letter_index]
|
60
33
|
end
|
61
34
|
|
62
|
-
#
|
35
|
+
# Retrieves an array of the indicies for the roms (i.e. ["A","B","C"...])
|
63
36
|
def get_rom_indices
|
64
|
-
# Arguments: None
|
65
|
-
#
|
66
|
-
# Return:
|
67
|
-
# => Array<String>
|
68
37
|
@rom_indices.keys
|
69
38
|
end
|
70
39
|
|
71
|
-
#
|
40
|
+
# Retrieves the url for roms of a particular letter index (e.g. "A" => "http://freeroms.com/genesis_games_that_start_with_a.html")
|
72
41
|
def get_rom_collection_url(letter_index)
|
73
|
-
# Arguments:
|
74
|
-
# => 1. letter_index (String): Letter used as key to retrieve url
|
75
|
-
# Return:
|
76
|
-
# => String
|
77
42
|
@rom_indices[letter_index]
|
78
43
|
end
|
79
44
|
|
80
|
-
#
|
45
|
+
# Add the game collection scraped from http://freeroms.com to the GameSystem object to the roms (Hash)
|
81
46
|
def add_roms_to_collection_by_letter(letter_index, game_obj_array)
|
82
|
-
|
83
|
-
# => 1. letter_index (String): Letter to be used as a key for the roms Hash
|
84
|
-
# => 2. game_obj_array (Array<GameRom>): Contains array of GameRom objects (e.g. [Sonic the Hedgehog, Streets of Rage,...]
|
85
|
-
#
|
86
|
-
# Return:
|
87
|
-
# => Array<GameRom>
|
47
|
+
|
88
48
|
game_obj_array.each { |game| game.system = self }
|
89
49
|
@roms[letter_index] = game_obj_array
|
90
50
|
end
|
@@ -1,40 +1,24 @@
|
|
1
|
-
require_relative 'freeroms_scraper.rb'
|
2
|
-
require_relative 'game_rom.rb'
|
3
|
-
require_relative 'game_system.rb'
|
4
|
-
require_relative 'scraping_error/no_element_found.rb'
|
5
1
|
|
6
2
|
# The CLI class
|
7
|
-
class
|
8
|
-
# Class Variables: none
|
9
|
-
#
|
10
|
-
# Instance Variables: none
|
3
|
+
class RomLoader::RomLoaderCli
|
11
4
|
|
12
|
-
# Purpose: Instantiates a GameSystem collection from information scraped from http://freeroms.com
|
13
5
|
def initialize
|
14
|
-
|
15
|
-
|
16
|
-
# Return:
|
17
|
-
# => RomloaderCli object
|
18
|
-
GameSystem.create_from_collection(FreeromsScraper.system_scrape("http://freeroms.com"))
|
19
|
-
raise ScrapingError::NoElementFound.exception("System index is currently unavailable. Exiting the program.") if GameSystem.all.size == 0
|
6
|
+
RomLoader::GameSystem.create_from_collection(RomLoader::FreeromsScraper.system_scrape("http://freeroms.com"))
|
7
|
+
raise RomLoader::ScrapingError::NoElementFound.exception("System index is currently unavailable. Exiting the program.") if RomLoader::GameSystem.all.size == 0
|
20
8
|
end
|
21
9
|
|
22
|
-
#
|
10
|
+
# Starts the CLI, called in romloader.rb
|
23
11
|
def start
|
24
|
-
# Arguments: None
|
25
|
-
#
|
26
|
-
# Return:
|
27
|
-
# => nil
|
28
12
|
input_stack = []
|
29
13
|
control_flow_level = 1
|
30
14
|
|
31
|
-
puts "Thanks for using RomLoader, powered by freeroms.com!\nConnecting to freeroms.com and retrieving the
|
32
|
-
sleep
|
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"
|
16
|
+
sleep 3
|
33
17
|
while control_flow_level > 0
|
34
18
|
case control_flow_level
|
35
19
|
when 1
|
36
20
|
list_systems
|
37
|
-
input = input_prompt("Select a system (1-#{GameSystem.all.size}) [exit]:",1..GameSystem.all.size)
|
21
|
+
input = input_prompt("Select a system (1-#{RomLoader::GameSystem.all.size}) [exit]:",1..RomLoader::GameSystem.all.size)
|
38
22
|
if input == "exit"
|
39
23
|
control_flow_level = 0
|
40
24
|
else
|
@@ -46,7 +30,7 @@ class RomloaderCli
|
|
46
30
|
list_system_index(system)
|
47
31
|
if system.get_rom_indices.empty?
|
48
32
|
begin
|
49
|
-
raise ScrapingError::NoElementFound.exception("Requested system is currently unavailable. Try another one.")
|
33
|
+
raise RomLoader::ScrapingError::NoElementFound.exception("Requested system is currently unavailable. Try another one.")
|
50
34
|
rescue
|
51
35
|
control_flow_level -= 1
|
52
36
|
input_stack.shift
|
@@ -59,7 +43,7 @@ class RomloaderCli
|
|
59
43
|
game_collection = select_game_collection_by_index(system,input_stack[0].upcase)
|
60
44
|
if game_collection.empty?
|
61
45
|
begin
|
62
|
-
raise ScrapingError::NoElementFound.exception("Requested game index is currently unavailable. Try another one.")
|
46
|
+
raise RomLoader::ScrapingError::NoElementFound.exception("Requested game index is currently unavailable. Try another one.")
|
63
47
|
rescue
|
64
48
|
control_flow_level -= 1
|
65
49
|
input_stack.shift
|
@@ -73,16 +57,23 @@ class RomloaderCli
|
|
73
57
|
game = select_game(game_collection,input_stack[0].to_i)
|
74
58
|
if game.download_url == nil
|
75
59
|
begin
|
76
|
-
raise ScrapingError::NoElementFound.exception("Requested game is currently unavailable. Try another one.")
|
60
|
+
raise RomLoader::ScrapingError::NoElementFound.exception("Requested game is currently unavailable. Try another one.")
|
77
61
|
rescue
|
78
62
|
control_flow_level -= 1
|
79
63
|
input_stack.shift
|
80
64
|
end
|
81
65
|
else
|
82
66
|
display_rom_details(game)
|
83
|
-
input = input_prompt("Download (Y/n) [exit]:", /[yn]/, control_flow_level)
|
67
|
+
input = input_prompt("Download? (Y/n) [exit]:", /[yn]/, control_flow_level)
|
84
68
|
if input == 'y' || input == ""
|
85
|
-
download_rom(game)
|
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 == ""
|
86
77
|
end
|
87
78
|
input_stack.shift
|
88
79
|
input == "exit" ? control_flow_level = 0 : control_flow_level -= 1
|
@@ -93,15 +84,8 @@ class RomloaderCli
|
|
93
84
|
puts "Happy Gaming!"
|
94
85
|
end
|
95
86
|
|
96
|
-
#
|
87
|
+
# Sets control_flow_level in RomLoaderCli#start, manipulates input_stack in RomLoaderCli#start
|
97
88
|
def flow_controller(input,control_flow_level,input_stack)
|
98
|
-
# Arguments:
|
99
|
-
# => 1. input (String): Current user input from the CLI
|
100
|
-
# => 2. control_flow_level (Fixnum): Indicator of current user progress through the CLI
|
101
|
-
# => 3. input_stack (Array<String>): Buffer of previous user input from the CLI
|
102
|
-
#
|
103
|
-
# Return:
|
104
|
-
# => Fixnum
|
105
89
|
if input == "exit"
|
106
90
|
0
|
107
91
|
elsif input == "back"
|
@@ -113,35 +97,21 @@ class RomloaderCli
|
|
113
97
|
end
|
114
98
|
end
|
115
99
|
|
116
|
-
#
|
117
|
-
def list_systems
|
118
|
-
#
|
119
|
-
#
|
120
|
-
# Return:
|
121
|
-
# => nil
|
122
|
-
GameSystem.all.each_with_index { |game_system, index| puts "#{index+1}. #{game_system.name}"}
|
100
|
+
# Lists the game systems scraped from http://freeroms.com and saved in Romloader::GameSystem.all (e.g. 1. Amiga, 2. Atari, etc...)
|
101
|
+
def list_systems
|
102
|
+
RomLoader::GameSystem.all.each_with_index { |game_system, index| puts "#{index+1}. #{game_system.name}"}
|
123
103
|
print "\n"
|
124
104
|
end
|
125
105
|
|
126
|
-
#
|
106
|
+
# Retrieves an individual Romloader::GameSystem object from Romloader::GameSystem.all
|
127
107
|
def select_system(index)
|
128
|
-
|
129
|
-
# => 1. index (Fixnum): Retrieved from user input
|
130
|
-
#
|
131
|
-
# Return:
|
132
|
-
# => GameSystem object
|
133
|
-
GameSystem.all[index-1]
|
108
|
+
RomLoader::GameSystem.all[index-1]
|
134
109
|
end
|
135
110
|
|
136
|
-
#
|
111
|
+
# List game index for the selected system by letter (e.g. A B C D...)
|
137
112
|
def list_system_index(selected_system)
|
138
|
-
# Arguments:
|
139
|
-
# => 1. selected_system (String): Retrieved from user input
|
140
|
-
#
|
141
|
-
# Return:
|
142
|
-
# => nil
|
143
113
|
if selected_system.get_rom_indices.empty?
|
144
|
-
selected_system.rom_indices = FreeromsScraper.rom_index_scrape(selected_system.rom_index_url)
|
114
|
+
selected_system.rom_indices = RomLoader::FreeromsScraper.rom_index_scrape(selected_system.rom_index_url)
|
145
115
|
end
|
146
116
|
|
147
117
|
puts "#{selected_system.name} index:"
|
@@ -149,64 +119,34 @@ class RomloaderCli
|
|
149
119
|
puts "\n\n"
|
150
120
|
end
|
151
121
|
|
152
|
-
#
|
122
|
+
# Retrieves all the games available for the selected system under the selected index (e.g. NES,"G")
|
153
123
|
def select_game_collection_by_index(system, letter)
|
154
|
-
# Arguments:
|
155
|
-
# => 1. system (GameSystem): Selected by user through CLI
|
156
|
-
# => 2. letter (String): Retrieved from user input
|
157
|
-
#
|
158
|
-
# Return:
|
159
|
-
# => Array<GameRom>
|
160
124
|
puts "Loading roms...\n"
|
161
125
|
games_list = system.get_roms_by_letter(letter)
|
162
|
-
games_list ||= system.add_roms_to_collection_by_letter(letter,GameRom.create_collection(FreeromsScraper.rom_scrape(system.get_rom_collection_url(letter))))
|
126
|
+
games_list ||= system.add_roms_to_collection_by_letter(letter,RomLoader::GameRom.create_collection(RomLoader::FreeromsScraper.rom_scrape(system.get_rom_collection_url(letter))))
|
163
127
|
end
|
164
128
|
|
165
|
-
#
|
129
|
+
# List all the games available for the selected index (e.g. "S": 1. Super Castlevania, 2. Super Mario World, etc...)
|
166
130
|
def list_games(games)
|
167
|
-
# Arguments:
|
168
|
-
# => 1. games (Array<GameRom>): Selected by user through CLI
|
169
|
-
#
|
170
|
-
# Return:
|
171
|
-
# => nil
|
172
131
|
games.each_with_index {|game,index| puts "#{index+1}. #{game.name}"}
|
173
132
|
print "\n"
|
174
133
|
end
|
175
134
|
|
176
|
-
#
|
135
|
+
# Selects an individual game from the provided collection via index
|
177
136
|
def select_game(game_collection,index)
|
178
|
-
|
179
|
-
# => 1. game_collection (GameRom): Selected by user through CLI
|
180
|
-
# => 2. index (Fixnum): Retrieved from user input
|
181
|
-
#
|
182
|
-
# Return:
|
183
|
-
# => GameRom object
|
184
|
-
game_collection[index-1].set_rom_details(FreeromsScraper.rom_details(game_collection[index-1].rom_detail_url))
|
137
|
+
game_collection[index-1].set_rom_details(RomLoader::FreeromsScraper.rom_details(game_collection[index-1].rom_detail_url))
|
185
138
|
game_collection[index-1]
|
186
139
|
end
|
187
140
|
|
188
|
-
#
|
141
|
+
# List the details of the selected game (e.g. Chrono Trigger | 5.38 MB | .zip)
|
189
142
|
def display_rom_details(game)
|
190
|
-
# Arguments:
|
191
|
-
# => 1. game (GameRom): Selected by user through CLI
|
192
|
-
#
|
193
|
-
# Return:
|
194
|
-
# => nil
|
195
143
|
puts "Rom details:"
|
196
144
|
puts "#{game.name} | System: #{game.system.name} | File size: #{game.size} | File type: #{game.file_ext}"
|
197
|
-
puts "NOTE: To uncompress 7-Zip (.7z) files, please download a system compatible version at http://www.7-zip.org/download.html" if game.file_ext == ".7z"
|
198
145
|
print "\n"
|
199
146
|
end
|
200
147
|
|
201
|
-
#
|
148
|
+
# Prints a custom message, takes user input, asesses whether the input is valid, and returns the input
|
202
149
|
def input_prompt(message,accepted_input,control_flow_level=nil)
|
203
|
-
# Arguments:
|
204
|
-
# => 1. message (String): A custom message detailing the expected input
|
205
|
-
# => 2. accepted_input (Regexp or Range): Will be checked against the input to verify validity
|
206
|
-
# => 3. control_flow_level [optional] (Fixnum): Used to assess input in context specific situations (e.g. user providing "back" when CLI is on it's first screen)
|
207
|
-
#
|
208
|
-
# Return:
|
209
|
-
# => Fixnum
|
210
150
|
valid = false
|
211
151
|
until valid
|
212
152
|
print message + " "
|
@@ -227,20 +167,20 @@ class RomloaderCli
|
|
227
167
|
input
|
228
168
|
end
|
229
169
|
|
230
|
-
#
|
170
|
+
# Downloads the selected game to the local directory (~/videogame_roms)
|
231
171
|
def download_rom(game)
|
232
|
-
|
233
|
-
# => 1. game (GameRom): Selected by user through CLI
|
234
|
-
#
|
235
|
-
# Return:
|
236
|
-
# => nil
|
172
|
+
file_or_dir_to_open = ""
|
237
173
|
puts "Downloading #{game.name} (#{game.size})..."
|
238
|
-
result = Dir.chdir(File.join(Dir.home,"videogame_roms"))
|
239
|
-
|
174
|
+
result = Dir.chdir(File.join(Dir.home,"videogame_roms")) { system("curl -Og# \"#{game.download_url}\"") }
|
175
|
+
if result == true
|
176
|
+
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)
|
178
|
+
else
|
179
|
+
puts "An error occured, the rom couldn't be downloaded.\n"
|
240
180
|
end
|
241
|
-
result ? puts("Finished downloading to #{File.join(Dir.home,"videogame_roms")}.\n") : puts("An error occured, the rom couldn't be downloaded.\n")
|
242
181
|
sleep 3
|
243
182
|
puts "\n"
|
183
|
+
file_or_dir_to_open
|
244
184
|
end
|
245
185
|
|
246
186
|
end
|
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:
|
4
|
+
version: 1.0.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-
|
11
|
+
date: 2016-10-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -24,6 +24,48 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rubyzip
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.2'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.2'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: seven_zip_ruby
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.2'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
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'
|
27
69
|
- !ruby/object:Gem::Dependency
|
28
70
|
name: bundler
|
29
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -79,11 +121,12 @@ files:
|
|
79
121
|
- README.md
|
80
122
|
- bin/romloader
|
81
123
|
- lib/romloader.rb
|
124
|
+
- lib/romloader/archive_extractor.rb
|
82
125
|
- lib/romloader/freeroms_scraper.rb
|
83
126
|
- lib/romloader/game_rom.rb
|
84
127
|
- lib/romloader/game_system.rb
|
85
128
|
- lib/romloader/romloader_cli.rb
|
86
|
-
- lib/romloader/scraping_error/
|
129
|
+
- lib/romloader/scraping_error/errors.rb
|
87
130
|
homepage: https://github.com/jinstrider2000/romloader-cli-gem
|
88
131
|
licenses:
|
89
132
|
- MIT
|