Initial commit

This commit is contained in:
Ivan Tham 2015-11-28 21:08:54 +08:00
commit 8f2d5e294f
10 changed files with 403 additions and 0 deletions

30
.gitignore vendored Normal file
View File

@ -0,0 +1,30 @@
# Object files
*.o
*.ko
*.obj
*.elf
# Libraries
*.lib
*.a
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
/spt
# vim
*.swp
*~
config.h

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT/X Consortium License
© 2015 Ivan Tham <pickfire at riseup dot net>
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.

59
Makefile Normal file
View File

@ -0,0 +1,59 @@
# spt - simple pomodoro timer
# See LICENSE file for copyright and license details.
include config.mk
SRC = spt.c
OBJ = ${SRC:.c=.o}
all: options spt
options:
@echo spt build options:
@echo "CFLAGS = ${CFLAGS}"
@echo "LDFLAGS = ${LDFLAGS}"
@echo "CC = ${CC}"
.c.o:
@echo CC $<
@${CC} -c ${CFLAGS} $<
${OBJ}: config.h config.mk
config.h:
@echo creating $@ from config.def.h
@cp config.def.h $@
spt: ${OBJ}
@echo CC -o $@
@${CC} -o $@ ${OBJ} ${LDFLAGS}
clean:
@echo cleaning
@rm -f ${SRC:.c=} ${OBJ} spt-${VERSION}.tar.xz
dist: clean
@echo creating dist tarball
@mkdir -p spt-${VERSION}
@cp -R LICENSE Makefile README config.mk config.def.h spt.info spt.1 ${SRC} spt-${VERSION}
@tar -cf spt-${VERSION}.tar spt-${VERSION}
@xz spt-${VERSION}.tar
@rm -rf spt-${VERSION}
install: all
@echo installing executable file to ${DESTDIR}${PREFIX}/bin
@mkdir -p ${DESTDIR}${PREFIX}/bin
@cp -f spt ${DESTDIR}${PREFIX}/bin
@chmod 755 ${DESTDIR}${PREFIX}/bin/spt
@echo installing manual page to ${DESTDIR}${MANPREFIX}/man1
@mkdir -p ${DESTDIR}${MANPREFIX}/man1
@sed "s/VERSION/${VERSION}/g" < spt.1 > ${DESTDIR}${MANPREFIX}/man1/spt.1
@chmod 644 ${DESTDIR}${MANPREFIX}/man1/spt.1
uninstall:
@echo removing executable file from ${DESTDIR}${PREFIX}/bin
@rm -f ${DESTDIR}${PREFIX}/bin/spt
@echo removing manual page from ${DESTDIR}${MANPREFIX}/man1
@rm -f ${DESTDIR}${MANPREFIX}/man1/spt.1
.PHONY: all options clean dist install uninstall

37
README Normal file
View File

@ -0,0 +1,37 @@
spt - simple pomodoro timer
===========================
spt is a simple timer that uses the pomodoro technique that doubles your
efficiency.
Features
--------
- Get the jobs done quicker than ever
- Keeps you free like a dog
Installation
------------
Edit config.mk to match your local setup (spt is installed into the /usr/local
namespace by default).
Afterwards enter the following command to build and install spt (if necessary
as root):
make clean install
See the man pages for additional details.
Configuration
-------------
The configuration of dwm is done by creating a custom config.h
and (re)compiling the source code.
Links
-----
http://pomodorotechnique.com/
The project is licensed under the MIT license.

9
TODO Normal file
View File

@ -0,0 +1,9 @@
major
-----
- Add options to start and stop spt with only one process
misc
----
$ grep -n 'TODO' spt.c
# vim:ft=markdown:

40
arg.h Normal file
View File

@ -0,0 +1,40 @@
/*
* Copy me if you can.
* by 20h
*/
#ifndef __ARG_H__
#define __ARG_H__
extern char *argv0;
#define USED(x) ((void)(x))
#define ARGBEGIN for (argv0 = *argv, argv++, argc--;\
argv[0] && argv[0][1]\
&& argv[0][0] == '-';\
argc--, argv++) {\
char _argc;\
char **_argv;\
if (argv[0][1] == '-' && argv[0][2] == '\0') {\
argv++;\
argc--;\
break;\
}\
for (argv[0]++, _argv = argv; argv[0][0];\
argv[0]++) {\
if (_argv != argv)\
break;\
_argc = argv[0][0];\
switch (_argc)
#define ARGEND }\
USED(_argc);\
}\
USED(argv);\
USED(argc);
#define EARGF(x) ((argv[1] == NULL)? ((x), abort(), (char *)0) :\
(argc--, argv++, argv[0]))
#endif

22
config.def.h Normal file
View File

