summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Parecki <aaron@parecki.com>2016-02-11 02:47:04 +0000
committerAaron Parecki <aaron@parecki.com>2016-02-11 02:47:04 +0000
commit76aa9c2bc9d31549e44bc0b10817eb6e252dbe11 (patch)
treee7820622820ca39424333c01ab2d238f56be1a11
parent1fdf8feb67fd11f46811fe925537ab6bf3e4d626 (diff)
parent704241a3a4f3480eb87260aef9fca8f1ce00e638 (diff)
Merge branch 'master' of github.com:aaronpk/IndiePost
-rw-r--r--controllers/controllers.php55
-rw-r--r--lib/helpers.php51
-rw-r--r--public/js/script.js32
-rw-r--r--views/dashboard.php15
-rw-r--r--views/new-itinerary.php209
-rw-r--r--views/partials/header.php6
6 files changed, 334 insertions, 34 deletions
diff --git a/controllers/controllers.php b/controllers/controllers.php
index 70e84cf..ef619a6 100644
--- a/controllers/controllers.php
+++ b/controllers/controllers.php
@@ -41,6 +41,16 @@ function generate_login_token() {
), Config::$jwtSecret);
}
+$app->get('/dashboard', function() use($app) {
+ if($user=require_login($app)) {
+ $html = render('dashboard', array(
+ 'title' => 'Dashboard',
+ 'authorizing' => false
+ ));
+ $app->response()->body($html);
+ }
+});
+
$app->get('/new', function() use($app) {
if($user=require_login($app)) {
$params = $app->request()->params();
@@ -130,6 +140,18 @@ $app->get('/favorite', function() use($app) {
}
});
+$app->get('/itinerary', function() use($app) {
+ if($user=require_login($app)) {
+ $params = $app->request()->params();
+
+ $html = render('new-itinerary', array(
+ 'title' => 'Itinerary',
+ 'authorizing' => false
+ ));
+ $app->response()->body($html);
+ }
+});
+
$app->get('/photo', function() use($app) {
if($user=require_login($app)) {
$params = $app->request()->params();
@@ -217,7 +239,7 @@ $app->get('/add-to-home', function() use($app) {
if($user=require_login($app)) {
if(array_key_exists('start', $params)) {
$_SESSION['add-to-home-started'] = true;
-
+
$token = JWT::encode(array(
'user_id' => $_SESSION['user_id'],
'me' => $_SESSION['me'],
@@ -260,7 +282,7 @@ $app->get('/email', function() use($app) {
'test_response' => $test_response,
'user' => $user
));
- $app->response()->body($html);
+ $app->response()->body($html);
}
});
@@ -294,7 +316,7 @@ $app->get('/favorite-popup', function() use($app) {
$params = $app->request()->params();
$html = $app->render('favorite-popup.php', array(
- 'url' => $params['url'],
+ 'url' => $params['url'],
'token' => $params['token']
));
$app->response()->body($html);
@@ -339,7 +361,7 @@ function create_favorite(&$user, $url) {
if($user->twitter_access_token && preg_match('/https?:\/\/(?:www\.)?twitter\.com\/[^\/]+\/status(?:es)?\/(\d+)/', $url, $match)) {
$tweet_id = $match[1];
- $twitter = new \TwitterOAuth\Api(Config::$twitterClientID, Config::$twitterClientSecret,
+ $twitter = new \TwitterOAuth\Api(Config::$twitterClientID, Config::$twitterClientSecret,
$user->twitter_access_token, $user->twitter_token_secret);
$result = $twitter->post('favorites/create', array(
'id' => $tweet_id
@@ -373,7 +395,7 @@ function create_repost(&$user, $url) {
if($user->twitter_access_token && preg_match('/https?:\/\/(?:www\.)?twitter\.com\/[^\/]+\/status(?:es)?\/(\d+)/', $url, $match)) {
$tweet_id = $match[1];
- $twitter = new \TwitterOAuth\Api(Config::$twitterClientID, Config::$twitterClientSecret,
+ $twitter = new \TwitterOAuth\Api(Config::$twitterClientID, Config::$twitterClientSecret,
$user->twitter_access_token, $user->twitter_token_secret);
$result = $twitter->post('statuses/retweet/'.$tweet_id);
}
@@ -390,8 +412,8 @@ $app->get('/favorite.js', function() use($app) {
$r = create_favorite($user, $params['url']);
$app->response()->body($app->render('favorite-js.php', array(
- 'url' => $params['url'],
- 'like_url' => $r['location'],
+ 'url' => $params['url'],
+ 'like_url' => $r['location'],
'error' => $r['error'],
// 'facebook_id' => $facebook_id
)));
@@ -464,6 +486,20 @@ $app->post('/repost', function() use($app) {
}
});
+$app->post('/itinerary', function() use($app) {
+ if($user=require_login($app)) {
+ $params = $app->request()->params();
+
+ $r = micropub_post_for_user($user, json_decode($params['data'], true), null, true);
+
+ $app->response()->body(json_encode(array(
+ 'location' => $r['location'],
+ 'error' => $r['error'],
+ 'response' => $r['response']
+ )));
+ }
+});
+
$app->get('/micropub/syndications', function() use($app) {
if($user=require_login($app)) {
$data = get_syndication_targets($user);
@@ -545,7 +581,7 @@ $app->get('/auth/twitter', function() use($app) {
// If there is an existing Twitter token, check if it is valid
// Otherwise, generate a Twitter login link
$twitter_login_url = false;
- $twitter = new \TwitterOAuth\Api(Config::$twitterClientID, Config::$twitterClientSecret,
+ $twitter = new \TwitterOAuth\Api(Config::$twitterClientID, Config::$twitterClientSecret,
$user->twitter_access_token, $user->twitter_token_secret);
if(array_key_exists('login', $params)) {
@@ -582,7 +618,7 @@ $app->get('/auth/twitter/callback', function() use($app) {
if($user=require_login($app)) {
$params = $app->request()->params();
- $twitter = new \TwitterOAuth\Api(Config::$twitterClientID, Config::$twitterClientSecret,
+ $twitter = new \TwitterOAuth\Api(Config::$twitterClientID, Config::$twitterClientSecret,
$_SESSION['twitter_auth']['oauth_token'], $_SESSION['twitter_auth']['oauth_token_secret']);
$credentials = $twitter->getAccessToken($params['oauth_verifier']);
@@ -634,4 +670,3 @@ $app->get('/auth/instagram/callback', function() use($app) {
$app->redirect('/settings');
}
});
-
diff --git a/lib/helpers.php b/lib/helpers.php
index 5121d36..0407129 100644
--- a/lib/helpers.php
+++ b/lib/helpers.php
@@ -75,23 +75,23 @@ function get_timezone($lat, $lng) {
}
if(!function_exists('http_build_url')) {
- function http_build_url($parsed_url) {
- $scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : '';
- $host = isset($parsed_url['host']) ? $parsed_url['host'] : '';
- $port = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : '';
- $user = isset($parsed_url['user']) ? $parsed_url['user'] : '';
- $pass = isset($parsed_url['pass']) ? ':' . $parsed_url['pass'] : '';
- $pass = ($user || $pass) ? "$pass@" : '';
- $path = isset($parsed_url['path']) ? $parsed_url['path'] : '';
- $query = isset($parsed_url['query']) ? '?' . $parsed_url['query'] : '';
- $fragment = isset($parsed_url['fragment']) ? '#' . $parsed_url['fragment'] : '';
- return "$scheme$user$pass$host$port$path$query$fragment";
- }
+ function http_build_url($parsed_url) {
+ $scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : '';
+ $host = isset($parsed_url['host']) ? $parsed_url['host'] : '';
+ $port = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : '';
+ $user = isset($parsed_url['user']) ? $parsed_url['user'] : '';
+ $pass = isset($parsed_url['pass']) ? ':' . $parsed_url['pass'] : '';
+ $pass = ($user || $pass) ? "$pass@" : '';
+ $path = isset($parsed_url['path']) ? $parsed_url['path'] : '';
+ $query = isset($parsed_url['query']) ? '?' . $parsed_url['query'] : '';
+ $fragment = isset($parsed_url['fragment']) ? '#' . $parsed_url['fragment'] : '';
+ return "$scheme$user$pass$host$port$path$query$fragment";
+ }
}
-function micropub_post_for_user(&$user, $params, $file_path = NULL) {
+function micropub_post_for_user(&$user, $params, $file_path = NULL, $json = false) {
// Now send to the micropub endpoint
- $r = micropub_post($user->micropub_endpoint, $params, $user->micropub_access_token, $file_path);
+ $r = micropub_post($user->micropub_endpoint, $params, $user->micropub_access_token, $file_path, $json);
$user->last_micropub_response = substr(json_encode($r), 0, 1024);
$user->last_micropub_response_date = date('Y-m-d H:i:s');
@@ -109,7 +109,7 @@ function micropub_post_for_user(&$user, $params, $file_path = NULL) {
return $r;
}
-function micropub_post($endpoint, $params, $access_token, $file_path = NULL) {
+function micropub_post($endpoint, $params, $access_token, $file_path = NULL, $json = false) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $endpoint);
curl_setopt($ch, CURLOPT_POST, true);
@@ -118,14 +118,23 @@ function micropub_post($endpoint, $params, $access_token, $file_path = NULL) {
// https://github.com/aaronpk/Quill/issues/4
// http://indiewebcamp.com/irc/2015-02-14#t1423955287064
$httpheaders = array('Authorization: Bearer ' . $access_token);
- $params = array_merge(array(
- 'h' => 'entry',
- 'access_token' => $access_token
- ), $params);
+
+ if(!$json) {
+ $params = array_merge(array(
+ 'h' => 'entry',
+ 'access_token' => $access_token
+ ), $params);
+ }
if(!$file_path) {
- $post = http_build_query($params);
- $post = preg_replace('/%5B[0-9]+%5D/', '%5B%5D', $post); // change [0] to []
+ if($json) {
+ $params['access_token'] = $access_token;
+ $httpheaders[] = 'Content-type: application/json';
+ $post = json_encode($params);
+ } else {
+ $post = http_build_query($params);
+ $post = preg_replace('/%5B[0-9]+%5D/', '%5B%5D', $post); // change [0] to []
+ }
} else {
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mimetype = finfo_file($finfo, $file_path);
diff --git a/public/js/script.js b/public/js/script.js
new file mode 100644
index 0000000..399af05
--- /dev/null
+++ b/public/js/script.js
@@ -0,0 +1,32 @@
+
+ function tz_seconds_to_offset(seconds) {
+ var tz_offset = '';
+ var hours = zero_pad(Math.abs(seconds / 60 / 60));
+ var minutes = zero_pad(Math.floor(seconds / 60) % 60);
+ return (seconds < 0 ? '-' : '+') + hours + ":" + minutes;
+ }
+ function zero_pad(num) {
+ num = "" + num;
+ if(num.length == 1) {
+ num = "0" + num;
+ }
+ return num;
+ }
+
+
+$(function(){
+
+ // Set the date from JS
+ var d = new Date();
+ $("#note_date").val(d.getFullYear()+"-"+zero_pad(d.getMonth()+1)+"-"+zero_pad(d.getDate()));
+ $("#note_time").val(zero_pad(d.getHours())+":"+zero_pad(d.getMinutes())+":"+zero_pad(d.getSeconds()));
+ $("#note_tzoffset").val(tz_seconds_to_offset(d.getTimezoneOffset() * 60 * -1));
+
+ // ctrl-s to save
+ $(window).on('keydown', function(e){
+ if(e.keyCode == 83 && e.ctrlKey){
+ $("#btn_post").click();
+ }
+ });
+
+})
diff --git a/views/dashboard.php b/views/dashboard.php
new file mode 100644
index 0000000..3c29f92
--- /dev/null
+++ b/views/dashboard.php
@@ -0,0 +1,15 @@
+<div class="narrow">
+ <?= partial('partials/header') ?>
+
+ <ul style="margin-top: 1em;">
+ <li><a href="/editor">Editor</a></li>
+ <li><a href="/new">Note</a></li>
+ <li><a href="/bookmark">Bookmark</a></li>
+ <li><a href="/favorite">Favorite</a></li>
+ <li><a href="/repost">Repost</a></li>
+ <li><a href="/photo">Photo</a></li>
+ <li><a href="/itinerary">Itinerary</a></li>
+ <li><a href="/email">Email</a></li>
+ </ul>
+
+</div>
diff --git a/views/new-itinerary.php b/views/new-itinerary.php
new file mode 100644
index 0000000..8d8811c
--- /dev/null
+++ b/views/new-itinerary.php
@@ -0,0 +1,209 @@
+<div class="narrow">
+ <?= partial('partials/header') ?>
+
+ <div style="clear: both;">
+ <div class="alert alert-success hidden" id="test_success"><strong>Success! We found a Location header in the response!</strong><br>Your post should be on your website now!<br><a href="" id="post_href">View your post</a></div>
+ <div class="alert alert-danger hidden" id="test_error"><strong>Your endpoint did not return a Location header.</strong><br>See <a href="/creating-a-micropub-endpoint">Creating a Micropub Endpoint</a> for more information.</div>
+ </div>
+
+ <form role="form" style="margin-top: 20px;" id="note_form">
+
+ <h4>Legs</h4>
+ <div class="form-group" id="itinerary-legs-container">
+ <div style="display:none;" id="leg-template">
+ <div class="itinerary-leg">
+ <input type="hidden" class="template" value="1">
+ <div class="remove">&times;</div>
+ <div class="row">
+ <div class="col-xs-3">
+ <label>Transit Type</label>
+ <select class="leg-transit-type form-control">
+ <option value="air">Air</option>
+ <option value="train">Train</option>
+ <option value="bus">Bus</option>
+ <option value="boat">Boat</option>
+ <option value="generic">Generic</option>
+ </select>
+ </div>
+ <div class="col-xs-3">
+ <label>Operator</label>
+ <input type="text" class="form-control leg-operator" placeholder="Operator" value="">
+ </div>
+ <div class="col-xs-3">
+ <label>Number</label>
+ <input type="text" class="form-control leg-number" placeholder="Number" value="">
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-xs-2">
+ <label>Origin</label>
+ <input type="text" class="form-control leg-origin" placeholder="Origin" value="">
+ </div>
+ <div class="col-xs-9">
+ <label>Departure</label>
+ <div class="form-group leg-departure">
+ <input type="text" class="form-control leg-departure-date date" style="max-width:160px; float:left; margin-right: 4px;" value="">
+ <input type="text" class="form-control leg-departure-time time" style="max-width:85px; float:left; margin-right: 4px;" value="">
+ <input type="text" class="form-control leg-departure-tz tz" style="max-width:75px;" value="">
+ </div>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-xs-2">
+ <label>Destination</label>
+ <input type="text" class="form-control leg-destination" placeholder="Destination" value="">
+ </div>
+ <div class="col-xs-9">
+ <label>Arrival</label>
+ <div class="form-group leg-arrival">
+ <input type="text" class="form-control leg-arrival-date date" style="max-width:160px; float:left; margin-right: 4px;" value="">
+ <input type="text" class="form-control leg-arrival-time time" style="max-width:85px; float:left; margin-right: 4px;" value="">
+ <input type="text" class="form-control leg-arrival-tz tz" style="max-width:75px;" value="">
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <button class="btn btn-default" id="btn_add_leg">Add Leg</button>
+
+ <div class="form-group" style="margin-top: 18px;">
+ <label for="note_category">Tags (comma-separated)</label>
+ <input type="text" id="note_category" value="" class="form-control">
+ </div>
+
+ <div style="float: right; margin-top: 6px;">
+ <button class="btn btn-success" id="btn_post">Post</button>
+ </div>
+
+ </form>
+
+</div>
+
+
+
+<style type="text/css">
+.itinerary-leg {
+ margin-bottom: 10px;
+ padding: 8px 8px;
+ border-left: 4px #5bc0de solid;
+ background-color: #f4f8fa;
+}
+.itinerary-leg .row {
+ margin-bottom: 10px;
+}
+.itinerary-leg .remove {
+ float: right;
+ margin-right: 10px;
+ margin-top: 0;
+ font-size: 20px;
+ cursor: pointer;
+ color: #40A9C7;
+}
+.itinerary-leg .remove:hover {
+ color: #7ECDE4;
+}
+</style>
+
+<script src="/js/script.js"></script>
+<script>
+$(function(){
+
+ $("#btn_add_leg").click(function(){
+ add_leg();
+ return false;
+ });
+
+ function bind_leg_x() {
+ $(".itinerary-leg .remove").unbind("click").click(function(){
+ // Don't allow the only leg to be removed. (2 because there is an invisible one as the template)
+ if($(".itinerary-leg").length > 2) {
+ $(this).parent().remove();
+ }
+ });
+ }
+
+ function add_leg() {
+ $("#itinerary-legs-container").append($("#leg-template").html());
+
+ $(".itinerary-leg:last .template").val(0);
+ var d = new Date();
+ $(".itinerary-leg:last .date").val(d.getFullYear()+"-"+zero_pad(d.getMonth()+1)+"-"+zero_pad(d.getDate()));
+ $(".itinerary-leg:last .time").val(zero_pad(d.getHours())+":"+zero_pad(d.getMinutes())+":00");
+ $(".itinerary-leg:last .tz").val(tz_seconds_to_offset(d.getTimezoneOffset() * 60 * -1));
+
+ /*
+ $('.itinerary-leg:last .date').datepicker({
+ 'format': 'yyyy-mm-dd',
+ 'autoclose': true,
+ 'todayHighlight': true
+ });
+
+ $('.itinerary-leg:last .time').timepicker({
+ 'showDuration': true,
+ 'timeFormat': 'g:ia'
+ });
+
+ $('.itinerary-leg:last').datepair();
+ */
+
+ bind_leg_x();
+ }
+
+ add_leg();
+
+ $("#btn_post").click(function(){
+
+ var itinerary = [];
+
+ $(".itinerary-leg").each(function(){
+ if($(this).find(".template").val() == 1) { return; }
+
+ var departure = $(this).find(".leg-departure-date").val()+"T"+$(this).find(".leg-departure-time").val()+$(this).find(".leg-departure-tz").val();
+ var arrival = $(this).find(".leg-arrival-date").val()+"T"+$(this).find(".leg-arrival-time").val()+$(this).find(".leg-arrival-tz").val();
+
+ itinerary.push({
+ "type": "h-leg",
+ "properties": {
+ "transit-type": $(this).find(".leg-transit-type").val(),
+ "operator": $(this).find(".leg-operator").val(),
+ "number": $(this).find(".leg-number").val(),
+ "origin": $(this).find(".leg-origin").val(),
+ "destination": $(this).find(".leg-destination").val(),
+ "departure": departure,
+ "arrival": arrival
+ }
+ });
+ });
+
+ var category = $("#note_category").val().split(/[, ]+/)
+
+ $.post("/itinerary", {
+ data: JSON.stringify({
+ "type": "h-entry",
+ "properties": {
+ "itinerary": itinerary,
+ "category": category
+ }
+ })
+ }, function(data){
+ var response = JSON.parse(data);
+
+ if(response.location != false) {
+ $("#test_success").removeClass('hidden');
+ $("#test_error").addClass('hidden');
+ $("#post_href").attr("href", response.location);
+ } else {
+ $("#test_success").addClass('hidden');
+ $("#test_error").removeClass('hidden');
+ }
+
+ });
+ return false;
+ });
+
+});
+
+<?= partial('partials/syndication-js') ?>
+
+</script>
diff --git a/views/partials/header.php b/views/partials/header.php
index ef9f15a..4243557 100644
--- a/views/partials/header.php
+++ b/views/partials/header.php
@@ -1,4 +1,4 @@
<div class="header">
- <img src="/images/quill-logo.png" width="42" height="42">
- Quill
-</div> \ No newline at end of file
+ <a href="/dashboard"><img src="/images/quill-logo.png" width="42" height="42"></a>
+ <a href="/dashboard">Quill</a>
+</div>