Thursday, January 17, 2013

Push to iCal, and avocado.io

This is a terrible one you guys. I feel I need to apologize in advance. This script is poorly put together, has errors, and is generally not of a good quality.It's an amalgam of haberdash. Suprisingly enough though… it works. I wanted to be able to, create an alarm event in iCal, that also pushed to avocado. Avocado.io is a shared list for "you and your favorite person", I had a similiar idea and it's why I purchased the domain shoprlistr.com, however I clearly didn't pull the trigger fast enough on that one…or at all for that matter. I knew that pushing to ical would be easy with applescript, so what I did was devoted some time to creating a script that did just that. THERE IS A CODE UPDATE TO THIS POST

<<END
set now to (current date)
 set eStart to now + $minutes_to_add * minutes
 set eEnd to now + $two_more * minutes
 set eName to \" $name \"
 set alarmTime to 0 -- alarm at the exact moment of the event

 tell application \"iCal\"
  set newEvent to make new event at end of events of calendar \"Home\" with properties {summary:eName, start date:eStart, end date:eEnd}
   make new display alarm at end of display alarms of newEvent with properties {trigger interval:alarmTime}
   end tell
END
I interspersed some php, essentially to take arguments at the command line. And some things with Unix Epoch time. iCal wanted an argument in minutes after the current time, which was easy to do, because of the convience of Unix Epoch Time. Honestly is there a better way to express time? (Clearly seconds since the advent of unix, in 1970 January, is superior to all other ways of telling time.) So essentially I took the code for the signing in of Gaucomole,(the API for avocado.io), and then made some sort of ham fisted half ass post. And what I was left with is the script below, which works, with plenty of errors. So after all was said in done, I created an alias to the script, called todo. Letting me now set an alarm in iCal as well as a date in avocado, by typing: todo 02/02/13 13 "Reminder - Therapy on Friday" which is: php -c /etc/php.ini.default reminder.php: todo The date of when you want the next alarm: 02/02/13 February 2nd, 2013, then the hour of that day, using military time so 1 for 1 am and 12 for noon, 13 for 1 pm. 1 pm: 13 Then a description of the event in quotes: "Reminder - Therapy on Friday" It's funky, it's ugly, the php is bad, the applescript is abysmal, the fact it works is a miracle, and clearly a very real indicator that my mind, is full of disease.
<?php

define("_AVOCADO_API_URL_BASE", "https://avocado.io/api/");
define("_AVOCADO_API_URL_LOGIN", _AVOCADO_API_URL_BASE . "authentication/login");
define("_AVOCADO_API_URL_COUPLE", _AVOCADO_API_URL_BASE . "couple");
define("_AVOCADO_COOKIE_NAME", "user_email");
define("_AVOCADO_USER_AGENT", "Avocado Test Api Client v.1.0");

$date = $argv[1];
$military = $argv[2] * 60;
$name = $argv[3];
if (preg_match('/^\d{1,2}\/\d{1,2}\/\d{4}$/', $date)) { 
 $seconds = strtotime($date);
 $milliseconds = $seconds * 1000;
 $minutes_to_add = (($seconds - time()) / 60) + $military;
}
echo $minutes_to_add;
$two_more = $minutes_to_add + 2;
$two_more_milli = ($seconds + 120) * 1000;
$appscript = "<<END
set now to (current date)
 set eStart to now + $minutes_to_add * minutes
 set eEnd to now + $two_more * minutes
 set eName to \" $name \"
 set alarmTime to 0 -- alarm at the exact moment of the event

 tell application \"iCal\"
  set newEvent to make new event at end of events of calendar \"Home\" with properties {summary:eName, start date:eStart, end date:eEnd}
   make new display alarm at end of display alarms of newEvent with properties {trigger interval:alarmTime}
   end tell
END";

`osascript $appscript`;
echo "he";
// Comment these out if you don't want to use this as a command-line script.
$api = new AvocadoAPI();
$api->updateFromCommandLineInput();
$api->createReminder($milliseconds, $two_more_milli, $name);
class AvocadoAPI {
  var $couple,
      $authManager;

  function AvocadoAPI() {
    $this->authManager = new AvocadoAuthManager();
  }

