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