Subversion Repositories basico

Rev

Rev 217 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
26 t00mlabs 1
#!/usr/bin/python
2
# -*- coding: utf-8 -*-
3
# File: utils.py
4
# Author: Tomás Vírseda
5
# License: GPL v3
6
# Description: Generic functions service
7
 
8
import os
32 t00mlabs 9
import sys
10
import subprocess
26 t00mlabs 11
import tarfile
12
import zipfile
53 t00mlabs 13
import shutil
26 t00mlabs 14
import urllib.request
15
import requests
40 t00mlabs 16
import webbrowser
38 t00mlabs 17
import feedparser
207 t00m 18
from datetime import datetime
38 t00mlabs 19
 
233 t00m 20
from basico.core.service import Service
26 t00mlabs 21
 
22
class Utils(Service):
23
    def initialize(self):
24
        self.uas = []
25
 
207 t00m 26
    def timestamp(self):
27
        now = datetime.now()
217 t00m 28
        timestamp = "%4d%02d%02d_%02d%02d%02d" % (now.year, now.month, now.day, now.hour, now.minute, now.second)
32 t00mlabs 29
 
207 t00m 30
        return timestamp
31
 
32
 
33
    def get_datetime(self, timestamp):
217 t00m 34
        adate = datetime.strptime(timestamp, "%Y%m%d_%H%M%S")
207 t00m 35
        return adate
36
 
37
 
233 t00m 38
    def get_human_date_from_timestamp(self, timestamp):
39
        adate = self.get_datetime(timestamp)
40
        return "%s" % adate.strftime("%A, %B %e, %Y at %H:%M")
41
 
42
 
207 t00m 43
    def fuzzy_date_from_timestamp(self, timestamp):
44
        # ~ date = self.get_datetime(timestamp)
45
        d1 = self.get_datetime(timestamp)
46
        d2 = datetime.now()
47
        rdate = d2 - d1 # DateTimeDelta
48
        if int(rdate.days) > 0:
49
            if (rdate.days >= 365):
50
                return "%d years ago" % int((rdate.days/365))
51
            else:
52
                return "%d days ago" % int(rdate.days)
53
 
54
        hours = rdate.seconds / 3600
55
        if int(hours) > 0:
56
            return "%d hours ago" % int(hours)
57
 
58
        minutes = rdate.seconds / 60
59
        if int(minutes) > 0:
60
            return "%d minutes ago" % int(minutes)
61
 
62
        if int(rdate.seconds) > 0:
63
            return "%d seconds ago" % int(rdate.seconds)
64
 
65
 
174 t00m 66
    def browse(self, url):
40 t00mlabs 67
        if sys.platform in ['linux', 'linux2']:
68
            browser = webbrowser.get('firefox')
69
        elif sys.platform == 'win32':
70
            browser = webbrowser.get('windows-default')
71
 
174 t00m 72
        browser.open_new_tab(url)
40 t00mlabs 73
 
74
 
32 t00mlabs 75
    def which(self, program):
36 t00mlabs 76
        if sys.platform == 'win32':
77
            program = program + '.exe'
78
 
32 t00mlabs 79
        def is_exe(fpath):
80
            return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
81
 
82
        fpath, fname = os.path.split(program)
83
        if fpath:
84
            if is_exe(program):
85
                return program
86
        else:
87
            for path in os.environ["PATH"].split(os.pathsep):
88
                path = path.strip('"')
89
                exe_file = os.path.join(path, program)
90
                if is_exe(exe_file):
91
                    return exe_file
92
 
93
        return None
94
 
26 t00mlabs 95
 
32 t00mlabs 96
    def install_geckodriver(self):
97
        """Get last version of Gecko webdriver from github"""
133 t00mlabs 98
        self.debug("OS Platform: %s" % sys.platform)
32 t00mlabs 99
        if sys.platform in ['linux', 'linux2']:
145 t00mlabs 100
            GECKO_SOURCE = "https://github.com/mozilla/geckodriver/releases/download/v0.23.0/geckodriver-v0.23.0-linux64.tar.gz"
36 t00mlabs 101
            GECKO_TARGET = self.get_var('TMP', scope='local') + 'gecko.tar.gz'
32 t00mlabs 102
        elif sys.platform == 'win32':
145 t00mlabs 103
            GECKO_SOURCE = "https://github.com/mozilla/geckodriver/releases/download/v0.23.0/geckodriver-v0.23.0-win64.zip"
36 t00mlabs 104
            GECKO_TARGET = self.get_var('TMP', scope='local') + 'gecko.zip'
32 t00mlabs 105
 
35 t00mlabs 106
        GECKO_INSTALL_DIR = self.get_var('DRIVERS', 'local')
32 t00mlabs 107
 
36 t00mlabs 108
 
32 t00mlabs 109
        if os.path.exists(GECKO_TARGET):
133 t00mlabs 110
            self.debug("Gecko webdriver already downloaded")
32 t00mlabs 111
            downloaded = True
112
        else:
113
            downloaded = self.download('Gecko', GECKO_SOURCE, GECKO_TARGET)
114
 
115
        if downloaded:
36 t00mlabs 116
            if sys.platform in ['linux', 'linux2']:
117
                extracted = self.extract(GECKO_TARGET, GECKO_INSTALL_DIR, 'tar.gz')
118
            elif sys.platform == 'win32':
119
                extracted = self.extract(GECKO_TARGET, GECKO_INSTALL_DIR, 'zip')
32 t00mlabs 120
            if extracted:
133 t00mlabs 121
                self.debug("Gecko webdriver deployed successfully")
32 t00mlabs 122
            else:
123
                self.log.error("Gecko could not be deployed")
124
                self.log.error("Tip: maybe %s is corrupt. Delete it" % GECKO_TARGET)
125
                #FIXME: stop application gracefully
126
                exit(-1)
127
 
128
 
28 t00mlabs 129
    def download(self, prgname, source, target):
26 t00mlabs 130
        try:
133 t00mlabs 131
            self.debug ("Downloading %s from: %s" % (prgname, source))
26 t00mlabs 132
            response = requests.get(source, stream=True)
133
            with open(target, 'wb') as out_file:
134
                shutil.copyfileobj(response.raw, out_file)
135
            del response
133 t00mlabs 136
            self.debug ("%s downloaded to %s" % (prgname, target))
26 t00mlabs 137
            return True
138
        except Exception as error:
139
            self.log.error(error)
140
            return False
141
 
28 t00mlabs 142
 
26 t00mlabs 143
    def extract(self, filename, target_path, protocol):
133 t00mlabs 144
        self.debug("Extracting %s to %s using protocol %s" % (filename, target_path, protocol))
32 t00mlabs 145
        if protocol in ['tar.gz', 'bz2']:
146
            try:
147
                tar = tarfile.open(filename, "r:*")
148
                tar.extractall(target_path)
149
                tar.close()
133 t00mlabs 150
                self.debug("Extracted successfully")
32 t00mlabs 151
                return True
152
            except Exception as error:
153
                self.log.error(error)
154
                return False
155
        elif protocol == 'zip':
156
            try:
157
                self.unzip(filename, target_path)
133 t00mlabs 158
                self.debug("Extracted successfully")
32 t00mlabs 159
                return True
160
            except Exception as error:
161
                self.log.error(error)
162
                return False
26 t00mlabs 163
 
53 t00mlabs 164
    def zip(self, filename, directory):
165
        # http://stackoverflow.com/a/25650295
57 t00mlabs 166
        #~ make_archive(archive_name, 'gztar', root_dir)
167
        res = shutil.make_archive(filename, 'gztar', directory)
133 t00mlabs 168
        self.debug("%s - %s" % (filename, directory))
169
        self.debug("zip res: %s" % res)
26 t00mlabs 170
 
53 t00mlabs 171
 
26 t00mlabs 172
    def unzip(self, target, install_dir):
173
        zip_archive = zipfile.ZipFile(target, "r")
174
        zip_archive.extractall(path=install_dir)
175
        zip_archive.close()
176
 
177
 
36 t00mlabs 178
    def get_firefox_profile_dir(self):
179
        if sys.platform in ['linux', 'linux2']:
180
            cmd = "ls -d /home/$USER/.mozilla/firefox/*.default/"
181
            p = subprocess.Popen([cmd], shell=True, stdout=subprocess.PIPE)
182
            FF_PRF_DIR = p.communicate()[0][0:-2]
37 t00mlabs 183
            FF_PRF_DIR_DEFAULT = str(FF_PRF_DIR,'utf-8')
36 t00mlabs 184
        elif sys.platform == 'win32':
185
            import glob
186
            APPDATA = os.getenv('APPDATA')
187
            FF_PRF_DIR = "%s\\Mozilla\\Firefox\\Profiles\\" % APPDATA
188
            PATTERN = FF_PRF_DIR + "*default*"
189
            FF_PRF_DIR_DEFAULT = glob.glob(PATTERN)[0]
26 t00mlabs 190
 
37 t00mlabs 191
        return FF_PRF_DIR_DEFAULT
26 t00mlabs 192
 
193
 
38 t00mlabs 194
    def feedparser_parse(self, thing):
195
        try:
196
            return feedparser.parse(thing)
197
        except TypeError:
198
            if 'drv_libxml2' in feedparser.PREFERRED_XML_PARSERS:
199
                feedparser.PREFERRED_XML_PARSERS.remove('drv_libxml2')
200
                return feedparser.parse(thing)
201
            else:
202
                self.log.error(self.get_traceback())
203
                return None