1. Miki Tebeka
  2. dude-remember

Source

dude-remember / src / tropo.clj

(ns tropo
  (:gen-class :extends javax.servlet.http.HttpServlet)
  (:use appengine.datastore
        appengine.users 
        clojure.contrib.prxml
        [clojure.contrib.json :only [json-str read-json]]
        [clojure.java.io :only [reader]]
        compojure.core
        hiccup.core
        hiccup.form-helpers
        hiccup.page-helpers
        ring.util.response
        ring.util.servlet)
  (:require [compojure.route :as route]
            [clojure.contrib.logging :as log]))

(def *title* "Tropo Playground")

(defn header-link []
  (if (nil? (current-user))
    [:a {:href (login-url "/")} "Login"]
    [:a {:href (logout-url "/")} "Logout"]))

(def *jquery-url* 
  "http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js")

(defn page [& content]
  (html
    [:head
     (include-css "/static/site.css")
     (include-js *jquery-url*)
     (include-js "/static/site.js")
     [:title *title*]]
    [:body 
     [:div {:class "header"} (header-link)]
     [:h1 *title*]
     content]))

(def *titles* [
  "Bread and Circuses: The State of Web App Startups"
  "MongoDB's lead developer: Foursquare outage post mortem"
  "IE6 effect in HTML5"
  "Microsoft Buying Adobe?"
  "Caught Spying on Student, FBI Demands GPS Tracker Back"
  "Dear Gap, I have your new logo."
  "Who are North Korea’s 13 Twitter friends?"
  "Costco - Food for a whole year - $799 Awesome"
  "Microsoft announces NuPack, a new package manager for open source .NET librarie"
  "Writer for iPad: First Reactions"
  "The stock market as a single, very big piece of multithreaded software"
  "How to be a freelance web developer, part 2"])
(def *index* (ref 0))

(def *on* {
      :on (vec (for [event ["continue" "error" "hangup" "incomplete"]]
                 {:event event :next "/tropo/voice"}))})

(defn ask [title]
  {:ask {
         :choices { :value "next, read" }
         :bargein true
         :timeout 1.0
         :say [{:value title :voice "kate"}]}})

(defn tropo-response [& params]
  {:tropo params})

(defn tropo-reply [params]
  (if (< @*index* (count *titles*))
    (let [title (*titles* @*index*)]
      (dosync (alter *index* inc))
      (tropo-response *on* (ask title)))
    (do 
      (dosync (alter *index* (fn [_] 0)))
      (tropo-response {:say [{:value "That's all dude" :voice "kate"}]}
                      {:hangup nil}))))

(defn tropo-voice [params]
  (log/info (str "VOICE: " params))
  (json-str (tropo-reply params)))

(defn welcome-page []
  (page "Playing with Tropo"))

(defn parse-tropo [body]
  (let [json (read-json (reader body))]
    (merge (:session json) (:result json))))

(defroutes tropo-routes
  (GET "/" [] (welcome-page))

  (POST "/tropo/voice" {body :body} (tropo-voice (parse-tropo body)))

; Uncomment these when debugging, *don't* let them slip to production           
;  (GET "/_eval" [] (eval-page "0"))
;  (POST "/_eval" {params :params} (eval-page (params "expr")))

  (route/not-found "Dude! I can't find it."))

(defservice tropo-routes)