40 Commits
Author SHA1 Message Date
golderweb 027ca4cb09 Merge branch 'release-0.2.1' back into develop 2021-03-06 17:41:42 +01:00
golderweb aee4986957 Prepare release v0.2.1 2021-03-06 17:39:14 +01:00
golderweb eed989fd2a euroexchange: Fix removed APISite.getcurrenttime()
Pywikibot removed method  APISite.getcurrenttime replaced with
APISite.server_time
2021-03-06 17:35:02 +01:00
golderweb 59aaac408d Merge branch 'release-0.2' back into develop 2018-10-21 20:06:02 +02:00
golderweb 76a174144a Prepare release v0.2 2018-10-21 20:04:51 +02:00
golderweb 3da9e2cb1d Add .gitignore file for python 2018-10-21 20:02:34 +02:00
golderweb d130761401 Merge branch 'i#1-update-gnuplot-scripts' into develop 2018-10-21 20:00:43 +02:00
golderweb 6572a89085 descpage: Implement inserting helptext in code
Add helping comments to beginning of gnuplot scripts explaining data
source

Issue #1 (#1)
2018-10-20 21:26:57 +02:00
golderweb ecb6bb8607 Call DescPageBot in EuroExchangeBot
Issue #1 (#1)
2018-10-18 16:49:00 +02:00
golderweb 11bfe90e3b descpage: Implement gnuplot script update
Replace the current wiki script with local variant

Issue #1 (#1)
2018-10-18 16:45:31 +02:00
golderweb dd76936ee0 descpage: Prepare gnuplot script for wiki
We need to replace environment variable usage to simplify script usage
and be platform independent

Issue #1 (#1)
2018-10-18 16:42:10 +02:00
golderweb af55fde4db descpage: implement loading gnuplot script
Issue #1 (#1)
2018-10-18 16:40:29 +02:00
golderweb 5b06d2229e descpage: Implement loading, parsing and updating
To be able to change file description page, we need to load current
text, do manipulations and to update with new text

Issue #1 (#1)
2018-10-18 16:39:11 +02:00
golderweb 0878d53a55 Move configration to separate class/file
To be able to include it in other files without whole EuroExchangeBot
class

Issue #1 (#1)
2018-10-18 14:46:30 +02:00
golderweb 7c15e18071 Merge branch 'release-0.1.1' back into develop 2018-10-18 14:16:28 +02:00
golderweb e49cf9aa50 Prepare bugfix release 0.1.1 2018-10-18 14:13:23 +02:00
golderweb 00d31dda47 FIX: enable update period check
For debugging purposes, this check was disabled and unintentionally not
reenabled
2018-10-18 14:09:08 +02:00
golderweb 6af5ed5d06 Merge branch 'i#2-check-gnuplot-exit' into develop 2018-10-17 14:30:06 +02:00
golderweb 3a9268086b Check returncode of gnuplot to detect errors
Do not try to upload image, if gnuplot run fails

