Compare commits

..

10 Commits

Author SHA1 Message Date
168b4f092c add readme & makefile + small typo fixes. 2023-08-20 12:14:52 +02:00
24f3108395 add minimalistic working version. 2023-08-20 11:46:34 +02:00
25bb1ec9c2 start rewrite of spt based on sent rather than inotify. 2023-08-20 10:43:48 +02:00
Ivan Tham
64cdc50fbc
Reduce nap time to 15 minutes as mentioned in docs 2022-04-11 14:35:23 +08:00
Mohammed Anas
9f85802024 Join breaks together 2022-04-11 14:34:30 +08:00
Mohammed Anas
83c4384053 Make a small grammar fix 2022-04-10 23:28:17 +08:00
Ville Witt
b90123aca0 Fix man page for -e.
Maybe we should document for the none programmer, that currently, if
notifycmd is set, the -DNOTIFY part is skipped.
2021-01-11 22:14:17 +08:00
Ivan Tham
628804ae43
Merge pull request #16 from matesz44/patch-1
break times were switched
2020-11-22 01:22:42 +08:00
M4t35Z
c248fc1018
break times were switched 2020-11-20 13:24:35 +01:00
Ivan Tham
d5c2dd57ab
0.6 release 2020-11-06 23:45:15 +08:00
13 changed files with 82 additions and 432 deletions

30
.gitignore vendored
View File

@ -1,30 +0,0 @@
# 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

View File

@ -1,4 +1,5 @@
Copyright (c) 2015-2020, Ivan Tham <pickfire@riseup.net> Copyright (c) 2015-2020, Ivan Tham <pickfire@riseup.net>
2023- , Nuño Sempere <nuno.semperelh@protonmail.com>
Permission to use, copy, modify, and/or distribute this software for any Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above purpose with or without fee is hereby granted, provided that the above

View File

@ -1,59 +0,0 @@
# 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

View File

