draftcode-termtter 1.0.8
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/History.txt +4 -0
- data/README.rdoc +100 -0
- data/Rakefile +55 -0
- data/bin/kill_termtter +22 -0
- data/bin/termtter +6 -0
- data/lib/plugins/addspace.rb +27 -0
- data/lib/plugins/april_fool.rb +15 -0
- data/lib/plugins/bomb.rb +39 -0
- data/lib/plugins/clear.rb +14 -0
- data/lib/plugins/command_plus.rb +47 -0
- data/lib/plugins/confirm.rb +33 -0
- data/lib/plugins/cool.rb +10 -0
- data/lib/plugins/countter.rb +23 -0
- data/lib/plugins/devel.rb +18 -0
- data/lib/plugins/direct_messages.rb +36 -0
- data/lib/plugins/en2ja.rb +11 -0
- data/lib/plugins/english.rb +25 -0
- data/lib/plugins/erb.rb +17 -0
- data/lib/plugins/exec.rb +17 -0
- data/lib/plugins/exec_and_update.rb +14 -0
- data/lib/plugins/expand-tinyurl.rb +34 -0
- data/lib/plugins/fib.rb +28 -0
- data/lib/plugins/fib_filter.rb +14 -0
- data/lib/plugins/filter.rb +69 -0
- data/lib/plugins/graduatter.rb +8 -0
- data/lib/plugins/grass.rb +27 -0
- data/lib/plugins/group.rb +64 -0
- data/lib/plugins/growl.rb +52 -0
- data/lib/plugins/growl2.rb +143 -0
- data/lib/plugins/hatebu.rb +59 -0
- data/lib/plugins/hatebu_and_update.rb +58 -0
- data/lib/plugins/history.rb +93 -0
- data/lib/plugins/ignore.rb +19 -0
- data/lib/plugins/keyword.rb +18 -0
- data/lib/plugins/l2.rb +25 -0
- data/lib/plugins/log.rb +73 -0
- data/lib/plugins/me.rb +10 -0
- data/lib/plugins/modify_arg_hook_sample.rb +7 -0
- data/lib/plugins/msagent.rb +38 -0
- data/lib/plugins/multi_reply.rb +27 -0
- data/lib/plugins/notify-send.rb +22 -0
- data/lib/plugins/notify-send2.rb +52 -0
- data/lib/plugins/notify-send3.rb +45 -0
- data/lib/plugins/open_url.rb +59 -0
- data/lib/plugins/otsune.rb +21 -0
- data/lib/plugins/outputz.rb +33 -0
- data/lib/plugins/pause.rb +3 -0
- data/lib/plugins/post_exec_hook_sample.rb +9 -0
- data/lib/plugins/pre_exec_hook_sample.rb +9 -0
- data/lib/plugins/primes.rb +30 -0
- data/lib/plugins/quicklook.rb +41 -0
- data/lib/plugins/random.rb +23 -0
- data/lib/plugins/reblog.rb +40 -0
- data/lib/plugins/reload.rb +3 -0
- data/lib/plugins/reply.rb +8 -0
- data/lib/plugins/retweet.rb +46 -0
- data/lib/plugins/reverse.rb +13 -0
- data/lib/plugins/say.rb +26 -0
- data/lib/plugins/scrape.rb +41 -0
- data/lib/plugins/screen-notify.rb +20 -0
- data/lib/plugins/screen.rb +24 -0
- data/lib/plugins/shell.rb +14 -0
- data/lib/plugins/sl.rb +48 -0
- data/lib/plugins/spam.rb +16 -0
- data/lib/plugins/standard_plugins.rb +525 -0
- data/lib/plugins/stdout.rb +220 -0
- data/lib/plugins/storage.rb +55 -0
- data/lib/plugins/storage/DB.rb +37 -0
- data/lib/plugins/storage/status.rb +83 -0
- data/lib/plugins/storage/status_mook.rb +30 -0
- data/lib/plugins/switch_user.rb +22 -0
- data/lib/plugins/system_status.rb +33 -0
- data/lib/plugins/timer.rb +18 -0
- data/lib/plugins/tinyurl.rb +20 -0
- data/lib/plugins/translation.rb +38 -0
- data/lib/plugins/typable_id.rb +94 -0
- data/lib/plugins/update_editor.rb +53 -0
- data/lib/plugins/uri-open.rb +66 -0
- data/lib/plugins/wassr_post.rb +22 -0
- data/lib/plugins/yhara.rb +148 -0
- data/lib/plugins/yhara_filter.rb +8 -0
- data/lib/plugins/yonda.rb +21 -0
- data/lib/termtter.rb +38 -0
- data/lib/termtter/api.rb +57 -0
- data/lib/termtter/client.rb +324 -0
- data/lib/termtter/command.rb +80 -0
- data/lib/termtter/config.rb +68 -0
- data/lib/termtter/config_setup.rb +38 -0
- data/lib/termtter/connection.rb +41 -0
- data/lib/termtter/hook.rb +31 -0
- data/lib/termtter/optparse.rb +14 -0
- data/lib/termtter/system_extensions.rb +115 -0
- data/lib/termtter/task.rb +17 -0
- data/lib/termtter/task_manager.rb +116 -0
- data/lib/termtter/version.rb +4 -0
- data/spec/plugins/cool_spec.rb +10 -0
- data/spec/plugins/english_spec.rb +19 -0
- data/spec/plugins/fib_spec.rb +15 -0
- data/spec/plugins/filter_spec.rb +18 -0
- data/spec/plugins/pause_spec.rb +8 -0
- data/spec/plugins/primes_spec.rb +15 -0
- data/spec/plugins/shell_spec.rb +10 -0
- data/spec/plugins/sl_spec.rb +8 -0
- data/spec/plugins/spam_spec.rb +4 -0
- data/spec/plugins/standard_plugins_spec.rb +23 -0
- data/spec/plugins/storage/DB_spec.rb +12 -0
- data/spec/plugins/storage/status_spec.rb +24 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/termtter/client_spec.rb +255 -0
- data/spec/termtter/command_spec.rb +107 -0
- data/spec/termtter/config_spec.rb +111 -0
- data/spec/termtter/hook_spec.rb +78 -0
- data/spec/termtter/task_manager_spec.rb +78 -0
- data/spec/termtter/task_spec.rb +22 -0
- data/spec/termtter_spec.rb +29 -0
- data/test/friends_timeline.json +5 -0
- data/test/search.json +8 -0
- metadata +211 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
require 'termcolor'
|
|
4
|
+
require 'erb'
|
|
5
|
+
require 'tempfile'
|
|
6
|
+
require 'curses'
|
|
7
|
+
require 'dl/import'
|
|
8
|
+
|
|
9
|
+
module Readline
|
|
10
|
+
begin
|
|
11
|
+
module LIBREADLINE
|
|
12
|
+
if DL.const_defined? :Importable
|
|
13
|
+
extend DL::Importable
|
|
14
|
+
else
|
|
15
|
+
extend DL::Importer
|
|
16
|
+
end
|
|
17
|
+
pathes = Array(ENV['TERMTTER_EXT_LIB'] || [
|
|
18
|
+
'/opt/local/lib/libreadline.dylib',
|
|
19
|
+
'/usr/lib/libreadline.so',
|
|
20
|
+
'/usr/local/lib/libreadline.so',
|
|
21
|
+
File.join(Gem.bindir, 'readline.dll')
|
|
22
|
+
])
|
|
23
|
+
dlload(pathes.find { |path| File.exist?(path)})
|
|
24
|
+
extern 'int rl_refresh_line(int, int)'
|
|
25
|
+
end
|
|
26
|
+
def self.refresh_line
|
|
27
|
+
LIBREADLINE.rl_refresh_line(0, 0)
|
|
28
|
+
end
|
|
29
|
+
rescue Exception
|
|
30
|
+
def self.refresh_line;end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
if win?
|
|
35
|
+
require 'iconv'
|
|
36
|
+
|
|
37
|
+
module Readline
|
|
38
|
+
$iconv_sj_to_u8 = Iconv.new('UTF-8', "CP#{$wGetACP.call()}")
|
|
39
|
+
alias :old_readline :readline
|
|
40
|
+
def readline(*a)
|
|
41
|
+
str = old_readline(*a)
|
|
42
|
+
out = ''
|
|
43
|
+
loop do
|
|
44
|
+
begin
|
|
45
|
+
out << $iconv_sj_to_u8.iconv(str)
|
|
46
|
+
break
|
|
47
|
+
rescue Iconv::Failure
|
|
48
|
+
out << "#{$!.success}?"
|
|
49
|
+
str = $!.failed[1..-1]
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
return out
|
|
53
|
+
end
|
|
54
|
+
module_function :old_readline, :readline
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
config.plugins.stdout.set_default(
|
|
59
|
+
:colors,
|
|
60
|
+
[:none, :red, :green, :yellow, :blue, :magenta, :cyan])
|
|
61
|
+
config.plugins.stdout.set_default(
|
|
62
|
+
:timeline_format,
|
|
63
|
+
'<90><%=time%></90> <<%=status_color%>><%=status%></<%=status_color%>> <90><%=id%></90>')
|
|
64
|
+
config.plugins.stdout.set_default(:search_highlight_format, '<on_magenta><white>\1</white></on_magenta>')
|
|
65
|
+
|
|
66
|
+
config.plugins.stdout.set_default(:enable_pager, true)
|
|
67
|
+
config.plugins.stdout.set_default(:pager, 'less -R -f +G')
|
|
68
|
+
config.plugins.stdout.set_default(:window_height, 50)
|
|
69
|
+
|
|
70
|
+
class String
|
|
71
|
+
def truncate_column(col)
|
|
72
|
+
count = 0
|
|
73
|
+
ary = []
|
|
74
|
+
ret = []
|
|
75
|
+
self.split(//u).each {|c|
|
|
76
|
+
count += (c.size == 1 ? 1 : 2)
|
|
77
|
+
if count > col then
|
|
78
|
+
ret.push(ary.to_s)
|
|
79
|
+
ary = []
|
|
80
|
+
count = 0
|
|
81
|
+
end
|
|
82
|
+
ary.push(c)
|
|
83
|
+
}
|
|
84
|
+
ret.push(ary.to_s) unless ary.empty?
|
|
85
|
+
ret
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
module Termtter
|
|
90
|
+
class StdOut < Hook
|
|
91
|
+
def initialize
|
|
92
|
+
super(:name => :stdout, :points => [:output])
|
|
93
|
+
@input_thread = nil
|
|
94
|
+
Client.register_hook(
|
|
95
|
+
:name => :stdout_exit,
|
|
96
|
+
:points => [:exit],
|
|
97
|
+
:exec_proc => lambda { @input_thread.kill if @input_thread }
|
|
98
|
+
)
|
|
99
|
+
Client.register_hook(
|
|
100
|
+
:name => :stdout_readline_yield_thread,
|
|
101
|
+
:points => [:before_task_thread_run],
|
|
102
|
+
:exec_proc => lambda { start_input_thread() unless @input_thread }
|
|
103
|
+
)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def call(statuses, event)
|
|
107
|
+
print_statuses(statuses)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def trap_setting()
|
|
111
|
+
begin
|
|
112
|
+
stty_save = `stty -g`.chomp
|
|
113
|
+
trap("INT") do
|
|
114
|
+
begin
|
|
115
|
+
system "stty", stty_save
|
|
116
|
+
ensure
|
|
117
|
+
exit
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
rescue Errno::ENOENT
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def setup_readline
|
|
125
|
+
if Readline.respond_to?(:basic_word_break_characters=)
|
|
126
|
+
Readline.basic_word_break_characters= "\t\n\"\\'`><=;|&{("
|
|
127
|
+
end
|
|
128
|
+
Readline.completion_proc = Client.get_command_completion_proc()
|
|
129
|
+
vi_or_emacs = config.editing_mod
|
|
130
|
+
unless vi_or_emacs.empty?
|
|
131
|
+
Readline.__send__("#{vi_or_emacs}_editing_mode")
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def start_input_thread
|
|
136
|
+
setup_readline()
|
|
137
|
+
trap_setting()
|
|
138
|
+
@input_thread = Thread.new do
|
|
139
|
+
while buf = Readline.readline(ERB.new(config.prompt).result(API.twitter.__send__(:binding)), true)
|
|
140
|
+
Readline::HISTORY.pop if buf.empty?
|
|
141
|
+
begin
|
|
142
|
+
Client.call_commands(buf)
|
|
143
|
+
rescue CommandNotFound => e
|
|
144
|
+
warn "Unknown command \"#{e}\""
|
|
145
|
+
warn 'Enter "help" for instructions'
|
|
146
|
+
rescue => e
|
|
147
|
+
Client.handle_error e
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
@input_thread.join
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def print_statuses(statuses, sort = true, time_format = nil)
|
|
155
|
+
return unless statuses and statuses.first
|
|
156
|
+
unless time_format
|
|
157
|
+
t0 = Time.now
|
|
158
|
+
t1 = Time.parse(statuses.first[:created_at])
|
|
159
|
+
t2 = Time.parse(statuses.last[:created_at])
|
|
160
|
+
time_format =
|
|
161
|
+
if [t0.year, t0.month, t0.day] == [t1.year, t1.month, t1.day] \
|
|
162
|
+
and [t1.year, t1.month, t1.day] == [t2.year, t2.month, t2.day]
|
|
163
|
+
'%H:%M:%S'
|
|
164
|
+
else
|
|
165
|
+
'%y/%m/%d %H:%M'
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
output_text = ''
|
|
170
|
+
output_text += "\e[1K\e[0G" unless win?
|
|
171
|
+
Curses::init_screen;
|
|
172
|
+
cols = Curses.cols;
|
|
173
|
+
Curses::close_screen
|
|
174
|
+
statuses.each do |s|
|
|
175
|
+
text = s.text
|
|
176
|
+
status_color = config.plugins.stdout.colors[s.user.id.hash % config.plugins.stdout.colors.size]
|
|
177
|
+
status = "#{s.user.screen_name}: #{TermColor.escape(text)}"
|
|
178
|
+
if s.in_reply_to_status_id
|
|
179
|
+
status += " (reply to #{s.in_reply_to_status_id})"
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
time = "(#{Time.parse(s.created_at).strftime(time_format)})"
|
|
183
|
+
id = s.id
|
|
184
|
+
len = id.to_s.length + 2
|
|
185
|
+
if cols > 0 then
|
|
186
|
+
status = status.truncate_column(cols-len-1).join( "\n" )
|
|
187
|
+
status = status.gsub( /\n/, "\n".ljust(len) )
|
|
188
|
+
end
|
|
189
|
+
source =
|
|
190
|
+
case s.source
|
|
191
|
+
when />(.*?)</ then $1
|
|
192
|
+
when 'web' then 'web'
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
erbed_text = ERB.new(config.plugins.stdout.timeline_format).result(binding)
|
|
196
|
+
output_text << TermColor.parse(erbed_text) + "\n"
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
if config.plugins.stdout.enable_pager && ENV['LINES'] && statuses.size > ENV['LINES'].to_i
|
|
200
|
+
file = Tempfile.new('termtter')
|
|
201
|
+
file.print output_text
|
|
202
|
+
file.close
|
|
203
|
+
system "#{config.plugins.stdout.pager} #{file.path}"
|
|
204
|
+
file.close(true)
|
|
205
|
+
else
|
|
206
|
+
output_text << TermColor.parse("<90>-----Fetched on " + Time.now.strftime(time_format) + "</90>\n")
|
|
207
|
+
print output_text
|
|
208
|
+
end
|
|
209
|
+
Readline.refresh_line
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
Client.register_hook(StdOut.new)
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
# stdout.rb
|
|
217
|
+
# output statuses to stdout
|
|
218
|
+
# example config
|
|
219
|
+
# config.plugins.stdout.colors = [:none, :red, :green, :yellow, :blue, :magenta, :cyan]
|
|
220
|
+
# config.plugins.stdout.timeline_format = '<90><%=time%></90> <<%=status_color%>><%=status%></<%=status_color%>> <90><%=id%></90>'
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
require 'pp'
|
|
4
|
+
require 'time'
|
|
5
|
+
|
|
6
|
+
require File.dirname(__FILE__) + '/storage/status'
|
|
7
|
+
|
|
8
|
+
module Termtter::Client
|
|
9
|
+
public_storage[:log] = []
|
|
10
|
+
|
|
11
|
+
register_hook(
|
|
12
|
+
:name => :storage,
|
|
13
|
+
:points => [:pre_filter],
|
|
14
|
+
:exec_proc => lambda {|statuses, event|
|
|
15
|
+
statuses.each do |s|
|
|
16
|
+
Termtter::Storage::Status.insert(
|
|
17
|
+
:post_id => s.id,
|
|
18
|
+
:created_at => Time.parse(s.created_at).to_i,
|
|
19
|
+
:in_reply_to_status_id => s.in_reply_to_status_id,
|
|
20
|
+
:in_reply_to_user_id => s.in_reply_to_user_id,
|
|
21
|
+
:text => s.text,
|
|
22
|
+
:user_id => s.user.id,
|
|
23
|
+
:screen_name => s.user.screen_name
|
|
24
|
+
)
|
|
25
|
+
end
|
|
26
|
+
}
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
register_command(
|
|
30
|
+
:name => :search_storage,
|
|
31
|
+
:aliases => [:ss],
|
|
32
|
+
:exec_proc => lambda {|arg|
|
|
33
|
+
unless arg.strip.empty?
|
|
34
|
+
key = arg.strip
|
|
35
|
+
statuses = Termtter::Storage::Status.search({:text => key})
|
|
36
|
+
output(statuses, :search)
|
|
37
|
+
end
|
|
38
|
+
},
|
|
39
|
+
:help => [ 'search_storage WORD', 'Search storage for WORD' ]
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
register_command(
|
|
43
|
+
:name => :search_storage_user,
|
|
44
|
+
:aliases => [:ssu],
|
|
45
|
+
:exec_proc => lambda {|arg|
|
|
46
|
+
unless arg.strip.empty?
|
|
47
|
+
key = arg.strip
|
|
48
|
+
statuses = Termtter::Storage::Status.search_user({:user => key})
|
|
49
|
+
output(statuses, :search)
|
|
50
|
+
end
|
|
51
|
+
},
|
|
52
|
+
:help => [ 'search_storage_user SCREEN_NAME', 'Search storage for SCREE_NAME' ]
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
require 'sqlite3'
|
|
4
|
+
require 'singleton'
|
|
5
|
+
|
|
6
|
+
module Termtter::Storage
|
|
7
|
+
class DB
|
|
8
|
+
include Singleton
|
|
9
|
+
attr_reader :db
|
|
10
|
+
|
|
11
|
+
def initialize
|
|
12
|
+
@db = SQLite3::Database.new(Termtter::CONF_DIR + '/storage.db')
|
|
13
|
+
@db.type_translation = true
|
|
14
|
+
create_table
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def create_table
|
|
18
|
+
sql =<<-SQL
|
|
19
|
+
CREATE TABLE IF NOT EXISTS user (
|
|
20
|
+
id int NOT NULL,
|
|
21
|
+
screen_name text,
|
|
22
|
+
PRIMARY KEY (id)
|
|
23
|
+
);
|
|
24
|
+
CREATE TABLE IF NOT EXISTS post (
|
|
25
|
+
post_id int NOT NULL, -- twitter側のpostのid
|
|
26
|
+
created_at int, -- 日付(RubyでUNIX時間に変換)
|
|
27
|
+
in_reply_to_status_id int, -- あったほうがよいらしい
|
|
28
|
+
in_reply_to_user_id int, -- あったほうがよいらしい
|
|
29
|
+
post_text text,
|
|
30
|
+
user_id int NOT NULL,
|
|
31
|
+
PRIMARY KEY (post_id)
|
|
32
|
+
);
|
|
33
|
+
SQL
|
|
34
|
+
@db.execute_batch(sql)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
require File.dirname(__FILE__) + '/DB'
|
|
4
|
+
require 'sqlite3'
|
|
5
|
+
|
|
6
|
+
module Termtter::Storage
|
|
7
|
+
class Status
|
|
8
|
+
KEYS = %w[post_id created_at in_reply_to_status_id in_reply_to_user_id post_text user_id screen_name]
|
|
9
|
+
|
|
10
|
+
def self.size
|
|
11
|
+
DB.instance.db.get_first_value("select count(*) from post").to_i
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.search(query)
|
|
15
|
+
raise "query must be Hash(#{query}, #{query.class})" unless query.kind_of? Hash
|
|
16
|
+
if query[:text] == nil then
|
|
17
|
+
query[:text] = '';
|
|
18
|
+
end
|
|
19
|
+
if query[:user] == nil then
|
|
20
|
+
query[:user] = '';
|
|
21
|
+
end
|
|
22
|
+
result = []
|
|
23
|
+
sql = "select created_at, screen_name, post_text, in_reply_to_status_id, post_id, user_id "
|
|
24
|
+
sql += "from post inner join user on post.user_id = user.id where post_text like '%' || ? || '%'"
|
|
25
|
+
DB.instance.db.execute(sql,
|
|
26
|
+
query[:text]) do |created_at, screen_name, post_text, in_reply_to_status_id, post_id, user_id|
|
|
27
|
+
created_at = Time.at(created_at).to_s
|
|
28
|
+
result << {
|
|
29
|
+
:id => post_id,
|
|
30
|
+
:created_at => created_at,
|
|
31
|
+
:text => post_text,
|
|
32
|
+
:in_reply_to_status_id => in_reply_to_status_id,
|
|
33
|
+
:in_reply_to_user_id => nil,
|
|
34
|
+
:user => {
|
|
35
|
+
:id => user_id,
|
|
36
|
+
:screen_name => screen_name
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
end
|
|
40
|
+
Rubytter.json_to_struct(result)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def self.search_user(query)
|
|
44
|
+
raise "query must be Hash(#{query}, #{query.class})" unless query.kind_of? Hash
|
|
45
|
+
result = []
|
|
46
|
+
sql = "select created_at, screen_name, post_text, in_reply_to_status_id, post_id, user_id "
|
|
47
|
+
sql += "from post inner join user on post.user_id = user.id where "
|
|
48
|
+
sql += query[:user].split(' ').map!{|que| que.gsub(/(\w+)/, 'screen_name like \'%\1%\'')}.join(' or ')
|
|
49
|
+
DB.instance.db.execute(sql) do |created_at, screen_name, post_text, in_reply_to_status_id, post_id, user_id|
|
|
50
|
+
created_at = Time.at(created_at).to_s
|
|
51
|
+
result << {
|
|
52
|
+
:id => post_id,
|
|
53
|
+
:created_at => created_at,
|
|
54
|
+
:text => post_text,
|
|
55
|
+
:in_reply_to_status_id => in_reply_to_status_id,
|
|
56
|
+
:in_reply_to_user_id => nil,
|
|
57
|
+
:user => {
|
|
58
|
+
:id => user_id,
|
|
59
|
+
:screen_name => screen_name
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
end
|
|
63
|
+
Rubytter.json_to_struct(result)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def self.insert(data)
|
|
67
|
+
return unless data[:text]
|
|
68
|
+
DB.instance.db.execute(
|
|
69
|
+
"insert into post values(?,?,?,?,?,?)",
|
|
70
|
+
data[:post_id],
|
|
71
|
+
data[:created_at],
|
|
72
|
+
data[:in_reply_to_status_id],
|
|
73
|
+
data[:in_reply_to_user_id],
|
|
74
|
+
data[:text],
|
|
75
|
+
data[:user_id])
|
|
76
|
+
DB.instance.db.execute(
|
|
77
|
+
"insert into user values(?,?)",
|
|
78
|
+
data[:user_id],
|
|
79
|
+
data[:screen_name])
|
|
80
|
+
rescue SQLite3::SQLException
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
require 'sqlite3'
|
|
4
|
+
|
|
5
|
+
module Termtter::Storage
|
|
6
|
+
class Status
|
|
7
|
+
def initialize
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.create
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.all
|
|
14
|
+
[]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.search
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
def db
|
|
22
|
+
@db ||= connect
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def connect
|
|
26
|
+
@db = SQLite3::Database.new(File.expand_path('~/test.db'))
|
|
27
|
+
@db.type_translation = true
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
module Termtter::Client
|
|
4
|
+
register_command(
|
|
5
|
+
:name => :switch_user,
|
|
6
|
+
:exec_proc => lambda {|arg|
|
|
7
|
+
Termtter::API.switch_user(arg)
|
|
8
|
+
},
|
|
9
|
+
:completion_proc => lambda {|cmd, arg|
|
|
10
|
+
# TODO
|
|
11
|
+
},
|
|
12
|
+
:help => ["switch_user USERNAME", "Switch twitter account."]
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
register_command(
|
|
16
|
+
:name => :restore_user,
|
|
17
|
+
:exec_proc => lambda {|arg|
|
|
18
|
+
Termtter::API.restore_user
|
|
19
|
+
},
|
|
20
|
+
:help => ["restore_user", "Restore default twitter account."]
|
|
21
|
+
)
|
|
22
|
+
end
|