Issue #2 (#2)
2018-10-17 14:28:52 +02:00
golderweb efe6943659 Merge branch 'release-0.1' back into develop 2018-10-09 08:43:20 +02:00
golderweb 34c0835d22 Merge branch 'release-0.1' 2018-10-09 08:42:34 +02:00
golderweb 4395cb42eb Prepare stable release v0.1 2018-10-09 08:41:14 +02:00
golderweb 3cd639eef9 Move configuration vars to jogobot config 2018-10-05 20:24:00 +02:00
golderweb c35c296e92 Do not track gnuplotscripts in this repo
Since they are more config, we will use separate repo
2018-10-05 16:14:48 +02:00
golderweb b3a0857ddd Fix typo in Euroexchange 2018-10-05 16:11:35 +02:00
golderweb 0477940fdf Define requirements
Installable via pip install -r requirements.txt
2018-10-05 14:46:50 +02:00
golderweb f9a39a6f49 Make it possible to run Bot with -always
To be able to run script unattended
2018-10-05 14:43:43 +02:00
golderweb 638d2b6a3d Do not raise Exception when image not exists
Just output a warning and go on with further jobs
2018-09-27 08:41:53 +02:00
golderweb 1d41e206c0 Fix deprecated calls to UploadRobot 2018-09-27 08:23:26 +02:00
golderweb a0377e1f80 Fix typo in upload comment 2018-09-26 16:00:03 +02:00
golderweb f4296d8410 Set upload warnings which can be ignored
We always upload existing images, so do not complain about this.
For testing purposes, also duplicates are normal
2018-09-25 16:59:50 +02:00
golderweb f28fad2edb Fix old var name 2018-09-25 16:59:19 +02:00
golderweb 5cf5c5a597 fix Pywikibot does not import specialbots by default 2018-09-25 16:32:25 +02:00
golderweb 6c5eff65fb For testing on betawiki, prepend prefix to filename
As otherwise we will overwrite original files on commons
2018-09-24 21:16:00 +02:00
golderweb 46447d6f32 Load jobs from json file 2018-09-24 21:15:38 +02:00
golderweb 6358a3db9b Check if file was changed before upload
Use sha1 hash of file, which is available via FileInfo() to check for
changes
2018-09-24 20:32:36 +02:00
golderweb 3a46ea8ddc Add update frequenzy in days to job
Check against timestamp of latest file revision
2018-09-24 20:31:07 +02:00
golderweb e874804591 Store current job in bot object
For not having to provide it for each dependend method as param
2018-09-24 20:26:50 +02:00
golderweb 776950d990 Use UploadRobot directly from pywikibot.specialbots
Remove unneccessary import roundtrip via pywikibot/scripts/upload
2018-09-24 20:24:27 +02:00
golderweb 93827e9f3b Log if new input file is downloaded 2018-09-24 20:23:36 +02:00
9 changed files with 483 additions and 151 deletions
+133
View File
@@ -0,0 +1,133 @@
# Created by https://www.gitignore.io/api/python
### Python ###
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
### Python Patch ###
.venv/
### Python.VirtualEnv Stack ###
# Virtualenv
# http://iamzed.com/2009/05/07/a-primer-on-virtualenv/
[Bb]in
[Ii]nclude
[Ll]ib
[Ll]ib64
[Ll]ocal
[Ss]cripts
pyvenv.cfg
pip-selfcheck.json
# End of https://www.gitignore.io/api/python
View File
+19 -9
View File
@@ -1,9 +1,7 @@
# wiki-jogobot-euroexange
This is a [Pywikibot](https://www.mediawiki.org/wiki/Manual:Pywikibot) based [Wikipedia Bot](https://de.wikipedia.org/wiki/Wikipedia:Bots)
of [User:JogoBot](https://de.wikipedia.org/wiki/Benutzer:JogoBot) on the
[German Wikipedia](https://de.wikipedia.org/wiki/Wikipedia:Hauptseite).
# wiki-jogobot-euroexchange
This is a [Pywikibot](https://www.mediawiki.org/wiki/Manual:Pywikibot) based [Wikipedia Bot](https://commons.wikimedia.org/wiki/Commons:Bots)
of [User:JogoBot](https://commons.wikimedia.org/wiki/User:JogoBot) on
[Wikimedia Commons](https://commons.wikimedia.org/wiki/Main_Page).
## Requirements
* Python 3.4+ (at least it is only tested with those)
@@ -12,14 +10,26 @@ of [User:JogoBot](https://de.wikipedia.org/wiki/Benutzer:JogoBot) on the
## Usage
```
python euroexange.py
python euroexchange.py
```
## Versions
*
* 0.1
- First stable release to be run on wmflabs
- Download recent sourcefile, generate images based on json job list and upload them
* 0.1.1
- Bugfix: only update image if update period is reached
* 0.2
- Checks gnuplot exitcode and only upload chart if successfull created
- Update gnuplot script on commons file description page
* 0.2.1
- Compatibility issue with recent pywikibot fixed
## Bugs
[jogobot-euroexange Issues](https://git.golderweb.de/wiki/jogobot-euroexange/issues)
[jogobot-euroexchange Issues](https://git.golderweb.de/wiki/jogobot-euroexchange/issues)
## License
GPLv3+
+47
View File
@@ -0,0 +1,47 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# config.py
#
# Copyright 2018 Jonathan Golder <jonathan@golderweb.de>
#
# 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 2 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, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
#
#
"""
Loads configuration of EuroExchangeBot
"""
import os
import jogobot
class Config():
"""
Configuration container for EuroExchangeBot
"""
base_dir = os.path.expanduser(jogobot.config["euroexchange"]["base_dir"])
working_dir = os.path.join( base_dir, "working_dir" )
gnuplot_script_dir = os.path.join(base_dir, "gnuplot_scripts")
gnuplot = jogobot.config["euroexchange"]["gnuplot_bin"]
data_source = jogobot.config["euroexchange"]["data_source"]
zip_file = jogobot.config["euroexchange"]["data_zip_filename"]
csv_file = jogobot.config["euroexchange"]["data_csv_filename"]
upload_comment = jogobot.config["euroexchange"]["upload_comment"]
gnuplot_script_comment = jogobot.config["euroexchange"]["gnuplot_script_comment"]
gnuplot_script_help = jogobot.config["euroexchange"]["gnuplot_script_help"]
+129
View File
@@ -0,0 +1,129 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# descpage.py
#
# Copyright 2018 Jonathan Golder <jonathan@golderweb.de>
#
# 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 2 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, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
#
#
import os
import re
import pywikibot
import mwparserfromhell as mwparser
from config import Config
class DescPageBot(pywikibot.bot.Bot):
"""
Updates file description page with EuroExchangeBot related content
"""
def treat_job( self, job ):
"""
Handles work on file description page for given job
@param job Job to work on
@type EuroExchangeBotJob
"""
# Store job
self.job = job
# Store file page object
self.current_page = job.filepage
# Parse filepage
self.parse_page()
# Update gnuplot script
self.update_gnuplot_script()
# Update wiki page
self.update_page()
def load_gnuplot_script(self):
"""
Load the gnuplot script for current job
@return Gnuplot script content
@rtype str
"""
with open( os.path.join(
Config.gnuplot_script_dir, self.job.script + ".plt" ), "r") as fd:
return fd.read()
def prepare_gnuplot_script(self):
"""
Prepare gnuplot script code for publishing on image description page
"""
# Load gnuplot script
gnuplot_script = self.load_gnuplot_script()
# Strip leadig and trailing whitespace
gnuplot_script = gnuplot_script.strip(" \n")
# Replace
gnuplot_script = gnuplot_script.\
replace( "system(\"echo $INFILE\")",
"'{}'".format( os.path.basename( Config.csv_file ) ) ).\
replace( "system(\"echo $OUTFILE\")",
"'{}'".format (os.path.basename( self.job.image ) ) )
# Locate first empty line
m = re.search(r"^\s*$", gnuplot_script, re.MULTILINE)
if m:
# Insert help lines
gnuplot_script = gnuplot_script[:m.end()] +\
Config.gnuplot_script_help + gnuplot_script[m.end():]
return gnuplot_script
def parse_page(self):
"""
Load current page content and parse with mwparser
"""
self.current_page.wikicode = mwparser.parse(self.current_page.text)
def update_gnuplot_script(self):
"""
Update the gnuplot script embedded in page
"""
# Get source tag with gnuplot script
gnuplot_script = next(
self.current_page.wikicode.ifilter_tags(
matches="<source lang=\"gnuplot\">" ) )
# Replace script
gnuplot_script.contents = "\n" + self.prepare_gnuplot_script() + "\n"
def update_page(self):
"""
Put updated content to wiki
"""
# Convert wikicode back to str
new_text = str(self.current_page.wikicode)
# Save new text
self.userPut( self.current_page,
self.current_page.text,
new_text,
summary=Config.gnuplot_script_comment )
@@ -25,53 +25,55 @@ import zipfile
import shlex
import subprocess
import email.utils
import hashlib
import json
import pywikibot
import upload
import pywikibot.specialbots
import jogobot
from config import Config
from descpage import DescPageBot
class EuroExangeBotJob():
class EuroExchangeBotJob():
"""
Used for EuroExangeBot job queue
Used for EuroExchangeBot job queue
"""
def __init__( self, **kwargs ):
self.image = kwargs['image']
self.script = kwargs['script']
self.freq = kwargs['freq']
# On beta prepend string TEST_ to filename to prevent overwriting of
# originial commons files
if pywikibot.Site().family.name == "wpbeta":
self.image = "TEST_{}".format(self.image)
class EuroExangeBot( pywikibot.bot.BaseBot ):
working_dir = os.path.dirname(os.path.realpath(__file__)) + "/../wdir"
gnuplot_script_dir = os.path.dirname(os.path.realpath(__file__)) + \
"/../gnuplot_scripts"
gnuplot = "/usr/bin/gnuplot"
data_source = "http://www.ecb.int/stats/eurofxref/eurofxref-hist.zip"
zip_file = "eurofxref-hist.zip"
csv_file = "eurofxref-hist.csv"
upload_comment = "Bot: ([[User:Jogobot/Euroexange|euroexange]]) update chart"
jobs = [ EuroExangeBotJob( image="TEST_Euro_exchange_rate_to_TRY_-_Turkish_Currency_and_Debt_Crisis_2018.svg", script="Euro_exchange_rate_to_TRY_-_Turkish_Currency_and_Debt_Crisis_2018" ) ]
class EuroExchangeBot( pywikibot.bot.BaseBot ):
def __init__( self, genFactory, **kwargs ):
# Init working directory
self.init_wdir()
super().__init__(*kwargs)
# Prepare DescPage editing bot
self.descpagebot = DescPageBot( **kwargs )
super().__init__(**kwargs)
def run(self):
# Make sure input data is uptodate
self.update_data()
for job in type(self).jobs:
# Load and treat jobs
for job in self.load_jobs():
self.treat_job(job)
pass
def init_wdir(self):
"""
@@ -79,7 +81,7 @@ class EuroExangeBot( pywikibot.bot.BaseBot ):
"""
#Normalize working dir
self.wdir = os.path.realpath(type(self).working_dir)
self.wdir = os.path.realpath(Config.working_dir)
if os.path.exists(self.wdir):
@@ -102,7 +104,7 @@ class EuroExangeBot( pywikibot.bot.BaseBot ):
"""
# Check if zip file exists
if os.path.exists( os.path.join(self.wdir, type(self).zip_file) ):
if os.path.exists( os.path.join(self.wdir, Config.zip_file) ):
# If file is outdated, remove data input files
if not self.is_zip_uptodate():
@@ -126,7 +128,7 @@ class EuroExangeBot( pywikibot.bot.BaseBot ):
@rtype bool
"""
# Get file stat
stat = os.stat( os.path.join(self.wdir, type(self).zip_file) )
stat = os.stat( os.path.join(self.wdir, Config.zip_file) )
# Get file modification datetime
mdt = datetime.datetime.fromtimestamp( stat.st_mtime )
@@ -152,8 +154,8 @@ class EuroExangeBot( pywikibot.bot.BaseBot ):
Deletes data input files
"""
input_files = ( os.path.join(self.wdir, type(self).zip_file),
os.path.join(self.wdir, type(self).csv_file) )
input_files = ( os.path.join(self.wdir, Config.zip_file),
os.path.join(self.wdir, Config.csv_file) )
for f in input_files:
os.remove( f )
@@ -164,9 +166,9 @@ class EuroExangeBot( pywikibot.bot.BaseBot ):
Download the zipfile from EZB
"""
# Download the file and save it locally
with urllib.request.urlopen(type(self).data_source) as response,\
with urllib.request.urlopen(Config.data_source) as response,\
open( os.path.join(self.wdir,
type(self).zip_file), 'wb') as out_file:
Config.zip_file), 'wb') as out_file:
shutil.copyfileobj(response, out_file)
@@ -176,89 +178,182 @@ class EuroExangeBot( pywikibot.bot.BaseBot ):
response.info()["Last-Modified"])
# Set ctime to value from http header
os.utime( os.path.join(self.wdir, type(self).zip_file),
os.utime( os.path.join(self.wdir, Config.zip_file),
(datetime.datetime.now().timestamp(), mdate.timestamp()) )
# Log
jogobot.output( "New input file downloaded." )
def extract_csv( self ):
"""
Extract csv file from zip archive
"""
if not os.path.exists( os.path.join(self.wdir, type(self).csv_file) ):
if not os.path.exists( os.path.join(self.wdir, Config.csv_file) ):
with zipfile.ZipFile(
os.path.join(self.wdir, type(self).zip_file)) as zipobj:
os.path.join(self.wdir, Config.zip_file)) as zipobj:
zipobj.extract(
os.path.basename(
os.path.join(self.wdir, type(self).csv_file)),
os.path.join(self.wdir, Config.csv_file)),
path=self.wdir )
def load_jobs( self ):
"""
Load jobs from json file
@returns Generator of EuroExchangeBotJob objects
@rtype generator
"""
# Load json jobs file
with open( os.path.join(Config.base_dir, "jobs.json"), "r") as fd:
jobs_js = json.load( fd )
# yield each job
for job_args in jobs_js:
yield EuroExchangeBotJob( **job_args )
def treat_job( self, job ):
"""
Handles working on specific jobs
@param job: Job to work on
@type job: EuroExangeBotJob
@type job: EuroExchangeBotJob
"""
# Store reference to current job in Bot obj
self.current_job = job
# Log job
jogobot.output( "Work on Job {}".format(job.image) )
# Get file page
filepage = pywikibot.page.FilePage(pywikibot.Site(), job.image)
self.current_job.filepage = pywikibot.page.FilePage(
pywikibot.Site(), job.image)
# Stop if file not jet exists
if not filepage.exists():
jogobot.output( "Work on Job {}".format(job.image), "ERROR" )
raise pywikibot.NoPage( filepage )
# Skip if file not yet exists
if not self.current_job.filepage.exists():
jogobot.output( "Image {} does not exists on wiki, job skipped!".
format( self.current_job.image), "WARNING" )
return
#~ raise pywikibot.NoPage( self.current_job.filepage )
# Check if update is necessary
if self.image_update_needed():
try:
self.call_gnuplot( job )
if self.file_changed():
self.upload_file( job )
else:
jogobot.output( "No upload needed for Job {}.".format(
self.current_job.image) )
except subprocess.CalledProcessError as e:
jogobot.output( "Subprocess terminated with exit code {}!".
format( e.returncode), "ERROR" )
# Nothing to do
else:
jogobot.output( "No update needed for Job {}".format(
self.current_job.image) )
# Update file description page
self.descpagebot.treat_job( self.current_job )
def image_update_needed( self ):
"""
Checks weather image update intervall is reached.
@returns True if update needed
@rtype bool
"""
# Get datetime of last update
last_update = self.current_job.filepage.latest_file_info.timestamp
# Get current time
now = pywikibot.Site().server_time()
# Calculate allowed delta (with tolerance)
delta = datetime.timedelta( days=self.current_job.freq, hours=-2 )
if now >= last_update + delta:
return True
else:
return False
def call_gnuplot( self, job ):
"""
@param job: Job to work on
@type job: EuroExangeBotJob
@type job: EuroExchangeBotJob
"""
cmd = shlex.split ( type(self).gnuplot + " " + os.path.realpath(
os.path.join( type(self).gnuplot_script_dir,
cmd = shlex.split ( Config.gnuplot + " " + os.path.realpath(
os.path.join( Config.gnuplot_script_dir,
job.script + ".plt" ) ) )
plt_env = os.environ.copy()
plt_env["INFILE"] = type(self).csv_file
plt_env["INFILE"] = Config.csv_file
plt_env["OUTFILE"] = job.image
subprocess.call( cmd, cwd=self.wdir, env=plt_env )
subprocess.check_call( cmd, cwd=self.wdir, env=plt_env )
def file_changed( self ):
"""
Checks if generated file and online file differs via sha1 hash
@returns True if file was changed
@rtype bool
"""
# Get online file sha1 hash
online_sha1 = self.current_job.filepage.latest_file_info.sha1
# Get local file sha1 hash
with open(os.path.join(self.wdir, self.current_job.image),'rb') as fd:
local_sha1 = hashlib.sha1(fd.read()).hexdigest()
if online_sha1 == local_sha1:
return False
else:
return True
def upload_file( self, job ):
"""
@param job: Job to work on
@type job: EuroExangeBotJob
@type job: EuroExchangeBotJob
"""
comment = type(self).upload_comment
comment = Config.upload_comment
filename = job.image
filepath = os.path.join(self.wdir, job.image)
filepath = [ os.path.join(self.wdir, job.image) ]
keepFilename = True #set to True to skip double-checking/editing destination filename
verifyDescription = True #set to False to skip double-checking/editing description => change to bot-mode
ignoreWarning=False #set to True to skip warnings, Upload even if another file would be overwritten or another mistake would be risked
ignoreWarning = [ "exists", "duplicate", ] #set to True to skip warnings, Upload even if another file would be overwritten or another mistake would be risked
targetSite = pywikibot.Site()
always = self.getOption("always")
aborts = True if self.getOption("always") else list()
bot = upload.UploadRobot( filepath,
bot = pywikibot.specialbots.UploadRobot(
filepath,
description=comment,
useFilename=filename,
keepFilename=keepFilename,
verifyDescription=verifyDescription,
ignoreWarning=ignoreWarning,
targetSite = targetSite
targetSite = targetSite,
always=always,
aborts=aborts,
)
bot.upload_image(debug=True)
bot.run()
def main(*args):
"""
@@ -290,7 +385,7 @@ def main(*args):
local_args, None )
# Init Bot
bot = jogobot.bot.init_bot( task_slug, None, EuroExangeBot, genFactory)
bot = jogobot.bot.init_bot( task_slug, None, EuroExchangeBot, genFactory, **subtask_args)
# Run bot
jogobot.bot.run_bot( task_slug, None, bot )
@@ -1,84 +0,0 @@
# based on code of [[User:Gorgo]]/[[:c:File:Euro exchange rate to TRY.svg]]
# gnuplot script for plotting eurofxref-hist.csv as obtained from
# http://www.ecb.int/stats/exchange/eurofxref/html/index.en.html
infile=system("echo $INFILE")
outfile=system("echo $OUTFILE")
# Start und Ende ermitteln (z.Zt. nur für Consolenausagabe)
stats infile every ::1 u (strptime("%Y-%m-%d",strcol(1))) nooutput
print ' -----Stats-(Timestamp)----'
print ' Start: ', strftime("%d. %B %Y",STATS_min)
print ' Ende: ', strftime("%d. %B %Y",STATS_max)
print ' --------------------------'
set label 'last update: ' . strftime("%Y-%m-%d",STATS_max) at graph 0.05, graph 0.9
#input
set timefmt "%Y-%m-%d"
set datafile missing 'N/A'
set datafile separator ','
#output
set key bottom right
set style data lines
set border 3 # Rahmen unten (Bit 1) und links (+ Bit 2)
unset grid # Gitterlinien verwenden
# Gitterlinienen per Hand setzen falls gewünscht
set style line 1 linetype rgb '#696969' linewidth 0.5 dashtype 0 # Def. Major-grid
set style line 2 linetype rgb '#C9C9C9' linewidth 0.5 dashtype 3 # def. Minor-grid
#set grid xtics mxtics # eventuell noxtics und nomxtics
set grid x2tics
set grid ytics mytics # eventuell noytics und nomytics
set grid back # Gitter im Hintergrund
set grid linestyle 1, linestyle 2 # Setzen des linestyle für Major u. Minor
# die Kalenderwochen-Markierung machen wir über x2 !!!
set xdata time
set x2data time
set format x '1. %b'
set xtics rotate by +15 center offset 0,-0.5
set format x2 ''
set xrange ['2018-01-01':'2019-01-01']
set x2range ['2018-01-01':'2019-01-01']
set x2tics '2018-01-01', 60 * 60 * 24 * 7
set x2tic scale 0
set xtics nomirror
unset mxtics
set xlabel '2018'
set ylabel 'TRY'
# set y2label 'TRY'
set format y '%.0f'
# set format y2 '%.0f'
set ytics 1
set mytics 5
set ytics nomirror
# Zebramuster
set style rect fillcolor lt -1 fillstyle solid 0.06 noborder
do for [i=1:12:2] {
marker_start=sprintf("2018-%1.2d-01",i)
marker_stop =sprintf("2018-%1.2d-01",i+1)
print 'setze grauen Marker: ' . marker_start . "-" . marker_stop
set object rectangle from marker_start,graph 0 to marker_stop, graph 1
}
## gnuplot for SVG - gnuplot 4.2 / Ubuntu 8.10
set term svg size 800,400 font "Arial,16"
set outp outfile
set style line 1 lt rgb 'blue' lw 1
#available currencies:
#first one is $2, second $3 and so on
#USD,JPY,BGN,CYP,CZK,DKK,EEK,GBP,HUF,LTL,LVL,MTL,PLN,ROL,RON,SEK,SIT,SKK,CHF,ISK,NOK,HRK,RUB,TRL,TRY,AUD,BRL,CAD,CNY,HKD,IDR,ILS,INR,KRW,MXN,MYR,NZD,PHP,SGD,THB,ZAR
plot \
infile \
usi 1:($26) axis x1y1 tit '1 EUR in TRY' lt rgb 'blue' lw 1,\
infile \
usi 1:($26) axis x1y1 notit w p lc rgb 'black' lt 1 lw 1.5 pt 7 ps 0.1 \
+2
View File
@@ -0,0 +1,2 @@
# jogobot
git+https://git.golderweb.de/wiki/jogobot.git#egg=jogobot