Skip to content

Commit f41e29a

Browse files
authored
yfquotes@thegli: Fix cache authorization parameters (#1553)
- Fix libsoup2 support for cache authorization parameters - Enable line-wrapping in displayed error messages
1 parent 4f4564f commit f41e29a

17 files changed

Lines changed: 314 additions & 351 deletions

File tree

yfquotes@thegli/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
### 0.17.1 - August 22, 2025
2+
3+
Bugfixes:
4+
5+
- fix libsoup2 support for cache authorization parameters
6+
- enable line-wrapping in displayed error messages
7+
18
### 0.17.0 - August 21, 2025
29

310
Features:

yfquotes@thegli/README.md

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,11 @@
11
# Cinnamon Desklet for Yahoo Finance quotes
22

3-
## Description
3+
## About
44

5-
This repository contains a [desklet for the Cinnamon desktop environment](https://cinnamon-spices.linuxmint.com/desklets) that displays financial market information provided by [Yahoo Finance](https://finance.yahoo.com/).
5+
This [desklet](https://cinnamon-spices.linuxmint.com/desklets) for the Cinnamon desktop environment displays financial market information provided by [Yahoo Finance](https://finance.yahoo.com/).
66

77
![Screenshot](screenshot.png)
88

9-
This desklet is based on the [desklet from fthuin](https://github.com/fthuin/yahoofinance-cinnamon-desklet). The data retrieval part is adopted to an alternative service url, after the Yahoo Finance community table got retired in May 2017.
10-
11-
Tested with
12-
13-
- Linux Mint Cinnamon 17 up to 22
14-
- Debian 9 with Cinnamon 3.2
15-
- Manjaro with Cinnamon 3.8
16-
- Fedora 38 Cinnamon Spin with Cinnamon 5.6 and libsoup3
17-
189
## Installation
1910

2011
Either follow the installation instructions on [Cinnamon spices](https://cinnamon-spices.linuxmint.com/desklets) (recommended), or manually download the directory **yfquotes@thegli** (below "files") and copy the directory and its content to `~/.local/share/cinnamon/desklets/`
@@ -64,9 +55,10 @@ Solution:
6455
- Enable option *Send custom User-Agent header*
6556
- Enable and configure external program *curl*
6657

67-
Both options are found on the tab "Network" in the configuration settings.
58+
These options are found on the tab "Network" in the configuration settings.
59+
You need to press the button "Apply network settings" to apply any changed options.
6860

69-
### Debug Logging
61+
### Debug Log
7062

7163
**Only enable debug logging in case of problems, and when you know why you need it!**
7264

yfquotes@thegli/files/yfquotes@thegli/desklet.js

Lines changed: 33 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ const Gio = imports.gi.Gio;
1616
const GLib = imports.gi.GLib;
1717
// Gtk library (policies for scrollview)
1818
const Gtk = imports.gi.Gtk;
19+
// text layouting and rendering
20+
const Pango = imports.gi.Pango;
1921
const Soup = imports.gi.Soup;
2022
const ByteArray = imports.byteArray;
2123
// Binding desklet to mainloop function
@@ -109,23 +111,23 @@ CurlMessage.prototype = {
109111
init: function(response) {
110112
const responseParts = response.split(CURL_RESPONSE_CODE_PREFIX);
111113
this.response_body = responseParts[0];
112-
this.status_code = responseParts[1];
114+
this.status_code = Number(responseParts[1]);
113115
this.reason_phrase = this.determineReasonPhrase(this.status_code);
114116
},
115117

116118
determineReasonPhrase: function(statusCode) {
117119
switch (statusCode) {
118-
case '200': return "OK";
119-
case '400': return "Bad Request";
120-
case '401': return "Unauthorized";
121-
case '403': return "Forbidden";
122-
case '404': return "Not Found";
123-
case '422': return "Unprocessable Content";
124-
case '429': return "Too Many Requests";
125-
case '500': return "Internal Server Error";
126-
case '502': return "Bad Gateway";
127-
case '503': return "Service Unavailable";
128-
case '504': return "Gateway Timeout";
120+
case 200: return "OK";
121+
case 400: return "Bad Request";
122+
case 401: return "Unauthorized";
123+
case 403: return "Forbidden";
124+
case 404: return "Not Found";
125+
case 422: return "Unprocessable Content";
126+
case 429: return "Too Many Requests";
127+
case 500: return "Internal Server Error";
128+
case 502: return "Bad Gateway";
129+
case 503: return "Service Unavailable";
130+
case 504: return "Gateway Timeout";
129131
default: return "Unknown reason";
130132
}
131133
},
@@ -366,7 +368,7 @@ YahooFinanceQuoteReader.prototype = {
366368
value: IS_SOUP_2 ? authCookie.value : authCookie.get_value(),
367369
domain: IS_SOUP_2 ? authCookie.domain : authCookie.get_domain(),
368370
path: IS_SOUP_2 ? authCookie.path : authCookie.get_path(),
369-
expires: expiresDateTime ? expiresDateTime.to_unix() : -1
371+
expires: expiresDateTime ? (IS_SOUP_2 ? expiresDateTime.to_time_t() : expiresDateTime.to_unix()) : -1
370372
},
371373
crumb: {
372374
value: this.getCrumb()
@@ -396,10 +398,10 @@ YahooFinanceQuoteReader.prototype = {
396398
this.addCookieToJar(cachedAuthParams.cookie);
397399
this.setCrumb(cachedAuthParams.crumb.value);
398400

399-
this.quoteUtils.logDebug("Restored cached authorization parameters: " + Object.entries(cachedAuthParams));
401+
this.quoteUtils.logDebug("Restored cached authorization parameters");
400402
} else {
401403
// either no params cached, or version mismatch
402-
this.quoteUtils.logDebug("No cached authorization parameters restored: " + Object.entries(cachedAuthParams));
404+
this.quoteUtils.logDebug("No cached authorization parameters restored");
403405
}
404406
},
405407

@@ -443,7 +445,7 @@ YahooFinanceQuoteReader.prototype = {
443445
}
444446
}
445447

446-
this.quoteUtils.logDebug("No cookie found with name: " + name);
448+
this.quoteUtils.logDebug("No cookie found with name " + name);
447449
return null;
448450
},
449451

@@ -454,12 +456,7 @@ YahooFinanceQuoteReader.prototype = {
454456
addCookieToJar: function(cookieParams) {
455457
const cookie = new Soup.Cookie(cookieParams.name, cookieParams.value, cookieParams.domain, cookieParams.path, -1);
456458
if (cookieParams.expires > 0) {
457-
const expiresDateTime = GLib.DateTime.new_from_unix_utc(cookieParams.expires);
458-
if (IS_SOUP_2) {
459-
cookie.expires = expiresDateTime;
460-
} else {
461-
cookie.set_expires = expiresDateTime;
462-
}
459+
cookie.set_expires(IS_SOUP_2 ? Soup.Date.new_from_time_t(cookieParams.expires) : GLib.DateTime.new_from_unix_utc(cookieParams.expires));
463460
}
464461
this.cookieJar.add_cookie(cookie);
465462
this.quoteUtils.logDebug("Added cookie to jar: " + Object.entries(cookieParams));
@@ -724,7 +721,7 @@ YahooFinanceQuoteReader.prototype = {
724721
callback.call(_that, _that.buildErrorResponse(_("Authorization parameters have expired")), true, true);
725722
} else {
726723
_that.quoteUtils.logWarning("Curl Error retrieving url " + requestUrl + ". Status: " + _that.quoteUtils.getMessageStatusInfo(curlMessage));
727-
callback.call(_that, _that.buildErrorResponse(_("Yahoo Finance service not available!\\nStatus: ") + _that.quoteUtils.getMessageStatusInfo(curlMessage)));
724+
callback.call(_that, _that.buildErrorResponse(_("Yahoo Finance service not available! Status: ") + _that.quoteUtils.getMessageStatusInfo(curlMessage)));
728725
}
729726
});
730727
} else {
@@ -750,7 +747,7 @@ YahooFinanceQuoteReader.prototype = {
750747
callback.call(_that, _that.buildErrorResponse(_("Authorization parameters have expired")), true, true);
751748
} else {
752749
_that.quoteUtils.logWarning("Error retrieving url " + requestUrl + ". Status: " + _that.quoteUtils.getMessageStatusInfo(message));
753-
callback.call(_that, _that.buildErrorResponse(_("Yahoo Finance service not available!\\nStatus: ") + _that.quoteUtils.getMessageStatusInfo(message)));
750+
callback.call(_that, _that.buildErrorResponse(_("Yahoo Finance service not available! Status: ") + _that.quoteUtils.getMessageStatusInfo(message)));
754751
}
755752
});
756753
} else {
@@ -773,7 +770,7 @@ YahooFinanceQuoteReader.prototype = {
773770
callback.call(_that, _that.buildErrorResponse(_("Authorization parameters have expired")), true, true);
774771
} else {
775772
_that.quoteUtils.logWarning("Error retrieving url " + requestUrl + ". Status: " + _that.quoteUtils.getMessageStatusInfo(message));
776-
callback.call(_that, _that.buildErrorResponse(_("Yahoo Finance service not available!\\nStatus: ") + _that.quoteUtils.getMessageStatusInfo(message)));
773+
callback.call(_that, _that.buildErrorResponse(_("Yahoo Finance service not available! Status: ") + _that.quoteUtils.getMessageStatusInfo(message)));
777774
}
778775
});
779776
}
@@ -1229,10 +1226,16 @@ StockQuoteDesklet.prototype = {
12291226
const errorMsg = _("Error: ") + JSON.stringify(responseError);
12301227
this.quoteUtils.logWarning(errorMsg);
12311228

1232-
return new St.Label({
1229+
const errorLabel = new St.Label({
12331230
text: errorMsg,
12341231
style_class: "error-label"
12351232
});
1233+
const clutterText = errorLabel.clutter_text;
1234+
clutterText.line_wrap = true;
1235+
clutterText.set_line_wrap_mode(Pango.WrapMode.WORD_CHAR);
1236+
clutterText.ellipsize = Pango.EllipsizeMode.NONE;
1237+
1238+
return errorLabel;
12361239
},
12371240

12381241
// called on events that change the desklet window
@@ -1370,7 +1373,7 @@ StockQuoteDesklet.prototype = {
13701373
} else {
13711374
_that.quoteUtils.logWarning("Failed to retrieve auth cookie!");
13721375
_that.authAttempts++;
1373-
_that.processFailedFetch(_("Failed to retrieve authorization parameter! Unable to fetch quotes data.\\nStatus: ") + _that.quoteUtils.getMessageStatusInfo(authResponseMessage));
1376+
_that.processFailedFetch(_("Failed to retrieve authorization parameter! Unable to fetch quotes data. Status: ") + _that.quoteUtils.getMessageStatusInfo(authResponseMessage));
13741377
}
13751378
});
13761379
},
@@ -1397,13 +1400,13 @@ StockQuoteDesklet.prototype = {
13971400
} else {
13981401
_that.quoteUtils.logWarning("Failed to retrieve auth cookie from consent form");
13991402
_that.authAttempts++;
1400-
_that.processFailedFetch(_("Consent processing failed! Unable to fetch quotes data.\\nStatus: ") + _that.quoteUtils.getMessageStatusInfo(consentResponseMessage));
1403+
_that.processFailedFetch(_("Consent processing failed! Unable to fetch quotes data. Status: ") + _that.quoteUtils.getMessageStatusInfo(consentResponseMessage));
14011404
}
14021405
});
14031406
} else {
14041407
this.quoteUtils.logWarning("Consent form not detected");
14051408
this.authAttempts++;
1406-
this.processFailedFetch(_("Consent processing not completed! Unable to fetch quotes data.\\nStatus: ") + this.quoteUtils.getMessageStatusInfo(authResponseMessage));;
1409+
this.processFailedFetch(_("Consent processing not completed! Unable to fetch quotes data. Status: ") + this.quoteUtils.getMessageStatusInfo(authResponseMessage));;
14071410
}
14081411
},
14091412

