online update ...

This commit is contained in:
Frederik Jaeckel 2022-11-19 00:21:52 +01:00
parent f8ba90d633
commit d54f3805ab
13 changed files with 453 additions and 4 deletions

View file

@ -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')

View file

@ -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):

View file

@ -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 #
###################

View file

@ -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"

View file

@ -17,8 +17,16 @@ full copyright notices and license terms. -->
<field name="group" ref="group_investment_admin"/>
</record>
<!-- menu: /Investment/Online Source -->
<menuitem id="menu_onlinesource" action="act_source_view" sequence="10"
icon="tryton-list" parent="menu_investment"/>
<record model="ir.ui.menu-res.group" id="menu_onlinesource-group_investment_admin">
<field name="menu" ref="menu_onlinesource"/>
<field name="group" ref="group_investment_admin"/>
</record>
<!-- menu: /Investment/Asset -->
<menuitem id="menu_asset" action="act_asset_view"
<menuitem id="menu_asset" action="act_asset_view" sequence="20"
icon="tryton-list" parent="menu_investment"/>
<record model="ir.ui.menu-res.group" id="menu_asset-group_investment">
<field name="menu" ref="menu_asset"/>

View file

@ -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

67
onlinesource.xml Normal file
View file

@ -0,0 +1,67 @@
<?xml version="1.0"?>
<!-- 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. -->
<tryton>
<data>
<!-- views -->
<record model="ir.ui.view" id="source_view_list">
<field name="model">investment.source</field>
<field name="type">tree</field>
<field name="priority" eval="20"/>
<field name="name">source_list</field>
</record>
<record model="ir.ui.view" id="source_view_form">
<field name="model">investment.source</field>
<field name="type">form</field>
<field name="priority" eval="30"/>
<field name="name">source_form</field>
</record>
<!-- action view - list -->
<record model="ir.action.act_window" id="act_source_view">
<field name="name">Online Source</field>
<field name="res_model">investment.source</field>
</record>
<record model="ir.action.act_window.view" id="act_source_view-1">
<field name="sequence" eval="10"/>
<field name="view" ref="source_view_list"/>
<field name="act_window" ref="act_source_view"/>
</record>
<record model="ir.action.act_window.view" id="act_source_view-2">
<field name="sequence" eval="20"/>
<field name="view" ref="source_view_form"/>
<field name="act_window" ref="act_source_view"/>
</record>
<!-- permission -->
<!-- anon: deny all -->
<record model="ir.model.access" id="access_source-anon">
<field name="model" search="[('model', '=', 'investment.source')]"/>
<field name="perm_read" eval="False"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<!-- group_investment: read -->
<record model="ir.model.access" id="access_source-group_investment">
<field name="model" search="[('model', '=', 'investment.source')]"/>
<field name="group" ref="group_investment"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<!-- group_investment_admin: read/write -->
<record model="ir.model.access" id="access_source-group_investment_admin">
<field name="model" search="[('model', '=', 'investment.source')]"/>
<field name="group" ref="group_investment_admin"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_delete" eval="True"/>
</record>
</data>
</tryton>

View file

@ -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():

View file

@ -11,6 +11,8 @@ xml:
message.xml
group.xml
asset.xml
onlinesource.xml
update_wiz.xml
rate.xml
menu.xml
cron.xml

31
update_wiz.py Normal file
View file

@ -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

24
update_wiz.xml Normal file
View file

@ -0,0 +1,24 @@
<?xml version="1.0"?>
<!-- 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. -->
<tryton>
<data>
<record model="ir.action.wizard" id="updt_source_wiz">
<field name="name">Update Source</field>
<field name="wiz_name">investment.source_update</field>
</record>
<record model="ir.action.keyword" id="updt_source_wiz_keyword">
<field name="keyword">form_action</field>
<field name="model">investment.asset,-1</field>
<field name="action" ref="updt_source_wiz"/>
</record>
<record model="ir.action-res.group"
id="updt_source_wiz-group_investment_admin">
<field name="action" ref="updt_source_wiz"/>
<field name="group" ref="group_investment_admin"/>
</record>
</data>
</tryton>

33
view/source_form.xml Normal file
View file

@ -0,0 +1,33 @@
<?xml version="1.0"?>
<!-- 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. -->
<form col="6">
<label name="name"/>
<field name="name"/>
<newline/>
<label name="url"/>
<field name="url" colspan="3"/>
<label name="nohtml"/>
<field name="nohtml"/>
<separator colspan="6" id="sepsymb" string="Test parameters"/>
<label colspan="6" xalign="0.0" id="lab1"
string="Configure a source for receiving course data here. The source is queried with the parameters according to schedule."/>
<label colspan="6" xalign="0.0" id="lab2"
string="Select a website where the price data, ISIN, date, etc. is contained in the loaded HTML file."/>
<label colspan="6" xalign="0.0" id="lab3"
string="Purely javascript-based websites do not work here."/>
<label name="isin"/>
<field name="isin"/>
<label name="nsin"/>
<field name="nsin"/>
<label name="symbol"/>
<field name="symbol"/>
<separator name="text" colspan="6" string="Result"/>
<field name="text" colspan="6" xexpand="1"/>
</form>

8
view/source_list.xml Normal file
View file

@ -0,0 +1,8 @@
<?xml version="1.0"?>
<!-- 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. -->
<tree>
<field name="name"/>
<field name="url"/>
</tree>