| Module | Hobix::CommandLine |
| In: |
lib/hobix/commandline.rb
|
| HOME_DIR | = | home_dir |
| RC | = | File.join( HOME_DIR, '.hobixrc' ) |
# File lib/hobix/commandline.rb, line 39
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
# File lib/hobix/commandline.rb, line 223
223: def add_weblog( name, path )
224: @config['weblogs'] ||= {}
225: path = File.expand_path( path )
226: puts "*** Checking for existence of blog."
227: require 'hobix/weblog'
228: if File.directory? path
229: path = File.join( path, 'hobix.yaml' )
230: puts "*** Path is a directory, using `#{ path }'."
231: end
232: unless File.exists? path
233: puts "*** No file `#{ path }' found! Aborting."
234: return
235: end
236: join_as_author( name, path )
237: end
# File lib/hobix/commandline.rb, line 222
222: def add_weblog_args; ['weblog-name', '/path/to/hobix.yaml']; end
# File lib/hobix/commandline.rb, line 524
524: def aorta( obj )
525: if @config['use editor']
526: # I am quite displeased that Tempfile.open eats its blocks result,
527: # thereby necessitating this blecherous construct...
528: tempfile = nil
529: Tempfile.open("hobix.post") { |tempfile| tempfile << obj.to_yaml }
530:
531: begin
532: created = File.mtime( tempfile.path )
533: system( "#{ ENV['EDITOR'] || 'vi' } #{ tempfile.path }" )
534: return nil unless File.exists?( tempfile.path )
535:
536: if created < File.mtime( tempfile.path )
537: obj = YAML::load( tempfile.open )
538: else
539: puts "** Edit aborted"
540: obj = nil
541: end
542: rescue StandardError => e
543: puts "There was an error saving the entry: #{ e.class }: #{ e.message }"
544: print "Re-edit [Yn]? "
545: response = gets.strip
546: if response.empty? or response =~ /^[Yy]/
547: retry
548: else
549: puts "** Edit aborted"
550: obj = nil
551: end
552: ensure
553: # tempfile will get closed/unlinked when it's collected anyway;
554: # may as well do it here to provide some determinism for the user
555: begin
556: tempfile.close true
557: rescue
558: end
559: end
560: else
561: require 'hobix/util/objedit'
562: obj = Hobix::Util::ObjEdit( obj )
563: end
564: obj
565: end
# File lib/hobix/commandline.rb, line 131
131: def blogs_weblog
132: if @config['weblogs'].respond_to?( :sort ) && !@config['weblogs'].empty?
133: blogs = @config['weblogs'].sort
134: name_width = blogs.collect { |b| b[0].length }.max
135: tabular( blogs, [[-name_width, 0, 'weblog-name'], [-40, 1, 'path']] )
136: else
137: puts "** You have no blogs set up. Use `hobix setup_blogs' to get started."
138: end
139: end
List all your weblogs
# File lib/hobix/commandline.rb, line 129
129: def blogs_weblog_explain; "List your weblogs."; end
# File lib/hobix/commandline.rb, line 148
148: def create_weblog( name, path )
149: @config['weblogs'] ||= {}
150: if @config['weblogs'][name]
151: print "*** Blog '#{ name }' exists already! Overwrite?? [y/N]: "
152: if gets.strip.upcase != 'Y'
153: puts "*** Creation of weblog `#{ name }' aborted."
154: return
155: end
156: end
157: path = File.expand_path( path )
158: puts "|*** Creation of weblog `\#{ name }' will add the following directory\"\n| structure to directory \#{ path }\"\n|\n| \#{ path }\n| hobix.yaml <- configuration\n|\n| entries/ <- edit and organize\n| your news items,\n| articles and so on.\n|\n| skel/ <- contains your\n| templates\n|\n| htdocs/ <- html is created here,\n| store all your images here,\n| this is your viewable\n| websyht\n|\n| lib/ <- extra hobix libraries\n| (plugins) go here\n|\n"
159: print "Create this structure? [y/N]: "
160: if gets.strip.upcase != 'Y'
161: puts "*** Creation of weblog `#{ name }' aborted."
162: return
163: end
164:
165: modes = load_patchsets
166:
167: puts "The default blog is available in the following modes:"
168: puts " #{ modes.keys.join( ', ' ) }"
169: puts
170: mode = nil
171: loop do
172: print "Modes: [Comma between each mode or Enter for none] "
173: mode = gets.strip.downcase
174: m = mode
175: break if mode.empty? or not mode.split( /,/ ).detect { |m| m.strip!; not modes.has_key?( m ) }
176: puts "*** No `#{ m }' mode available."
177: end
178:
179: require 'fileutils'
180: FileUtils.makedirs path
181: FileUtils.cp_r Dir.glob( "#{ Hobix::SHARE_PATH }/default-blog/*" ), path
182:
183: # apply any patches
184: patchlist = mode.split( /,/ ).map { |m| modes[m.strip] }.flatten.uniq
185: require 'hobix/util/patcher'
186: patchlist.collect! { |p| "#{ Hobix::SHARE_PATH }/default-blog.#{ p }.patch" }
187: patcher = Hobix::Util::Patcher[ *patchlist ]
188: patcher.apply( path )
189:
190: hobix_yaml = File.join( path, "hobix.yaml" )
191: join_as_author( name, hobix_yaml )
192: weblog = Hobix::Weblog.load( hobix_yaml )
193: weblog.setup
194: edit_action( weblog )
195: end
# File lib/hobix/commandline.rb, line 147
147: def create_weblog_args; ['weblog-name', '/path/to/']; end
Create a new skeleton for a weblog
# File lib/hobix/commandline.rb, line 146
146: def create_weblog_explain; "Create a brand new weblog."; end
# File lib/hobix/commandline.rb, line 275
275: def del_weblog( name )
276: @config['weblogs'] ||= {}
277: @config['weblogs'].delete( name )
278: save_config
279: end
# File lib/hobix/commandline.rb, line 284
284: def druby_weblog
285: if @config['weblogs']
286: unless @config['druby']
287: @config['druby'] = 'druby://:4081'
288: puts "** No drb url found, using #{ @config['druby'] }"
289: end
290: require 'drb'
291: blogs = {}
292: @config['weblogs'].each do |name, path|
293: blogs[name] = Hobix::Weblog.load path
294: end
295: require 'hobix/api'
296: api = Hobix::API.new blogs
297: DRb.start_service @config['druby'], api
298: DRb.thread.join
299: else
300: puts "** No blogs found in the configuration."
301: end
302: end
Run a DRuby daemon for blogs in your configuration
# File lib/hobix/commandline.rb, line 282
282: def druby_weblog_explain; "Start the DRuby daemon for weblogs in your config."; end
# File lib/hobix/commandline.rb, line 265
265: def edit_action( weblog )
266: path = weblog.hobix_yaml
267: weblog = aorta( weblog )
268: return if weblog.nil?
269: weblog.save( path )
270: end
# File lib/hobix/commandline.rb, line 645
645: def http_edit_remote( weblog )
646: config = http_get( weblog, "edit" )
647: config = aorta( config )
648: return if config.nil?
649: p http_post( weblog, "edit", config )
650: end
# File lib/hobix/commandline.rb, line 601
601: def http_get( weblog, *args )
602: require 'net/http'
603: response =
604: Net::HTTP.new( weblog.host, weblog.port ).start do |http|
605: http.get( File.expand_path( "remote/#{ args.join '/' }", weblog.path ) )
606: end
607: case response
608: when Net::HTTPSuccess then YAML::load( response.body )
609: else
610: response.error!
611: end
612: end
# File lib/hobix/commandline.rb, line 652
652: def http_list_remote( weblog, inpath = '' )
653: require 'hobix/storage/filesys'
654: entries = http_get( weblog, 'list', inpath )
655: if entries.empty?
656: puts "** No posts found in the weblog for path '#{inpath}'."
657: else
658: tabular_entries( entries )
659: end
660: end
# File lib/hobix/commandline.rb, line 672
672: def http_patch_remote( *args )
673: puts "** Weblogs cannot be patched over the wire yet."
674: exit
675: end
# File lib/hobix/commandline.rb, line 614
614: def http_post( weblog, url, obj )
615: require 'net/http'
616: response =
617: Net::HTTP.new( weblog.host, weblog.port ).start do |http|
618: http.post( File.expand_path( "remote/#{ url }", weblog.path ), obj.to_yaml, "Content-Type" => "text/yaml" )
619: end
620: case response
621: when Net::HTTPSuccess then YAML::load( response.body )
622: else
623: response.error!
624: end
625: end
# File lib/hobix/commandline.rb, line 627
627: def http_post_remote( weblog, entry_id )
628: entry = http_get( weblog, "post", entry_id )
629: if entry.class == Errno::ENOENT
630: entry = http_get( weblog, 'new' )
631: entry.author = @config['username']
632: entry.title = entry_id.split( '/' ).
633: last.
634: gsub( /^\w|_\w|[A-Z]/ ) { |up| " #{up[-1, 1].upcase}" }.
635: strip
636: end
637: entry = aorta( entry )
638: return if entry.nil?
639:
640: rsp = http_post( weblog, "post/#{ entry_id }", entry )
641: http_get( weblog, "upgen" ) if @config['post upgen']
642: p rsp
643: end
# File lib/hobix/commandline.rb, line 662
662: def http_search_remote( weblog, words, inpath = '' )
663: require 'hobix/storage/filesys'
664: entries = http_get( weblog, 'search', words, inpath )
665: if entries.empty?
666: puts "** No posts found in the weblog for path '#{inpath}'."
667: else
668: tabular_entries( entries )
669: end
670: end
# File lib/hobix/commandline.rb, line 239
239: def join_as_author( name, path )
240: weblog = Hobix::Weblog.load( path )
241: puts "*** Joining blog `#{ weblog.title }', adding you as author."
242: weblog.authors[@config['username']] = @config['personal']
243: weblog.save( path )
244: @config['weblogs'][name] = path
245: save_config
246: end
# File lib/hobix/commandline.rb, line 318
318: def list_action( weblog, inpath = '' )
319: entries = weblog.storage.find( :all => true, :inpath => inpath )
320: if entries.empty?
321: puts "** No posts found in the weblog for path '#{inpath}'."
322: else
323: tabular_entries( entries )
324: end
325: end
# File lib/hobix/commandline.rb, line 317
317: def list_action_args; ['weblog-name', 'search/path']; end
List entries
# File lib/hobix/commandline.rb, line 316
316: def list_action_explain; "List all posts within a given path."; end
# File lib/hobix/commandline.rb, line 141
141: def load_patchsets
142: File.open( "#{ Hobix::SHARE_PATH }/default-blog-modes.yaml" ) { |f| YAML::load( f ) }
143: end
# File lib/hobix/commandline.rb, line 87
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
# File lib/hobix/commandline.rb, line 307
307: def patch_action( weblog, patch )
308: require 'hobix/util/patcher'
309: modes = load_patchsets
310: patchlist = modes[patch.strip].map { |p| "#{ Hobix::SHARE_PATH }/default-blog.#{ p }.patch" }
311: patcher = Hobix::Util::Patcher[ *patchlist ]
312: patcher.apply( weblog.path )
313: end
# File lib/hobix/commandline.rb, line 306
306: def patch_action_args; ['weblog-name', 'patch-name']; end
Patch a weblog
# File lib/hobix/commandline.rb, line 305
305: def patch_action_explain; "Applies a patch to a weblog."; end
# File lib/hobix/commandline.rb, line 345
345: def post_action( weblog, *args )
346: if args.size == 1
347: entry_type = nil
348: entry_id = args[0]
349: elsif args.size == 2
350: ( entry_type, entry_id ) = args
351: else
352: raise ArgumentError, "Wrong number of arguments"
353: end
354:
355: entry_class = weblog.entry_class(entry_type)
356: begin
357: entry = weblog.storage.load_entry( entry_id )
358: if entry_type and not entry.instance_of? entry_class
359: raise TypeError, "#{entry_id} already exists with a different type (#{entry.class})"
360: end
361: rescue Errno::ENOENT
362: entry = entry_class.new
363: entry.author = @config['username']
364: entry.title = entry_id.split( '/' ).
365: last.
366: gsub( /^\w|\W\w|_\w|[A-Z]/ ) { |up| " #{up[-1, 1].upcase}" }.
367: strip
368: end
369: entry = aorta( entry )
370: return if entry.nil?
371:
372: begin
373: weblog.storage.save_entry( entry_id, entry )
374: rescue Errno::ENOENT
375: puts
376: puts "The category for #{entry_id} doesn't exist."
377: print "Create it [Yn]? "
378: response = gets.strip
379:
380: if response.empty? or response =~ /^[Yy]/
381: weblog.storage.save_entry( entry_id, entry, true )
382: else
383: puts
384: print "Supply a different shortName [<Enter> to discard post]: "
385: response = gets.strip
386:
387: if response.empty?
388: return nil
389: else
390: entry_id = response
391: retry
392: end
393: end
394: end
395: weblog.regenerate( :update ) if @config['post upgen']
396: end
# File lib/hobix/commandline.rb, line 344
344: def post_action_args; ['weblog-name', '[type]', 'shortName']; end
Post a new entry
# File lib/hobix/commandline.rb, line 340
340: def post_action_explain; "Add or edit a post with identifier 'shortName'.\n" +
341: "(You can use full paths. 'blog/weddings/anotherPatheticWedding')\n" +
342: "'type' specifies the type of entry to create if the entry does not\n" +
343: "already exist." ; end
# File lib/hobix/commandline.rb, line 590
590: def puts( str = '' )
591: Kernel::puts str.gsub( /^\s+\|/, '' )
592: end
# File lib/hobix/commandline.rb, line 258
258: def regen_action( weblog )
259: weblog.regenerate
260: end
Regenerate the site
# File lib/hobix/commandline.rb, line 256
256: def regen_action_explain; "Regenerate the all the pages throughout the site."; end
# File lib/hobix/commandline.rb, line 98
98: def save_config
99: File.open( RC, "w" ) do |f|
100: f.write @config.to_yaml
101: end
102: end
Setup user‘s RC
# File lib/hobix/commandline.rb, line 401
401: def setup
402: @config = {}
403: puts "Welcome to hobix (a simple weblog tool). Looks like your"
404: puts "first time running hobix, eh? Time to get a bit of information"
405: puts "from you before you start using hobix. (All of this will be stored"
406: puts "in the file #{ Hobix::CommandLine::RC } if you need to edit.)"
407: puts
408:
409: username = ''
410: default_user = ''
411: user_prompt = 'Your hobix username'
412: if ENV['USER']
413: default_user = ENV['USER']
414: user_prompt << " [<Enter> for #{ ENV['USER'] }]"
415: end
416: while username.empty?
417: puts
418: print "#{ user_prompt }: "
419: username = gets.strip
420: if username.empty?
421: username = default_user
422: end
423: end
424: @config['username'] = username
425:
426: puts
427: puts "Your EDITOR environment variable is set to '#{ ENV['EDITOR'] }'."
428: puts "You can edit entries with your EDITOR or you can just use hobix."
429: puts "** NOTE: If you don't use your own editor, then you will be using"
430: puts " the Hobix built-in object editor, which is highly experimental"
431: puts " and may not work on your platform.)"
432: print "Use your EDITOR to edit entries? [Y/n]: "
433: editor = gets.strip.upcase
434:
435: if editor == 'N'
436: @config['use editor'] = false
437: else
438: @config['use editor'] = true
439: end
440:
441: puts
442: puts "After posting a new entry, would you like Hobix to automatically"
443: print "update the site? [Y/n]: "
444: post_upgen = gets.strip.upcase
445:
446: if post_upgen == 'N'
447: @config['post upgen'] = false
448: else
449: @config['post upgen'] = true
450: end
451: save_config
452: end
Extra setup, triggered upon installation
# File lib/hobix/commandline.rb, line 475
475: def setup_blogs
476: puts
477: puts " === Joining an existing weblog? ==="
478: puts "If you want to join an existing hobix weblog, we can do that now."
479: puts "Each weblog needs a name and a path. Use <ENTER> at any prompt"
480: puts "to simply move on."
481: puts
482: loop do
483: puts "Short name for weblog, used on the command line (i.e. hobix upgen blogName)."
484: print ": "
485: blogname = gets.strip
486: break if blogname.empty?
487:
488: print "Path to weblog's hobix.yaml `#{ blogname }': "
489: blogpath = gets.strip
490: if blogpath.empty?
491: puts "*** Aborting setup of weblog `#{ blogname }'."
492: break
493: end
494: add_weblog( blogname, blogpath )
495: puts
496: puts "** Add another weblog?"
497: end
498:
499: puts "To setup more weblogs later, use: hobix add #{ add_weblog_args.join( ' ' ) }"
500: puts
501: puts " === Create a new weblog? ==="
502: puts "If you want to create a new hobix weblog, we can do that now."
503: puts "Each weblog needs a name and a path. Use <ENTER> at any prompt"
504: puts "to simply move on."
505: loop do
506: puts
507: puts "Short name for weblog, used on the command line (i.e. hobix upgen blogName)."
508: print ": "
509: blogname = gets.strip
510: break if blogname.empty?
511:
512: print "Path to create weblog `#{ blogname }': "
513: blogpath = gets.strip
514: if blogpath.empty?
515: puts "*** Aborting creation of weblog `#{ blogname }'."
516: break
517: end
518: create_weblog( blogname, blogpath )
519: end
520: puts "To create more weblogs later, use: hobix create #{ create_weblog_args.join( ' ' ) }"
521: puts
522: end
Setup personal information
# File lib/hobix/commandline.rb, line 457
457: def setup_personal
458: @config['personal'] ||= {}
459: puts
460: puts "Your personal information has not been setup yet."
461: [['name', 'Your real name', true],
462: ['url', 'URL to your home page', false],
463: ['email', 'Your e-mail address', false]].each do |k, txt, req|
464: print "#{ txt }: "
465: val = gets.strip
466: retry if req and val.empty?
467: @config['personal'][k] = val
468: end
469: save_config
470: end
# File lib/hobix/commandline.rb, line 567
567: def tabular( table, fields, desc = nil )
568: field_widths = fields.collect do |width, id, title|
569: ([width.abs, title.length].max + 1) * ( width / width.abs )
570: end
571: client_format = field_widths.collect { |width| "%#{ width}s"}.join( ': ')
572: puts client_format % fields.collect { |width, id, title| title }
573: puts field_widths.collect { |width| "-" * width.abs }.join( ':-' )
574: table.each do |row|
575: puts client_format % fields.collect { |width, id, title| row[ id ] }
576: if desc
577: puts row[ desc ]
578: puts
579: end
580: end
581: end
# File lib/hobix/commandline.rb, line 583
583: def tabular_entries( entries )
584: entries.sort { |e1, e2| e1.id <=> e2.id }
585: name_width = entries.collect { |e| e.id.length }.max
586: rows = entries.inject([]) { |rows, entry| rows << [entry.id, entry.created] }
587: tabular( rows, [[-name_width, 0, 'shortName'], [-34, 1, 'created']] )
588: end
# File lib/hobix/commandline.rb, line 251
251: def upgen_action( weblog )
252: weblog.regenerate( :update )
253: end
Update the site
# File lib/hobix/commandline.rb, line 249
249: def upgen_action_explain; "Update site with only the latest changes."; end
# File lib/hobix/commandline.rb, line 107
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: puts "** Retrieving a new Hobix version is disabled in Debian, " +
113: "please update via apt/dpkg!"
114: puts "Only performing administrative upgrade task (if any)..."
115:
116: # Now look at all blogs and delete entries/index.{hobix,search}
117: if @config['weblogs'].respond_to? :sort
118: blogs = @config['weblogs'].sort
119: blogs.each do |e|
120: weblog = Hobix::Weblog.load( e[1] )
121: puts "Removing index.search and index.hobix from #{weblog.entry_path}"
122: File.safe_unlink( File.join(weblog.entry_path, "index.search"),
123: File.join(weblog.entry_path, "index.hobix"))
124: end
125: end
126: end