revolt 0.5.1
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.
- data/README +150 -0
- data/Rakefile +197 -0
- data/bin/rv_find_levels.rb +186 -0
- data/bin/rv_install_level_urls.rb +191 -0
- data/bin/rv_install_levels.rb +76 -0
- data/examples/find_rv_track.rb +17 -0
- data/examples/install_rv_track.rb +28 -0
- data/lib/revolt/args.rb +46 -0
- data/lib/revolt/config.rb +5 -0
- data/lib/revolt/exceptions.rb +34 -0
- data/lib/revolt/fetcher/file_system.rb +31 -0
- data/lib/revolt/fetcher/www.rb +117 -0
- data/lib/revolt/fetcher.rb +30 -0
- data/lib/revolt/info.rb +40 -0
- data/lib/revolt/level.rb +298 -0
- data/lib/revolt/levels.rb +362 -0
- data/lib/revolt/logger.rb +24 -0
- data/lib/revolt/package/archive/analyzer/normalized.rb +50 -0
- data/lib/revolt/package/archive/analyzer/troubled.rb +97 -0
- data/lib/revolt/package/archive/analyzer.rb +34 -0
- data/lib/revolt/package/archive/zip/browser.rb +44 -0
- data/lib/revolt/package/archive.rb +35 -0
- data/lib/revolt/package/exe.rb +10 -0
- data/lib/revolt/package/installer/archive.rb +105 -0
- data/lib/revolt/package/installer/exe.rb +10 -0
- data/lib/revolt/package.rb +64 -0
- data/lib/revolt/util/fs_browser.rb +30 -0
- data/lib/revolt/util.rb +20 -0
- data/lib/revolt.rb +12 -0
- data/test/common.rb +78 -0
- data/test/fixtures/files/nodirs_track.zip +0 -0
- data/test/fixtures/files/readme.txt +1 -0
- data/test/fixtures/files/rickyd_track.zip +0 -0
- data/test/fixtures/files/standard_multi.zip +0 -0
- data/test/fixtures/files/standard_rev_track.zip +0 -0
- data/test/fixtures/files/standard_track.zip +0 -0
- data/test/fixtures/files/zips_inside.zip +0 -0
- data/test/fixtures/rv/gfx/levid.bmp +1 -0
- data/test/fixtures/rv/gfx/levid.bmq +1 -0
- data/test/fixtures/rv/gfx/levidrev.bmp +1 -0
- data/test/fixtures/rv/gfx/levidrev.bmq +1 -0
- data/test/fixtures/rv/gfx/tEsT Level.bmp +1 -0
- data/test/fixtures/rv/levels/levid/levid.inf +1 -0
- data/test/fixtures/rv/levels/levid/levid.w +1 -0
- data/test/fixtures/rv/levels/levid/levida.bmp +1 -0
- data/test/fixtures/rv/levels/levid/readme.txt +1 -0
- data/test/fixtures/rv/levels/levidrev/levidrev.inf +1 -0
- data/test/fixtures/rv/levels/levidrev/levidrev.w +1 -0
- data/test/fixtures/rv/levels/levidrev/levidreva.bmp +1 -0
- data/test/fixtures/rv/levels/levidrev/readme.txt +1 -0
- data/test/fixtures/rv/levels/levidrev/reversed/levidrev.cam +1 -0
- data/test/fixtures/rv/levels/levidrev/reversed/levidrev.fan +1 -0
- data/test/fixtures/rv/levels/levidrev/reversed/levidrev.fin +1 -0
- data/test/fixtures/rv/levels/test lEveL/TEst level.inf +4 -0
- data/test/fixtures/rv/levels/test lEveL/TeST level.w +1 -0
- data/test/fixtures/rv/levels/test lEveL/readme.txt +1 -0
- data/test/fixtures/rv/levels/test lEveL/reversed/TEst level.inf +1 -0
- data/test/fixtures/rv/levels/test lEveL/reversed/TeST level.w +1 -0
- data/test/fixtures/rv/levels/test lEveL/reversed/readme.txt +1 -0
- data/test/fixtures/rv/levels/test lEveL/reversed/test LEVELa.bmp +1 -0
- data/test/fixtures/rv/levels/test lEveL/test LEVELa.bmp +1 -0
- data/test/tc_archive_analyzer.rb +185 -0
- data/test/tc_args.rb +55 -0
- data/test/tc_args_external.rb +55 -0
- data/test/tc_file_system_fetcher.rb +26 -0
- data/test/tc_info.rb +23 -0
- data/test/tc_level.rb +182 -0
- data/test/tc_level_installer.rb +88 -0
- data/test/tc_level_installer_external.rb +124 -0
- data/test/tc_levels.rb +68 -0
- data/test/tc_package_track_installer.rb +174 -0
- data/test/ts_base.rb +14 -0
- data/test/ts_external.rb +7 -0
- metadata +133 -0
data/README
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
= Ruby Re-Volt Tools
|
2
|
+
A library for easy managing of Re-Volt's files in various ways.
|
3
|
+
|
4
|
+
== Requirements
|
5
|
+
gem install rubyzip
|
6
|
+
|
7
|
+
== Install
|
8
|
+
Download the gem:
|
9
|
+
http://users.tkk.fi/~ajalkane/ruby/revolt-0.5.0.gem
|
10
|
+
Install it:
|
11
|
+
gem install revolt-0.5.0.gem
|
12
|
+
|
13
|
+
== Summary
|
14
|
+
For the moment the library mostly has functionality related to
|
15
|
+
track management. This may extend in the future.
|
16
|
+
|
17
|
+
Using the library users can easily create automated
|
18
|
+
tasks. Some of the major features are:
|
19
|
+
- Install track packages from WWW server
|
20
|
+
- Move, copy and delete tracks
|
21
|
+
- Search tracks with various criteria
|
22
|
+
- Create alternative track repositories
|
23
|
+
|
24
|
+
== Documentation
|
25
|
+
Most of the important API documentation is in ReVolt::Levels and ReVolt::Level
|
26
|
+
classes. The rest of the library is usually accessed through
|
27
|
+
them.
|
28
|
+
|
29
|
+
Conventions:
|
30
|
+
- methods that return files return Pathname objects.
|
31
|
+
|
32
|
+
== Examples
|
33
|
+
Here is a listing of some very simple, but illustrative
|
34
|
+
examples of how the library could be used.
|
35
|
+
|
36
|
+
=== Listing all installed track names
|
37
|
+
require 'revolt'
|
38
|
+
|
39
|
+
levels = ReVolt::Levels.installed
|
40
|
+
levels.each_level do |level|
|
41
|
+
puts "Level: " + level.name
|
42
|
+
end
|
43
|
+
|
44
|
+
=== Installing a track from a web-site
|
45
|
+
require 'revolt'
|
46
|
+
|
47
|
+
levels = ReVolt::Levels.installed
|
48
|
+
levels.install('http://url.for.track/trackname.zip')
|
49
|
+
|
50
|
+
=== Moving all non-favorite custom tracks to c:/removed
|
51
|
+
Note that in this example the c:/removed folder has to
|
52
|
+
exist. The favorite array has the level names of all
|
53
|
+
your favorite tracks that you want to keep, other custom
|
54
|
+
tracks are removed. If a filename given as a parameter,
|
55
|
+
reads the leves from there. Since the favorite tracks
|
56
|
+
are as strings and not as symbol, the level id is
|
57
|
+
changed to string before comparison (favorites.member?(level.id.to_s)
|
58
|
+
|
59
|
+
require 'revolt'
|
60
|
+
|
61
|
+
favorites = [
|
62
|
+
'alderon',
|
63
|
+
'sakura',
|
64
|
+
're-ville'
|
65
|
+
]
|
66
|
+
|
67
|
+
if ARGV[0]
|
68
|
+
favorites = open(ARGV[0]).readlines.map {|l| l.chomp}
|
69
|
+
end
|
70
|
+
levels = ReVolt::Levels.installed
|
71
|
+
removed = ReVolt::Levels.at('c:/removed')
|
72
|
+
removed.create_dir_structure
|
73
|
+
levels.each_custom do |level|
|
74
|
+
level.move_to(removed) if !favorites.member?(level.id.to_s)
|
75
|
+
end
|
76
|
+
|
77
|
+
=== Installing everything that looks like URL
|
78
|
+
A bit more complex example. Reads input from the user and
|
79
|
+
tries installing everything that looks like an URL first
|
80
|
+
to a temporary directory. From there copies tracks to
|
81
|
+
installed tracks that do not exist already. This example
|
82
|
+
is useful as it stands for example to install track URLs
|
83
|
+
that are copy pasted to a chat.
|
84
|
+
|
85
|
+
require 'revolt'
|
86
|
+
levels = ReVolt::Levels.installed
|
87
|
+
tmplevels = ReVolt::Levels.at('./tmp')
|
88
|
+
tmplevels.create_dir_structure
|
89
|
+
|
90
|
+
# Read input from console line by line
|
91
|
+
STDIN.each_line do |possible_urls|
|
92
|
+
tmplevels.install_urls(possible_urls)
|
93
|
+
end
|
94
|
+
|
95
|
+
# Copy the levels that have arrived to tmplevels
|
96
|
+
# into installed levels
|
97
|
+
tmplevels.each do |level|
|
98
|
+
# Install only levels that do not exist already
|
99
|
+
if levels.member? level
|
100
|
+
puts "Skipping installing of " + level.to_s + " because it exists"
|
101
|
+
else
|
102
|
+
puts "Installing level " + level.to_s
|
103
|
+
level.copy_to levels
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
== Applications
|
108
|
+
There are a couple of applications distributed with the library
|
109
|
+
that are useful on their own
|
110
|
+
|
111
|
+
=== rv_install_level_urls.rb
|
112
|
+
Reads from the console everything that looks like an URL and tries
|
113
|
+
to install it. Useful for installing easily tracks that are copy
|
114
|
+
pasted to a chat. Use the -h switch to see more usage options.
|
115
|
+
|
116
|
+
=== rv_install_levels.rb
|
117
|
+
Installs track packages that are given as command line parameters.
|
118
|
+
The tracks can be on a web-server or on the file system.
|
119
|
+
For example if you have in my_tracks directory sakura.zip and
|
120
|
+
happy_track.zip that are track packages, you can install them both
|
121
|
+
with:
|
122
|
+
|
123
|
+
rv_install_levels.rb my_tracks/sakura.zip my_tracks/happy_track.zip
|
124
|
+
|
125
|
+
Or if you want to get a track from web-site use:
|
126
|
+
|
127
|
+
rv_install_levels.rb 'http://somesite.com/the_track_url'
|
128
|
+
|
129
|
+
=== rv_find_levels.rb
|
130
|
+
Finds levels by various criteria from installed levels. Basically
|
131
|
+
you can find tracks by any property defined in the tracks .inf file.
|
132
|
+
The easiest way to use it is to just enter the part of the name of
|
133
|
+
the track you want to find. For examples:
|
134
|
+
|
135
|
+
rv_find_levels temple
|
136
|
+
|
137
|
+
That would search for all levels whose name contains 'temple'
|
138
|
+
(case insensitive). Another more complex example is to find
|
139
|
+
all custom tracks that can be raced in reverse mode that
|
140
|
+
have FARCLIP more than 10000:
|
141
|
+
|
142
|
+
rv_find_levels -m 'custom?,reverse?,farclip>10000'
|
143
|
+
|
144
|
+
Use the -h option to get more help. The output format is:
|
145
|
+
|
146
|
+
<level id> (<level name>) [<matched_attribute>=<matched_value>]
|
147
|
+
|
148
|
+
Trying it in practice should clear the syntax if that seems weird.
|
149
|
+
|
150
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,197 @@
|
|
1
|
+
# Rakefile
|
2
|
+
require "rake/testtask"
|
3
|
+
require "rake/clean"
|
4
|
+
require "rake/rdoctask"
|
5
|
+
require "rake/gempackagetask"
|
6
|
+
|
7
|
+
# The name of your project
|
8
|
+
PROJECT = "Re-Volt tools"
|
9
|
+
MAIN_NAMESPACE = "ReVolt"
|
10
|
+
# Your name, used in packaging.
|
11
|
+
MY_NAME = "Arto Jalkanen"
|
12
|
+
# Your email address, used in packaging.
|
13
|
+
MY_EMAIL = "ajalkane@gmail.com"
|
14
|
+
# Short summary of your project, used in packaging.
|
15
|
+
PROJECT_SUMMARY = "Library for managing Re-Volt game, and some Commandline tools"
|
16
|
+
# The project's package name (as opposed to its display name). Used for
|
17
|
+
# RubyForge connectivity and packaging.
|
18
|
+
UNIX_NAME = "revolt"
|
19
|
+
# Your RubyForge user name.
|
20
|
+
RUBYFORGE_USER = ENV["RUBYFORGE_USER"] || "ajalkane"
|
21
|
+
# Directory on RubyForge where your website's files should be uploaded.
|
22
|
+
WEBSITE_DIR = "website"
|
23
|
+
# Output directory for the rdoc html files.
|
24
|
+
# If you don't have a custom homepage, and want to use the RDoc
|
25
|
+
# index.html as homepage, just set it to WEBSITE_DIR.
|
26
|
+
RDOC_HTML_DIR = "#{WEBSITE_DIR}" # /rdoc"
|
27
|
+
|
28
|
+
HAVE_EXT = nil
|
29
|
+
EXT_DIST_FILES = nil
|
30
|
+
|
31
|
+
#################
|
32
|
+
##
|
33
|
+
## Getting Version of library
|
34
|
+
##
|
35
|
+
#################
|
36
|
+
REQUIRE_PATHS = ["lib"]
|
37
|
+
REQUIRE_PATHS << EXT_DIR if HAVE_EXT
|
38
|
+
$LOAD_PATH.concat(REQUIRE_PATHS)
|
39
|
+
# This library file defines the MyProject::VERSION constant.
|
40
|
+
require "#{UNIX_NAME}"
|
41
|
+
PROJECT_VERSION = eval("#{MAIN_NAMESPACE}::VERSION") # e.g., "1.0.2"
|
42
|
+
|
43
|
+
# Options common to RDocTask AND Gem::Specification.
|
44
|
+
# The --main argument specifies which file appears on the index.html page
|
45
|
+
GENERAL_RDOC_OPTS = {
|
46
|
+
"--title" => "#{PROJECT} API documentation",
|
47
|
+
"--main" => "README"
|
48
|
+
}
|
49
|
+
|
50
|
+
# Additional RDoc formatted files, besides the Ruby source files.
|
51
|
+
RDOC_FILES = FileList["README"]
|
52
|
+
# Remove the following line if you don't want to extract RDoc from
|
53
|
+
# the extension C sources.
|
54
|
+
# RDOC_FILES.include(EXT_SOURCES)
|
55
|
+
# Ruby library code.
|
56
|
+
LIB_FILES = FileList["lib/**/*.rb"]
|
57
|
+
# Filelist with Test::Unit test cases.
|
58
|
+
TEST_FILES = FileList["test/ts_base.rb"]
|
59
|
+
# Executable scripts, all non-garbage files under bin/.
|
60
|
+
BIN_FILES = FileList["bin/*"]
|
61
|
+
# This filelist is used to create source packages.
|
62
|
+
# Include all Ruby and RDoc files.
|
63
|
+
DIST_FILES = FileList["**/*.rb", "**/*.rdoc"]
|
64
|
+
DIST_FILES.include("Rakefile")
|
65
|
+
DIST_FILES.include(BIN_FILES)
|
66
|
+
DIST_FILES.include("test/fixtures/**/*")
|
67
|
+
DIST_FILES.include("#{WEBSITE_DIR}/**/*.{html,css}", "man/*.[0-9]")
|
68
|
+
# Don't package files which are autogenerated by RDocTask
|
69
|
+
DIST_FILES.exclude(/^(\.\/)?#{RDOC_HTML_DIR}(\/|$)/)
|
70
|
+
# Include extension source files.
|
71
|
+
DIST_FILES.include(EXT_DIST_FILES) if EXT_DIST_FILES
|
72
|
+
# Don't package temporary files, perhaps created by tests.
|
73
|
+
DIST_FILES.exclude("**/temp_*", "**/*.tmp")
|
74
|
+
# Don't get into recursion...
|
75
|
+
DIST_FILES.exclude(/^(\.\/)?pkg(\/|$)/)
|
76
|
+
|
77
|
+
# Run the tests if rake is invoked without arguments.
|
78
|
+
task "default" => ["test"]
|
79
|
+
|
80
|
+
test_task_name = HAVE_EXT ? "run-tests" : "test"
|
81
|
+
Rake::TestTask.new(test_task_name) do |t|
|
82
|
+
# t.libs << "test"
|
83
|
+
t.test_files = TEST_FILES
|
84
|
+
t.libs = REQUIRE_PATHS
|
85
|
+
end
|
86
|
+
|
87
|
+
# The "rdoc" task generates API documentation.
|
88
|
+
|
89
|
+
Rake::RDocTask.new("rdoc") do |t|
|
90
|
+
t.rdoc_files = RDOC_FILES + LIB_FILES
|
91
|
+
t.title = GENERAL_RDOC_OPTS["--title"]
|
92
|
+
t.main = GENERAL_RDOC_OPTS["--main"]
|
93
|
+
t.rdoc_dir = RDOC_HTML_DIR
|
94
|
+
end
|
95
|
+
|
96
|
+
GEM_SPEC = Gem::Specification.new do |s|
|
97
|
+
s.name = UNIX_NAME
|
98
|
+
s.version = PROJECT_VERSION
|
99
|
+
s.summary = PROJECT_SUMMARY
|
100
|
+
s.rubyforge_project = UNIX_NAME
|
101
|
+
s.homepage = "http://#{UNIX_NAME}.rubyforge.org/"
|
102
|
+
s.author = MY_NAME
|
103
|
+
s.email = MY_EMAIL
|
104
|
+
s.files = DIST_FILES
|
105
|
+
s.test_files = TEST_FILES
|
106
|
+
s.executables = BIN_FILES.map { |fn| File.basename(fn) }
|
107
|
+
s.has_rdoc = true
|
108
|
+
s.extra_rdoc_files = RDOC_FILES
|
109
|
+
s.rdoc_options = GENERAL_RDOC_OPTS.to_a.flatten
|
110
|
+
if HAVE_EXT
|
111
|
+
s.extensions = EXTCONF_FILES
|
112
|
+
s.require_paths << EXT_DIR
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# Now we can generate the package-related tasks.
|
117
|
+
Rake::GemPackageTask.new(GEM_SPEC) do |pkg|
|
118
|
+
pkg.need_zip = true
|
119
|
+
pkg.need_tar = true
|
120
|
+
end
|
121
|
+
|
122
|
+
desc "Upload website to RubyForge. " +
|
123
|
+
"scp will prompt for your RubyForge password."
|
124
|
+
task "publish-website" => ["rdoc"] do
|
125
|
+
rubyforge_path = "/var/www/gforge-projects/#{UNIX_NAME}/"
|
126
|
+
sh "scp -r #{WEBSITE_DIR}/* " +
|
127
|
+
"#{RUBYFORGE_USER}@rubyforge.org:#{rubyforge_path}",
|
128
|
+
:verbose => true
|
129
|
+
end
|
130
|
+
|
131
|
+
task "rubyforge-setup" do
|
132
|
+
unless File.exist?(File.join(ENV["HOME"], ".rubyforge"))
|
133
|
+
puts "rubyforge will ask you to edit its config.yml now."
|
134
|
+
puts "Please set the `username' and `password' entries"
|
135
|
+
puts "to your RubyForge username and RubyForge password!"
|
136
|
+
puts "Press ENTER to continue."
|
137
|
+
$stdin.gets
|
138
|
+
sh "rubyforge setup", :verbose => true
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
task "rubyforge-login" => ["rubyforge-setup"] do
|
143
|
+
# Note: We assume that username and password were set in
|
144
|
+
# rubyforge's config.yml.
|
145
|
+
sh "rubyforge login", :verbose => true
|
146
|
+
end
|
147
|
+
|
148
|
+
task "publish-packages" => ["package", "rubyforge-login"] do
|
149
|
+
# Upload packages under pkg/ to RubyForge
|
150
|
+
# This task makes some assumptions:
|
151
|
+
# * You have already created a package on the "Files" tab on the
|
152
|
+
# RubyForge project page. See pkg_name variable below.
|
153
|
+
# * You made entries under package_ids and group_ids for this
|
154
|
+
# project in rubyforge's config.yml. If not, eventually read
|
155
|
+
# "rubyforge --help" and then run "rubyforge setup".
|
156
|
+
pkg_name = ENV["PKG_NAME"] || UNIX_NAME
|
157
|
+
cmd = "rubyforge add_release #{UNIX_NAME} #{pkg_name} " +
|
158
|
+
"#{PROJECT_VERSION} #{UNIX_NAME}-#{PROJECT_VERSION}"
|
159
|
+
cd "pkg" do
|
160
|
+
sh(cmd + ".gem", :verbose => true)
|
161
|
+
sh(cmd + ".tgz", :verbose => true)
|
162
|
+
sh(cmd + ".zip", :verbose => true)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
# The "prepare-release" task makes sure your tests run, and then generates
|
167
|
+
# files for a new release.
|
168
|
+
desc "Run tests, generate RDoc and create packages."
|
169
|
+
task "prepare-release" => ["clobber"] do
|
170
|
+
puts "Preparing release of #{PROJECT} version #{VERSION}"
|
171
|
+
Rake::Task["test"].invoke
|
172
|
+
Rake::Task["rdoc"].invoke
|
173
|
+
Rake::Task["package"].invoke
|
174
|
+
end
|
175
|
+
|
176
|
+
# The "publish" task is the overarching task for the whole project. It
|
177
|
+
# builds a release and then publishes it to RubyForge.
|
178
|
+
desc "Publish new release of #{PROJECT}"
|
179
|
+
task "publish" => ["prepare-release"] do
|
180
|
+
puts "Uploading documentation..."
|
181
|
+
Rake::Task["publish-website"].invoke
|
182
|
+
puts "Checking for rubyforge command..."
|
183
|
+
`rubyforge --help`
|
184
|
+
if $? == 0
|
185
|
+
puts "Uploading packages..."
|
186
|
+
Rake::Task["publish-packages"].invoke
|
187
|
+
puts "Release done!"
|
188
|
+
else
|
189
|
+
puts "Can't invoke rubyforge command."
|
190
|
+
puts "Either install rubyforge with 'gem install rubyforge'"
|
191
|
+
puts "and retry or upload the package files manually!"
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
|
196
|
+
# To get an overview of this extensive Rakefile, run rake -T:
|
197
|
+
|
@@ -0,0 +1,186 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
#
|
3
|
+
require 'optparse'
|
4
|
+
require 'pp'
|
5
|
+
require 'revolt'
|
6
|
+
require 'set'
|
7
|
+
|
8
|
+
def main
|
9
|
+
cmd = CmdArguments.new(ARGV)
|
10
|
+
ReVolt::Logger.enable if cmd[:debug]
|
11
|
+
levels = ReVolt::Levels.at(cmd[:base])
|
12
|
+
levels.each_level do |level|
|
13
|
+
matches = {}
|
14
|
+
nmatches = 0
|
15
|
+
cmd[:match].each do |op|
|
16
|
+
value = level_cmp_match(op, level)
|
17
|
+
if value != nil
|
18
|
+
# level.inf[key].send(:=~, ''/#{value}/i')) # =~ /#{value}/i
|
19
|
+
matches[op[:name]] = value # level.inf[key]
|
20
|
+
nmatches += 1
|
21
|
+
end
|
22
|
+
end
|
23
|
+
if cmd[:match].size == nmatches
|
24
|
+
keyvaluestr = matches.map{|(k,v)|"#{k}=#{v}"}.join(', ')
|
25
|
+
puts "%s [%s]" % [level.to_s, keyvaluestr]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def level_cmp_match(op, level)
|
31
|
+
return false if !level || !op
|
32
|
+
args1 = [op[:method]]
|
33
|
+
args2 = [op[:cmp], op[:expect]]
|
34
|
+
obj = level
|
35
|
+
ret_value = true
|
36
|
+
if op[:method] == :inf
|
37
|
+
lvlinfval = level.inf[op[:infkey]]
|
38
|
+
return false if !lvlinfval
|
39
|
+
obj = lvlinfval
|
40
|
+
# op[:method] = [op[:infcmp], op[:infval]]
|
41
|
+
ret_value = lvlinfval
|
42
|
+
|
43
|
+
# Check if comparing to a number (if non digits, not a number)
|
44
|
+
#ReVolt::Logger.debug("Second class: #{s.class} value: #{s}")
|
45
|
+
case
|
46
|
+
when op[:infcmp] == :=~:
|
47
|
+
ReVolt::Logger.debug("Its a regexp")
|
48
|
+
# If a regular expression, do the comparison to reg exp match's return value
|
49
|
+
obj = lvlinfval =~ /#{op[:infval]}/i
|
50
|
+
# If the return value is integer, a match was found
|
51
|
+
args1 = [:is_a?, Integer]
|
52
|
+
when !(op[:infval] =~ /[^\d]/)
|
53
|
+
ReVolt::Logger.debug("Its a number")
|
54
|
+
# If comparing to an integer
|
55
|
+
# Return false unless both comparisons to integer
|
56
|
+
return false if lvlinfval =~ /[^\d]/
|
57
|
+
# Do the comparison as integers
|
58
|
+
obj = lvlinfval.to_i
|
59
|
+
args1 = [op[:infcmp], op[:infval].to_i]
|
60
|
+
else
|
61
|
+
# obj = lvlinfval
|
62
|
+
args1 = [op[:infcmp], op[:infval]]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
ReVolt::Logger.debug("Sending operation #{args1} to object #{obj.class} with value #{obj}")
|
67
|
+
ReVolt::Logger.debug("Args2: #{args2}") # Sending operation #{args} to object #{obj.class}")
|
68
|
+
# ret = obj.send(infcmp, infval) # *args)
|
69
|
+
# ret = (obj =~ infval)
|
70
|
+
# ReVolt::Logger.debug("Return value: #{ret}, class: #{ret.class}")
|
71
|
+
if (obj.send(*args1)).send(*args2)
|
72
|
+
ReVolt::Logger.debug("Returning value #{ret_value}")
|
73
|
+
return ret_value
|
74
|
+
end
|
75
|
+
nil
|
76
|
+
end
|
77
|
+
|
78
|
+
class CmdArguments < Hash
|
79
|
+
def initialize(cmd)
|
80
|
+
super()
|
81
|
+
|
82
|
+
inf_matches = []
|
83
|
+
self[:base] = ReVolt::Info::path
|
84
|
+
|
85
|
+
opts = OptionParser.new do |opts|
|
86
|
+
opts.banner = "Usage: #$0 [options] [name_match]\n"
|
87
|
+
|
88
|
+
opts.separator "Examples:"
|
89
|
+
opts.separator " Searches for all tracks which name contains temple:"
|
90
|
+
opts.separator " #$0 temple"
|
91
|
+
opts.separator " All tracks which farclip is more than 31000 and startgrid is 3"
|
92
|
+
opts.separator " #$0 -m 'farclip>31000,startgrid=3'"
|
93
|
+
opts.separator " All custom tracks that can be raced in reversed mode"
|
94
|
+
opts.separator " #$0 -m 'reverse?,custom?'"
|
95
|
+
|
96
|
+
opts.separator ""
|
97
|
+
opts.separator "Operators:"
|
98
|
+
opts.separator " <op> in the options can be replaced with:"
|
99
|
+
opts.separator " = equality"
|
100
|
+
opts.separator " < smaller than"
|
101
|
+
opts.separator " > larger than"
|
102
|
+
opts.separator " =~ regular expression match"
|
103
|
+
opts.separator ""
|
104
|
+
opts.separator " The match can include also the following toggles:"
|
105
|
+
opts.separator " reversed?"
|
106
|
+
opts.separator " stock?"
|
107
|
+
opts.separator " custom?"
|
108
|
+
|
109
|
+
opts.separator ""
|
110
|
+
|
111
|
+
opts.separator "Options:"
|
112
|
+
|
113
|
+
opts.on('-m', '--match [key<op>match[,key2<op>match2[,...]]]', Array,
|
114
|
+
'Matches values in the .inf file with operator') do |value|
|
115
|
+
# 'Match to values in level inf files') do |value|
|
116
|
+
inf_matches = value
|
117
|
+
end
|
118
|
+
opts.on('-d', '--debug',
|
119
|
+
'Outputs debug information') do
|
120
|
+
self[:debug] = true
|
121
|
+
end
|
122
|
+
opts.on('-b', '--base [DIR]',
|
123
|
+
'RV base path. Defaults to RV installation') do |value|
|
124
|
+
self[:base] = value
|
125
|
+
end
|
126
|
+
|
127
|
+
opts.on_tail('-h', '--help',
|
128
|
+
'Display this help and exit') do
|
129
|
+
puts opts
|
130
|
+
exit(1)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
opts.parse!(cmd)
|
135
|
+
|
136
|
+
if cmd.size != 0
|
137
|
+
inf_matches << '%s=~%s' % ['name', cmd[0]]
|
138
|
+
end
|
139
|
+
|
140
|
+
# If input file not specified, at least start date is required
|
141
|
+
if inf_matches.size == 0
|
142
|
+
puts "Error: no matches specified"
|
143
|
+
STDERR.puts opts
|
144
|
+
exit 1
|
145
|
+
end
|
146
|
+
|
147
|
+
self[:match] = []
|
148
|
+
inf_matches.each do |keyvalue|
|
149
|
+
op = {
|
150
|
+
:cmp => :==,
|
151
|
+
:expect => true
|
152
|
+
}
|
153
|
+
case keyvalue
|
154
|
+
when 'reverse?','stock?','custom?'
|
155
|
+
op.merge!({
|
156
|
+
:method => keyvalue.to_sym,
|
157
|
+
:name => keyvalue
|
158
|
+
})
|
159
|
+
else
|
160
|
+
((key,cmp,value)) = keyvalue.scan(/(\w+)(=~|<|>|=)(.+)/)
|
161
|
+
# (key, value) = keyvalue.split('=')
|
162
|
+
if key.nil?
|
163
|
+
STDERR.puts "Error: invalid match '#{keyvalue}', should be key<cmp>value"
|
164
|
+
STDERR.puts " where cmp is comparison type, one of: =,<,> or =~"
|
165
|
+
STDERR.puts " Example: name=~temple"
|
166
|
+
STDERR.puts opts
|
167
|
+
exit 1
|
168
|
+
end
|
169
|
+
|
170
|
+
cmp = '==' if cmp == '='
|
171
|
+
op.merge!({
|
172
|
+
:method => :inf,
|
173
|
+
:infkey => key.downcase.to_sym,
|
174
|
+
:infcmp => cmp.to_sym,
|
175
|
+
:infval => value,
|
176
|
+
:name => key,
|
177
|
+
})
|
178
|
+
|
179
|
+
end
|
180
|
+
self[:match] << op
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
|
186
|
+
main
|