yapra 0.1.0

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.
Files changed (104) hide show
  1. data/History.txt +4 -0
  2. data/LICENCE +22 -0
  3. data/License.txt +22 -0
  4. data/Manifest.txt +103 -0
  5. data/PostInstall.txt +7 -0
  6. data/README.txt +66 -0
  7. data/Rakefile +13 -0
  8. data/bin/yapra +52 -0
  9. data/config/hoe.rb +75 -0
  10. data/config/requirements.rb +15 -0
  11. data/legacy_plugins/Download/nicovideo.rb +45 -0
  12. data/legacy_plugins/Feed/custom_feed.rb +87 -0
  13. data/legacy_plugins/Feed/google_calendar.rb +51 -0
  14. data/legacy_plugins/Feed/google_search_history.rb +45 -0
  15. data/legacy_plugins/Feed/hatena_graph.rb +37 -0
  16. data/legacy_plugins/Feed/lirs.rb +36 -0
  17. data/legacy_plugins/Filter/Translations/yahoo.rb +40 -0
  18. data/legacy_plugins/Filter/apply_text_html.rb +26 -0
  19. data/legacy_plugins/Filter/average.rb +6 -0
  20. data/legacy_plugins/Filter/deduped.rb +51 -0
  21. data/legacy_plugins/Filter/find_num.rb +8 -0
  22. data/legacy_plugins/Filter/find_regex.rb +9 -0
  23. data/legacy_plugins/Filter/fresh.rb +9 -0
  24. data/legacy_plugins/Filter/get_html.rb +11 -0
  25. data/legacy_plugins/Filter/grep.rb +16 -0
  26. data/legacy_plugins/Filter/invert.rb +14 -0
  27. data/legacy_plugins/Filter/sort.rb +10 -0
  28. data/legacy_plugins/Filter/subs.rb +6 -0
  29. data/legacy_plugins/Filter/to_integer.rb +4 -0
  30. data/legacy_plugins/Publish/delicious.rb +91 -0
  31. data/legacy_plugins/Publish/google_calendar.rb +58 -0
  32. data/legacy_plugins/Publish/hatena_bookmark.rb +47 -0
  33. data/legacy_plugins/Publish/hatena_diary_writer.rb +53 -0
  34. data/legacy_plugins/Publish/hatena_graph.rb +39 -0
  35. data/legacy_plugins/Publish/lingr.rb +110 -0
  36. data/legacy_plugins/Publish/mixi_diary_writer.rb +104 -0
  37. data/legacy_plugins/Publish/scuttle.rb +92 -0
  38. data/legacy_plugins/Publish/twitter.rb +35 -0
  39. data/legacy_plugins/RSS/load.rb +38 -0
  40. data/legacy_plugins/RSS/save.rb +41 -0
  41. data/legacy_plugins/Yaml/load.rb +5 -0
  42. data/legacy_plugins/Yaml/save.rb +9 -0
  43. data/legacy_plugins/argv.rb +5 -0
  44. data/legacy_plugins/concat.rb +18 -0
  45. data/legacy_plugins/const_list.rb +15 -0
  46. data/legacy_plugins/first.rb +11 -0
  47. data/legacy_plugins/head.rb +14 -0
  48. data/legacy_plugins/load_path.rb +21 -0
  49. data/legacy_plugins/plagger.rb +94 -0
  50. data/legacy_plugins/plugin_from_uri.rb +31 -0
  51. data/legacy_plugins/pluginbase.rb +4 -0
  52. data/legacy_plugins/print.rb +15 -0
  53. data/legacy_plugins/reverse.rb +10 -0
  54. data/legacy_plugins/send_msg.rb +18 -0
  55. data/legacy_plugins/stdin.rb +6 -0
  56. data/legacy_plugins/stdout.rb +6 -0
  57. data/lib/yapra/config.rb +103 -0
  58. data/lib/yapra/inflector.rb +55 -0
  59. data/lib/yapra/legacy_plugin/advance_mode_registry.rb +38 -0
  60. data/lib/yapra/legacy_plugin/base.rb +26 -0
  61. data/lib/yapra/legacy_plugin/compatible_mode_registry.rb +34 -0
  62. data/lib/yapra/legacy_plugin/registry_factory.rb +21 -0
  63. data/lib/yapra/legacy_plugin.rb +5 -0
  64. data/lib/yapra/pipeline.rb +74 -0
  65. data/lib/yapra/plugin/base.rb +14 -0
  66. data/lib/yapra/plugin/context_aware.rb +14 -0
  67. data/lib/yapra/plugin/erb_applier.rb +15 -0
  68. data/lib/yapra/plugin/feed_item_operator.rb +21 -0
  69. data/lib/yapra/plugin/mechanize_base.rb +26 -0
  70. data/lib/yapra/plugin.rb +5 -0
  71. data/lib/yapra/runtime.rb +36 -0
  72. data/lib/yapra/version.rb +9 -0
  73. data/lib/yapra.rb +44 -0
  74. data/lib-plugins/yapra/plugin/config/agent.rb +34 -0
  75. data/lib-plugins/yapra/plugin/config/basic_auth.rb +19 -0
  76. data/lib-plugins/yapra/plugin/config/web_post.rb +21 -0
  77. data/lib-plugins/yapra/plugin/feed/custom.rb +41 -0
  78. data/lib-plugins/yapra/plugin/feed/load.rb +29 -0
  79. data/lib-plugins/yapra/plugin/filter/entry_full_text.rb +59 -0
  80. data/lib-plugins/yapra/plugin/publish/file_download.rb +109 -0
  81. data/lib-plugins/yapra/plugin/publish/gmail.rb +27 -0
  82. data/lib-plugins/yapra/plugin/publish/imap.rb +82 -0
  83. data/lib-plugins/yapra/plugin/test/append_entry.rb +25 -0
  84. data/plugins/Filter/deduped.rb +57 -0
  85. data/plugins/Filter/sort.rb +28 -0
  86. data/plugins/Filter/subs.rb +16 -0
  87. data/script/console +10 -0
  88. data/script/destroy +14 -0
  89. data/script/generate +14 -0
  90. data/script/txt2html +82 -0
  91. data/setup.rb +1585 -0
  92. data/spec/spec.opts +1 -0
  93. data/spec/spec_helper.rb +11 -0
  94. data/spec/yapra_spec.rb +11 -0
  95. data/tasks/deployment.rake +34 -0
  96. data/tasks/environment.rake +7 -0
  97. data/tasks/rspec.rake +21 -0
  98. data/tasks/website.rake +17 -0
  99. data/website/index.html +115 -0
  100. data/website/index.txt +57 -0
  101. data/website/javascripts/rounded_corners_lite.inc.js +285 -0
  102. data/website/stylesheets/screen.css +138 -0
  103. data/website/template.html.erb +48 -0
  104. 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,6 @@