@ -1,36 +1,26 @@
spt - simple pomodoro timer # pomo - a simple pomodoro timer
===========================
spt is a simple timer that uses the pomodoro technique that doubles your
efficiency.
Features ## about
--------
- Get the jobs done quicker than ever
- Keeps you free like a dog
- Able to show remaining time
Installation pomo is a simple timer that uses the pomodoro technique. It is based on [spt](https://github.com/pickfire/spt), which is a bit less simple.
------------
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 ## dependencies
as root):
make clean install Instead of inotify, this pomodoro timer uses [sent](https://tools.suckless.org/sent/), displaying messages to the user by spawning a process that calls `echo 'msg' | sent`.
See the man pages for additional details. ## installation
Configuration Read pomo.c, then:
-------------
The configuration of spt is done by creating a custom config.h and
(re)compiling the source code. By default, the timer runs by 4
pomodoro timer (25 mins) with subsequent rests in between (15 mins)
followed by a long rest (5 mins) in an infinite loop.
Links ```
----- make
http://pomodorotechnique.com/ sudo make install
```
## usage
The project is licensed under the MIT license. In a terminal, call the "pomo" command. Then, an initial message will appear in its own window. Close it and start working. By default, the timer runs by 4 pomodoro timer (25 mins) with subsequent rests in between (5 mins) followed by a long rest (15 mins) in an infinite loop.
## configuration
read through the <60 lines of C, and change as appropriate. If this functionality is too simple, consider looking at [spt](https://github.com/pickfire/spt) instead.

1
TODO
View File

@ -1 +0,0 @@
Good luck! Nothing TODO for now.

40
arg.h
View File

@ -1,40 +0,0 @@
/*
* 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

View File

@ -1,22 +0,0 @@
/* See LICENSE file for copyright and license details. */
/* Notification, remove DNOTIFY in config.mk if you don't want it */
static char *notifycmd = ""; /* Uses given command if not compiled by DNOTIFY */
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 Timers timers[] = {
/* timer(s) 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!"},
};

View File

@ -1,24 +0,0 @@
# spt version
VERSION = 0.5
# Customize below to fit your system
# paths
PREFIX = /usr/local
MANPREFIX = ${PREFIX}/share/man
INCS = -I. -I/usr/include
LIBS = -L/usr/lib
# libnotify, comment if you don't want it
DEFS = -DNOTIFY
INCS+= `pkg-config --cflags libnotify`
LIBS+= `pkg-config --libs libnotify`
# flags
CPPFLAGS += -DVERSION=\"${VERSION}\" -D_POSIX_C_SOURCE=199309
CFLAGS += -g -std=c99 -pedantic -Wall -Os ${INCS} ${DEFS} ${CPPFLAGS}
LDFLAGS += -g ${LIBS}
# compiler and linker
CC ?= cc

View File

@ -1,6 +0,0 @@
#!/bin/sh
# A notification wrapper for MacOS. It will appear in Notification
# Center as owned by Script Editor.
#
# usage: spt -n ./notify-macos
osascript -e "display notification \"$2\" with title \"$1\""

8
makefile Normal file
View File

@ -0,0 +1,8 @@
build:
gcc pomo.c -o pomo
install:
mv ./pomo /bin/pomo
lint:
clang-tidy pomo.c --

56
pomo.c Normal file
View File

@ -0,0 +1,56 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define MAX_MSG_LEN 100
#define LEN(a) (sizeof(a) / sizeof(a[0]))
typedef struct {
unsigned int t;
char *msg;
} Timers;
static Timers timers[] = {
/* timer(s) 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!"},
{ 900, "Time to take a longer rest!" },
};
void spawn(char *argv[]){
if (fork() == 0) {
// we need to fork the process so that
// when we exit the sent screen
// this program continues.
setsid();
execvp(argv[0], argv);
perror(" failed");
exit(0);
}
}
void display_message(char *msg){
char sh_command[MAX_MSG_LEN];
snprintf(sh_command, MAX_MSG_LEN, "echo '%s' | sent", msg); // NOLINT: We are being carefull here by considering MAX_MSG_LEN explicitly.
printf("%s", sh_command);
char *spawn_args[] = {
"/bin/sh",
"-c",
sh_command,
NULL
};
spawn(spawn_args);
// fprintf(stderr, "%s\n", msg);
}
int main(int argc, char *argv[]){
for(int i=0; ; i = (i+1) % LEN(timers)){
display_message(timers[i].msg);
sleep(timers[i].t);
}
}

51
spt.1
View File

@ -1,51 +0,0 @@
.TH SPT 1 spt\-VERSION
.SH NAME
spt \- simple pomodoro timer
.SH SYNOPSIS
.B spt
.RB [ \-e
.IR notifyext ]
.RB [ \-n
.IR notifycmd ]
.RB [ \-v ]
.SH DESCRIPTION
.B spt
is a simple timer that uses pomodoro technique with desktop notification to
double your efficiency.
.B spt
receives 2 signals:
.P
.RS
.B SIGUSR1
\- show remaining time, state
.br
.B SIGUSR2
\- play/pause the timer
.RE
.SH OPTIONS
.TP
.BI \-e " notifyext"
Execute
.I notifycmd
when timer starts ticking.
.TP
.BI \-n " notifycmd"
Execute
.I notifycmd
if not compiled with
.IR "-DNOTIFY".
.TP
.BI \-v
Prints version information to stderr, then exits.
.SH TIMER
4 pomodoro timer (
.B 25 min.
) with subsequent rests in between (
.B 5 min.
) and followed by a long rest (
.B 15 min.
) in an infinite loop.
.SH EXAMPLES
Use system notify_send and play a music without libnotify:
.IP
spt -e 'aplay alarm.wav' -n 'notify-send'

172
spt.c
View File

@ -1,172 +0,0 @@
/* See LICENSE file for copyright and license details. */
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
#ifdef NOTIFY
#include <libnotify/notify.h>
#endif /* NOTIFY */
#include "arg.h"
char *argv0;
/* macros */
#define LEN(a) (sizeof(a) / sizeof(a[0]))
typedef struct {
unsigned int tmr;
char *cmt;
} Timers;
#include "config.h"
volatile static sig_atomic_t display, suspend;
/* function declarations */
static void die(const char *errstr, ...);
static void spawn(char *argv[]);
static void notify_send(char *cmt);
static void display_state(int remaining, int suspend);
static void toggle_display(int sigint);
static void toggle_suspend(int sigint);
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(1);
}
void
spawn(char *argv[])
{
if (fork() == 0) {
setsid();
execvp(argv[0], argv);
die("spt: execvp %s\n", argv[0]);
perror(" failed");
exit(0);
}
}
void
notify_send(char *cmt)
{
if (strcmp(notifycmd, ""))
spawn((char *[]) { notifycmd, "spt", cmt, NULL });
#ifdef NOTIFY
else {
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();
}
#endif /* NOTIFY */
if (strcmp(notifyext, "")) /* extra commands to use */
spawn((char *[]) { "/bin/sh", "-c", notifyext, NULL });
}
void
display_state(int remaining, int suspend)
{
char buf[29];
snprintf(buf, 29, "Remaining: %02d:%02d %s",
remaining / 60,
remaining % 60,
(suspend) ? "" : "");
notify_send(buf);
display = 0;
}
void
toggle_display(int sigint)
{
display = 1;
}
void
toggle_suspend(int sigint)
{
suspend ^= 1;
}
void
usage(void)
{
die("usage: %s [-e notifyext] [-n notifycmd] [-v]\n", argv0);
}
int
main(int argc, char *argv[])
{
struct timespec remaining;
struct sigaction sa;
sigset_t emptymask;
int i;
ARGBEGIN {
case 'e':
notifyext = EARGF(usage());
break;
case 'n':
notifycmd = EARGF(usage());
break;
case 'v':
die("spt " VERSION " © 2015-2020 spt engineers, "
"see LICENSE for details\n");
default:
usage();
} ARGEND;
/* add SIGUSR1 handler: remaining_time */
sa.sa_handler = toggle_display;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
if (sigaction(SIGUSR1, &sa, NULL) == -1)
die("cannot associate SIGUSR1 to handler\n");
/* add SIGUSR2 handler: toggle */
sa.sa_handler = toggle_suspend;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
if (sigaction(SIGUSR2, &sa, NULL) == -1)
die("cannot associate SIGUSR2 to handler\n");
sigemptyset(&emptymask);
for (i = 0; ; i = (i + 1) % LEN(timers)) {
notify_send(timers[i].cmt);
remaining.tv_sec = timers[i].tmr;
remaining.tv_nsec = 0;
while (remaining.tv_sec) {
if (display)
display_state(remaining.tv_sec, suspend);
if (suspend)
sigsuspend(&emptymask);
else
if (nanosleep(&remaining, &remaining) == 0)
remaining.tv_sec = remaining.tv_nsec = 0;
}
}
return 0;
}