Class: Okayu::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/client.rb

Constant Summary collapse

TOP_URL =
'http://www.nicovideo.jp/'
LOGIN_URL =
'https://secure.nicovideo.jp/secure/login?site=niconico'
PLAYER_STATUS_URL =
'http://live.nicovideo.jp/api/getplayerstatus?v='
@@channels =
[]
@@connected =
false
@@agent =
WWW::Mechanize.new

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(channel) ⇒ Client

Returns a new instance of Client.



152
153
154
# File 'lib/client.rb', line 152

def initialize channel
  @channel = channel
end

Instance Attribute Details

#channelObject (readonly)

instance methods



151
152
153
# File 'lib/client.rb', line 151

def channel
  @channel
end

Class Method Details

.agentObject



40
41
42
# File 'lib/client.rb', line 40

def agent
  @@agent
end

.channelsObject



33
34
35
# File 'lib/client.rb', line 33

def channels
  @@channels
end

.close(channel) ⇒ Object



136
137
138
139
140
# File 'lib/client.rb', line 136

def close channel
  index = @@channels.index(channel)
  @@channels[index].thread.kill
  @@channels[index] = nil
end

.close_allObject



142
143
144
145
146
# File 'lib/client.rb', line 142

def close_all
  @@channels.each do |channel|
    channel.thread.kill
  end
end

.connect(auth = {}) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/client.rb', line 44

def connect auth={}
  begin
    if auth[:mail] && auth[:password]
      @@login_page = @@agent.post(LOGIN_URL, 'mail' => auth[:mail], 'password' => auth[:password])
    elsif auth[:cookie]
      @@agent.cookie_jar.load_cookiestxt(auth[:cookie])
      @@login_page = @@agent.get(TOP_URL)
    end

    if @@login_page
      @@connected = true unless @@login_page.forms.first.name == 'login'
    else
      @@connected = false
    end
  rescue
    @@connected = false
  end
end

.connected?Boolean

Returns:

  • (Boolean)


36
37
38
# File 'lib/client.rb', line 36

def connected?
  @@connected
end

.get_player_status(live_id) ⇒ Object



109
110
111
# File 'lib/client.rb', line 109

def get_player_status live_id
    PlayerStatus.new(@@agent.get(PLAYER_STATUS_URL + live_id).body)
end

.get_postkey(thread_info) ⇒ Object



122
123
124
125
126
127
128
129
# File 'lib/client.rb', line 122

def get_postkey thread_info
  postkey_page = @@agent.get(postkey_url(thread_info.thread, thread_info.last_res))
  if /postkey=(.+)/ =~ postkey_page.body
    $1
  else
    nil
  end
end

.live_id_from_url(url) ⇒ Object



63
64
65
66
67
68
69
# File 'lib/client.rb', line 63

def live_id_from_url url
  if /lv\d+/ =~ url
    $&
  else
    nil
  end
end

.live_query_msg(thread, res_from) ⇒ Object



113
114
115
# File 'lib/client.rb', line 113

def live_query_msg thread, res_from
  %Q[<thread thread="#{thread}" res_from="#{res_from}" version="20061206" />\0]
end

.open(live_id, res_from = -200) ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/client.rb', line 71

def open live_id, res_from=-200
  if live_id
    channel = Channel.new
    channel.id = live_id
    channel.player_status = get_player_status(live_id)
    if channel.player_status.status
      @@channels << channel
      channel.thread = Thread.new(@@channels.index(channel), channel.player_status, res_from) do |index, ps, res_from|
        begin
          s = TCPSocket.open(ps.addr, ps.port)
          s.print live_query_msg(ps.thread, res_from)
          thread_info = ThreadInfo.new s.gets("\0")
          while true
            @@channels[index].queue.enq s.gets("\0").slice(0...-1)
          end
        ensure
          s.close
        end
      end
      self.new channel
    end
  end
end

.postkey_url(thread, last_res) ⇒ Object



117
118
119
120
# File 'lib/client.rb', line 117

def postkey_url thread, last_res
  block_no = last_res.to_i / 100
  %Q[http://live.nicovideo.jp/api/getpostkey?thread=#{thread}&block_no=#{block_no}]
end

.send_comment(live_id, comment, mail) ⇒ Object



95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/client.rb', line 95

def send_comment live_id, comment, mail
  if live_id
    player_status = get_player_status(live_id)
    if player_status.status
      s = TCPSocket.open(player_status.addr, player_status.port)
      s.print live_query_msg(player_status.thread, -0)
      thread_info = ThreadInfo.new s.gets("\0")
      postkey = get_postkey(thread_info)
      s.print(send_comment_msg(comment, mail, player_status, thread_info, postkey))
      s.close
    end
  end
end

.send_comment_msg(comment, mail, player_status, thread_info, postkey) ⇒ Object



131
132
133
134
# File 'lib/client.rb', line 131

def send_comment_msg comment, mail, player_status, thread_info, postkey
  vpos = ((Time.new - Time.at(player_status.open_time.to_i)) * 100).to_i
  %Q[<chat thread="#{thread_info.thread}" ticket="#{thread_info.ticket}" vpos="#{vpos}" postkey="#{postkey}" mail="#{mail}" user_id="#{player_status.user_id}" premium="#{player_status.is_premium}">#{comment}</chat>\0]
end

Instance Method Details

#base_timeObject



207
208
209
# File 'lib/client.rb', line 207

def base_time
  Time.at(@channel.player_status.base_time.to_i)
end

#closeObject



156
157
158
# File 'lib/client.rb', line 156

def close
  self.class.close @channel
end

#comment_hash_from_xml(xml) ⇒ Object



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
# File 'lib/client.rb', line 170

def comment_hash_from_xml xml
  hash = Hash.new
  reader = Nokogiri::XML::Reader(xml)
  reader.read
  if reader.name == 'chat'
    hash[:commented_at] = Time.at(reader.attribute('date').to_i)
    hash[:mail]         = reader.attribute('mail') || ''
    hash[:number]       = reader.attribute('no')
    hash[:user_id]      = reader.attribute('user_id')
    case reader.attribute('premium')
    when '1'
      hash[:premium]    = true
      hash[:owner]      = false
      hash[:command]    = false
    when '2'
      hash[:premium]    = true
      hash[:owner]      = true
      hash[:command]    = true
    when '3'
      hash[:premium]    = true
      hash[:owner]      = true
      hash[:command]    = false
    else
      hash[:premium]    = false
      hash[:owner]      = false
      hash[:command]    = false
    end
    reader.read
    hash[:message]      = reader.value
  end
  hash
end

#commentsObject



160
161
162
163
164
165
166
167
168
# File 'lib/client.rb', line 160

def comments
  comments = []
  counter = 0
  until @channel.queue.empty? || counter > 5
    comments << @channel.queue.deq
    counter += 1
  end
  comments.map{|comment| comment_hash_from_xml(comment)}
end

#communityObject



203
204
205
# File 'lib/client.rb', line 203

def community
  @channel.player_status.default_community
end