#!/usr/bin/env ruby require 'backpack_calendar' BACKPACK_ICON = File.join( ENV['HOME'], 'Library', 'Application Support', %w{Quicksilver PlugIns}, 'Backpack Module.qsplugin', %w{Contents Resources Backpack.png} ) APPLICATION = "Backpack Calendar" KEY = "Backpack API" def notify(message, opts = {}) notifications = %q{{"Confirmation", "Error"}} opts = { :type => :confirmation, :title => APPLICATION, :sticky => false, }.merge(opts) message.gsub!(/\"/, '\"') # escape double quotes for AppleScript image = File.exist?(BACKPACK_ICON) ? %{image from location "#{BACKPACK_ICON}"} : "" cmd = <<-END.gsub(/^\s+/m, '') /usr/bin/osascript <&1} token = password.grep(/password:/).first.match(/: "([^"]+)"/)[1] username = password.grep(/"acct"[^=]*=/).first.match(/="([^"]+)"/)[1] rescue msg = "No key found in keychain. Add a key called '#{KEY}' " + "with your Backpack user name as the account name " + "and your API token as the password." notify(msg, :type => :error, :sticky => true) end # event text post = ARGV.join(" ") # calendar list session = Backpack::Calendar.new("http://#{username}.backpackit.com", token) begin calendars = session.calendars rescue notify("Login failed. Check your API token.", :type => :error) exit end # reminder? post.sub!(/(\s+\+rem.*)\b/, '') remind = !$1.nil? # pick calendar post.sub!(/\s*\[([^\]]+)\]/, '') calendar = if $1 calendars.find do |calendar| calendar.name.downcase == $1.downcase end or calendars.first else calendars.first end # post it response = session.post_calendar_event( calendar.id, :title => post, :remind => remind ) if response event_id = response.match(%r{/(\d+).xml}).captures.first event = session.calendar_event(event_id) event_time = event.all_day ? event.occurs_at : event.occurs_at.localtime now = Time.now date_format = if event_time.to_a[3..5] == now.to_a[3..5] nil # today elsif (event_time - 86400).to_a[3..5] == now.to_a[3..5] "tomorrow" elsif (event_time - now) < 604800 # one week "%A" # day of the week elsif now.year != event_time.year "%e %B %Y" # 14 April 2007 else "%e %B" # 14 April end date = date_format && event_time.strftime(date_format) notify( [date, event.title, event.remind ? "reminder" : nil].compact.join("\n") ) else notify("Event post failed", :type => :error) end