# hx/commandline - Commandline interface for Hx # # Copyright (c) 2009-2010 MenTaLguY # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. require 'hx' require 'ostruct' require 'optparse' require 'pathname' require 'tempfile' module Hx module CLI DEFAULT_CONFIG_FILENAME = "config.hx" def self.main(*args) options = OpenStruct.new options.config_file = nil OptionParser.new do |opts| opts.banner = < #{path}" if written end end def self.cmd_editup(site, entry_spec) cmd_edit(site, entry_spec) cmd_upgen(site) end def self.cmd_postup(site, entry_spec) cmd_post(site, entry_spec) cmd_upgen(site) end def self.parse_entry_spec(entry_spec) source_name, path = entry_spec.split(':', 2) raise "Invalid entry specification #{entry_spec}" unless path return source_name, path end def self.cmd_edit(site, entry_spec) source_name, path = parse_entry_spec(entry_spec) do_edit(site, source_name, path, nil) end def self.cmd_post(site, entry_spec) source_name, path = parse_entry_spec(entry_spec) prototype = { 'title' => Hx.make_default_title(site.options, path), 'author' => Hx.get_default_author(site.options), 'content' => "" } do_edit(site, source_name, path, prototype) end def self.do_edit(site, source_name, path, prototype) source = site.sources[source_name] raise ArgumentError, "No such source #{source_name}" unless source catch(:unchanged) do begin tempfile = Tempfile.new('hx-entry') original_text = nil loop do begin source.edit_entry(path, prototype) do |text| unless original_text File.open(tempfile.path, 'w') { |s| s << text } original_text = text end # TODO: deal with conflict if text != original_text editor = ENV['EDITOR'] || 'vi' system(editor, tempfile.path) new_text = File.open(tempfile.path, 'r') { |s| s.read } throw(:unchanged) if new_text == text new_text end break rescue Exception => e $stderr.puts e $stderr.print "Edit failed; retry? [Yn] " $stderr.flush response = $stdin.gets.strip raise unless response =~ /^y/i end end ensure tempfile.unlink end end end end end