bnicovideo 0.0.1

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.
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
+