[office/skrooge] /: Replace yahoo source (not working) by boursorama source

Stephane MANKOWSKI <[email protected]>
Newsgroups gmane.comp.kde.cvs,gmane.comp.kde.doc
Message-ID <[email protected]>
Git commit 5758d908b5918401a0e75b17b1d23253fb12272a by Stephane MANKOWSKI.
Committed on 25/09/2024 at 19:16.
Pushed by smankowski into branch 'master'.

Replace yahoo source (not working) by boursorama source

M  +5    -0    CHANGELOG
M  +3    -3    doc/index.docbook
M  +3    -3    skgbankmodeler/CMakeLists.txt
A  +143  -0    skgbankmodeler/skrooge-boursorama.py
D  +0    -111  skgbankmodeler/skrooge-yahoodl.py
A  +55   -0    skgbankmodeler/sources/org.kde.skrooge-source-boursorama.desktop
D  +0    -99   skgbankmodeler/sources/org.kde.skrooge-source-yahoo.desktop
M  +1    -1    tests/scripts/skgtestunit.sh
M  +4    -4    tests/skgbankmodelertest/skgtestunit.cpp

https://invent.kde.org/office/skrooge/-/commit/5758d908b5918401a0e75b17b1d23253fb12272a

diff --git a/CHANGELOG b/CHANGELOG
index 1549e9465..062662a41 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,8 @@
+skrooge (2.34.0)
+  *Correction: Replace yahoo source (not working) by boursorama source
+  
+ -- Stephane MANKOWSKI <[email protected]>  XXX
+
 skrooge (2.33.0)
   *Correction bug 485366: Differnce in different Report-Selections (2)
   *Correction bug 484156: "Monthly Report" Last month grahic failure
diff --git a/doc/index.docbook b/doc/index.docbook
index 1ac424746..9862cc665 100644
--- a/doc/index.docbook
+++ b/doc/index.docbook
@@ -1,6 +1,6 @@
 <?xml version="1.0" ?>
-<!-- SPDX-FileCopyrightText: 2022 S. MANKOWSKI [email protected] -->
-<!-- SPDX-FileCopyrightText: 2022 G. DE BURE [email protected] -->
+<!-- SPDX-FileCopyrightText: 2024 S. MANKOWSKI [email protected] -->
+<!-- SPDX-FileCopyrightText: 2024 G. DE BURE [email protected] -->
 <!-- SPDX-License-Identifier: GPL-3.0-or-later -->
 <!DOCTYPE book PUBLIC "-//KDE//DTD DocBook XML V4.5-Based Variant V1.1//EN" "dtd/kdedbx45.dtd" [
 <!ENTITY skrooge '<application>Skrooge</application>'> <!--remove when skrooge requires kdoctools 5.13-->
@@ -2011,7 +2011,7 @@ file is opened. It is also recommended to create a different account (&eg; "ETF"
 		  <listitem><para>Type: see <link linkend="unit_types">Unit Types</link>.</para></listitem>
 		  <listitem><para>Reference Unit: the (other) unit used to compute value of the (current) unit. For example, if you have EADS shares, and want to see their value in euros, you should select € as reference unit in EADS unit.</para></listitem>
 		  <listitem><para>Country</para></listitem>
-                  <listitem><para>Download source: The source to download quotes. The recommended one is "Yahoo". By clicking on the arrow on the right of the "Download" field, you can directly download new sources from <ulink url="https://store.kde.org/browse/cat/339/ord/latest/">store.kde.org</ulink></para></listitem>
+                  <listitem><para>Download source: The source to download quotes. The recommended one is "boursorama". By clicking on the arrow on the right of the "Download" field, you can directly download new sources from <ulink url="https://store.kde.org/browse/cat/339/ord/latest/">store.kde.org</ulink></para></listitem>
 		  <listitem><para>Internet Code: The Internet code for this unit. If given this code, &skrooge; is able to download the unit values from selected source.</para></listitem>
 		</itemizedlist>
 	      </listitem>
diff --git a/skgbankmodeler/CMakeLists.txt b/skgbankmodeler/CMakeLists.txt
index c21f356ec..abd21d19f 100644
--- a/skgbankmodeler/CMakeLists.txt
+++ b/skgbankmodeler/CMakeLists.txt
@@ -1,6 +1,6 @@
 #***************************************************************************
-#* SPDX-FileCopyrightText: 2022 S. MANKOWSKI [email protected]
-#* SPDX-FileCopyrightText: 2022 G. DE BURE [email protected]
+#* SPDX-FileCopyrightText: 2024 S. MANKOWSKI [email protected]
+#* SPDX-FileCopyrightText: 2024 G. DE BURE [email protected]
 #* SPDX-License-Identifier: GPL-3.0-or-later
 #***************************************************************************
 MESSAGE( STATUS "..:: CMAKE SKGBANKMODELER ::..")
@@ -51,8 +51,8 @@ ADD_SUBDIRECTORY(currency)
 INSTALL(TARGETS skgbankmodeler ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}  LIBRARY NAMELINK_SKIP)
 INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skrooge-source-plugin.desktop DESTINATION ${KDE_INSTALL_KSERVICETYPES5DIR})
 INSTALL(DIRECTORY sources DESTINATION ${KDE_INSTALL_KSERVICES5DIR} FILES_MATCHING PATTERN "*.desktop")
