hobix 0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +7 -0
  2. data/bin/hobix +90 -0
  3. data/lib/hobix/api.rb +91 -0
  4. data/lib/hobix/article.rb +22 -0
  5. data/lib/hobix/base.rb +477 -0
  6. data/lib/hobix/bixwik.rb +200 -0
  7. data/lib/hobix/commandline.rb +661 -0
  8. data/lib/hobix/comments.rb +99 -0
  9. data/lib/hobix/config.rb +39 -0
  10. data/lib/hobix/datamarsh.rb +110 -0
  11. data/lib/hobix/entry.rb +83 -0
  12. data/lib/hobix/facets/comments.rb +74 -0
  13. data/lib/hobix/facets/publisher.rb +314 -0
  14. data/lib/hobix/facets/trackbacks.rb +80 -0
  15. data/lib/hobix/linklist.rb +76 -0
  16. data/lib/hobix/out/atom.rb +92 -0
  17. data/lib/hobix/out/erb.rb +64 -0
  18. data/lib/hobix/out/okaynews.rb +55 -0
  19. data/lib/hobix/out/quick.rb +312 -0
  20. data/lib/hobix/out/rdf.rb +97 -0
  21. data/lib/hobix/out/redrum.rb +26 -0
  22. data/lib/hobix/out/rss.rb +115 -0
  23. data/lib/hobix/plugin/bloglines.rb +73 -0
  24. data/lib/hobix/plugin/calendar.rb +220 -0
  25. data/lib/hobix/plugin/flickr.rb +110 -0
  26. data/lib/hobix/plugin/recent_comments.rb +82 -0
  27. data/lib/hobix/plugin/sections.rb +91 -0
  28. data/lib/hobix/plugin/tags.rb +60 -0
  29. data/lib/hobix/publish/ping.rb +53 -0
  30. data/lib/hobix/publish/replicate.rb +283 -0
  31. data/lib/hobix/publisher.rb +18 -0
  32. data/lib/hobix/search/dictionary.rb +141 -0
  33. data/lib/hobix/search/porter_stemmer.rb +203 -0
  34. data/lib/hobix/search/simple.rb +209 -0
  35. data/lib/hobix/search/vector.rb +100 -0
  36. data/lib/hobix/storage/filesys.rb +398 -0
  37. data/lib/hobix/trackbacks.rb +94 -0
  38. data/lib/hobix/util/objedit.rb +193 -0
  39. data/lib/hobix/util/patcher.rb +155 -0
  40. data/lib/hobix/webapp/cli.rb +195 -0
  41. data/lib/hobix/webapp/htmlform.rb +107 -0
  42. data/lib/hobix/webapp/message.rb +177 -0
  43. data/lib/hobix/webapp/urigen.rb +141 -0
  44. data/lib/hobix/webapp/webrick-servlet.rb +90 -0
  45. data/lib/hobix/webapp.rb +723 -0
  46. data/lib/hobix/weblog.rb +860 -0
  47. data/lib/hobix.rb +223 -0
  48. metadata +87 -0
