holysugar-www-enbujyo 0.1.7 → 0.1.9

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.7
1
+ 0.1.9
@@ -1,10 +1,14 @@
1
1
  require 'time'
2
+ require 'json'
3
+
4
+ require 'www/enbujyo/helper'
2
5
 
3
6
  module WWW
4
7
  class Enbujyo
5
8
  class Game
6
9
  attr_reader :player0, :deck0, :location0, :player1, :deck1, :location1,
7
10
  :date, :movie_date
11
+ attr_reader :id
8
12
 
9
13
  def initialize(p0, p0deck, p0loc, p1, p1deck, p1loc, options = {})
10
14
  @player0 = p0
@@ -22,6 +26,8 @@ module WWW
22
26
  when 'win'
23
27
  @winner = 0
24
28
  end
29
+
30
+ @id = options[:id]
25
31
  end
26
32
 
27
33
  def to_s
@@ -29,12 +35,72 @@ module WWW
29
35
  #{player0} #{"「#{player0.team}」" if player0.team}
30
36
  #{location0}
31
37
  #{deck0}
32
- ----
38
+ ---
33
39
  #{player1} #{"「#{player1.team}」" if player1.team}
34
40
  #{location1}
35
41
  #{deck1}
36
42
  EOD
37
43
  end
44
+
45
+ def self.parse_replay(agent, id)
46
+ url = "http://enbujyo.3594t.com/members/replay.cgi?u=#{id}"
47
+ gamedata = agent.get(url).body
48
+ parse(gamedata, id)
49
+ end
50
+
51
+ def self.parse(gamedata, id = nil)
52
+ if gamedata.is_a? String
53
+ json = Utils.hack_json(gamedata)
54
+ gamedata = JSON.parse(json)
55
+ end
56
+
57
+ rep = gamedata['replay'][0]
58
+
59
+ rep[:id] = id if id
60
+
61
+ p0, p0deck, p0loc = _parse_player_data('p0', rep)
62
+ p1, p1deck, p1loc = _parse_player_data('p1', rep)
63
+
64
+ game = new(p0, p0deck, p0loc, p1, p1deck, p1loc, rep)
65
+ game
66
+ end
67
+
68
+ def self._parse_player_data(prefix, rep)
69
+ deck = Deck.new
70
+ rep.keys.grep(/#{prefix}card_params_\d/).sort.each{|k|
71
+ deck.cards.push WWW::Enbujyo::Card.parse_from_jsonstr(rep[k])
72
+ }
73
+ %w|0 1|.each do |num|
74
+ next unless rep[prefix+'staff_image_'+num]
75
+
76
+ deck.gcards.push(WWW::Enbujyo::Gunshi.new(
77
+ :image => rep[prefix+'staff_image_'+num],
78
+ :level => rep[prefix+'staff_level_'+num],
79
+ :longname => rep[prefix+'staff_name_'+num],
80
+ :team => rep[prefix+'staff_seiryoku_name_'+num],
81
+ :attribute => rep[prefix+'staff_zokusei_name'],
82
+ :strategy => rep[prefix+'strategy_name'],
83
+ :ex => rep[prefix+'skill_ex_name']
84
+ ))
85
+ end
86
+ player = WWW::Enbujyo::Player.new(
87
+ :name => rep[prefix+'name'],
88
+ :name_image_url => rep[prefix+'image'],
89
+ :team => rep[prefix+'team_name'],
90
+ :title => rep[prefix+'grade_name'],
91
+ :brave => rep[prefix+'brave'],
92
+ :brave_desc => rep[prefix+'brave_desc'],
93
+ :rank => rep[prefix+'rank'],
94
+ :wins => rep[prefix+'win'],
95
+ :loses => rep[prefix+'lose'],
96
+ :rate => rep[prefix+'win_rate']
97
+ )
98
+ location = WWW::Enbujyo::Location.new(
99
+ :pref => rep[prefix+'pref_name'],
100
+ :office => rep[prefix+'office']
101
+ )
102
+ return [player, deck, location]
103
+ end
38
104
  end