-INSTALL(PROGRAMS skrooge-yahoodl.py DESTINATION ${KDE_INSTALL_DATADIR}/skrooge)
 INSTALL(PROGRAMS skrooge-cryptocompare.py DESTINATION ${KDE_INSTALL_DATADIR}/skrooge)
 INSTALL(PROGRAMS skrooge-coinmarketcap.py DESTINATION ${KDE_INSTALL_DATADIR}/skrooge)
 INSTALL(PROGRAMS skrooge-exchangerates.py DESTINATION ${KDE_INSTALL_DATADIR}/skrooge)
 INSTALL(PROGRAMS skrooge-exchangerates_apilayer.py DESTINATION ${KDE_INSTALL_DATADIR}/skrooge)
+INSTALL(PROGRAMS skrooge-boursorama.py DESTINATION ${KDE_INSTALL_DATADIR}/skrooge)
diff --git a/skgbankmodeler/skrooge-boursorama.py b/skgbankmodeler/skrooge-boursorama.py
new file mode 100755
index 000000000..9598784dd
--- /dev/null
+++ b/skgbankmodeler/skrooge-boursorama.py
@@ -0,0 +1,143 @@
+#!/usr/bin/env python3
+
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#***************************************************************************
+#* SPDX-FileCopyrightText: 2024 S. MANKOWSKI [email protected]
+#* SPDX-FileCopyrightText: 2024 G. DE BURE [email protected]
+#* SPDX-License-Identifier: GPL-3.0-or-later
+#***************************************************************************
+import csv
+import enum
+import locale
+import re
+import sys
+from collections.abc import Generator, Iterable
+from contextlib import contextmanager
+from dataclasses import dataclass
+from datetime import date, datetime
+from typing import TextIO
+
+import bs4
+import requests
+from requests.models import Response
+
+BASE_URL = "https://bourse.boursobank.com/_formulaire-periode/"
+LOOKUP_URL = "https://www.boursorama.com/recherche/"
+SYMBOL_RE = re.compile(r"/cours/([a-zA-Z0-9]+)")
+NAVIGATION_RE = re.compile(r"Page \d+")
+
+
+class Interval(enum.Enum):
+    daily = "1d"
+    monthly = "1mo"
+    weekly = "1wk"
+
+
+INTERVAL_TO_PERIOD = {Interval.daily: 1, Interval.monthly: 30, Interval.weekly: 7}
+
+# Always ask for 3Y, worst case we'll have less
+DURATION = "3Y"
+EXPECTED_DATE_FORMAT = "%d/%m/%Y"
+
+
+@dataclass
+class TickerValue:
+    date: date
+    price: float
+
+
+def ticker_to_url(ticker: str) -> str:
+    response = requests.get(
+        LOOKUP_URL, params=dict(query=ticker), allow_redirects=False
+    )
+    if not (response.is_permanent_redirect or response.is_redirect):
+        raise ValueError(
+            "Ticker search did not return a valid redirect: check the symbol"
+        )
+    redirect = response.headers.get("Location") or ""
+    match = SYMBOL_RE.match(redirect)
+    if match is None:
+        raise ValueError(
+            "Ticker search did not return a valid redirect: check the symbol"
+        )
+    actual_code = match.groups()[0]
+    return actual_code
+
+
+@contextmanager
+def override_locale(category, locale_string):
+    prev_locale_string = locale.getlocale(category)
+    locale.setlocale(category, locale_string)
+    yield
+    locale.setlocale(category, prev_locale_string)
+
+
+def request_one_page(
+    interval: Interval, symbol: str, start_date: date, page: int | None = None
+) -> Response:
+    params: dict[str, str | int] = {
+        "symbol": symbol,
+        "historic_search[start_date]": start_date.strftime(EXPECTED_DATE_FORMAT),
+        "historic_search[duration]": DURATION,
+        "historic_search[period]": INTERVAL_TO_PERIOD[interval],
+    }
+    url = BASE_URL
+    if page is not None:
+        url += f"page-{page}"
+    response = requests.get(url, params=params)
+    return response
+
+
+def parse_one_page(
+    soup: bs4.BeautifulSoup, from_date: date
+) -> Generator[TickerValue, None, date | None]:
+    base_div = soup.find("div", {"data-refreshable-id": "historical-period"})
+    if base_div is None:
+        raise ValueError("Page does not have the expected format")
+    rows = base_div.findAll("tr", {"class": "c-table__row"})  # type: ignore[union-attr]
+    date = None
+    with override_locale(locale.LC_NUMERIC, "fr_FR.UTF-8"):
+        for row in rows:
+            cells = row.findAll("td")
+            date = datetime.strptime(cells[0].text.strip(), EXPECTED_DATE_FORMAT).date()
+            price = locale.atof(cells[1].text.strip().replace(' ', ''))
+            if date < from_date:
+                break
+            yield TickerValue(date, price)
+    return date
+
+
+def download_history(
+    interval: Interval, symbol: str, start_date: date
+) -> Generator[TickerValue]:
+    response = request_one_page(interval, symbol, start_date)
+    soup = bs4.BeautifulSoup(response.text, features="lxml")
+    earliest_date = yield from parse_one_page(soup, start_date)
+    # Now lookup if we have any more pages
+    for page_link in soup.find("div", {"class": "c-pagination"}).findAll("a"):  # type: ignore[union-attr]
+        if earliest_date is None or earliest_date < start_date:
+            break
+        if NAVIGATION_RE.match(page_link["aria-label"]):
+            page_num = int(page_link.text)
+            if page_num != 1:
+                response = request_one_page(interval, symbol, start_date, page=page_num)
+                soup = bs4.BeautifulSoup(response.text, features="lxml")
+                earliest_date = yield from parse_one_page(soup, start_date)
+
+
+def dump_to_csv(symbol: str, ticker_values: Iterable[TickerValue], output: TextIO):
+    writer = csv.writer(output)
+    writer.writerow(("date", "price"))
+    for value in ticker_values:
+        writer.writerow((value.date, value.price))
+
+
+if __name__ == "__main__":
+    symbol = sys.argv[1]
+    from_date = date.fromisoformat(sys.argv[2])
+    interval = Interval(sys.argv[3])
+
+    actual_symbol = ticker_to_url(symbol)
+    results = download_history(interval, actual_symbol, from_date)
+    dump_to_csv(symbol, results, sys.stdout)
diff --git a/skgbankmodeler/skrooge-yahoodl.py b/skgbankmodeler/skrooge-yahoodl.py
deleted file mode 100755
index bebad7e83..000000000
--- a/skgbankmodeler/skrooge-yahoodl.py
+++ /dev/null
@@ -1,111 +0,0 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-#***************************************************************************
-#* SPDX-FileCopyrightText: 2022 S. MANKOWSKI [email protected]
-#* SPDX-FileCopyrightText: 2022 G. DE BURE [email protected]
-#* SPDX-License-Identifier: GPL-3.0-or-later
-#***************************************************************************
-
-"""
-Created on Thu May 18 22:58:12 2017
-@author: c0redumb
-"""
-
-# To make print working for Python2/3
-from __future__ import print_function
-
-# Use six to import urllib so it is working for Python2/3
-from six.moves import urllib
-# If you don't want to use six, please comment out the line above
-# and use the line below instead (for Python3 only).
-#import urllib.request, urllib.parse, urllib.error
-
-import time
-import sys
-
-'''
-Starting on May 2017, Yahoo financial has terminated its service on
-the well used EOD data download without warning. This is confirmed
-by Yahoo employee in forum posts.
-Yahoo financial EOD data, however, still works on Yahoo financial pages.
-These download links uses a "crumb" for authentication with a cookie "B".
-This code is provided to obtain such matching cookie and crumb.
-'''
-
-# Build the cookie handler
-cookier = urllib.request.HTTPCookieProcessor()
-opener = urllib.request.build_opener(cookier)
-urllib.request.install_opener(opener)
-
-# Cookie and corresponding crumb
-_cookie = None
-_crumb = None
-
-def _get_cookie_crumb(ticker):
-	'''
-	This function perform a query and extract the matching cookie and crumb.
-	'''
-	# Perform a Yahoo financial lookup
-	url = 'https://finance.yahoo.com/quote/' + ticker
-	hdr = { 'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1; Win64; x64)',
-		'content-type': 'text/html; charset=utf-8'}
-	req = urllib.request.Request(url, headers=hdr)
-	f = urllib.request.urlopen(req)
-	alines = f.read()
-	alines = alines.decode('utf-8')
-
-	# Extract the crumb from the response
-	global _crumb
-	cs = alines.find('CrumbStore')
-	cr = alines.find('crumb', cs + 10)
-	cl = alines.find(':', cr + 5)
-	q1 = alines.find('"', cl + 1)
-	q2 = alines.find('"', q1 + 1)
-	crumb = alines[q1 + 1:q2]
-	_crumb = crumb
-
-	# Extract the cookie from cookiejar
-	global cookier, _cookie
-	for c in cookier.cookiejar:
-		if c.domain != '.yahoo.com':
-			continue
-		if c.name != 'B':
-			continue
-		_cookie = c.value
-
-def load_yahoo_quote(ticker, begindate, enddate, interval):
-	'''
-	This function load the corresponding history from Yahoo.
-	'''
-	# Check to make sure that the cookie and crumb has been loaded
-	global _cookie, _crumb
-	if _cookie == None or _crumb == None:
-		_get_cookie_crumb(ticker)
-		
-	begindate = begindate.replace('-', '')
-	enddate = enddate.replace('-', '')
-
-	# Prepare the parameters and the URL
-	tb = int(time.mktime((int(begindate[0:4]), int(begindate[4:6]), int(begindate[6:8]), 0, 0, 0, 0, 0, 0)))
-	te = int(time.mktime((int(enddate[0:4]), int(enddate[4:6]), int(enddate[6:8]), 0, 0, 0, 0, 0, 0)))
-	if te == tb:
-		tb = tb -1 
-
-	param = dict()
-	param['period1'] = tb
-	param['period2'] = te
-	param['interval'] = interval
-	param['events'] = 'history'
-	param['crumb'] = _crumb
-	params = urllib.parse.urlencode(param)
-	url = 'https://query1.finance.yahoo.com/v7/finance/download/{}?{}'.format(ticker, params)
-
-	# Perform the query
-	# There is no need to enter the cookie here, as it is automatically handled by opener
-	f = urllib.request.urlopen(url)
-	alines = f.read().decode('utf-8')
-	return sorted(alines.split('\n'), reverse=True)
-
-
-for l in load_yahoo_quote(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4]):
-	print(l)
diff --git a/skgbankmodeler/sources/org.kde.skrooge-source-boursorama.desktop b/skgbankmodeler/sources/org.kde.skrooge-source-boursorama.desktop
new file mode 100644
index 000000000..7819ffd41
--- /dev/null
+++ b/skgbankmodeler/sources/org.kde.skrooge-source-boursorama.desktop
@@ -0,0 +1,55 @@
+[Desktop Entry]
+# SPDX-FileCopyrightText: 2022 S. MANKOWSKI [email protected]
+# SPDX-FileCopyrightText: 2022 G. DE BURE [email protected]
+# SPDX-License-Identifier: GPL-3.0-or-later
+Name=Boursorama
+Name[x-test]=xxBoursoramaxx
+Name[zh_CN]=Boursorama
+Comment=You can get the list of available quotes from <a href="https://boursorama.com/bourse/">Boursorama</a>.<br/>Then, enter the symbol of the expected quotes.
+Comment[x-test]=xxYou can get the list of available quotes from <a href="https://boursorama.com/bourse/">Boursorama</a>.<br/>Then, enter the symbol of the expected quotes.xx
+Encoding=UTF-8
+Icon=skrooge
+Type=Service
+X-KDE-ServiceTypes=skrooge/source
+X-Krunner-ID=yahoo
+X-KDE-PluginInfo-Author=Ronan Dunklau
[email protected]
+X-KDE-PluginInfo-Name=Boursorama
+X-KDE-PluginInfo-Version=1.0
+X-KDE-PluginInfo-Website=https://skrooge.org/
+X-KDE-PluginInfo-Category=Plugins
+X-KDE-PluginInfo-License=GPL
+X-KDE-PluginInfo-EnabledByDefault=true
+
+#To know if this plugin needs a key API
+X-SKROOGE-keyAPI=false
+
+#The url or the command line to get the list of accounts in the standard output, something like this:
+#%1 will be replaced by the internet code of the unit
+#%2 will be replaced by the current day in format yyyy-MM-dd
+#%3 will be replaced by the previous date in format yyyy-MM-dd
+#%4 will be replaced by the interval
+#%5 will be replaced by the key API
+#Example:
+# X-SKROOGE-url=https://server/?s=%1
+# or
+# X-SKROOGE-script=mydownloadscript %1
+#This parameter is MANDATORY
+X-SKROOGE-script=skrooge-boursorama.py %1 %3 %4
+
+
+#The mode (HTML or CSV or CSVR). In HTML mode, only one value will be extracted from downloaded page. In CSV mode, a value per line will be extracted. CSVR means CSV in reverse mode
+X-SKROOGE-mode=CSV
+
+#Regular expression to capture the price of the quote
+#This parameter is not MANDATORY.
+#X-SKROOGE-price=[^,]*,[^,]*,[^,]*,[^,]*,([^,]*)
+X-SKROOGE-price=[^,]*,([^,]*)
+
+#Regular expression to capture the date of the quote
+#This parameter is not MANDATORY.
+#X-SKROOGE-date=([^,]*),.*
+X-SKROOGE-date=([^,]*),.*
+
+#The date format
+X-SKROOGE-dateformat=yyyy-MM-dd
diff --git a/skgbankmodeler/sources/org.kde.skrooge-source-yahoo.desktop b/skgbankmodeler/sources/org.kde.skrooge-source-yahoo.desktop
deleted file mode 100644
index 1d8d5d82d..000000000
--- a/skgbankmodeler/sources/org.kde.skrooge-source-yahoo.desktop
+++ /dev/null
@@ -1,99 +0,0 @@
-[Desktop Entry]
-# SPDX-FileCopyrightText: 2022 S. MANKOWSKI [email protected]
-# SPDX-FileCopyrightText: 2022 G. DE BURE [email protected]
-# SPDX-License-Identifier: GPL-3.0-or-later
-Name=Yahoo
-Name[ar]=ياهو
-Name[ca]=Yahoo
-Name[ca@valencia]=Yahoo
-Name[cs]=Yahoo
-Name[de]=Yahoo
-Name[en_GB]=Yahoo
-Name[eo]=Yahoo
-Name[es]=Yahoo
-Name[et]=Yahoo
-Name[eu]=Yahoo
-Name[fi]=Yahoo
-Name[fr]=Yahoo
-Name[gl]=Yahoo
-Name[ia]=Yahoo
-Name[it]=Yahoo
-Name[ka]=Yahoo
-Name[ko]=Yahoo
-Name[nl]=Yahoo
-Name[pl]=Yahoo
-Name[pt]=Yahoo
-Name[pt_BR]=Yahoo
-Name[ru]=Yahoo
-Name[sk]=Yahoo
-Name[sl]=Yahoo
-Name[sv]=Yahoo
-Name[tr]=Yahoo
-Name[uk]=Yahoo
-Name[x-test]=xxYahooxx
-Name[zh_CN]=Yahoo
-Comment=You can get the list of available quotes from <a href="https://finance.yahoo.com">Yahoo Finance</a>.<br/>Then, enter the symbol of the expected quotes.
-Comment[ca]=Podeu obtenir la llista de les cotitzacions disponibles a <a href="https://finance.yahoo.com">Yahoo Finance</a>.<br/>Després introduïu el símbol de les cotitzacions esperades.
-Comment[ca@valencia]=Podeu obtindre la llista de les cotitzacions disponibles a <a href="https://finance.yahoo.com">Yahoo Finance</a>.<br/>Després introduïu el símbol de les cotitzacions esperades.
-Comment[en_GB]=You can get the list of available quotes from <a href="https://finance.yahoo.com">Yahoo Finance</a>.<br/>Then, enter the symbol of the expected quotes.
-Comment[eo]=Vi povas akiri la liston de disponeblaj citaĵoj de <a href="https://finance.yahoo.com">Yahoo Finance</a>.<br/>Do, enigu la simbolon de la atendataj citaĵoj.
-Comment[es]=Puede obtener la lista de las cotizaciones disponibles de <a href="https://finance.yahoo.com">Yahoo Finance</a>.<br/>A continuación, introduzca el símbolo de las cotizaciones esperadas.
-Comment[et]=Saadaolevate kursside loendi võib hankida saidilt <a href="https://finance.yahoo.com">Yahoo Finance</a>.<br/>Seejärel sisesta oodatava kursi sümbol.
-Comment[eu]=Eskuragarri dauden kotizazioen zerrenda aurki dezakezu <a href="https://finance.yahoo.com">Yahoo Finance</a>.<br/>Ondoren, sartu aurreikusitako kotizazioaren ikurra.
-Comment[fr]=Vous pouvez accéder à la liste des cotation disponibles depuis <a href="https://finance.yahoo.com">Yahoo Finance</a>.<br/> Ensuite, saisissez le symbole de la cotation souhaitée.
-Comment[gl]=Pode obter a lista de cotizacións dispoñíbeis de <a href="https://finance.yahoo.com">Yahoo Finance</a>.A continuación escriba o símbolo das cotizacións esperadas.
-Comment[it]=Puoi scaricare l'elenco delle quotazioni disponibili da <a href="https://it.finance.yahoo.com/">Yahoo Finanza</a>.<br/>Digita, quindi, il simbolo delle quotazioni desiderate.
-Comment[ka]=ხელმისაწვდომი კურსების სია შეგიძლიათ <a href="https://finance.yahoo.com">Yahoo Finance</a>-დან მიიღოთ.<br/>შემდეგ კი სასურველი კურსის სიმბოლო შეიყვანეთ.
-Comment[nl]=U kunt de lijst met namen van beschikbare koersen ophalen uit <a href="https://finance.yahoo.com">Yahoo Finance</a>.<br/>Voer dan de naam van de gewenste koers in.
-Comment[pl]=Możesz pobrać wykaz dostępnych wycen z <a href="https://finance.yahoo.com">Yahoo Finance</a>.<br/>Następnie podaj symbol żądanej wyceny.
-Comment[pt]=Poderá obter a lista de cotações disponíveis a partir do <a href="https://finance.yahoo.com">Yahoo Finance</a>. Depois, indique o símbolo das cotações esperadas.
-Comment[ru]=Список доступных курсов возможно получить здесь: <a href="https://finance.yahoo.com">Yahoo Finance</a>.<br/>Затем следует ввести символ ожидаемого курса.
-Comment[sl]=Seznam razpoložljivih kotacij lahko pridobite na  <a href="https://finance.yahoo.com">Yahoo Finance</a>.<br/>Nato vnesite simbole pričakovanih kotacij.
-Comment[sv]=Listan över tillgängliga kursnoteringar kan hämtas från <a href="https://finance.yahoo.com">Yahoo Finance</a>.<br/>Skriv därefter in symbolen för de förväntade kurserna.
-Comment[tr]=Kullanılabilir kurların listesini <a href="https://finance.yahoo.com">Yahoo Finance</a>’den alabilirsiniz.<br/>Sonrasında istenen kurların sembollerini girin.
-Comment[uk]=Список доступних курсів можна отримати з <a href="https://finance.yahoo.com">Yahoo Finance</a>.<br/>Далі, введіть позначення потрібних курсів.
-Comment[x-test]=xxYou can get the list of available quotes from <a href="https://finance.yahoo.com">Yahoo Finance</a>.<br/>Then, enter the symbol of the expected quotes.xx
-Encoding=UTF-8
-Icon=skrooge
-Type=Service
-X-KDE-ServiceTypes=skrooge/source
-X-Krunner-ID=yahoo
-X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
[email protected]
-X-KDE-PluginInfo-Name=Yahoo
-X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=https://skrooge.org/
-X-KDE-PluginInfo-Category=Plugins
-X-KDE-PluginInfo-License=GPL
-X-KDE-PluginInfo-EnabledByDefault=true
-
-#To know if this plugin needs a key API
-X-SKROOGE-keyAPI=false
-
-#The url or the command line to get the list of accounts in the standard output, something like this:
-#%1 will be replaced by the internet code of the unit
-#%2 will be replaced by the current day in format yyyy-MM-dd
-#%3 will be replaced by the previous date in format yyyy-MM-dd
-#%4 will be replaced by the interval
-#%5 will be replaced by the key API
-#Example:
-# X-SKROOGE-url=https://server/?s=%1
-# or
-# X-SKROOGE-script=mydownloadscript %1
-#This parameter is MANDATORY
-X-SKROOGE-script=skrooge-yahoodl.py %1 %3 %2 %4
-
-
-#The mode (HTML or CSV or CSVR). In HTML mode, only one value will be extracted from downloaded page. In CSV mode, a value per line will be extracted. CSVR means CSV in reverse mode
-X-SKROOGE-mode=CSV
-
-#Regular expression to capture the price of the quote
-#This parameter is not MANDATORY.
-X-SKROOGE-price=[^,]*,[^,]*,[^,]*,[^,]*,([^,]*)
-
-#Regular expression to capture the date of the quote
-#This parameter is not MANDATORY.
-X-SKROOGE-date=([^,]*),.*
-
-#The date format
-X-SKROOGE-dateformat=yyyy-MM-dd
diff --git a/tests/scripts/skgtestunit.sh b/tests/scripts/skgtestunit.sh
index 2c481e3f9..f3482cb0e 100755
--- a/tests/scripts/skgtestunit.sh
+++ b/tests/scripts/skgtestunit.sh
@@ -6,7 +6,7 @@ EXE=skgtestunit
 
 export PATH=${IN}/../../skgbankmodeler:${PATH}
 
