読者です 読者をやめる 読者になる 読者になる

pythonからニコ生アラートAPIから番組通知を取得する(完全版)

Page not found · GitHubに整理したコードぶち込みました.

ニコ生アラートAPIから番組通知を取得する - miettal diaryこのエントリの続きです.
前回のエントリでは(ニコ生にあるすべての放送の)番組放送開始通知を受け取りましたが,今回はこの中から自分の参加しているコミニュティの通知を受け取った時だけ,番組情報を取得し,表示するようにしました.

相変わらずなぐり書きですが...

#!/usr/bin/python
# -*- coding: utf-8 -*-

import urllib2
import urllib
import xml2dict
import socket
import re
from pprint import pprint


mail = 'YOUR_MAIL_ADDRESS'
password = 'YOUR_NIKONIKO_PASSWORD'
xml = xml2dict.XML2Dict()


query = {'mail':mail, 'password':password}
res = urllib2.urlopen('https://secure.nicovideo.jp/secure/login?site=nicolive_antenna',
  urllib.urlencode(query))

res_data = xml.fromstring(res.read())
# sample response
#{'nicovideo_user_response': {'status': {'value': 'ok'},
#                             'ticket': {'value': 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'},
#                             'value': '\n\t'}}

ticket = res_data.nicovideo_user_response.ticket

query = {'ticket':ticket}
res = urllib2.urlopen('http://live.nicovideo.jp/api/getalertstatus', urllib.urlencode(query))

res_data = xml.fromstring(res.read())
# sample response
#{'getalertstatus': {'communities': {'community_id': {'value': 'co9320'}},
#                    'ms': {'addr': {'value': 'twr02.live.nicovideo.jp'},
#                           'port': {'value': '2532'},
#                           'thread': {'value': '1000000015'}},
#                    'status': {'value': 'ok'},
#                    'time': {'value': '1324980560'},
#                    'user_age': {'value': '19'},
#                    'user_hash': {'value': 'xxxxxxxxxxxxxxxxxxxxxxxxxxx'},
#                    'user_id': {'value': 'xxxxxxxx'},
#                    'user_name': {'value': 'miettal'},
#                    'user_prefecture': {'value': '12'},
#                    'user_sex': {'value': '1'}}}
if res_data.getalertstatus.status != 'ok' :
  raise NICOAlertAuthorizeError

if isinstance(res_data.getalertstatus.communities.community_id, int) :
  mycommunities = [ res_data.getalertstatus.communities.community_id ]
else :
  mycommunities = [ x.value for x in res_data.getalertstatus.communities.community_id ]

host = res_data.getalertstatus.ms.addr
port = int(res_data.getalertstatus.ms.port)
thread = res_data.getalertstatus.ms.thread

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((host, port))
sock.sendall(('<thread thread="%s" version="20061206" res_form="-1"/>'+chr(0)) % thread)

msg = ""
while True :
  rcvmsg = sock.recv(1024)
  for ch in rcvmsg:
    if ch == chr(0) :
      res_data = xml.fromstring(msg)
      # sample response
      #{'thread': {'last_res': {'value': '14238750'},
      #            'resultcode': {'value': '0'},
      #            'revision': {'value': '1'},
      #            'server_time': {'value': '1325054571'},
      #            'thread': {'value': '1000000015'},
      #            'ticket': {'value': '0x9639240'}}}
      #{'chat': {'date': {'value': '1325054572'},
      #          'no': {'value': '14238751'},
      #          'premium': {'value': '2'},
      #          'thread': {'value': '1000000015'},
      #          'user_id': {'value': '394'},
      #          'value': '75844139,co1140439,13064030'}}

      try :
        if 'thread' in res_data :
          print("番組通知の受信を開始しました.")
        if 'chat' in res_data :
          bloadcast_id = res_data.chat.value.split(',')[0]
          community_id = res_data.chat.value.split(',')[1]
          user_id = res_data.chat.value.split(',')[2]
          
          if community_id in mycommunities :
            res = urllib2.urlopen('http://live.nicovideo.jp/api/getstreaminfo/lv'+bloadcast_id)

            res_data = xml.fromstring(res.read())
            # sample response
            #{'getstreaminfo': {'adsense': {'item': {'name': {'value': u'xxxxxxx'},
            #                                        'url': {'value': 'http://live.nicovideo.jp/cruise'}}},
            #                   'communityinfo': {'name': {'value': u'xxxxxxx'},
            #                                     'thumbnail': {'value': 'http://xxxxxxx'}},
            #                   'request_id': {'value': 'lv75933298'},
            #                   'status': {'value': 'ok'},
            #                   'streaminfo': {'default_community': {'value': 'co1247778'},
            #                                  'description': {'value': u'xxxxxxx'},
            #                                  'provider_type': {'value': 'community'},
            #                                  'title': {'value': u'xxxxxxx'}}}}

            community_name = res_data.getstreaminfo.communityinfo.name
            bloadcast_name = res_data.getstreaminfo.streaminfo.title

            print("%sの「%s」が放送開始しました." % (community_name.encode('UTF-8'), bloadcast_name.encode('UTF-8')))
      except KeyError :
        print("その他のデータを受信しました.")
      msg = ""
    else :
      msg += ch