livejournal 0.0.1 → 0.1.0
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/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 :
|