drip 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'drip_tw'
3
+
4
+ app = DripDemo.new
5
+ app.update("@m_seki なんで?", 76285215248617472)
@@ -0,0 +1,52 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'drip_tw'
3
+
4
+ def last_tweet_id
5
+ key = nil
6
+ while kv = MyDrip.older(key, 'DripDemo MyStatus')
7
+ key, value = kv
8
+ return value['id'] if value['id']
9
+ end
10
+ nil
11
+ end
12
+
13
+ def get_user_timeline(app, since_id, max_id)
14
+ count = 3
15
+ begin
16
+ ary = app.user_timeline(since_id, max_id)
17
+ rescue
18
+ p $!
19
+ count -= 1
20
+ return nil, [] if count <= 0
21
+ sleep 5
22
+ retry
23
+ end
24
+ max_id = nil
25
+ ary.reverse_each do |event|
26
+ next unless event['id']
27
+ max_id = event['id'] - 1
28
+ break
29
+ end
30
+ return max_id, ary
31
+ end
32
+
33
+ app = DripDemo.new
34
+
35
+ since_id = last_tweet_id
36
+
37
+ max_id = nil
38
+ timeline = []
39
+ while true
40
+ max_id, ary = get_user_timeline(app, since_id, max_id)
41
+ break if ary.empty?
42
+ pp [ary[0]['text'], ary[-1]['text']] rescue nil
43
+ sleep 5
44
+ timeline += ary
45
+ end
46
+
47
+ p [timeline.size, 'continue?']
48
+ gets
49
+
50
+ timeline.reverse_each do |event|
51
+ MyDrip.write(event, 'DripDemo MyStatus')
52
+ end
@@ -0,0 +1,140 @@
1
+ #
2
+ # import from https://github.com/shibason/rb-simple-oauth
3
+ # see: http://d.hatena.ne.jp/shibason/20090809/1249764381
4
+ require 'uri'
5
+ require 'net/http'
6
+ require 'openssl'
7
+
8
+ class SimpleOAuth
9
+ def initialize(consumer_key, consumer_secret, token, token_secret)
10
+ @consumer_key = consumer_key
11
+ @consumer_secret = consumer_secret
12
+ @token = token
13
+ @token_secret = token_secret
14
+ # This class supports only 'HMAC-SHA1' as signature method at present.
15
+ @signature_method = 'HMAC-SHA1'
16
+ end
17
+
18
+ def get(url, headers = {})
19
+ request(:GET, url, nil, headers)
20
+ end
21
+
22
+ def head(url, headers = {})
23
+ request(:HEAD, url, nil, headers)
24
+ end
25
+
26
+ def post(url, body = nil, headers = {})
27
+ request(:POST, url, body, headers)
28
+ end
29
+
30
+ def put(url, body = nil, headers = {})
31
+ request(:PUT, url, body, headers)
32
+ end
33
+
34
+ def delete(url, headers = {})
35
+ request(:DELETE, url, nil, headers)
36
+ end
37
+
38
+ private
39
+ def request(method, url, body = nil, headers = {})
40
+ method = method.to_s
41
+ url = URI.parse(url)
42
+ request = create_http_request(method, url.request_uri, body, headers)
43
+ request['Authorization'] = auth_header(method, url, request.body)
44
+ Net::HTTP.new(url.host, url.port).request(request)
45
+ end
46
+
47
+ RESERVED_CHARACTERS = /[^a-zA-Z0-9\-\.\_\~]/
48
+
49
+ def escape(value)
50
+ URI.escape(value.to_s, RESERVED_CHARACTERS)
51
+ end
52
+
53
+ def encode_parameters(params, delimiter = '&', quote = nil)
54
+ if params.is_a?(Hash)
55
+ params = params.map do |key, value|
56
+ "#{escape(key)}=#{quote}#{escape(value)}#{quote}"
57
+ end
58
+ else
59
+ params = params.map { |value| escape(value) }
60
+ end
61
+ delimiter ? params.join(delimiter) : params
62
+ end
63
+
64
+ VERSION = '0.1'
65
+ USER_AGENT = "SimpleOAuth/#{VERSION}"
66
+
67
+ def create_http_request(method, path, body, headers)
68
+ method = method.capitalize.to_sym
69
+ request = Net::HTTP.const_get(method).new(path, headers)
70
+ request['User-Agent'] = USER_AGENT
71
+ if method == :Post || method == :Put
72
+ request.body = body.is_a?(Hash) ? encode_parameters(body) : body.to_s
73
+ request.content_type = 'application/x-www-form-urlencoded'
74
+ request.content_length = (request.body || '').length
75
+ end
76
+ request
77
+ end
78
+
79
+ def auth_header(method, url, body)
80
+ parameters = oauth_parameters
81
+ parameters[:oauth_signature] = signature(method, url, body, parameters)
82
+ 'OAuth ' + encode_parameters(parameters, ', ', '"')
83
+ end
84
+
85
+ OAUTH_VERSION = '1.0'
86
+
87
+ def oauth_parameters
88
+ {
89
+ :oauth_consumer_key => @consumer_key,
90
+ :oauth_token => @token,
91
+ :oauth_signature_method => @signature_method,
92
+ :oauth_timestamp => timestamp,
93
+ :oauth_nonce => nonce,
94
+ :oauth_version => OAUTH_VERSION
95
+ }
96
+ end
97
+
98
+ def timestamp
99
+ Time.now.to_i.to_s
100
+ end
101
+
102
+ def nonce
103
+ OpenSSL::Digest::Digest.hexdigest('MD5', "#{Time.now.to_f}#{rand}")
104
+ end
105
+
106
+ def signature(*args)
107
+ base64(digest_hmac_sha1(signature_base_string(*args)))
108
+ end
109
+
110
+ def base64(value)
111
+ [ value ].pack('m').gsub(/\n/, '')
112
+ end
113
+
114
+ def digest_hmac_sha1(value)
115
+ OpenSSL::HMAC.digest(OpenSSL::Digest::SHA1.new, secret, value)
116
+ end
117
+
118
+ def secret
119
+ escape(@consumer_secret) + '&' + escape(@token_secret)
120
+ end
121
+
122
+ def signature_base_string(method, url, body, parameters)
123
+ method = method.upcase
124
+ base_url = signature_base_url(url)
125
+ parameters = normalize_parameters(parameters, body, url.query)
126
+ encode_parameters([ method, base_url, parameters ])
127
+ end
128
+
129
+ def signature_base_url(url)
130
+ URI::HTTP.new(url.scheme, url.userinfo, url.host, nil, nil, url.path,
131
+ nil, nil, nil)
132
+ end
133
+
134
+ def normalize_parameters(parameters, body, query)
135
+ parameters = encode_parameters(parameters, nil)
136
+ parameters += body.split('&') if body
137
+ parameters += query.split('&') if query
138
+ parameters.sort.join('&')
139
+ end
140
+ end
@@ -0,0 +1,154 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'my_drip'
3
+ require 'MeCab'
4
+ require 'pp'
5
+
6
+ class Bag
7
+ def initialize
8
+ @bag = Hash.new(0)
9
+ @size = 0
10
+ @cache = nil
11
+ end
12
+ attr_reader :size
13
+
14
+ def push(obj)
15
+ @cache = nil
16
+ @bag[obj] += 1
17
+ @size += 1
18
+ obj
19
+ end
20
+
21
+ def sample
22
+ @cache = @bag.sort_by {|k, v| v} unless @cache
23
+ prob = rand(@size)
24
+ @cache.each do |k, v|
25
+ prob -= v
26
+ return k if prob < 0
27
+ end
28
+ end
29
+ end
30
+
31
+ class BagInBag < Bag
32
+ def initialize(&blk)
33
+ super
34
+ @bag_in_bag = Hash.new {|h, k| h[k] = blk.call}
35
+ end
36
+
37
+ def push(obj, *rest)
38
+ super(obj)
39
+ @bag_in_bag[obj].push(*rest)
40
+ end
41
+
42
+ def [](key, *rest)
43
+ if rest.empty?
44
+ @bag_in_bag[key]
45
+ else
46
+ @bag_in_bag[key][*rest]
47
+ end
48
+ end
49
+ end
50
+
51
+ class EntityEnum
52
+ def initialize(str, entity)
53
+ @str = str || ''
54
+ @entity = []
55
+ (entity || []).each do |k, v|
56
+ @entity += v
57
+ end
58
+ end
59
+
60
+ def each
61
+ unless @entity
62
+ yield(@str, nil)
63
+ return
64
+ end
65
+ ary = @entity.sort_by {|e| e['indices'][0]}
66
+ cursor = 0
67
+ while head = ary.shift
68
+ left, right = head['indices']
69
+ if left > cursor
70
+ yield(@str[cursor ... left], nil)
71
+ end
72
+ yield(@str[left .. right], head)
73
+ cursor = right + 1
74
+ end
75
+ if @str.length > cursor
76
+ yield(@str[cursor ... @str.length], nil)
77
+ end
78
+ end
79
+ end
80
+
81
+ class Markov
82
+ def initialize
83
+ @bag = BagInBag.new { BagInBag.new { Bag.new } }
84
+ @start = Bag.new
85
+ @intern = Hash.new
86
+ end
87
+
88
+ def intern(str)
89
+ @intern[str] ||= str
90
+ @intern[str]
91
+ end
92
+
93
+ def add(ary)
94
+ return if ary.size <= 3
95
+ ary = ary.collect {|s| intern(s)}
96
+ @start.push(ary[0])
97
+ ary.each_cons(3) do |p0, p1, suffix|
98
+ @bag.push(p0, p1, suffix)
99
+ end
100
+ end
101
+
102
+ def generate(max_len=30)
103
+ s = @start.sample
104
+ ary = [s, @bag[s].sample]
105
+ max_len.times do
106
+ it = @bag[*ary[-2, 2]].sample
107
+ break if it == :eos
108
+ ary << it
109
+ end
110
+ ary
111
+ end
112
+ end
113
+
114
+ $screen_name = {}
115
+
116
+ def mention_user
117
+ " @#{$screen_name.keys.sample} "
118
+ end
119
+
120
+ def as_str(ary)
121
+ ary = ary.map {|x| x == :name ? mention_user : x}
122
+ ary.inject{|s,c|s+=(s+"\00"+c=~/\w\00\w/?" ":"")+c}
123
+ end
124
+
125
+ markov = Markov.new
126
+ m = MeCab::Tagger.new('-Owakati')
127
+
128
+ MyDrip.head(4000, 'DripDemo MyStatus').each do |k, v|
129
+ next if v['retweeted_status']
130
+ entity = v['entities']
131
+ str = v['text']
132
+ ary = []
133
+ EntityEnum.new(str, entity).each do |s, kind|
134
+ next if s == 'RT'
135
+ unless kind
136
+ ary += m.parse(s).split(' ')
137
+ else
138
+ ary <<:name if kind['screen_name']
139
+ if kind['screen_name']
140
+ $screen_name[kind['screen_name']] = true
141
+ end
142
+ end
143
+ end
144
+ markov.add(ary + [:eos])
145
+ end
146
+
147
+ while gets
148
+ 10.times do
149
+ ary = markov.generate
150
+ next if ary.size < 10
151
+ puts as_str(ary)
152
+ puts
153
+ end
154
+ end
@@ -0,0 +1,156 @@
1
+ require 'test/unit'
2
+ require '../lib/drip.rb'
3
+ require 'fileutils'
4
+
5
+ class TestDrip < Test::Unit::TestCase
6
+ def setup
7
+ @drip = Drip.new(nil)
8
+ end
9
+
10
+ def test_time_travel
11
+ @drip.write('age' => 1)
12
+ @drip.write('age' => 2)
13
+ @drip.write('age' => 3)
14
+ oid, value = @drip.older(nil)
15
+ assert_equal(value, 'age' => 3)
16
+ oid, value = @drip.older(oid)
17
+ assert_equal(value, 'age' => 2)
18
+ oid, value = @drip.older(oid)
19
+ assert_equal(value, 'age' => 1)
20
+ oid, value = @drip.older(oid)
21
+ assert_equal(oid, nil)
22
+ assert_equal(value, nil)
23
+
24
+ oid, value = @drip.newer(0)
25
+ assert_equal(value, 'age' => 1)
26
+ oid, value = @drip.newer(oid)
27
+ assert_equal(value, 'age' => 2)
28
+ oid, value = @drip.newer(oid)
29
+ assert_equal(value, 'age' => 3)
30
+ oid, value = @drip.newer(oid)
31
+ assert_equal(oid, nil)
32
+ assert_equal(value, nil)
33
+ end
34
+
35
+ def test_read
36
+ 11.times do |n|
37
+ @drip.write("n=#{n}" => 'x' * n, n => n, "n" => n, :symbol => n)
38
+ end
39
+ ary = @drip.read(0, 3)
40
+ assert_equal(ary.size, 3)
41
+ assert_equal(ary[0][1]['n'], 0)
42
+ assert_equal(ary[1][1]['n'], 1)
43
+ assert_equal(ary[2][1]['n'], 2)
44
+ ary = @drip.read(ary[2][0], 3)
45
+ assert_equal(ary.size, 3)
46
+ ary = @drip.read(ary[2][0], 3)
47
+ assert_equal(ary.size, 3)
48
+ ary = @drip.read(ary[2][0], 3)
49
+ assert_equal(ary.size, 2)
50
+
51
+ oid = @drip.write('latest', 'tag1', 'tag2')
52
+ oid, value, *tags = @drip.newer(oid - 1)
53
+ assert_equal(value, 'latest')
54
+ assert_equal(tags, ['tag1', 'tag2'])
55
+ end
56
+
57
+ def test_symbol_is_not_tag
58
+ @drip.write({:symbol => :symbol, 'string' => :string}, :symbol, 'string')
59
+ assert_raise(ArgumentError) {@drip.read_tag(0, :symbol, 1, 0)}
60
+ oid, value = @drip.older(@drip.time_to_key(Time.now))
61
+ assert_equal(value, {:symbol => :symbol, 'string' => :string})
62
+ end
63
+
64
+ def test_number_is_not_tag
65
+ @drip.write({5 => :five, 'string' => :string}, 5, 'string')
66
+ assert_equal(@drip.read_tag(0, 'string', 1, 0).size, 1)
67
+ assert_raise(ArgumentError) {@drip.read_tag(0, 5, 1, 0)}
68
+ end
69
+
70
+ def test_older_now_is_newest
71
+ @drip.write('age' => 1)
72
+ @drip.write('age' => 2)
73
+ @drip.write('age' => 3)
74
+ oid, value = @drip.older(nil)
75
+ assert_equal(value, 'age' => 3)
76
+ oid, value = @drip.older(@drip.time_to_key(Time.now))
77
+ assert_equal(value, 'age' => 3)
78
+
79
+ # newer(past)
80
+ assert_equal(@drip.newer(0)[1], 'age' => 1)
81
+ assert_equal(@drip.newer(0)[1], 'age' => 1)
82
+ end
83
+
84
+ def test_read_tag
85
+ 3.times do |n|
86
+ @drip.write({'n' => n}, 'n')
87
+ @drip.write({'n' => n, '2' => n * 2}, 'n', '2')
88
+ @drip.write({'n' => n, '2' => n * 2, '3' => n * 3}, 'n', '2', '3')
89
+ end
90
+
91
+ ary = @drip.read_tag(0, 'n', 10)
92
+ assert_equal(ary.size, 9)
93
+ assert_equal(ary[0][1]['n'], 0)
94
+ assert_equal(ary[0][2], 'n')
95
+ assert_equal(ary[2][4], '3')
96
+ end
97
+
98
+ def test_head
99
+ 10.times do |n|
100
+ @drip.write(n)
101
+ end
102
+
103
+ ary = @drip.head(3)
104
+ assert_equal(ary.size, 3)
105
+ assert_equal(ary[0][1], 7)
106
+ assert_equal(ary[2][1], 9)
107
+ end
108
+
109
+ def test_after
110
+ assert_equal(@drip.write_after(Time.at(1), 1), 1000000)
111
+ assert_equal(@drip.write_after(Time.at(2), 2), 2000000)
112
+ assert_equal(@drip.write_after(Time.at(3), 3), 3000000)
113
+ assert_equal(@drip.write_after(Time.at(4), 4), 4000000)
114
+ assert_equal(@drip.write_after(Time.at(4), 5), 4000001)
115
+ assert_equal(@drip.write_after(Time.at(2), 6), 4000002)
116
+ assert_equal(@drip.write_after(Time.at(5), 6), 5000000)
117
+ assert_equal(@drip.write_after(Time.at(5), 7), 5000001)
118
+ assert_equal(@drip.write_at(Time.at(6), 8), 6000000)
119
+ assert_raise(RuntimeError) {@drip.write_at(Time.at(6), 8)}
120
+ assert_equal(@drip.write_after(Time.at(5), 8), 6000001)
121
+ end
122
+ end
123
+
124
+ class TestDripUsingStorage < TestDrip
125
+ def remove_drip(dir='test_db')
126
+ FileUtils.rm_r(dir, :force => true)
127
+ end
128
+
129
+ def setup
130
+ remove_drip
131
+ @drip = Drip.new('test_db')
132
+ end
133
+
134
+ def teardown
135
+ remove_drip
136
+ end
137
+
138
+ def test_twice
139
+ 11.times do |n|
140
+ @drip.write("n=#{n}" => 'x' * n, n => n, "n" => n, :symbol => n)
141
+ end
142
+
143
+ drip = Drip.new('test_db')
144
+ ary = drip.read(0, 3)
145
+ assert_equal(ary.size, 3)
146
+ assert_equal(ary[0][1]['n'], 0)
147
+ assert_equal(ary[1][1]['n'], 1)
148
+ assert_equal(ary[2][1]['n'], 2)
149
+ ary = drip.read(ary[2][0], 3)
150
+ assert_equal(ary.size, 3)
151
+ ary = drip.read(ary[2][0], 3)
152
+ assert_equal(ary.size, 3)
153
+ ary = drip.read(ary[2][0], 3)
154
+ assert_equal(ary.size, 2)
155
+ end
156
+ end