bnicovideo 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ /nbproject/private/
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in bnicovideo.gemspec
4
+ gemspec
5
+ gem 'sqlite3'
6
+ gem 'inifile'
data/README ADDED
@@ -0,0 +1,6 @@
1
+ == About this gem
2
+ This gem is the Niconico Douga API library which uses browser's cookie.
3
+ == How to install this gem
4
+ +gem install bnicovideo+
5
+ ==TODO
6
+ 1. Test in Google Chrome, Safari, and Internet Explorer
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "bnicovideo/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "bnicovideo"
7
+ s.version = Bnicovideo::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["MH35"]
10
+ s.email = ["contact@mh35.info"]
11
+ s.homepage = ""
12
+ s.summary = %q{Get niconico douga video information using browser's cookie}
13
+ s.description = %q{Get niconico douga video information using browser's cookie}
14
+
15
+ s.rubyforge_project = "bnicovideo"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+ end
@@ -0,0 +1,63 @@
1
+ # coding: utf-8
2
+
3
+ # This file is mylist class file
4
+
5
+ require 'rexml/document'
6
+ require 'uri'
7
+ require 'net/http'
8
+
9
+ module Bnicovideo
10
+ # Mylist class
11
+ class Mylist
12
+ # Mylist ID
13
+ attr_reader :mylist_id
14
+ # Videos' hash. Video key is Bnicovideo::Video class object, and Content key is mylist description.
15
+ attr_reader :videos
16
+ # Mylist title
17
+ attr_reader :title
18
+ # Mylist description
19
+ attr_reader :subtitle
20
+ # Mylist author
21
+ attr_reader :author
22
+ # Init from user session and mylist ID
23
+ # user_session :: Bnicovideo::UserSession
24
+ # mylist_id :: Mylist ID
25
+ def initialize(user_session, mylist_id)
26
+ @got = false
27
+ @user_session = user_session
28
+ @mylist_id = mylist_id
29
+ end
30
+ # Force read information
31
+ def read!
32
+ @videos = []
33
+ resp = nil
34
+ Net::HTTP.start('www.nicovideo.jp') do |http|
35
+ resp = http.get('/mylist/' + @mylist_id.to_s + '?rss=atom',
36
+ {'Cookie' => 'user_session=' + @user_session.session_id})
37
+ end
38
+ resp.value
39
+ xml = REXML::Document.new(resp.body)
40
+ root = xml.root
41
+ @title = root.elements['title'].text
42
+ @subtitle = root.elements['subtitle'].text
43
+ @author = root.elements['author/name'].text
44
+ root.elements.each('entry') do |entry|
45
+ video_link = entry.elements['link'].attributes['href']
46
+ uri = URI.parse(video_link)
47
+ next unless uri.scheme == 'http' && uri.host == 'www.nicovideo.jp'
48
+ video_id = uri.path.split('/')[-1]
49
+ @videos.push({
50
+ 'Video' => Bnicovideo::Video.new(@user_session, video_id),
51
+ 'Content' => entry.elements['content'].text
52
+ })
53
+ end
54
+ @got = true
55
+ end
56
+ # Read information
57
+ # refresh :: If this is true, force read. Otherwise, read unless not read.
58
+ def read(refresh = false)
59
+ return if @got && !refresh
60
+ read!
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+
3
+ # This file has Niconico Douga tag class.
4
+
5
+ module Bnicovideo
6
+ # The tag class
7
+ class Tag
8
+ # Tag name
9
+ attr_reader :name
10
+ # True if tag is locked
11
+ attr_reader :locked
12
+ # True if tag is the category tag
13
+ attr_reader :category
14
+ # Initialize from name, locked and whether this tag is category.
15
+ # name :: Tag name
16
+ # locked :: Whether this tag is locked
17
+ # category :: Whether this tag is the category tag.
18
+ def initialize(name, locked = false, category = false)
19
+ @name = name
20
+ @locked = locked
21
+ @category = category
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,114 @@
1
+ # coding: utf-8
2
+
3
+ # This file has user session class.
4
+
5
+ require 'rubygems'
6
+ require 'sqlite3'
7
+ require 'inifile'
8
+
9
+ module Bnicovideo
10
+ # User session class
11
+ class UserSession
12
+ # User session ID
13
+ attr_reader :session_id
14
+ def initialize(sid)
15
+ @session_id = sid
16
+ end
17
+ # Get user session from Firefox(3.0 or later)
18
+ def self.init_from_firefox
19
+ ini_path = File.join(ENV['APPDATA'], 'Mozilla', 'Firefox', 'profiles.ini')
20
+ ini_hash = IniFile.load(ini_path).to_h
21
+ profile_path = nil
22
+ ini_hash.each do |k, v|
23
+ next unless v['Name'] == 'default'
24
+ relative = (v['IsRelative'] != '0')
25
+ input_path = v['Path']
26
+ if relative
27
+ profile_path = File.join(ENV['APPDATA'], 'Mozilla', 'Firefox', input_path)
28
+ else
29
+ profile_path = input_path
30
+ end
31
+ sql_path = File.join(profile_path, 'cookies.sqlite')
32
+ conn = SQLite3::Database.new(sql_path)
33
+ val = conn.get_first_value("select value from moz_cookies" +
34
+ " where host='.nicovideo.jp' AND name='user_session'")
35
+ return self.new(val)
36
+ end
37
+ return nil
38
+ end
39
+ # Get user session from Google Chrome
40
+ def self.init_from_chrome
41
+ sql_path = File.join(ENV['LOCALAPPDATA'], 'Google','Chrome', 'User Data', 'Default', 'Cookies')
42
+ conn = SQLite3::Database.new(sql_path)
43
+ val = conn.get_first_value("select value from cookies" +
44
+ " where host_key='.nicovideo.jp' AND name='user_session'")
45
+ conn.close
46
+ return self.new(val)
47
+ end
48
+ # Get user session from Internet Explorer
49
+ def self.init_from_ie
50
+ cookies_path = File.join(ENV['APPDATA'], 'Microsoft', 'Windows', 'Cookies', 'Low')
51
+ Dir.open(cookies_path) do |dir|
52
+ dir.each do |fn|
53
+ next unless (/.*@nicovideo.*/ =~ fn)
54
+ File.open(fn) do |f|
55
+ cb = f.read
56
+ cs = cb.split(/\*\n/)
57
+ cs.each do |c|
58
+ ca = c.split(/\n/)
59
+ return self.new(ca[1]) if ca[0] == 'user_session'
60
+ end
61
+ end
62
+ end
63
+ end
64
+ return nil
65
+ end
66
+ # Get user session from Safari
67
+ def self.init_from_safari
68
+ cookie_path = File.join(ENV['APPDATA'], 'Apple Computer', 'Safari',
69
+ 'Cookies', 'Cookies.binarycookies')
70
+ bin = nil
71
+ File.open(cookie_path, 'rb') do |file|
72
+ bin = file.read
73
+ end
74
+ raise 'Invalid Cookie file' unless bin[0..3] == 'cook'
75
+ page_num = bin[4..7].unpack('N')[0]
76
+ pages_length = []
77
+ page_num.times do |i|
78
+ page_length = bin[(8 + i * 4)..(11 + i * 4)].unpack('N')[0]
79
+ pages_length.push(page_length)
80
+ end
81
+ read_ptr = 8 + page_num * 4
82
+ pages_length.each do |pgl|
83
+ page = bin[read_ptr..(read_ptr + pgl - 1)]
84
+ cookies_num = page[4..7].unpack('V')[0]
85
+ nread_ptr = read_ptr
86
+ cookies_offset = []
87
+ cookies_num.length.times do |i|
88
+ cookie_offset = page[(8 + i * 4)..(11 + i * 4)].unpack('V')[0]
89
+ cookies_offset.push(cookie_offset)
90
+ end
91
+ nread_ptr += 12 + cookies_num * 4
92
+ read_ptr += pgl
93
+ cookies_offset.each do |cof|
94
+ cookie_length = page[cof..(cof + 3)].unpack('V')[0]
95
+ cookie_bin = page[cof..(cof + cookie_length - 1)]
96
+ offset_url = page[(cof + 16)..(cof + 19)].unpack('V')[0]
97
+ offset_name = page[(cof + 20)..(cof + 23)].unpack('V')[0]
98
+ offset_path = page[(cof + 24)..(cof + 27)].unpack('V')[0]
99
+ offset_value = page[(cof + 28)..(cof + 31)].unpack('V')[0]
100
+ url_end = (/\x00/ =~ cookie_bin[offset_url..-1])
101
+ url = cookie_bin[offset_url, url_end]
102
+ name_end = (/\x00/ =~ cookie_bin[offset_name..-1])
103
+ name = cookie_bin[offset_name, name_end]
104
+ path_end = (/\x00/ =~ cookie_bin[offset_path..-1])
105
+ path = cookie_bin[offset_path, path_end]
106
+ value_end = (/\x00/ =~ cookie_bin[offset_value..-1])
107
+ value = cookie_bin[offset_value, value_end]
108
+ return self.new(value) if (/nicovideo\.jp$/ =~ url) && (name == 'user_session')
109
+ end
110
+ end
111
+ return nil
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,3 @@
1
+ module Bnicovideo
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,95 @@
1
+ # coding: utf-8
2
+
3
+ # This file has video class.
4
+
5
+ require 'net/http'
6
+ require 'rexml/document'
7
+ require 'date'
8
+
9
+ module Bnicovideo
10
+ # This class represents video of Niconico Douga
11
+ class Video
12
+ # Video ID
13
+ attr_reader :video_id
14
+ # Video title
15
+ attr_reader :title
16
+ # Video description
17
+ attr_reader :description
18
+ # Thumbnail URL
19
+ attr_reader :thumbnail_url
20
+ # DateTime object when the video was post
21
+ attr_reader :first_retrieve
22
+ # Video length in seconds
23
+ attr_reader :length
24
+ # Movie type(mp4, flv, ...)
25
+ attr_reader :movie_type
26
+ # How many times this video was viewed
27
+ attr_reader :view_counter
28
+ # How many comments were post
29
+ attr_reader :comment_num
30
+ # How many mylists have this video
31
+ attr_reader :mylist_counter
32
+ # Embeddable this video
33
+ attr_reader :embeddable
34
+ # Whether this video can play in Niconico live streaming
35
+ attr_reader :live_allowed
36
+ # Tags' hash. Key is language and value is the array of Bnicovideo::Tag object.
37
+ attr_reader :tags
38
+ # User id of this video's author
39
+ attr_reader :user_id
40
+ # Whether this video was deleted
41
+ attr_reader :deleted
42
+ # Initialize from user session and video ID
43
+ # user_session :: Bnicovideo::UserSession object
44
+ # video_id :: Video ID
45
+ def initialize(user_session, video_id)
46
+ @user_session = user_session
47
+ @video_id = video_id
48
+ @info_got = false
49
+ end
50
+ # Get video information
51
+ # refresh :: If this is set true, force get. Otherwise, get only if not gotten.
52
+ def get_info(refresh = false)
53
+ if @info_got && !refresh
54
+ return
55
+ end
56
+ resp = nil
57
+ Net::HTTP.start('ext.nicovideo.jp') do |http|
58
+ resp = http.get('/api/getthumbinfo/' + @video_id,
59
+ {'Cookie' => 'user_session=' + @user_session.session_id})
60
+ end
61
+ resp.value
62
+ xml = REXML::Document.new(resp.body)
63
+ root = xml.root
64
+ if root.attributes['status'] == 'ok'
65
+ @title = root.elements['thumb/title'].text
66
+ @description = root.elements['thumb/description'].text
67
+ @thumbnail_url = root.elements['thumb/thumbnail_url'].text
68
+ @first_retrieve = DateTime.parse(root.elements['thumb/first_retrieve'].text)
69
+ length_string = root.elements['thumb/length'].text
70
+ length_arr = length_string.split(':')
71
+ @length = length_arr[0].to_i * 60 + length_arr[1].to_i
72
+ @movie_type = root.elements['thumb/movie_type'].text
73
+ @view_counter = root.elements['thumb/view_counter'].text.to_i
74
+ @comment_num = root.elements['thumb/comment_num'].text.to_i
75
+ @mylist_counter = root.elements['thumb/mylist_counter'].text.to_i
76
+ @embeddable = root.elements['thumb/embeddable'].text == '1'
77
+ @live_allowed = root.elements['thumb/no_live_play'].text == '0'
78
+ @tags = {}
79
+ root.elements.each('thumb/tags') do |tse|
80
+ key = tse.attributes['domain']
81
+ dtags = []
82
+ tse.elements.each('tag') do |tge|
83
+ dtags.push(Bnicovideo::Tag.new(tge.text,
84
+ tge.attributes['lock'] == '1', tge.attributes['category'] == '1'))
85
+ end
86
+ @tags[key] = dtags
87
+ end
88
+ @user_id = root.elements['thumb/user_id'].text
89
+ else
90
+ @deleted = true
91
+ end
92
+ @info_got = true
93
+ end
94
+ end
95
+ end
data/lib/bnicovideo.rb ADDED
@@ -0,0 +1,9 @@
1
+ # This file has the top level of module
2
+
3
+ # Top level module of bnicovideo gem.
4
+ module Bnicovideo
5
+ autoload :Mylist, File.join(File.dirname(__FILE__), 'bnicovideo', 'mylist.rb')
6
+ autoload :Tag, File.join(File.dirname(__FILE__), 'bnicovideo', 'tag.rb')
7
+ autoload :UserSession, File.join(File.dirname(__FILE__), 'bnicovideo', 'user_session.rb')
8
+ autoload :Video, File.join(File.dirname(__FILE__), 'bnicovideo', 'video.rb')
9
+ end
@@ -0,0 +1,5 @@
1
+ file.reference.bnicovideo-lib=lib
2
+ main.file=
3
+ platform.active=Ruby
4
+ source.encoding=UTF-8
5
+ src.dir=${file.reference.bnicovideo-lib}
@@ -0,0 +1,13 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project xmlns="http://www.netbeans.org/ns/project/1">
3
+ <type>org.netbeans.modules.ruby.rubyproject</type>
4
+ <configuration>
5
+ <data xmlns="http://www.netbeans.org/ns/ruby-project/1">
6
+ <name>bnicovideo</name>
7
+ <source-roots>
8
+ <root id="src.dir"/>
9
+ </source-roots>
10
+ <test-roots/>
11
+ </data>
12
+ </configuration>
13
+ </project>
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bnicovideo
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - MH35
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2012-02-24 00:00:00 +09:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description: Get niconico douga video information using browser's cookie
22
+ email:
23
+ - contact@mh35.info
24
+ executables: []
25
+
26
+ extensions: []
27
+
28
+ extra_rdoc_files: []
29
+
30
+ files:
31
+ - .gitignore
32
+ - Gemfile
33
+ - README
34
+ - Rakefile
35
+ - bnicovideo.gemspec
36
+ - lib/bnicovideo.rb
37
+ - lib/bnicovideo/mylist.rb
38
+ - lib/bnicovideo/tag.rb
39
+ - lib/bnicovideo/user_session.rb
40
+ - lib/bnicovideo/version.rb
41
+ - lib/bnicovideo/video.rb
42
+ - nbproject/project.properties
43
+ - nbproject/project.xml
44
+ has_rdoc: true
45
+ homepage: ""
46
+ licenses: []
47
+
48
+ post_install_message:
49
+ rdoc_options: []
50
+
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ segments:
67
+ - 0
68
+ version: "0"
69
+ requirements: []
70
+
71
+ rubyforge_project: bnicovideo
72
+ rubygems_version: 1.3.7
73
+ signing_key:
74
+ specification_version: 3
75
+ summary: Get niconico douga video information using browser's cookie
76
+ test_files: []
77
+