aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoraxtloss <axtlos@getcryst.al>2024-05-28 19:12:49 +0200
committeraxtloss <axtlos@getcryst.al>2024-05-28 19:12:49 +0200
commite2d8b96945423c14adbf7a54693f5064d5b157c1 (patch)
tree0052bad56749bcdf9dd99e822bd9c2ebd54999d4
parentad8ba2db29c0f3abecb292b1059dad554bf7f3b5 (diff)
downloadautodarkmode-e2d8b96945423c14adbf7a54693f5064d5b157c1.tar.gz
autodarkmode-e2d8b96945423c14adbf7a54693f5064d5b157c1.tar.bz2
add configuration system
-rw-r--r--.gitmodules3
-rw-r--r--src/configuration.c77
-rw-r--r--src/configuration.h14
-rw-r--r--src/extString.c63
-rw-r--r--src/extString.h3
m---------src/iniparser0
-rw-r--r--src/main.c192
-rw-r--r--src/meson.build6
-rw-r--r--src/sun.c65
-rw-r--r--src/sun.h7
10 files changed, 342 insertions, 88 deletions
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..d9a732d
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "src/iniparser"]
+ path = src/iniparser
+ url = https://gitlab.com/iniparser/iniparser
diff --git a/src/configuration.c b/src/configuration.c
new file mode 100644
index 0000000..81a5bbb
--- /dev/null
+++ b/src/configuration.c
@@ -0,0 +1,77 @@
+#include "configuration.h"
+
+#include "iniparser/src/iniparser.h"
+#include "iniparser/src/dictionary.h"
+#include "extString.h"
+#include <string.h>
+#include <glib.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+dictionary *
+load_config(void)
+{
+ char *xdg_config = getenv ("XDG_CONFIG_HOME");
+ char *home = getenv ("HOME");
+ if (home == NULL)
+ return NULL;
+ if (xdg_config == NULL) {
+ xdg_config = malloc (strlen(home)*sizeof(char)+strlen("/.config")*sizeof(char)+1);
+ sprintf (xdg_config, "%s/.config", home);
+ }
+ char *config_path = malloc(strlen(xdg_config)*sizeof(char)+strlen("/autodarkmode/config.ini")*sizeof(char)+1);
+ sprintf (config_path, "%s/autodarkmode/config.ini", xdg_config);
+
+ free (xdg_config);
+
+ if (access(config_path, F_OK) != 0) {
+ g_printerr ("Config file not found. Using default values.\n");
+ free (config_path);
+ return NULL;
+ }
+
+ g_print ("Loading config file %s\n", config_path);
+
+ dictionary *dict = iniparser_load (config_path);
+
+ free (config_path);
+ return dict;
+}
+
+enum LocationType
+config_get_location_type(dictionary *d)
+{
+ if (d == NULL)
+ return GCLUE;
+
+ char *loctype = iniparser_getstring (d, "main:locationtype", "gclue");
+
+ if (strcmp(strlwr(loctype), "gclue") == 0) {
+ return GCLUE;
+ } else if (strcmp(strlwr(loctype), "manual") == 0) {
+ return MANUAL;
+ } else {
+ g_printerr("Invalid Location type %s. Defaulting to GeoClue\n", loctype);
+ return GCLUE;
+ }
+ return GCLUE;
+}
+
+float
+config_get_latitude (dictionary *d)
+{
+ if (d == NULL)
+ return 0;
+
+ return iniparser_getdouble (d, "manual:latitude", 0);
+}
+
+float
+config_get_longitude (dictionary *d)
+{
+ if (d == NULL)
+ return 0;
+
+ return iniparser_getdouble (d, "manual:longitude", 0);
+}
+
diff --git a/src/configuration.h b/src/configuration.h
new file mode 100644
index 0000000..ba1f393
--- /dev/null
+++ b/src/configuration.h
@@ -0,0 +1,14 @@
+#include "iniparser/src/iniparser.h"
+#include "iniparser/src/dictionary.h"
+
+enum LocationType {
+ GCLUE,
+ MANUAL,
+};
+
+dictionary *load_config(void);
+
+enum LocationType config_get_location_type(dictionary *d);
+
+float config_get_latitude (dictionary *d);
+float config_get_longitude (dictionary *d);
diff --git a/src/extString.c b/src/extString.c
new file mode 100644
index 0000000..6538dac
--- /dev/null
+++ b/src/extString.c
@@ -0,0 +1,63 @@
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+char *strlwr(char *s)
+{
+ unsigned char *p = (unsigned char *)s;
+
+ while (*p) {
+ *p = tolower((unsigned char)*p);
+ p++;
+ }
+
+ return s;
+}
+
+char *trim(char *s)
+{
+ char *result = strdup(s);
+ char *end;
+
+ while(isspace((unsigned char)*result)) result++;
+
+ if(*result == 0)
+ return result;
+
+ end = result + strlen(result) - 1;
+ while(end > result && isspace((unsigned char)*end)) end--;
+
+ end[1] = '\0';
+
+ return result;
+}
+
+char *replaceStr(char *s, char *old, char *replace) {
+ char* result;
+ int i, cnt = 0;
+ size_t newSize = strlen(replace);
+ size_t oldSize = strlen(old);
+
+ for (i = 0; s[i] != '\0'; i++) {
+ if (strstr(&s[i], old) == &s[i]) {
+ cnt++;
+ i += oldSize - 1;
+ }
+ }
+
+ result = (char*)malloc(i + cnt * (newSize - oldSize) + 1);
+
+ i = 0;
+ while (*s) {
+ if (strstr(s, old) == s) {
+ strcpy(&result[i], replace);
+ i += newSize;
+ s += oldSize;
+ }
+ else
+ result[i++] = *s++;
+ }
+
+ result[i] = '\0';
+ return result;
+};
diff --git a/src/extString.h b/src/extString.h
new file mode 100644
index 0000000..66149f1
--- /dev/null
+++ b/src/extString.h
@@ -0,0 +1,3 @@
+char *strlwr(char *s);
+char *trim(char *s);
+char *replaceStr(char *s, char *old, char *replace);
diff --git a/src/iniparser b/src/iniparser
new file mode 160000
+Subproject 762715ca6cdba9dcf31a5af9297b444f3b5b8c0
diff --git a/src/main.c b/src/main.c
index 4e459bf..b4b5330 100644
--- a/src/main.c
+++ b/src/main.c
@@ -18,106 +18,127 @@
*/
#include "config.h"
+#include "configuration.h"
#include "sun.h"
-#include<math.h>
+#include <string.h>
+#include <unistd.h>
+#include <math.h>
+#include <signal.h>
#include <glib.h>
#include <stdlib.h>
#include <locale.h>
#include <glib/gi18n.h>
#include <geoclue.h>
-static gint timeout = 30; /* seconds */
static GClueAccuracyLevel accuracy_level = GCLUE_ACCURACY_LEVEL_EXACT;
-static gint time_threshold;
+
GClueSimple *simple = NULL;
GClueClient *client = NULL;
GMainLoop *main_loop;
-static gboolean
-on_location_timeout (gpointer user_data)
-{
- g_clear_object (&client);
- g_clear_object (&simple);
- g_main_loop_quit (main_loop);
-
- return FALSE;
-}
+enum LocationType loctype = 0;
+dictionary *dict = NULL;
+bool quit = false;
+float lat = 0;
+float lng = 0;
static void
-print_location (GClueSimple *simple)
+get_gclue_location (GClueSimple *simple)
{
GClueLocation *location;
-
- GDateTime *current_time = g_date_time_new_now_local();
-
location = gclue_simple_get_location (simple);
- g_print ("\nNew location:\n");
- g_print ("Latitude: %f°\nLongitude: %f°\nAccuracy: %f meters\n",
- gclue_location_get_latitude (location),
- gclue_location_get_longitude (location),
- gclue_location_get_accuracy (location));
-
- int year, month, day;
- g_date_time_get_ymd (current_time, &year, &month, &day);
- g_print ("%d - %d - %d\n", year, month, day);
-
- int utc_offset = g_date_time_get_utc_offset (current_time)*2.7778*pow(10.0, -10.0);
+ lat = gclue_location_get_latitude (location);
+ lng = gclue_location_get_longitude (location);
- float localT = calculateSun(year, month, day, gclue_location_get_latitude (location), gclue_location_get_longitude (location), utc_offset, 0);
- double hours;
- float minutes = modf(localT,&hours)*60;
- g_print("Sunrise: %.0f:%.0f\n",hours,minutes);
-
- float sunsetT = calculateSun(year, month, day, gclue_location_get_latitude (location), gclue_location_get_longitude (location), utc_offset, 1);
- double sunHours;
- float sunMinutes = modf(sunsetT,&sunHours)*60;
- g_print("Sunset: %.0f:%.0f\n",sunHours,sunMinutes);
-
- g_free (current_time);
+ return;
}
-static void
-on_client_active_notify (GClueClient *client,
- GParamSpec *pspec,
- gpointer user_data)
+void
+on_dark (void)
{
- if (gclue_client_get_active (client))
- return;
+ g_print ("on dark");
+ char *home = getenv ("HOME");
+ char *darklock;
+ if (home != NULL) {
+ darklock = malloc(strlen(home)*sizeof(char)+strlen("/.cache/darkmode")*sizeof(char)+1);
+ sprintf (darklock, "%s/.cache/darkmode", home);
+ if (access(darklock, F_OK) == 0) {
+ free (darklock);
+ return;
+ }
+ }
- g_print ("Geolocation disabled. Quitting..\n");
- on_location_timeout (NULL);
+ const char *dark_command = iniparser_getstring (dict, "dark:cmd", "");
+ if (sizeof (dark_command) == sizeof ("")) {
+ g_printerr ("No command for dark mode specified!");
+ return;
+ }
+ int rtrn = system (dark_command);
+ if (rtrn != 0) {
+ g_printerr("Dark command failed with non-zero exit code!");
+ free (darklock);
+ return;
+ }
+ FILE *dark = fopen (darklock, "w");
+ fclose (dark);
}
-static void
-on_simple_ready (GObject *source_object,
- GAsyncResult *res,
- gpointer user_data)
+void
+on_light (void)
{
- GError *error = NULL;
+ g_print ("on light\n");
+ char *home = getenv ("HOME");
+ char *darklock;
+ if (home != NULL) {
+ darklock = malloc(strlen(home)*sizeof(char)+strlen("/.cache/darkmode")*sizeof(char)+1);
+ sprintf (darklock, "%s/.cache/darkmode", home);
+ if (access(darklock, F_OK) != 0) {
+ free (darklock);
+ return;
+ }
- simple = gclue_simple_new_with_thresholds_finish (res, &error);
- if (error != NULL) {
- g_critical ("Failed to connect to GeoClue2 service: %s", error->message);
- exit (-1);
}
- client = gclue_simple_get_client (simple);
- if (client) {
- g_object_ref (client);
- g_print ("Client object: %s\n",
- g_dbus_proxy_get_object_path (G_DBUS_PROXY (client)));
-
- g_signal_connect (client,
- "notify::active",
- G_CALLBACK (on_client_active_notify),
- NULL);
+
+ const char *light_command = iniparser_getstring (dict, "light:cmd", "");
+ if (sizeof (light_command) == sizeof ("")) {
+ g_printerr ("No command for light mode specified!");
+ return;
+ }
+ int rtrn = system (light_command);
+ if (rtrn != 0) {
+ g_printerr("Light command failed with non-zero exit code!");
+ free (darklock);
+ return;
}
- print_location (simple);
- g_signal_connect (simple,
- "notify::location",
- G_CALLBACK (print_location),
- NULL);
+ remove (darklock);
+ free (darklock);
+}
+
+void
+loop (void)
+{
+ float sunrise = getSunrise (lat, lng);
+ double hours;
+ float minutes = modf (sunrise, &hours)*60;
+ g_print ("Sunrise: %.0f:%.0f\n", hours, minutes);
+
+ float sunset = getSunset (lat, lng);
+ minutes = modf (sunset, &hours)*60;
+ g_print ("Sunset: %.0f:%.0f\n", hours, minutes);
+
+ if (isDark (sunrise, sunset))
+ on_dark ();
+ else
+ on_light ();
+}
+
+void
+handleExit(int sig) {
+ quit = true;
+ signal(sig, SIG_IGN);
+ return;
}
gint
@@ -147,18 +168,29 @@ main (gint argc,
return EXIT_SUCCESS;
}
- g_timeout_add_seconds (timeout, on_location_timeout, NULL);
+ dict = load_config ();
+ loctype = config_get_location_type (dict);
+ g_print("%d\n", loctype);
+
+ if (loctype == MANUAL) {
+ lat = config_get_latitude (dict);
+ lng = config_get_longitude (dict);
+ } else {
+ get_gclue_location (gclue_simple_new_sync ("autodarkmode",
+ accuracy_level,
+ NULL,
+ NULL));
+ g_print ("lat: %f\n", lat);
+ g_print ("lng: %f\n", lng);
+ }
- gclue_simple_new_with_thresholds ("autodarkmode",
- accuracy_level,
- time_threshold,
- 0,
- NULL,
- on_simple_ready,
- NULL);
+ signal(SIGINT, handleExit);
+ while (!quit) {
+ loop();
+ sleep (60);
+ }
- main_loop = g_main_loop_new (NULL, FALSE);
- g_main_loop_run (main_loop);
+ iniparser_freedict (dict);
return EXIT_SUCCESS;
}
diff --git a/src/meson.build b/src/meson.build
index 7668291..6642e9d 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -1,6 +1,10 @@
autodarkmode_sources = [
'main.c',
- 'sun.c'
+ 'sun.c',
+ 'extString.c',
+ 'configuration.c',
+ 'iniparser/src/dictionary.c',
+ 'iniparser/src/iniparser.c',
]
autodarkmode_deps = [
diff --git a/src/sun.c b/src/sun.c
index 8d5a7e6..1f32be6 100644
--- a/src/sun.c
+++ b/src/sun.c
@@ -1,5 +1,6 @@
#include <math.h>
#include <glib.h>
+#include <stdbool.h>
#include "sun.h"
#define ZENITH -.83
@@ -14,10 +15,7 @@ float to_deg (float n) {
// http://edwilliams.org/sunrise_sunset_algorithm.htm
// if the sunset is desired, set sunset to >= 1
// returns -1 if the sun never rises/sets in the specified location
-float calculateSun(int year, int month, int day, float lat, float lng, int localOffset, int sunset) {
-
- if (sunset > 1)
- sunset = 1;
+float calculateSun(int year, int month, int day, float lat, float lng, int localOffset, bool sunset) {
float N1 = floor(275 * month / 9);
float N2 = floor((month + 9) / 12);
@@ -26,7 +24,7 @@ float calculateSun(int year, int month, int day, float lat, float lng, int local
float lngHour = lng / 15.0;
- float t = N + ((sunset == 0 ? 6 : 18 - lngHour) / 24);
+ float t = N + ((!sunset ? 6 : 18 - lngHour) / 24);
float M = (0.9856 * t) - 3.289;
@@ -49,7 +47,7 @@ float calculateSun(int year, int month, int day, float lat, float lng, int local
else if (cosH < -1)
return -1;
- float H = sunset == 0 ? (360 - to_deg(acos(cosH))) : to_deg(acos(cosH));
+ float H = !sunset ? (360 - to_deg(acos(cosH))) : to_deg(acos(cosH));
H = H / 15;
float T = H + RA - (0.06571 * t) - 6.622;
@@ -63,3 +61,58 @@ float calculateSun(int year, int month, int day, float lat, float lng, int local
return UT + localOffset;
}
+
+float getSunrise(float lat, float lang) {
+ int year, month, day;
+ GDateTime *current_time = g_date_time_new_now_local();
+ g_date_time_get_ymd (current_time, &year, &month, &day);
+
+ int utc_offset = g_date_time_get_utc_offset (current_time)*2.7778*pow(10.0, -10.0);
+
+ free (current_time);
+ return calculateSun (year, month, day, lat, lang, utc_offset, false);
+}
+
+float getSunset(float lat, float lang) {
+ int year, month, day;
+ GDateTime *current_time = g_date_time_new_now_local();
+ g_date_time_get_ymd (current_time, &year, &month, &day);
+
+ int utc_offset = g_date_time_get_utc_offset (current_time)*2.7778*pow(10.0, -10.0);
+
+ free (current_time);
+ return calculateSun (year, month, day, lat, lang, utc_offset, true);
+}
+
+bool isDark(float sunrise, float sunset) {
+ GDateTime *current_time = g_date_time_new_now_local();
+
+ double rise_hours;
+ float rise_minutes = modf (sunrise, &rise_hours)*60;
+ double set_hours;
+ float set_minutes = modf (sunset, &set_hours)*60;
+
+ GDateTime *rise_time = g_date_time_new_local (g_date_time_get_year (current_time),
+ g_date_time_get_month (current_time),
+ g_date_time_get_day_of_month (current_time),
+ rise_hours,
+ rise_minutes,
+ 0);
+ GDateTime *set_time = g_date_time_new_local (g_date_time_get_year (current_time),
+ g_date_time_get_month (current_time),
+ g_date_time_get_day_of_month (current_time),
+ set_hours,
+ set_minutes,
+ 0);
+
+ if (g_date_time_compare (current_time, rise_time) == 1 && g_date_time_compare (current_time, set_time) == -1) {
+ free (rise_time);
+ free (set_time);
+ free (current_time);
+ return false;
+ }
+ free (rise_time);
+ free (set_time);
+ free (current_time);
+ return true;
+}
diff --git a/src/sun.h b/src/sun.h
index 9a571e8..dc22a6c 100644
--- a/src/sun.h
+++ b/src/sun.h
@@ -1,5 +1,10 @@
+#include <stdbool.h>
float to_rad (float n);
float to_deg (float n);
-float calculateSun(int year,int month,int day,float lat, float lng,int localOffset, int sunset);
+float calculateSun(int year,int month,int day,float lat, float lng,int localOffset, bool sunset);
+float getSunrise(float lat, float lang);
+float getSunset(float lat, float lang);
+
+bool isDark (float sunrise, float sunset);