Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

First commit! It mostly works. I think.

  • Loading branch information...
commit d73aef3170cc04b3d031bb061e8219a3da0b7ae1 0 parents
@smajda authored
48 handheld.css
@@ -0,0 +1,48 @@
+html {padding: 0;margin: 0;}
+body {
+ width: 480px;
+ font-size: 10px;
+ line-height: 1em;
+}
+
+
+div#wrapper { padding-left: 3px; margin: 7px;}
+div#top { padding: 0; margin: 0; background: none; border-bottom: none;}
+div#top form {margin-bottom: none;}
+div#output { margin: 0; }
+
+h1{
+ padding: 0;
+ text-align: left;
+ padding-left: 20px;
+}
+
+
+/* form */
+input#cmd{
+ width:auto;
+ height:auto;
+ font-size:14px;
+}
+input#sub{
+ width: auto;
+ height:auto;
+ font-size:14px;
+ margin-top:5px;
+ margin-bottom: 0;
+}
+
+
+/* output */
+#results-note {font-size: 1.0em;}
+
+ul {
+ margin-bottom: 10px;
+}
+ul, li {
+ padding: 2px 0 2px 8px;
+ margin: 0;
+ list-style: none;
+ font-size:1em;
+}
+
2  includes/.htaccess
@@ -0,0 +1,2 @@
+Order allow,deny
+Deny from all
73 includes/access.php
@@ -0,0 +1,73 @@
+<?php
+/* Simple Authentication
+ *
+ * You could just use .htaccess/.htpasswd but
+ * but Mobile Safari won't save these passwords
+ * so we'll use a simple login form with cookies.
+ *
+ * modified from:
+ * http://www.legend.ws/blog/tips-tricks/php-authentication-login-script/
+*/
+
+function displayform($error) {
+echo <<<HTML
+<html>
+ <head>
+ <title>todotxt login</title>
+ <meta name="viewport" content="width=480" />
+ <link media="screen" href="stylesheet.css" rel="stylesheet" type="text/css">
+ <link media="handheld" href="handset.css" rel="stylesheet" type="text/css">
+ <style type="text/css">
+ body {margin: 10px;}
+ form#login input {
+ margin-bottom: 7px;
+ }
+ </style>
+ </head>
+ <body>
+
+HTML;
+
+ if($error) echo "<p><b>Wrong credentials.</b></p>";
+
+echo <<<HTML
+ <form id="login" action="" method="post">
+ <label>username:</label>
+ <input type='text' name='input_user' /><br />
+ <label>password:</label>
+ <input type='password' name='input_password' /><br />
+ <input type='Submit' value='Login&raquo;' name='loginbutton'>
+ </form>
+
+ </body>
+</html>
+HTML;
+exit;
+}
+
+
+session_start();
+
+
+if(!$_SESSION['authenticated']) {
+
+ if (isset($_COOKIE[$user])) {
+ $_SESSION['authenticated'] = 1;
+ } elseif($_POST['loginbutton']) {
+ $inputuser = $_POST['input_user'];
+ $inputpassword = $_POST['input_password'];
+
+ if(!strcmp($inputuser ,$user) && !strcmp($inputpassword,$password)) {
+ $expire=time()+60*60*24*30;
+ setcookie($user,"todotxt-web",$expire);
+ $_SESSION['authenticated'] = 1;
+ header("Location:".$_SERVER[PHP_SELF]);
+ } else {
+ displayform(1);
+ }
+ } else {
+ displayform(0);
+ }
+}
+
+?>
52 includes/config-sample.php
@@ -0,0 +1,52 @@
+<?php
+
+/* Instructions:
+ *
+ * Rename this file "config.php" and fill in the
+ * variables below.
+ *
+ * Note: This script defaults to your todo.sh default command,
+ * set with TODOTXT_DEFAULT_ACTION (added to todo.sh on 2009-03-16)
+ * in your todo config file. So unless you like seeing the
+ * usage text, upgrade (if necessary) and set this variable.
+ *
+ * Example:
+ * export TODOTXT_DEFAULT_ACTION=ls
+ *
+*/
+
+
+/* URL
+ * The root URL for this site, like so:
+ * $todoUrl = "http://yourdomain.com/path/to/todo/";
+*/
+$todoUrl = "";
+
+/* Set the command
+ * 1. Use full paths
+ * 2. The following options for todo.sh are required for this:
+ * -p (no colors)
+ * -d /path/to/your/todo.cfg
+ * 3. Example:
+ * $todoCmd = '/home/me/bin/todo.sh -p -a -n -d /home/me/.todo.cfg';
+ *
+*/
+$todoCmd = "";
+
+/* Simple authentication
+ * Set your username and password here
+*/
+$user = "";
+$password = "";
+
+
+/* iPhone only: use as a "web app" or not?
+ * Default is 'no', change to 'yes' if you want to use this.
+ * This means if you add an icon to your home screen, it will open
+ * without normal Safari browser chrome.
+ * Cool idea, but it annoyed me, though I left it in as an option.
+*/
+$iphoneWebApp = "no";
+
+
+?>
95 includes/todo.php
@@ -0,0 +1,95 @@
+<?php
+
+// process $_GET
+function get_cmd($_GET, $id='cmd') {
+ if($cmd=$_GET[$id]) {
+ $cmd=rawurldecode($cmd);
+ $cmd=stripslashes($cmd);
+ }
+ return $cmd;
+}
+
+// checks if a command is an ls command or not
+function ls_check($cmd) {
+ // array of actions you do *not* want to follow
+ // with a rerun of previous ls
+ // (mostly this means the 'ls' commands, hence the name)
+ $lsCmds=array(
+ '',
+ 'ls','list',
+ 'lsa','listall',
+ 'lf','listfile',
+ 'listpri','lsp',
+ 'lsprj','listproj'
+ );
+
+ // split previous command into array, so we can...
+ $cmd=split(' ', $cmd);
+
+ // see if the action is in the list of actions
+ // that don't get a rerun of previous command
+ if(in_array($cmd[0], $lsCmds)) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+// sets cmd2 input to most recent ls
+function get_cmd2($cmd='',$cmd2='') {
+ if(ls_check($cmd)) {
+ return $cmd;
+ } else {
+ return $cmd2;
+ }
+}
+
+// runs todo.sh command and prints list
+function run_todo($cmd) {
+ global $todoCmd;
+
+ if(!empty($cmd)) {
+ echo '<div id="results-note">Result of: ';
+ echo "<code>".$cmd."</code></div>\n";
+ }
+
+ exec($todoCmd.' '.$cmd, $results);
+
+ $output = "<ul>\n";
+ foreach($results as $task) {
+ // make numbers into links for js
+ $task = preg_replace(
+ '/(^[0-9]+)/', // numbers at start of task
+ '<a class="todo-number" href="javascript:void(0);">$1</a>',
+ $task
+ );
+ // make projects and contexts into links for js
+ $task = preg_replace(
+ '/((@|\+)[\S]+)/', // numbers at start of task
+ '<a class="todo-tag" href="javascript:void(0);">$1</a>',
+ $task
+ );
+ // linkify external links
+ $task = preg_replace(
+ '@(https?://([-\w\.]+)+(:\d+)?(/([\w/_\.]*(\S+)?)?)?[^.\ ,:)])@',
+ '<a target="blank" class="todo-extlink" href="$1">$1</a>',
+ $task
+ );
+ $output .= "\t\t<li>".$task."</li>\n";
+ }
+ $output .= "\t</ul>\n";
+
+ echo $output;
+}
+
+
+function logout() {
+ global $todoUrl, $user;
+ // delete cookie
+ setcookie($user,"todotxt-web", time()-3600);
+ session_unset();
+ echo "You have logged out. <a href=\"".$todoUrl."\">Login</a>.";
+ exit();
+}
+
+?>
64 index.php
@@ -0,0 +1,64 @@
+<?php
+require_once('includes/config.php');
+require_once('includes/access.php');
+require_once('includes/todo.php');
+if($_GET['logout'] == 'true') {logout();}
+$cmd = get_cmd($_GET);
+$cmd2 = get_cmd($_GET, 'cmd2');
+?><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 TRANSITIONAL//EN">
+<html>
+
+<head>
+ <title>todo.txt</title>
+
+ <meta name="viewport" content="initial-scale=1.0,maximum-scale=1,user-scalable=0" />
+ <?php if($iphoneWebApp == 'yes'){ ?>
+ <meta name="apple-mobile-web-app-capable" content="yes" />
+ <?php } ?>
+ <link rel="apple-touch-icon" href="todotxt_logo.png"/>
+
+ <link media="screen" href="stylesheet.css" rel="stylesheet" type="text/css">
+ <link media="handheld" href="handheld.css" rel="stylesheet" type="text/css">
+
+ <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
+ <script type="text/javascript" src="todo.js">
+ </script>
+
+</head>
+
+<body>
+<div id="container">
+
+ <div id="top">
+
+ <h1><a href="<?php echo $todoUrl; ?>">todo.txt</a></h1>
+
+ <form id="todo" name="todo" action="<?php echo $todoUrl; ?>" method="GET">
+ <input autocapitalize="off" autocorrect="off"
+ type="text" id="cmd" name="cmd"
+ value="<?php if(isset($cmd)){echo $cmd." ";} ?>" /><br />
+ <input type="hidden" id="cmd2" name="cmd2"
+ value="<?php echo get_cmd2($cmd,$cmd2); ?>" />
+ <input type="submit" id="sub" value="Submit" />
+ </form>
+ </div>
+
+ <div id="output">
+ <?php
+ // run todo.sh and print list
+ run_todo($cmd);
+
+ // rerun the previous list command if current command is not a list
+ if(isset($cmd2) && !ls_check($cmd)){
+ run_todo($cmd2);
+ }
+ ?>
+ </div>
+
+ <div id="footer">
+ <a href="<?php echo $todoUrl; ?>?logout=true">Logout</a>
+ </div>
+
+</div>
+</body>
+</html>
52 readme.mkd
@@ -0,0 +1,52 @@
+=== todo.txt web interface ===
+
+A simple, iPhone-friendly web interface for [todo.sh](http://todotxt.com) written in PHP and spiced up with a wee bit of jQuery.
+
+Designed to work well in Mobile Safari on an iPhone/iPod Touch. Also tested on a Palm Centro, though the jQuery stuff doesn't work in crappy Blazer. If you try it out on other devices, let me know how it works, ok?
+
+Author: Jon Smajda
+License: GPL, http://www.gnu.org/copyleft/gpl.html
+URL: http://github.com/smajda/todo.txt-web
+
+
+=== Installation ===
+
+1. First, you need a working installation of [todo.sh](http://todotxt.com). (Presumably variants like todo.py will work, though I haven't tested them.)
+
+2. Your todo.txt files and your todo.cfg need to be writable by your webserver. There are a variety of ways to make this happen: chmod 666 on your todo files, set some ACLs, let your web server run todo.sh as sudo... They're all a bit scary, so take your pick.
+
+3. Install the todo.txt-web files where you want them on your web server.
+
+4. Copy or rename the file `includes/config-sample.php` to `includes/config.php` and fill in all the variables. It's well-commented.
+
+5. That should be it. If you have problems, a few things to check:
+
+ * There's an `.htaccess` file in the `includes` directory preventing web access to that directory. If your web server isn't configured to allow this, that can cause problems.
+
+ * I'm using Google's copy of jQuery instead of a local copy. If this is a problem, just [download jQuery](http://jquery.com/) and change the link in the `<head>` section of `index.php`.
+
+
+=== Behavior ===
+
+- By default, it will display whatever command you have set as `TODOTXT_DEFAULT_ACTION` in your todo config file.
+
+- Treat the input box as your command line, only you don't have to type `todo.sh` first. So you can type `ls` to list all your items, but you can also type things like `-h` to get help info.
+
+- The task numbers and tags (words starting with "@" or "+") are links that send numbers or tags to the input box, respectively. After using this for awhile, I found this was the most handy way for this to work:
+
+ * When you click on the task number, it sends that number to the input field for you and then positions the cursor _in front of_ the number. This makes it easy to just type `do`, `pri`, `rm`, `replace`, etc.
+
+ * When you click on a tag, it sends that tag to the input field, prepends `ls ` to the front of it and leaves the cursor at the end of the input field so you can either hit submit or add further `ls ` terms.
+
+- Any regular URLs in your task are also made into links.
+
+- Because I got sick of automatically doing an `ls` again right after any non-listing command: whenever you do any command that isn't an `ls`, the last `ls` command you ran is ran again and displayed right after your command's output.
+
+
+=== Credit ===
+
+I borrowed the idea and some code to get me started from [this thread](http://tech.groups.yahoo.com/group/todotxt/message/1320) on the todotxt mailing list.
+
+The "move the cursor to the start of the input field" trick found on [Stack Overflow](http://stackoverflow.com/questions/499126/jquery-set-cursor-position-in-text-area).
+
+I modified the simple authentication code [found here](http://www.legend.ws/blog/tips-tricks/php-authentication-login-script/).
12 readme.txt
@@ -0,0 +1,12 @@
+Information (author, description, etc.)
+
+
+ Original idea: http://tech.groups.yahoo.com/group/todotxt/message/1320
+
+Installation
+
+
+Behavior
+
+
+Licence
99 stylesheet.css
@@ -0,0 +1,99 @@
+html, body {
+ margin: 0;
+ padding: 0;
+ height:100%;
+}
+body {
+ font-family: 'Lucida Grande', 'Verdana', sans-serif;
+}
+#container {
+ min-height: 100%;
+ position: relative;
+}
+
+h1{
+ font-size: 1.2em;
+ text-align:center;
+ padding: 0;
+}
+
+a {
+ color: #008;
+}
+
+
+/* form */
+div#top {
+ overflow: hidden;
+ padding: 0;
+ margin: 0;
+ background: #eee;
+ border-bottom: solid 1px #777;
+}
+div#top form {
+ margin: 0 5% 0.5em 5%;
+}
+input#cmd{
+ width: 100%;
+ font-size: 1em;
+}
+input#sub{
+ width: 100%;
+ margin-top: 0.5em;
+ font-size: 1.0em;
+}
+
+
+/* output */
+div#output {
+ margin: 0;
+ padding-bottom: 3em; /* height of footer */
+}
+#results-note {
+ font-weight: bold;
+ padding: 7px;
+}
+code {
+ font-family: 'Monaco','Courier','Courier New', monospace;
+ font-weight: normal;
+ font-size: 1.3em;
+ background-color: #eee;
+ padding: 2px;
+}
+ul {
+ margin: 0 5px 6px -2.2em;
+ padding-bottom: 3em;
+}
+ul li {
+ text-indent: -1.7em;
+ padding: 0.5em 0.5 0.5em 1.7em;
+ list-style: none;
+ border-bottom: solid 1px #ccc;
+}
+
+a.todo-number {
+ color: #999;
+ text-decoration: none;
+}
+a.todo-tag {
+ text-decoration: none;
+}
+a.todo-extlink {
+ color: #770000;
+ text-decoration: none;
+}
+
+/* footer */
+div#footer {
+ position: absolute;
+ bottom: 0;
+ height: 3em;
+
+ margin: 0;
+ padding: 1em 0 0 0 ;
+ width: 100%;
+
+ background-color: #eee;
+ text-align: center;
+ border-top: solid 1px #777;
+}
45 todo.js
@@ -0,0 +1,45 @@
+$(function() {
+ // hide toolbar
+ setTimeout(scrollTo, 0, 0, 1);
+
+ // auto-focus the input field
+ $("input#cmd").focus();
+
+ // for todo-tag links
+ $('a.todo-tag').click(function(event){
+ var str = $(event.target).text();
+ str = "ls " + str + " ";
+ $("input#cmd").val(str).focus();
+ });
+
+ // for todo-number links
+ $('a.todo-number').click(function(event){
+ var str = $(event.target).text();
+ $("input#cmd").val(str).focus(function(){
+ $(this).setCursorPosition(0);
+ }).focus();
+ });
+
+ // prevent double submit
+ $('form#todo').submit(function() {
+ $(':submit', this).attr('disabled','disabled').val('Loading...');
+ });
+
+});
+
+// setCursorPosition function for todo-number, from:
+// http://stackoverflow.com/questions/499126/jquery-set-cursor-position-in-text-area
+new function($) {
+ $.fn.setCursorPosition = function(pos) {
+ if ($(this).get(0).setSelectionRange) {
+ $(this).get(0).setSelectionRange(pos, pos);
+ } else if ($(this).get(0).createTextRange) {
+ var range = $(this).get(0).createTextRange();
+ range.collapse(true);
+ range.moveEnd('character', pos);
+ range.moveStart('character', pos);
+ range.select();
+ }
+ }
+}(jQuery);
+
BIN  todotxt_logo.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Please sign in to comment.
Something went wrong with that request. Please try again.