welcome - welcome - a terminal program which always greets you

git clone git://git.bcharge.de/welcome.git

About | Log | Files | Refs | License

commit 0eb7692a92641249f0c5d1f5c19e2759892981d2
Author: Bakar Chargeishvili <bakar@bcharge.de>
Date:   Mon, 11 Dec 2023 14:00:43 +0100

Initial commit

Diffstat:
A.gitignore | 2++
ALICENSE | 29+++++++++++++++++++++++++++++
AMakefile | 40++++++++++++++++++++++++++++++++++++++++
AREADME.md | 3+++
Awelcome.c | 179+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 253 insertions(+), 0 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -0,0 +1,2 @@ +*.o +welcome diff --git a/LICENSE b/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2023, Bakar Chargeishvili +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Makefile b/Makefile @@ -0,0 +1,40 @@ +# welcome - a program which always greets you +# See LICENSE file for copyright and license details. + +#version +VERSION = 0.1 + +# paths +PREFIX = /usr/local + +# includes and libs +INCS = -I$(PREFIX)/include +LIBS = -L$(PREFIX)/lib -lncurses -l curl + +# flags +CFLAGS = -pedantic -Wall -Os $(INCS) +LDFLAGS = $(LIBS) + +# compiler and linker +CC = cc + +SRC = welcome.c +OBJ = $(SRC:.c=.o) + +all: options welcome + +options: + @echo welcome build options: + @echo "CFLAGS = $(CFLAGS)" + @echo "LDFLAGS = $(LDFLAGS)" + @echo "CC = $(CC)" + +.c.o: + $(CC) -c $(CFLAGS) $< + +welcome: welcome.o + #gcc -Wall -lncurses -l curl welcome.c -o welcome + $(CC) -o $@ welcome.o $(LDFLAGS) + +clean: + rm -f welcome $(OBJ) diff --git a/README.md b/README.md @@ -0,0 +1,3 @@ +# Welcome - a program which always greets you + +Coming soon... diff --git a/welcome.c b/welcome.c @@ -0,0 +1,179 @@ +/* See LICENSE file for copyright and license details. */ + +#include <curses.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <curl/curl.h> +#include <locale.h> + +#define MAXPIPE 1024 +#define EVBOX_W 50 + +typedef struct { + char *ptr; + size_t len; +} string; + +void init_string(string *s) { + s->len = 0; + s->ptr = malloc(s->len+1); + if (s->ptr == NULL) { + fprintf(stderr, "malloc() failed\n"); + exit(EXIT_FAILURE); + } + s->ptr[0] = '\0'; +} + +size_t writefunc(void *ptr, size_t size, size_t nmemb, string *s) +{ + size_t new_len = s->len + size*nmemb; + s->ptr = realloc(s->ptr, new_len+1); + if (s->ptr == NULL) { + fprintf(stderr, "realloc() failed\n"); + exit(EXIT_FAILURE); + } + memcpy(s->ptr+s->len, ptr, size*nmemb); + s->ptr[new_len] = '\0'; + s->len = new_len; + + return size*nmemb; +} + +int curl(char* input, string* output) +{ + CURL *curl; + CURLcode res; + + curl = curl_easy_init(); + if(curl) { + //string s; + //init_string(&s); + + curl_easy_setopt(curl, CURLOPT_URL, input); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, output); + res = curl_easy_perform(curl); + + //printf("Inside curl: %s", output->ptr); + //free(s.ptr); + + /* always cleanup */ + curl_easy_cleanup(curl); + } + return 0; +} + +int pipe(char* input, char* output) { + //char buf[11500] = {0}; + char* buf = output; + + FILE *fp; + + if ((fp = popen(input, "r")) == NULL) { + printf("Error opening pipe!\n"); + } + size_t len=MAXPIPE; + getdelim(&buf, &len, '\0', fp); + //while (fgets(buf, 400, fp) != NULL) { + //mvaddstr(++lineno, COLS/2-shift, buf); + //printw(buf); + //printf("OUTPUT: %s", buf); + //} + //printf("OUTPUT: %s", output); + + if (pclose(fp)) { + printf("Command not found or exited with error status\n"); + } + + return 0; +} + +int print_greet(WINDOW* frame) { + char buf[500] = {0}; + const char *cmd = "figlet Welcome Bakar!"; + + FILE *fp; + + if ((fp = popen(cmd, "r")) == NULL) { + printf("Error opening pipe!\n"); + } + //ssize_t bytes_read = getdelim(&buf, &len, '\0', fp); + int lineno = 0; + int shift = 0; + while (fgets(buf, 400, fp) != NULL) { + if(lineno==0) + shift=strlen(buf)/2; + mvwaddstr(frame,++lineno, COLS/2-shift, buf); + //printw(buf); + //printf("OUTPUT: %s", buf); + } + + if (pclose(fp)) { + printf("Command not found or exited with error status\n"); + } + + return 0; +} + +int main() +{ + setlocale(LC_ALL, ""); + initscr(); + cbreak(); + noecho(); + curs_set(0); + start_color(); + init_pair(1, COLOR_RED, COLOR_BLACK); + + WINDOW* mainframe = newwin(LINES,COLS-2,0,1); + + wattron(mainframe,COLOR_PAIR(1)); + //printw("Hello World !!!"); + wattron(mainframe,A_BLINK); + wattron(mainframe,A_BOLD); + print_greet(mainframe); + wattroff(mainframe,A_BLINK); + + /***************************** + * Extract the information * + *****************************/ + string location; + init_string(&location); + string temperature; + init_string(&temperature); + char *events = calloc(MAXPIPE + 1,sizeof(char)); + char *today = calloc(MAXPIPE + 1,sizeof(char)); + curl("wttr.in/?format=%l",&location); + curl("wttr.in/?format=%t%20(%f)",&temperature); + pipe("calcurse -r7 --format-apt='- %S -> %E %m\n' --output-datefmt=\"%B %d, %Y\"",events); + pipe("date '+%B %d, %Y' | tr -d '\n'",today); + if(events[0]=='\0') + strcpy(events,"🎉 Looks like you have not planned anything 🎉\n" + ); + + /*************************** + * Print the information * + ***************************/ + wprintw(mainframe,"Today is:\t%s\n",today); + wprintw(mainframe,"We are in:\t%s\n",location.ptr); + wprintw(mainframe,"Temperature:\t%s\n",temperature.ptr); + refresh(); + wrefresh(mainframe); + + WINDOW* fr = newwin(LINES/2,EVBOX_W,LINES/2,(COLS-EVBOX_W)/2); + WINDOW* c = derwin(fr,LINES/2-2,EVBOX_W-4,1,2); + box(fr,0,0); + //wmove(fr, 0, 0); + //printw("Events within next 7 days:\t%s\n",events); + char evts_title[]="Events within next 7 days\n\n"; + mvwaddstr(c,0,(EVBOX_W-strlen(evts_title))/2-1,evts_title); + wprintw(c,events); + wrefresh(fr); + + getch(); + endwin(); + + return 0; +}