[MerlinMusicPlayer] fixed google cover display
[enigma2-plugins.git] / epgbackup / src / EPGBackup.sh
1 #!/bin/sh
2
3 LINE="--------------------------------------"
4 PLUGINNAME="EPGBackup"
5 PLUGINDIR="/usr/lib/enigma2/python/Plugins/Extensions/EPGBackup"
6 PLUGINCONFPREFIX="config.plugins.epgbackup"
7 SCRIPTNAME=`basename $0`
8 LOGPREFIX="[$PLUGINNAME-Script]"
9 SCRIPTEXEC="[ -x $PLUGINDIR/$SCRIPTNAME ] && $PLUGINDIR/$SCRIPTNAME"
10
11 # Options
12 BACKUPENABLED=`grep "$PLUGINCONFPREFIX.backup_enabled" /etc/enigma2/settings | sed -e "s/^.*=\(.*\)\.*$/\1/"`
13 VALIDSIZE=`grep "$PLUGINCONFPREFIX.filesize_valid" /etc/enigma2/settings | sed -e "s/^.*=\(.*\)\.*$/\1/"`
14 VALIDTIMESPAN=`grep "$PLUGINCONFPREFIX.timespan_valid" /etc/enigma2/settings | sed -e "s/^.*=\(.*\)\.*$/\1/"`
15 EPGWRITEWAIT=`grep "$PLUGINCONFPREFIX.epgwrite_wait" /etc/enigma2/settings | sed -e "s/^.*=\(.*\)\.*$/\1/"`
16 SHOWIN_USR_SCRIPTS=`grep "$PLUGINCONFPREFIX.showin_usr_scripts" /etc/enigma2/settings | sed -e "s/^.*=\(.*\)\.*$/\1/"`
17 BACKUP_STRATEGY=`grep "$PLUGINCONFPREFIX.backup_strategy" /etc/enigma2/settings | sed -e "s/^.*=\(.*\)\.*$/\1/"`
18 MAKE_BACKUP_AFTER_UNSUCCESS_RESTORE=`grep "$PLUGINCONFPREFIX.make_backup_after_unsuccess_restore" /etc/enigma2/settings | sed -e "s/^.*=\(.*\)\.*$/\1/"`
19 ENABLEDEUG=`grep "$PLUGINCONFPREFIX.enable_debug" /etc/enigma2/settings | sed -e "s/^.*=\(.*\)\.*$/\1/"`
20 LOGPATH=`grep "$PLUGINCONFPREFIX.backup_log_dir" /etc/enigma2/settings | sed -e "s/^.*=\(.*\)\.*$/\1/"`
21 MAXBOOTCOUNT=`grep "$PLUGINCONFPREFIX.max_boot_count" /etc/enigma2/settings | sed -e "s/^.*=\(.*\)\.*$/\1/"`
22 # defaults
23 BACKUPENABLED=${BACKUPENABLED:-true}
24 VALIDSIZE=${VALIDSIZE:-3} # MiB
25 VALIDSIZE=$(($VALIDSIZE*1024)) # KiB
26 VALIDSIZE=$(($VALIDSIZE*1024)) # Bytes
27 VALIDTIMESPAN=${VALIDTIMESPAN:-7} # days
28 EPGWRITEWAIT=${EPGWRITEWAIT:-3} # seconds
29 SHOWIN_USR_SCRIPTS=${SHOWIN_USR_SCRIPTS:-true}
30 BACKUP_STRATEGY=${BACKUP_STRATEGY:-youngest_before_biggest}
31 MAKE_BACKUP_AFTER_UNSUCCESS_RESTORE=${MAKE_BACKUP_AFTER_UNSUCCESS_RESTORE:-true}
32 ENABLEDEUG=${ENABLEDEUG:-false}
33 LOGPATH=${LOGPATH:-/media/hdd}
34 MAXBOOTCOUNT=${MAXBOOTCOUNT:-3}
35
36 # standard and/or Merlin?
37 EPGPATH=`grep "config.misc.epgcache_filename" /etc/enigma2/settings | sed -e "s/^.*=\(.*\)\.*$/\1/" | sed -e "s/\/epg\.dat$//"`
38 if [ -z "$EPGPATH" ]; then
39   EPGPATH=`cat /etc/enigma2/gemini_plugin.conf 2> /dev/null | grep epgCacheDir | sed -e "s/^.*=\(.*\)\.*$/\1/"`
40 fi
41 EPGPATH=${EPGPATH:-/media/hdd} # fallback
42 EPGFILE=$EPGPATH/epg.dat
43
44 # Constants
45 FORCEPREFIX="FORCE"
46 BACKUPFILEPREFIX="epg_"
47 BOOTCOUNTERFILE="/tmp/.EPGBackup.boot.counter"
48 LASTRESTOREDFILE="/tmp/.EPGBackup.lastfile.restored"
49 LASTBACKUPEDFILE="/tmp/.EPGBackup.lastfile.backuped"
50 OUTERRORTXTFILE="/tmp/.EPGBackup.outerrortxt"
51
52 if [ `echo "$ENABLEDEUG" | tr [:upper:] [:lower:]` == "true" ] ; then
53   debug="true"
54   logfile=$LOGPATH/EPGBackup.log.`date +%Y%m%d`
55 else
56   # always log the current run, but make sure that the file doesn't become to big
57   logfile=/tmp/EPGBackup.log
58   echo "" > $logfile
59 fi
60
61 getVersion () {
62   if [ -n "$debug" ] ; then
63     vers=`grep -iE ".*version[[:space:]]*=[[:space:]]*\"[0-9]*" $PLUGINDIR/EPGBackupTools.py`
64     vers=`echo "$vers" | sed -e "s/^.*=[[:space:]]*\"\(.*\)\"*$/\1/"`
65     vers=`echo "$vers" | sed -e "s/\"//"`
66     echo -n " V$vers"
67   fi
68 }
69
70 echologprefix () {
71   echo -n "$LOGPREFIX [`date +'%Y%m%d %H:%M:%S'``getVersion`] "
72 }
73
74 housekeeping () {
75   if [ "$1" != "nolog" ]; then
76     echologprefix; echo "housekeeping..."
77     hkDebug="$debug"
78   fi
79   
80   if [ "$VALIDTIMESPAN" == 1 ]; then
81     [ -n "$hkDebug" ] && find "$EPGPATH" -mtime 1 -name "$BACKUPFILEPREFIX*.dat"
82     find "$EPGPATH" -mtime 1 -name "$BACKUPFILEPREFIX*.dat" -exec rm {} \;
83     if [ -d "$LOGPATH" ]; then
84       [ -n "$hkDebug" ] && find "$LOGPATH" -mtime 1 -name "EPGBackup.log*"
85       find "$LOGPATH" -mtime 1 -name "EPGBackup.log*" -exec rm {} \;
86     fi
87     # maybe there are older files than 1 day, so also delete them
88     localTimespan=1
89   else
90     localTimespan=$(($VALIDTIMESPAN-1))
91   fi
92   [ -n "$hkDebug" ] && find "$EPGPATH" -mtime +"$localTimespan" -name "$BACKUPFILEPREFIX*.dat"
93   find "$EPGPATH" -mtime +"$localTimespan" -name "$BACKUPFILEPREFIX*.dat" -exec rm {} \;
94   if [ -d "$LOGPATH" ]; then
95     [ -n "$hkDebug" ] && find "$LOGPATH" -mtime +"$localTimespan" -name "EPGBackup.log*"
96     find "$LOGPATH" -mtime +"$localTimespan" -name "EPGBackup.log*" -exec rm {} \;
97   fi
98 }
99
100 printVars () {
101   echo "$LINE"
102   echo "Variables:"
103   echo -e "Backup enabled: $BACKUPENABLED"
104   echo -e "Make backup after unsuccessfully restore: $MAKE_BACKUP_AFTER_UNSUCCESS_RESTORE"
105   echo -e "Valid Size: $VALIDSIZE Bytes"
106   echo -e "Valid Timespan: $VALIDTIMESPAN"
107   echo -e "EPG writetime: $EPGWRITEWAIT"
108   echo -e "Backup-Strategy: $BACKUP_STRATEGY"
109   echo -e "Maximal Bootcount: $MAXBOOTCOUNT"
110   echo -e "Debug: $ENABLEDEUG"
111   echo -e "Logpath: $LOGPATH"
112   echo -e "EPG-Path: $EPGPATH"
113   echo "$LINE"
114 }
115
116 getLastFileInfo () {
117   fileInfo=""
118   if [ "$1" == "backup" ]; then
119     [ -e $LASTBACKUPEDFILE ] && fileInfo=`cat $LASTBACKUPEDFILE`
120   elif [ "$1" == "error" ]; then
121     [ -e $OUTERRORTXTFILE ] && fileInfo=`cat $OUTERRORTXTFILE`
122   else
123     [ -e $LASTRESTOREDFILE ] && fileInfo=`cat $LASTRESTOREDFILE`
124   fi
125   
126   echo -n "$fileInfo"
127 }
128
129 makeBackup () {
130   rm -f $LASTBACKUPEDFILE 2> /dev/null
131   if [ `echo "$BACKUPENABLED" | tr [:upper:] [:lower:]` != "true" ] ; then
132     echologprefix; echo "Backup/Restore is disabled2!"
133     OUTERRORTEXT="BACKUP_RESTORE_DISABLED"
134     return
135   fi
136   echologprefix; echo "Backuping ..."
137   [ -n "$debug" ] && printVars
138   
139   if [ -f "$EPGFILE" ]; then
140     # Wait until the filesize didn't change
141     trycount=0
142     let filesizeold=`ls -lr "$EPGFILE" | tr -s " " | cut -d " " -f 5 | head -n1`
143     while [ $trycount -le $EPGWRITEWAIT ]
144     do
145       sleep 1
146       let EPGFILESIZE=`ls -lr "$EPGFILE" | tr -s " " | cut -d " " -f 5 | head -n1`
147       if [ $EPGFILESIZE -eq $filesizeold ]; then
148         trycount=`expr $trycount + 1`
149       else
150         trycount=0
151       fi
152       filesizeold=$EPGFILESIZE
153     done
154     
155     if [ "$EPGFILESIZE" -gt "$VALIDSIZE" ]; then
156       EPGbackup="$BACKUPFILEPREFIX`date +%Y%m%d_%H%M`.dat"
157       echologprefix; echo "making Backup $EPGbackup ($(($EPGFILESIZE / 1024)) KiB)"
158       cp "$EPGFILE" "$EPGPATH/$EPGbackup"
159       echo "$EPGPATH/$EPGbackup" > $LASTBACKUPEDFILE 2> /dev/null
160     else
161       echologprefix; echo "Epg-File too small for Backup ($(($EPGFILESIZE / 1024)) KiB)"
162       OUTERRORTEXT="BACKUP_EPGFILE_TOO_SMALL#$(($EPGFILESIZE / 1024)) KiB#$(($VALIDSIZE / 1024)) KiB"
163     fi
164   else
165     echologprefix; echo "No Epg-File found at $EPGPATH"
166     OUTERRORTEXT="BACKUP_NO_EPGFILE_FOUND#$EPGPATH"
167   fi
168 }
169
170 _restore () {
171   success="false"
172   
173   local __resultvar=$2
174
175   if [ -f "$EPGFILE" ]; then
176     let EPGFILESIZE=`ls -lr "$EPGFILE" | tr -s " " | cut -d " " -f 5 | head -n1`
177   else
178     EPGFILESIZE=0
179   fi
180   
181   wasForced="false"
182   if [ "$3" != "" ]; then
183     EPGbackup=`ls $EPGPATH/$3 2> /dev/null | head -n1`
184   else
185     # maybe there's a forced-file
186     EPGbackup=`ls $EPGPATH/${FORCEPREFIX}$BACKUPFILEPREFIX*.dat 2> /dev/null | head -n1`
187     wasForced="true"
188   fi
189   if [ -f "$EPGbackup" ]; then
190     echologprefix; echo "Forced restoring from `basename $EPGbackup`"
191     cp -f "$EPGbackup" "$EPGFILE"
192     [ "$wasForced" == "true" ] && rm -f $EPGbackup
193     success="true"
194   else
195     if [ "$1" == "biggest" ]; then
196       EPGbackupInfo=`ls -leS $EPGPATH/$BACKUPFILEPREFIX*.dat 2> /dev/null | head -n1 | tr -s " "`
197     else
198       EPGbackupInfo=`ls -let $EPGPATH/$BACKUPFILEPREFIX*.dat 2> /dev/null | head -n1 | tr -s " "`
199     fi  
200     EPGbackup=`echo $EPGbackupInfo | cut -d " " -f 11`
201
202     if [ -f "$EPGbackup" ]; then
203       if [ "$1" == "biggest" ]; then
204         let BACKUPSIZE=`echo $EPGbackupInfo | cut -d " " -f 5`
205         if [ ! -f "$EPGFILE" -o $BACKUPSIZE -gt $EPGFILESIZE ]; then
206           echologprefix; echo "Restoring from `basename $EPGbackup`"
207           cp -f "$EPGbackup" "$EPGFILE"
208           success="true"
209         else
210           echologprefix; echo "`basename $EPGbackup` smaller or equal: $(($BACKUPSIZE / 1024)) KiB --> no restoring!"
211           echologprefix; echo "Size of existing Epg-File: $(($EPGFILESIZE / 1024)) KiB"
212           OUTERRORTEXT="RESTORE_BACKUPFILE_SMALLER#$(($BACKUPSIZE / 1024)) KiB#$(($EPGFILESIZE / 1024)) KiB"
213         fi
214       else
215         # youngest
216         if [ ! -f "$EPGFILE" -o "$EPGbackup" -nt "$EPGFILE" ]; then
217           echologprefix; echo "Restoring from `basename $EPGbackup`"
218           cp -f "$EPGbackup" "$EPGFILE"
219           success="true"
220         else
221           if [ -n "$debug" ]; then
222             BACKUPAGE=`echo $EPGbackupInfo | cut -d " " -f 7-10`
223             EPGFILEAGE=`ls -ler "$EPGFILE" | tr -s " " | cut -d " " -f 7-10 | head -n1`
224             echologprefix; echo "`basename $EPGbackup` older or equal: $BACKUPAGE --> no restoring!"
225             echologprefix; echo "Modify-Date of Epg-File: $EPGFILEAGE"
226             OUTERRORTEXT="RESTORE_BACKUPFILE_OLDER#$BACKUPAGE#$EPGFILEAGE"
227           fi
228         fi
229       fi
230     fi
231   fi
232   
233   [ "$success" == "true" ] && echo "$EPGbackup" > $LASTRESTOREDFILE 2> /dev/null
234   eval $__resultvar="'$success'"
235 }
236
237 _incrementBootCounter () {
238   local  __resultvar=$1
239   
240   count=`cat $BOOTCOUNTERFILE 2> /dev/null` 
241   count=${count:-0}
242   
243   count=`expr $count + 1`
244   echo "$count" > $BOOTCOUNTERFILE
245   
246   eval $__resultvar="'$count'"
247 }
248
249 _isValidFile () {
250   valid="false"
251   checkFile="$1"
252   local  __resultvar=$2
253   
254   if [ -f "$checkFile" ]; then
255     ageOk=`find $(dirname "$checkFile") -mtime -"$VALIDTIMESPAN" -name $(basename "$checkFile") | wc -l`
256     if [ "$ageOk" -gt 0 ] ; then
257       FILEINFO=`ls -le "$checkFile" | tr -s " "`
258       FILESIZE=`echo $FILEINFO | cut -d " " -f 5`
259       FILESIZE=${FILESIZE:-0}
260       if [ $VALIDSIZE -lt $FILESIZE ]; then
261         valid="true"
262       else
263         [ -n "$debug" ] && echo "`basename $checkFile` hasn't a valid size: $(($FILESIZE / 1024)) KiB"
264       fi
265     else
266       [ -n "$debug" ] && echo "`basename $checkFile` hasn't a valid age: `echo $FILEINFO | cut -d " " -f 7-10`"
267     fi
268   fi
269   
270   eval $__resultvar="'$valid'"
271 }
272
273 restore () {
274   parambackupfile=$1
275   rm -f $LASTRESTOREDFILE 2> /dev/null
276   if [ `echo "$BACKUPENABLED" | tr [:upper:] [:lower:]` != "true" ] ; then
277     echologprefix; echo "Backup/Restore is disabled!"
278     OUTERRORTEXT="BACKUP_RESTORE_DISABLED"
279     return
280   fi
281   echologprefix; echo "Restoring ..."
282   [ -n "$debug" ] && printVars
283   
284   aktbootcount=0
285   [ -n "$parambackupfile" ] || _incrementBootCounter aktbootcount
286   
287   if [ "$aktbootcount" -gt "$MAXBOOTCOUNT" ]; then
288     echologprefix; echo "Maximum Boot-Count reached: Deleting EPG-File!"
289     OUTERRORTEXT="RESTORE_MAXBOOTCOUNT_REACHED"
290     rm -f $EPGFILE 2> /dev/null
291     return
292   fi
293   
294   case "$BACKUP_STRATEGY" in
295     biggest_before_youngest|biggest)
296       _restore "biggest" success $parambackupfile
297       if [ "$BACKUP_STRATEGY" == "biggest_before_youngest" -a "$success" == "false" ]; then
298         _isValidFile $EPGFILE isValid
299         if [ "$isValid" == "false" ] ; then
300           echologprefix; echo "Trying fallback - strategy youngest!"
301           _restore "youngest" success
302         else
303           # keep the state unsuccessfully, maybe make a backup later
304           echologprefix; echo "Original epg.dat is valid, fallback - strategy not needed!"
305           OUTERRORTEXT="RESTORE_ORIGINALFILE_VALID"
306         fi
307       fi
308       ;;
309     youngest_before_biggest|youngest)
310       _restore "youngest" success $parambackupfile
311       if [ "$BACKUP_STRATEGY" == "youngest_before_biggest" -a "$success" == "false" ]; then
312         _isValidFile $EPGFILE isValid
313         if [ "$isValid" == "false" ] ; then
314           echologprefix; echo "Trying fallback - strategy biggest!"
315           _restore "biggest" success
316         else
317           # keep the state unsuccessfully, maybe make a backup later
318           echologprefix; echo "Original epg.dat is valid, fallback - strategy not needed!"
319           OUTERRORTEXT="RESTORE_ORIGINALFILE_VALID"
320         fi
321       fi
322   esac 
323   
324   if [ "$success" == "false" ]; then
325     echologprefix; echo "No valid Backup found for restore, or restore not needed!"
326     if [ `echo "$MAKE_BACKUP_AFTER_UNSUCCESS_RESTORE" | tr [:upper:] [:lower:]` == "true" ]; then
327       echologprefix; echo "Trying to make a Backup of current epg.dat!"
328       makeBackup
329     fi
330   fi
331 }
332
333 epgInfo () {
334   if [ "$1" == "bySize" ]; then
335     files=`ls -S $EPGPATH/$BACKUPFILEPREFIX*.dat 2> /dev/null`
336   else
337     files=`ls -t $EPGPATH/$BACKUPFILEPREFIX*.dat 2> /dev/null`
338   fi
339   biggest=`ls -lS $EPGPATH/$BACKUPFILEPREFIX*.dat 2> /dev/null | head -n1 | tr -s " " | cut -d " " -f 9`
340   [ -n "$biggest" ] && biggest=`basename $biggest`
341   youngest=`ls -t $EPGPATH/$BACKUPFILEPREFIX*.dat 2> /dev/null | head -n1 | tr -s " " | cut -d " " -f 9`
342   [ -n "$youngest" ] && youngest=`basename $youngest`
343   forced=`ls $EPGPATH/${FORCEPREFIX}$BACKUPFILEPREFIX*.dat 2> /dev/null | head -n1`
344   if [ -n "$forced" ]; then
345     forced=`basename $forced`
346     forced=`echo $forced | cut -c 6-`
347   fi
348   for aktFile in $files; do
349     aktFile=`echo "$aktFile" | tr -s " " | cut -d " " -f 9`
350     size=`du -ha $aktFile | cut -f 1`
351     aktFile=`basename $aktFile`
352     
353     if [ "$aktFile" == "$forced" ]; then
354       forcextend=" (force)"
355     else
356       forcextend=""
357     fi
358     
359     if [ "$aktFile" == "$youngest" ]; then
360       youngextend=" (youngest)"
361     else
362       youngextend=""
363     fi
364     
365     if [ "$aktFile" == "$biggest" ]; then
366       bigextend=" (biggest)"
367     else
368       bigextend=""
369     fi
370     
371     echo -e "$aktFile   $size$forcextend$youngextend$bigextend"
372   done
373 }
374
375 setforcefile () {
376   forcefile="$1"
377   
378   rm -f $EPGPATH/$FORCEPREFIX*.dat 2> /dev/null
379   if [ -f "$EPGPATH/$forcefile" ]; then
380     ln -s $EPGPATH/$forcefile $EPGPATH/$FORCEPREFIX$forcefile
381   fi
382   
383 }
384
385 prestartfile="/usr/bin/enigma2_pre_start20epgrestore.sh"
386 info () {
387   echo "$LINE"
388   printVars
389   
390   echo -n "$LOGPREFIX Enigma-pre-hook-File $prestartfile "
391   if [ -e "$prestartfile" ] ; then
392     echo "exists"
393   else
394     echo "doesn't exists"
395   fi
396   echo "$LINE"
397 }
398
399 installit () {
400   echo $LINE
401
402   # enigma2.sh - hook
403   if [ ! -e "$prestartfile" ] ; then
404     echo "$LOGPREFIX creating enigma-pre-hook '$prestartfile'"
405     echo -e "#!/bin/sh" > $prestartfile
406     echo -e "\n$SCRIPTEXEC restore" >> $prestartfile
407     echo -e "exit 0" >> $prestartfile
408     chmod 755 $prestartfile
409   else
410     echo "$LOGPREFIX $prestartfile exists"
411   fi
412   
413   # if there is an Oozoon(like)-Image: enable it in user-scripts
414   if [ -d "/usr/script/" ] ; then
415     echo "$LOGPREFIX enable $PLUGINNAME in User-Scripts: $SHOWIN_USR_SCRIPTS"
416     if [ `echo "$SHOWIN_USR_SCRIPTS" | tr [:upper:] [:lower:]` == "true" ] ; then
417       ln -sfn $PLUGINDIR/$SCRIPTNAME /usr/script/
418     else
419       rm /usr/script/$SCRIPTNAME > /dev/null 2>&1
420     fi
421   fi
422   echo $LINE
423 }
424
425 uninstall(){
426   echo $LINE
427   # enigma2.sh - hook
428   echo "$LOGPREFIX remove '$prestartfile'"
429   rm -f $prestartfile > /dev/null 2>&1
430   
431   if [ -d "/usr/script/" ] ; then
432     echo "$LOGPREFIX remove $PLUGINNAME from User-Scripts"
433     rm -f /usr/script/$SCRIPTNAME > /dev/null 2>&1
434   fi
435   echo $LINE
436 }
437
438 if [ "$1" != "epginfo" -a "$1" != "getlastfile"  ]; then
439   [ -n "$debug" ] || echo "$LOGPREFIX Action: $*"
440   [ -n "$debug" ] && echo "$LOGPREFIX [`date +%Y%m%d_%H%M%S``getVersion`] Action: $*"
441 fi
442 case "$1" in
443      epginfo)
444         housekeeping "nolog"
445         epgInfo "$2"
446         ;;
447      getlastfile)
448         getLastFileInfo "$2"
449         ;;
450      backup|b)
451         errorHandling=TRUE
452         echo "Output will be append to $logfile"
453         exec >> $logfile 2>&1
454         echo $LINE
455         housekeeping
456         makeBackup
457         ;;
458      restore|r)
459         errorHandling=TRUE
460         echo "Output will be append to $logfile"
461         exec >> $logfile 2>&1
462         echo $LINE
463         [ -z "$2" ] && housekeeping
464         restore $2
465         ;;
466      setforcefile)
467         errorHandling=TRUE
468         setforcefile "$2"
469         ;;
470      info)
471         info
472         ;;
473      install)
474         SHOWIN_USR_SCRIPTS=${2:-$SHOWIN_USR_SCRIPTS}
475         installit
476         ;;
477      housekeeping)
478         [ -n "$debug" ] && printVars
479         housekeeping
480         ;;
481      uninstall)
482         uninstall
483         ;;
484      *)
485         echo "Usage: $0 b|backup|r|restore|epginfo|getlastfile|setforcefile|housekeeping|info|install|uninstall"
486         exit 1
487         ;;
488 esac
489
490 if [ -n "$errorHandling" ] ; then
491   rm -f $OUTERRORTXTFILE 2> /dev/null
492   if [ -n "$OUTERRORTEXT" ] ; then
493     echo "$OUTERRORTEXT" > $OUTERRORTXTFILE
494   fi
495 fi
496
497 exit 0