@@ -1439,7 +1442,7 @@ StockQuoteDesklet.prototype = {
14391442
_that.quoteUtils.logWarning("Failed to retrieve crumb!");
14401443
_that.authAttempts++;
14411444
_that.saveAuthorizationParameters(true);
1442-
_that.processFailedFetch(_('Failed to retrieve authorization crumb! Unable to fetch quotes data.\\nStatus: ') + _that.quoteUtils.getMessageStatusInfo(crumbResponseMessage));
1445+
_that.processFailedFetch(_('Failed to retrieve authorization crumb! Unable to fetch quotes data. Status: ') + _that.quoteUtils.getMessageStatusInfo(crumbResponseMessage));
14431446
}
14441447
});
14451448
},

yfquotes@thegli/files/yfquotes@thegli/metadata.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33
"name": "Yahoo Finance Quotes",
44
"prevent-decorations": true,
55
"max-instances": "10",
6-
"version": "0.17.0",
6+
"version": "0.17.1",
77
"uuid": "yfquotes@thegli"
88
}

yfquotes@thegli/files/yfquotes@thegli/po/ca.po

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ msgstr ""
77
"Project-Id-Version: yfquotes@thegli 0.13.0\n"
88
"Report-Msgid-Bugs-To: https://github.com/linuxmint/cinnamon-spices-desklets/"
99
"issues\n"
10-
"POT-Creation-Date: 2025-08-21 21:41+0200\n"
10+
"POT-Creation-Date: 2025-08-22 22:21+0200\n"
1111
"PO-Revision-Date: 2024-12-18 21:52+0100\n"
1212
"Last-Translator: Dan <d3vf4n-linux (at) tutanota (dot) com>\n"
1313
"Language-Team: \n"
@@ -17,60 +17,58 @@ msgstr ""
1717
"Content-Transfer-Encoding: 8bit\n"
1818
"X-Generator: Poedit 3.0.1\n"
1919

