Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 641093b
Showing
65 changed files
with
4,117 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[ | ||
"tropo" | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
## CouchConf NYC Demo | ||
|
||
This is a simple [Tropo](http://www.tropo.com/) + [CouchBase](http://www.couchbase.com/) app I demoed at [CouchConf NYC](http://www.couchbase.com/couchconf-nyc). It's a realtime SMS voting app that was used to select the best rock song over 6 minutes in length, but it can be used as the basis for any kind of voting app you want to build. | ||
|
||
The magic is in Tropo's ability to make HTTP requests from inside a running telephony application to a CouchDB instance running on your local machine, your server, in the cloud - anywhere! | ||
|
||
Tropo + CouchBase == Cloud Telephony Awesomeness! | ||
|
||
## What is a CouchApp? | ||
|
||
CouchApps are web applications which can be served directly from [CouchDB](http://couchdb.apache.org). This gives them the nice property of replicating just like any other data stored in CouchDB. They are also simple to write as they can use the built-in jQuery libraries and plugins that ship with CouchDB. | ||
|
||
[More info about CouchApps here.](http://couchapp.org) | ||
|
||
## Deploying this app | ||
|
||
Assuming you just cloned this app from git, and you have changed into the app directory in your terminal, you want to push it to your CouchDB with the CouchApp command line tool, like this: | ||
|
||
couchapp push . http://name:password@hostname:5984/mydatabase | ||
|
||
If you don't have a password on your CouchDB (admin party) you can do it like this (but it's a bad, idea, set a password): | ||
|
||
couchapp push . http://hostname:5984/mydatabase | ||
|
||
If you get sick of typing the URL, you should setup a `.couchapprc` file in the root of your directory. Remember not to check this into version control as it will have passwords in it. | ||
|
||
The `.couchapprc` file should have contents like this: | ||
|
||
{ | ||
"env" : { | ||
"public" : { | ||
"db" : "http://name:pass@mycouch.couchone.com/mydatabase" | ||
}, | ||
"default" : { | ||
"db" : "http://name:pass@localhost:5984/mydatabase" | ||
} | ||
} | ||
} | ||
|
||
Now that you have the `.couchapprc` file set up, you can push your app to the CouchDB as simply as: | ||
|
||
couchapp push | ||
|
||
This pushes to the `default` as specified. To push to the `public` you'd run: | ||
|
||
couchapp push public | ||
|
||
Of course you can continue to add more deployment targets as you see fit, and give them whatever names you like. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
<html> | ||
<head> | ||
<title>Tropo-Powered Realtime SMS Voting</title> | ||
<link rel="stylesheet" href="style/main.css" type="text/css"></head> | ||
<body> | ||
<h2></h2> | ||
<center> | ||
<div id="row"></div> | ||
</center> | ||
<p class="footer">Powered by <a href="http://tropo.com">Tropo</a></p> | ||
</body> | ||
<script src="vendor/couchapp/loader.js"></script> | ||
<script type="text/javascript" charset="utf-8"> | ||
|
||
$.couch.app(function(app) { | ||
|
||
// Set the database to use. | ||
var db = $.couch.db("couchconfdemo"); | ||
|
||
// Get the phone number for voting and render. | ||
db.view("couchconfdemo/number", { | ||
success: function(data) { | ||
for(var i=0; i<data.rows.length; i++) { | ||
$("h2").append(data.rows[i].value); | ||
} | ||
} | ||
}); | ||
|
||
// Get all selections available for voting. | ||
db.view("couchconfdemo/selections", { | ||
success: function(data) { | ||
for(var i=0; i<data.rows.length; i++) { | ||
var selection = "<div id=\"choice\"><p class=\"score\" id=\"" + data.rows[i].id + "\">0</p><div class=\"selection\">"; | ||
selection += data.rows[i].id + "</div><p class=\"name\">" + data.rows[i].value.song; | ||
selection += " (" + data.rows[i].value.group + ")</p></div>"; | ||
$("#row").append(selection); | ||
} | ||
} | ||
}); | ||
|
||
// Get all past votes and incremement total. | ||
db.view("couchconfdemo/votes", { | ||
success: function(data) { | ||
for(var i=0; i<data.rows.length; i++) { | ||
var selector = "#" + data.rows[i].value; | ||
var newValue = parseInt($(selector).html()) + 1; | ||
$(selector).html(newValue); | ||
} | ||
} | ||
}); | ||
|
||
// Watch the changes API for new votes. | ||
db.changes(null, {include_docs: true}).onChange(function (data) { | ||
for(var i=0; i<data.results.length; i++) { | ||
var selector = "#" + data.results[i].doc.selection; | ||
var newValue = parseInt($(selector).html()) + 1; | ||
$(selector).html(newValue); | ||
} | ||
}); | ||
|
||
}); | ||
|
||
</script> | ||
<script type="text/javascript" src="/_utils/script/jquery.couch.js"></script> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
body { | ||
text-align: center; | ||
background-image: url('http://blog.tropo.com/files/2011/10/Tropo-Vert.png'), url('http://blog.tropo.com/files/2011/10/couch-300x300.png'); | ||
background-position: 2% 2%, 98% 2%; | ||
background-size: 10%, 10%; | ||
background-repeat: no-repeat, no-repeat;; | ||
} | ||
|
||
#row { | ||
width: 65%; | ||
margin-left: 5px; | ||
} | ||
|
||
#choice { | ||
text-align: center; | ||
padding: 5px; | ||
border-style: dashed; | ||
border-width: 1px; | ||
margin: 2px; | ||
margin-top: 0px; | ||
background-color: silver; | ||
} | ||
|
||
.score { | ||
font-weight: bold; | ||
color: maroon; | ||
font-size: 115%; | ||
margin-bottom: 2px; | ||
margin-top: 2px; | ||
} | ||
|
||
.name { | ||
font-weight: bold; | ||
} | ||
|
||
.selection { | ||
float: left; | ||
font-size: 125%; | ||
font-weight: bold; | ||
color: blue; | ||
margin-top: 3px; | ||
text-decoration: overline; | ||
} | ||
|
||
h4 { | ||
margin-top: 5px; | ||
} | ||
|
||
.footer { | ||
font-size: 80%; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
_design/couchconfdemo |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"name": "Tropo-Powered Realtime SMS Voting", | ||
"description": "CouchApp" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
function(data) { | ||
// $.log(data) | ||
var p; | ||
return { | ||
items : data.rows.map(function(r) { | ||
p = (r.value && r.value.profile) || {}; | ||
p.message = r.value && r.value.message; | ||
return p; | ||
}) | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<p>Customize this format here: <tt>ddoc.evently.items._changes.mustache</tt></p> | ||
<h3>Recent Messages</h3> | ||
<ul> | ||
{{#items}} | ||
<li> | ||
<div class="avatar"> | ||
{{#gravatar_url}}<img src="{{gravatar_url}}" alt="{{name}}"/>{{/gravatar_url}} | ||
<div class="name"> | ||
{{nickname}} | ||
</div> | ||
</div> | ||
<p>{{message}}</p> | ||
<div style="clear:left;"></div> | ||
</li> | ||
{{/items}} | ||
</ul> | ||
<p><em>Protip:</em> If you setup continuous replication between this database and a remote one, this list will reflect remote changes in near real-time.</p> | ||
<p>This would be a good place to add pagination.</p> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"view" : "recent-items", | ||
"descending" : "true", | ||
"limit" : 50 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<p>Most applications will customize this template (<tt>ddoc.evently.profile.profileReady.mustache</tt>) for user input.</p> | ||
|
||
<div class="avatar"> | ||
{{#gravatar_url}}<img src="{{gravatar_url}}"/>{{/gravatar_url}} | ||
<div class="name"> | ||
{{name}} | ||
</div> | ||
</div> | ||
|
||
<form> | ||
<label>New message from {{nickname}}: <input type="text" name="message" size=60 value=""></label> | ||
</form> | ||
|
||
<div style="clear:left;"></div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
function() { | ||
var form = $(this); | ||
var fdoc = form.serializeObject(); | ||
fdoc.created_at = new Date(); | ||
fdoc.profile = $$("#profile").profile; | ||
$$(this).app.db.saveDoc(fdoc, { | ||
success : function() { | ||
form[0].reset(); | ||
} | ||
}); | ||
return false; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
javascript |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
[ | ||
{ | ||
"from": "", | ||
"to": "index.html" | ||
}, | ||
{ | ||
"from": "vendor/*", | ||
"to": "vendor/*" | ||
}, | ||
{ | ||
"from": "app/*", | ||
"to": "app/*" | ||
}, | ||
{ | ||
"from": "style/*", | ||
"to": "style/*" | ||
}, | ||
{ | ||
"from": "_view/*", | ||
"to": "_view/*" | ||
}, | ||
{ | ||
"from": "_changes/*", | ||
"to": "_changes/*" | ||
}, | ||
{ | ||
"from": "couchconfdemo/*", | ||
"to": "../../*" | ||
}, | ||
{ | ||
"from": "couchconfdemo/", | ||
"to": "../../" | ||
} | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
<?php | ||
|
||
// CouchDB settings | ||
define("COUCH_HOST", ""); | ||
define("COUCH_PORT", ""); | ||
define("COUCH_DB_NAME", ""); | ||
define("COUCH_USER", ""); | ||
define("COUCH_PASS", ""); | ||
|
||
// Function to save vote. | ||
function saveVote($id, $vote) { | ||
|
||
$doc = json_encode(array("selection" => $vote)); | ||
$url = COUCH_HOST.":".COUCH_DB_PORT."/".COUCH_DB_NAME."/$id"; | ||
|
||
$putData = tmpfile(); | ||
fwrite($putData, $doc); | ||
fseek($putData, 0); | ||
|
||
$ch = curl_init($url); | ||
curl_setopt($ch, CURLOPT_PUT, true); | ||
curl_setopt($ch, CURLOPT_INFILE, $putData); | ||
curl_setopt($ch, CURLOPT_INFILESIZE, strlen($doc)); | ||
curl_setopt($ch, CURLOPT_USERPWD, COUCH_USER . ":" . COUCH_PASS); | ||
curl_exec($ch); | ||
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE); | ||
curl_close($ch); | ||
|
||
// Conflict update means someone tried to vote twice. :-( | ||
if ($code != '201') { | ||
_log("*** HTTP response code: $code ***"); | ||
return false; | ||
} | ||
return true; | ||
|
||
} | ||
|
||
// If the caller uses the voice channel, there is no initialText. | ||
if(!$currentCall->initialText) { | ||
$vote = ask("Please enter the number of the selection you wish to vote for.", array("choices" => "1,2,3,4,5,6", "attempts" => 3)); | ||
} | ||
|
||
// If the text channel is used, initialText is used to complete ask(); | ||
else { | ||
$vote = ask("", array("choices" => "[ANY]", "attempts" => 1)); | ||
} | ||
|
||
// Save the vote. | ||
if(saveVote($currentCall->callerID, $vote->value)) { | ||
if($currentCall->channel == "VOICE") { | ||
say("Thank you, your vote has been recorded."); | ||
} | ||
else { | ||
_log("*** Vote recorded for " . $currentCall->callerID . " ***"); | ||
} | ||
} else { | ||
say("Sorry, there was a problem saving your vote."); | ||
} | ||
|
||
?> |
Oops, something went wrong.