39
105
  end
40
106
  end
@@ -0,0 +1,89 @@
1
+ module WWW
2
+ class Enbujyo
3
+ module ExtendedAgent
4
+ def auth_get(url)
5
+ baseurl = URI.parse('http://enbujyo.3594t.com/')
6
+ url = (baseurl + url).to_s
7
+ ret = get(url)
8
+ if /error/i =~ page.uri.to_s or /エラー/ =~ page.title
9
+ if self.autologin?
10
+ login
11
+ ret = get(url)
12
+ if /error/i =~ page.uri.to_s or /エラー/ =~ page.title
13
+ raise LoginError
14
+ end
15
+ else
16
+ raise LoginError
17
+ end
18
+ end
19
+ ret
20
+ end
21
+ def autologin=(b)
22
+ @autologin = b
23
+ end
24
+ def autologin?
25
+ @autologin
26
+ end
27
+ end
28
+
29
+ module Utils
30
+ module_function
31
+ def random_string(length = 10, strings = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789')
32
+ Array.new(length).map{ strings[rand(strings.size),1] }.join
33
+ end
34
+
35
+ def download_movie(agent, url, options = {})
36
+ puts "Downloading #{url} ..."
37
+ tmpname = "_enbujyo_download.#{random_string}.wmv"
38
+ open(tmpname, 'w'){|tmp|
39
+ tmp.print agent.get_file(url)
40
+ }
41
+ if options[:filename]
42
+ filename = options[:filename]
43
+ elsif agent.page.response['content-disposition']
44
+ /filename="(.*?)"/ =~ agent.page.response['content-disposition']
45
+ if $1
46
+ filename = windows? ? $1 : NKF.nkf('-Sw', $1) # cp932 -> utf-8
47
+ end
48
+ end
49
+ if filename
50
+ FileUtils.mv(tmpname, filename)
51
+ else
52
+ filename = tmpname
53
+ end
54
+ puts "Downloading #{filename} has finished."
55
+ filename
56
+ end
57
+
58
+ def windows?
59
+ RUBY_PLATFORM.downcase =~ /mswin(?!ce)|mingw|cygwin|bccwin/
60
+ end
61
+
62
+ def hack_json(jsonstr)
63
+ jsonstr.sub(/^\w+=/,'').gsub(/\},.*\]/m, '}]')
64
+ end
65
+
66
+ CH_NUMBER_TABLE = {
67
+ '〇' => 0,
68
+ '一' => 1,
69
+ '二' => 2,
70
+ '三' => 3,
71
+ '四' => 4,
72
+ '五' => 5,
73
+ '六' => 6,
74
+ '七' => 7,
75
+ '八' => 8,
76
+ '九' => 9,
77
+ '十' => 10,
78
+ }
79
+
80
+ def ch_to_i(chinesenumber)
81
+ CH_NUMBER_TABLE[chinesenumber]
82
+ end
83
+
84
+ end
85
+ end
86
+ end
87
+
88
+
89
+
@@ -0,0 +1,107 @@
1
+ # -*- mode:ruby; coding:utf-8 -*-
2
+ require 'www/enbujyo/helper'
3
+
4
+ module WWW
5
+ class Enbujyo
6
+ class Movie
7
+ include WWW::Enbujyo::Utils
8
+ STATES = [:none, :accepted, :encoding, :completed, :downloaded, :unavailable]
9
+ RESULT = [:win, :draw, :lose]
10
+
11
+ # needed
12
+ attr_reader :title, :date, :result, :status
13
+
14
+ # maybe nil
15
+ attr_reader :encoded_at, :requested_at, :bought_at
16
+ attr_reader :download_limit, :download_left
17
+ attr_reader :thumbnail
18
+ attr_reader :url, :delete_url
19
+ attr_reader :id
20
+ attr_reader :game
21
+
22
+ def initialize(info, game, max_download = 5)
23
+ @game = game
24
+
25
+ @title = info[:title] or warn 'Movie: title not found'
26
+ @date = info[:date] or warn 'Movie: date not found'
27
+ @result = info[:result]
28
+ @result = case info[:result]
29
+ when /勝利/ : :win
30
+ when /敗北/ : :lose
31
+ when /分/ : :draw
32
+ else
33
+ warn 'Movie: result not found'
34
+ end
35
+
36
+ @status = case info[:encode_status]
37
+ when /受付中/ : :accepted
38
+ when /エンコード中/ : :encoding
39
+ else
40
+ if info[:download_left].nil?
41
+ :completed
42
+ elsif info[:download_left] > 0
43
+ :downloaded
44
+ else
45
+ :unavailable
46
+ end
47
+ end
48
+
49
+ @encoded_at = info[:encoded_at]
50
+ @requested_at = info[:requested_at]
51
+ @bought_at = info[:bought_at]
52
+ @download_limit = info[:download_limit]
53
+ @download_left = info[:download_left]
54
+ @thumbnails = info[:thumbnails]
55
+
56
+ @url = info[:url] || info[:purchase_url]
57
+ @id = @url.scan(/u=(.*)/).to_s if @url
58
+ @delete_url = info[:delete_url]
59
+ end
60
+
61
+ def download(agent)
62
+ unless @url
63
+ warn "Can't download this movie yet."
64
+ return false
65
+ end
66
+ case @status
67
+ when :completed
68
+ download_completed(agent, @url)
69
+ when :downloaded
70
+ download_downloaded(agent, @url)
71
+ else
72
+ warn "Can't download this movie."
73
+ return false
74
+ end
75
+ end
76
+
77
+ def downloadable?
78
+ [:downloaded, :completed].include? @status
79
+ end
80
+
81
+ private
82
+ def download_completed(agent, url)
83
+ page = agent.auth_get url
84
+ # XXX: 動画券がないときの処理.
85
+ link = page.links.find{|l| /download-ok\.html/ =~ l.href }
86
+ if link
87
+ download_downloaded(agent, page.uri + link.href)
88
+ else
89
+ warn "Download link is not found in #{page.uri}"
90
+ false
91
+ end
92
+ end
93
+
94
+ def download_downloaded(agent, url)
95
+ page = agent.auth_get url
96
+ link = page.links.find{|l| /download.cgi/ =~ l.href }
97
+ if link
98
+ download_movie(agent, page.uri + link.href)
99
+ else
100
+ warn "Download link is not found in #{page.uri}"
101
+ false
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
107
+
@@ -0,0 +1,68 @@
1
+ require 'www/enbujyo/game'
2
+ require 'www/enbujyo/movie'
3
+ require 'activesupport'
4
+
5
+ module WWW
6
+ class Enbujyo
7
+ class MyMovie
8
+ def initialize(agent)
9
+ @agent = agent
10
+ end
11
+
12
+ def parse
13
+ page = @agent.auth_get '/members/movie/list.html'
14
+ slots_status = page.search('div[@class="st_block_info2_body"] a')
15
+
16
+ movies_info_html = page.search('div.st_movie_info')
17
+ movies_info = movies_info_html.collect do |div|
18
+ info = {}
19
+ info[:title] = div.search('div.st_movie_info_desc_battle_vs').text
20
+ date = div.search('div.st_movie_info_desc_battle_date span')
21
+ info[:date] = Time.parse(date[0].text)
22
+ info[:result] = date[1].text
23
+ info[:movie] = div.search('div.st_movie_info_desc_movie').text
24
+
25
+ # if completed...
26
+
27
+ div.search('div.st_movie_info_datetime_date').each do |d|
28
+ case d.text
29
+ when /完成日時: (20.*?)/
30
+ info[:encoded_at] = Time.parse($1)
31
+ when /完成日時: \[(.*?)\]/
32
+ info[:encode_status] = $1
33
+ when /発注日時: (20.*?)/
34
+ info[:requested_at] = Time.parse($1)
35
+ when /購入日時: (20.*?)/
36
+ info[:bought_at] = Time.parse($1)
37
+ when /ダウンロード期限: (20.*?)/
38
+ info[:download_limit] = Time.parse($1)
39
+ when /残りダウンロード回数: (\d+)回/
40
+ info[:download_left] = $1.to_i
41
+ end
42
+ end
43
+
44
+ id = div.search('*/@u')[0].to_s
45
+
46
+ if thumbnail = div.search('div.st_movie_info_thumbnail_mini_all')
47
+ info[:thumbnails] = thumbnail.search('a/@href').collect(&:to_s)
48
+ end
49
+ if download = div.search('span.st_reserve_menu_download_l a/@href')[0]
50
+ info[:url] = (page.uri + download.to_s).to_s unless download.to_s.blank?
51
+ end
52
+ if purchase_url = div.search('span.st_reserve_menu_purchase_l a/@href')[0]
53
+ info[:purchase_url] = (page.uri + purchase_url.to_s).to_s
54
+ end
55
+ if delete_url = div.search('span.st_reserve_menu_delete_l a/@href')[0]
56
+ info[:delete_url] = page.uri + delete_url.to_s
57
+ end
58
+
59
+ game = Game.parse_replay(@agent, id)
60
+ Movie.new(info, game)
61
+ end
62
+ movies_info
63
+ end
64
+
65
+ end
66
+ end
67
+ end
68
+
@@ -1,4 +1,3 @@
1
- require 'www/enbujyo/util'
2
1
 
