atig 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 +24 -0
- data/Gemfile +3 -0
- data/README.mkdn +52 -0
- data/Rakefile +15 -0
- data/atig.gemspec +25 -0
- data/bin/atig +74 -0
- data/docs/OMakefile +32 -0
- data/docs/OMakeroot +45 -0
- data/docs/_static/allow.png +0 -0
- data/docs/_static/emacs.png +0 -0
- data/docs/_static/irc_setting.png +0 -0
- data/docs/_static/irssi.png +0 -0
- data/docs/_static/limechat.png +0 -0
- data/docs/_static/limechat_s.png +0 -0
- data/docs/_static/oauth_channel.png +0 -0
- data/docs/_static/screenshot.png +0 -0
- data/docs/_static/structure.png +0 -0
- data/docs/_static/verify.png +0 -0
- data/docs/changelog.rst +96 -0
- data/docs/commandline_options.rst +21 -0
- data/docs/commands.rst +84 -0
- data/docs/conf.py +194 -0
- data/docs/config.rst +159 -0
- data/docs/feature.rst +41 -0
- data/docs/graphics.graffle +1995 -0
- data/docs/hacking_guide.rst +43 -0
- data/docs/index.rst +109 -0
- data/docs/irc.rst +31 -0
- data/docs/options.rst +75 -0
- data/docs/quickstart.rst +89 -0
- data/docs/resize.sh +7 -0
- data/docs/tiarra.rst +2 -0
- data/docs/tig.rst +21 -0
- data/lib/atig.rb +19 -0
- data/lib/atig/agent.rb +8 -0
- data/lib/atig/agent/agent.rb +38 -0
- data/lib/atig/agent/clenup.rb +23 -0
- data/lib/atig/agent/dm.rb +35 -0
- data/lib/atig/agent/following.rb +45 -0
- data/lib/atig/agent/full_list.rb +20 -0
- data/lib/atig/agent/list.rb +55 -0
- data/lib/atig/agent/list_status.rb +46 -0
- data/lib/atig/agent/mention.rb +13 -0
- data/lib/atig/agent/other_list.rb +18 -0
- data/lib/atig/agent/own_list.rb +18 -0
- data/lib/atig/agent/stream_follow.rb +38 -0
- data/lib/atig/agent/timeline.rb +13 -0
- data/lib/atig/agent/user_stream.rb +31 -0
- data/lib/atig/basic_twitter.rb +116 -0
- data/lib/atig/bitly.rb +52 -0
- data/lib/atig/channel.rb +5 -0
- data/lib/atig/channel/channel.rb +17 -0
- data/lib/atig/channel/dm.rb +14 -0
- data/lib/atig/channel/list.rb +76 -0
- data/lib/atig/channel/mention.rb +20 -0
- data/lib/atig/channel/retweet.rb +28 -0
- data/lib/atig/channel/timeline.rb +74 -0
- data/lib/atig/command.rb +21 -0
- data/lib/atig/command/autofix.rb +58 -0
- data/lib/atig/command/command.rb +24 -0
- data/lib/atig/command/command_helper.rb +95 -0
- data/lib/atig/command/destroy.rb +44 -0
- data/lib/atig/command/dm.rb +31 -0
- data/lib/atig/command/favorite.rb +27 -0
- data/lib/atig/command/info.rb +50 -0
- data/lib/atig/command/limit.rb +15 -0
- data/lib/atig/command/location.rb +23 -0
- data/lib/atig/command/name.rb +18 -0
- data/lib/atig/command/option.rb +37 -0
- data/lib/atig/command/refresh.rb +18 -0
- data/lib/atig/command/reply.rb +37 -0
- data/lib/atig/command/retweet.rb +63 -0
- data/lib/atig/command/search.rb +51 -0
- data/lib/atig/command/spam.rb +26 -0
- data/lib/atig/command/status.rb +41 -0
- data/lib/atig/command/thread.rb +44 -0
- data/lib/atig/command/time.rb +32 -0
- data/lib/atig/command/uptime.rb +32 -0
- data/lib/atig/command/user.rb +42 -0
- data/lib/atig/command/user_info.rb +27 -0
- data/lib/atig/command/version.rb +49 -0
- data/lib/atig/command/whois.rb +39 -0
- data/lib/atig/db/db.rb +60 -0
- data/lib/atig/db/followings.rb +131 -0
- data/lib/atig/db/listenable.rb +22 -0
- data/lib/atig/db/lists.rb +76 -0
- data/lib/atig/db/roman.rb +30 -0
- data/lib/atig/db/sized_uniq_array.rb +62 -0
- data/lib/atig/db/sql.rb +35 -0
- data/lib/atig/db/statuses.rb +147 -0
- data/lib/atig/db/transaction.rb +47 -0
- data/lib/atig/exception_util.rb +26 -0
- data/lib/atig/gateway.rb +62 -0
- data/lib/atig/gateway/channel.rb +99 -0
- data/lib/atig/gateway/session.rb +326 -0
- data/lib/atig/http.rb +95 -0
- data/lib/atig/ifilter.rb +7 -0
- data/lib/atig/ifilter/expand_url.rb +74 -0
- data/lib/atig/ifilter/retweet.rb +14 -0
- data/lib/atig/ifilter/retweet_time.rb +16 -0
- data/lib/atig/ifilter/sanitize.rb +18 -0
- data/lib/atig/ifilter/strip.rb +15 -0
- data/lib/atig/ifilter/utf7.rb +26 -0
- data/lib/atig/ifilter/xid.rb +36 -0
- data/lib/atig/levenshtein.rb +49 -0
- data/lib/atig/monkey.rb +4 -0
- data/lib/atig/oauth-patch.rb +40 -0
- data/lib/atig/oauth.rb +55 -0
- data/lib/atig/ofilter.rb +4 -0
- data/lib/atig/ofilter/escape_url.rb +102 -0
- data/lib/atig/ofilter/footer.rb +20 -0
- data/lib/atig/ofilter/geo.rb +17 -0
- data/lib/atig/ofilter/short_url.rb +47 -0
- data/lib/atig/option.rb +90 -0
- data/lib/atig/scheduler.rb +79 -0
- data/lib/atig/search.rb +22 -0
- data/lib/atig/search_twitter.rb +21 -0
- data/lib/atig/sized_hash.rb +33 -0
- data/lib/atig/stream.rb +66 -0
- data/lib/atig/twitter.rb +79 -0
- data/lib/atig/twitter_struct.rb +63 -0
- data/lib/atig/unu.rb +27 -0
- data/lib/atig/update_checker.rb +53 -0
- data/lib/atig/url_escape.rb +62 -0
- data/lib/atig/util.rb +16 -0
- data/lib/atig/version.rb +3 -0
- data/lib/memory_profiler.rb +77 -0
- data/spec/command/autofix_spec.rb +35 -0
- data/spec/command/destroy_spec.rb +98 -0
- data/spec/command/dm_spec.rb +28 -0
- data/spec/command/favorite_spec.rb +55 -0
- data/spec/command/limit_spec.rb +27 -0
- data/spec/command/location_spec.rb +25 -0
- data/spec/command/name_spec.rb +19 -0
- data/spec/command/option_spec.rb +133 -0
- data/spec/command/refresh_spec.rb +22 -0
- data/spec/command/reply_spec.rb +79 -0
- data/spec/command/retweet_spec.rb +66 -0
- data/spec/command/spam_spec.rb +27 -0
- data/spec/command/status_spec.rb +44 -0
- data/spec/command/thread_spec.rb +91 -0
- data/spec/command/time_spec.rb +52 -0
- data/spec/command/uptime_spec.rb +55 -0
- data/spec/command/user_info_spec.rb +42 -0
- data/spec/command/user_spec.rb +50 -0
- data/spec/command/version_spec.rb +67 -0
- data/spec/command/whois_spec.rb +78 -0
- data/spec/db/followings_spec.rb +100 -0
- data/spec/db/listenable_spec.rb +32 -0
- data/spec/db/lists_spec.rb +104 -0
- data/spec/db/roman_spec.rb +17 -0
- data/spec/db/sized_uniq_array_spec.rb +63 -0
- data/spec/db/statuses_spec.rb +180 -0
- data/spec/ifilter/expand_url_spec.rb +44 -0
- data/spec/ifilter/retweet_spec.rb +28 -0
- data/spec/ifilter/retweet_time_spec.rb +25 -0
- data/spec/ifilter/sanitize_spec.rb +25 -0
- data/spec/ifilter/sid_spec.rb +29 -0
- data/spec/ifilter/strip_spec.rb +23 -0
- data/spec/ifilter/tid_spec.rb +29 -0
- data/spec/ifilter/utf7_spec.rb +30 -0
- data/spec/levenshtein_spec.rb +24 -0
- data/spec/ofilter/escape_url_spec.rb +50 -0
- data/spec/ofilter/footer_spec.rb +32 -0
- data/spec/ofilter/geo_spec.rb +33 -0
- data/spec/ofilter/short_url_spec.rb +127 -0
- data/spec/option_spec.rb +91 -0
- data/spec/sized_hash_spec.rb +45 -0
- data/spec/spec_helper.rb +35 -0
- data/spec/update_checker_spec.rb +55 -0
- metadata +326 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# -*- mode:ruby; coding:utf-8 -*-
|
|
2
|
+
require 'forwardable'
|
|
3
|
+
|
|
4
|
+
module Atig
|
|
5
|
+
module Db
|
|
6
|
+
module Listenable
|
|
7
|
+
SingleThread = false
|
|
8
|
+
def listen(&f)
|
|
9
|
+
@listeners ||= []
|
|
10
|
+
@listeners.push f
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
def notify(*args)
|
|
15
|
+
@listeners ||= []
|
|
16
|
+
@listeners.each{|f|
|
|
17
|
+
f.call(*args)
|
|
18
|
+
}
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# -*- mode:ruby; coding:utf-8 -*-
|
|
2
|
+
|
|
3
|
+
require 'atig/db/listenable'
|
|
4
|
+
require 'atig/db/transaction'
|
|
5
|
+
module Atig
|
|
6
|
+
module Db
|
|
7
|
+
class Lists
|
|
8
|
+
include Listenable
|
|
9
|
+
include Transaction
|
|
10
|
+
|
|
11
|
+
def initialize(name)
|
|
12
|
+
@name = name
|
|
13
|
+
@lists = {}
|
|
14
|
+
@on_invalidated = lambda{|*_| }
|
|
15
|
+
@members = nil
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def update(lists)
|
|
19
|
+
@members = Hash.new{|hash,key|
|
|
20
|
+
hash[key] = []
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
(lists.keys - @lists.keys).each do|name|
|
|
24
|
+
list = Followings.new(@name % name)
|
|
25
|
+
list.listen{|kind,users|
|
|
26
|
+
notify kind,name,users
|
|
27
|
+
}
|
|
28
|
+
@lists[name] = list
|
|
29
|
+
notify :new, name
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
(@lists.keys - lists.keys).each do|x|
|
|
33
|
+
@lists.delete x
|
|
34
|
+
notify :del,x
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
lists.each do|name,users|
|
|
38
|
+
@lists[name].update users
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
lists.each do|list, users|
|
|
42
|
+
users.each do|user|
|
|
43
|
+
@members[user.screen_name] << list
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def [](name)
|
|
49
|
+
@lists[name]
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def invalidate(name)
|
|
53
|
+
@on_invalidated.call name
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def on_invalidated(&f)
|
|
57
|
+
@on_invalidated = f
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def find_by_screen_name(name)
|
|
61
|
+
return [] unless @members
|
|
62
|
+
@members[name]
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def find_by_list_name(name)
|
|
66
|
+
@lists[name].users
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def each(&f)
|
|
70
|
+
@lists.each do|name,users|
|
|
71
|
+
f.call name,users.users
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# -*- mode:ruby; coding:utf-8 -*-
|
|
2
|
+
|
|
3
|
+
module Atig
|
|
4
|
+
module Db
|
|
5
|
+
class Roman
|
|
6
|
+
Seq = %w[
|
|
7
|
+
a i u e o ka ki ku ke ko sa shi su se so
|
|
8
|
+
ta chi tsu te to na ni nu ne no ha hi fu he ho
|
|
9
|
+
ma mi mu me mo ya yu yo ra ri ru re ro
|
|
10
|
+
wa wo n
|
|
11
|
+
ga gi gu ge go za ji zu ze zo da de do
|
|
12
|
+
ba bi bu be bo pa pi pu pe po
|
|
13
|
+
kya kyu kyo sha shu sho cha chu cho
|
|
14
|
+
nya nyu nyo hya hyu hyo mya myu myo
|
|
15
|
+
rya ryu ryo
|
|
16
|
+
gya gyu gyo ja ju jo bya byu byo
|
|
17
|
+
pya pyu pyo
|
|
18
|
+
].freeze
|
|
19
|
+
|
|
20
|
+
def make(n)
|
|
21
|
+
ret = []
|
|
22
|
+
begin
|
|
23
|
+
n, r = n.divmod(Seq.size)
|
|
24
|
+
ret << Seq[r]
|
|
25
|
+
end while n > 0
|
|
26
|
+
ret.reverse.join
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# -*- mode:ruby; coding:utf-8 -*-
|
|
2
|
+
|
|
3
|
+
require 'forwardable'
|
|
4
|
+
|
|
5
|
+
module Atig
|
|
6
|
+
module Db
|
|
7
|
+
class SizedUniqArray
|
|
8
|
+
extend Forwardable
|
|
9
|
+
include Enumerable
|
|
10
|
+
def_delegators :@xs,:[]
|
|
11
|
+
|
|
12
|
+
attr_reader :size
|
|
13
|
+
|
|
14
|
+
def initialize(capacity)
|
|
15
|
+
@size = 0
|
|
16
|
+
@index = 0
|
|
17
|
+
@capacity = capacity
|
|
18
|
+
@xs = Array.new(capacity, nil)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def each(&f)
|
|
22
|
+
if @size < @capacity then
|
|
23
|
+
0.upto(@size - 1) {|i|
|
|
24
|
+
f.call @xs[i]
|
|
25
|
+
}
|
|
26
|
+
else
|
|
27
|
+
0.upto(@size - 1){|i|
|
|
28
|
+
f.call @xs[ (i + @index) % @capacity ]
|
|
29
|
+
}
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def reverse_each(&f)
|
|
34
|
+
if @size < @capacity then
|
|
35
|
+
(@size - 1).downto(0) {|i|
|
|
36
|
+
f.call @xs[i]
|
|
37
|
+
}
|
|
38
|
+
else
|
|
39
|
+
(@size - 1).downto(0){|i|
|
|
40
|
+
f.call @xs[ (i + @index) % @capacity ]
|
|
41
|
+
}
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def include?(item)
|
|
46
|
+
self.any?{|x|
|
|
47
|
+
x.id == item.id
|
|
48
|
+
}
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def push(item)
|
|
52
|
+
return nil if include? item
|
|
53
|
+
i = @index
|
|
54
|
+
@xs[i] = item
|
|
55
|
+
@size = [ @size + 1, @capacity ].min
|
|
56
|
+
@index = ( @index + 1 ) % @capacity
|
|
57
|
+
i
|
|
58
|
+
end
|
|
59
|
+
alias_method :<<, :push
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
data/lib/atig/db/sql.rb
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# -*- mode:ruby; coding:utf-8 -*-
|
|
2
|
+
|
|
3
|
+
require 'sqlite3'
|
|
4
|
+
|
|
5
|
+
module Atig
|
|
6
|
+
module Db
|
|
7
|
+
class Sql
|
|
8
|
+
def initialize(name)
|
|
9
|
+
@name = name
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def dump(obj)
|
|
13
|
+
[Marshal.dump(obj)].pack('m')
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def load(text)
|
|
17
|
+
if text == nil then
|
|
18
|
+
nil
|
|
19
|
+
else
|
|
20
|
+
Marshal.load(text.unpack('m').first)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def execute(&f)
|
|
25
|
+
db = SQLite3::Database.new @name
|
|
26
|
+
begin
|
|
27
|
+
res = f.call db
|
|
28
|
+
ensure
|
|
29
|
+
db.close
|
|
30
|
+
end
|
|
31
|
+
res
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# -*- mode:ruby; coding:utf-8 -*-
|
|
2
|
+
require 'atig/db/listenable'
|
|
3
|
+
require 'atig/db/transaction'
|
|
4
|
+
require 'sqlite3'
|
|
5
|
+
require 'atig/db/roman'
|
|
6
|
+
require 'atig/db/sql'
|
|
7
|
+
require 'base64'
|
|
8
|
+
|
|
9
|
+
class OpenStruct
|
|
10
|
+
def id; method_missing(:id) end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
module Atig
|
|
14
|
+
module Db
|
|
15
|
+
class Statuses
|
|
16
|
+
include Listenable
|
|
17
|
+
include Transaction
|
|
18
|
+
|
|
19
|
+
Size = 400
|
|
20
|
+
|
|
21
|
+
def initialize(name)
|
|
22
|
+
@db = Sql.new name
|
|
23
|
+
@roman = Roman.new
|
|
24
|
+
|
|
25
|
+
unless File.exist? name then
|
|
26
|
+
@db.execute do|db|
|
|
27
|
+
db.execute %{create table status (
|
|
28
|
+
id integer primary key,
|
|
29
|
+
status_id text,
|
|
30
|
+
tid text,
|
|
31
|
+
sid text,
|
|
32
|
+
screen_name text,
|
|
33
|
+
user_id text,
|
|
34
|
+
created_at integer,
|
|
35
|
+
data blob);}
|
|
36
|
+
|
|
37
|
+
db.execute %{create table id (
|
|
38
|
+
id integer primary key,
|
|
39
|
+
screen_name text,
|
|
40
|
+
count integer);}
|
|
41
|
+
|
|
42
|
+
# thx to @L_star
|
|
43
|
+
# http://d.hatena.ne.jp/mzp/20100407#c
|
|
44
|
+
db.execute_batch %{
|
|
45
|
+
create index status_createdat on status(created_at);
|
|
46
|
+
create index status_sid on status(sid);
|
|
47
|
+
create index status_statusid on status(status_id);
|
|
48
|
+
create index status_tid on status(tid);
|
|
49
|
+
create index status_userid on status(user_id);
|
|
50
|
+
|
|
51
|
+
create index status_id on status(id);
|
|
52
|
+
create index id_id on id(id);
|
|
53
|
+
}
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def add(opt)
|
|
59
|
+
@db.execute do|db|
|
|
60
|
+
id = opt[:status].id
|
|
61
|
+
return unless db.execute(%{SELECT id FROM status WHERE status_id = ?}, id).empty?
|
|
62
|
+
|
|
63
|
+
screen_name = opt[:user].screen_name
|
|
64
|
+
sum = db.get_first_value("SELECT sum(count) FROM id").to_i
|
|
65
|
+
count = db.get_first_value("SELECT count FROM id WHERE screen_name = ?", screen_name).to_i
|
|
66
|
+
entry = OpenStruct.new opt.merge(:tid => @roman.make(sum),
|
|
67
|
+
:sid => "#{screen_name}:#{@roman.make(count)}")
|
|
68
|
+
db.execute(%{INSERT INTO status
|
|
69
|
+
VALUES(NULL, :id, :tid, :sid, :screen_name, :user_id, :created_at, :data)},
|
|
70
|
+
:id => id,
|
|
71
|
+
:tid => entry.tid,
|
|
72
|
+
:sid => entry.sid,
|
|
73
|
+
:screen_name => screen_name,
|
|
74
|
+
:user_id => opt[:user].id,
|
|
75
|
+
:created_at => Time.parse(opt[:status].created_at).to_i,
|
|
76
|
+
:data => @db.dump(entry))
|
|
77
|
+
if count == 0 then
|
|
78
|
+
db.execute("INSERT INTO id VALUES(NULL,?,?)", screen_name, 1)
|
|
79
|
+
else
|
|
80
|
+
db.execute("UPDATE id SET count = ? WHERE screen_name = ?", count + 1, screen_name)
|
|
81
|
+
end
|
|
82
|
+
notify entry
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def find_all(opt={})
|
|
87
|
+
find '1', 1, opt
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def find_by_screen_name(name, opt={})
|
|
91
|
+
find 'screen_name',name, opt
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def find_by_user(user, opt={})
|
|
95
|
+
find 'user_id', user.id, opt
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def find_by_tid(tid)
|
|
99
|
+
find('tid', tid).first
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def find_by_sid(tid)
|
|
103
|
+
find('sid', tid).first
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def find_by_status_id(id)
|
|
107
|
+
find('status_id', id).first
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def find_by_id(id)
|
|
111
|
+
find('id', id).first
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def remove_by_id(id)
|
|
115
|
+
@db.execute do|db|
|
|
116
|
+
db.execute "DELETE FROM status WHERE id = ?",id
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def cleanup
|
|
121
|
+
@db.execute do|db|
|
|
122
|
+
created_at = db.execute("SELECT created_at FROM status ORDER BY created_at DESC LIMIT 1 OFFSET ?", Size-1)
|
|
123
|
+
unless created_at.empty? then
|
|
124
|
+
db.execute "DELETE FROM status WHERE created_at < ?", created_at.first
|
|
125
|
+
end
|
|
126
|
+
db.execute "VACUUM status"
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
private
|
|
131
|
+
def find(lhs,rhs, opt={},&f)
|
|
132
|
+
query = "SELECT id,data FROM status WHERE #{lhs} = :rhs ORDER BY created_at DESC LIMIT :limit"
|
|
133
|
+
params = { :rhs => rhs, :limit => opt.fetch(:limit,20) }
|
|
134
|
+
res = []
|
|
135
|
+
|
|
136
|
+
@db.execute do|db|
|
|
137
|
+
db.execute(query,params) do|id,data,*_|
|
|
138
|
+
e = @db.load(data)
|
|
139
|
+
e.id = id.to_i
|
|
140
|
+
res << e
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
res
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# -*- mode:ruby; coding:utf-8 -*-
|
|
2
|
+
require 'timeout'
|
|
3
|
+
require 'atig/util'
|
|
4
|
+
|
|
5
|
+
module Atig
|
|
6
|
+
module Db
|
|
7
|
+
module Transaction
|
|
8
|
+
include Util
|
|
9
|
+
|
|
10
|
+
def init
|
|
11
|
+
return if @queue
|
|
12
|
+
|
|
13
|
+
debug "transaction thread start"
|
|
14
|
+
@queue = SizedQueue.new 10
|
|
15
|
+
daemon do
|
|
16
|
+
f,src = @queue.pop
|
|
17
|
+
debug "transaction is poped at #{src}"
|
|
18
|
+
|
|
19
|
+
if respond_to?(:timeout_interval) && timeout_interval > 0 then
|
|
20
|
+
begin
|
|
21
|
+
timeout(timeout_interval){ f.call self }
|
|
22
|
+
rescue TimeoutError
|
|
23
|
+
debug "transaction is timeout at #{src}"
|
|
24
|
+
end
|
|
25
|
+
else
|
|
26
|
+
f.call self
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
debug "transaction is finished at #{src}"
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def transaction(&f)
|
|
34
|
+
init
|
|
35
|
+
|
|
36
|
+
debug "transaction is registered"
|
|
37
|
+
@queue.push [ f, caller.first ]
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def debug(s)
|
|
41
|
+
if respond_to? :log
|
|
42
|
+
log :debug, s
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# -*- mode:ruby; coding:utf-8 -*-
|
|
2
|
+
|
|
3
|
+
module Atig
|
|
4
|
+
module ExceptionUtil
|
|
5
|
+
def safe(&f)
|
|
6
|
+
begin
|
|
7
|
+
f.call
|
|
8
|
+
rescue Exception => e
|
|
9
|
+
s = e.inspect + "\n"
|
|
10
|
+
e.backtrace.each do |l|
|
|
11
|
+
s += "\t#{l}\n"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
log :error,s
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def daemon(&f)
|
|
19
|
+
Thread.new do
|
|
20
|
+
loop{ safe { f.call }}
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
module_function :safe,:daemon
|
|
25
|
+
end
|
|
26
|
+
end
|