  function updateFromCommandLineInput() {
    $this->authManager->updateAuthFromCommandLineInput();
    $this->updateCouple();

    # Check that the response from the Avocado API was valid.
    if ($this->couple == null) {
      print "FAILED.  Signature was tested and failed. Try again and check the auth information.\n";
    } else {
      print "SUCCESS.\n\nBelow is your Avocado API signature:\n" .
        $this->authManager->signature . "\n";
    }
  }
  function getCouple(){
//  $qry_str = "?avosig=".$this->authManager->signature;
  $ch = curl_init();

  // Set query data here with the URL
  curl_setopt($ch, CURLOPT_URL, _AVOCADO_API_URL_BASE."calendar");
  $this->signCurlRequest($ch);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  curl_setopt($ch, CURLOPT_TIMEOUT, '3');
  $content = trim(curl_exec($ch));
  curl_close($ch);
  $content = json_decode($content);
  print_r($content);
  }
  function createReminder($milliseconds, $two_more_milli, $name){
//  $qry_str = "?avosig=".$this->authManager->signature;
   $ch = curl_init(_AVOCADO_API_URL_BASE."calendar");
  $fields = array (
  "start" => urlencode($milliseconds),
  "end" => urlencode($two_more_milli),
  "title" => urlencode($name),
  "location" => '',
  "description" => urlencode($name),
  "timezone" => "America/Chicago"
  );
    curl_setopt($ch, CURLOPT_POSTFIELDS,  $fields);
 curl_setopt($ch, CURLOPT_HEADER, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_USERAGENT, _AVOCADO_USER_AGENT);
  $this->signCurlRequest($ch);

 $returndata = curl_exec ($ch);
  curl_close($ch);

  //  $content = json_decode($content);
//  print_r($content);
 echo $returndata;
    $this->createdReminder = $response_code == 200 ? json_decode($output) : null;
 echo $this->createdReminder;
  }

  
  function updateCouple() {
    # Send the POST request.
    $ch = curl_init(_AVOCADO_API_URL_COUPLE);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  //  $this->signCurlRequest($ch);
    $output = curl_exec($ch);
    $response_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    # Use the HTTP response code to test if a valid API request was made.
    $this->couple = $response_code == 200 ? json_decode($output) : null;
  }

  function signCurlRequest($ch) {
    curl_setopt($ch, CURLOPT_COOKIE, _AVOCADO_COOKIE_NAME . "=" . $this->authManager->cookie);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array("X-AvoSig: " . $this->authManager->signature));
    curl_setopt($ch, CURLOPT_USERAGENT, _AVOCADO_USER_AGENT);
  }
}


class AvocadoAuthManager {
  var $cookie,
      $developer_id,
      $developer_key,
      $email,
      $password,
      $signature;

  function AvocadoAuthManager() {}

  function updateAuthFromCommandLineInput() {
    # Ask the user for all of the necessary authentication info
    $this->email = 'your@email.com';
    $this->password = 'yourpassword';
    $this->developer_id = 43;
    $this->developer_key = 'Yourdevkey';
    $this->updateSignature();
  }

  function updateSignature() {
    # Get a new cookie by logging into Avocado.
    $this->updateLoginCookie();

    # Hash the user token.
    $hashed_user_token = hash("sha256", $this->cookie . $this->developer_key);

    # Store the new signature.
    $this->signature = $this->developer_id . ":" . $hashed_user_token;
  }

  function updateLoginCookie() {
    $fields = array(
      'email'=>urlencode($this->email),
      'password'=>urlencode($this->password)
    );

    # Send the POST request.
    $ch = curl_init(_AVOCADO_API_URL_LOGIN);
    curl_setopt($ch, CURLOPT_HEADER, true);
    curl_setopt($ch, CURLOPT_POST, count($fields));
    curl_setopt($ch, CURLOPT_POSTFIELDS,  get_querystring_from_array($fields));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_USERAGENT, _AVOCADO_USER_AGENT);
    $header = substr(curl_exec($ch), 0, curl_getinfo($ch, CURLINFO_HEADER_SIZE));
    curl_close($ch);

    # Store the cookie for use in later API requests.
    $this->cookie = get_cookie_from_header($header, _AVOCADO_COOKIE_NAME);
  }
}


#-----------------------------------------------------
# Mama's little helpers: functions we needed for this.
#-----------------------------------------------------

function get_querystring_from_array($fields) {
  foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
  rtrim($fields_string, '&');
  return $fields_string;
}

function get_cookie_from_header($header, $cookie_name) {
  preg_match('/^Set-Cookie: ' . $cookie_name . '=(.*?);/m', $header, $cookie_array);
  return $cookie_array[1];
}

function get_input_silently($msg){
  # NOTE: stty only works on *nix systems.
  system('stty -echo');
  $input = get_input("Password");
  system('stty echo');
  print "\n";
  return $input;
}

function get_input($msg){
  fwrite(STDOUT, "$msg: ");
  return trim(fgets(STDIN));
}

?>

No comments: