Skip to content

Commit

Permalink
A calendar with terminal interface, web interface and git integration
Browse files Browse the repository at this point in the history
  • Loading branch information
kjellwinblad committed Apr 1, 2017
0 parents commit 2f48b89
Show file tree
Hide file tree
Showing 26 changed files with 3,812 additions and 0 deletions.
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.#*
*~
/wtplan
/wtplan-web
/bin
src/wtplan-web/textfiles.go
src/wtplan-web/wtplan-web
src/wtplan/wtplan
src/wtplan/version.go
20 changes: 20 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Copyright 2017 Kjell Winblad ([email protected], http://winsh.me)

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
52 changes: 52 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# wtplan
# See LICENSE file for copyright and license details.

include config.mk


export GOPATH=$(shell pwd)
export VERSIONSTR=${VERSION}

all: wtplan wtplan-web

wtplan: src/wtplan/main.go
${GO} generate wtplan
${GO} build wtplan

wtplan-web: $(wildcard src/wtplan-web/*.go src/wtplan-web/*.js)
${GO} generate wtplan-web
${GO} build wtplan-web

clean:
@echo cleaning
@rm -f wtplan
@rm -f wtplan-web

dist: clean
@echo creating dist tarball
@mkdir -p wtplan-${VERSION}
@cp -R src LICENSE Makefile config.mk README.md wtplan.1 wtplan-${VERSION}
@tar -cf wtplan-${VERSION}.tar wtplan-${VERSION}
@gzip wtplan-${VERSION}.tar
@rm -rf wtplan-${VERSION}

install: all
@echo installing executable files wtplan and wtplan-web to ${DESTDIR}${PREFIX}/bin
@mkdir -p ${DESTDIR}${PREFIX}/bin
@cp -f wtplan ${DESTDIR}${PREFIX}/bin
@chmod 755 ${DESTDIR}${PREFIX}/bin/wtplan
@cp -f wtplan-web ${DESTDIR}${PREFIX}/bin
@chmod 755 ${DESTDIR}${PREFIX}/bin/wtplan-web
@echo installing manual page to ${DESTDIR}${MANPREFIX}/man1
@mkdir -p ${DESTDIR}${MANPREFIX}/man1
@sed "s/VERSION/${VERSION}/g" < wtplan.1 > ${DESTDIR}${MANPREFIX}/man1/wtplan.1
@chmod 644 ${DESTDIR}${MANPREFIX}/man1/wtplan.1

uninstall:
@echo removing executable files from ${DESTDIR}${PREFIX}/bin
@rm -f ${DESTDIR}${PREFIX}/bin/wtplan
@rm -f ${DESTDIR}${PREFIX}/bin/wtplan-web
@echo removing manual page from ${DESTDIR}${MANPREFIX}/man1
@rm -f ${DESTDIR}${MANPREFIX}/man1/wtplan.1

.PHONY: all clean dist install uninstall
40 changes: 40 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
wtplan - web terminal planner
=============================

wtplan helps you manage a calendar. The calendar can be managed from a
command line interface and/or a web interface. The calendar data is
stored in a simple text file (located in `~/.wtplan` by
default). wtplan integrates with git to make backup and
synchronization between multiple computers convenient.


See the man page (`wtplan.1`) for more details

Features
--------

* command line interfaces
* web interface
* optional password authentication
* git integration
* simple json based data format

Requirements
------------

* golang is required to compile wtplan.
* (optional) git is required if you want to use wtplan's git integration.
* (optional) make makes building and installing more convenient but is not
required. See the Makefile for how to build without make.

Install
-------

1. Edit the paths in config.mk to fit your system if needed. (wtplan is
installed into `/usr/local/{bin,share/man/man1}` by default.)
2. Run `make install` as root. (This will build and install wtplan)

License
-------

The MIT/X Consortium License. See the LICENSE file for details.
13 changes: 13 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
* Make the web interface usable even when there is no connection to
the server. This can be done by adding a command queue to the web
interface that can be flushed when the server is accessible again.

* Make it possible to read calendar data from multiple config
folders. This can be useful if one wants to share a kid's calendar
with the other parent. This could be implemented by letting one
specify additional calendar data files when starting the web
interface. The calendar data from the additional calendar data files
would then be viewable in a read-only way in the web interface.

* Support for importing calendar data from an iCal formatted calendar
data file.
11 changes: 11 additions & 0 deletions config.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# wtplan version
VERSION = 0.1

# Customize below to fit your system

# paths
PREFIX = /usr/local
MANPREFIX = ${PREFIX}/share/man

# Compiler and build tool
GO = go
51 changes: 51 additions & 0 deletions src/wtplan-web/calendar_item.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright 2017 Kjell Winblad ([email protected], http://winsh.me)
// License: MIT License, see the LICENSE file

var WTPLAN = WTPLAN || {};

(function() {

//Constructor
WTPLAN.CalendarItem = function(calendarItemData, id) {
this.date = calendarItemData.date;
this.duration = calendarItemData.duration;
this.description = calendarItemData.description;
this.id = id;
};

WTPLAN.CalendarItem.prototype.startDate = function() {
return new Date(this.date);
};

WTPLAN.CalendarItem.prototype.endDate = function() {
var result = WTPLAN.durationRegExp.exec(this.duration);
if (result[1] === "NA") {
return this.startDate();
}
var hours = 0;
var minutes = 0;
if (result[2] != undefined) {
hours = parseInt(result[2], 10);
}
if (result[3] != undefined) {
minutes = parseInt(result[3], 10);
}
var endDate = new Date(this.startDate());
endDate.setHours(endDate.getHours() + hours);
endDate.setMinutes(endDate.getMinutes() + minutes);
return endDate;
};

WTPLAN.CalendarItem.prototype.toPlainObject = function() {
return {
date: this.date,
duration: this.duration,
description: this.description
};
};

WTPLAN.CalendarItem.prototype.toString = function() {
return this.date;
};

})();
75 changes: 75 additions & 0 deletions src/wtplan-web/component.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// Copyright 2017 Kjell Winblad ([email protected], http://winsh.me)
// License: MIT License, see the LICENSE file

var WTPLAN = WTPLAN || {};

(function() {
var componentId = 0;

WTPLAN.Component = function(props) {
if (props === undefined) {
this.state = {};
} else {
this.state = props;
}
this.componentId = componentId;
componentId = componentId + 1;
}

WTPLAN.Component.prototype.renderAt = function(element) {
var newElement = $(this.render());
newElement.attr("data-wtplanid", "" + this.componentId);
element.replaceWith(newElement);
var outerThis = this;
outerThis.componentDidMount(newElement);
};

WTPLAN.Component.prototype.setState = function(newState) {
this.state = newState;
var element = this.getRenderedComponent();
var renderedHtml = this.render();
var newElement = $(renderedHtml);
newElement.attr("data-wtplanid", "" + this.componentId);
element.replaceWith(newElement);
var outerThis = this;
outerThis.componentDidMount(newElement);
};

WTPLAN.Component.prototype.render = function() {
console.log("WARNING: render has not been implemented for component");
}

WTPLAN.Component.prototype.componentDidMount = function(element) {

}

WTPLAN.Component.prototype.getRenderedComponent = function() {
return $('[data-wtplanid="' + this.componentId + '"]');
}

// Object.create() polyfill from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create

if (typeof Object.create != 'function') {
Object.create = (function(undefined) {
var Temp = function() {};
return function(prototype, propertiesObject) {
if (prototype !== Object(prototype) && prototype !== null) {
throw TypeError('Argument must be an object, or null');
}
Temp.prototype = prototype || {};
var result = new Temp();
Temp.prototype = null;
if (propertiesObject !== undefined) {
Object.defineProperties(result, propertiesObject);
}

// to imitate the case of Object.create(null)
if (prototype === null) {
result.__proto__ = null;
}
return result;
};
})();
}

})();
42 changes: 42 additions & 0 deletions src/wtplan-web/day_list.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright 2017 Kjell Winblad ([email protected], http://winsh.me)
// License: MIT License, see the LICENSE file

var WTPLAN = WTPLAN || {};

(function() {

//Constructor
WTPLAN.DayList = function(params) {
WTPLAN.Component.call(this);
this.state = params;
}
//Extending Component
WTPLAN.DayList.prototype = Object.create(WTPLAN.Component.prototype);
WTPLAN.DayList.prototype.constructor = WTPLAN.DayList;

//Methods
WTPLAN.DayList.prototype.render = function() {
var dayDivs = "";
var i = 0;
for (var i = 0; i <= this.state.numberOfDaysAfterToday; i++) {
dayDivs = dayDivs + '<div id="day' + i + '"></div>';
}
return '<div>' + dayDivs + '</div>';
};

WTPLAN.DayList.prototype.componentDidMount = function(component) {
var currentDay = WTPLAN.getLocalStartOfDay(this.state.currentDay);
var i = 0;
for (; i <= this.state.numberOfDaysAfterToday; i++) {
new WTPLAN.DayListDay({
'currentDay': new Date(currentDay.getTime()),
'calendarItems': this.state.calendarItems,
'openAddDialog': this.state.openAddDialog,
'openEditDialog': this.state.openEditDialog,
'removeItemAction': this.state.removeItemAction
}).renderAt($('#day' + i));
currentDay.setDate(currentDay.getDate() + 1);;
}
};

})()
Loading

0 comments on commit 2f48b89

Please sign in to comment.