summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--setup.py2
-rwxr-xr-xwikifolio-plot-trades16
-rwxr-xr-xwikifolio-rss3
-rw-r--r--wikifolio/__init__.py48
-rw-r--r--wikifolio/model.py27
6 files changed, 83 insertions, 16 deletions
diff --git a/.gitignore b/.gitignore
index 16f7637..5ba4b60 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
/.idea
-/*.iml \ No newline at end of file
+/*.iml
+*swp \ No newline at end of file
diff --git a/setup.py b/setup.py
index ec22a2c..b2c4c61 100644
--- a/setup.py
+++ b/setup.py
@@ -8,5 +8,5 @@ setup(name='wikifolio-rss',
author_email='yvesf+wikifolio@xapek.org',
url='https://www.xapek.org/git/yvesf/wikifolio-rss',
packages=['wikifolio'],
- scripts=['wikifolio-rss'],
+ scripts=['wikifolio-rss', 'wikifolio-plot-trades'],
install_requires=['ll-xist'])
diff --git a/wikifolio-plot-trades b/wikifolio-plot-trades
new file mode 100755
index 0000000..3bd53dc
--- /dev/null
+++ b/wikifolio-plot-trades
@@ -0,0 +1,16 @@
+#!/usr/bin/python3
+import os
+import sys
+import logging
+
+import wikifolio
+
+logging.basicConfig(level=logging.INFO)
+
+if len(sys.argv) == 2 and os.path.exists(sys.argv[1]):
+ filename = sys.argv[1]
+ name, _ = os.path.splitext(filename)
+ cert = wikifolio.get_id_from_name(name)
+ trades = wikifolio.get_trades(cert)
+ for trade in trades:
+ print(repr(trade))
diff --git a/wikifolio-rss b/wikifolio-rss
index e285f06..5034dd7 100755
--- a/wikifolio-rss
+++ b/wikifolio-rss
@@ -5,13 +5,14 @@ import logging
import wikifolio
import wikifolio.rss
+import os
logging.basicConfig(level=logging.INFO)
if len(sys.argv) == 2 and os.path.exists(sys.argv[1]):
filename = sys.argv[1]
name = os.path.basename(filename)
- name = name[:name.find('.')]
+ name, _ = os.path.splitext(name)
cert = wikifolio.get_id_from_name(name)
comments = wikifolio.get_comments(cert)
with open(filename, "w") as f:
diff --git a/wikifolio/__init__.py b/wikifolio/__init__.py
index 06559e1..667ca98 100644
--- a/wikifolio/__init__.py
+++ b/wikifolio/__init__.py
@@ -1,7 +1,7 @@
import logging
import codecs
import time
-import urllib.request
+from urllib.request import urlopen, Request
from lxml.html import parse
@@ -16,12 +16,17 @@ COMMENT_URL = "https://www.wikifolio.com/dynamic/de/de/invest/" \
"&page=1" \
"&pageSize=5" \
"&_={timestamp}"
+TRADES_URL = "https://www.wikifolio.com/dynamic/de/de/invest/" \
+ "getpagedtradesforwikifolio/{name}?id={id}" \
+ "&page=1&pageSize=100"
USER_AGENT = "Mozilla/4.0 (compatible; MSIE 6.0; " \
"Windows NT 5.1; FSL 7.0.6.01001)"
def make_request(url):
- request = urllib.request.Request(url)
+ """:rtype: Request"""
+ logging.info("Make request: {}".format(url))
+ request = Request(url)
request.add_header("User-Agent", USER_AGENT)
return request
@@ -29,13 +34,14 @@ def make_request(url):
def get_id_from_name(name):
"""
:param name: sanitized name of the certificate (line in url)
- :rtype: Certificate
+ :rtype: model.Certificate
"""
request = make_request(model.BASE_URL + name)
- with urllib.request.urlopen(request) as input_raw:
+ with urlopen(request) as input_raw:
document = parse(codecs.getreader('utf-8')(input_raw))
try:
return model.Certificate(
+ name,
document.find('//input[@id="wikifolio"]').value,
document.find('//input[@id="wikifolio-shortdesc"]').value,
document.find('//input[@id="wikifolio-isin"]').value,
@@ -45,13 +51,11 @@ def get_id_from_name(name):
def get_comments(cert):
- """
- :type cert: Certificate instance
- """
+ """:type cert: model.Certificate"""
logger.info("Fetch comments of {.name}".format(cert))
request = make_request(COMMENT_URL.format(
- id=cert.id, name=cert.name, timestamp=int(time.time())))
- with urllib.request.urlopen(request) as input_raw:
+ id=cert.guid, name=cert.name, timestamp=int(time.time())))
+ with urlopen(request) as input_raw:
document = parse(codecs.getreader('utf-8')(input_raw))
comments = document.findall('//div[@class="user-comment"]')
for div_comment in comments:
@@ -62,3 +66,29 @@ def get_comments(cert):
div_comment.find('div[@class="message-item-content"]').text,
div_comment.get('id'),
cert.make_url())
+
+def get_trades(cert):
+ """:type cert: model.Certificate"""
+ request = make_request(TRADES_URL.format(name=cert.name, id=cert.guid))
+ with urlopen(request) as input_raw:
+ document = parse(codecs.getreader('utf-8')(input_raw))
+ trade_blocks = document.findall('//table/tr')
+
+ share_name = share_isin = None
+ for trade_block in trade_blocks:
+ typ = trade_block.find('td[2]').text.strip()
+ if typ != "": # not a continuation
+ share_name = trade_block.find('td[1]/div/a/span').text.strip()
+ share_isin = trade_block.find('td[1]/div/div').text.strip()
+ else: # a continuaton, read type from first column
+ typ = trade_block.find('td[1]/span').text.strip()
+ timestamp = trade_block.find('td[3]/div[2]').text.strip()
+ timestamp = timestamp.replace('\xa0', ' ')
+ timestamp = time.strptime(timestamp, "%d.%m.%Y %H:%M")
+ yield model.Trade(share_name,
+ share_isin,
+ typ,
+ trade_block.find('td[3]/div[1]').text.strip(), #status
+ timestamp,
+ trade_block.find('td[4]').text.strip(), #quote
+ trade_block.find('td[5]').text.strip()) # kurs \ No newline at end of file
diff --git a/wikifolio/model.py b/wikifolio/model.py
index 7315782..ce8feba 100644
--- a/wikifolio/model.py
+++ b/wikifolio/model.py
@@ -2,9 +2,10 @@ BASE_URL = "https://www.wikifolio.com/de/de/wikifolio/"
class Certificate:
- def __init__(self, id, shortdesc, isin, trader):
- self.id = id
- self.name = shortdesc
+ def __init__(self, name, guid, shortdesc, isin, trader):
+ self.name = name
+ self.guid = guid
+ self.shortdesc = shortdesc
self.isin = isin
self.trader = trader
@@ -13,7 +14,7 @@ class Certificate:
def __repr__(self):
return "<{} id={} shortdesc=\"{}\" isin={}>".format(
- self.__class__.__name__, self.id, self.name, self.isin)
+ self.__class__.__name__, self.guid, self.name, self.isin)
class Comment:
@@ -23,3 +24,21 @@ class Comment:
self.description = text
self.guid = guid
self.link = link
+
+
+class Trade:
+ TYPE_KAUF = 'Quote Kauf'
+ TYPE_VERKAUF = 'Quote Verkauf'
+
+ def __init__(self, share_name, share_isin, typ, status, timestamp, quote, volume):
+ self.share_name = share_name
+ self.share_isin = share_isin
+ self.typ = typ
+ self.status = status
+ self.timestamp = timestamp
+ self.quote = quote
+ self.volume = volume
+
+ def __repr__(self):
+ return "<{} {}".format(type(self).__name__,
+ " ".join(map(lambda kv: "{}={}".format(*kv), self.__dict__.items())))