weather: store api key directly in config

Also only notify once when no api key for both weather and news
This commit is contained in:
2 * r + 2 * t 2025-04-09 00:14:48 +10:00
parent 55271a93f4
commit a6f26b3d37
5 changed files with 39 additions and 42 deletions

1
.gitignore vendored
View file

@ -1,4 +1,3 @@
@girs/
node_modules/
scss/scheme/_index.scss
assets/weather-api-key.txt

View file

@ -125,7 +125,7 @@ export default {
},
weather: {
interval: 600000,
key: "assets/weather-api-key.txt", // Path to file containing api key relative to the base directory. To get a key, visit https://weatherapi.com/
apiKey: "", // An API key from https://weatherapi.com for accessing weather data
location: "", // Location as a string or empty to autodetect
imperial: false,
},

View file

@ -78,7 +78,7 @@ export default {
"math.maxHistory": NUM,
"updates.interval": NUM,
"weather.interval": NUM,
"weather.key": STR,
"weather.apiKey": STR,
"weather.location": STR,
"weather.imperial": BOOL,
"cpu.interval": NUM,

View file

@ -21,6 +21,7 @@ export default class News extends GObject.Object {
}
readonly #cachePath = `${CACHE}/news.json`;
#notified = false;
#loading: boolean = false;
#articles: Article[] = [];
@ -37,15 +38,18 @@ export default class News extends GObject.Object {
async getNews() {
if (!config.apiKey.get()) {
notify({
summary: "A newsdata.io API key is required",
body: "You can get one by creating an account at https://newsdata.io",
icon: "dialog-error-symbolic",
urgency: "critical",
actions: {
"Get API key": () => execAsync("app2unit -O -- https://newsdata.io").catch(console.error),
},
});
if (!this.#notified) {
notify({
summary: "A newsdata.io API key is required",
body: "You can get one by creating an account at https://newsdata.io",
icon: "dialog-warning-symbolic",
urgency: "critical",
actions: {
"Get API key": () => execAsync("app2unit -O -- https://newsdata.io").catch(console.error),
},
});
this.#notified = true;
}
return;
}

View file

@ -217,8 +217,8 @@ export default class Weather extends GObject.Object {
}
readonly #cache: string = `${CACHE}/weather.json`;
#notified = false;
#key: string = "";
#data: WeatherData = DEFAULT;
#interval: Time | null = null;
@ -322,15 +322,28 @@ export default class Weather extends GObject.Object {
async getWeather() {
const location = config.location || JSON.parse(await execAsync("curl ipinfo.io")).city;
return JSON.parse(
await execAsync([
"curl",
`https://api.weatherapi.com/v1/forecast.json?key=${this.#key}&q=${location}&days=1&aqi=no&alerts=no`,
])
);
const opts = `key=${config.apiKey.get()}&q=${location}&days=1&aqi=no&alerts=no`;
const url = `https://api.weatherapi.com/v1/forecast.json?${opts}`;
return JSON.parse(await execAsync(["curl", url]));
}
async updateWeather() {
if (!config.apiKey.get()) {
if (!this.#notified) {
notify({
summary: "Weather API key required",
body: `A weather API key is required to get weather data. Get one from https://www.weatherapi.com.`,
icon: "dialog-warning-symbolic",
urgency: "critical",
actions: {
"Get API key": () => execAsync(`app2unit -O 'https://www.weatherapi.com'`).catch(print),
},
});
this.#notified = true;
}
return;
}
if (GLib.file_test(this.#cache, GLib.FileTest.EXISTS)) {
const cache = await readFileAsync(this.#cache);
const cache_data: WeatherData = JSON.parse(cache);
@ -354,32 +367,13 @@ export default class Weather extends GObject.Object {
this.#notify();
}
#init(first: boolean) {
if (GLib.file_test(config.key.get(), GLib.FileTest.EXISTS))
readFileAsync(config.key.get())
.then(k => {
this.#key = k.trim();
this.updateWeather().catch(console.error);
this.#interval = interval(config.interval.get(), () => this.updateWeather().catch(console.error));
})
.catch(console.error);
else if (first)
notify({
summary: "Weather API key required",
body: `A weather API key is required to get weather data. Get one from https://www.weatherapi.com and put it in ${config.key}.`,
icon: "dialog-warning-symbolic",
urgency: "critical",
actions: {
"Get API key": () => execAsync(`app2unit -O 'https://www.weatherapi.com'`).catch(print),
},
});
}
constructor() {
super();
this.#init(true);
config.key.subscribe(() => this.#init(false));
this.updateWeather().catch(console.error);
this.#interval = interval(config.interval.get(), () => this.updateWeather().catch(console.error));
config.apiKey.subscribe(() => this.updateWeather());
config.interval.subscribe(i => {
this.#interval?.cancel();