about summary refs log tree commit diff
diff options
context:
space:
mode:
authorXiao Pan <gky44px1999@gmail.com>2024-06-15 02:22:17 -0700
committerXiao Pan <gky44px1999@gmail.com>2024-06-15 02:22:17 -0700
commit21e8d30d3e6fea0db5f345ba18936e66a1941a09 (patch)
tree84e4f338d8574ff5437c0bf58d24f8269bc52dfd
parent561777b7e71d278485e200752350dea6c92b0089 (diff)
archive dynotify
-rw-r--r--c/.gitignore1
-rw-r--r--c/Makefile20
-rw-r--r--c/dynotify.c144
3 files changed, 165 insertions, 0 deletions
diff --git a/c/.gitignore b/c/.gitignore
new file mode 100644
index 0000000..061bc35
--- /dev/null
+++ b/c/.gitignore
@@ -0,0 +1 @@
+dynotify
diff --git a/c/Makefile b/c/Makefile
new file mode 100644
index 0000000..bab4f8f
--- /dev/null
+++ b/c/Makefile
@@ -0,0 +1,20 @@
+PREFIX = /usr/local
+
+all: dynotify
+
+dynotify: dynotify.c
+#	https://stackoverflow.com/q/28533059
+#	https://stackoverflow.com/q/3220277
+	cc -Wall $$(pkg-config --cflags --libs libnotify libcurl json-c) -o $@ $<
+
+clean:
+	rm -f dynotify
+
+install: all
+	mkdir -p ${DESTDIR}${PREFIX}/bin
+	cp -f dynotify ${DESTDIR}${PREFIX}/bin
+
+uninstall:
+	rm -f ${DESTDIR}${PREFIX}/bin/dynotify
+
+.PHONY: all clean install uninstall
diff --git a/c/dynotify.c b/c/dynotify.c
new file mode 100644
index 0000000..ec7cea8
--- /dev/null
+++ b/c/dynotify.c
@@ -0,0 +1,144 @@
+// curl:
+// man curl_easy_init CURLOPT_URL curl_easy_setopt CURLOPT_WRITEFUNCTION libcurl-errors curl_easy_strerror
+// https://curl.se/libcurl/
+// https://curl.se/libcurl/c/
+// https://curl.se/libcurl/c/libcurl-tutorial.html
+// https://stackoverflow.com/a/2329792
+
+// json-c:
+// pacman -Qs json c
+// https://github.com/json-c/json-c#using
+// https://github.com/json-c/json-c/blob/master/tests/test2.c
+// https://github.com/rbtylee/tutorial-jsonc/blob/master/tutorial/legacy.md
+// https://github.com/rbtylee/tutorial-jsonc/blob/master/tutorial/parsing2.md
+
+// libnotify:
+// https://gitlab.gnome.org/GNOME/libnotify/-/blob/master/tests/test-basic.c?ref_type=heads
+// https://gnome.pages.gitlab.gnome.org/libnotify/index.html
+
+// compile, maybe wrong:
+// https://stackoverflow.com/a/39120702
+// cc -Wall -lcurl -ljson-c $(pkg-config --cflags --libs libnotify) ./dynotify.c
+// or:
+// cc -Wall $(pkg-config --cflags --libs libnotify libcurl json-c) ./dynotify.c
+// misc:
+// /usr/lib/pkgconfig/libnotify.pc
+
+#include<stdio.h> // for sprintf
+#include<stdbool.h> // for bool
+#include<stdlib.h> // for realloc
+#include<string.h> // for memcpy
+#include<unistd.h> // for sleep
+#include<curl/curl.h> // MIT
+#include<json-c/json.h> // MIT
+#include<libnotify/notify.h> //LGPL
+
+#define DYROOM_ID_LEN 9
+// utf-8 most chinese characters 3 bytes, my longest name currently is 2 chinese characters, 2*3=6, +1 for \0
+// but gcc will not error when not consider \0, maybe the complier auto add one more element?
+#define DYROOM_NAME_LEN 6
+
+struct memory {
+	char *response;
+	size_t size;
+};
+
+struct dyroom {
+	// another way: `const char *name;`
+	const char name[DYROOM_NAME_LEN];
+	const unsigned int id;
+	bool up;
+};
+
+// /home/xyz/archive/programs/private_archive_codes/c/c_primer_plus/practices/Chapter14/14-1monthStruct.c 
+struct dyroom room[5]={
+	{"阿冉",4605243,false},
+	{"甜汤",2766480,false},
+	{"少君",9640128,false},
+	{"她她",236288,false},
+	{"郑正",10883525,false}
+};
+
+// copy from `man CURLOPT_WRITEFUNCTION`
+static size_t cb(char *data, size_t size, size_t nmemb, void *clientp)
+{
+	size_t realsize = size * nmemb;
+	struct memory *mem = (struct memory *)clientp;
+
+	char *ptr = realloc(mem->response, mem->size + realsize + 1);
+	if(!ptr)
+		return 0;  /* out of memory! */
+
+	mem->response = ptr;
+	memcpy(&(mem->response[mem->size]), data, realsize);
+	mem->size += realsize;
+	mem->response[mem->size] = 0;
+
+	return realsize;
+}
+
+int main (void)
+{
+	// man libcurl-errors
+	CURLcode res;
+	// `man curl_easy_init`: "It is encouraged to reuse easy handles for repeated transfers.", so I choose to reuse it
+	CURL *curl = curl_easy_init();
+	NotifyNotification *n;
+	notify_init ("dynotify");
+
+	if(curl) {
+		for(;;)
+		{
+			for(int i=0;i<5;i++)
+			{
+				// manpage assign 0 to struct, it seems because C11 when cast 0 to void* is same as NULL? see:
+				// https://www.geeksforgeeks.org/null-pointer-in-c/
+				struct memory chunk = {0};
+				char url[29+DYROOM_ID_LEN];
+				sprintf(url, "https://www.douyu.com/betard/%d", room[i].id);
+
+				curl_easy_setopt(curl, CURLOPT_URL, url);
+				curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, cb);
+				curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
+				res = curl_easy_perform(curl);
+				// man curl_easy_strerror
+				if(res != CURLE_OK)
+				{
+					fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
+					free(chunk.response);
+					break;
+				}
+				//printf("%s\n",chunk.response);
+
+				json_object *root;
+				root=json_tokener_parse(chunk.response);
+				if (json_object_get_int(json_object_object_get(json_object_object_get(root,"room"),"show_status")) == 1)
+				{
+					if(!room[i].up)
+					{
+						// 开播 is 2*3=6 bytes
+						char msg[DYROOM_NAME_LEN+6];
+						sprintf(msg,"%s开播",room[i].name);
+
+						n = notify_notification_new (msg, NULL, NULL);
+						notify_notification_set_urgency(n, NOTIFY_URGENCY_CRITICAL);
+						notify_notification_show (n, NULL);
+
+						room[i].up=true;
+					}
+				}
+				else if(room[i].up)
+					room[i].up=false;
+
+				free(chunk.response);
+				// must call json_object_put to free *root, else memory leak!
+				json_object_put(root);
+			}
+			sleep(60);
+		}
+		curl_easy_cleanup(curl);
+	}
+
+	g_object_unref (G_OBJECT (n));
+	return 0;
+}