Live Stock Monitor
Friday, 27 July 2018
|
Today, a small Python script to track live stock exchanges. It fetch data from boursorama website and format it for "Generic Monitor" XFCE applet which allows to display result of a command line script. Just setup the path of this script in genmon properties and set the delay to 60s (to avoid flooding website).
#!/usr/bin/python
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
import requests
import json
params_gettickseod = {"symbol":"%s","length":"1","period":"0","guid":""}
params_updatecharts = {"symbol":"%s","period":"-1"}
base_headers = {
'Host': 'www.boursorama.com',
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'fr,en-US;q=0.7,en;q=0.3',
'DNT': '1',
'Upgrade-Insecure-Requests': '1',
'Pragma': 'no-cache',
'Cache-Control': 'no-cache',
}
base_address = 'https://www.boursorama.com/cours/'
headers = {
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0',
'Accept': 'application/json, text/javascript, */*; q=0.01',
'Accept-Language': 'fr,en-US;q=0.7,en;q=0.3',
'Accept-Encoding': 'gzip, deflate, br',
'Referer': 'https://www.boursorama.com/cours/%s/',
'Content-Type': 'application/json; charset=utf-8',
'X-Requested-With': 'XMLHttpRequest',
'DNT': '1',
'Connection': 'keep-alive',
}
xhr_address = 'https://www.boursorama.com/bourse/action/graph/ws/'
address_gettickseod = xhr_address + 'GetTicksEOD'
address_updatecharts = xhr_address + 'UpdateCharts'
cookies = None
def _do_request(address, params, headers):
if cookies is None:
req = requests.get(address, params=params, headers=headers)
else:
req = requests.get(address, params=params, headers=headers, cookies=cookies)
if req.status_code == requests.codes.ok:
j = req.json()
if len(j) == 0:
raise Exception('Not available')
return j
else:
raise Exception("Request error!")
def getStock(stock, display_name=None):
my_headers = headers.copy()
my_headers['Referer'] = headers['Referer'] % (stock)
close_value = 0
res = ''
my_params = params_updatecharts.copy()
my_params["symbol"] = stock
try:
j = _do_request(address_updatecharts, my_params, my_headers)
except:
req = requests.get(base_address + stock, headers=base_headers)
# cookies = req.cookies
j = _do_request(address_updatecharts, my_params, my_headers)
current = float(j['d'][0]['c'])
my_params = params_gettickseod.copy()
my_params["symbol"] = stock
try:
j = _do_request(address_gettickseod, my_params, my_headers)
close_value = float(j['d']['qv']['c'])
except Exception, e:
if not len(j):
raise e
close_value = float(j['d'][0]['o']) # Open value
if close_value != 0:
var = ((current/close_value) - 1)*100
else:
var = 0
if current < close_value:
color = 'red'
var = -var
else:
color = 'green'
if not display_name is None:
res += '%s ' % (display_name)
res += '%.3f <span fgcolor="%s">%.2f</span>' % (current, color, var)
return res
def getMail():
res = ''
nb_messages = ''
pipew = open("/tmp/gmail-pipe-w", "wb+")
piper = open("/tmp/gmail-pipe-r", "rb+")
pipew.write("a\n")
pipew.flush()
while not len(nb_messages):
nb_messages = piper.readline()
if len(nb_messages):
nb_messages = int(nb_messages)
if nb_messages == 1:
res = ', 1 msg'
elif nb_messages > 1:
res = ', %d msgs' % (nb_messages)
pipew.close()
piper.close()
return res
def getStocks(stocks):
res = ''
for stock in stocks:
if res != '': res += ', '
try:
res += getStock(*stock)
except Exception, e:
if len(stock) > 1:
res += "%s %s" % (stock[1], str(e))
else:
res += str(e)
res += getMail()
print('<txt>%s</txt>' % (res))
getStocks([('1rPENX', 'Euronext'), ('1rPAIR',)])
Get stock code id from website URL (last part). A file version is available here.
I added another part to get email count from gmail. It relies on a bash script that fetches RSS feeds when data is wrote in the FIFO.
Body of the script :
#!/bin/bash
USER='soutade'
while [ 1 ] ; do
echo -n "Please enter gmail account password : "
read -s password
echo ""
echo -n "Confirm password : "
read -s password2
echo ""
if [ "$password" != "$password2" ] ; then
echo -e "Passwords doesn't match !!\n"
continue
fi
break
done
pipew="/tmp/gmail-pipe-w"
piper="/tmp/gmail-pipe-r"
rm -f $pipew $piper
mkfifo $pipew $piper
while [ 1 ] ; do
read line < $pipew
feeds=`curl -u "$USER:$password" --silent "https://mail.google.com/mail/feed/atom"`
echo $feeds | sed s/.*\<fullcount\>//g | sed s/\<\\/fullcount\>.*//g > $piper
done
You can hardcode password in the script, but I don't like having my password in clear on the harddrive. A file version is available here.