From 506400a5280b836650d18febca9286cba32a8c5a Mon Sep 17 00:00:00 2001 From: Jonathan Golder Date: Fri, 21 Sep 2018 13:16:09 +0200 Subject: [PATCH 01/29] Basic structure for jogobot bot --- euroexange/euroexange.py | 75 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 euroexange/euroexange.py diff --git a/euroexange/euroexange.py b/euroexange/euroexange.py new file mode 100644 index 0000000..722231b --- /dev/null +++ b/euroexange/euroexange.py @@ -0,0 +1,75 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# 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 locale + +import pywikibot + +import jogobot + + +class EuroExangeBot( pywikibot.bot.BaseBot ): + + def __init__( self, genFactory, **kwargs ): + + super().__init__(*kwargs) + + def run(self): + + pass + + +def main(*args): + """ + Process command line arguments and invoke bot. + + If args is an empty list, sys.argv is used. + + @param args: command line arguments + @type args: list of unicode + """ + + # Make sure locale is set to 'de_DE.UTF-8' to prevent problems + # with wrong month abreviations in strptime + locale.setlocale(locale.LC_ALL, 'de_DE.UTF-8') + + # Process global arguments to determine desired site + local_args = pywikibot.handle_args(args) + + # Get the jogobot-task_slug (basename of current file without ending) + task_slug = os.path.basename(__file__)[:-len(".py")] + + # Actually not needed since we only run semi-automaticall + # Before run, we need to check wether we are currently active or not + #~ if not jogobot.bot.active( task_slug ): + #~ return + + # Parse local Args to get information about subtask + ( subtask, genFactory, subtask_args ) = jogobot.bot.parse_local_args( + local_args, None ) + + # Init Bot + bot = jogobot.bot.init_bot( task_slug, None, EuroExangeBot, genFactory) + + # Run bot + jogobot.bot.run_bot( task_slug, None, bot ) + + +if( __name__ == "__main__" ): + main() From 29c5d725f135a0275724f9e66e8120848824ca3d Mon Sep 17 00:00:00 2001 From: Jonathan Golder Date: Fri, 21 Sep 2018 13:45:09 +0200 Subject: [PATCH 02/29] Add initialisation of working dir --- euroexange/euroexange.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/euroexange/euroexange.py b/euroexange/euroexange.py index 722231b..b4aff8e 100644 --- a/euroexange/euroexange.py +++ b/euroexange/euroexange.py @@ -26,14 +26,39 @@ import jogobot class EuroExangeBot( pywikibot.bot.BaseBot ): + working_dir = os.path.dirname(os.path.realpath(__file__)) + "/../wdir" + def __init__( self, genFactory, **kwargs ): + self.init_wdir() + super().__init__(*kwargs) def run(self): pass + def init_wdir(self): + """ + Make sure, the working directory exists + """ + + #Normalize working dir + self.wdir = os.path.realpath(type(self).working_dir) + + if os.path.exists(self.wdir): + + if os.path.isdir(self.wdir): + return + else: + raise OSError("Working directory at {} already exists, but is no directory".format( + self.wdir)) + + else: + os.makedirs( self.wdir ) + jogobot.output( "Create empty working directory at {}".format( + self.wdir)) + def main(*args): """ From 5dd52e3ac52b651e9e5c52673457016ee36c641d Mon Sep 17 00:00:00 2001 From: Jonathan Golder Date: Fri, 21 Sep 2018 15:52:21 +0200 Subject: [PATCH 03/29] Implement download, extracting and update of data Make sure we have always the most recent data version --- euroexange/euroexange.py | 103 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 102 insertions(+), 1 deletion(-) diff --git a/euroexange/euroexange.py b/euroexange/euroexange.py index b4aff8e..27ea313 100644 --- a/euroexange/euroexange.py +++ b/euroexange/euroexange.py @@ -18,6 +18,10 @@ import os import locale +import urllib.request +import shutil +import datetime +import zipfile import pywikibot @@ -27,15 +31,22 @@ import jogobot class EuroExangeBot( pywikibot.bot.BaseBot ): working_dir = os.path.dirname(os.path.realpath(__file__)) + "/../wdir" + data_source = "http://www.ecb.int/stats/eurofxref/eurofxref-hist.zip" + zip_file = "eurofxref-hist.zip" + csv_file = "eurofxref-hist.csv" def __init__( self, genFactory, **kwargs ): + # Init working directory self.init_wdir() super().__init__(*kwargs) def run(self): + # Make sure input data is uptodate + self.update_data() + pass def init_wdir(self): @@ -51,7 +62,8 @@ class EuroExangeBot( pywikibot.bot.BaseBot ): if os.path.isdir(self.wdir): return else: - raise OSError("Working directory at {} already exists, but is no directory".format( + raise OSError( ("Working directory at {} already exists," +\ + "but is no directory").format( self.wdir)) else: @@ -59,6 +71,95 @@ class EuroExangeBot( pywikibot.bot.BaseBot ): jogobot.output( "Create empty working directory at {}".format( self.wdir)) + def update_data(self): + """ + Checks if zip file exists and make sure it is uptodate, and extract + csv data if neccessary + """ + + # Check if zip file exists + if os.path.exists( os.path.join(self.wdir, type(self).zip_file) ): + + # If file is outdated, remove data input files + if not self.is_zip_uptodate(): + self.remove_input_files() + + # Recall method to get new file + self.update_data() + + # Otherwise download + else: + self.download_zip() + + # Extract csv data + self.extract_csv() + + def is_zip_uptodate(self): + """ + Timechecks weather zip file is the most recent version based on mdate + + @returns True if zip file is uptodate, otherwise false + @rtype bool + """ + # Get file stat + stat = os.stat( os.path.join(self.wdir, type(self).zip_file) ) + + # Get file modification datetime + mdt = datetime.datetime.fromtimestamp( stat.st_mtime ) + # Current datetime + cdt = datetime.datetime.now() + + # On weekends (weekday 5,6) update not sensefull + if cdt.weekday() == 5: + allowed_delta = 2 + elif cdt.weekday() == 6: + allowed_delta = 3 + else: + allowed_delta = 1 + + # If file is outdated, remove and recall method + if (cdt - mdt) >= datetime.timedelta(days=allowed_delta): + return False + + return True + + def remove_input_files(self): + """ + Deletes data input files + """ + + input_files = ( os.path.join(self.wdir, type(self).zip_file), + os.path.join(self.wdir, type(self).csv_file) ) + + for f in input_files: + os.remove( f ) + + + def download_zip( self ): + """ + Download the zipfile from EZB + """ + # Download the file and save it locally + with urllib.request.urlopen(type(self).data_source) as response,\ + open( os.path.join(self.wdir, + type(self).zip_file), 'wb') as out_file: + + shutil.copyfileobj(response, out_file) + + def extract_csv( self ): + """ + Extract csv file from zip archive + """ + if not os.path.exists( os.path.join(self.wdir, type(self).csv_file) ): + + with zipfile.ZipFile( + os.path.join(self.wdir, type(self).zip_file)) as zipobj: + + zipobj.extract( + os.path.basename( + os.path.join(self.wdir, type(self).csv_file)), + path=self.wdir ) + def main(*args): """ From d2aa47899a89fc4bf114cdcaf2d4db8fecd1fcca Mon Sep 17 00:00:00 2001 From: Jonathan Golder Date: Fri, 21 Sep 2018 17:17:38 +0200 Subject: [PATCH 04/29] First steps of job handling --- euroexange/euroexange.py | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/euroexange/euroexange.py b/euroexange/euroexange.py index 27ea313..94bd7f2 100644 --- a/euroexange/euroexange.py +++ b/euroexange/euroexange.py @@ -28,6 +28,16 @@ import pywikibot import jogobot +class EuroExangeBotJob(): + """ + Used for EuroExangeBot job queue + """ + + def __init__( self, **kwargs ): + + self.image = kwargs['image'] + + class EuroExangeBot( pywikibot.bot.BaseBot ): working_dir = os.path.dirname(os.path.realpath(__file__)) + "/../wdir" @@ -35,6 +45,8 @@ class EuroExangeBot( pywikibot.bot.BaseBot ): zip_file = "eurofxref-hist.zip" csv_file = "eurofxref-hist.csv" + jobs = [ EuroExangeBotJob( image="TEST_Euro_exchange_rate_to_TRY_-_Turkish_Currency_and_Debt_Crisis_2018.svg" ) ] + def __init__( self, genFactory, **kwargs ): # Init working directory @@ -47,6 +59,9 @@ class EuroExangeBot( pywikibot.bot.BaseBot ): # Make sure input data is uptodate self.update_data() + for job in type(self).jobs: + self.treat_job(job) + pass def init_wdir(self): @@ -160,6 +175,27 @@ class EuroExangeBot( pywikibot.bot.BaseBot ): os.path.join(self.wdir, type(self).csv_file)), path=self.wdir ) + def treat_job( self, job ): + """ + Handles working on specific jobs + + @param job: Job to work on + @type job: EuroExangeBotJob + """ + + # Log job + jogobot.output( "Work on Job {}".format(job.image) ) + + # Get file page + 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 ) + + + def main(*args): """ From ad325a0afef4f2cf6f42c0a1c0bec8669117a53e Mon Sep 17 00:00:00 2001 From: Jonathan Golder Date: Fri, 21 Sep 2018 17:57:39 +0200 Subject: [PATCH 05/29] Implement basic gnuplot call --- euroexange/euroexange.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/euroexange/euroexange.py b/euroexange/euroexange.py index 94bd7f2..e8a7bec 100644 --- a/euroexange/euroexange.py +++ b/euroexange/euroexange.py @@ -22,6 +22,8 @@ import urllib.request import shutil import datetime import zipfile +import shlex +import subprocess import pywikibot @@ -36,16 +38,20 @@ class EuroExangeBotJob(): def __init__( self, **kwargs ): self.image = kwargs['image'] + self.script = kwargs['script'] 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" - jobs = [ EuroExangeBotJob( image="TEST_Euro_exchange_rate_to_TRY_-_Turkish_Currency_and_Debt_Crisis_2018.svg" ) ] + 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" ) ] def __init__( self, genFactory, **kwargs ): @@ -194,7 +200,20 @@ class EuroExangeBot( pywikibot.bot.BaseBot ): jogobot.output( "Work on Job {}".format(job.image), "ERROR" ) raise pywikibot.NoPage( filepage ) + self.call_gnuplot( job ) + def call_gnuplot( self, job ): + """ + + @param job: Job to work on + @type job: EuroExangeBotJob + """ + + cmd = shlex.split ( type(self).gnuplot + " " + os.path.realpath( + os.path.join( type(self).gnuplot_script_dir, + job.script + ".plt" ) ) ) + + subprocess.call( cmd, cwd=self.wdir ) def main(*args): From 05b6a78bc0e2d9f09df172ce229c10af0f4ede51 Mon Sep 17 00:00:00 2001 From: Jonathan Golder Date: Fri, 21 Sep 2018 18:00:10 +0200 Subject: [PATCH 06/29] gnuplot_scripts: Basic version obtained from wiki Source https://commons.wikimedia.org/w/index.php?title=File:Euro_exchange_rate_to_TRY_-_Turkish_Currency_and_Debt_Crisis_2018.svg&oldid=320846888 --- ..._Turkish_Currency_and_Debt_Crisis_2018.plt | 98 +++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 gnuplot_scripts/Euro_exchange_rate_to_TRY_-_Turkish_Currency_and_Debt_Crisis_2018.plt diff --git a/gnuplot_scripts/Euro_exchange_rate_to_TRY_-_Turkish_Currency_and_Debt_Crisis_2018.plt b/gnuplot_scripts/Euro_exchange_rate_to_TRY_-_Turkish_Currency_and_Debt_Crisis_2018.plt new file mode 100644 index 0000000..24767c3 --- /dev/null +++ b/gnuplot_scripts/Euro_exchange_rate_to_TRY_-_Turkish_Currency_and_Debt_Crisis_2018.plt @@ -0,0 +1,98 @@ +# 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 + + +# download and unzip data if not available +# code only für Unix-Shells sh, bash, ... +# remove or comment out these lines in Windows/MacOS. an load fram source manualy +# +# sh: remove file eurofxref-hist.csv if last zip-file is not from today +! [ -f upload-from-$(date '+%Y-%m-%d').zip ] || \ + remove eurofxref-hist.csv \ + -O upload-from-$(date '+%Y-%m-%d').zip +# sh: get new zip-file from EZB if last zip-file is not from today +! [ -f upload-from-$(date '+%Y-%m-%d').zip ] || \ + wget http://www.ecb.int/stats/eurofxref/eurofxref-hist.zip \ + -O upload-from-$(date '+%Y-%m-%d').zip +# sh: extract zip-file every time +! unzip -o upload-from-$(date '+%Y-%m-%d').zip + + +# Start und Ende ermitteln (z.Zt. nur für Consolenausagabe) + stats 'eurofxref-hist.csv' 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 'Euro exchange rate to TRY - Turkish Currency and Debt Crisis 2018.svg' +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 \ + 'eurofxref-hist.csv' \ + usi 1:($26) axis x1y1 tit '1 EUR in TRY' lt rgb 'blue' lw 1,\ + 'eurofxref-hist.csv' \ + usi 1:($26) axis x1y1 notit w p lc rgb 'black' lt 1 lw 1.5 pt 7 ps 0.1 \ From 5e7f718b45a82f22d444cac470d4109db4ee04ca Mon Sep 17 00:00:00 2001 From: Jonathan Golder Date: Fri, 21 Sep 2018 18:02:22 +0200 Subject: [PATCH 07/29] gnuplot_scripts: Remove download of data We do this in python script --- ...Y_-_Turkish_Currency_and_Debt_Crisis_2018.plt | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/gnuplot_scripts/Euro_exchange_rate_to_TRY_-_Turkish_Currency_and_Debt_Crisis_2018.plt b/gnuplot_scripts/Euro_exchange_rate_to_TRY_-_Turkish_Currency_and_Debt_Crisis_2018.plt index 24767c3..4653209 100644 --- a/gnuplot_scripts/Euro_exchange_rate_to_TRY_-_Turkish_Currency_and_Debt_Crisis_2018.plt +++ b/gnuplot_scripts/Euro_exchange_rate_to_TRY_-_Turkish_Currency_and_Debt_Crisis_2018.plt @@ -4,22 +4,6 @@ # http://www.ecb.int/stats/exchange/eurofxref/html/index.en.html -# download and unzip data if not available -# code only für Unix-Shells sh, bash, ... -# remove or comment out these lines in Windows/MacOS. an load fram source manualy -# -# sh: remove file eurofxref-hist.csv if last zip-file is not from today -! [ -f upload-from-$(date '+%Y-%m-%d').zip ] || \ - remove eurofxref-hist.csv \ - -O upload-from-$(date '+%Y-%m-%d').zip -# sh: get new zip-file from EZB if last zip-file is not from today -! [ -f upload-from-$(date '+%Y-%m-%d').zip ] || \ - wget http://www.ecb.int/stats/eurofxref/eurofxref-hist.zip \ - -O upload-from-$(date '+%Y-%m-%d').zip -# sh: extract zip-file every time -! unzip -o upload-from-$(date '+%Y-%m-%d').zip - - # Start und Ende ermitteln (z.Zt. nur für Consolenausagabe) stats 'eurofxref-hist.csv' every ::1 u (strptime("%Y-%m-%d",strcol(1))) nooutput print ' -----Stats-(Timestamp)----' From 111fc388816bc9ecfaf91736a4f361103e206c32 Mon Sep 17 00:00:00 2001 From: Jonathan Golder Date: Fri, 21 Sep 2018 18:04:19 +0200 Subject: [PATCH 08/29] Filenames for gnuplot via env-vars To not have hardcoded filenames in gnuplot script https://wiki.ubuntuusers.de/Gnuplot/#Stapelverarbeitung-Zugriff-auf-Umgebungsvariablen --- euroexange/euroexange.py | 6 +++++- ..._to_TRY_-_Turkish_Currency_and_Debt_Crisis_2018.plt | 10 ++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/euroexange/euroexange.py b/euroexange/euroexange.py index e8a7bec..d40662a 100644 --- a/euroexange/euroexange.py +++ b/euroexange/euroexange.py @@ -213,7 +213,11 @@ class EuroExangeBot( pywikibot.bot.BaseBot ): os.path.join( type(self).gnuplot_script_dir, job.script + ".plt" ) ) ) - subprocess.call( cmd, cwd=self.wdir ) + plt_env = os.environ.copy() + plt_env["INFILE"] = type(self).csv_file + plt_env["OUTFILE"] = job.image + + subprocess.call( cmd, cwd=self.wdir, env=plt_env ) def main(*args): diff --git a/gnuplot_scripts/Euro_exchange_rate_to_TRY_-_Turkish_Currency_and_Debt_Crisis_2018.plt b/gnuplot_scripts/Euro_exchange_rate_to_TRY_-_Turkish_Currency_and_Debt_Crisis_2018.plt index 4653209..61b24f1 100644 --- a/gnuplot_scripts/Euro_exchange_rate_to_TRY_-_Turkish_Currency_and_Debt_Crisis_2018.plt +++ b/gnuplot_scripts/Euro_exchange_rate_to_TRY_-_Turkish_Currency_and_Debt_Crisis_2018.plt @@ -3,9 +3,11 @@ # 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 'eurofxref-hist.csv' every ::1 u (strptime("%Y-%m-%d",strcol(1))) nooutput + 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) @@ -68,7 +70,7 @@ do for [i=1:12:2] { ## gnuplot for SVG - gnuplot 4.2 / Ubuntu 8.10 set term svg size 800,400 font "Arial,16" -set outp 'Euro exchange rate to TRY - Turkish Currency and Debt Crisis 2018.svg' +set outp outfile set style line 1 lt rgb 'blue' lw 1 #available currencies: @@ -76,7 +78,7 @@ set style line 1 lt rgb 'blue' lw 1 #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 \ - 'eurofxref-hist.csv' \ + infile \ usi 1:($26) axis x1y1 tit '1 EUR in TRY' lt rgb 'blue' lw 1,\ - 'eurofxref-hist.csv' \ + infile \ usi 1:($26) axis x1y1 notit w p lc rgb 'black' lt 1 lw 1.5 pt 7 ps 0.1 \ From b14c0fa3a7f852f17623b3358648ada8f3b32e03 Mon Sep 17 00:00:00 2001 From: Jonathan Golder Date: Fri, 21 Sep 2018 20:37:42 +0200 Subject: [PATCH 09/29] Set correct mtime of zip file Since we are writing the zip file with python, the original mdate, on which is_zip_uptodate() relies gets lost. Therefore overwrite it with value of "Last-Modified" HTTP header --- euroexange/euroexange.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/euroexange/euroexange.py b/euroexange/euroexange.py index d40662a..3b83487 100644 --- a/euroexange/euroexange.py +++ b/euroexange/euroexange.py @@ -24,6 +24,7 @@ import datetime import zipfile import shlex import subprocess +import email.utils import pywikibot @@ -167,6 +168,15 @@ class EuroExangeBot( pywikibot.bot.BaseBot ): shutil.copyfileobj(response, out_file) + # Extract original change date from http header + # We need to set it later, since we write a new file + mdate = email.utils.parsedate_to_datetime( + response.info()["Last-Modified"]) + + # Set ctime to value from http header + os.utime( os.path.join(self.wdir, type(self).zip_file), + (datetime.datetime.now().timestamp(), mdate.timestamp()) ) + def extract_csv( self ): """ Extract csv file from zip archive From 206917ed6deb7ee53ccb9e429c2f1829b2b87b64 Mon Sep 17 00:00:00 2001 From: Jonathan Golder Date: Fri, 21 Sep 2018 21:02:39 +0200 Subject: [PATCH 10/29] Implement file upload --- euroexange/euroexange.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/euroexange/euroexange.py b/euroexange/euroexange.py index 3b83487..97619fe 100644 --- a/euroexange/euroexange.py +++ b/euroexange/euroexange.py @@ -27,6 +27,7 @@ import subprocess import email.utils import pywikibot +import upload import jogobot @@ -51,6 +52,7 @@ class EuroExangeBot( pywikibot.bot.BaseBot ): 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" ) ] @@ -212,6 +214,8 @@ class EuroExangeBot( pywikibot.bot.BaseBot ): self.call_gnuplot( job ) + self.upload_file( job ) + def call_gnuplot( self, job ): """ @@ -229,6 +233,32 @@ class EuroExangeBot( pywikibot.bot.BaseBot ): subprocess.call( cmd, cwd=self.wdir, env=plt_env ) + def upload_file( self, job ): + """ + + @param job: Job to work on + @type job: EuroExangeBotJob + """ + + comment = type(self).upload_comment + + filename = 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 + targetSite = pywikibot.Site() + + bot = upload.UploadRobot( filepath, + description=comment, + useFilename=filename, + keepFilename=keepFilename, + verifyDescription=verifyDescription, + ignoreWarning=ignoreWarning, + targetSite = targetSite + ) + + bot.upload_image(debug=True) def main(*args): """ From 93827e9f3b625b62b34979e6e1757bc2de403981 Mon Sep 17 00:00:00 2001 From: Jonathan Golder Date: Mon, 24 Sep 2018 20:23:36 +0200 Subject: [PATCH 11/29] Log if new input file is downloaded --- euroexange/euroexange.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/euroexange/euroexange.py b/euroexange/euroexange.py index 97619fe..3864e44 100644 --- a/euroexange/euroexange.py +++ b/euroexange/euroexange.py @@ -179,6 +179,9 @@ class EuroExangeBot( pywikibot.bot.BaseBot ): os.utime( os.path.join(self.wdir, type(self).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 From 776950d99020e79c727186be054a39a0de2f5cd3 Mon Sep 17 00:00:00 2001 From: Jonathan Golder Date: Mon, 24 Sep 2018 20:24:27 +0200 Subject: [PATCH 12/29] Use UploadRobot directly from pywikibot.specialbots Remove unneccessary import roundtrip via pywikibot/scripts/upload --- euroexange/euroexange.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/euroexange/euroexange.py b/euroexange/euroexange.py index 3864e44..347b764 100644 --- a/euroexange/euroexange.py +++ b/euroexange/euroexange.py @@ -27,7 +27,6 @@ import subprocess import email.utils import pywikibot -import upload import jogobot @@ -252,14 +251,15 @@ class EuroExangeBot( pywikibot.bot.BaseBot ): ignoreWarning=False #set to True to skip warnings, Upload even if another file would be overwritten or another mistake would be risked targetSite = pywikibot.Site() - bot = upload.UploadRobot( filepath, - description=comment, - useFilename=filename, - keepFilename=keepFilename, - verifyDescription=verifyDescription, - ignoreWarning=ignoreWarning, - targetSite = targetSite - ) + bot = pywikibot.specialbots.UploadRobot( + filepath, + description=comment, + useFilename=filename, + keepFilename=keepFilename, + verifyDescription=verifyDescription, + ignoreWarning=ignoreWarning, + targetSite = targetSite + ) bot.upload_image(debug=True) From e8748045912b3ed436d8cb810594b4feb2279586 Mon Sep 17 00:00:00 2001 From: Jonathan Golder Date: Mon, 24 Sep 2018 20:26:50 +0200 Subject: [PATCH 13/29] Store current job in bot object For not having to provide it for each dependend method as param --- euroexange/euroexange.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/euroexange/euroexange.py b/euroexange/euroexange.py index 347b764..d4d21c4 100644 --- a/euroexange/euroexange.py +++ b/euroexange/euroexange.py @@ -203,15 +203,20 @@ class EuroExangeBot( pywikibot.bot.BaseBot ): @type job: EuroExangeBotJob """ + # 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" ) + if not self.current_job.filepage.exists(): + jogobot.output( "Work on Job {}".format( self.current_job.image), + "ERROR" ) raise pywikibot.NoPage( filepage ) self.call_gnuplot( job ) From 3a46ea8ddca1e1c0bc1ad7607160e3af2b76558b Mon Sep 17 00:00:00 2001 From: Jonathan Golder Date: Mon, 24 Sep 2018 20:31:07 +0200 Subject: [PATCH 14/29] Add update frequenzy in days to job Check against timestamp of latest file revision --- euroexange/euroexange.py | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/euroexange/euroexange.py b/euroexange/euroexange.py index d4d21c4..5528ed1 100644 --- a/euroexange/euroexange.py +++ b/euroexange/euroexange.py @@ -40,6 +40,7 @@ class EuroExangeBotJob(): self.image = kwargs['image'] self.script = kwargs['script'] + self.freq = kwargs['freq'] class EuroExangeBot( pywikibot.bot.BaseBot ): @@ -53,7 +54,9 @@ class EuroExangeBot( pywikibot.bot.BaseBot ): 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" ) ] + 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", freq=1 ) + ] def __init__( self, genFactory, **kwargs ): @@ -219,9 +222,40 @@ class EuroExangeBot( pywikibot.bot.BaseBot ): "ERROR" ) raise pywikibot.NoPage( filepage ) - self.call_gnuplot( job ) + # Check if update is necessary + if self.image_update_needed(): + self.call_gnuplot( job ) - self.upload_file( job ) + self.upload_file( job ) + + # Nothing to do + else: + jogobot.output( "No update needed for Job {}".format( + self.current_job.image) ) + + def image_update_needed( self ): + """ + Checks weather image update intervall is reached. + + @returns True if update needed + @rtype bool + """ + + return True + + # Get datetime of last update + last_update = self.current_job.filepage.latest_file_info.timestamp + + # Get current time + now = pywikibot.Site().getcurrenttime() + + # 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 ): """ From 6358a3db9ba771f4adfa7b713081fb8540b8043c Mon Sep 17 00:00:00 2001 From: Jonathan Golder Date: Mon, 24 Sep 2018 20:32:36 +0200 Subject: [PATCH 15/29] Check if file was changed before upload Use sha1 hash of file, which is available via FileInfo() to check for changes --- euroexange/euroexange.py | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/euroexange/euroexange.py b/euroexange/euroexange.py index 5528ed1..37a321a 100644 --- a/euroexange/euroexange.py +++ b/euroexange/euroexange.py @@ -25,6 +25,7 @@ import zipfile import shlex import subprocess import email.utils +import hashlib import pywikibot @@ -226,7 +227,11 @@ class EuroExangeBot( pywikibot.bot.BaseBot ): if self.image_update_needed(): self.call_gnuplot( job ) - self.upload_file( job ) + if self.file_changed(): + self.upload_file( job ) + else: + jogobot.output( "No upload needed for Job {}.".format( + self.current_job.image) ) # Nothing to do else: @@ -274,6 +279,26 @@ class EuroExangeBot( pywikibot.bot.BaseBot ): subprocess.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 ): """ From 46447d6f329343ff47810f8d4f757cfcb8481738 Mon Sep 17 00:00:00 2001 From: Jonathan Golder Date: Mon, 24 Sep 2018 21:15:38 +0200 Subject: [PATCH 16/29] Load jobs from json file --- euroexange/euroexange.py | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/euroexange/euroexange.py b/euroexange/euroexange.py index 37a321a..5bfd422 100644 --- a/euroexange/euroexange.py +++ b/euroexange/euroexange.py @@ -26,6 +26,7 @@ import shlex import subprocess import email.utils import hashlib +import json import pywikibot @@ -46,6 +47,7 @@ class EuroExangeBotJob(): class EuroExangeBot( pywikibot.bot.BaseBot ): + base_dir = os.path.dirname(os.path.realpath(__file__)) + "/.." working_dir = os.path.dirname(os.path.realpath(__file__)) + "/../wdir" gnuplot_script_dir = os.path.dirname(os.path.realpath(__file__)) + \ "/../gnuplot_scripts" @@ -55,10 +57,6 @@ class EuroExangeBot( pywikibot.bot.BaseBot ): 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", freq=1 ) - ] - def __init__( self, genFactory, **kwargs ): # Init working directory @@ -71,10 +69,10 @@ class EuroExangeBot( pywikibot.bot.BaseBot ): # 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): """ @@ -199,6 +197,23 @@ class EuroExangeBot( pywikibot.bot.BaseBot ): os.path.join(self.wdir, type(self).csv_file)), path=self.wdir ) + def load_jobs( self ): + """ + Load jobs from json file + + @returns Generator of EuroExangeBotJob objects + @rtype generator + """ + + # Load json jobs file + with open( os.path.join(self.base_dir, "jobs.json"), "r") as fd: + jobs_js = json.load( fd ) + + # yield each job + for job_args in jobs_js: + yield EuroExangeBotJob( **job_args ) + + def treat_job( self, job ): """ Handles working on specific jobs From 6c5eff65fb0ff57159827ec88b67ff6851fa71fb Mon Sep 17 00:00:00 2001 From: Jonathan Golder Date: Mon, 24 Sep 2018 21:16:00 +0200 Subject: [PATCH 17/29] For testing on betawiki, prepend prefix to filename As otherwise we will overwrite original files on commons --- euroexange/euroexange.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/euroexange/euroexange.py b/euroexange/euroexange.py index 5bfd422..9bc9036 100644 --- a/euroexange/euroexange.py +++ b/euroexange/euroexange.py @@ -44,6 +44,11 @@ class EuroExangeBotJob(): 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 ): From 5cf5c5a5970f5c68c3082b58a0072dffe7124664 Mon Sep 17 00:00:00 2001 From: Jonathan Golder Date: Tue, 25 Sep 2018 16:32:25 +0200 Subject: [PATCH 18/29] fix Pywikibot does not import specialbots by default --- euroexange/euroexange.py | 1 + 1 file changed, 1 insertion(+) diff --git a/euroexange/euroexange.py b/euroexange/euroexange.py index 9bc9036..d938242 100644 --- a/euroexange/euroexange.py +++ b/euroexange/euroexange.py @@ -29,6 +29,7 @@ import hashlib import json import pywikibot +import pywikibot.specialbots import jogobot From f28fad2edb93ced87659da71a5254bfc2cce6fbe Mon Sep 17 00:00:00 2001 From: Jonathan Golder Date: Tue, 25 Sep 2018 16:59:19 +0200 Subject: [PATCH 19/29] Fix old var name --- euroexange/euroexange.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/euroexange/euroexange.py b/euroexange/euroexange.py index d938242..5a32ac3 100644 --- a/euroexange/euroexange.py +++ b/euroexange/euroexange.py @@ -242,7 +242,7 @@ class EuroExangeBot( pywikibot.bot.BaseBot ): if not self.current_job.filepage.exists(): jogobot.output( "Work on Job {}".format( self.current_job.image), "ERROR" ) - raise pywikibot.NoPage( filepage ) + raise pywikibot.NoPage( self.current_job.filepage ) # Check if update is necessary if self.image_update_needed(): From f4296d8410bc504381fbe99deeeb0674e5b5dfdd Mon Sep 17 00:00:00 2001 From: Jonathan Golder Date: Tue, 25 Sep 2018 16:59:50 +0200 Subject: [PATCH 20/29] 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 --- euroexange/euroexange.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/euroexange/euroexange.py b/euroexange/euroexange.py index 5a32ac3..e710074 100644 --- a/euroexange/euroexange.py +++ b/euroexange/euroexange.py @@ -331,9 +331,9 @@ class EuroExangeBot( pywikibot.bot.BaseBot ): filename = 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 + 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 = [ "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() bot = pywikibot.specialbots.UploadRobot( From a0377e1f80ee01127bcae1ed391b64706bbc7f03 Mon Sep 17 00:00:00 2001 From: Jonathan Golder Date: Wed, 26 Sep 2018 16:00:03 +0200 Subject: [PATCH 21/29] Fix typo in upload comment --- euroexange/euroexange.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/euroexange/euroexange.py b/euroexange/euroexange.py index e710074..91368b6 100644 --- a/euroexange/euroexange.py +++ b/euroexange/euroexange.py @@ -61,7 +61,7 @@ class EuroExangeBot( pywikibot.bot.BaseBot ): 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" + upload_comment = "Bot: ([[User:JogoBot/Euroexange|euroexange]]) update chart" def __init__( self, genFactory, **kwargs ): From 1d41e206c0e983e2a79c012e0f5ea431d6ce15e4 Mon Sep 17 00:00:00 2001 From: Jonathan Golder Date: Thu, 27 Sep 2018 08:23:26 +0200 Subject: [PATCH 22/29] Fix deprecated calls to UploadRobot --- euroexange/euroexange.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/euroexange/euroexange.py b/euroexange/euroexange.py index 91368b6..eae2d4a 100644 --- a/euroexange/euroexange.py +++ b/euroexange/euroexange.py @@ -330,7 +330,7 @@ class EuroExangeBot( pywikibot.bot.BaseBot ): comment = type(self).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 = [ "exists", "duplicate", ] #set to True to skip warnings, Upload even if another file would be overwritten or another mistake would be risked @@ -346,7 +346,7 @@ class EuroExangeBot( pywikibot.bot.BaseBot ): targetSite = targetSite ) - bot.upload_image(debug=True) + bot.run() def main(*args): """ From 638d2b6a3d951a913c95cc18d449b940e7d6bcd6 Mon Sep 17 00:00:00 2001 From: Jonathan Golder Date: Thu, 27 Sep 2018 08:41:53 +0200 Subject: [PATCH 23/29] Do not raise Exception when image not exists Just output a warning and go on with further jobs --- euroexange/euroexange.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/euroexange/euroexange.py b/euroexange/euroexange.py index eae2d4a..9c54020 100644 --- a/euroexange/euroexange.py +++ b/euroexange/euroexange.py @@ -238,11 +238,13 @@ class EuroExangeBot( pywikibot.bot.BaseBot ): self.current_job.filepage = pywikibot.page.FilePage( pywikibot.Site(), job.image) - # Stop if file not jet exists + # Skip if file not yet exists if not self.current_job.filepage.exists(): - jogobot.output( "Work on Job {}".format( self.current_job.image), - "ERROR" ) - raise pywikibot.NoPage( self.current_job.filepage ) + 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(): From f9a39a6f49ca4573f81871bd8e04dbdd0302f210 Mon Sep 17 00:00:00 2001 From: Jonathan Golder Date: Fri, 5 Oct 2018 14:43:43 +0200 Subject: [PATCH 24/29] Make it possible to run Bot with -always To be able to run script unattended --- euroexange/euroexange.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/euroexange/euroexange.py b/euroexange/euroexange.py index 9c54020..78f9a7a 100644 --- a/euroexange/euroexange.py +++ b/euroexange/euroexange.py @@ -68,7 +68,7 @@ class EuroExangeBot( pywikibot.bot.BaseBot ): # Init working directory self.init_wdir() - super().__init__(*kwargs) + super().__init__(**kwargs) def run(self): @@ -337,6 +337,8 @@ class EuroExangeBot( pywikibot.bot.BaseBot ): verifyDescription = True #set to False to skip double-checking/editing description => change to bot-mode 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 = pywikibot.specialbots.UploadRobot( filepath, @@ -345,7 +347,9 @@ class EuroExangeBot( pywikibot.bot.BaseBot ): keepFilename=keepFilename, verifyDescription=verifyDescription, ignoreWarning=ignoreWarning, - targetSite = targetSite + targetSite = targetSite, + always=always, + aborts=aborts, ) bot.run() @@ -380,7 +384,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, EuroExangeBot, genFactory, **subtask_args) # Run bot jogobot.bot.run_bot( task_slug, None, bot ) From 0477940fdf725d5befb5be59c51c9c96012d431c Mon Sep 17 00:00:00 2001 From: Jonathan Golder Date: Fri, 5 Oct 2018 14:46:50 +0200 Subject: [PATCH 25/29] Define requirements Installable via pip install -r requirements.txt --- requirements.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 requirements.txt diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..1f92eaa --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +# jogobot +git+https://git.golderweb.de/wiki/jogobot.git#egg=jogobot From b3a0857ddd449b249bb7fdc99bc9ac8b27d7451e Mon Sep 17 00:00:00 2001 From: Jonathan Golder Date: Fri, 5 Oct 2018 16:11:35 +0200 Subject: [PATCH 26/29] Fix typo in Euroexchange --- README.md | 7 +++---- {euroexange => euroexchange}/__init__.py | 0 .../euroexchange.py | 20 +++++++++---------- 3 files changed, 13 insertions(+), 14 deletions(-) rename {euroexange => euroexchange}/__init__.py (100%) rename euroexange/euroexange.py => euroexchange/euroexchange.py (95%) diff --git a/README.md b/README.md index 91e0c8e..3c112db 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# wiki-jogobot-euroexange +# wiki-jogobot-euroexchange 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). @@ -12,14 +12,13 @@ of [User:JogoBot](https://de.wikipedia.org/wiki/Benutzer:JogoBot) on the ## Usage ``` -python euroexange.py -``` +python euroexchange.py ## Versions * ## 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+ diff --git a/euroexange/__init__.py b/euroexchange/__init__.py similarity index 100% rename from euroexange/__init__.py rename to euroexchange/__init__.py diff --git a/euroexange/euroexange.py b/euroexchange/euroexchange.py similarity index 95% rename from euroexange/euroexange.py rename to euroexchange/euroexchange.py index 78f9a7a..88d3236 100644 --- a/euroexange/euroexange.py +++ b/euroexchange/euroexchange.py @@ -34,9 +34,9 @@ import pywikibot.specialbots import jogobot -class EuroExangeBotJob(): +class EuroExchangeBotJob(): """ - Used for EuroExangeBot job queue + Used for EuroExchangeBot job queue """ def __init__( self, **kwargs ): @@ -51,7 +51,7 @@ class EuroExangeBotJob(): self.image = "TEST_{}".format(self.image) -class EuroExangeBot( pywikibot.bot.BaseBot ): +class EuroExchangeBot( pywikibot.bot.BaseBot ): base_dir = os.path.dirname(os.path.realpath(__file__)) + "/.." working_dir = os.path.dirname(os.path.realpath(__file__)) + "/../wdir" @@ -61,7 +61,7 @@ class EuroExangeBot( pywikibot.bot.BaseBot ): 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" + upload_comment = "Bot: ([[User:JogoBot/Euroexchange|euroexchange]]) update chart" def __init__( self, genFactory, **kwargs ): @@ -207,7 +207,7 @@ class EuroExangeBot( pywikibot.bot.BaseBot ): """ Load jobs from json file - @returns Generator of EuroExangeBotJob objects + @returns Generator of EuroExchangeBotJob objects @rtype generator """ @@ -217,7 +217,7 @@ class EuroExangeBot( pywikibot.bot.BaseBot ): # yield each job for job_args in jobs_js: - yield EuroExangeBotJob( **job_args ) + yield EuroExchangeBotJob( **job_args ) def treat_job( self, job ): @@ -225,7 +225,7 @@ class EuroExangeBot( pywikibot.bot.BaseBot ): 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 @@ -289,7 +289,7 @@ class EuroExangeBot( pywikibot.bot.BaseBot ): """ @param job: Job to work on - @type job: EuroExangeBotJob + @type job: EuroExchangeBotJob """ cmd = shlex.split ( type(self).gnuplot + " " + os.path.realpath( @@ -326,7 +326,7 @@ class EuroExangeBot( pywikibot.bot.BaseBot ): """ @param job: Job to work on - @type job: EuroExangeBotJob + @type job: EuroExchangeBotJob """ comment = type(self).upload_comment @@ -384,7 +384,7 @@ def main(*args): local_args, None ) # Init Bot - bot = jogobot.bot.init_bot( task_slug, None, EuroExangeBot, genFactory, **subtask_args) + bot = jogobot.bot.init_bot( task_slug, None, EuroExchangeBot, genFactory, **subtask_args) # Run bot jogobot.bot.run_bot( task_slug, None, bot ) From c35c296e9278912b271106c87596b6a05b60617c Mon Sep 17 00:00:00 2001 From: Jonathan Golder Date: Fri, 5 Oct 2018 16:14:48 +0200 Subject: [PATCH 27/29] Do not track gnuplotscripts in this repo Since they are more config, we will use separate repo --- ..._Turkish_Currency_and_Debt_Crisis_2018.plt | 84 ------------------- 1 file changed, 84 deletions(-) delete mode 100644 gnuplot_scripts/Euro_exchange_rate_to_TRY_-_Turkish_Currency_and_Debt_Crisis_2018.plt diff --git a/gnuplot_scripts/Euro_exchange_rate_to_TRY_-_Turkish_Currency_and_Debt_Crisis_2018.plt b/gnuplot_scripts/Euro_exchange_rate_to_TRY_-_Turkish_Currency_and_Debt_Crisis_2018.plt deleted file mode 100644 index 61b24f1..0000000 --- a/gnuplot_scripts/Euro_exchange_rate_to_TRY_-_Turkish_Currency_and_Debt_Crisis_2018.plt +++ /dev/null @@ -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 \ From 3cd639eef94d2a349888c37a41a974aed42c545e Mon Sep 17 00:00:00 2001 From: Jonathan Golder Date: Fri, 5 Oct 2018 20:24:00 +0200 Subject: [PATCH 28/29] Move configuration vars to jogobot config --- euroexchange/euroexchange.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/euroexchange/euroexchange.py b/euroexchange/euroexchange.py index 88d3236..9e4286d 100644 --- a/euroexchange/euroexchange.py +++ b/euroexchange/euroexchange.py @@ -53,15 +53,14 @@ class EuroExchangeBotJob(): class EuroExchangeBot( pywikibot.bot.BaseBot ): - base_dir = os.path.dirname(os.path.realpath(__file__)) + "/.." - 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/Euroexchange|euroexchange]]) update chart" + 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"] def __init__( self, genFactory, **kwargs ): From 4395cb42eb9a15a6d7e930709fcbe9030cef5dbd Mon Sep 17 00:00:00 2001 From: Jonathan Golder Date: Tue, 9 Oct 2018 08:41:14 +0200 Subject: [PATCH 29/29] Prepare stable release v0.1 --- license.txt => LICENSE.txt | 0 README.md | 13 +++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) rename license.txt => LICENSE.txt (100%) diff --git a/license.txt b/LICENSE.txt similarity index 100% rename from license.txt rename to LICENSE.txt diff --git a/README.md b/README.md index 3c112db..94a676e 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,7 @@ # wiki-jogobot-euroexchange -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). - - +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) @@ -13,9 +11,12 @@ of [User:JogoBot](https://de.wikipedia.org/wiki/Benutzer:JogoBot) on the ## Usage ``` 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 ## Bugs [jogobot-euroexchange Issues](https://git.golderweb.de/wiki/jogobot-euroexchange/issues)