summaryrefslogtreecommitdiff
path: root/dynotify.c
blob: 9ee06cebafa4366b683ddec0ab791152635682d8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// curl:
// man curl_easy_init CURLOPT_URL curl_easy_setopt CURLOPT_WRITEFUNCTION
// 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<stdlib.h>
#include<string.h>
#include<stdbool.h>
#include<unistd.h>
// MIT
#include<curl/curl.h>
// MIT
#include<json-c/json.h> 
// LGPL2
#include<libnotify/notify.h>

#define DYROOM_ID_LEN 9

struct memory {
	char *response;
	size_t size;
};

struct dyroom {
	// utf-8 most chinese characters 3 bytes, my longest msg currently is 5 chinese characters, 5*3=15, +1 for \0
	// but gcc will not error when use 15, maybe the complier auto add one more element?
	const char msg[16];
	const char id[DYROOM_ID_LEN];
	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)
{
	// https://curl.se/libcurl/c/libcurl-errors.html
	//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]="https://www.douyu.com/betard/";
				strcat(url,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);
				curl_easy_perform(curl);
				//printf("%s\n",chunk.response);

				if (json_object_get_int(json_object_object_get(json_object_object_get(json_tokener_parse(chunk.response),"room"),"show_status")) == 1)
				{
					if(!room[i].up)
					{
						n = notify_notification_new (room[i].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);
			}
			sleep(60);
		}
		curl_easy_cleanup(curl);
	}

	g_object_unref (G_OBJECT (n));
	return 0;
}