yapra 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +4 -0
- data/LICENCE +22 -0
- data/License.txt +22 -0
- data/Manifest.txt +103 -0
- data/PostInstall.txt +7 -0
- data/README.txt +66 -0
- data/Rakefile +13 -0
- data/bin/yapra +52 -0
- data/config/hoe.rb +75 -0
- data/config/requirements.rb +15 -0
- data/legacy_plugins/Download/nicovideo.rb +45 -0
- data/legacy_plugins/Feed/custom_feed.rb +87 -0
- data/legacy_plugins/Feed/google_calendar.rb +51 -0
- data/legacy_plugins/Feed/google_search_history.rb +45 -0
- data/legacy_plugins/Feed/hatena_graph.rb +37 -0
- data/legacy_plugins/Feed/lirs.rb +36 -0
- data/legacy_plugins/Filter/Translations/yahoo.rb +40 -0
- data/legacy_plugins/Filter/apply_text_html.rb +26 -0
- data/legacy_plugins/Filter/average.rb +6 -0
- data/legacy_plugins/Filter/deduped.rb +51 -0
- data/legacy_plugins/Filter/find_num.rb +8 -0
- data/legacy_plugins/Filter/find_regex.rb +9 -0
- data/legacy_plugins/Filter/fresh.rb +9 -0
- data/legacy_plugins/Filter/get_html.rb +11 -0
- data/legacy_plugins/Filter/grep.rb +16 -0
- data/legacy_plugins/Filter/invert.rb +14 -0
- data/legacy_plugins/Filter/sort.rb +10 -0
- data/legacy_plugins/Filter/subs.rb +6 -0
- data/legacy_plugins/Filter/to_integer.rb +4 -0
- data/legacy_plugins/Publish/delicious.rb +91 -0
- data/legacy_plugins/Publish/google_calendar.rb +58 -0
- data/legacy_plugins/Publish/hatena_bookmark.rb +47 -0
- data/legacy_plugins/Publish/hatena_diary_writer.rb +53 -0
- data/legacy_plugins/Publish/hatena_graph.rb +39 -0
- data/legacy_plugins/Publish/lingr.rb +110 -0
- data/legacy_plugins/Publish/mixi_diary_writer.rb +104 -0
- data/legacy_plugins/Publish/scuttle.rb +92 -0
- data/legacy_plugins/Publish/twitter.rb +35 -0
- data/legacy_plugins/RSS/load.rb +38 -0
- data/legacy_plugins/RSS/save.rb +41 -0
- data/legacy_plugins/Yaml/load.rb +5 -0
- data/legacy_plugins/Yaml/save.rb +9 -0
- data/legacy_plugins/argv.rb +5 -0
- data/legacy_plugins/concat.rb +18 -0
- data/legacy_plugins/const_list.rb +15 -0
- data/legacy_plugins/first.rb +11 -0
- data/legacy_plugins/head.rb +14 -0
- data/legacy_plugins/load_path.rb +21 -0
- data/legacy_plugins/plagger.rb +94 -0
- data/legacy_plugins/plugin_from_uri.rb +31 -0
- data/legacy_plugins/pluginbase.rb +4 -0
- data/legacy_plugins/print.rb +15 -0
- data/legacy_plugins/reverse.rb +10 -0
- data/legacy_plugins/send_msg.rb +18 -0
- data/legacy_plugins/stdin.rb +6 -0
- data/legacy_plugins/stdout.rb +6 -0
- data/lib/yapra/config.rb +103 -0
- data/lib/yapra/inflector.rb +55 -0
- data/lib/yapra/legacy_plugin/advance_mode_registry.rb +38 -0
- data/lib/yapra/legacy_plugin/base.rb +26 -0
- data/lib/yapra/legacy_plugin/compatible_mode_registry.rb +34 -0
- data/lib/yapra/legacy_plugin/registry_factory.rb +21 -0
- data/lib/yapra/legacy_plugin.rb +5 -0
- data/lib/yapra/pipeline.rb +74 -0
- data/lib/yapra/plugin/base.rb +14 -0
- data/lib/yapra/plugin/context_aware.rb +14 -0
- data/lib/yapra/plugin/erb_applier.rb +15 -0
- data/lib/yapra/plugin/feed_item_operator.rb +21 -0
- data/lib/yapra/plugin/mechanize_base.rb +26 -0
- data/lib/yapra/plugin.rb +5 -0
- data/lib/yapra/runtime.rb +36 -0
- data/lib/yapra/version.rb +9 -0
- data/lib/yapra.rb +44 -0
- data/lib-plugins/yapra/plugin/config/agent.rb +34 -0
- data/lib-plugins/yapra/plugin/config/basic_auth.rb +19 -0
- data/lib-plugins/yapra/plugin/config/web_post.rb +21 -0
- data/lib-plugins/yapra/plugin/feed/custom.rb +41 -0
- data/lib-plugins/yapra/plugin/feed/load.rb +29 -0
- data/lib-plugins/yapra/plugin/filter/entry_full_text.rb +59 -0
- data/lib-plugins/yapra/plugin/publish/file_download.rb +109 -0
- data/lib-plugins/yapra/plugin/publish/gmail.rb +27 -0
- data/lib-plugins/yapra/plugin/publish/imap.rb +82 -0
- data/lib-plugins/yapra/plugin/test/append_entry.rb +25 -0
- data/plugins/Filter/deduped.rb +57 -0
- data/plugins/Filter/sort.rb +28 -0
- data/plugins/Filter/subs.rb +16 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/txt2html +82 -0
- data/setup.rb +1585 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/yapra_spec.rb +11 -0
- data/tasks/deployment.rake +34 -0
- data/tasks/environment.rake +7 -0
- data/tasks/rspec.rake +21 -0
- data/tasks/website.rake +17 -0
- data/website/index.html +115 -0
- data/website/index.txt +57 -0
- data/website/javascripts/rounded_corners_lite.inc.js +285 -0
- data/website/stylesheets/screen.css +138 -0
- data/website/template.html.erb +48 -0
- metadata +170 -0
@@ -0,0 +1,36 @@
|
|
1
|
+
## load lirs file plugin -- takatoh
|
2
|
+
##
|
3
|
+
## see http://d.hatena.ne.jp/takatoh/20070308/loadlirs
|
4
|
+
##
|
5
|
+
## example
|
6
|
+
## - module: Feed::load_lirs
|
7
|
+
## config:
|
8
|
+
## url: http://example.com/hoge.lirs.gz
|
9
|
+
##
|
10
|
+
|
11
|
+
|
12
|
+
require 'open-uri'
|
13
|
+
require 'rss/maker'
|
14
|
+
require 'zlib'
|
15
|
+
require 'kconv'
|
16
|
+
|
17
|
+
def parse_lirs(record)
|
18
|
+
fields = record.chomp.split(",")
|
19
|
+
item = RSS::RDF::Item.new
|
20
|
+
item.title = fields[6] # Title
|
21
|
+
item.link = fields[5] # URL
|
22
|
+
item.date = Time.at(fields[1].to_i + fields[3].to_i) # Last-Modified (local time)
|
23
|
+
return item
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
def lirs(config, data)
|
28
|
+
f = open(config["url"])
|
29
|
+
lirs = Zlib::GzipReader.wrap(f) {|gz| gz.read }.toutf8
|
30
|
+
items = lirs.map {|record| parse_lirs(record) }
|
31
|
+
return items
|
32
|
+
rescue
|
33
|
+
puts "LoadError File = #{config["url"]}"
|
34
|
+
return []
|
35
|
+
end
|
36
|
+
|
@@ -0,0 +1,40 @@
|
|
1
|
+
## Translate input strings by Yahoo Honyaku -- Soutaro Matsumoto
|
2
|
+
|
3
|
+
def yahoo(config, data)
|
4
|
+
begin
|
5
|
+
require 'rubygems'
|
6
|
+
rescue LoadError
|
7
|
+
end
|
8
|
+
require 'mechanize'
|
9
|
+
|
10
|
+
|
11
|
+
config = (config || { "translation" => "en=>ja" })
|
12
|
+
|
13
|
+
trans = case config["translation"]
|
14
|
+
when "en=>ja": "EJ"
|
15
|
+
when "kr=>ja": "KJ"
|
16
|
+
when "cn=>ja": "CJ"
|
17
|
+
when "ja=>en": "JE"
|
18
|
+
when "ja=>kr": "JK"
|
19
|
+
when "ja=>cn": "JC"
|
20
|
+
else
|
21
|
+
return data
|
22
|
+
end
|
23
|
+
|
24
|
+
data.collect {|d|
|
25
|
+
if d && d =~ /\S/
|
26
|
+
agent = WWW::Mechanize.new
|
27
|
+
start = agent.get("http://honyaku.yahoo.co.jp/")
|
28
|
+
form = start.forms.last
|
29
|
+
|
30
|
+
form.radiobuttons.each {|radio| radio.checked = (radio.value =~ /#{trans}/) ? true : false }
|
31
|
+
form.fields.name("text").first.value = d
|
32
|
+
|
33
|
+
result = agent.submit(form)
|
34
|
+
result.forms.name("textFormEntry").fields.name("trn_text").value
|
35
|
+
else
|
36
|
+
d.to_s
|
37
|
+
end
|
38
|
+
}
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
|
2
|
+
def apply_text_html(config, data)
|
3
|
+
begin
|
4
|
+
require 'rubygems'
|
5
|
+
rescue LoadError
|
6
|
+
end
|
7
|
+
require 'hpricot'
|
8
|
+
|
9
|
+
data.collect {|d|
|
10
|
+
doc = Hpricot(d.to_s.toutf8)
|
11
|
+
texts = []
|
12
|
+
doc.traverse_text {|text|
|
13
|
+
texts << text.to_s
|
14
|
+
}
|
15
|
+
|
16
|
+
data2 = eval_pragger(config, texts)
|
17
|
+
|
18
|
+
result_html = d.to_s.toutf8
|
19
|
+
|
20
|
+
Hash[*texts.zip(data2).flatten].each {|k,v|
|
21
|
+
result_html.sub!(k,v)
|
22
|
+
}
|
23
|
+
|
24
|
+
result_html
|
25
|
+
}
|
26
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
## Filter::deduped - Plugin to get Deduped entries -- emergent
|
2
|
+
##
|
3
|
+
## Plugin to get Deduped entries
|
4
|
+
## Cache path can be set.
|
5
|
+
##
|
6
|
+
## - module: Filter::deduped
|
7
|
+
## config:
|
8
|
+
## path: /tmp/cache/hoge
|
9
|
+
##
|
10
|
+
require 'pathname'
|
11
|
+
require 'digest/md5'
|
12
|
+
|
13
|
+
def mkdir_p path
|
14
|
+
begin
|
15
|
+
Dir.mkdir(path)
|
16
|
+
rescue Errno::ENOENT
|
17
|
+
mkdir_p Pathname.new(path).parent
|
18
|
+
retry
|
19
|
+
rescue Errno::EACCES
|
20
|
+
raise
|
21
|
+
end
|
22
|
+
0
|
23
|
+
end
|
24
|
+
|
25
|
+
def deduped config, data
|
26
|
+
cacheroot = Pathname(__FILE__).parent.parent.parent.realpath + 'cache'
|
27
|
+
cachepath = Pathname.new(config['path']) || root
|
28
|
+
if cachepath.relative?
|
29
|
+
cachepath = cacheroot + cachepath
|
30
|
+
end
|
31
|
+
puts ' cache path: ' + cachepath
|
32
|
+
|
33
|
+
if !File.exists?(cachepath)
|
34
|
+
begin
|
35
|
+
mkdir_p cachepath
|
36
|
+
rescue
|
37
|
+
puts "could'nt make cache directory"
|
38
|
+
return data
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
deduped_data = data.select {|d|
|
43
|
+
hashpath = cachepath.to_s + '/' + Digest::MD5.hexdigest(d.to_s)
|
44
|
+
if File.exists?(hashpath)
|
45
|
+
false
|
46
|
+
else
|
47
|
+
File.open(hashpath, "wb").write(d.to_s) rescue false
|
48
|
+
end
|
49
|
+
}
|
50
|
+
return deduped_data
|
51
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
## Filter input by given regular expression -- IKeJI
|
2
|
+
##
|
3
|
+
## Filter input by given regular expression.
|
4
|
+
## The test will be done with the result of to_s method of the input.
|
5
|
+
## invert option will invert results(-v option of UNIX grep command).
|
6
|
+
##
|
7
|
+
## - module: grep
|
8
|
+
## config:
|
9
|
+
## regex: "[あ-ん]"
|
10
|
+
## invert: false
|
11
|
+
|
12
|
+
def grep(config,data)
|
13
|
+
regex = Regexp.new(config["regex"])
|
14
|
+
invert = config["invert"] || false
|
15
|
+
data.select {|i| invert ^ (regex =~ i.to_s) }
|
16
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
## filter::invert
|
2
|
+
##
|
3
|
+
## Apply filter of config: section and invert the result.
|
4
|
+
##
|
5
|
+
## - module: filter::invert
|
6
|
+
## config:
|
7
|
+
## - module: grep
|
8
|
+
## config:
|
9
|
+
## regex: "理系の人々"
|
10
|
+
##
|
11
|
+
|
12
|
+
def invert(config, data)
|
13
|
+
data - eval_pragger(config, data)
|
14
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
## Publish::delicious - to post feed items to del.icio.us-- emergent
|
2
|
+
##
|
3
|
+
## - module: Publish::delicious
|
4
|
+
## config:
|
5
|
+
## username: your_username
|
6
|
+
## password: your_password
|
7
|
+
## opt_tag: pragger
|
8
|
+
## no_comment: 1
|
9
|
+
##
|
10
|
+
require 'rubygems'
|
11
|
+
require 'mechanize'
|
12
|
+
require 'uri'
|
13
|
+
require 'kconv'
|
14
|
+
|
15
|
+
class Delicious
|
16
|
+
def initialize username, password, proxy=nil
|
17
|
+
@username = username
|
18
|
+
@password = password
|
19
|
+
@agent = WWW::Mechanize.new
|
20
|
+
@agent.basic_auth(@username, @password)
|
21
|
+
if proxy && proxy.is_a?(Hash) && proxy['proxy_addr'] && proxy['proxy_port']
|
22
|
+
@agent.set_proxy(proxy['proxy_addr'], proxy['proxy_port'],
|
23
|
+
proxy['proxy_user'], proxy['proxy_pass'])
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def post url, desc, option=nil
|
28
|
+
params = {}
|
29
|
+
post_url = 'https://api.del.icio.us/v1/posts/add?'
|
30
|
+
|
31
|
+
params[:url] = url
|
32
|
+
params[:description] = desc
|
33
|
+
|
34
|
+
if option
|
35
|
+
params[:extended] = option["summary"] if option["summary"]
|
36
|
+
params[:dt] = option["datetime"] if option["datetime"]
|
37
|
+
params[:tags] = option["tags"] if option["tags"]
|
38
|
+
params[:replace] = 'no' if option["no_replace"]
|
39
|
+
params[:shared] = 'no' if option["private"]
|
40
|
+
end
|
41
|
+
|
42
|
+
req_param = []
|
43
|
+
params.map do |k,v|
|
44
|
+
req_param << k.to_s.toutf8 + '=' + v.toutf8 if (v.length > 0)
|
45
|
+
end
|
46
|
+
result = @agent.get(URI.encode(post_url + req_param.join('&')))
|
47
|
+
puts URI.encode(post_url + req_param.join('&'))
|
48
|
+
if result.body =~ /code="done"/
|
49
|
+
return true
|
50
|
+
end
|
51
|
+
false
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def get_tags entry
|
56
|
+
entry.dc_subjects.map do |s| s.content end.join(' ') rescue ''
|
57
|
+
end
|
58
|
+
|
59
|
+
def delicious config, data
|
60
|
+
sleeptime = 3
|
61
|
+
|
62
|
+
if config['sleep']
|
63
|
+
sleeptime = config['sleep'].to_i
|
64
|
+
end
|
65
|
+
|
66
|
+
data.each {|entry|
|
67
|
+
print 'posting ' + entry.title + ': '
|
68
|
+
|
69
|
+
tags = get_tags entry
|
70
|
+
if config['opt_tag']
|
71
|
+
tags = [tags, config['opt_tag']].select{|t| t.length > 0}.join(' ')
|
72
|
+
end
|
73
|
+
|
74
|
+
summary = config['no_comment'].to_i > 0 ? '' : entry.description
|
75
|
+
|
76
|
+
begin
|
77
|
+
agent = Delicious.new(config['username'], config['password'])
|
78
|
+
res = agent.post(entry.link, entry.title,
|
79
|
+
'tags' => tags, 'summary' => summary)
|
80
|
+
|
81
|
+
if res then puts 'done' else puts 'failed' end
|
82
|
+
rescue
|
83
|
+
puts 'exception'
|
84
|
+
#raise
|
85
|
+
end
|
86
|
+
|
87
|
+
sleep sleeptime
|
88
|
+
}
|
89
|
+
data
|
90
|
+
end
|
91
|
+
|
@@ -0,0 +1,58 @@
|
|
1
|
+
## Write Google Calendar Events -- Soutaro Matsumoto
|
2
|
+
##
|
3
|
+
## Write Events on given Calendar.
|
4
|
+
## The input must be an array of GooleCalendar::Event.
|
5
|
+
##
|
6
|
+
## - module: publish::google_calendar
|
7
|
+
## config:
|
8
|
+
## mail: your gmail address
|
9
|
+
## pass: your password
|
10
|
+
## calendar: the name of calendar
|
11
|
+
|
12
|
+
begin
|
13
|
+
require 'rubygems'
|
14
|
+
rescue LoadError
|
15
|
+
end
|
16
|
+
require 'gcalapi'
|
17
|
+
require 'date'
|
18
|
+
|
19
|
+
def google_calendar(config, data)
|
20
|
+
today = Date.today
|
21
|
+
|
22
|
+
pass = config['pass']
|
23
|
+
mail = config['mail']
|
24
|
+
calendar_name = /#{config['calendar']}/
|
25
|
+
|
26
|
+
start_day = today - 30
|
27
|
+
end_day = today + 31
|
28
|
+
|
29
|
+
start_time = Time.mktime(start_day.year, start_day.month, start_day.day)
|
30
|
+
end_time = Time.mktime(end_day.year, end_day.month, end_day.day)
|
31
|
+
|
32
|
+
srv = GoogleCalendar::Service.new(mail, pass)
|
33
|
+
cal_list = GoogleCalendar::Calendar.calendars(srv)
|
34
|
+
calendar = cal_list.values.find {|cal| calendar_name =~ cal.title }
|
35
|
+
|
36
|
+
if calendar
|
37
|
+
calendar.events(:'start-min' => start_time, :'start-max' => end_time).each {|event|
|
38
|
+
event.destroy!
|
39
|
+
}
|
40
|
+
|
41
|
+
data.each {|event|
|
42
|
+
begin
|
43
|
+
new_event = calendar.create_event
|
44
|
+
new_event.title = event.title
|
45
|
+
new_event.desc = event.desc
|
46
|
+
new_event.where = event.where
|
47
|
+
new_event.st = event.st
|
48
|
+
new_event.en = event.en
|
49
|
+
new_event.allday = event.allday
|
50
|
+
new_event.save!
|
51
|
+
rescue
|
52
|
+
end
|
53
|
+
}
|
54
|
+
end
|
55
|
+
|
56
|
+
data
|
57
|
+
end
|
58
|
+
|
@@ -0,0 +1,47 @@
|
|
1
|
+
## author "emergent"
|
2
|
+
## description "post feeds to hatena bookmark"
|
3
|
+
## this requires hatenabm
|
4
|
+
## -----
|
5
|
+
## $ gem install hatenabm
|
6
|
+
## -----
|
7
|
+
## example <<EOE
|
8
|
+
## - module: Publish::hatena_bookmark
|
9
|
+
## config:
|
10
|
+
## username: your_username
|
11
|
+
## password: your_password
|
12
|
+
## opt_tag: "imported"
|
13
|
+
## no_comment: 1
|
14
|
+
## EOE
|
15
|
+
## config({ :username => Field.new("username to login", String, true),
|
16
|
+
## :password => Field.new("password to login", String, true),
|
17
|
+
## :opt_tag => Field.new("optional tag(s)", String) })
|
18
|
+
require 'rubygems'
|
19
|
+
require 'hatenabm'
|
20
|
+
|
21
|
+
def hatena_bookmark(config, data)
|
22
|
+
sleeptime = config["sleep"] ? config["sleep"].to_i : 2
|
23
|
+
|
24
|
+
opt_tag = config[:opt_tag] || ''
|
25
|
+
hbm = HatenaBM.new(:user => config['username'],:pass => config['password'])
|
26
|
+
|
27
|
+
data.each {|entry|
|
28
|
+
puts 'posting ' + entry.title + ': '
|
29
|
+
|
30
|
+
tags = entry.dc_subjects.map do |s| s.content end.join(' ') rescue ''
|
31
|
+
if config['opt_tag']
|
32
|
+
tags = [tags, config['opt_tag']].select{|t| t.length > 0}.join(' ')
|
33
|
+
end
|
34
|
+
|
35
|
+
summary = config['no_comment'] ? '' : entry.description
|
36
|
+
|
37
|
+
hbm.post(
|
38
|
+
:title => entry.title,
|
39
|
+
:link => entry.link,
|
40
|
+
:tags => tags,
|
41
|
+
:summary => summary
|
42
|
+
)
|
43
|
+
sleep sleeptime
|
44
|
+
}
|
45
|
+
return data
|
46
|
+
end
|
47
|
+
|
@@ -0,0 +1,53 @@
|
|
1
|
+
## Post data to Hatena Diary -- garyo
|
2
|
+
##
|
3
|
+
## - module: Publish::hatena_diary_writer
|
4
|
+
## config:
|
5
|
+
## user_id: your-hatena-user-id
|
6
|
+
## password: your-password
|
7
|
+
|
8
|
+
require 'rubygems'
|
9
|
+
require 'mechanize'
|
10
|
+
require 'kconv'
|
11
|
+
|
12
|
+
class HatenaDiaryWriter
|
13
|
+
def initialize(id,password)
|
14
|
+
@id = id
|
15
|
+
@password = password
|
16
|
+
@agent = WWW::Mechanize.new
|
17
|
+
if proxy = ENV['HTTP_PROXY']
|
18
|
+
proxy = URI.parse(proxy)
|
19
|
+
@agent.set_proxy(proxy.host, proxy.port)
|
20
|
+
end
|
21
|
+
@diary = @agent.get("http://d.hatena.ne.jp/#{id}/")
|
22
|
+
end
|
23
|
+
|
24
|
+
def login
|
25
|
+
login_link = @diary.links.text("ログイン".toeuc)
|
26
|
+
login_page = @agent.get(login_link.href)
|
27
|
+
login_form = login_page.forms.first
|
28
|
+
login_form['name'] = @id
|
29
|
+
login_form['password'] = @password
|
30
|
+
redirect_page = @agent.submit(login_form)
|
31
|
+
@diary_link = redirect_page.links.text("こちら".toutf8)
|
32
|
+
@diary_page = @agent.get(@diary_link.href)
|
33
|
+
end
|
34
|
+
|
35
|
+
def edit(content)
|
36
|
+
edit_link = @diary_page.links.text("日記を書く".toeuc)
|
37
|
+
edit_page = @agent.get(edit_link.href)
|
38
|
+
edit_form = edit_page.forms.name("edit").first
|
39
|
+
edit_form["body"] += content
|
40
|
+
ok_button = edit_form.buttons.name("edit")
|
41
|
+
@agent.submit(edit_form, ok_button)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def hatena_diary_writer(config, data)
|
46
|
+
diary = HatenaDiaryWriter.new(config['user_id'], config['password'])
|
47
|
+
content = ''
|
48
|
+
data.each do |line|
|
49
|
+
content << ("* "+line.title+"\n"+line.link+"\n"+line.description rescue line.to_s)
|
50
|
+
end
|
51
|
+
diary.login
|
52
|
+
diary.edit(content.toeuc)
|
53
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
## Post data to Hatena Graph -- takatoh
|
2
|
+
##
|
3
|
+
## hatenaapigraph 0.2.1 is required.
|
4
|
+
##
|
5
|
+
## - module: Publish::hatena_graph
|
6
|
+
## config:
|
7
|
+
## user_id: your-hatena-user-id
|
8
|
+
## password: your-password
|
9
|
+
## graph_name: the-name-of-graph
|
10
|
+
## proxy_host: proxy-host-name (optional)
|
11
|
+
## proxy_port: proxy-port (optional)
|
12
|
+
## proxy_user: proxy-user (optional)
|
13
|
+
## proxy_pass: proxy-password (optional)
|
14
|
+
|
15
|
+
begin
|
16
|
+
require 'rubygems'
|
17
|
+
gem 'hatenaapigraph', '>=0.2.2'
|
18
|
+
rescue Exception
|
19
|
+
end
|
20
|
+
require 'hatena/api/graph'
|
21
|
+
|
22
|
+
|
23
|
+
def hatena_graph(config, data)
|
24
|
+
graph = Hatena::API::Graph.new(config['user_id'], config['password'])
|
25
|
+
if config['proxy_host']
|
26
|
+
proxy_host = config['proxy_host']
|
27
|
+
proxy_port = config['proxy_port']
|
28
|
+
proxy_user = config['proxy_user']
|
29
|
+
proxy_pass = config['proxy_pass']
|
30
|
+
graph.proxy = ::Net::HTTP.Proxy(proxy_host, proxy_port, proxy_user, proxy_pass)
|
31
|
+
end
|
32
|
+
data.each do |d|
|
33
|
+
begin
|
34
|
+
graph.post_data(config['graph_name'], :date => d.date, :value => d.value.to_f)
|
35
|
+
rescue
|
36
|
+
graph.post_data(config['graph_name'], :date => Date.today, :value => d.to_f)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
|
2
|
+
def lingr(config,data)
|
3
|
+
require 'open-uri'
|
4
|
+
require 'kconv'
|
5
|
+
require 'net/http'
|
6
|
+
require 'rexml/document'
|
7
|
+
Net::HTTP.version_1_2
|
8
|
+
lapi = LingrRoom.new(config['key'],config['room']||'pragger',config['nick']||'praggrTan')
|
9
|
+
|
10
|
+
data.each do |i|
|
11
|
+
txt = i.title rescue txt = i.to_s
|
12
|
+
lapi.say txt
|
13
|
+
end
|
14
|
+
return data
|
15
|
+
end
|
16
|
+
|
17
|
+
# Lingr API is from Sasada
|
18
|
+
# http://www.atdot.net/~ko1/diary/200702.html#d5
|
19
|
+
|
20
|
+
class LingrRoom
|
21
|
+
class LingrAPIError < RuntimeError; end
|
22
|
+
|
23
|
+
def initialize key, room, nick
|
24
|
+
@key = key
|
25
|
+
create_session
|
26
|
+
enter room, nick
|
27
|
+
@active = true
|
28
|
+
end
|
29
|
+
|
30
|
+
def post uri, params = {}
|
31
|
+
uri = URI.parse("http://www.lingr.com/api/#{uri}")
|
32
|
+
Net::HTTP.start(uri.host, uri.port) {|http|
|
33
|
+
response = http.post(uri.path, uri.query)
|
34
|
+
body = response.body
|
35
|
+
|
36
|
+
if false # ||true
|
37
|
+
puts "---------------------------------------------"
|
38
|
+
puts response.code
|
39
|
+
puts uri
|
40
|
+
puts body
|
41
|
+
body
|
42
|
+
end
|
43
|
+
body
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
def get uri, params = {}
|
48
|
+
open("http://www.lingr.com/api/#{uri}"){|f|
|
49
|
+
f.read
|
50
|
+
}
|
51
|
+
end
|
52
|
+
|
53
|
+
def get_text doc, path
|
54
|
+
e = doc.elements[path]
|
55
|
+
raise LingrAPIError.new("path not found: #{path} at #{doc}") unless e
|
56
|
+
e.get_text
|
57
|
+
end
|
58
|
+
|
59
|
+
def request method, uri, params
|
60
|
+
doc = REXML::Document.new(__send__(method, uri, params))
|
61
|
+
raise LingrAPIError.new("Error: #{doc.to_s}") if get_text(doc, '/response/status') != 'ok'
|
62
|
+
doc
|
63
|
+
end
|
64
|
+
|
65
|
+
def post_request uri, params = {}
|
66
|
+
request :post, uri, params
|
67
|
+
end
|
68
|
+
|
69
|
+
def get_request uri, params = {}
|
70
|
+
request :get, uri, params
|
71
|
+
end
|
72
|
+
|
73
|
+
def create_session
|
74
|
+
doc = post_request "session/create?api_key=#{@key}"
|
75
|
+
@session = get_text(doc, '/response/session')
|
76
|
+
end
|
77
|
+
|
78
|
+
def enter room, nick
|
79
|
+
doc = post_request "room/enter?session=#{@session}&id=#{room}&nickname=#{nick}"
|
80
|
+
@room_doc = doc
|
81
|
+
@ticket = get_text(doc, '/response/ticket')
|
82
|
+
@counter = get_text(doc, '/response/room/counter')
|
83
|
+
end
|
84
|
+
|
85
|
+
def observe
|
86
|
+
doc = get_request "room/observe?session=#{@session}&ticket=#{@ticket}&counter=#{@counter}"
|
87
|
+
#
|
88
|
+
@counter = get_text(doc, '/response/counter')
|
89
|
+
result = []
|
90
|
+
doc.elements['/response/messages'].each{|e|
|
91
|
+
nick = get_text(e, 'nickname')
|
92
|
+
text = get_text(e, 'text')
|
93
|
+
result << [nick, text]
|
94
|
+
}
|
95
|
+
result
|
96
|
+
end
|
97
|
+
|
98
|
+
def observe_loop
|
99
|
+
while @active
|
100
|
+
observe.each{|nick, text|
|
101
|
+
puts "#{nick}: #{text}".tosjis
|
102
|
+
}
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def say text
|
107
|
+
doc = post_request "room/say?session=#{@session}&ticket=#{@ticket}&message=#{URI.encode(text)}"
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|