@ -0,0 +1,22 @@
/* See LICENSE file for copyright and license details. */
/* Notification */
static char *notifycmd = "libnotify"; /* Use built-in libnotify if empty */
static char *notifyext = ""; /* Notify with extra command (eg. play an alarm) */
/*
* This is the array which defines all the timer that will be used.
* It will be repeated after all of it is executed.
*/
static Timer timer[] = {
/* timer comment */
{ 1500, "Time to start working!"},
{ 300, "Time to start resting!"},
{ 1500, "Time to start working!"},
{ 300, "Time to start resting!"},
{ 1500, "Time to start working!"},
{ 300, "Time to start resting!"},
{ 1500, "Time to start working!"},
{ 300, "Time to start resting!"},
{ 900, "Time to take some nap!"},
};

22
config.mk Normal file
View File

@ -0,0 +1,22 @@
# spt version
VERSION = 0.0
# Customize below to fit your system
# paths
PREFIX = /usr/local
MANPREFIX = ${PREFIX}/share/man
# includes and libs
INCS = -I. -I/usr/include \
`pkg-config --cflags libnotify`
LIBS = -L/usr/lib \
`pkg-config --libs libnotify`
# flags
CPPFLAGS = -DVERSION=\"${VERSION}\"
CFLAGS += -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS}
LDFLAGS += -g ${LIBS}
# compiler and linker
# CC = cc

52
spt.1 Normal file
View File

@ -0,0 +1,52 @@
.TH SPT 1 spt\-VERSION
.SH NAME
spt \- simple pomodoro timer
.SH SYNOPSIS
.B spt
.RB [ \-e
.IR notifycmd ]
.RB [ \-n
.IR notifyext ]
.RB [ \-v ]
.SH DESCRIPTION
.B spt
is a simple timer that uses pomodoro technique with desktop notification to
double your efficiency.
.SH OPTIONS
.TP
.BI \-e " notifyext"
Execute
.I notifycmd
when timer starts ticking.
.TP
.BI \-n " notifycmd"
If
.IR empty ,
do nothing. If
.IR libnotify ,
use the default notification. If neither, it will use the command specified.
.TP
.BI \-v
Prints version information to stderr, then exits.
.SH TIMER
4 pomodoro timer
.RB ( "25 min." )
with subsequent rests in between
.RB ( "5 min." )
and
followed by a long rest
.RB ( "15 min." )
.SH EXAMPLES
Use system notify_send and play a music without libnotify:
.RS
.B spt -e 'aplay alarm.wav' -n 'notify-send'
.RE
.SH AUTHOR
The author is not that important. A message from the author:
.TP
.I "Good luck and have a nice day!"
.SH LICENSE
See the LICENSE file for the terms of redistribution.
.SH BUGS
Bugs? You must be kidding; there is no bugs in this software. But if we
happened to be wrong, please report the bugs!

111
spt.c Normal file
View File

@ -0,0 +1,111 @@
/* See LICENSE file for copyright and license details. */
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <libnotify/notify.h>
#include "arg.h"
char *argv0;
/* macros */
#define LEN(a) (sizeof(a) / sizeof(a)[0])
typedef struct {
unsigned int tmr;
char *cmt;
} Timer;
#include "config.h"
/* function declarations */
static void die(const char *errstr, ...);
static void spawn(char *);
static void notify_send(char *);
static void usage(void);
/* functions implementations */
void
die(const char *errstr, ...)
{
va_list ap;
va_start(ap, errstr);
vfprintf(stderr, errstr, ap);
va_end(ap);
exit(EXIT_FAILURE);
}
void
spawn(char *cmd)
{
if (fork() == 0) {
setsid();
execvp("sh", (char *const []){"/bin/sh", "-c", cmd, 0});
fprintf(stderr, "spt: execvp %s", cmd);
perror(" failed");
exit(0);
}
}
void
notify_send(char *cmt)
{
if (!strcmp(notifycmd, "libnotify")) { /* use libnotify */
notify_init("spt");
NotifyNotification *n = notify_notification_new("spt", cmt, "dialog-information");
notify_notification_show(n, NULL);
g_object_unref(G_OBJECT(n));
notify_uninit();
} else if (strcmp(notifycmd, "")) {
/* TODO(pickfire): merge this into spawn() */
if (fork() == 0) {
setsid();
execlp(notifycmd, "spt", cmt, NULL);
fprintf(stderr, "spt: execlp %s", notifycmd);
perror(" failed");
exit(0);
}
}
if (strcmp(notifyext, "")) /* extra commands to use */
spawn(notifyext);
}
void
usage(void)
{
die("usage: %s [-e notifyext] [-n notifycmd] [-v]\n", argv0);
}
int
main(int argc, char *argv[])
{
int i = 0;
ARGBEGIN {
case 'e':
notifyext = EARGF(usage());
break;
case 'n':
notifycmd = EARGF(usage());
break;
case 'v':
die("spt " VERSION " © 2015 spt engineers, "
"see LICENSE for details\n");
default:
usage();
break;
} ARGEND;
run:
notify_send(timer[i].cmt);
sleep(timer[i].tmr);
i + 1 >= LEN(timer) ? i = 0 : i++; /* i infinal loop */
goto run;
return 0;
}