Subversion Repositories basico

Rev

Rev 353 | Rev 356 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
340 t00mlabs 1
#!/usr/bin/python
2
# -*- coding: utf-8 -*-
3
"""
4
# File: srv_utils.py
5
# Author: Tomás Vírseda
6
# License: GPL v3
7
# Description: Generic functions service
8
"""
9
 
10
import os
11
import re
12
import sys
355 t00mlabs 13
import json
340 t00mlabs 14
import subprocess
15
import tarfile
16
import zipfile
17
import shutil
18
import requests
19
import webbrowser
20
import feedparser
21
from datetime import datetime
355 t00mlabs 22
from basico.core.mod_env import GPATH, LPATH, FILE
340 t00mlabs 23
from basico.core.mod_srv import Service
24
 
25
class Utils(Service):
26
    """
27
    Missing class docstring (missing-docstring)
28
    """
29
 
30
    def initialize(self):
31
        """
32
        Missing method docstring (missing-docstring)
33
        """
34
        self.get_services()
355 t00mlabs 35
        self.load_extensions()
340 t00mlabs 36
 
37
 
355 t00mlabs 38
    def load_extensions(self):
39
        with open(FILE['EXT'], 'r') as fext:
40
            self.extensions = json.load(fext)
41
            self.log.debug("%d extensions loaded", len(self.extensions))
42
 
43
 
340 t00mlabs 44
    def get_services(self):
45
        """
46
        Missing method docstring (missing-docstring)
47
        """
48
        self.srvdtb = self.get_service('DB')
49
 
50
 
355 t00mlabs 51
    def get_file_description(self, ext):
52
        try:
53
            filetype, description = self.extensions[ext]
54
            return description
55
        except:
56
            return None
57
 
58
 
353 t00mlabs 59
    def get_disk_usage(self, path):
60
        """
61
        Get disk usage for a given path
62
        """
63
        return shutil.disk_usage(path)
64
 
65
 
66
    def get_disk_usage_fraction(self, path):
67
        """
68
        Get disk usage as a fraction for using with Gtk.Progressbar)
69
        """
70
        total, used, free = self.get_disk_usage(path)
71
        return used/total
72
 
73
    def get_disk_usage_human(self, path):
74
        """
75
        Get disk usage as a fraction for using with Gtk.Progressbar)
76
        Some bytes borrowed from:
77
        https://github.com/juancarlospaco/anglerfish/blob/master/anglerfish/bytes2human.py
78
        """
79
        def get_kilobytes(integer_bytes):
80
            kilo, bites = divmod(int(abs(integer_bytes)), 1_024)
81
            # ~ self.log.debug("%d bytes -> %d Kb", integer_bytes, kilo)
82
            return kilo
83
 
84
        def get_megabytes(integer_bytes):
85
            kilo = get_kilobytes(integer_bytes)
86
            mega, kilo = divmod(kilo, 1_024)
87
            # ~ self.log.debug("%d bytes -> %d Mb", integer_bytes, mega)
88
            return mega
89
 
90
        def get_gigabytes(integer_bytes):
91
            mega = get_megabytes(integer_bytes)
92
            giga, mega = divmod(mega, 1_024)
93
            # ~ self.log.debug("%d bytes -> %d Gb", integer_bytes, giga)
94
            return giga
95
 
96
        total, used, free = self.get_disk_usage(path)
97
        tgb = get_gigabytes(total)
98
        ugb = get_gigabytes(used)
99
        fgb = get_gigabytes(total-used)
100
        humansize = "Using %dGb of %dGb (Free space: %dGb)" % (int(ugb), int(tgb), int(fgb))
101
        return humansize
102
 
340 t00mlabs 103
    def timestamp(self):
104
        """
105
        Missing method docstring (missing-docstring)
106
        """
107
        now = datetime.now()
108
        timestamp = "%4d%02d%02d_%02d%02d%02d" % (now.year, now.month, now.day, now.hour, now.minute, now.second)
109
 
110
        return timestamp
111
 
112
 
113
    def get_datetime(self, timestamp):
114
        """
115
        Missing method docstring (missing-docstring)
116
        """
117
        adate = datetime.strptime(timestamp, "%Y%m%d_%H%M%S")