-skrooge-yahoodl.py AIR.PA 20170801 20170809 1d
+skrooge-boursorama.py AIRBUS 2024-09-01 1d
 rc=$?
 if [ $rc != 0 ] ; then
 	exit $rc
diff --git a/tests/skgbankmodelertest/skgtestunit.cpp b/tests/skgbankmodelertest/skgtestunit.cpp
index 91f89b4a1..a8639daac 100644
--- a/tests/skgbankmodelertest/skgtestunit.cpp
+++ b/tests/skgbankmodelertest/skgtestunit.cpp
@@ -1,6 +1,6 @@
 /***************************************************************************
- * SPDX-FileCopyrightText: 2022 S. MANKOWSKI [email protected]
- * SPDX-FileCopyrightText: 2022 G. DE BURE [email protected]
+ * SPDX-FileCopyrightText: 2024 S. MANKOWSKI [email protected]
+ * SPDX-FileCopyrightText: 2024 G. DE BURE [email protected]
  * SPDX-License-Identifier: GPL-3.0-or-later
  ***************************************************************************/
 /** @file
@@ -320,8 +320,8 @@ int main(int argc, char** argv)
             SKGBEGINTRANSACTION(document1, QStringLiteral("UNIT"), err)
             SKGTESTERROR(QStringLiteral("UNIT:setName"), unit1.setName(QStringLiteral("DS")), true)
             SKGTESTERROR(QStringLiteral("UNIT:setSymbol"), unit1.setSymbol(QStringLiteral("DS")), true)
-            SKGTESTERROR(QStringLiteral("UNIT:setDownloadSource"), unit1.setDownloadSource(QStringLiteral("Yahoo")), true)
-            SKGTESTERROR(QStringLiteral("UNIT:setInternetCode"), unit1.setInternetCode(QStringLiteral("DSY.PA")), true)
+            SKGTESTERROR(QStringLiteral("UNIT:setDownloadSource"), unit1.setDownloadSource(QStringLiteral("Boursorama")), true)
+            SKGTESTERROR(QStringLiteral("UNIT:setInternetCode"), unit1.setInternetCode(QStringLiteral("AIRBUS")), true)
             SKGTESTERROR(QStringLiteral("UNIT:save"), unit1.save(), true)
             SKGTESTERROR(QStringLiteral("UNIT:downloadUnitValue"), unit1.downloadUnitValue(SKGUnitObject::ALL_DAILY, 20), true)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.