3
2
  module WWW
4
3
  class Enbujyo
data/lib/www/enbujyo.rb CHANGED
@@ -7,17 +7,22 @@ require 'tempfile'
7
7
  require 'fileutils'
8
8
  require 'nkf'
9
9
  require 'json'
10
+ require 'uri'
10
11
 
12
+ require 'www/enbujyo/helper'
11
13
  require 'www/enbujyo/player'
12
14
  require 'www/enbujyo/deck'
13
15
  require 'www/enbujyo/location'
14
16
  require 'www/enbujyo/game'
17
+ require 'www/enbujyo/my_movie'
15
18
 
16
19
  #
17
20
  # SEGA の三国志大戦公式サイトへアクセスするライブラリ.
18
21
  #
19
22
  module WWW
20
23
  class Enbujyo
24
+ include Utils
25
+
21
26
  attr_accessor :mail, :password
22
27
  attr_reader :agent
23
28
 
@@ -31,6 +36,8 @@ module WWW
31
36
  unless @agent
32
37
  @agent = WWW::Mechanize.new
33
38
  @agent.user_agent_alias = 'Windows Mozilla'
39
+ @agent.extend ExtendedAgent
40
+ @agent.autologin = @options['autologin']
34
41
  end
35
42
  end
36
43
 
@@ -47,7 +54,7 @@ module WWW
47
54
 