@@ -0,0 +1,661 @@
1
+ #
2
+ # = hobix/commandline.rb
3
+ #
4
+ # Hobix command-line weblog system.
5
+ #
6
+ # Copyright (c) 2003-2004 why the lucky stiff
7
+ # Copyright (c) 2005 MenTaLguY
8
+ #
9
+ # Written & maintained by why the lucky stiff <why@ruby-lang.org>
10
+ # Additional bits by MenTaLguY <mental@rydia.net>
11
+ #
12
+ # This program is free software, released under a BSD license.
13
+ # See COPYING for details.
14
+ #
15
+ #--
16
+ # $Id$
17
+ #++
18
+ require 'hobix'
19
+ require 'tempfile'
20
+
21
+ module Hobix
22
+ module CommandLine
23
+ ##
24
+ ## Locate RC
25
+ ##
26
+ [
27
+ [ENV['HOME'], ENV['HOME']],
28
+ [ENV['APPDATA'], File.join( ENV['APPDATA'] || "", 'Hobix' )]
29
+ ].each do |home_top, home_dir|
30
+ next unless home_top
31
+ if File.exists? home_top
32
+ File.makedirs( home_dir )
33
+ HOME_DIR = home_dir
34
+ break
35
+ end
36
+ end
37
+ RC = File.join( HOME_DIR, '.hobixrc' )
38
+
39
+ def CommandLine.extended( o )
40
+ #
41
+ # When extended we should get all required plugin for the
42
+ # whole Hobix stuff
43
+ #
44
+ return unless File.exists? RC
45
+
46
+ config = YAML::load( File.open( RC ) )
47
+
48
+ #
49
+ # Add a new instance variable to o
50
+ #
51
+ o.instance_variable_set( :@config, config )
52
+
53
+ #
54
+ # Eventually add user specified path
55
+ #
56
+ if config['libs']
57
+ config['libs'].each do |p|
58
+ if File.exists?( p ) && File.directory?( p )
59
+ $LOAD_PATH << p
60
+ else
61
+ warn "#{p} not loaded. Either inexistant or not a directory"
62
+ end
63
+ end
64
+ end
65
+
66
+ #
67
+ # And system wide path too
68
+ #
69
+ if File.exists?( Hobix::SHARE_PATH )
70
+ $LOAD_PATH << File.join(Hobix::SHARE_PATH,"lib")
71
+ end
72
+
73
+ #
74
+ # Load plugins if necessary
75
+ #
76
+ if config['requires']
77
+ config['requires'].each do |req|
78
+ Hobix::BasePlugin::start( req, self )
79
+ end
80
+ end
81
+
82
+ end
83
+
84
+ def gets; $stdin.gets; end
85
+ def puts( *args ); $stdin.puts( *args ); end
86
+
87
+ def login( config = nil )
88
+ config ||= RC
89
+ @config = File.open( config ) { |f| YAML::load( f ) } if File.exists? RC
90
+ setup unless @config
91
+ setup_personal unless @config['personal']
92
+ end
93
+
94
+ def config
95
+ @config
96
+ end
97
+
98
+ def save_config
99
+ File.open( RC, "w" ) do |f|
100
+ f.write @config.to_yaml
101
+ end
102
+ end
103
+
104
+ # Update your Hobix setup
105
+ def upgrade_app_explain; "Check for updates to Hobix."; end
106
+ def upgrade_app_args; []; end
107
+ def upgrade_app( config )
108
+ require 'rbconfig'
109
+ require 'open-uri'
110
+ c = ::Config::CONFIG.merge( config )
111
+ eval(open("http://go.hobix.com/").read)
112
+ end
113
+
114
+ # List all your weblogs
115
+ def blogs_weblog_explain; "List your weblogs."; end
116
+ def blogs_weblog_args; []; end
117
+ def blogs_weblog
118
+ if @config['weblogs'].respond_to? :sort
119
+ blogs = @config['weblogs'].sort
120
+ name_width = blogs.collect { |b| b[0].length }.max
121
+ tabular( blogs, [[-name_width, 0, 'weblog-name'], [-40, 1, 'path']] )
122
+ else
123
+ puts "** You have no blogs set up. Use `hobix setup_blogs' to get started."
124
+ end
125
+ end
126
+
127
+ def load_patchsets
128
+ File.open( "#{ Hobix::SHARE_PATH }/default-blog-modes.yaml" ) { |f| YAML::load( f ) }
129
+ end
130
+
131
+ # Create a new skeleton for a weblog
132
+ def create_weblog_explain; "Create a brand new weblog."; end
133
+ def create_weblog_args; ['weblog-name', '/path/to/']; end
134
+ def create_weblog( name, path )
135
+ @config['weblogs'] ||= {}
136
+ if @config['weblogs'][name]
137
+ print "*** Blog '#{ name }' exists already! Overwrite?? [y/N]: "
138
+ if gets.strip.upcase != 'Y'
139
+ puts "*** Creation of weblog `#{ name }' aborted."
140
+ return
141
+ end
142
+ end
143
+ path = File.expand_path( path )
144
+ puts <<-NOTE
145
+ |*** Creation of weblog `#{ name }' will add the following directory"
146
+ | structure to directory #{ path }"
147
+ |
148
+ | #{ path }
149
+ | hobix.yaml <- configuration
150
+ |
151
+ | entries/ <- edit and organize
152
+ | your news items,
153
+ | articles and so on.
154
+ |
155
+ | skel/ <- contains your
156
+ | templates
157
+ |
158
+ | htdocs/ <- html is created here,
159
+ | store all your images here,
160
+ | this is your viewable
161
+ | websyht
162
+ |
163
+ | lib/ <- extra hobix libraries
164
+ | (plugins) go here
165
+ |
166
+ NOTE
167
+ print "Create this structure? [y/N]: "
168
+ if gets.strip.upcase != 'Y'
169
+ puts "*** Creation of weblog `#{ name }' aborted."
170
+ return
171
+ end
172
+
173
+ modes = load_patchsets
174
+
175
+ puts "The default blog is available in the following modes:"
176
+ puts " #{ modes.keys.join( ', ' ) }"
177
+ puts
178
+ mode = nil
179
+ loop do
180
+ print "Modes: [Comma between each mode or Enter for none] "
181
+ mode = gets.strip.downcase
182
+ m = mode
183
+ break if mode.empty? or not mode.split( /,/ ).detect { |m| m.strip!; not modes.has_key?( m ) }
184
+ puts "*** No `#{ m }' mode available."
185
+ end
186
+
187
+ require 'fileutils'
188
+ FileUtils.makedirs path
189
+ FileUtils.cp_r Dir.glob( "#{ Hobix::SHARE_PATH }/default-blog/*" ), path
190
+
191
+ # apply any patches
192
+ patchlist = mode.split( /,/ ).map { |m| modes[m.strip] }.flatten.uniq
193
+ require 'hobix/util/patcher'
194
+ patchlist.collect! { |p| "#{ Hobix::SHARE_PATH }/default-blog.#{ p }.patch" }
195
+ patcher = Hobix::Util::Patcher[ *patchlist ]
196
+ patcher.apply( path )
197
+
198
+ hobix_yaml = File.join( path, "hobix.yaml" )
199
+ join_as_author( name, hobix_yaml )
200
+ weblog = Hobix::Weblog.load( hobix_yaml )
201
+ weblog.setup
202
+ edit_action( weblog )
203
+ end
204
+
205
+ # Add a weblog to local config
206
+ def add_weblog_explain; "Adds a pre-existing hobix weblog to your list."; end
207
+ def add_weblog_args; ['weblog-name', '/path/to/hobix.yaml']; end
208
+ def add_weblog( name, path )
209
+ @config['weblogs'] ||= {}
210
+ path = File.expand_path( path )
211
+ puts "*** Checking for existence of blog."
212
+ require 'hobix/weblog'
213
+ if File.directory? path
214
+ path = File.join( path, 'hobix.yaml' )
215
+ puts "*** Path is a directory, using `#{ path }'."
216
+ end
217
+ unless File.exists? path
218
+ puts "*** No file `#{ path }' found! Aborting."
219
+ return
220
+ end
221
+ join_as_author( name, path )
222
+ end
223
+
224
+ def join_as_author( name, path )
225
+ weblog = Hobix::Weblog.load( path )
226
+ puts "*** Joining blog `#{ weblog.title }', adding you as author."
227
+ weblog.authors[@config['username']] = @config['personal']
228
+ weblog.save( path )
229
+ @config['weblogs'][name] = path
230
+ save_config
231
+ end
232
+
233
+ # Update the site
234
+ def upgen_action_explain; "Update site with only the latest changes."; end
235
+ def upgen_action_args; ['weblog-name']; end
236
+ def upgen_action( weblog )
237
+ weblog.regenerate( :update )
238
+ end
239
+
240
+ # Regenerate the site
241
+ def regen_action_explain; "Regenerate the all the pages throughout the site."; end
242
+ def regen_action_args; ['weblog-name']; end
243
+ def regen_action( weblog )
244
+ weblog.regenerate
245
+ end
246
+
247
+ # Edit a weblog from local config
248
+ def edit_action_explain; "Edit weblog's configuration"; end
249
+ def edit_action_args; ['weblog-name']; end
250
+ def edit_action( weblog )
251
+ path = weblog.hobix_yaml
252
+ weblog = aorta( weblog )
253
+ return if weblog.nil?
254
+ weblog.save( path )
255
+ end
256
+
257
+ # Delete a weblog from local config
258
+ def del_weblog_explain; "Remove weblog from your list."; end
259
+ def del_weblog_args; ['weblog-name']; end
260
+ def del_weblog( name )
261
+ @config['weblogs'] ||= {}
262
+ @config['weblogs'].delete( name )
263
+ save_config
264
+ end
265
+
266
+ # Run a DRuby daemon for blogs in your configuration
267
+ def druby_weblog_explain; "Start the DRuby daemon for weblogs in your config."; end
268
+ def druby_weblog_args; []; end
269
+ def druby_weblog
270
+ if @config['weblogs']
271
+ unless @config['druby']
272
+ @config['druby'] = 'druby://:4081'
273
+ puts "** No drb url found, using #{ @config['druby'] }"
274
+ end
275
+ require 'drb'
276
+ blogs = {}
277
+ @config['weblogs'].each do |name, path|
278
+ blogs[name] = Hobix::Weblog.load path
279
+ end
280
+ require 'hobix/api'
281
+ api = Hobix::API.new blogs
282
+ DRb.start_service @config['druby'], api
283
+ DRb.thread.join
284
+ else
285
+ puts "** No blogs found in the configuration."
286
+ end
287
+ end
288
+
289
+ # Patch a weblog
290
+ def patch_action_explain; "Applies a patch to a weblog."; end
291
+ def patch_action_args; ['weblog-name', 'patch-name']; end
292
+ def patch_action( weblog, patch )
293
+ require 'hobix/util/patcher'
294
+ modes = load_patchsets
295
+ patchlist = modes[patch.strip].map { |p| "#{ Hobix::SHARE_PATH }/default-blog.#{ p }.patch" }
296
+ patcher = Hobix::Util::Patcher[ *patchlist ]
297
+ patcher.apply( weblog.path )
298
+ end
299
+
300
+ # List entries
301
+ def list_action_explain; "List all posts within a given path."; end
302
+ def list_action_args; ['weblog-name', 'search/path']; end
303
+ def list_action( weblog, inpath = '' )
304
+ entries = weblog.storage.find( :all => true, :inpath => inpath )
305
+ if entries.empty?
306
+ puts "** No posts found in the weblog for path '#{inpath}'."
307
+ else
308
+ tabular_entries( entries )
309
+ end
310
+ end
311
+
312
+ # Search (disabled in 0.4)
313
+ # def search_action_explain; "Search for words within posts of a given path."; end
314
+ # def search_action_args; ['weblog-name', 'word1,word2', 'search/path']; end
315
+ # def search_action( weblog, words, inpath = '' )
316
+ # entries = weblog.storage.find( :all => true, :inpath => inpath, :search => words.split( ',' ) )
317
+ # if entries.empty?
318
+ # puts "** No posts found in the weblog for path '#{inpath}'."
319
+ # else
320
+ # tabular_entries( entries )
321
+ # end
322
+ # end
323
+
324
+ # Post a new entry
325
+ def post_action_explain; "Add or edit a post with identifier 'shortName'.\n" +
326
+ "(You can use full paths. 'blog/weddings/anotherPatheticWedding')\n" +
327
+ "'type' specifies the type of entry to create if the entry does not\n" +
328
+ "already exist." ; end
329
+ def post_action_args; ['weblog-name', '[type]', 'shortName']; end
330
+ def post_action( weblog, *args )
331
+ if args.size == 1
332
+ entry_type = nil
333
+ entry_id = args[0]
334
+ elsif args.size == 2
335
+ ( entry_type, entry_id ) = args
336
+ else
337
+ raise ArgumentError, "Wrong number of arguments"
338
+ end
339
+
340
+ entry_class = weblog.entry_class(entry_type)
341
+ begin
342
+ entry = weblog.storage.load_entry( entry_id )
343
+ if entry_type and not entry.instance_of? entry_class
344
+ raise TypeError, "#{entry_id} already exists with a different type (#{entry.class})"
345
+ end
346
+ rescue Errno::ENOENT
347
+ entry = entry_class.new
348
+ entry.author = @config['username']
349
+ entry.title = entry_id.split( '/' ).
350
+ last.
351
+ gsub( /^\w|\W\w|_\w|[A-Z]/ ) { |up| " #{up[-1, 1].upcase}" }.
352
+ strip
353
+ end
354
+ entry = aorta( entry )
355
+ return if entry.nil?
356
+
357
+ begin
358
+ weblog.storage.save_entry( entry_id, entry )
359
+ rescue Errno::ENOENT
360
+ puts
361
+ puts "The category for #{entry_id} doesn't exist."
362
+ print "Create it [Yn]? "
363
+ response = gets.strip
364
+
365
+ if response.empty? or response =~ /^[Yy]/
366
+ weblog.storage.save_entry( entry_id, entry, true )
367
+ else
368
+ puts
369
+ print "Supply a different shortName [<Enter> to discard post]: "
370
+ response = gets.strip
371
+
372
+ if response.empty?
373
+ return nil
374
+ else
375
+ entry_id = response
376
+ retry
377
+ end
378
+ end
379
+ end
380
+ weblog.regenerate( :update ) if @config['post upgen']
381
+ end
382
+
383
+ ##
384
+ ## Setup user's RC
385
+ ##
386
+ def setup
387
+ @config = {}
388
+ puts "Welcome to hobix (a simple weblog tool). Looks like your"
389
+ puts "first time running hobix, eh? Time to get a bit of information"
390
+ puts "from you before you start using hobix. (All of this will be stored"
391
+ puts "in the file #{ Hobix::CommandLine::RC } if you need to edit.)"
392
+ puts
393
+
394
+ username = ''
395
+ default_user = ''
396
+ user_prompt = 'Your hobix username'
397
+ if ENV['USER']
398
+ default_user = ENV['USER']
399
+ user_prompt << " [<Enter> for #{ ENV['USER'] }]"
400
+ end
401
+ while username.empty?
402
+ puts
403
+ print "#{ user_prompt }: "
404
+ username = gets.strip
405
+ if username.empty?
406
+ username = default_user
407
+ end
408
+ end
409
+ @config['username'] = username
410
+
411
+ puts
412
+ puts "Your EDITOR environment variable is set to '#{ ENV['EDITOR'] }'."
413
+ puts "You can edit entries with your EDITOR or you can just use hobix."
414
+ puts "** NOTE: If you don't use your own editor, then you will be using"
415
+ puts " the Hobix built-in object editor, which is highly experimental"
416
+ puts " and may not work on your platform.)"
417
+ print "Use your EDITOR to edit entries? [Y/n]: "
418
+ editor = gets.strip.upcase
419
+
420
+ if editor == 'N'
421
+ @config['use editor'] = false
422
+ else
423
+ @config['use editor'] = true
424
+ end
425
+
426
+ puts
427
+ puts "After posting a new entry, would you like Hobix to automatically"
428
+ print "update the site? [Y/n]: "
429
+ post_upgen = gets.strip.upcase
430
+
431
+ if post_upgen == 'N'
432
+ @config['post upgen'] = false
433
+ else
434
+ @config['post upgen'] = true
435
+ end
436
+ save_config
437
+ end
438
+
439
+ ##
440
+ ## Setup personal information
441
+ ##
442
+ def setup_personal
443
+ @config['personal'] ||= {}
444
+ puts
445
+ puts "Your personal information has not been setup yet."
446
+ [['name', 'Your real name', true],
447
+ ['url', 'URL to your home page', false],
448
+ ['email', 'Your e-mail address', false]].each do |k, txt, req|
449
+ print "#{ txt }: "
450
+ val = gets.strip
451
+ retry if req and val.empty?
452
+ @config['personal'][k] = val
453
+ end
454
+ save_config
455
+ end
456
+
457
+ ##
458
+ ## Extra setup, triggered upon installation
459
+ ##
460
+ def setup_blogs
461
+ puts
462
+ puts " === Joining an existing weblog? ==="
463
+ puts "If you want to join an existing hobix weblog, we can do that now."
464
+ puts "Each weblog needs a name and a path. Use <ENTER> at any prompt"
465
+ puts "to simply move on."
466
+ loop do
467
+ puts
468
+ puts "Short name for weblog, used on the command line (i.e. hobix upgen blogName)."
469
+ print ": "
470
+ blogname = gets.strip
471
+ break if blogname.empty?
472
+
473
+ print "Path to weblog's hobix.yaml `#{ blogname }': "
474
+ blogpath = gets.strip
475
+ if blogpath.empty?
476
+ puts "*** Aborting setup of weblog `#{ blogname }'."
477
+ break
478
+ end
479
+ add_weblog( blogname, blogpath )
480
+ end
481
+
482
+ puts "To setup more weblogs later, use: hobix add #{ add_weblog_args.join( ' ' ) }"
483
+ puts
484
+ puts " === Create a new weblog? ==="
485
+ puts "If you want to create a new hobix weblog, we can do that now."
486
+ puts "Each weblog needs a name and a path. Use <ENTER> at any prompt"
487
+ puts "to simply move on."
488
+ loop do
489
+ puts
490
+ puts "Short name for weblog, used on the command line (i.e. hobix upgen blogName)."
491
+ print ": "
492
+ blogname = gets.strip
493
+ break if blogname.empty?
494
+
495
+ print "Path to create weblog `#{ blogname }': "
496
+ blogpath = gets.strip
497
+ if blogpath.empty?
498
+ puts "*** Aborting creation of weblog `#{ blogname }'."
499
+ break
500
+ end
501
+ create_weblog( blogname, blogpath )
502
+ end
503
+ puts "To create more weblogs later, use: hobix create #{ create_weblog_args.join( ' ' ) }"
504
+ puts
505
+ end
506
+
507
+ def aorta( obj )
508
+ if @config['use editor']
509
+ # I am quite displeased that Tempfile.open eats its blocks result,
510
+ # thereby necessitating this blecherous construct...
511
+ tempfile = nil
512
+ Tempfile.open("hobix.post") { |tempfile| tempfile << obj.to_yaml }
513
+
514
+ begin
515
+ created = File.mtime( tempfile.path )
516
+ system( "#{ ENV['EDITOR'] || 'vi' } #{ tempfile.path }" )
517
+ return nil unless File.exists?( tempfile.path )
518
+
519
+ if created < File.mtime( tempfile.path )
520
+ obj = YAML::load( tempfile.open )
521
+ else
522
+ puts "** Edit aborted"
523
+ obj = nil
524
+ end
525
+ rescue StandardError => e
526
+ puts "There was an error saving the entry: #{ e.class }: #{ e.message }"
527
+ print "Re-edit [Yn]? "
528
+ response = gets.strip
529
+ if response.empty? or response =~ /^[Yy]/
530
+ retry
531
+ else
532
+ puts "** Edit aborted"
533
+ obj = nil
534
+ end
535
+ ensure
536
+ # tempfile will get closed/unlinked when it's collected anyway;
537
+ # may as well do it here to provide some determinism for the user
538
+ begin
539
+ tempfile.close true
540
+ rescue
541
+ end
542
+ end
543
+ else
544
+ require 'hobix/util/objedit'
545
+ obj = Hobix::Util::ObjEdit( obj )
546
+ end
547
+ obj
548
+ end
549
+
550
+ def tabular( table, fields, desc = nil )
551
+ field_widths = fields.collect do |width, id, title|
552
+ ([width.abs, title.length].max + 1) * ( width / width.abs )
553
+ end
554
+ client_format = field_widths.collect { |width| "%#{ width}s"}.join( ': ')
555
+ puts client_format % fields.collect { |width, id, title| title }
556
+ puts field_widths.collect { |width| "-" * width.abs }.join( ':-' )
557
+ table.each do |row|
558
+ puts client_format % fields.collect { |width, id, title| row[ id ] }
559
+ if desc
560
+ puts row[ desc ]
561
+ puts
562
+ end
563
+ end
564
+ end
565
+
566
+ def tabular_entries( entries )
567
+ entries.sort { |e1, e2| e1.id <=> e2.id }
568
+ name_width = entries.collect { |e| e.id.length }.max
569
+ rows = entries.inject([]) { |rows, entry| rows << [entry.id, entry.created] }
570
+ tabular( rows, [[-name_width, 0, 'shortName'], [-34, 1, 'created']] )
571
+ end
572
+
573
+ def puts( str = '' )
574
+ Kernel::puts str.gsub( /^\s+\|/, '' )
575
+ end
576
+
577
+ ##
578
+ ## Hobix over the wire
579
+ ##
580
+ def http( *args )
581
+ p http_get( *args )
582
+ end
583
+
584
+ def http_get( weblog, *args )
585
+ require 'net/http'
586
+ response =
587
+ Net::HTTP.new( weblog.host, weblog.port ).start do |http|
588
+ http.get( File.expand_path( "remote/#{ args.join '/' }", weblog.path ) )
589
+ end
590
+ case response
591
+ when Net::HTTPSuccess then YAML::load( response.body )
592
+ else
593
+ response.error!
594
+ end
595
+ end
596
+
597
+ def http_post( weblog, url, obj )
598
+ require 'net/http'
599
+ response =
600
+ Net::HTTP.new( weblog.host, weblog.port ).start do |http|
601
+ http.post( File.expand_path( "remote/#{ url }", weblog.path ), obj.to_yaml, "Content-Type" => "text/yaml" )
602
+ end
603
+ case response
604
+ when Net::HTTPSuccess then YAML::load( response.body )
605
+ else
606
+ response.error!
607
+ end
608
+ end
609
+
610
+ def http_post_remote( weblog, entry_id )
611
+ entry = http_get( weblog, "post", entry_id )
612
+ if entry.class == Errno::ENOENT
613
+ entry = http_get( weblog, 'new' )
614
+ entry.author = @config['username']
615
+ entry.title = entry_id.split( '/' ).
616
+ last.
617
+ gsub( /^\w|_\w|[A-Z]/ ) { |up| " #{up[-1, 1].upcase}" }.
618
+ strip
619
+ end
620
+ entry = aorta( entry )
621
+ return if entry.nil?
622
+
623
+ rsp = http_post( weblog, "post/#{ entry_id }", entry )
624
+ http_get( weblog, "upgen" ) if @config['post upgen']
625
+ p rsp
626
+ end
627
+
628
+ def http_edit_remote( weblog )
629
+ config = http_get( weblog, "edit" )
630
+ config = aorta( config )
631
+ return if config.nil?
632
+ p http_post( weblog, "edit", config )
633
+ end
634
+
635
+ def http_list_remote( weblog, inpath = '' )
636
+ require 'hobix/storage/filesys'
637
+ entries = http_get( weblog, 'list', inpath )
638
+ if entries.empty?
639
+ puts "** No posts found in the weblog for path '#{inpath}'."
640
+ else
641
+ tabular_entries( entries )
642
+ end
643
+ end
644
+
645
+ def http_search_remote( weblog, words, inpath = '' )
646
+ require 'hobix/storage/filesys'
647
+ entries = http_get( weblog, 'search', words, inpath )
648
+ if entries.empty?
649
+ puts "** No posts found in the weblog for path '#{inpath}'."
650
+ else
651
+ tabular_entries( entries )
652
+ end
653
+ end
654
+
655
+ def http_patch_remote( *args )
656
+ puts "** Weblogs cannot be patched over the wire yet."
657
+ exit
658
+ end
659
+ end
660
+ end
661
+