sosowa 1.1.2 → 2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +5 -0
- data/lib/sosowa/version.rb +1 -1
- data/lib/sosowa.rb +8 -51
- data/sosowa.gemspec +1 -1
- data/spec/sosowa_spec.rb +11 -11
- metadata +5 -7
- data/lib/sosowa/parser.rb +0 -85
- data/lib/sosowa/scheme.rb +0 -194
data/CHANGELOG.md
CHANGED
data/lib/sosowa/version.rb
CHANGED
data/lib/sosowa.rb
CHANGED
@@ -1,64 +1,21 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
|
3
|
-
require "
|
4
|
-
require "nokogiri"
|
5
|
-
require "net/http"
|
6
|
-
require "time"
|
7
|
-
require "uri"
|
3
|
+
require "megalith"
|
8
4
|
|
9
5
|
$LOAD_PATH.unshift(File.expand_path("../", __FILE__))
|
10
6
|
require "sosowa/version"
|
11
|
-
require "sosowa/scheme"
|
12
|
-
require "sosowa/parser"
|
13
7
|
|
14
8
|
module Sosowa
|
15
|
-
BASE_URL =
|
16
|
-
|
17
|
-
protected
|
18
|
-
|
19
|
-
# @param [Hash] parameter
|
20
|
-
# @return [String] URL Serialized parameters
|
21
|
-
def self.serialize_parameter(parameter, add_prefix=true)
|
22
|
-
return "" unless parameter.class == Hash
|
23
|
-
ant = Hash.new
|
24
|
-
parameter.each do |key, value|
|
25
|
-
ant[key.to_sym] = value.to_s
|
26
|
-
end
|
27
|
-
param = ant.inject(""){|k,v|k+"&#{v[0]}=#{URI.escape(v[1])}"}
|
28
|
-
if add_prefix
|
29
|
-
param.sub!(/^&/,"?")
|
30
|
-
else
|
31
|
-
param.sub!(/^&/,"")
|
32
|
-
end
|
33
|
-
return param ? param : ""
|
34
|
-
end
|
35
|
-
|
36
|
-
def self.send_req(args)
|
37
|
-
params = serialize_parameter(args)
|
38
|
-
path = File.join(BASE_URL.path, params)
|
39
|
-
|
40
|
-
Net::HTTP.version_1_2
|
41
|
-
Net::HTTP.start(BASE_URL.host, BASE_URL.port) do |http|
|
42
|
-
response = http.get(path, 'User-Agent' => "Sosowa Ruby Wrapper #{Sosowa::VERSION}")
|
43
|
-
return Nokogiri::HTML(response.body.toutf8)
|
44
|
-
end
|
45
|
-
return false
|
46
|
-
end
|
47
|
-
|
48
|
-
public
|
9
|
+
BASE_URL = "http://coolier.sytes.net:8080/sosowa/ssw_l/"
|
49
10
|
|
50
11
|
def self.get(args={})
|
51
12
|
args[:log] ||= 0
|
52
|
-
|
53
|
-
|
54
|
-
parser.fetch_novel(args[:log], args[:key])
|
55
|
-
else
|
56
|
-
parser.fetch_index(args[:log])
|
57
|
-
end
|
13
|
+
megalith = Megalith.new(BASE_URL)
|
14
|
+
megalith.get args
|
58
15
|
end
|
59
16
|
|
60
|
-
def self.search(query, args={})
|
61
|
-
|
62
|
-
|
63
|
-
end
|
17
|
+
#def self.search(query, args={})
|
18
|
+
# parser = Parser.new
|
19
|
+
# parser.search(query, args)
|
20
|
+
#end
|
64
21
|
end
|
data/sosowa.gemspec
CHANGED
data/spec/sosowa_spec.rb
CHANGED
@@ -8,35 +8,35 @@ describe Sosowa, "が #get, :log => 0 を呼ぶ時は" do
|
|
8
8
|
@log = Sosowa.get :log => 0
|
9
9
|
end
|
10
10
|
|
11
|
-
it "
|
12
|
-
@log.class.should ==
|
11
|
+
it "Megalith::Subjectを返すこと" do
|
12
|
+
@log.class.should == Megalith::Subject
|
13
13
|
end
|
14
14
|
|
15
|
-
it "最初が
|
16
|
-
@log.first.class.should ==
|
15
|
+
it "最初がMegalith::Indexであること" do
|
16
|
+
@log.first.class.should == Megalith::Index
|
17
17
|
end
|
18
18
|
|
19
19
|
it "最初のタイトルがStringであること" do
|
20
20
|
@log.first.title.class.should == String
|
21
21
|
end
|
22
22
|
|
23
|
-
it "#next_pageが
|
24
|
-
@log.next_page.class.should ==
|
23
|
+
it "#next_pageがMegalith::Subjectを返すこと" do
|
24
|
+
@log.next_page.class.should == Megalith::Subject
|
25
25
|
end
|
26
26
|
|
27
|
-
it "#prev_pageが
|
28
|
-
@log.prev_page.class.should ==
|
27
|
+
it "#prev_pageがMegalith::Subjectを返すこと" do
|
28
|
+
@log.prev_page.class.should == Megalith::Subject
|
29
29
|
end
|
30
30
|
|
31
31
|
it "#latest_logがFixnumを返すこと" do
|
32
32
|
@log.latest_log.class.should == Fixnum
|
33
33
|
end
|
34
34
|
|
35
|
-
it "最初を#fetchしたら
|
36
|
-
@log.first.fetch.class.should ==
|
35
|
+
it "最初を#fetchしたらMegalith::Novelを返すこと" do
|
36
|
+
@log.first.fetch.class.should == Megalith::Novel
|
37
37
|
end
|
38
38
|
|
39
|
-
it "最初を#fetchした
|
39
|
+
it "最初を#fetchしたMegalith::Novel#titleがStringなこと" do
|
40
40
|
@log.first.fetch.title.class.should == String
|
41
41
|
end
|
42
42
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sosowa
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: '2.0'
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,10 +9,10 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-08-
|
12
|
+
date: 2012-08-23 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
15
|
+
name: megalith
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
@@ -43,8 +43,6 @@ files:
|
|
43
43
|
- README.md
|
44
44
|
- Rakefile
|
45
45
|
- lib/sosowa.rb
|
46
|
-
- lib/sosowa/parser.rb
|
47
|
-
- lib/sosowa/scheme.rb
|
48
46
|
- lib/sosowa/version.rb
|
49
47
|
- samples/chara_recognize.rb
|
50
48
|
- samples/feature-0.3.rb
|
@@ -68,7 +66,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
68
66
|
version: '0'
|
69
67
|
segments:
|
70
68
|
- 0
|
71
|
-
hash:
|
69
|
+
hash: 3888570212557509469
|
72
70
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
71
|
none: false
|
74
72
|
requirements:
|
@@ -77,7 +75,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
77
75
|
version: '0'
|
78
76
|
segments:
|
79
77
|
- 0
|
80
|
-
hash:
|
78
|
+
hash: 3888570212557509469
|
81
79
|
requirements: []
|
82
80
|
rubyforge_project:
|
83
81
|
rubygems_version: 1.8.24
|
data/lib/sosowa/parser.rb
DELETED
@@ -1,85 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
module Sosowa
|
4
|
-
class Parser
|
5
|
-
def initialize
|
6
|
-
|
7
|
-
end
|
8
|
-
|
9
|
-
def search(query, args={})
|
10
|
-
page = Sosowa.send_req({:mode => :search, :type => (args[:type] ? args[:type] : :insubject), :query => query.tosjis})
|
11
|
-
parse_index(page)
|
12
|
-
end
|
13
|
-
|
14
|
-
def fetch_index(log)
|
15
|
-
page = Sosowa.send_req({:log => log})
|
16
|
-
indexes = parse_index(page)
|
17
|
-
abs_log_num = parse_absolute_log_number(page)
|
18
|
-
Log.new(indexes, page, abs_log_num)
|
19
|
-
end
|
20
|
-
|
21
|
-
def parse_absolute_log_number(page)
|
22
|
-
li = page.search(%{ul[@id="pages"] li > *})
|
23
|
-
log = li.size
|
24
|
-
li.each do |l|
|
25
|
-
if l.attributes["id"] && l.attributes["id"].value == "selectedPage"
|
26
|
-
return log
|
27
|
-
end
|
28
|
-
log -= 1
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def parse_latest_log_number(page)
|
33
|
-
li = page.search(%{ul[@id="pages"] li > *})
|
34
|
-
return li.size
|
35
|
-
end
|
36
|
-
|
37
|
-
def parse_index(page)
|
38
|
-
indexes = []
|
39
|
-
tr = page.search("tr")
|
40
|
-
tr = tr[1, tr.size-1]
|
41
|
-
num = 1
|
42
|
-
tr.each do |tr|
|
43
|
-
unless (tr/%{td[@class="tags"]}).size > 0
|
44
|
-
title = tr.search(%{td[@class="title cell_title"] > a})[0].children[0].text.strip
|
45
|
-
tags = tr.search(%{td[@class="title cell_title"] > a})[0].attributes["title"].value.split(" / ").reject{|n| n == ""}
|
46
|
-
log = parse_absolute_log_number(page)
|
47
|
-
key = tr.search(%{td[@class="title cell_title"] > a})[0].attributes["href"].value.gsub(/^.+key=(.+?)&.+$/, '\1').to_i
|
48
|
-
author = tr.search(%{td[@class="cell_author"]})[0].inner_html.to_s.strip
|
49
|
-
created_at = Time.parse(tr.search(%{td[@class="cell_created"]})[0].inner_html.to_s.strip).strftime("%Y/%m/%d %H:%M:%S")
|
50
|
-
updated_at = Time.parse(tr.search(%{td[@class="cell_lastup"]})[0].inner_html.to_s.strip).strftime("%Y/%m/%d %H:%M:%S")
|
51
|
-
eval = tr.search(%{td[@class="cell_eval"]})[0].inner_html.to_s.strip.split("/")
|
52
|
-
review_count = eval[1].to_i
|
53
|
-
comment_count = eval[0].to_i
|
54
|
-
point = tr.search(%{td[@class="cell_point"]})[0].inner_html.to_s.strip.to_i
|
55
|
-
rate = tr.search(%{td[@class="cell_rate"]})[0].inner_html.to_s.strip.to_f
|
56
|
-
size = tr.search(%{td[@class="cell_size"]})[0].inner_html.to_s.strip
|
57
|
-
url = tr.search(%{td[@class="title cell_title"] > a})[0].attributes["href"].value
|
58
|
-
index = {
|
59
|
-
:log => log,
|
60
|
-
:key => key,
|
61
|
-
:title => title,
|
62
|
-
:author => author,
|
63
|
-
:created_at => created_at,
|
64
|
-
:updated_at => updated_at,
|
65
|
-
:review_count => review_count,
|
66
|
-
:comment_count => comment_count,
|
67
|
-
:point => point,
|
68
|
-
:tags => tags,
|
69
|
-
:rate => rate,
|
70
|
-
:size => size,
|
71
|
-
:url => URI.join(Sosowa::BASE_URL, "?mode=read&key=#{key}&log=#{log}").to_s
|
72
|
-
}
|
73
|
-
indexes << Index.new(index)
|
74
|
-
end
|
75
|
-
num += 1
|
76
|
-
end
|
77
|
-
return indexes
|
78
|
-
end
|
79
|
-
|
80
|
-
def fetch_novel(log, key)
|
81
|
-
novel = Novel.new(:log => log, :key => key)
|
82
|
-
return novel
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
data/lib/sosowa/scheme.rb
DELETED
@@ -1,194 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
module Sosowa
|
4
|
-
class Scheme
|
5
|
-
attr_reader :element
|
6
|
-
|
7
|
-
def initialize(element)
|
8
|
-
@element = element
|
9
|
-
end
|
10
|
-
|
11
|
-
def method_missing(action, *args)
|
12
|
-
return @element[action.to_s.to_sym] rescue nil
|
13
|
-
end
|
14
|
-
|
15
|
-
def params() @element.keys.map{|k|k.to_sym} ; end
|
16
|
-
alias_method :available_methods, :params
|
17
|
-
|
18
|
-
def to_hash
|
19
|
-
@element
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
class Novel < Scheme
|
24
|
-
attr_reader :log
|
25
|
-
attr_reader :key
|
26
|
-
attr_reader :page
|
27
|
-
|
28
|
-
def initialize(args)
|
29
|
-
@log = args[:log] || 0
|
30
|
-
@key = args[:key]
|
31
|
-
@page = nil
|
32
|
-
super(fetch(@log, @key))
|
33
|
-
end
|
34
|
-
|
35
|
-
def fetch(log, key)
|
36
|
-
@page = Sosowa.send_req({:mode => :read, :log => log, :key => key})
|
37
|
-
title = (@page/%{div[@class="header"] > h1})[0].inner_html.to_s.toutf8.strip
|
38
|
-
tags = (@page/%{dl[@class="info"][1] > dd > a}).map{|t| t.inner_html.to_s.toutf8 }
|
39
|
-
text = ""
|
40
|
-
text_node = @page/%{div[@class="contents ss"]}
|
41
|
-
text_node.children.each do |node|
|
42
|
-
text += node.inner_html.to_s.toutf8.strip
|
43
|
-
end
|
44
|
-
aft = @page/%{div[@class="aft"]}
|
45
|
-
ps = (aft.size > 0) ? aft[0].inner_html.to_s.toutf8 : ""
|
46
|
-
author_name = (@page/%{div[@class="author"] b})[0].inner_html.to_s.toutf8
|
47
|
-
author_email, author_website = (@page/%{div[@class="author"] a}).map{|e| e.attributes["href"].value}
|
48
|
-
author = Author.new(:name => author_name, :email => (author_email ? author_email.gsub(/^mailto:/, "") : nil), :website => author_website)
|
49
|
-
header = (@page/%{div[@class="header"] > span})[0].inner_html.to_s.toutf8.split(/\r?\n/).map{|n| n.strip}.reject{|n| n == ""}.map{|n| n.split(": ")}
|
50
|
-
review = header[3][1].split("/")
|
51
|
-
comments = []
|
52
|
-
comment_element = (@page/%{div[@class="comments"] > dl > *})
|
53
|
-
if comment_element.size > 0
|
54
|
-
comment_element[1, comment_element.size-1].each_slice(2) do |element|
|
55
|
-
bobj = element[0].search("b").map{|n| n.inner_html.to_s.toutf8.strip}
|
56
|
-
point = element[0].search("span").inner_html.to_s.toutf8.to_i
|
57
|
-
id = element[0].inner_html.to_s.toutf8.split(/\r?\n/).map{|n| n.strip}[1].to_i
|
58
|
-
comment = Comment.new(
|
59
|
-
:id => id,
|
60
|
-
:point => point,
|
61
|
-
:name => bobj[0],
|
62
|
-
:created_at => bobj[1] ? Time.parse(bobj[1].gsub(/[^\/\d\s:]/, "")) : nil,
|
63
|
-
:text => element[1] ? element[1].inner_html.to_s.toutf8.strip : nil
|
64
|
-
)
|
65
|
-
comments << comment
|
66
|
-
end
|
67
|
-
end
|
68
|
-
novel = {
|
69
|
-
:title => title,
|
70
|
-
:text => text,
|
71
|
-
:ps => ps,
|
72
|
-
:author => author,
|
73
|
-
:tags => tags,
|
74
|
-
:log => log,
|
75
|
-
:key => key,
|
76
|
-
:created_at => Time.parse(header[1][1]).strftime("%Y/%m/%d %H:%M:%S"),
|
77
|
-
:updated_at => Time.parse(header[2][1]).strftime("%Y/%m/%d %H:%M:%S"),
|
78
|
-
:review_count => review[1].to_i,
|
79
|
-
:comment_count => review[0].to_i,
|
80
|
-
:point => header[4][1].to_i,
|
81
|
-
:rate => header[5][1].to_f,
|
82
|
-
:comments => comments
|
83
|
-
}
|
84
|
-
return novel
|
85
|
-
end
|
86
|
-
|
87
|
-
def simple_rating(point)
|
88
|
-
# Get cookie
|
89
|
-
get_params = Sosowa.serialize_parameter({
|
90
|
-
:mode => :read,
|
91
|
-
:key => @key,
|
92
|
-
:log => @log
|
93
|
-
})
|
94
|
-
http = Net::HTTP.new(BASE_URL.host, BASE_URL.port)
|
95
|
-
req = Net::HTTP::Get.new(BASE_URL.path)
|
96
|
-
req["User-Agent"] = "Sosowa Ruby Wrapper #{Sosowa::VERSION}"
|
97
|
-
res = http.request(req, get_params)
|
98
|
-
cookie = res["Set-Cookie"]
|
99
|
-
|
100
|
-
# Post Comment
|
101
|
-
post_uri_params = Sosowa.serialize_parameter({
|
102
|
-
:mode => :update,
|
103
|
-
:key => @key,
|
104
|
-
:log => @log,
|
105
|
-
:target => :res
|
106
|
-
})
|
107
|
-
post_params = Sosowa.serialize_parameter({:body => "#EMPTY#".tosjis, :point => point}, false)
|
108
|
-
req = Net::HTTP::Post.new(File.join(BASE_URL.path, post_uri_params))
|
109
|
-
req["Cookie"] = cookie
|
110
|
-
req["User-Agent"] = "Sosowa Ruby Wrapper #{Sosowa::VERSION}"
|
111
|
-
res = http.request(req, post_params)
|
112
|
-
return res
|
113
|
-
end
|
114
|
-
|
115
|
-
def comment(text, params={})
|
116
|
-
# Get cookie
|
117
|
-
get_params = Sosowa.serialize_parameter({
|
118
|
-
:mode => :read,
|
119
|
-
:key => @key,
|
120
|
-
:log => @log
|
121
|
-
})
|
122
|
-
http = Net::HTTP.new(BASE_URL.host, BASE_URL.port)
|
123
|
-
req = Net::HTTP::Get.new(BASE_URL.path)
|
124
|
-
req["User-Agent"] = "Sosowa Ruby Wrapper #{Sosowa::VERSION}"
|
125
|
-
res = http.request(req, get_params)
|
126
|
-
cookie = res["Set-Cookie"]
|
127
|
-
|
128
|
-
# Post Comment
|
129
|
-
post_uri_params = Sosowa.serialize_parameter({
|
130
|
-
:mode => :update,
|
131
|
-
:key => @key,
|
132
|
-
:log => @log,
|
133
|
-
:target => :res
|
134
|
-
})
|
135
|
-
params.each do |k, v|
|
136
|
-
params[k] = v.tosjis
|
137
|
-
end
|
138
|
-
post_params = Sosowa.serialize_parameter({:body => text.tosjis}.update(params), false)
|
139
|
-
req = Net::HTTP::Post.new(File.join(BASE_URL.path, post_uri_params))
|
140
|
-
req["Cookie"] = cookie
|
141
|
-
req["User-Agent"] = "Sosowa Ruby Wrapper #{Sosowa::VERSION}"
|
142
|
-
res = http.request(req, post_params)
|
143
|
-
return res
|
144
|
-
end
|
145
|
-
|
146
|
-
def plain
|
147
|
-
return @element[:text].gsub(/(<br>|\r?\n)/, "")
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
class Comment < Scheme
|
152
|
-
|
153
|
-
end
|
154
|
-
|
155
|
-
class Author < Scheme
|
156
|
-
|
157
|
-
end
|
158
|
-
|
159
|
-
class Index < Scheme
|
160
|
-
def fetch
|
161
|
-
Novel.new(:log => @element[:log], :key => @element[:key])
|
162
|
-
end
|
163
|
-
alias_method :get, :fetch
|
164
|
-
end
|
165
|
-
|
166
|
-
class Log < Array
|
167
|
-
attr_accessor :element
|
168
|
-
attr_reader :log
|
169
|
-
|
170
|
-
def initialize(element, page, log=0)
|
171
|
-
super(element)
|
172
|
-
@element = element
|
173
|
-
@page = page
|
174
|
-
@log = log
|
175
|
-
end
|
176
|
-
|
177
|
-
def next_page
|
178
|
-
parser = Parser.new
|
179
|
-
parser.fetch_index(@log-1)
|
180
|
-
end
|
181
|
-
alias_method :next, :next_page
|
182
|
-
|
183
|
-
def prev_page
|
184
|
-
parser = Parser.new
|
185
|
-
parser.fetch_index(@log+1)
|
186
|
-
end
|
187
|
-
alias_method :prev, :prev_page
|
188
|
-
|
189
|
-
def latest_log
|
190
|
-
parser = Parser.new
|
191
|
-
parser.parse_latest_log_number(@page)
|
192
|
-
end
|
193
|
-
end
|
194
|
-
end
|