mirror of
https://github.com/Llewellynvdm/conky.git
synced 2024-11-17 10:35:10 +00:00
Add new ${github_notifications} variable to count all unread notifications (#637)
* Add new ${github} variable to count all unread notifications * doc/variables.xml: add github_notifications * common.cc: Make the "skip" variable static so on each iteration to preserve the current state
This commit is contained in:
parent
610bbe0f0b
commit
84f136f84a
@ -1499,6 +1499,14 @@
|
|||||||
<listitem>Percent of file system used space.
|
<listitem>Percent of file system used space.
|
||||||
<para /></listitem>
|
<para /></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<command>
|
||||||
|
<option>github_notifications</option>
|
||||||
|
</command>
|
||||||
|
</term>
|
||||||
|
<listitem>Number of GitHub notifications.<para /></listitem>
|
||||||
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>
|
<term>
|
||||||
<command>
|
<command>
|
||||||
@ -1507,7 +1515,6 @@
|
|||||||
<option>x</option>
|
<option>x</option>
|
||||||
</term>
|
</term>
|
||||||
<listitem>The next element will be printed at position 'x'.
|
<listitem>The next element will be printed at position 'x'.
|
||||||
|
|
||||||
<para /></listitem>
|
<para /></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
|
101
src/common.cc
101
src/common.cc
@ -275,6 +275,7 @@ void format_seconds_short(char *buf, unsigned int n, long seconds) {
|
|||||||
conky::simple_config_setting<bool> no_buffers("no_buffers", true, true);
|
conky::simple_config_setting<bool> no_buffers("no_buffers", true, true);
|
||||||
conky::simple_config_setting<std::string> bar_fill("console_bar_fill", "#", false);
|
conky::simple_config_setting<std::string> bar_fill("console_bar_fill", "#", false);
|
||||||
conky::simple_config_setting<std::string> bar_unfill("console_bar_unfill", ".", false);
|
conky::simple_config_setting<std::string> bar_unfill("console_bar_unfill", ".", false);
|
||||||
|
conky::simple_config_setting<std::string> github_token("github_token", "", false);
|
||||||
|
|
||||||
void update_stuff() {
|
void update_stuff() {
|
||||||
/* clear speeds, addresses and up status in case device was removed and
|
/* clear speeds, addresses and up status in case device was removed and
|
||||||
@ -692,6 +693,106 @@ void print_include(struct text_object *obj, char *p, unsigned int p_max_size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BUILD_CURL
|
#ifdef BUILD_CURL
|
||||||
|
#define NEW_TOKEN "https://github.com/settings/tokens/new?scopes=notifications&description=conky-query-github\n"
|
||||||
|
static size_t read_github_data_cb(char *, size_t, size_t, char *);
|
||||||
|
static size_t read_github_data_cb(char *data, size_t size, size_t nmemb, char *p) {
|
||||||
|
char *ptr = data;
|
||||||
|
size_t sz = nmemb * size;
|
||||||
|
size_t z = 0;
|
||||||
|
static size_t x = 0;
|
||||||
|
static unsigned int skip = 0U;
|
||||||
|
|
||||||
|
for (; *ptr; ptr++, z++) {
|
||||||
|
if (z+4 < sz) { /* Verifying up to *(ptr+4) */
|
||||||
|
if ('u' == *ptr && 'n' == *(ptr+1) &&
|
||||||
|
'r' == *(ptr+2) && 'e' == *(ptr+3)) { /* "unread" */
|
||||||
|
++x;
|
||||||
|
skip = 0U;
|
||||||
|
}
|
||||||
|
if ('m' == *ptr && 'e' == *(ptr+1) &&
|
||||||
|
's' == *(ptr+2) && 's' == *(ptr+3) && z+13 < sz) { /* "message": */
|
||||||
|
if ('B' == *(ptr+10) && 'a' == *(ptr+11) &&
|
||||||
|
'd' == *(ptr+12)) { /* "Bad credentials" */
|
||||||
|
NORM_ERR("Bad credentials: generate a new token:\n" NEW_TOKEN);
|
||||||
|
snprintf(p, 80, "%s", "GitHub: Bad credentials, generate a new token.");
|
||||||
|
skip = 1U;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ('M' == *(ptr+10) && 'i' == *(ptr+11) &&
|
||||||
|
's' == *(ptr+12)) { /* Missing the 'notifications' scope. */
|
||||||
|
NORM_ERR("Missing 'notifications' scope. Generate a new token\n" NEW_TOKEN);
|
||||||
|
snprintf(p, 80, "%s", "GitHub: Missing the notifications scope. Generate a new token.");
|
||||||
|
skip = 1U;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (0U == skip) {
|
||||||
|
snprintf(p, 49, "%zu", x);
|
||||||
|
}
|
||||||
|
return sz;
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_github(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||||
|
(void)obj;
|
||||||
|
char github_url[256] = {""};
|
||||||
|
char user_agent[30] = {""};
|
||||||
|
static char cached_result[256] = {""};
|
||||||
|
static unsigned int last_update = 1U;
|
||||||
|
CURL *curl = nullptr;
|
||||||
|
CURLcode res;
|
||||||
|
|
||||||
|
if (0 == strcmp(github_token.get(*state).c_str(), "")) {
|
||||||
|
NORM_ERR("${github_notifications} requires token. "
|
||||||
|
"Go ahead and generate one "
|
||||||
|
NEW_TOKEN
|
||||||
|
"Insert it in conky.config = { github_token='TOKEN_SHA' }\n");
|
||||||
|
snprintf(p, p_max_size, "%s", "GitHub notifications requires token, generate a new one.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (1U != last_update) {
|
||||||
|
--last_update;
|
||||||
|
snprintf(p, p_max_size, "%s", cached_result);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(github_url, 255, "%s%s",
|
||||||
|
"https://api.github.com/notifications?access_token=", github_token.get(*state).c_str());
|
||||||
|
/* unique string for each conky user, so we dont hit any query limits */
|
||||||
|
snprintf(user_agent, 29, "conky/%s", github_token.get(*state).c_str());
|
||||||
|
|
||||||
|
curl_global_init(CURL_GLOBAL_ALL);
|
||||||
|
if (nullptr == (curl = curl_easy_init())) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
curl_easy_setopt(curl, CURLOPT_URL, github_url);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "gzip");
|
||||||
|
curl_easy_setopt(curl, CURLOPT_USERAGENT, user_agent);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 20L);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, read_github_data_cb);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, p);
|
||||||
|
|
||||||
|
res = curl_easy_perform(curl);
|
||||||
|
if (CURLE_OK != res) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
snprintf(cached_result, 255, "%s", p);
|
||||||
|
last_update = 60U;
|
||||||
|
|
||||||
|
error:
|
||||||
|
if (nullptr != curl) {
|
||||||
|
curl_easy_cleanup(curl);
|
||||||
|
}
|
||||||
|
curl_global_cleanup();
|
||||||
|
|
||||||
|
if (!isdigit((unsigned char)*p)) {
|
||||||
|
last_update = 1U;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void print_stock(struct text_object *obj, char *p, unsigned int p_max_size) {
|
void print_stock(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||||
if (!obj->data.s) {
|
if (!obj->data.s) {
|
||||||
p[0] = 0;
|
p[0] = 0;
|
||||||
|
@ -76,6 +76,7 @@ unsigned int round_to_int(float);
|
|||||||
extern conky::simple_config_setting<bool> no_buffers;
|
extern conky::simple_config_setting<bool> no_buffers;
|
||||||
extern conky::simple_config_setting<std::string> bar_fill;
|
extern conky::simple_config_setting<std::string> bar_fill;
|
||||||
extern conky::simple_config_setting<std::string> bar_unfill;
|
extern conky::simple_config_setting<std::string> bar_unfill;
|
||||||
|
extern conky::simple_config_setting<std::string> github_token;
|
||||||
|
|
||||||
int open_acpi_temperature(const char *name);
|
int open_acpi_temperature(const char *name);
|
||||||
double get_acpi_temperature(int fd);
|
double get_acpi_temperature(int fd);
|
||||||
@ -170,6 +171,7 @@ void print_updates(struct text_object *, char *, unsigned int);
|
|||||||
int updatenr_iftest(struct text_object *);
|
int updatenr_iftest(struct text_object *);
|
||||||
|
|
||||||
#ifdef BUILD_CURL
|
#ifdef BUILD_CURL
|
||||||
|
void print_github(struct text_object *, char *, unsigned int);
|
||||||
void print_stock(struct text_object *, char *, unsigned int);
|
void print_stock(struct text_object *, char *, unsigned int);
|
||||||
void free_stock(struct text_object *);
|
void free_stock(struct text_object *);
|
||||||
#endif /* BUILD_CURL */
|
#endif /* BUILD_CURL */
|
||||||
|
@ -1697,6 +1697,7 @@ struct text_object *construct_text_object(char *s, const char *arg, long line,
|
|||||||
curl_parse_arg(obj, arg);
|
curl_parse_arg(obj, arg);
|
||||||
obj->callbacks.print = &curl_print;
|
obj->callbacks.print = &curl_print;
|
||||||
obj->callbacks.free = &curl_obj_free;
|
obj->callbacks.free = &curl_obj_free;
|
||||||
|
END OBJ(github_notifications, 0) obj->callbacks.print = &print_github;
|
||||||
#endif /* BUILD_CURL */
|
#endif /* BUILD_CURL */
|
||||||
#ifdef BUILD_RSS
|
#ifdef BUILD_RSS
|
||||||
END OBJ_ARG(rss, 0,
|
END OBJ_ARG(rss, 0,
|
||||||
|
Loading…
Reference in New Issue
Block a user