livejournal 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +1 -1
- data/lib/livejournal/database.rb +4 -4
- data/lib/livejournal/entry.rb +83 -54
- data/lib/livejournal/friends.rb +4 -4
- data/lib/livejournal/request.rb +31 -21
- data/lib/livejournal/sync.rb +11 -12
- data/sample/export +1 -1
- data/sample/graph +209 -0
- data/test/login.rb +19 -0
- data/test/roundtrip.rb +45 -0
- metadata +5 -3
- data/sample/lj +0 -23
data/Rakefile
CHANGED
data/lib/livejournal/database.rb
CHANGED
@@ -146,10 +146,10 @@ module LiveJournal
|
|
146
146
|
end
|
147
147
|
end
|
148
148
|
|
149
|
-
# Yield
|
150
|
-
def each_entry(
|
151
|
-
sql = 'SELECT * FROM entry ORDER BY itemid
|
152
|
-
sql += "
|
149
|
+
# Yield a set of entries.
|
150
|
+
def each_entry(where=nil, &block)
|
151
|
+
sql = 'SELECT * FROM entry ORDER BY itemid ASC'
|
152
|
+
sql += " WHERE #{where}" if where
|
153
153
|
query_entries sql, &block
|
154
154
|
end
|
155
155
|
|
data/lib/livejournal/entry.rb
CHANGED
@@ -74,10 +74,15 @@ module LiveJournal
|
|
74
74
|
|
75
75
|
def ==(other)
|
76
76
|
[:subject, :event, :moodid, :mood, :music, :taglist, :pickeyword,
|
77
|
-
:preformatted, :backdated, :comments, :
|
77
|
+
:preformatted, :backdated, :comments, :security, :allowmask,
|
78
78
|
:screening, :props].each do |attr|
|
79
79
|
return false if send(attr) != other.send(attr)
|
80
80
|
end
|
81
|
+
# compare time fields one-by-one because livejournal ignores the
|
82
|
+
# "seconds" field.
|
83
|
+
[:year, :mon, :day, :hour, :min, :zone].each do |attr|
|
84
|
+
return false if @time.send(attr) != other.time.send(attr)
|
85
|
+
end
|
81
86
|
return true
|
82
87
|
end
|
83
88
|
|
@@ -174,9 +179,67 @@ module LiveJournal
|
|
174
179
|
end
|
175
180
|
html
|
176
181
|
end
|
182
|
+
|
183
|
+
def add_to_request req
|
184
|
+
req['event'] = self.event
|
185
|
+
req['lineendings'] = 'unix'
|
186
|
+
req['subject'] = self.subject
|
187
|
+
|
188
|
+
case self.security
|
189
|
+
when :public
|
190
|
+
req['security'] = 'public'
|
191
|
+
when :friends
|
192
|
+
req['security'] = 'usemask'
|
193
|
+
req['allowmask'] = 1
|
194
|
+
when :private
|
195
|
+
req['security'] = 'private'
|
196
|
+
when :custom
|
197
|
+
req['security'] = 'usemask'
|
198
|
+
req['allowmask'] = self.allowmask
|
199
|
+
end
|
200
|
+
|
201
|
+
req['year'], req['mon'], req['day'] =
|
202
|
+
self.time.year, self.time.mon, self.time.day
|
203
|
+
req['hour'], req['min'] = self.time.hour, self.time.min
|
204
|
+
|
205
|
+
{ 'current_mood' => self.mood,
|
206
|
+
'current_moodid' => self.moodid,
|
207
|
+
'current_music' => self.music,
|
208
|
+
'picture_keyword' => self.pickeyword,
|
209
|
+
'taglist' => self.taglist.join(', '),
|
210
|
+
'opt_preformatted' => self.preformatted ? 1 : 0,
|
211
|
+
'opt_nocomments' => self.comments == :none ? 1 : 0,
|
212
|
+
'opt_noemail' => self.comments == :noemail ? 1 : 0,
|
213
|
+
'opt_backdated' => self.backdated ? 1 : 0,
|
214
|
+
'opt_screening' =>
|
215
|
+
case self.screening
|
216
|
+
when :all; 'A'
|
217
|
+
when :anonymous; 'R'
|
218
|
+
when :nonfriends; 'F'
|
219
|
+
when :none; 'N'
|
220
|
+
when :default; ''
|
221
|
+
end
|
222
|
+
}.each do |name, value|
|
223
|
+
req["prop_#{name}"] = value
|
224
|
+
end
|
225
|
+
end
|
177
226
|
end
|
178
227
|
|
179
228
|
module Request
|
229
|
+
class PostEvent < Req
|
230
|
+
def initialize(user, entry)
|
231
|
+
super(user, 'postevent')
|
232
|
+
entry.add_to_request @request
|
233
|
+
@entry = entry
|
234
|
+
end
|
235
|
+
|
236
|
+
def run
|
237
|
+
super
|
238
|
+
@entry.itemid = @result['itemid'].to_i
|
239
|
+
@entry.anum = @result['anum'].to_i
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
180
243
|
class GetEvents < Req
|
181
244
|
# We support three different types of GetEvents:
|
182
245
|
# * <tt>GetEvents.new(user, :itemid => itemid)</tt> (fetch a single item)
|
@@ -184,17 +247,19 @@ module LiveJournal
|
|
184
247
|
# * <tt>GetEvents.new(user, :lastsync => lastsync)</tt> (for syncing)
|
185
248
|
def initialize(user, opts)
|
186
249
|
super(user, 'getevents')
|
187
|
-
|
250
|
+
@request['lineendings'] = 'unix'
|
188
251
|
|
189
252
|
if opts.has_key? :itemid
|
190
|
-
|
191
|
-
|
253
|
+
@request['selecttype'] = 'one'
|
254
|
+
@request['itemid'] = opts[:itemid]
|
192
255
|
elsif opts.has_key? :recent
|
193
|
-
|
194
|
-
|
256
|
+
@request['selecttype'] = 'lastn'
|
257
|
+
@request['howmany'] = opts[:recent]
|
195
258
|
elsif opts.has_key? :lastsync
|
196
|
-
|
197
|
-
|
259
|
+
@request['selecttype'] = 'syncitems'
|
260
|
+
@request['lastsync'] = opts[:lastsync] if opts[:lastsync]
|
261
|
+
else
|
262
|
+
raise ArgumentError, 'invalid options for GetEvents'
|
198
263
|
end
|
199
264
|
end
|
200
265
|
|
@@ -214,63 +279,27 @@ module LiveJournal
|
|
214
279
|
entries[itemid].load_prop(prop['name'], prop['value'])
|
215
280
|
end
|
216
281
|
|
217
|
-
if @
|
218
|
-
return entries[@
|
282
|
+
if @request.has_key? 'itemid'
|
283
|
+
return entries[@request['itemid']]
|
219
284
|
else
|
220
285
|
return entries
|
221
286
|
end
|
222
287
|
end
|
223
288
|
end
|
289
|
+
|
224
290
|
class EditEvent < Req
|
225
291
|
def initialize(user, entry, opts={})
|
226
292
|
super(user, 'editevent')
|
227
|
-
self['itemid'] = entry.itemid
|
228
|
-
if entry.event
|
229
|
-
self['event'] = entry.event
|
230
|
-
elsif entry.entry.nil? and opts.has_key? :delete
|
231
|
-
self['event'] = ''
|
232
|
-
else
|
233
|
-
raise AccidentalDeleteError
|
234
|
-
end
|
235
|
-
self['lineendings'] = 'unix'
|
236
|
-
self['subject'] = entry.subject
|
237
293
|
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
self['allowmask'] = 1
|
244
|
-
when :private
|
245
|
-
self['security'] = 'private'
|
246
|
-
when :custom
|
247
|
-
self['security'] = 'usemask'
|
248
|
-
self['allowmask'] = entry.allowmask
|
294
|
+
@request['itemid'] = entry.itemid
|
295
|
+
if opts.has_key? :delete
|
296
|
+
@request['event'] = ''
|
297
|
+
else
|
298
|
+
entry.add_to_request @request
|
249
299
|
end
|
250
300
|
|
251
|
-
|
252
|
-
|
253
|
-
self['hour'], self['min'] = entry.time.hour, entry.time.min
|
254
|
-
|
255
|
-
{ 'current_mood' => entry.mood,
|
256
|
-
'current_moodid' => entry.moodid,
|
257
|
-
'current_music' => entry.music,
|
258
|
-
'picture_keyword' => entry.pickeyword,
|
259
|
-
'taglist' => entry.taglist.join(', '),
|
260
|
-
'opt_preformatted' => entry.preformatted ? 1 : 0,
|
261
|
-
'opt_nocomments' => entry.comments == :none ? 1 : 0,
|
262
|
-
'opt_noemail' => entry.comments == :noemail ? 1 : 0,
|
263
|
-
'opt_backdated' => entry.backdated ? 1 : 0,
|
264
|
-
'opt_screening' =>
|
265
|
-
case entry.screening
|
266
|
-
when :all; 'A'
|
267
|
-
when :anonymous; 'R'
|
268
|
-
when :nonfriends; 'F'
|
269
|
-
when :none; 'N'
|
270
|
-
when :default; ''
|
271
|
-
end
|
272
|
-
}.each do |name, value|
|
273
|
-
self["prop_#{name}"] = value
|
301
|
+
if @request['event'].nil? or @request['event'].empty?
|
302
|
+
raise AccidentalDeleteError unless opts.has_key? :delete
|
274
303
|
end
|
275
304
|
end
|
276
305
|
end
|
data/lib/livejournal/friends.rb
CHANGED
@@ -89,11 +89,11 @@ module LiveJournal
|
|
89
89
|
end
|
90
90
|
# Returns true if there are new posts available.
|
91
91
|
def run
|
92
|
-
|
92
|
+
@request['lastupdate'] = @lastupdate if @lastupdate
|
93
93
|
super
|
94
|
-
@lastupdate =
|
95
|
-
@interval =
|
96
|
-
|
94
|
+
@lastupdate = @result['lastupdate']
|
95
|
+
@interval = @result['interval']
|
96
|
+
@result['new'] == '1'
|
97
97
|
end
|
98
98
|
end
|
99
99
|
end
|
data/lib/livejournal/request.rb
CHANGED
@@ -27,6 +27,7 @@ require 'livejournal/basic'
|
|
27
27
|
require 'cgi'
|
28
28
|
require 'net/http'
|
29
29
|
require 'date'
|
30
|
+
require 'digest/md5'
|
30
31
|
|
31
32
|
module LiveJournal
|
32
33
|
module Request
|
@@ -58,13 +59,20 @@ module LiveJournal
|
|
58
59
|
class Req #:nodoc:
|
59
60
|
def initialize(user, mode)
|
60
61
|
@user = user
|
61
|
-
@
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
62
|
+
@request = { 'mode' => mode,
|
63
|
+
'clientversion' => 'Ruby',
|
64
|
+
'ver' => 1 }
|
65
|
+
if user
|
66
|
+
challenge = GetChallenge.new.run
|
67
|
+
response = Digest::MD5.hexdigest(challenge +
|
68
|
+
Digest::MD5.hexdigest(user.password))
|
69
|
+
@request.update({ 'user' => user.username,
|
70
|
+
'auth_method' => 'challenge',
|
71
|
+
'auth_challenge' => challenge,
|
72
|
+
'auth_response' => response })
|
73
|
+
@request['usejournal'] = user.usejournal if user.usejournal
|
74
|
+
end
|
75
|
+
@result = {}
|
68
76
|
@verbose = false
|
69
77
|
@dryrun = false
|
70
78
|
end
|
@@ -72,18 +80,10 @@ module LiveJournal
|
|
72
80
|
def verbose!; @verbose = true; end
|
73
81
|
def dryrun!; @dryrun = true; end
|
74
82
|
|
75
|
-
def []=(key, value)
|
76
|
-
@reqparams[key] = value
|
77
|
-
end
|
78
|
-
|
79
|
-
def [](key)
|
80
|
-
@result[key]
|
81
|
-
end
|
82
|
-
|
83
83
|
def run
|
84
84
|
h = Net::HTTP.new('www.livejournal.com')
|
85
85
|
h.set_debug_output $stderr if @verbose
|
86
|
-
request = @
|
86
|
+
request = @request.collect { |key, value|
|
87
87
|
"#{CGI.escape(key)}=#{CGI.escape(value.to_s)}"
|
88
88
|
}.join("&")
|
89
89
|
p request if @verbose
|
@@ -91,8 +91,8 @@ module LiveJournal
|
|
91
91
|
response, data = h.post('/interface/flat', request)
|
92
92
|
parseresponse(data)
|
93
93
|
dumpresponse if @verbose
|
94
|
-
if
|
95
|
-
raise ProtocolException,
|
94
|
+
if @result['success'] != "OK"
|
95
|
+
raise ProtocolException, @result['errmsg']
|
96
96
|
end
|
97
97
|
end
|
98
98
|
|
@@ -110,8 +110,8 @@ module LiveJournal
|
|
110
110
|
end
|
111
111
|
|
112
112
|
def each_in_array(base)
|
113
|
-
for i in 1..(
|
114
|
-
yield HashStrip.new("#{base}_#{i.to_s}_",
|
113
|
+
for i in 1..(@result["#{base}_count"].to_i) do
|
114
|
+
yield HashStrip.new("#{base}_#{i.to_s}_", @result)
|
115
115
|
end
|
116
116
|
end
|
117
117
|
def build_array(base)
|
@@ -120,7 +120,17 @@ module LiveJournal
|
|
120
120
|
array
|
121
121
|
end
|
122
122
|
end
|
123
|
+
|
124
|
+
class GetChallenge < Req
|
125
|
+
def initialize
|
126
|
+
super(nil, 'getchallenge')
|
127
|
+
end
|
128
|
+
def run
|
129
|
+
super
|
130
|
+
return @result['challenge']
|
131
|
+
end
|
132
|
+
end
|
123
133
|
end
|
124
134
|
end
|
125
135
|
|
126
|
-
# vim: ts=2 sw=2 et :
|
136
|
+
# vim: ts=2 sw=2 et cino=(0 :
|
data/lib/livejournal/sync.rb
CHANGED
@@ -26,8 +26,7 @@
|
|
26
26
|
require 'livejournal/request'
|
27
27
|
# As well as a custom XML format via REST, for comments:
|
28
28
|
# http://www.livejournal.com/developer/exporting.bml
|
29
|
-
require '
|
30
|
-
require 'uri'
|
29
|
+
require 'open-uri'
|
31
30
|
require 'livejournal/comments-xml'
|
32
31
|
|
33
32
|
require 'livejournal/entry'
|
@@ -40,14 +39,14 @@ module LiveJournal
|
|
40
39
|
def initialize(user, syncitems=nil, lastsync=nil)
|
41
40
|
super(user, 'syncitems')
|
42
41
|
@syncitems = syncitems || {}
|
43
|
-
|
42
|
+
@request['lastsync'] = lastsync if lastsync
|
44
43
|
end
|
45
44
|
|
46
45
|
def run
|
47
46
|
super
|
48
47
|
lasttime = nil
|
49
48
|
@fetched = 0
|
50
|
-
@total =
|
49
|
+
@total = @result['sync_total'].to_i
|
51
50
|
each_in_array('sync') do |item|
|
52
51
|
item, time = item['item'], item['time']
|
53
52
|
next if @syncitems.has_key? item
|
@@ -75,7 +74,7 @@ module LiveJournal
|
|
75
74
|
end
|
76
75
|
def run
|
77
76
|
super
|
78
|
-
|
77
|
+
@result['ljsession']
|
79
78
|
end
|
80
79
|
end
|
81
80
|
end
|
@@ -145,13 +144,13 @@ module LiveJournal
|
|
145
144
|
path = "/export_comments.bml?get=comment_#{mode}&startid=#{start}"
|
146
145
|
# authas: hooray for features discovered by reading source!
|
147
146
|
path += "&authas=#{@user.usejournal}" if @user.usejournal
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
147
|
+
|
148
|
+
data = nil
|
149
|
+
open(@user.server.url + path,
|
150
|
+
'Cookie' => "ljsession=#{@session}") do |f|
|
151
|
+
# XXX stream this data to the XML parser.
|
152
|
+
data = f.read
|
153
|
+
end
|
155
154
|
return data
|
156
155
|
end
|
157
156
|
private :run_GET
|
data/sample/export
CHANGED
data/sample/graph
ADDED
@@ -0,0 +1,209 @@
|
|
1
|
+
#!/usr/bin/ruby -I../lib
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'rubygems'
|
5
|
+
require 'gruff'
|
6
|
+
rescue LoadError => e
|
7
|
+
puts <<EOT
|
8
|
+
Error loading libraries: #{e}
|
9
|
+
Though ljrb itself doesn't require them, the graph sample uses
|
10
|
+
the gruff library: http://nubyonrails.com/pages/gruff ,
|
11
|
+
which itself requires rubygems.
|
12
|
+
EOT
|
13
|
+
exit 1
|
14
|
+
end
|
15
|
+
require 'livejournal/database'
|
16
|
+
require 'livejournal/entry'
|
17
|
+
require 'optparse'
|
18
|
+
require 'time'
|
19
|
+
|
20
|
+
class Options
|
21
|
+
# required options
|
22
|
+
attr_reader :dbfile, :outfile, :mode
|
23
|
+
# optional options
|
24
|
+
attr_reader :smooth, :normalize, :geom, :starttime, :endtime
|
25
|
+
# mode-specific options
|
26
|
+
attr_reader :tags
|
27
|
+
|
28
|
+
def initialize
|
29
|
+
@smooth = 1
|
30
|
+
@dbfile = nil
|
31
|
+
@outfile = nil
|
32
|
+
@normalize = false
|
33
|
+
@mode = nil
|
34
|
+
@geom = 800
|
35
|
+
@opts = OptionParser.new do |o|
|
36
|
+
o.banner = "usage: graph [options] [modeparam [modeparam ...]]"
|
37
|
+
o.on('-d', '--db=FILE', 'database (required)') { |@dbfile| }
|
38
|
+
o.on('-o', '--out=FILENAME.PNG', 'output file (required)') { |@outfile| }
|
39
|
+
o.on('-g', '--geom=WxH', 'output geometry') { |@geom| }
|
40
|
+
o.on('--smooth=N',
|
41
|
+
'merge every set of n consecutive datapoints') do |smooth|
|
42
|
+
@smooth = smooth.to_i
|
43
|
+
end
|
44
|
+
o.on('--normalize',
|
45
|
+
'normalize relative to entry counts') { |@normalize| }
|
46
|
+
o.on('--start=TIME', 'start time') { |t| @starttime = Time.parse t }
|
47
|
+
o.on('--end=TIME', 'end time') { |t| @endtime = Time.parse t }
|
48
|
+
o.on('-m', '--mode=MODE',
|
49
|
+
'mode (required) one of {tags, security}') do |mode|
|
50
|
+
case mode
|
51
|
+
when 'tags'
|
52
|
+
@mode = :tags
|
53
|
+
when 'security'
|
54
|
+
@mode = :security
|
55
|
+
else
|
56
|
+
die "bad mode #{mode}"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
self
|
61
|
+
end
|
62
|
+
def parse!(argv)
|
63
|
+
@opts.parse! ARGV
|
64
|
+
check_params
|
65
|
+
self
|
66
|
+
end
|
67
|
+
def die(msg)
|
68
|
+
puts msg
|
69
|
+
puts @opts
|
70
|
+
exit 1
|
71
|
+
end
|
72
|
+
def check_params
|
73
|
+
die "must specify database." unless @dbfile
|
74
|
+
die "must specify output file." unless @outfile
|
75
|
+
die "must specify mode." unless @mode
|
76
|
+
|
77
|
+
case @mode
|
78
|
+
when :tags
|
79
|
+
@tags = ARGV
|
80
|
+
unless @tags.length > 0
|
81
|
+
die "must specify at least one tag as an extra command-line parameter."
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
$opts = Options.new.parse! ARGV
|
87
|
+
|
88
|
+
class DataSet
|
89
|
+
# store a series of (time, class, count) observations.
|
90
|
+
|
91
|
+
def initialize
|
92
|
+
# data: klass -> time -> count
|
93
|
+
@data = Hash.new { |h,k| h[k] = Hash.new { |h,k| h[k] = 0 } }
|
94
|
+
@firsttime = @lasttime = nil
|
95
|
+
@bucketing = :month
|
96
|
+
end
|
97
|
+
|
98
|
+
def bucket(time)
|
99
|
+
case @bucketing
|
100
|
+
when :month
|
101
|
+
mon = time.month
|
102
|
+
if $opts.smooth != 1
|
103
|
+
# when smooth = 3,
|
104
|
+
# 1 -> 1
|
105
|
+
# 3 -> 1
|
106
|
+
# 4 -> 4
|
107
|
+
# 5 -> 4
|
108
|
+
# 12 -> 10
|
109
|
+
mon = ((mon-1)/$opts.smooth * $opts.smooth) + 1
|
110
|
+
end
|
111
|
+
"%d-%02d" % [time.year, mon]
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def each_bucket
|
116
|
+
case @bucketing
|
117
|
+
when :month
|
118
|
+
time = Date.parse(@firsttime.strftime('%Y-%m-01'))
|
119
|
+
lasttime = Date.parse(@lasttime.strftime('%Y-%m-01'))
|
120
|
+
lastbucket = nil
|
121
|
+
while time < lasttime
|
122
|
+
b = bucket(time)
|
123
|
+
yield b if b != lastbucket
|
124
|
+
lastbucket = b
|
125
|
+
time = time >> 1
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def labels(count=5)
|
131
|
+
total = 0
|
132
|
+
each_bucket { total += 1 }
|
133
|
+
skip = (total / count.to_f).round
|
134
|
+
|
135
|
+
labels = {}
|
136
|
+
i = 0
|
137
|
+
each_bucket do |bucket|
|
138
|
+
labels[i] = bucket if i % skip == 0
|
139
|
+
i += 1
|
140
|
+
end
|
141
|
+
labels
|
142
|
+
end
|
143
|
+
|
144
|
+
def get_class(klass)
|
145
|
+
buckets = []
|
146
|
+
data = @data[klass]
|
147
|
+
each_bucket do |bucket|
|
148
|
+
buckets << if data.has_key? bucket
|
149
|
+
if $opts.normalize
|
150
|
+
data[bucket] / @data[:total][bucket].to_f
|
151
|
+
else
|
152
|
+
data[bucket]
|
153
|
+
end
|
154
|
+
else
|
155
|
+
0
|
156
|
+
end
|
157
|
+
end
|
158
|
+
buckets
|
159
|
+
end
|
160
|
+
|
161
|
+
def add(klass, time, count=1)
|
162
|
+
@firsttime = time if @firsttime.nil? or time < @firsttime
|
163
|
+
@lasttime = time if @lasttime.nil? or time > @lasttime
|
164
|
+
@data[klass][bucket(time)] += count
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
dataset = DataSet.new
|
169
|
+
db = LiveJournal::Database.new $opts.dbfile
|
170
|
+
total_entries = 0
|
171
|
+
|
172
|
+
db.each_entry do |entry|
|
173
|
+
next if $opts.starttime and $opts.starttime > entry.time
|
174
|
+
next if $opts.endtime and $opts.endtime < entry.time
|
175
|
+
|
176
|
+
dataset.add(:total, entry.time, 1)
|
177
|
+
case $opts.mode
|
178
|
+
when :tags
|
179
|
+
entry.taglist.each do |tag|
|
180
|
+
dataset.add(tag, entry.time)
|
181
|
+
end
|
182
|
+
when :security
|
183
|
+
case entry.security
|
184
|
+
when :public; dataset.add(:public, entry.time)
|
185
|
+
when :friends; dataset.add(:friends, entry.time)
|
186
|
+
else; dataset.add(:other, entry.time)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
total_entries += 1
|
190
|
+
end
|
191
|
+
|
192
|
+
g = Gruff::Line.new($opts.geom)
|
193
|
+
g.labels = dataset.labels
|
194
|
+
case $opts.mode
|
195
|
+
when :tags
|
196
|
+
g.title = 'Tag Rate'
|
197
|
+
$opts.tags.each do |tag|
|
198
|
+
g.data(tag, dataset.get_class(tag))
|
199
|
+
end
|
200
|
+
when :security
|
201
|
+
g.title = 'Entry Security'
|
202
|
+
[:public, :friends, :other].each do |sec|
|
203
|
+
g.data(sec.to_s, dataset.get_class(sec))
|
204
|
+
end
|
205
|
+
end
|
206
|
+
g.write $opts.outfile
|
207
|
+
|
208
|
+
# vim: ts=2 sw=2 et :
|
209
|
+
|
data/test/login.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
require 'livejournal/login'
|
4
|
+
require 'livejournal/entry'
|
5
|
+
require 'test/unit'
|
6
|
+
|
7
|
+
class TC_Login < Test::Unit::TestCase
|
8
|
+
def setup
|
9
|
+
@user = LiveJournal::User.new('test', 'test')
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_login
|
13
|
+
login = LiveJournal::Request::Login.new(@user)
|
14
|
+
login.run
|
15
|
+
assert_not_equal(@user.fullname, nil)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# vim: ts=2 sw=2 et :
|
data/test/roundtrip.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
require 'livejournal/login'
|
4
|
+
require 'livejournal/entry'
|
5
|
+
require 'test/unit'
|
6
|
+
|
7
|
+
include LiveJournal
|
8
|
+
|
9
|
+
class TC_RoundTrip < Test::Unit::TestCase
|
10
|
+
def setup
|
11
|
+
@user = User.new('ljrb_test', 'test_ljrb')
|
12
|
+
end
|
13
|
+
|
14
|
+
def roundtrip entry
|
15
|
+
postevent = Request::PostEvent.new(@user, entry)
|
16
|
+
postevent.run
|
17
|
+
|
18
|
+
getevents = Request::GetEvents.new(@user,
|
19
|
+
:itemid => entry.itemid)
|
20
|
+
new_entry = getevents.run
|
21
|
+
assert_equal(new_entry, entry)
|
22
|
+
|
23
|
+
delete = Request::EditEvent.new(@user, entry, :delete => true)
|
24
|
+
delete.run
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_roundtrip
|
28
|
+
e = Entry.new
|
29
|
+
e.subject = 'subject'
|
30
|
+
e.event = 'event here'
|
31
|
+
e.time = LiveJournal::coerce_gmt Time.now
|
32
|
+
roundtrip e
|
33
|
+
|
34
|
+
e = Entry.new
|
35
|
+
e.subject = 'subject here'
|
36
|
+
e.event = 'eventblah here'
|
37
|
+
e.time = LiveJournal::coerce_gmt Time.now
|
38
|
+
e.comments = :noemail
|
39
|
+
e.preformatted = true
|
40
|
+
e.security = :friends
|
41
|
+
roundtrip e
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# vim: set ts=2 sw=2 et cino=(0 :
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
|
|
3
3
|
specification_version: 1
|
4
4
|
name: livejournal
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.0
|
7
|
-
date: 2006-03-
|
6
|
+
version: 0.1.0
|
7
|
+
date: 2006-03-25 00:00:00 +09:00
|
8
8
|
summary: module for interacting with livejournal
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -45,12 +45,14 @@ files:
|
|
45
45
|
- lib/livejournal/comment.rb
|
46
46
|
- lib/livejournal/friends.rb
|
47
47
|
- lib/livejournal/basic.rb
|
48
|
-
- sample/
|
48
|
+
- sample/graph
|
49
49
|
- sample/export
|
50
50
|
- test/database.rb
|
51
51
|
- test/time.rb
|
52
52
|
- test/checkfriends.rb
|
53
|
+
- test/roundtrip.rb
|
53
54
|
- test/comments-xml.rb
|
55
|
+
- test/login.rb
|
54
56
|
test_files: []
|
55
57
|
rdoc_options: []
|
56
58
|
extra_rdoc_files: []
|
data/sample/lj
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
#!/usr/bin/ruby
|
2
|
-
|
3
|
-
require 'livejournal/login'
|
4
|
-
require 'livejournal/entry'
|
5
|
-
|
6
|
-
puts "Logging in..."
|
7
|
-
user = LiveJournal::User.new('test', 'test')
|
8
|
-
login = LiveJournal::Request::Login.new(user)
|
9
|
-
login.run
|
10
|
-
|
11
|
-
puts "Login response:"
|
12
|
-
login.dumpresponse
|
13
|
-
|
14
|
-
puts "User's full name: #{user.fullname}"
|
15
|
-
|
16
|
-
if false
|
17
|
-
get = LiveJournal::Request::GetEvents.new(user, :recent => 1)
|
18
|
-
entry = get.run
|
19
|
-
get.dumpresponse
|
20
|
-
p entry
|
21
|
-
end
|
22
|
-
|
23
|
-
# vim: ts=2 sw=2 et :
|