20-
#. desklet.js:690
20+
#. desklet.js:687
2121
msgid "Empty quotes list. Open settings and add some symbols."
2222
msgstr ""
2323
"Llista de cotitzacions buida. Obriu la configuració i afegiu-hi alguns "
2424
"símbols."
2525

26-
#. desklet.js:724 desklet.js:750 desklet.js:773
26+
#. desklet.js:721 desklet.js:747 desklet.js:770
2727
msgid "Authorization parameters have expired"
2828
msgstr "Els paràmetres d'autorització han expirat"
2929

30-
#. desklet.js:727 desklet.js:753 desklet.js:776
31-
msgid "Yahoo Finance service not available!\\nStatus: "
32-
msgstr "El servei de Yahoo finances no està disponible!\\nEstat: "
30+
#. desklet.js:724 desklet.js:750 desklet.js:773
31+
msgid "Yahoo Finance service not available! Status: "
32+
msgstr "El servei de Yahoo finances no està disponible! Estat: "
3333

34-
#. desklet.js:1087
34+
#. desklet.js:1084
3535
msgid "No quotes data to display"
3636
msgstr "No hi ha dades de cotitzacions per mostrar"
3737

38-
#. desklet.js:1197
38+
#. desklet.js:1194
3939
msgid "Updated at "
4040
msgstr "Actualitzat a les "
4141