118
        return adate
119
 
120
 
121
    def get_human_date_from_timestamp(self, timestamp=None):
122
        """
123
        Missing method docstring (missing-docstring)
124
        """
125
        if timestamp is None:
126
            timestamp = self.timestamp()
127
 
128
        adate = self.get_datetime(timestamp)
129
        return "%s" % adate.strftime("%Y/%m/%d %H:%M")
130
 
131
 
132
    def get_excel_date(self, timestamp):
133
        timestamp = timestamp.replace('-', '/')        
134
        timestamp = timestamp.replace('T', ' ')
135
        adate = datetime.strptime(timestamp, "%Y/%m/%d %H:%M:%S")
136
        excel_date = "%s" % adate.strftime("%d/%m/%Y")
137
        return excel_date
138
 
139
 
140
    def fuzzy_date_from_timestamp(self, timestamp):
141
        """
142
        Missing method docstring (missing-docstring)
143
        """
144
        d1 = self.get_datetime(timestamp)
145
        d2 = datetime.now()
146
        rdate = d2 - d1 # DateTimeDelta
147
        if rdate.days > 0:
148
            if rdate.days <= 31:
149
                return "%d days ago" % int(rdate.days)
150
 
151
            if rdate.days > 31 and rdate.days < 365:
152
                return "%d months ago" % int((rdate.days/31))
153
 
154
            if rdate.days >= 365:
155
                return "%d years ago" % int((rdate.days/365))
156
 
157
        hours = rdate.seconds / 3600
158
        if int(hours) > 0:
159
            return "%d hours ago" % int(hours)
160
 
161
        minutes = rdate.seconds / 60
162
        if int(minutes) > 0:
163
            return "%d minutes ago" % int(minutes)
164
 
165
        if int(rdate.seconds) > 0:
166
            return "%d seconds ago" % int(rdate.seconds)
167
 
168
        if int(rdate.seconds) == 0:
169
            return "Right now"
170
 
171
 
172
    def browse(self, url):
173
        """
174
        Missing method docstring (missing-docstring)
175
        """
176
        if sys.platform in ['linux', 'linux2']:
177
            browser = webbrowser.get('firefox')
178
        elif sys.platform == 'win32':
179
            browser = webbrowser.get('windows-default')
180
 
181
        browser.open_new_tab(url)
182
 
183
 
184
    def which(self, program):
185
        """
186
        Missing method docstring (missing-docstring)
187
        """
188
        if sys.platform == 'win32':
189
            program = program + '.exe'
190
 
191
        def is_exe(fpath):
192
            """
193
            Missing method docstring (missing-docstring)
194
            """
195
            return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
196
 
197
        fpath, fname = os.path.split(program)
198
        if fpath:
199
            if is_exe(program):
200
                return program
201
        else:
202
            for path in os.environ["PATH"].split(os.pathsep):
203
                path = path.strip('"')
204
                exe_file = os.path.join(path, program)
205
                if is_exe(exe_file):
206
                    return exe_file
207
 
208
        return None
209
 
210
 
211
    def install_geckodriver(self):
212
        """
213
        Install Gecko Driver
214
        """
215
        GECKODRIVER_LINUX = GPATH['DRIVERS'] + 'geckodriver'
216
        GECKODRIVER_WIN32 = GPATH['DRIVERS'] + 'geckodriver.exe'
217
        GECKO_INSTALL_DIR = LPATH['DRIVERS']
218
 
219
        if sys.platform == 'linux':
220
            shutil.copy(GECKODRIVER_LINUX, GECKO_INSTALL_DIR)
221
        else:
222
            shutil.copy(GECKODRIVER_WIN32, GECKO_INSTALL_DIR)
223
        self.log.debug("Gecko driver installed to %s" % GECKO_INSTALL_DIR)
224
 
225
 
226
    def download(self, prgname, source, target):
227
        """
228
        Missing method docstring (missing-docstring)
229
        """
230
        try:
231
            self.log.debug("Downloading %s from: %s" % (prgname, source))
232
            response = requests.get(source, stream=True)
233
            with open(target, 'wb') as out_file:
234
                shutil.copyfileobj(response.raw, out_file)
235
            del response
