valanga 0.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 +7 -0
- data/.gitignore +9 -0
- data/.rspec +3 -0
- data/.travis.yml +3 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +95 -0
- data/Rakefile +1 -0
- data/img/Valanga.png +0 -0
- data/lib/valanga/client.rb +37 -0
- data/lib/valanga/difficulty/base.rb +57 -0
- data/lib/valanga/difficulty/basic.rb +16 -0
- data/lib/valanga/difficulty/hard.rb +16 -0
- data/lib/valanga/difficulty/medium.rb +16 -0
- data/lib/valanga/difficulty/special.rb +19 -0
- data/lib/valanga/error.rb +7 -0
- data/lib/valanga/music/base.rb +15 -0
- data/lib/valanga/music/collete.rb +61 -0
- data/lib/valanga/music/groovin.rb +52 -0
- data/lib/valanga/music.rb +69 -0
- data/lib/valanga/music_attribute.rb +90 -0
- data/lib/valanga/music_search.rb +95 -0
- data/lib/valanga/version.rb +3 -0
- data/lib/valanga.rb +14 -0
- data/valanga.gemspec +31 -0
- metadata +181 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f95daa720a4018c12de977897f78345a4b51dbed
|
4
|
+
data.tar.gz: 1a12dd7871831461e0c1bbd93f6104eaf1fe315f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6a19f6f9b68dedf66b6ffd5a2debd070ff3f133149a56564d097d3ac167100707fb79fb5c05fbde747afd1122bb9cf427c0ea1ffe08109570f23d0e6702d89af
|
7
|
+
data.tar.gz: 95e7c39fc63612ef391caf2da11212b3a199fbbc3005bbb0d28299fc15db815aa0e1a847db183d906e97bbe1e8a807d134c23cf69f261d73fe04cb8d1849e801
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 mgi166
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
# Valanga
|
2
|
+
|
3
|
+
A Ruby client for [REFLEC BEAT](http://p.eagate.573.jp/game/reflec/groovin/p/index.html)
|
4
|
+
|
5
|
+

|
6
|
+
|
7
|
+
## Dependency
|
8
|
+
|
9
|
+
* [PhantomJS](http://phantomjs.org/)
|
10
|
+
|
11
|
+
## Usage
|
12
|
+
### Prepare
|
13
|
+
Create `Valanga::Client` instance.
|
14
|
+
The arguments of `name_or_email` is `KONAMI ID` or `email` that you registered.
|
15
|
+
|
16
|
+
```ruby
|
17
|
+
client = Valanga::Client.new(name_or_email, password)
|
18
|
+
```
|
19
|
+
|
20
|
+
### Fetch all music names
|
21
|
+
|
22
|
+
```ruby
|
23
|
+
client.list_musics
|
24
|
+
#=> ["Artifacter", "Army of Marionette", "RPG", "アイネクライネ", ....]
|
25
|
+
```
|
26
|
+
|
27
|
+
### Search music
|
28
|
+
Specifies the music name, returns `Valanga::Music` instance.
|
29
|
+
|
30
|
+
```ruby
|
31
|
+
music = client.search('Arousing').hard
|
32
|
+
|
33
|
+
music.name #=> "Arousing"
|
34
|
+
music.artist #=> "DJ TOTTO feat.吉河順央"
|
35
|
+
music.rank #=> "AAA+"
|
36
|
+
music.score #=> 1615
|
37
|
+
music.achievement_rate #=> 98.4
|
38
|
+
music.miss_count #=> 0
|
39
|
+
music.play_count #=> 21
|
40
|
+
music.clear #=> "clear"
|
41
|
+
music.full_combo #=> "all_just_reflec_full_combo"
|
42
|
+
|
43
|
+
music.cleared? #=> true
|
44
|
+
music.played? #=> true
|
45
|
+
music.full_combo? #=> true
|
46
|
+
music.has_special? #=> false
|
47
|
+
```
|
48
|
+
|
49
|
+
#### Difficulty / Version
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
music = client.search('music_name')
|
53
|
+
|
54
|
+
# basic
|
55
|
+
music.groovin.basic # groovin version.
|
56
|
+
music.collete.basic # collete version.
|
57
|
+
music.basic # merged score groovin and collete.
|
58
|
+
|
59
|
+
# medium
|
60
|
+
music.groovin.medium # groovin version.
|
61
|
+
music.collete.medium # collete version.
|
62
|
+
music.medium # merged score groovin and collete.
|
63
|
+
|
64
|
+
# hard
|
65
|
+
music.groovin.hard # groovin version.
|
66
|
+
music.collete.hard # collete version.
|
67
|
+
music.hard # merged score groovin and collete.
|
68
|
+
|
69
|
+
# special
|
70
|
+
music.special # only exists groovin version.
|
71
|
+
```
|
72
|
+
|
73
|
+
## Installation
|
74
|
+
|
75
|
+
Add this line to your application's Gemfile:
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
gem 'valanga'
|
79
|
+
```
|
80
|
+
|
81
|
+
And then execute:
|
82
|
+
|
83
|
+
$ bundle
|
84
|
+
|
85
|
+
Or install it yourself as:
|
86
|
+
|
87
|
+
$ gem install valanga
|
88
|
+
|
89
|
+
## Contributing
|
90
|
+
|
91
|
+
1. Fork it ( https://github.com/mgi166/valanga/fork )
|
92
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
93
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
94
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
95
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/img/Valanga.png
ADDED
Binary file
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'capybara'
|
2
|
+
require 'capybara/poltergeist'
|
3
|
+
|
4
|
+
module Valanga
|
5
|
+
class Client
|
6
|
+
include Valanga::MusicSearch
|
7
|
+
|
8
|
+
LOGIN_PAGE = "https://p.eagate.573.jp/gate/p/login.html"
|
9
|
+
|
10
|
+
attr_reader :session
|
11
|
+
|
12
|
+
def initialize(username, password)
|
13
|
+
Capybara.register_driver :poltergeist do |app|
|
14
|
+
Capybara::Poltergeist::Driver.new(app, js_errors: false)
|
15
|
+
end
|
16
|
+
|
17
|
+
@session = Capybara::Session.new(:poltergeist)
|
18
|
+
|
19
|
+
login!(username, password)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def login!(username, password)
|
25
|
+
@session.visit LOGIN_PAGE
|
26
|
+
|
27
|
+
@session.fill_in 'KID', with: username
|
28
|
+
@session.fill_in 'pass', with: password
|
29
|
+
|
30
|
+
@session.click_on "規約に同意してログイン"
|
31
|
+
|
32
|
+
unless @session.current_path == "/gate/p/mypage/index.html"
|
33
|
+
raise LoginError, session.find(:css, 'div.error_text_box').text
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Valanga
|
2
|
+
module Difficulty
|
3
|
+
class Base
|
4
|
+
def name
|
5
|
+
groovin.name || collete.name
|
6
|
+
end
|
7
|
+
|
8
|
+
def artist
|
9
|
+
groovin.artist || collete.artist
|
10
|
+
end
|
11
|
+
|
12
|
+
def rank
|
13
|
+
groovin.rank || collete.rank
|
14
|
+
end
|
15
|
+
|
16
|
+
def score
|
17
|
+
if groovin.score >= collete.score
|
18
|
+
groovin.score
|
19
|
+
else
|
20
|
+
collete.score
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def achievement_rate
|
25
|
+
if groovin.achievement_rate >= collete.achievement_rate
|
26
|
+
groovin.achievement_rate
|
27
|
+
else
|
28
|
+
collete.achievement_rate
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def miss_count
|
33
|
+
if [groovin.miss_count, collete.miss_count].all?
|
34
|
+
if groovin.miss_count >= collete.miss_count
|
35
|
+
collete.miss_count
|
36
|
+
else
|
37
|
+
groovin.miss_count
|
38
|
+
end
|
39
|
+
else
|
40
|
+
groovin.miss_count || collete.miss_count
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def play_count
|
45
|
+
groovin.play_count + collete.play_count
|
46
|
+
end
|
47
|
+
|
48
|
+
def clear
|
49
|
+
groovin.clear || collete.clear
|
50
|
+
end
|
51
|
+
|
52
|
+
def full_combo
|
53
|
+
groovin.full_combo || collete.full_combo
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Valanga
|
2
|
+
module Difficulty
|
3
|
+
class Medium < Base
|
4
|
+
attr_reader :collete, :groovin
|
5
|
+
|
6
|
+
def initialize(music)
|
7
|
+
@collete = music.collete.medium
|
8
|
+
@groovin = music.groovin.medium
|
9
|
+
end
|
10
|
+
|
11
|
+
def difficulty
|
12
|
+
'MEDIUM'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
module Valanga
|
4
|
+
module Difficulty
|
5
|
+
class Special < Base
|
6
|
+
extend Forwardable
|
7
|
+
|
8
|
+
def initialize(music)
|
9
|
+
@groovin = music.groovin.special
|
10
|
+
end
|
11
|
+
|
12
|
+
def_delegators :@groovin, :rank, :score, :achievement_rate, :miss_count, :play_count, :clear, :full_combo
|
13
|
+
|
14
|
+
def difficulty
|
15
|
+
'SPECIAL'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Valanga
|
2
|
+
class Music
|
3
|
+
class Collete < Base
|
4
|
+
COLLETE_KEY = %w(
|
5
|
+
rank
|
6
|
+
score
|
7
|
+
achievement_rate
|
8
|
+
miss_count
|
9
|
+
play_count
|
10
|
+
)
|
11
|
+
|
12
|
+
def basic
|
13
|
+
if has_special?
|
14
|
+
MusicAttribute.new(create_attr(6)).tap do |attr|
|
15
|
+
attr.name = name
|
16
|
+
attr.artist = artist
|
17
|
+
end
|
18
|
+
else
|
19
|
+
MusicAttribute.new(create_attr(5)).tap do |attr|
|
20
|
+
attr.name = name
|
21
|
+
attr.artist = artist
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def medium
|
27
|
+
if has_special?
|
28
|
+
MusicAttribute.new(create_attr(7)).tap do |attr|
|
29
|
+
attr.name = name
|
30
|
+
attr.artist = artist
|
31
|
+
end
|
32
|
+
else
|
33
|
+
MusicAttribute.new(create_attr(6)).tap do |attr|
|
34
|
+
attr.name = name
|
35
|
+
attr.artist = artist
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def hard
|
41
|
+
if has_special?
|
42
|
+
MusicAttribute.new(create_attr(8)).tap do |attr|
|
43
|
+
attr.name = name
|
44
|
+
attr.artist = artist
|
45
|
+
end
|
46
|
+
else
|
47
|
+
MusicAttribute.new(create_attr(7)).tap do |attr|
|
48
|
+
attr.name = name
|
49
|
+
attr.artist = artist
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def create_attr(index)
|
57
|
+
Hash[COLLETE_KEY.zip(music_info_box[index])]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Valanga
|
2
|
+
class Music
|
3
|
+
class Groovin < Base
|
4
|
+
GROOVIN_KEY = %w(
|
5
|
+
difficulty
|
6
|
+
rank
|
7
|
+
score
|
8
|
+
achievement_rate
|
9
|
+
miss_count
|
10
|
+
play_count
|
11
|
+
clear
|
12
|
+
full_combo
|
13
|
+
)
|
14
|
+
|
15
|
+
def basic
|
16
|
+
Valanga::MusicAttribute.new(create_attr(1)).tap do |attr|
|
17
|
+
attr.name = name
|
18
|
+
attr.artist = artist
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def medium
|
23
|
+
Valanga::MusicAttribute.new(create_attr(2)).tap do |attr|
|
24
|
+
attr.name = name
|
25
|
+
attr.artist = artist
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def hard
|
30
|
+
Valanga::MusicAttribute.new(create_attr(3)).tap do |attr|
|
31
|
+
attr.name = name
|
32
|
+
attr.artist = artist
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def special
|
37
|
+
if has_special?
|
38
|
+
Valanga::MusicAttribute.new(create_attr(4)).tap do |attr|
|
39
|
+
attr.name = name
|
40
|
+
attr.artist = artist
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def create_attr(index)
|
48
|
+
Hash[GROOVIN_KEY.zip(music_info_box[index])]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module Valanga
|
2
|
+
class Music
|
3
|
+
def initialize(document)
|
4
|
+
@document = Nokogiri::HTML.parse(document, nil, 'Shift_JIS')
|
5
|
+
end
|
6
|
+
|
7
|
+
def basic
|
8
|
+
Difficulty::Basic.new(self)
|
9
|
+
end
|
10
|
+
|
11
|
+
def medium
|
12
|
+
Difficulty::Medium.new(self)
|
13
|
+
end
|
14
|
+
|
15
|
+
def hard
|
16
|
+
Difficulty::Hard.new(self)
|
17
|
+
end
|
18
|
+
|
19
|
+
def special
|
20
|
+
Difficulty::Special.new(self)
|
21
|
+
end
|
22
|
+
|
23
|
+
def collete
|
24
|
+
Collete.new(self)
|
25
|
+
end
|
26
|
+
|
27
|
+
def groovin
|
28
|
+
Groovin.new(self)
|
29
|
+
end
|
30
|
+
|
31
|
+
def has_special?
|
32
|
+
music_bk.size == 9
|
33
|
+
end
|
34
|
+
|
35
|
+
def name
|
36
|
+
@name ||= @document.css("div.music_dataname h6").text
|
37
|
+
end
|
38
|
+
|
39
|
+
def artist
|
40
|
+
@artist ||= @document.css("div.music_artist h6").text
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def music_info_box
|
46
|
+
@music_info_box ||= music_bk.map do |dl|
|
47
|
+
dl.children.select(&:element?).map do |ele|
|
48
|
+
if (img = ele.search('img')).empty?
|
49
|
+
ele.text
|
50
|
+
else
|
51
|
+
img.attribute('src').value
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def music_bk
|
58
|
+
return @music_bk if defined? @music_bk
|
59
|
+
|
60
|
+
music_bk = @document.css("div.music_bk dl")
|
61
|
+
|
62
|
+
unless music_bk.size == 8 || music_bk.size == 9
|
63
|
+
raise NoMusicInformationError, "Not found music informations"
|
64
|
+
end
|
65
|
+
|
66
|
+
@music_bk = music_bk
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
3
|
+
module Valanga
|
4
|
+
class MusicAttribute < OpenStruct
|
5
|
+
def initialize(attribute)
|
6
|
+
super
|
7
|
+
attr = attribute.dup.extend(Transformable)
|
8
|
+
|
9
|
+
self.rank = attr.rank
|
10
|
+
self.score = attr.score
|
11
|
+
self.achievement_rate = attr.achievement_rate
|
12
|
+
self.miss_count = attr.miss_count
|
13
|
+
self.play_count = attr.play_count
|
14
|
+
self.clear = attr.clear
|
15
|
+
self.full_combo = attr.full_combo
|
16
|
+
end
|
17
|
+
|
18
|
+
def cleared?
|
19
|
+
achievement_rate && 70.0 <= achievement_rate
|
20
|
+
end
|
21
|
+
|
22
|
+
def played?
|
23
|
+
play_count > 0
|
24
|
+
end
|
25
|
+
|
26
|
+
def full_combo?
|
27
|
+
! full_combo.nil?
|
28
|
+
end
|
29
|
+
|
30
|
+
module Transformable
|
31
|
+
IMAGE_TEXT = {
|
32
|
+
"/game/reflec/groovin/p/images/music/rank/syousai_1.png" => "B",
|
33
|
+
"/game/reflec/groovin/p/images/music/rank/syousai_2.png" => "A",
|
34
|
+
"/game/reflec/groovin/p/images/music/rank/syousai_3.png" => "AA",
|
35
|
+
"/game/reflec/groovin/p/images/music/rank/syousai_4.png" => "AAA",
|
36
|
+
"/game/reflec/groovin/p/images/music/rank/syousai_5.png" => "AAA+",
|
37
|
+
"../images/music/fullcombo_img1.gif" => "full_combo",
|
38
|
+
"../images/music/fullcombo_img2.gif" => "all_just_reflec_full_combo",
|
39
|
+
"../images/music/d_clear_typ_0.gif" => "clear",
|
40
|
+
"../images/music/d_clear_typ_1.gif" => "hard_clear",
|
41
|
+
"../images/music/d_clear_typ_2.gif" => "super_hard_clear",
|
42
|
+
}
|
43
|
+
|
44
|
+
def rank
|
45
|
+
text = IMAGE_TEXT.fetch(self['rank'], self['rank'])
|
46
|
+
text == '-' ? nil : text
|
47
|
+
end
|
48
|
+
|
49
|
+
def score
|
50
|
+
self['score'].to_i
|
51
|
+
end
|
52
|
+
|
53
|
+
def achievement_rate
|
54
|
+
self['achievement_rate'].sub('%', '').to_f
|
55
|
+
end
|
56
|
+
|
57
|
+
def miss_count
|
58
|
+
self['miss_count'] == '-' ? nil : self['miss_count'].to_i
|
59
|
+
end
|
60
|
+
|
61
|
+
def play_count
|
62
|
+
self['play_count'].to_i
|
63
|
+
end
|
64
|
+
|
65
|
+
def clear
|
66
|
+
text = IMAGE_TEXT.fetch(self['clear'], self['clear'])
|
67
|
+
|
68
|
+
if text == '-'
|
69
|
+
nil
|
70
|
+
elsif text
|
71
|
+
text
|
72
|
+
else achievement_rate && achievement_rate >= 70.0
|
73
|
+
'clear'
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def full_combo
|
78
|
+
text = IMAGE_TEXT.fetch(self['full_combo'], self['full_combo'])
|
79
|
+
|
80
|
+
if text == '-'
|
81
|
+
nil
|
82
|
+
elsif text
|
83
|
+
text
|
84
|
+
else play_count > 0 && miss_count && miss_count.zero?
|
85
|
+
'full_combo'
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
module Valanga
|
2
|
+
module MusicSearch
|
3
|
+
MUSIC_INDEX = "http://p.eagate.573.jp/game/reflec/groovin/p/music/index.html"
|
4
|
+
|
5
|
+
def list_musics(page: nil, sorttype: nil, sort: nil)
|
6
|
+
musics = []
|
7
|
+
|
8
|
+
if [page, sorttype, sort].none?
|
9
|
+
page_sessions do |session|
|
10
|
+
html = Nokogiri::HTML.parse(session.html)
|
11
|
+
musics << html.css("#music_table1 td.music_jkimg a").map(&:text).map(&:strip)
|
12
|
+
end
|
13
|
+
else
|
14
|
+
session.visit(music_url(page: page, sorttype: sorttype, sort: sort))
|
15
|
+
html = Nokogiri::HTML.parse(session.html)
|
16
|
+
musics << html.css("#music_table1 td.music_jkimg a").map(&:text).map(&:strip)
|
17
|
+
end
|
18
|
+
|
19
|
+
musics.flatten
|
20
|
+
end
|
21
|
+
|
22
|
+
def [](music_name)
|
23
|
+
page_sessions do |session|
|
24
|
+
begin
|
25
|
+
session.within("#music_table1") do
|
26
|
+
session.click_link(music_name)
|
27
|
+
end
|
28
|
+
|
29
|
+
src = session.find(:css, "iframe")['src']
|
30
|
+
session.visit(info_url(src))
|
31
|
+
|
32
|
+
return Music.new(session.html)
|
33
|
+
rescue Capybara::ElementNotFound
|
34
|
+
# if link is not found, go next page.
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
alias_method :search, :[]
|
39
|
+
alias_method :find_music, :[]
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def page_sessions(&block)
|
44
|
+
page = 1
|
45
|
+
|
46
|
+
while page < 20 do
|
47
|
+
session.visit(music_url(page: page))
|
48
|
+
|
49
|
+
begin
|
50
|
+
session.find("#music_table1")
|
51
|
+
rescue Capybara::ElementNotFound
|
52
|
+
break
|
53
|
+
end
|
54
|
+
|
55
|
+
yield session
|
56
|
+
|
57
|
+
page += 1
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def info_url(src)
|
62
|
+
"http://p.eagate.573.jp/game/reflec/groovin/p/music/#{src}"
|
63
|
+
end
|
64
|
+
|
65
|
+
def music_url(page: nil, sorttype: nil, sort: nil)
|
66
|
+
if page && !(page.is_a? Integer)
|
67
|
+
raise ArgumentError, "page: `#{page}` is expected to be Integer"
|
68
|
+
end
|
69
|
+
|
70
|
+
if sorttype && ! valid_sorttypes.include?(sorttype.to_s)
|
71
|
+
raise ArgumentError, "sorttype: `#{sorttype}' is expected to be #{valid_sorttypes.keys.join(' or ')}"
|
72
|
+
end
|
73
|
+
|
74
|
+
if sort && ! valid_sorts.include?(sort.to_s)
|
75
|
+
raise ArgumentError, "sort: `#{sort}' is expected to be #{valid_sorts.keys.join(' or ')}"
|
76
|
+
end
|
77
|
+
|
78
|
+
URI.parse(MUSIC_INDEX).tap do |u|
|
79
|
+
u.query = {
|
80
|
+
page: page,
|
81
|
+
sorttype: valid_sorttypes[sorttype.to_s],
|
82
|
+
sort: valid_sorts[sort.to_s]
|
83
|
+
}.map { |k, v| "#{k}=#{v}" }.join('&')
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def valid_sorttypes
|
88
|
+
{ "music_name" => 0, "basic" => 1, "medium" => 2, "hard" => 3, "special" => 4 }
|
89
|
+
end
|
90
|
+
|
91
|
+
def valid_sorts
|
92
|
+
{ "asc" => 0, "desc" => 1 }
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
data/lib/valanga.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require "valanga/version"
|
2
|
+
require "valanga/error"
|
3
|
+
require "valanga/music_search"
|
4
|
+
require "valanga/client"
|
5
|
+
require "valanga/music"
|
6
|
+
require "valanga/music/base"
|
7
|
+
require "valanga/music/groovin"
|
8
|
+
require "valanga/music/collete"
|
9
|
+
require "valanga/music_attribute"
|
10
|
+
require "valanga/difficulty/base"
|
11
|
+
require "valanga/difficulty/basic"
|
12
|
+
require "valanga/difficulty/medium"
|
13
|
+
require "valanga/difficulty/hard"
|
14
|
+
require "valanga/difficulty/special"
|
data/valanga.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'valanga/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "valanga"
|
8
|
+
spec.version = Valanga::VERSION
|
9
|
+
spec.authors = ["mgi166"]
|
10
|
+
spec.email = ["skskoari@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = "A Ruby client for REFLEC BEAT."
|
13
|
+
spec.description = "A Ruby client for REFLEC BEAT. Uses PhantomJS to get the scores, achievement rate, etc. Provides Object-oriented API."
|
14
|
+
spec.homepage = "https://github.com/mgi166/valanga"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
spec.bindir = "exe"
|
19
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.9"
|
23
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
24
|
+
spec.add_development_dependency "rspec"
|
25
|
+
spec.add_development_dependency "pry"
|
26
|
+
spec.add_development_dependency "pry-byebug"
|
27
|
+
|
28
|
+
spec.add_dependency "capybara"
|
29
|
+
spec.add_dependency "nokogiri"
|
30
|
+
spec.add_dependency "poltergeist"
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,181 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: valanga
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- mgi166
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-06-04 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.9'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.9'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry-byebug
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: capybara
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: nokogiri
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: poltergeist
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
description: A Ruby client for REFLEC BEAT. Uses PhantomJS to get the scores, achievement
|
126
|
+
rate, etc. Provides Object-oriented API.
|
127
|
+
email:
|
128
|
+
- skskoari@gmail.com
|
129
|
+
executables: []
|
130
|
+
extensions: []
|
131
|
+
extra_rdoc_files: []
|
132
|
+
files:
|
133
|
+
- ".gitignore"
|
134
|
+
- ".rspec"
|
135
|
+
- ".travis.yml"
|
136
|
+
- Gemfile
|
137
|
+
- LICENSE.txt
|
138
|
+
- README.md
|
139
|
+
- Rakefile
|
140
|
+
- img/Valanga.png
|
141
|
+
- lib/valanga.rb
|
142
|
+
- lib/valanga/client.rb
|
143
|
+
- lib/valanga/difficulty/base.rb
|
144
|
+
- lib/valanga/difficulty/basic.rb
|
145
|
+
- lib/valanga/difficulty/hard.rb
|
146
|
+
- lib/valanga/difficulty/medium.rb
|
147
|
+
- lib/valanga/difficulty/special.rb
|
148
|
+
- lib/valanga/error.rb
|
149
|
+
- lib/valanga/music.rb
|
150
|
+
- lib/valanga/music/base.rb
|
151
|
+
- lib/valanga/music/collete.rb
|
152
|
+
- lib/valanga/music/groovin.rb
|
153
|
+
- lib/valanga/music_attribute.rb
|
154
|
+
- lib/valanga/music_search.rb
|
155
|
+
- lib/valanga/version.rb
|
156
|
+
- valanga.gemspec
|
157
|
+
homepage: https://github.com/mgi166/valanga
|
158
|
+
licenses:
|
159
|
+
- MIT
|
160
|
+
metadata: {}
|
161
|
+
post_install_message:
|
162
|
+
rdoc_options: []
|
163
|
+
require_paths:
|
164
|
+
- lib
|
165
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
166
|
+
requirements:
|
167
|
+
- - ">="
|
168
|
+
- !ruby/object:Gem::Version
|
169
|
+
version: '0'
|
170
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
171
|
+
requirements:
|
172
|
+
- - ">="
|
173
|
+
- !ruby/object:Gem::Version
|
174
|
+
version: '0'
|
175
|
+
requirements: []
|
176
|
+
rubyforge_project:
|
177
|
+
rubygems_version: 2.4.5
|
178
|
+
signing_key:
|
179
|
+
specification_version: 4
|
180
|
+
summary: A Ruby client for REFLEC BEAT.
|
181
|
+
test_files: []
|