48
55
  def get_player_user(reload = false)
49
56
  if reload or not @player_user
50
- auth_get(@agent, 'http://enbujyo.3594t.com/members/player/index.html')
57
+ @agent.auth_get 'http://enbujyo.3594t.com/members/player/index.html'
51
58
  @player_user = get_player_data(@agent)
52
59
  end
53
60
  @player_user
@@ -86,107 +93,26 @@ module WWW
86
93
  end
87
94
 
88
95
  def get_selection_info
89
- @agent.post('http://enbujyo.3594t.com/members/selection/selection.cgi', {
96
+ page = @agent.post('http://enbujyo.3594t.com/members/selection/selection.cgi', {
90
97
  'mode' => 'latest',
91
98
  'version' => 1
92
99
  })
93
- json = hack_json(@agent.page.body)
94
- obj = JSON.parse(json)
95
- rep = obj['replay'][0]
96
-
97
- p0, p0deck, p0loc = get_selection_info_build('p0', rep)
98
- p1, p1deck, p1loc = get_selection_info_build('p1', rep)
99
-
100
- game = WWW::Enbujyo::Game.new(p0, p0deck, p0loc, p1, p1deck, p1loc, rep)
101
- game
102
- end
103
-
104
- def get_selection_info_build(prefix, rep)
105
- deck = Deck.new
106
- rep.keys.grep(/#{prefix}card_params_\d/).sort.each{|k|
107
- deck.cards.push WWW::Enbujyo::Card.parse_from_jsonstr(rep[k])
108
- }
109
- %w|0 1|.each do |num|
110
- next unless rep[prefix+'staff_image_'+num]
111
-
112
- deck.gcards.push(WWW::Enbujyo::Gunshi.new(
113
- :image => rep[prefix+'staff_image_'+num],
114
- :level => rep[prefix+'staff_level_'+num],
115
- :longname => rep[prefix+'staff_name_'+num],
116
- :team => rep[prefix+'staff_seiryoku_name_'+num],
117
- :attribute => rep[prefix+'staff_zokusei_name'],
118
- :strategy => rep[prefix+'strategy_name'],
119
- :ex => rep[prefix+'skill_ex_name']
120
- ))
121
- end
122
- player = WWW::Enbujyo::Player.new(
123
- :name => rep[prefix+'name'],
124
- :name_image_url => rep[prefix+'image'],
125
- :team => rep[prefix+'team_name'],
126
- :title => rep[prefix+'grade_name'],
127
- :brave => rep[prefix+'brave'],
128
- :brave_desc => rep[prefix+'brave_desc'],
129
- :rank => rep[prefix+'rank'],
130
- :wins => rep[prefix+'win'],
131
- :loses => rep[prefix+'lose'],
132
- :rate => rep[prefix+'win_rate']
133
- )
134
- location = WWW::Enbujyo::Location.new(
135
- :pref => rep[prefix+'pref_name'],
136
- :office => rep[prefix+'office']
137
- )
138
- return [player, deck, location]
100
+ Game.parse(page.body)
139
101
  end
140
102
 
141
103
  def download_selection(movie_type = 's')
142
104
  movie_date = (Time.now - 60*60*17).strftime("%Y%m%d") # 17時で切り替え/JST前提
143
- auth_get(@agent, 'http://enbujyo.3594t.com/members/selection/index.html')
144
-
145
- tmpname = "_enbujyo_download.#{random_string}.wmv"
146
- open(tmpname, 'w'){|tmp|
147
- tmp.print @agent.get_file("http://download.enbujyo.3594t.com/selection_download.cgi?date=#{movie_date}&type=#{movie_type}")
148
- }
149
- filename = "selection_#{movie_date}.wmv"
150
- if @agent.page.response['content-disposition']
151
- /filename="(.*\.wmv)"/ =~ @agent.page.response['content-disposition']
152
- filename = windows? ? $1 : NKF.nkf('-Sw', $1)
153
- end
154
- FileUtils.mv(tmpname, filename)
155
- puts "Downloading #{filename} has finished." unless silent?
156
- filename
157
- end
105
+ @agent.auth_get 'http://enbujyo.3594t.com/members/selection/index.html'
158
106
 
159
- private
160
- def random_string(length = 10, strings = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789')
161
- Array.new(length).map{ strings[rand(strings.size),1] }.join
107
+ download_movie(@agent, "http://download.enbujyo.3594t.com/selection_download.cgi?date=#{movie_date}&type=#{movie_type}")
162
108
  end
163
109
 
164
- def windows?
165
- RUBY_PLATFORM.downcase =~ /mswin(?!ce)|mingw|cygwin|bccwin/
110
+ def my_movies
111
+ m = WWW::Enbujyo::MyMovie.new(@agent)
112
+ m.parse
166
113
  end
167
114
 
168
115
  def silent?
169
- @options[:silent]
170
- end
171
-
172
- def auto_relogin?
173
- @options[:auto_relogin]
174
- end
175
-
176
- def auth_get(agent, url)
177
- ret = agent.get(url)
178
- if /error/i =~ agent.page.uri.to_s or /エラー/ =~ agent.page.title
179
- if auto_relogin?
180
- login
181
- else
182
- raise LoginError
183
- end
184
- end
185
- ret
186
- end
187
-
188
- def hack_json(jsonstr)
189
- jsonstr.sub(/^\w+=/,'').gsub(/\},.*\]/m, '}]')
190
116
  end
191
117
 
192
118
  end
@@ -38,6 +38,15 @@ class WwwEnbujyoTest < Test::Unit::TestCase
38
38
  assert game.location1.is_a? WWW::Enbujyo::Location
39
39
  end
40
40
  end
41
+
42
+ context "my_movies method" do
43
+ should "return my movie information list" do
44
+ @agent.login
45
+ movies = @agent.my_movies
46
+ assert movies.length >= 5
47
+ end
48
+ end
49
+
41
50
  end
42
51
  end
43
52
 
data/www-enbujyo.gemspec CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{www-enbujyo}
5
- s.version = "0.1.7"
5
+ s.version = "0.1.9"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["holysugar"]
9
- s.date = %q{2009-08-28}
9
+ s.date = %q{2009-09-06}
10
10
  s.email = %q{holysugar@gmail.com}
11
11
  s.extra_rdoc_files = [
12
12
  "LICENSE",
@@ -22,9 +22,11 @@ Gem::Specification.new do |s|
22
22
  "lib/www/enbujyo.rb",
23
23
  "lib/www/enbujyo/deck.rb",
24
24
  "lib/www/enbujyo/game.rb",
25
+ "lib/www/enbujyo/helper.rb",
25
26
  "lib/www/enbujyo/location.rb",
27
+ "lib/www/enbujyo/movie.rb",
28
+ "lib/www/enbujyo/my_movie.rb",
26
29
  "lib/www/enbujyo/player.rb",
27
- "lib/www/enbujyo/util.rb",
28
30
  "test/test_helper.rb",
29
31
  "test/www-enbujyo_test.rb",
30
32
  "www-enbujyo.gemspec"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: holysugar-www-enbujyo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.7
4
+ version: 0.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - holysugar
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-08-28 00:00:00 -07:00
12
+ date: 2009-09-06 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -32,15 +32,16 @@ files:
32
32
  - lib/www/enbujyo.rb
33
33
  - lib/www/enbujyo/deck.rb
34
34
  - lib/www/enbujyo/game.rb
35
+ - lib/www/enbujyo/helper.rb
35
36
  - lib/www/enbujyo/location.rb
37
+ - lib/www/enbujyo/movie.rb
38
+ - lib/www/enbujyo/my_movie.rb
36
39
  - lib/www/enbujyo/player.rb
37
- - lib/www/enbujyo/util.rb
38
40
  - test/test_helper.rb
39
41
  - test/www-enbujyo_test.rb
40
42
  - www-enbujyo.gemspec
41
43
  has_rdoc: true
42
44
  homepage: http://github.com/holysugar/www-enbujyo
43
- licenses:
44
45
  post_install_message:
45
46
  rdoc_options:
46
47
  - --charset=UTF-8
@@ -61,7 +62,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
61
62
  requirements: []
62
63
 
63
64
  rubyforge_project:
64
- rubygems_version: 1.3.5
65
+ rubygems_version: 1.2.0
65
66
  signing_key:
66
67
  specification_version: 2
67
68
  summary: TODO
@@ -1,26 +0,0 @@
1
- # -*- mode:ruby; coding:utf-8 -*-
2
-
3
- module WWW
4
- class Enbujyo
5
- module Util
6
- ch_number_table = {
7
- '〇' => 0,
8
- '一' => 1,
9
- '二' => 2,
10
- '三' => 3,
11
- '四' => 4,
12
- '五' => 5,
13
- '六' => 6,
14
- '七' => 7,
15
- '八' => 8,
16
- '九' => 9,
17
- '十' => 10,
18
- }
19
- def self.ch_to_i(chinesenumber)
20
- ch_number_table[chinesenumber]
21
- end
22
- end
23
- end
24
- end
25
-
26
-