diff --git a/__init__.py b/__init__.py index eda6b6d..161c360 100644 --- a/__init__.py +++ b/__init__.py @@ -9,6 +9,7 @@ from .rate import Rate from .identifier import Identifier from .cron import Cron from .onlinesource import OnlineSource +from .update_wiz import UpdateSoureWizard def register(): @@ -19,3 +20,7 @@ def register(): Identifier, Cron, module='investment', type_='model') + Pool.register( + UpdateSoureWizard, + module='investment', type_='wizard') + diff --git a/asset.py b/asset.py index d6f4bba..ea955b5 100644 --- a/asset.py +++ b/asset.py @@ -309,11 +309,12 @@ class Asset(ModelSQL, ModelView): """ pool = Pool() Asset2 = pool.get('investment.asset') + OnlineSource = pool.get('investment.source') for asset in Asset2.search([ ('updtneeded', '=', True), ]): - pass + OnlineSource.update_rate(asset) @classmethod def create(cls, vlist): diff --git a/locale/de.po b/locale/de.po index 0089953..c42db17 100644 --- a/locale/de.po +++ b/locale/de.po @@ -46,6 +46,10 @@ msgctxt "model:ir.ui.menu,name:menu_asset" msgid "Asset" msgstr "Vermögenswert" +msgctxt "model:ir.ui.menu,name:menu_onlinesource" +msgid "Online Source" +msgstr "Online Quelle" + ############# # ir.action # @@ -54,6 +58,22 @@ msgctxt "model:ir.action,name:act_asset_view" msgid "Asset" msgstr "Vermögenswert" +msgctxt "model:ir.action,name:act_source_view" +msgid "Online Source" +msgstr "Online Quelle" + +msgctxt "model:ir.action,name:updt_source_wiz" +msgid "Update Source" +msgstr "Quelle aktualisieren" + + +############################ +# investment.source_update # +############################ +msgctxt "model:investment.source_update,name:" +msgid "Update Source" +msgstr "Quelle aktualisieren" + #################### # investment.asset # @@ -163,6 +183,66 @@ msgid "Course update needed" msgstr "Kursaktualisierung nötig" +##################### +# investment.source # +##################### +msgctxt "model:investment.source,name:" +msgid "Online Source" +msgstr "Online Quelle" + +msgctxt "view:investment.source:" +msgid "Result" +msgstr "Ergebnis" + +msgctxt "view:investment.source:" +msgid "Test parameters" +msgstr "Testparameter" + +msgctxt "view:investment.source:" +msgid "Configure a source for receiving course data here. The source is queried with the parameters according to schedule." +msgstr "Konfigurieren Sie hier eine Quelle für den Empfang von Kursdaten. Die Quelle wird mit den Paramtern nach Zeitplan abgefragt." + +msgctxt "view:investment.source:" +msgid "Select a website where the price data, ISIN, date, etc. is contained in the loaded HTML file." +msgstr "Wählen Sie eine Webseite bei der die Kursdaten, ISIN, Datum etc. in der geladenen HTML-Datei enthalten ist." + +msgctxt "view:investment.source:" +msgid "Purely javascript-based websites do not work here." +msgstr "Rein javascriptbasierte Webseiten funktionieren hier nicht." + +msgctxt "field:investment.source,name:" +msgid "Name" +msgstr "Name" + +msgctxt "field:investment.source,url:" +msgid "URL" +msgstr "URL" + +msgctxt "field:investment.source,nsin:" +msgid "NSIN" +msgstr "WKN" + +msgctxt "field:investment.source,isin:" +msgid "ISIN" +msgstr "ISIN" + +msgctxt "field:investment.source,symbol:" +msgid "Symbol" +msgstr "Symbol" + +msgctxt "field:investment.source,text:" +msgid "Result" +msgstr "Ergebnis" + +msgctxt "field:investment.source,nohtml:" +msgid "Remove HTML" +msgstr "HTML entfernen" + +msgctxt "help:investment.source,nohtml:" +msgid "Removes HTML tags before the text is interpreted." +msgstr "Entfernt HTML-Tags bevor der Text interpretiert wird." + + ################### # investment.rate # ################### diff --git a/locale/en.po b/locale/en.po index ffe1d99..61fe75a 100644 --- a/locale/en.po +++ b/locale/en.po @@ -30,10 +30,26 @@ msgctxt "model:ir.ui.menu,name:menu_asset" msgid "Asset" msgstr "Asset" +msgctxt "model:ir.ui.menu,name:menu_onlinesource" +msgid "Online Source" +msgstr "Online Source" + msgctxt "model:ir.action,name:act_asset_view" msgid "Asset" msgstr "Asset" +msgctxt "model:ir.action,name:act_source_view" +msgid "Online Source" +msgstr "Online Source" + +msgctxt "model:ir.action,name:updt_source_wiz" +msgid "Update Source" +msgstr "Update Source" + +msgctxt "model:investment.source_update,name:" +msgid "Update Source" +msgstr "Update Source" + msgctxt "model:investment.asset,name:" msgid "Asset" msgstr "Asset" @@ -138,6 +154,62 @@ msgctxt "field:investment.asset,updtneeded:" msgid "Course update needed" msgstr "Course update needed" +msgctxt "model:investment.source,name:" +msgid "Online Source" +msgstr "Online Source" + +msgctxt "view:investment.source:" +msgid "Result" +msgstr "Result" + +msgctxt "view:investment.source:" +msgid "Test parameters" +msgstr "Test parameters" + +msgctxt "view:investment.source:" +msgid "Configure a source for receiving course data here. The source is queried with the parameters according to schedule." +msgstr "Configure a source for receiving course data here. The source is queried with the parameters according to schedule." + +msgctxt "view:investment.source:" +msgid "Select a website where the price data, ISIN, date, etc. is contained in the loaded HTML file." +msgstr "Select a website where the price data, ISIN, date, etc. is contained in the loaded HTML file." + +msgctxt "view:investment.source:" +msgid "Purely javascript-based websites do not work here." +msgstr "Purely javascript-based websites do not work here." + +msgctxt "field:investment.source,name:" +msgid "Name" +msgstr "Name" + +msgctxt "field:investment.source,url:" +msgid "URL" +msgstr "URL" + +msgctxt "field:investment.source,nsin:" +msgid "NSIN" +msgstr "NSIN" + +msgctxt "field:investment.source,isin:" +msgid "ISIN" +msgstr "ISIN" + +msgctxt "field:investment.source,symbol:" +msgid "Symbol" +msgstr "Symbol" + +msgctxt "field:investment.source,text:" +msgid "Result" +msgstr "Result" + +msgctxt "field:investment.source,nohtml:" +msgid "Remove HTML" +msgstr "Remove HTML" + +msgctxt "help:investment.source,nohtml:" +msgid "Removes HTML tags before the text is interpreted." +msgstr "Removes HTML tags before the text is interpreted." + msgctxt "model:investment.rate,name:" msgid "Rate" msgstr "Rate" diff --git a/menu.xml b/menu.xml index ad16e04..2ab5feb 100644 --- a/menu.xml +++ b/menu.xml @@ -17,8 +17,16 @@ full copyright notices and license terms. --> + + + + + + + - diff --git a/onlinesource.py b/onlinesource.py index 562ca8f..20ffb1f 100644 --- a/onlinesource.py +++ b/onlinesource.py @@ -3,15 +3,133 @@ # The COPYRIGHT file at the top level of this repository contains the # full copyright notices and license terms. +import requests, logging, html2text from trytond.model import ModelView, ModelSQL, fields, Unique, Check from trytond.transaction import Transaction from trytond.pool import Pool +logger = logging.getLogger(__name__) class OnlineSource(ModelSQL, ModelView): 'Online Source' __name__ = 'investment.source' - name = fields.Char(string='Name') + name = fields.Char(string='Name', required=True) + url = fields.Char(string='URL', required=True) + nohtml = fields.Boolean(string='Remove HTML', + help='Removes HTML tags before the text is interpreted.') + + # field to test requests + nsin = fields.Function(fields.Char(string='NSIN'), + 'on_change_with_nsin', setter='set_test_value') + isin = fields.Function(fields.Char(string='ISIN'), + 'on_change_with_isin', setter='set_test_value') + symbol = fields.Function(fields.Char(string='Symbol'), + 'on_change_with_symbol', setter='set_test_value') + text = fields.Function(fields.Text(string='Result', + readonly=True), 'on_change_with_text') + + def call_online_source(self): + """ use updated values to call online-source + """ + OSourc = Pool().get('investment.source') + + result = OSourc.read_from_website(self, debug=True) + self.text = result.get('text', None) + + @classmethod + def default_nohtml(cls): + """ default: True + """ + return True + + @fields.depends('nsin', 'isin', 'symbol', 'text') + def on_change_nsin(self): + """ run request + """ + self.call_online_source() + + @fields.depends('nsin', 'isin', 'symbol', 'text') + def on_change_isin(self): + """ run request + """ + self.call_online_source() + + @fields.depends('nsin', 'isin', 'symbol', 'text') + def on_change_symbol(self): + """ run request + """ + self.call_online_source() + + def on_change_with_text(self, name=None): + """ return existing value + """ + return '' + + def on_change_with_nsin(self, name=None): + """ return existing value + """ + return '' + + def on_change_with_isin(self, name=None): + """ return existing value + """ + return '' + + def on_change_with_symbol(self, name=None): + """ return existing value + """ + return '' + + @classmethod + def set_test_value(cls, record, name, value): + """ dont store it + """ + pass + + @classmethod + def update_rate(cls, asset): + """ read data from inet + """ + if asset.updtsource is None: + return + + rate_data = cls.read_from_website(asset.updtsource) + + @classmethod + def cleanup_spaces(cls, text): + """ remove multiple spaces + """ + len1 = -1 + while len1 != len(text): + len1 = len(text) + text = text.replace('\t', ' ').replace(' ', ' ') + text = text.replace('\n\r', '\n').replace('\n\n', '\n') + return text + + @classmethod + def read_from_website(cls, updtsource, debug=False): + """ read from url, extract values + """ + result = {} + + res1 = requests.get(updtsource.url) + if res1.reason == 'OK': + html = cls.cleanup_spaces(res1.text) + + # remove html + if updtsource.nohtml: + o1 = html2text.HTML2Text() + o1.ignore_links = True + html = o1.handle(html) + del o1 + + if debug: + result['text'] = html + else : + logger.error('read_from_website: %s' % res1.text) + if debug: + result['text'] = res1.text + return result # end OnlineSource diff --git a/onlinesource.xml b/onlinesource.xml new file mode 100644 index 0000000..21e2433 --- /dev/null +++ b/onlinesource.xml @@ -0,0 +1,67 @@ + + + + + + + + investment.source + tree + + source_list + + + investment.source + form + + source_form + + + + + Online Source + investment.source + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/setup.py b/setup.py index 8f871f7..b84eb8a 100644 --- a/setup.py +++ b/setup.py @@ -42,7 +42,7 @@ with open(path.join(here, 'versiondep.txt'), encoding='utf-8') as f: major_version = 6 minor_version = 0 -requires = [] +requires = ['requests>=2.26', 'html2text'] for dep in info.get('depends', []): if not re.match(r'(ir|res|webdav)(\W|$)', dep): if dep in modversion.keys(): diff --git a/tryton.cfg b/tryton.cfg index eec3540..905a904 100644 --- a/tryton.cfg +++ b/tryton.cfg @@ -11,6 +11,8 @@ xml: message.xml group.xml asset.xml + onlinesource.xml + update_wiz.xml rate.xml menu.xml cron.xml diff --git a/update_wiz.py b/update_wiz.py new file mode 100644 index 0000000..0c16980 --- /dev/null +++ b/update_wiz.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# This file is part of the investment-module from m-ds for Tryton. +# The COPYRIGHT file at the top level of this repository contains the +# full copyright notices and license terms. + +from trytond.wizard import Wizard, StateTransition +from trytond.pool import Pool +from trytond.transaction import Transaction + + +class UpdateSoureWizard(Wizard): + 'Update Source' + __name__ = 'investment.source_update' + + start_state = 'runupdate' + runupdate = StateTransition() + + def transition_runupdate(self): + """ update selected sources + """ + pool = Pool() + OnlineSource = pool.get('investment.source') + Asset = pool.get('investment.asset') + context = Transaction().context + + assets = Asset.browse(context.get('active_ids', [])) + for asset in assets: + OnlineSource.update_rate(asset) + return 'end' + +# UpdateSoureWizard diff --git a/update_wiz.xml b/update_wiz.xml new file mode 100644 index 0000000..b84e96b --- /dev/null +++ b/update_wiz.xml @@ -0,0 +1,24 @@ + + + + + + + Update Source + investment.source_update + + + form_action + investment.asset,-1 + + + + + + + + + diff --git a/view/source_form.xml b/view/source_form.xml new file mode 100644 index 0000000..9ab1bb4 --- /dev/null +++ b/view/source_form.xml @@ -0,0 +1,33 @@ + + +
+