236
            self.log.debug("%s downloaded to %s" % (prgname, target))
237
            return True
238
        except Exception as error:
239
            self.log.error(error)
240
            return False
241
 
242
 
243
    def extract(self, filename, target_path, protocol):
244
        """
245
        Missing method docstring (missing-docstring)
246
        """
247
        self.log.debug("Extracting %s to %s using protocol %s" % (filename, target_path, protocol))
248
        if protocol in ['tar.gz', 'bz2']:
249
            try:
250
                tar = tarfile.open(filename, "r:*")
251
                tar.extractall(target_path)
252
                tar.close()
253
                self.log.debug("Extracted successfully")
254
                return True
255
            except Exception as error:
256
                self.log.error(error)
257
                return False
258
        elif protocol == 'zip':
259
            try:
260
                self.unzip(filename, target_path)
261
                self.log.debug("Extracted successfully")
262
                return True
263
            except Exception as error:
264
                self.log.error(error)
265
                return False
266
 
267
    def zip(self, filename, directory):
268
        """
269
        Zip directory and rename to .bco
270
        """
271
        # http://stackoverflow.com/a/25650295
272
        #~ make_archive(archive_name, 'gztar', root_dir)
273
        self.log.debug("Target: %s", filename)
274
        sourcename = os.path.basename(filename)
275
        dot = sourcename.find('.')
276
        if dot == -1:
277
            basename = sourcename
278
        else:
279
            basename = sourcename[:dot]
280
        sourcedir = os.path.dirname(filename)
281
        source = os.path.join(sourcedir, basename)
282
        zipfile = shutil.make_archive(source, 'zip', directory)
283
        target = source + '.bco'
284
        shutil.move(zipfile, target)
285
        return target
286
 
287
 
288
    def unzip(self, target, install_dir):
289
        """
290
        Unzip file to a given dir
291
        """
292
        zip_archive = zipfile.ZipFile(target, "r")
293
        zip_archive.extractall(path=install_dir)
294
        zip_archive.close()
295
 
296
 
297
    def get_firefox_profile_dir(self):
298
        """
299
        Self-explained. Get default Firefox directory
300
        """
301
        if sys.platform in ['linux', 'linux2']:
302
            cmd = "ls -d /home/$USER/.mozilla/firefox/*.default/"
303
            p = subprocess.Popen([cmd], shell=True, stdout=subprocess.PIPE)
304
            FF_PRF_DIR = p.communicate()[0][0:-2]
305
            FF_PRF_DIR_DEFAULT = str(FF_PRF_DIR, 'utf-8')
306
        elif sys.platform == 'win32':
307
            import glob
308
            APPDATA = os.getenv('APPDATA')
309
            FF_PRF_DIR = "%s\\Mozilla\\Firefox\\Profiles\\" % APPDATA
310
            PATTERN = FF_PRF_DIR + "*default*"
311
            FF_PRF_DIR_DEFAULT = glob.glob(PATTERN)[0]
312
 
313
        return FF_PRF_DIR_DEFAULT
314
 
315
 
316
    def feedparser_parse(self, thing):
317
        """
318
        Missing method docstring (missing-docstring)
319
        """
320
        try:
321
            return feedparser.parse(thing)
322
        except TypeError:
323
            if 'drv_libxml2' in feedparser.PREFERRED_XML_PARSERS:
324
                feedparser.PREFERRED_XML_PARSERS.remove('drv_libxml2')
325
                return feedparser.parse(thing)
326
            else:
327
                self.log.error(self.get_traceback())
328
                return None
329
 
330
 
331
    def check(self):
332
        """
333
        Check Basico environment
334
        """
335
        gtk_version = self.uif.check_gtk_version() # Check GTK version
336
        gecko_driver = self.driver.check() # Check Gecko webdrver
337
        run = gtk_version and gecko_driver
338
        if run:
339
            self.log.debug("Basico environment ready!")
340
        else:
341
            self.log.error("Error(s) found checking Basico environment")
342
 
343
        return run
344
 
345
 
346
 
347
 
348
    def clean_html(self, raw_html):
349
        cleanr = re.compile('<.*?>')
350
        cleantext = re.sub(cleanr, '', raw_html)
351
        return cleantext