rbitter 0.2.0-java → 0.2.1-java
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.
- checksums.yaml +4 -4
- data/.gitignore +23 -22
- data/.rspec +2 -2
- data/.travis.yml +15 -15
- data/Gemfile +12 -12
- data/LICENSE.txt +22 -22
- data/Rakefile +8 -8
- data/bin/rbitter +20 -20
- data/lib/rbitter/arcserver.rb +169 -165
- data/lib/rbitter/console.rb +93 -93
- data/lib/rbitter/default/config_json.rb +41 -41
- data/lib/rbitter/dlthread.rb +62 -62
- data/lib/rbitter/env.rb +116 -116
- data/lib/rbitter/override/gems/rubysl-socket/socket.rb +8 -8
- data/lib/rbitter/override/gems/twitter/connection.rb +45 -45
- data/lib/rbitter/override.rb +47 -47
- data/lib/rbitter/progress.rb +23 -0
- data/lib/rbitter/records.rb +127 -127
- data/lib/rbitter/records_migrate/20150327_add_index.rb +11 -11
- data/lib/rbitter/records_migrate/20150504_add_replyto_column.rb +11 -11
- data/lib/rbitter/streaming.rb +104 -104
- data/lib/rbitter/version.rb +20 -20
- data/lib/rbitter/xmlrpc.rb +3 -3
- data/lib/rbitter/xmlrpcd/base.rb +24 -24
- data/lib/rbitter/xmlrpcd/rpchandles.rb +11 -11
- data/lib/rbitter/xmlrpcd/xmlrpc_auth_server.rb +82 -82
- data/lib/rbitter/xmlrpcd/xmlrpcd.rb +69 -69
- data/lib/rbitter.rb +62 -62
- data/rbitter.gemspec +46 -46
- data/spec/config/default.json +32 -32
- data/spec/rbitter/arcserver_spec.rb +30 -30
- data/spec/rbitter/console_spec.rb +9 -9
- data/spec/rbitter/default/config_json_spec.rb +3 -3
- data/spec/rbitter/dlthread_spec.rb +8 -8
- data/spec/rbitter/env_spec.rb +76 -76
- data/spec/rbitter/override/gems/twitter/connection_spec.rb +8 -8
- data/spec/rbitter/progress_spec.rb +1 -0
- data/spec/rbitter/records_spec.rb +13 -13
- data/spec/rbitter/streaming_spec.rb +9 -9
- data/spec/rbitter/version_spec.rb +8 -8
- data/spec/rbitter/xmlrpc_spec.rb +8 -8
- data/spec/rbitter/xmlrpcd/base_spec.rb +29 -29
- data/spec/rbitter/xmlrpcd/rpchandles_spec.rb +10 -10
- data/spec/rbitter/xmlrpcd/xmlrpc_auth_server_spec.rb +8 -8
- data/spec/rbitter/xmlrpcd/xmlrpcd_spec.rb +9 -9
- data/spec/rbitter_spec.rb +38 -38
- data/spec/spec_helper.rb +39 -39
- metadata +6 -3
@@ -1,46 +1,46 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'http/parser'
|
4
|
-
require 'openssl'
|
5
|
-
require 'resolv'
|
6
|
-
|
7
|
-
module Twitter
|
8
|
-
module Streaming
|
9
|
-
class Connection
|
10
|
-
MODIFIED = true
|
11
|
-
attr_reader :tcp_socket_class, :ssl_socket_class
|
12
|
-
|
13
|
-
def initialize(options = {})
|
14
|
-
@tcp_socket_class = options.fetch(:tcp_socket_class) { TCPSocket }
|
15
|
-
@ssl_socket_class = options.fetch(:ssl_socket_class) { OpenSSL::SSL::SSLSocket }
|
16
|
-
end
|
17
|
-
|
18
|
-
def stream(request, response)
|
19
|
-
client_context = OpenSSL::SSL::SSLContext.new
|
20
|
-
client = @tcp_socket_class.new(Resolv.getaddress(request.uri.host), request.uri.port)
|
21
|
-
ssl_client = @ssl_socket_class.new(client, client_context)
|
22
|
-
ssl_client.connect
|
23
|
-
request.stream(ssl_client)
|
24
|
-
|
25
|
-
loop {
|
26
|
-
begin
|
27
|
-
body = ssl_client.read_nonblock(1024) # rubocop:disable AssignmentInCondition, WhileUntilModifier
|
28
|
-
response << body
|
29
|
-
rescue IO::WaitReadable
|
30
|
-
# The reason for setting 90 seconds as a timeout is documented on:
|
31
|
-
# https://dev.twitter.com/streaming/overview/connecting
|
32
|
-
r, w, e = IO.select([ssl_client], [], [], 90)
|
33
|
-
if r.nil?
|
34
|
-
# If timeout occurs
|
35
|
-
ssl_client.close
|
36
|
-
raise Twitter::Error::ServerError.new("Connection stalled")
|
37
|
-
else
|
38
|
-
# If socket is readable
|
39
|
-
retry
|
40
|
-
end
|
41
|
-
end
|
42
|
-
}
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'http/parser'
|
4
|
+
require 'openssl'
|
5
|
+
require 'resolv'
|
6
|
+
|
7
|
+
module Twitter
|
8
|
+
module Streaming
|
9
|
+
class Connection
|
10
|
+
MODIFIED = true
|
11
|
+
attr_reader :tcp_socket_class, :ssl_socket_class
|
12
|
+
|
13
|
+
def initialize(options = {})
|
14
|
+
@tcp_socket_class = options.fetch(:tcp_socket_class) { TCPSocket }
|
15
|
+
@ssl_socket_class = options.fetch(:ssl_socket_class) { OpenSSL::SSL::SSLSocket }
|
16
|
+
end
|
17
|
+
|
18
|
+
def stream(request, response)
|
19
|
+
client_context = OpenSSL::SSL::SSLContext.new
|
20
|
+
client = @tcp_socket_class.new(Resolv.getaddress(request.uri.host), request.uri.port)
|
21
|
+
ssl_client = @ssl_socket_class.new(client, client_context)
|
22
|
+
ssl_client.connect
|
23
|
+
request.stream(ssl_client)
|
24
|
+
|
25
|
+
loop {
|
26
|
+
begin
|
27
|
+
body = ssl_client.read_nonblock(1024) # rubocop:disable AssignmentInCondition, WhileUntilModifier
|
28
|
+
response << body
|
29
|
+
rescue IO::WaitReadable
|
30
|
+
# The reason for setting 90 seconds as a timeout is documented on:
|
31
|
+
# https://dev.twitter.com/streaming/overview/connecting
|
32
|
+
r, w, e = IO.select([ssl_client], [], [], 90)
|
33
|
+
if r.nil?
|
34
|
+
# If timeout occurs
|
35
|
+
ssl_client.close
|
36
|
+
raise Twitter::Error::ServerError.new("Connection stalled")
|
37
|
+
else
|
38
|
+
# If socket is readable
|
39
|
+
retry
|
40
|
+
end
|
41
|
+
end
|
42
|
+
}
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
46
|
end
|
data/lib/rbitter/override.rb
CHANGED
@@ -1,47 +1,47 @@
|
|
1
|
-
=begin
|
2
|
-
This module gives special workarounds for some issues.
|
3
|
-
|
4
|
-
Problems are bypassed by monkey-patching.
|
5
|
-
|
6
|
-
As soon as a problem is resolved, patch should be removed.
|
7
|
-
|
8
|
-
**** Known issues ****
|
9
|
-
|
10
|
-
1. gem/twitter
|
11
|
-
Location : override/gem/twitter/connection.rb
|
12
|
-
Maintain : until below issue is fixed
|
13
|
-
Reference: https://github.com/sferik/twitter/pull/669
|
14
|
-
|
15
|
-
Gem 'twitter' does not handle streaming timeout. By applying this,
|
16
|
-
reading timeout works and Rbitter can handle timeouts.
|
17
|
-
|
18
|
-
2. gem/rubysl-socket
|
19
|
-
Location : override/gem/rubysl-socket/socket.rb
|
20
|
-
Maintain : until ip_address_list is implemented
|
21
|
-
Reference: https://github.com/rubysl/rubysl-socket/pull/9
|
22
|
-
|
23
|
-
With ipv6 environment, Resolv#use_ipv6? (in rubysl-resolv gem) checks
|
24
|
-
Socket.ip_address_list. This is not implemented at all with rubysl-socket-2.0.1.
|
25
|
-
NoMethodError exception is raised instead of NotImplementedError.
|
26
|
-
|
27
|
-
By applying this, Socket.ip_address_list is implemented and the method throws
|
28
|
-
NotImplementedError exception.
|
29
|
-
|
30
|
-
=end
|
31
|
-
|
32
|
-
def gem_twitter_patcher
|
33
|
-
require 'rbitter/override/gems/twitter/connection'
|
34
|
-
end
|
35
|
-
|
36
|
-
if Twitter::Version.const_defined?(:MAJOR)
|
37
|
-
b5_version = Twitter::Version::MAJOR * 10000
|
38
|
-
+ Twitter::Version::MINOR * 100 + Twitter::Version::PATCH
|
39
|
-
gem_twitter_patcher if b5_version <= 51400
|
40
|
-
else
|
41
|
-
b6_version = Twitter::Version.to_a
|
42
|
-
if b6_version[0] <= 6 and b6_version[1] <= 0 and b6_version[2] <= 0
|
43
|
-
gem_twitter_patcher
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
require 'rbitter/override/gems/rubysl-socket/socket' if RUBY_ENGINE == 'rbx'
|
1
|
+
=begin
|
2
|
+
This module gives special workarounds for some issues.
|
3
|
+
|
4
|
+
Problems are bypassed by monkey-patching.
|
5
|
+
|
6
|
+
As soon as a problem is resolved, patch should be removed.
|
7
|
+
|
8
|
+
**** Known issues ****
|
9
|
+
|
10
|
+
1. gem/twitter
|
11
|
+
Location : override/gem/twitter/connection.rb
|
12
|
+
Maintain : until below issue is fixed
|
13
|
+
Reference: https://github.com/sferik/twitter/pull/669
|
14
|
+
|
15
|
+
Gem 'twitter' does not handle streaming timeout. By applying this,
|
16
|
+
reading timeout works and Rbitter can handle timeouts.
|
17
|
+
|
18
|
+
2. gem/rubysl-socket
|
19
|
+
Location : override/gem/rubysl-socket/socket.rb
|
20
|
+
Maintain : until ip_address_list is implemented
|
21
|
+
Reference: https://github.com/rubysl/rubysl-socket/pull/9
|
22
|
+
|
23
|
+
With ipv6 environment, Resolv#use_ipv6? (in rubysl-resolv gem) checks
|
24
|
+
Socket.ip_address_list. This is not implemented at all with rubysl-socket-2.0.1.
|
25
|
+
NoMethodError exception is raised instead of NotImplementedError.
|
26
|
+
|
27
|
+
By applying this, Socket.ip_address_list is implemented and the method throws
|
28
|
+
NotImplementedError exception.
|
29
|
+
|
30
|
+
=end
|
31
|
+
|
32
|
+
def gem_twitter_patcher
|
33
|
+
require 'rbitter/override/gems/twitter/connection'
|
34
|
+
end
|
35
|
+
|
36
|
+
if Twitter::Version.const_defined?(:MAJOR)
|
37
|
+
b5_version = Twitter::Version::MAJOR * 10000
|
38
|
+
+ Twitter::Version::MINOR * 100 + Twitter::Version::PATCH
|
39
|
+
gem_twitter_patcher if b5_version <= 51400
|
40
|
+
else
|
41
|
+
b6_version = Twitter::Version.to_a
|
42
|
+
if b6_version[0] <= 6 and b6_version[1] <= 0 and b6_version[2] <= 0
|
43
|
+
gem_twitter_patcher
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
require 'rbitter/override/gems/rubysl-socket/socket' if RUBY_ENGINE == 'rbx'
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Rbitter
|
4
|
+
module Progress
|
5
|
+
@@last_draw = 0
|
6
|
+
def putback
|
7
|
+
$> << "\r"
|
8
|
+
end
|
9
|
+
|
10
|
+
def draw sentence
|
11
|
+
$> << sentence
|
12
|
+
if sentence.length < @@last_draw
|
13
|
+
$> << " "*(@@last_draw - sentence.length)
|
14
|
+
end
|
15
|
+
@@last_draw = sentence.length
|
16
|
+
putback
|
17
|
+
end
|
18
|
+
|
19
|
+
def newline
|
20
|
+
puts ""
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/rbitter/records.rb
CHANGED
@@ -1,127 +1,127 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require "active_record"
|
4
|
-
require "date"
|
5
|
-
|
6
|
-
module Rbitter
|
7
|
-
class Record < ActiveRecord::Base
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
module ARSupport
|
12
|
-
SCHEME_VERSION = 20150504
|
13
|
-
SCHEME = {
|
14
|
-
:marker => :integer, # 0 normal, 1 begin 2 halt
|
15
|
-
:marker_msg => :string,
|
16
|
-
:userid => :integer,
|
17
|
-
:username => :string,
|
18
|
-
:tweetid => :integer,
|
19
|
-
:replyto => :integer,
|
20
|
-
:tweet => :text, # with url unpacked
|
21
|
-
:date => :datetime,
|
22
|
-
:rt_count => :integer,
|
23
|
-
:fav_count => :integer
|
24
|
-
}
|
25
|
-
|
26
|
-
module_function
|
27
|
-
def prepared?
|
28
|
-
ActiveRecord::Base.connection.table_exists?(:records)
|
29
|
-
end
|
30
|
-
|
31
|
-
def connect_database
|
32
|
-
if Rbitter['activerecord'] == 'sqlite3'
|
33
|
-
warn "Warning: If you enable XMLRPC access, using sqlite is not recommended."
|
34
|
-
warn "Warning: Random crash can happen because of concurrency."
|
35
|
-
|
36
|
-
if RUBY_PLATFORM == 'java'
|
37
|
-
require "jdbc/sqlite3"
|
38
|
-
Jdbc::SQLite3.load_driver
|
39
|
-
ActiveRecord::Base.establish_connection(
|
40
|
-
adapter: 'jdbcsqlite3',
|
41
|
-
database: Rbitter['sqlite3']['dbfile'],
|
42
|
-
timeout: 10000) # Long timeout for slow computer
|
43
|
-
else
|
44
|
-
ActiveRecord::Base.establish_connection(
|
45
|
-
adapter: 'sqlite3',
|
46
|
-
database: Rbitter['sqlite3']['dbfile'],
|
47
|
-
timeout: 10000) # Long timeout for slow computer
|
48
|
-
end
|
49
|
-
elsif Rbitter['activerecord'] == 'mysql2'
|
50
|
-
Jdbc::MySQL.load_driver if RUBY_PLATFORM == 'java'
|
51
|
-
|
52
|
-
ActiveRecord::Base.establish_connection(
|
53
|
-
adapter: (RUBY_PLATFORM == 'java' ? 'jdbcmysql' : 'mysql2'),
|
54
|
-
host: Rbitter['mysql2']['host'],
|
55
|
-
port: Rbitter['mysql2']['port'],
|
56
|
-
database: Rbitter['mysql2']['dbname'],
|
57
|
-
username: Rbitter['mysql2']['username'],
|
58
|
-
password: Rbitter['mysql2']['password'],
|
59
|
-
encoding: "utf8mb4",
|
60
|
-
collation: "utf8mb4_unicode_ci")
|
61
|
-
else
|
62
|
-
raise RuntimeException.new("Unknown configuration value. 'activerecord' value should be sqlite3 or mysql2.")
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
def disconnect_database
|
67
|
-
if ActiveRecord::Base.connected?
|
68
|
-
ActiveRecord::Base.connection.close
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
def update_database_scheme
|
73
|
-
current_version = ActiveRecord::Migrator.current_version
|
74
|
-
if current_version < SCHEME_VERSION
|
75
|
-
warn "[records] Your ActiveRecord scheme is outdated."
|
76
|
-
warn "[records] Migrate... #{current_version} => #{SCHEME_VERSION}"
|
77
|
-
ActiveRecord::Migrator.migrate(File.expand_path("../records_migrate", __FILE__), SCHEME_VERSION)
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
def prepare option_string=""
|
82
|
-
ActiveRecord::Schema.define(version: SCHEME_VERSION) {
|
83
|
-
# MySQL specific option_string:
|
84
|
-
# utf8mb4 -> supporting UTF-8 4-byte characters (i.e. Emoji)
|
85
|
-
create_table(:records, { :options => option_string }) do |t|
|
86
|
-
SCHEME.each_key { |column|
|
87
|
-
case SCHEME[column]
|
88
|
-
when :string
|
89
|
-
t.string column
|
90
|
-
when :integer
|
91
|
-
t.integer column, :limit => 8
|
92
|
-
when :datetime
|
93
|
-
t.datetime column
|
94
|
-
when :text
|
95
|
-
t.text column
|
96
|
-
else
|
97
|
-
puts "Unexpected column type '#{SCHEME[column]}' of #{column}"
|
98
|
-
end
|
99
|
-
}
|
100
|
-
end
|
101
|
-
|
102
|
-
add_index :records, :tweetid
|
103
|
-
}
|
104
|
-
end
|
105
|
-
|
106
|
-
def any_to_datestring(obj)
|
107
|
-
if obj.is_a?(String)
|
108
|
-
# try to parse it
|
109
|
-
DateTime.parse(obj).strftime("%Y-%m-%d %H:%M:%S")
|
110
|
-
elsif obj.is_a?(DateTime) or obj.is_a?(Time)
|
111
|
-
obj.strftime("%Y-%m-%d %H:%M:%S")
|
112
|
-
else
|
113
|
-
raise ArgumentError.new("Can\'t automatically extract DateTime info")
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
def export_to_csv(csvfile)
|
118
|
-
open(csvfile, 'w') { |f|
|
119
|
-
f.write("marker,marker_msg,userid,username,tweetid,replyto,tweet,date,rt_count,fav_count")
|
120
|
-
f.write("\n")
|
121
|
-
Rbitter::Record.find_each { |t|
|
122
|
-
f.write("#{t.marker},#{t.marker_msg},#{t.userid},#{t.username},#{t.tweetid},")
|
123
|
-
f.write("#{t.replyto},#{t.tweet},#{t.date},#{t.rt_count},#{t.fav_count}\n")
|
124
|
-
}
|
125
|
-
}
|
126
|
-
end
|
127
|
-
end
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "active_record"
|
4
|
+
require "date"
|
5
|
+
|
6
|
+
module Rbitter
|
7
|
+
class Record < ActiveRecord::Base
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
module ARSupport
|
12
|
+
SCHEME_VERSION = 20150504
|
13
|
+
SCHEME = {
|
14
|
+
:marker => :integer, # 0 normal, 1 begin 2 halt
|
15
|
+
:marker_msg => :string,
|
16
|
+
:userid => :integer,
|
17
|
+
:username => :string,
|
18
|
+
:tweetid => :integer,
|
19
|
+
:replyto => :integer,
|
20
|
+
:tweet => :text, # with url unpacked
|
21
|
+
:date => :datetime,
|
22
|
+
:rt_count => :integer,
|
23
|
+
:fav_count => :integer
|
24
|
+
}
|
25
|
+
|
26
|
+
module_function
|
27
|
+
def prepared?
|
28
|
+
ActiveRecord::Base.connection.table_exists?(:records)
|
29
|
+
end
|
30
|
+
|
31
|
+
def connect_database
|
32
|
+
if Rbitter['activerecord'] == 'sqlite3'
|
33
|
+
warn "Warning: If you enable XMLRPC access, using sqlite is not recommended."
|
34
|
+
warn "Warning: Random crash can happen because of concurrency."
|
35
|
+
|
36
|
+
if RUBY_PLATFORM == 'java'
|
37
|
+
require "jdbc/sqlite3"
|
38
|
+
Jdbc::SQLite3.load_driver
|
39
|
+
ActiveRecord::Base.establish_connection(
|
40
|
+
adapter: 'jdbcsqlite3',
|
41
|
+
database: Rbitter['sqlite3']['dbfile'],
|
42
|
+
timeout: 10000) # Long timeout for slow computer
|
43
|
+
else
|
44
|
+
ActiveRecord::Base.establish_connection(
|
45
|
+
adapter: 'sqlite3',
|
46
|
+
database: Rbitter['sqlite3']['dbfile'],
|
47
|
+
timeout: 10000) # Long timeout for slow computer
|
48
|
+
end
|
49
|
+
elsif Rbitter['activerecord'] == 'mysql2'
|
50
|
+
Jdbc::MySQL.load_driver if RUBY_PLATFORM == 'java'
|
51
|
+
|
52
|
+
ActiveRecord::Base.establish_connection(
|
53
|
+
adapter: (RUBY_PLATFORM == 'java' ? 'jdbcmysql' : 'mysql2'),
|
54
|
+
host: Rbitter['mysql2']['host'],
|
55
|
+
port: Rbitter['mysql2']['port'],
|
56
|
+
database: Rbitter['mysql2']['dbname'],
|
57
|
+
username: Rbitter['mysql2']['username'],
|
58
|
+
password: Rbitter['mysql2']['password'],
|
59
|
+
encoding: "utf8mb4",
|
60
|
+
collation: "utf8mb4_unicode_ci")
|
61
|
+
else
|
62
|
+
raise RuntimeException.new("Unknown configuration value. 'activerecord' value should be sqlite3 or mysql2.")
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def disconnect_database
|
67
|
+
if ActiveRecord::Base.connected?
|
68
|
+
ActiveRecord::Base.connection.close
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def update_database_scheme
|
73
|
+
current_version = ActiveRecord::Migrator.current_version
|
74
|
+
if current_version < SCHEME_VERSION
|
75
|
+
warn "[records] Your ActiveRecord scheme is outdated."
|
76
|
+
warn "[records] Migrate... #{current_version} => #{SCHEME_VERSION}"
|
77
|
+
ActiveRecord::Migrator.migrate(File.expand_path("../records_migrate", __FILE__), SCHEME_VERSION)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def prepare option_string=""
|
82
|
+
ActiveRecord::Schema.define(version: SCHEME_VERSION) {
|
83
|
+
# MySQL specific option_string:
|
84
|
+
# utf8mb4 -> supporting UTF-8 4-byte characters (i.e. Emoji)
|
85
|
+
create_table(:records, { :options => option_string }) do |t|
|
86
|
+
SCHEME.each_key { |column|
|
87
|
+
case SCHEME[column]
|
88
|
+
when :string
|
89
|
+
t.string column
|
90
|
+
when :integer
|
91
|
+
t.integer column, :limit => 8
|
92
|
+
when :datetime
|
93
|
+
t.datetime column
|
94
|
+
when :text
|
95
|
+
t.text column
|
96
|
+
else
|
97
|
+
puts "Unexpected column type '#{SCHEME[column]}' of #{column}"
|
98
|
+
end
|
99
|
+
}
|
100
|
+
end
|
101
|
+
|
102
|
+
add_index :records, :tweetid
|
103
|
+
}
|
104
|
+
end
|
105
|
+
|
106
|
+
def any_to_datestring(obj)
|
107
|
+
if obj.is_a?(String)
|
108
|
+
# try to parse it
|
109
|
+
DateTime.parse(obj).strftime("%Y-%m-%d %H:%M:%S")
|
110
|
+
elsif obj.is_a?(DateTime) or obj.is_a?(Time)
|
111
|
+
obj.strftime("%Y-%m-%d %H:%M:%S")
|
112
|
+
else
|
113
|
+
raise ArgumentError.new("Can\'t automatically extract DateTime info")
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def export_to_csv(csvfile)
|
118
|
+
open(csvfile, 'w') { |f|
|
119
|
+
f.write("marker,marker_msg,userid,username,tweetid,replyto,tweet,date,rt_count,fav_count")
|
120
|
+
f.write("\n")
|
121
|
+
Rbitter::Record.find_each { |t|
|
122
|
+
f.write("#{t.marker},#{t.marker_msg},#{t.userid},#{t.username},#{t.tweetid},")
|
123
|
+
f.write("#{t.replyto},#{t.tweet},#{t.date},#{t.rt_count},#{t.fav_count}\n")
|
124
|
+
}
|
125
|
+
}
|
126
|
+
end
|
127
|
+
end
|
@@ -1,12 +1,12 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
|
4
|
-
class AddIndex < ActiveRecord::Migration
|
5
|
-
def up
|
6
|
-
add_index :records, :tweetid
|
7
|
-
end
|
8
|
-
|
9
|
-
def change
|
10
|
-
up
|
11
|
-
end
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
|
4
|
+
class AddIndex < ActiveRecord::Migration
|
5
|
+
def up
|
6
|
+
add_index :records, :tweetid
|
7
|
+
end
|
8
|
+
|
9
|
+
def change
|
10
|
+
up
|
11
|
+
end
|
12
12
|
end
|
@@ -1,12 +1,12 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
|
4
|
-
class AddReplytoColumn < ActiveRecord::Migration
|
5
|
-
def up
|
6
|
-
add_column :records, :replyto, :integer, :limit => 8
|
7
|
-
end
|
8
|
-
|
9
|
-
def change
|
10
|
-
up
|
11
|
-
end
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
|
4
|
+
class AddReplytoColumn < ActiveRecord::Migration
|
5
|
+
def up
|
6
|
+
add_column :records, :replyto, :integer, :limit => 8
|
7
|
+
end
|
8
|
+
|
9
|
+
def change
|
10
|
+
up
|
11
|
+
end
|
12
12
|
end
|