1
+ ## average plugin -- takatoh
2
+
3
+ def average(config, data)
4
+ sum = data.inject(0.0){|a,b| a + b.to_f }
5
+ return [ sum / data.size ]
6
+ 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,8 @@
1
+ def find_num(config,data)
2
+ retval = []
3
+ data.each do |text|
4
+ text.gsub(/\d(\d|,)+/) {|i| retval.push(i) }
5
+ end
6
+ return retval
7
+ end
8
+
@@ -0,0 +1,9 @@
1
+ def find_regex(config,data)
2
+ retval = []
3
+ reg = Regexp.new(config["regex"])
4
+ data.each do |text|
5
+ text.gsub(reg) {|i| retval.push(i) }
6
+ end
7
+ return retval
8
+ end
9
+
@@ -0,0 +1,9 @@
1
+ def fresh(config,data)
2
+ t = config['duration']
3
+ t = t.to_i * (60) if t=~/m$/
4
+ t = t.to_i * (60*60) if t=~/h$/
5
+ t = t.to_i * (60*60*24) if t=~/d$/
6
+ data.delete_if do |i|
7
+ i.date < (Time.now - t)
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ def get_html(config,data)
2
+ require 'open-uri'
3
+ require 'kconv'
4
+
5
+ data.map do |line|
6
+ r = ""
7
+ open(line) {|f| r = f.read.toutf8 }
8
+ r
9
+ end
10
+ end
11
+
@@ -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,10 @@
1
+ def sort(config,data)
2
+ return data.sort do|a,b|
3
+ if(config==nil || config["method"] == nil)
4
+ a <=> b
5
+ else
6
+ eval_pragger(config["method"],[a])[0] <=> eval_pragger(config["method"],[b])[0]
7
+ end
8
+ end
9
+ end
10
+
@@ -0,0 +1,6 @@
1
+ def subs(config,data)
2
+ reg = Regexp.new(config["regex"])
3
+ to = config["to"]
4
+ return data.map {|i| i.gsub(reg,to) }
5
+ end
6
+
@@ -0,0 +1,4 @@
1
+ def to_integer(config,data)
2
+ return data.map{|i| i.to_i }
3
+ end
4
+
@@ -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
+