WebIf: some fixes for Backup Source
[enigma2-plugins.git] / webinterface / src / WebComponents / Sources / Backup.py
1 from enigma import eServiceReference, iServiceInformation, eServiceCenter
2 from Components.Sources.Source import Source
3 from Components.config import config, ConfigLocations
4 try:
5         from Plugins.SystemPlugins.SoftwareManager import BackupRestore
6 except ImportError as ie:
7         from enigma import eEnv
8         # defaults from BackupRestore
9         backupdirs = ConfigLocations(default=[eEnv.resolve('${sysconfdir}/enigma2/'), '/etc/network/interfaces', '/etc/wpa_supplicant.conf', '/etc/wpa_supplicant.ath0.conf', '/etc/wpa_supplicant.wlan0.conf', '/etc/resolv.conf', '/etc/default_gw', '/etc/hostname'])
10 else:
11         backupdirs = config.plugins.configurationbackup.backupdirs
12 from os import remove, path, popen
13 from re import compile as re_compile
14
15 try:
16         import tarfile
17 except ImportError as ie:
18         tarfile = None
19
20 class Backup(Source):
21         BACKUP = 0
22         RESTORE = 1
23
24         BACKUP_PATH = "/tmp"
25         BACKUP_FILENAME = "backup.tar" # XXX: better default name?
26
27         def __init__(self, func=BACKUP):
28                 Source.__init__(self)
29                 self.func = func
30                 self.command = None
31                 self.result = ( False, _("Missing or Wrong Argument") )
32
33         def handleCommand(self, cmd):
34                 if self.func is self.BACKUP:
35                         self.result = self.backupFiles(cmd)
36                 elif self.func is self.RESTORE:
37                         self.result = self.restoreFiles(cmd)
38                 else:
39                         self.result = ( False, "one two three four unknown command" )
40
41         def getCompressionMode(self, tarname):
42                 """
43                   This basically guesses which compression to use.
44                   No real intelligence here, just keeps some ugliness out of sight.
45                 """
46                 isGz = tarname.endswith((".tar.gz", ".tgz"))
47                 isBz2 = tarname.endswith((".tar.bz2", ".tbz2"))
48                 if tarfile:
49                         return 'gz' if isGz else 'bz2' if isBz2 else ''
50                 else:
51                         return 'z' if isGz else 'j' if isBz2 else ''
52
53         def writeTarFile(self, destfile, filenames):
54                 """
55                   Create a new tar file, either with the tarfile library module or using popen.
56                 """
57                 compression = self.getCompressionMode(destfile)
58                 if tarfile:
59                         f = tarfile.open(destfile, 'w:%s' % compression)
60                         for sourcefile in filenames:
61                                 if path.exists(sourcefile):
62                                         f.add(sourcefile)
63                         f.close()
64                 else:
65                         tarFiles = ' '.join(filenames)
66                         lines = popen("tar cv%sf %s %s" % (compression, destfile, tarFiles)).readlines()
67                 return (True, destfile)
68
69         def backupFiles(self, filename):
70                 if not filename:
71                         filename = self.BACKUP_FILENAME
72                 invalidCharacters = re_compile(r'[^A-Za-z0-9_\. ]+|^\.|\.$|^ | $|^$')
73                 tarFilename = "%s.tar" % invalidCharacters.sub('_', filename)
74                 backupFilename = path.join(self.BACKUP_PATH, tarFilename)
75                 if path.exists(backupFilename):
76                         remove(backupFilename)
77
78                 return self.writeTarFile(backupFilename, backupdirs.value)
79
80         def unpackTarFile(self, filename, destination="/"):
81                 """
82                   Unpack existing tar file to destination folder.
83                 """
84                 compression = self.getCompressionMode(filename)
85                 if tarfile:
86                         f = tarfile.open(filename, 'r:%s' % compression)
87                         f.extractall(path=destination)
88                         f.close()
89                 else:
90                         lines = popen('tar xv%sf %s -C /' % (compression, filename)).readlines()
91                 return (True, "Backup was successfully restored")
92
93         def restoreFiles(self, filename):
94                 if not path.exists(filename):
95                         return (False, "Error, %s does not exists, restore is not possible..." % (backupFilename,))
96
97                 ret = self.unpackTarFile(filename)
98                 if ret[0]:
99                         remove(filename)
100                 return ret