42-
#. desklet.js:1229
42+
#. desklet.js:1226
4343
msgid "Error: "
4444
msgstr "Error: "
4545

46-
#. desklet.js:1373
46+
#. desklet.js:1376
4747
msgid ""
48-
"Failed to retrieve authorization parameter! Unable to fetch quotes data."
49-
"\\nStatus: "
48+
"Failed to retrieve authorization parameter! Unable to fetch quotes data. "
49+
"Status: "
5050
msgstr ""
5151
"Error en recuperar el paràmetre d'autorització. No s'han pogut obtenir les "
52-
"dades de les cotitzacions.\\nEstat: "
52+
"dades de les cotitzacions. Estat: "
5353

54-
#. desklet.js:1400
55-
msgid "Consent processing failed! Unable to fetch quotes data.\\nStatus: "
54+
#. desklet.js:1403
55+
msgid "Consent processing failed! Unable to fetch quotes data. Status: "
5656
msgstr ""
5757
"No s'ha pogut processar el consentiment! No s'han pogut obtenir les dades de "
58-
"les cotitzacions.\\nEstat: "
58+
"les cotitzacions. Estat: "
5959

60-
#. desklet.js:1406
61-
msgid ""
62-
"Consent processing not completed! Unable to fetch quotes data.\\nStatus: "
60+
#. desklet.js:1409
61+
msgid "Consent processing not completed! Unable to fetch quotes data. Status: "
6362
msgstr ""
6463
"No s'ha completat el processament del consentiment. No s'han pogut obtenir "
65-
"les dades de les cotitzacions.\\nEstat: "
64+
"les dades de les cotitzacions. Estat: "
6665

67-
#. desklet.js:1442
66+
#. desklet.js:1445
6867
msgid ""
69-
"Failed to retrieve authorization crumb! Unable to fetch quotes data."
70-
"\\nStatus: "
68+
"Failed to retrieve authorization crumb! Unable to fetch quotes data. Status: "
7169
msgstr ""
7270
"No s'ha pogut recuperar la ruta d'autorització! No s'han pogut obtenir les "
73-
"dades de les cotitzacions.\\nEstat: "
71+
"dades de les cotitzacions. Estat: "
7472

7573
#. metadata.json->description
7674
msgid ""
@@ -569,7 +567,6 @@ msgid "Send custom User-Agent header"
569567
msgstr "Enviar capçalera User-Agent personalitzada"
570568

571569
#. settings-schema.json->sendCustomUserAgent->tooltip
572-
#, fuzzy
573570
msgid "Include a custom User-Agent header in Yahoo Finance Quotes API requests"
574571
msgstr ""
575572
"Inclou una capçalera User-Agent personalitzada a les sol·licituds de l'API "
@@ -607,8 +604,7 @@ msgid "Apply network settings"
607604
msgstr ""
608605

609606
#. settings-schema.json->applyNetworkSettingsButton->tooltip
610-
#, fuzzy
611607
msgid "Fetches new authorization parameters and refreshes quotes data"
612608
msgstr ""
613609
"Error en recuperar el paràmetre d'autorització. No s'han pogut obtenir les "
614-
"dades de les cotitzacions.\\nEstat: "
610+
"dades de les cotitzacions. Estat: "

0 commit comments

Comments
 (0)