Subversion Repositories basico

Rev

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

Rev Author Line No. Line
4 t00mlabs 1
#!/usr/bin/python3
2
# -*- coding: utf-8 -*-
3
# File: basico.py
4
# Author: Tomás Vírseda
5
# License: GPL v3
6
# Description: Main entry point por Basico app
7
import os
74 t00mlabs 8
# -*- coding: utf-8 -*-
4 t00mlabs 9
import sys
74 t00mlabs 10
import codecs
11
sys.stdout = codecs.getwriter("iso-8859-1")(sys.stdout, 'xmlcharrefreplace')
4 t00mlabs 12
import traceback as tb
13
import imp
14
import signal
74 t00mlabs 15
from pprint import pprint
4 t00mlabs 16
from os.path import abspath, sep as SEP
17
from configparser import SafeConfigParser, ExtendedInterpolation
126 t00mlabs 18
from datetime import datetime
4 t00mlabs 19
 
74 t00mlabs 20
import selenium
21
 
16 t00mlabs 22
import gi
23
gi.require_version('Gtk', '3.0')
24
from gi.repository import Gtk
4 t00mlabs 25
 
233 t00m 26
from basico.core.utils import Utils
27
from basico.core.log import get_logger
28
from basico.core.gui import GUI
29
from basico.core.iconmanager import IconManager
30
from basico.core.sap import SAP
31
from basico.core.settings import Settings
32
from basico.core.uifuncs import UIFuncs
33
from basico.core.callbacks import Callback
34
from basico.core.notify import Notification
35
from basico.core.database import Database
36
from basico.core.driver import SeleniumDriver
37
from basico.core.collections import Collections
38
from basico.core.annotations import Annotation
39
from basico.core.env import ROOT, APP, LPATH, GPATH, FILE, STATS
4 t00mlabs 40
 
41
 
132 t00mlabs 42
class Basico(object):
4 t00mlabs 43
    def __init__(self):
44
        """Main class: the entry point for Basico.
45
        It stands for Controller.
46
        """
126 t00mlabs 47
        STATS['BASICO_STARTUP_START'] = datetime.now()
74 t00mlabs 48
 
49
        # Create local paths if they do not exist
50
        for entry in LPATH:
51
            if not os.path.exists(LPATH[entry]):
52
                os.makedirs(LPATH[entry])
53
 
150 t00m 54
        # Truncate existing log file
55
        if os.path.exists(FILE['LOG']):
56
            flog = open(FILE['LOG'], 'w')
57
            flog.close()
74 t00mlabs 58
 
150 t00m 59
        # Create logger
4 t00mlabs 60
        self.log = get_logger(self.__class__.__name__, FILE['LOG'])
133 t00mlabs 61
        self.debug("Starting Basico")
74 t00mlabs 62
 
4 t00mlabs 63
        self.services = {}
64
        try:
65
            services = {
229 t00m 66
                'GUI'           :   GUI(),
67
                'Utils'         :   Utils(),
68
                'UIF'           :   UIFuncs(),
69
                'SAP'           :   SAP(),
70
                'Settings'      :   Settings(),
71
                'Notify'        :   Notification(),
72
                'IM'            :   IconManager(),
73
                'Callbacks'     :   Callback(),
74
                'DB'            :   Database(),
75
                'Driver'        :   SeleniumDriver(),
76
                'Collections'   :   Collections(),
77
                'Annotation'    :   Annotation()
4 t00mlabs 78
            }
79
            self.register_services(services)
80
        except Exception as error:
81
            self.log.error(error)
82
            raise
83
 
133 t00mlabs 84
    def debug(self, message):
141 t00mlabs 85
        self.log.debug("%18s | %s" % (self.__class__.__name__, message))
4 t00mlabs 86
 
74 t00mlabs 87
    def setup(self):
88
        """
89
        Setup Basico Envrionment
90
        Info about ConfigParser options:
91
        https://docs.python.org/3/library/configparser.html#interpolation-of-values
92
        https://docs.python.org/3/library/configparser.html#configparser.ConfigParser.optionxform
93
        """
133 t00mlabs 94
        self.debug("Setting up Basico environment")
95
        self.debug("Global path: %s" % GPATH['ROOT'])
96
        self.debug("Local path: %s" % LPATH['ROOT'])
4 t00mlabs 97
 
98
 
99
    def get_file(self, name):
100
        try:
101
            return FILE[name]
102
        except:
103
            self.log.error(self.get_traceback())
104
 
105
 
106
    def get_app_info(self, var):
107
        try:
108
            return APP[var]
109
        except:
110
            return None
111
 
112
 
113
    def get_var(self, name, scope='global'):
114
        if scope == 'global':
115
            return GPATH[name]
116
        else:
117
            return LPATH[name]
118
 
119
 
120
    def list_services(self):
121
        """Return a dictionary of services"""
122
        return self.services
123
 
124
 
125
    def get_service(self, name):
126
        """Get/Start a registered service
127
        @type name: name of the service
128
        @param name: given a service name it returns the associated
129
        class. If service was not running it is started.
130
        """
131
        try:
132
            service = self.services[name]
133
            if service.is_started():
134
                return service
135
            else:
136
                service.start(self, name)
137
                return service
138
        except KeyError as service:
139
            self.log.error("Service %s not registered or not found" % service)
140
            raise
141
 
74 t00mlabs 142
 
4 t00mlabs 143
    def register_services(self, services):
144
        """Register a list of services
145
        @type services: dict
146
        @param services: a dictionary of name:class for each service
147
        """
148
        for name in services:
149
            self.register_service(name, services[name])
150
 
151
 
152
    def register_service(self, name, service):
153
        """Register a new service
154
        @type name: string
155
        @param name: name of the service
156
        @type service: class
157
        @param service: class which contains the code
158
        """
159
        try:
160
            self.services[name] = service
161
        except Exception as error:
162
            self.log.error(error)
163
 
164
 
165
    def deregister_service(self, name):
166
        """Deregister a running service
167
        @type name: string
168
        @param name: name of the service
169
        """
170
        self.services[name].end()
171
        self.services[name] = None
133 t00mlabs 172
        self.debug("Service %s stopped" % name)
4 t00mlabs 173
 
174
 
16 t00mlabs 175
    def check_gtk_version(self):
176
        vmajor = Gtk.get_major_version()
177
        vminor = Gtk.get_minor_version()
178
        vmicro = Gtk.get_micro_version()
133 t00mlabs 179
        self.debug("Found GTK+ Version: %d.%d.%d" % (vmajor, vminor, vmicro))
16 t00mlabs 180
 
181
        if vmajor == 3 and vminor >= 18:
182
            return True
183
        else:
184
            return False
185
 
4 t00mlabs 186
    def check(self):
74 t00mlabs 187
        '''
188
        Check Basico environment
189
        '''
190
        utils = self.get_service("Utils")
191
        uif = self.get_service('UIF')
192
        driver = self.get_service('Driver')
4 t00mlabs 193
 
74 t00mlabs 194
        # Show Selenium version
133 t00mlabs 195
        self.debug("Selenium version: %s" % selenium.__version__)
74 t00mlabs 196
 
197
        # Check proper GTK version
198
        GTK_VERSION = uif.check_gtk_version()
199
 
200
        # Check Gecko webdrver
201
        GECKO_DRIVER = driver.check()
202
 
203
        run = GTK_VERSION and GECKO_DRIVER
204
 
205
        if run:
133 t00mlabs 206
            self.debug("Basico environment ready!")
74 t00mlabs 207
            return True
16 t00mlabs 208
        else:
74 t00mlabs 209
            self.log.error("Error(s) found checking Basico environment")
210
            return False
4 t00mlabs 211
 
16 t00mlabs 212
 
213
 
74 t00mlabs 214
 
4 t00mlabs 215
    def stop(self):
216
        """For each service registered, it executes the 'end' method
217
        (if any) to finalize them properly.
218
        """
219
 
220
        # Deregister all services loaded
221
        self.deregister_service('GUI')
222
        for name in self.services:
223
            try:
74 t00mlabs 224
                if name != 'GUI':
225
                    self.deregister_service(name)
226
            except Exception as error:
227
                self.log.error(self.get_traceback())
228
                raise
229
 
133 t00mlabs 230
        self.debug("Basico finished")
4 t00mlabs 231
 
232
 
233
    def get_traceback(self):
234
        return tb.format_exc()
235
 
236
 
237
    def run(self):
238
        try:
239
            self.gui = self.get_service('GUI')
240
            self.gui.run()
137 t00mlabs 241
        except Exception as error:
242
            self.debug(error)
4 t00mlabs 243
 
244
 
245
def main():
246
    #DOC: http://stackoverflow.com/questions/16410852/keyboard-interrupt-with-with-python-gtk
247
    signal.signal(signal.SIGINT, signal.SIG_DFL)
248
    basico = Basico()
74 t00mlabs 249
    basico.setup()
250
    ok = basico.check()
251
    if ok:
4 t00mlabs 252
        basico.run()
253
    sys.exit(0)