Subversion Repositories basico

Rev

Rev 14 | 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
8
import sys
9
import traceback as tb
10
import imp
11
import signal
12
from os.path import abspath, sep as SEP
13
from configparser import SafeConfigParser, ExtendedInterpolation
14
 
15 t00mlabs 15
import gi
16
gi.require_version('Gtk', '3.0')
17
from gi.repository import Gtk
4 t00mlabs 18
 
19
from .log import get_logger
20
from .gui import GUI
21
from .iconmanager import IconManager
22
from .sap import SAP
23
from .settings import Settings
24
from .uifuncs import UIFuncs
25
from .menus import Menus
26
from .projects import Projects
27
from .tasks import Tasks
28
from .plugins import Plugins
29
from .callbacks import Callback
30
from .notify import Notification
31
from .stats import Stats
32
from .env import ROOT, APP, LPATH, GPATH, FILE
33
 
34
 
35
class Basico:
36
    def __init__(self):
37
        """Main class: the entry point for Basico.
38
        It stands for Controller.
39
        """
40
        self.__set_env()
41
        self.log = get_logger(self.__class__.__name__, FILE['LOG'])
42
        self.log.info("Starting Basico")
43
        self.__init_config()
44
        self.services = {}
45
        try:
46
            services = {
47
                'GUI'       :   GUI(),
48
                'UIF'       :   UIFuncs(),
49
                'Menus'     :   Menus(),
50
                'SAP'       :   SAP(),
51
                'Settings'  :   Settings(),
52
                'Notify'    :   Notification(),
53
                'Tasks'     :   Tasks(),
54
                'IM'        :   IconManager(),
55
                'Plugins'   :   Plugins(),
56
                'Callbacks' :   Callback(),
57
                'Stats'     :   Stats(),
58
            }
59
            self.register_services(services)
60
        except Exception as error:
61
            self.log.error(error)
62
            raise
63
 
64
 
65
    def __set_env(self):
66
        # Create local paths if they do not exist
67
        for DIR in LPATH:
68
            if not os.path.exists(LPATH[DIR]):
69
                os.makedirs(LPATH[DIR])
70
 
71
 
72
    def __init_config(self):
73
        #~ self.log.debug("ROOT: %s" % ROOT)
74
        # Set up config
75
        CONFIG_FILE = self.get_file('CNF')
76
 
77
        #~ https://docs.python.org/3/library/configparser.html#interpolation-of-values
78
        self.config = SafeConfigParser(interpolation=ExtendedInterpolation())
79
 
80
        #~ https://docs.python.org/3/library/configparser.html#configparser.ConfigParser.optionxform
81
        self.config.optionxform = str
82
 
83
        # Save config
84
        if not os.path.exists(CONFIG_FILE):
85
            self.log.debug('Configuration file not found. Creating a new one')
86
            with open(CONFIG_FILE, 'w') as configfile:
87
                self.config.write(configfile)
88
            self.log.info('Config file initialited')
89
 
90
 
91
    def get_config(self):
92
        CONFIG_FILE = self.get_file('CNF')
93
        self.config.read(CONFIG_FILE)
94
 
95
        return self.config
96
 
97
 
98
    def get_file(self, name):
99
        try:
100
            return FILE[name]
101
        except:
102
            self.log.error(self.get_traceback())
103
 
104
 
105
    def get_app_info(self, var):
106
        try:
107
            return APP[var]
108
        except:
109
            return None
110
 
111
 
112
    def get_var(self, name, scope='global'):
113
        if scope == 'global':
114
            return GPATH[name]
115
        else:
116
            return LPATH[name]
117
 
118
 
119
    def list_services(self):
120
        """Return a dictionary of services"""
121
        return self.services
122
 
123
 
124
    def get_service(self, name):
125
        """Get/Start a registered service
126
        @type name: name of the service
127
        @param name: given a service name it returns the associated
128
        class. If service was not running it is started.
129
        """
130
        try:
131
            service = self.services[name]
132
            if service.is_started():
133
                return service
134
            else:
135
                service.start(self, name)
136
                return service
137
        except KeyError as service:
138
            self.log.error("Service %s not registered or not found" % service)
139
            raise
140
 
141
    def register_services(self, services):
142
        """Register a list of services
143
        @type services: dict
144
        @param services: a dictionary of name:class for each service
145
        """
146
        for name in services:
147
            self.register_service(name, services[name])
148
 
149
 
150
    def register_service(self, name, service):
151
        """Register a new service
152
        @type name: string
153
        @param name: name of the service
154
        @type service: class
155
        @param service: class which contains the code
156
        """
157
        try:
158
            self.services[name] = service
159
            #~ self.log.debug("Service '%s' loaded successfully" % name)
160
        except Exception as error:
161
            self.log.error(error)
162
 
163
 
164
    def deregister_service(self, name):
165
        """Deregister a running service
166
        @type name: string
167
        @param name: name of the service
168
        """
169
        self.services[name].end()
170
        self.services[name] = None
171
 
172
 
15 t00mlabs 173
    def check_gtk_version(self):
174
        vmajor = Gtk.get_major_version()
175
        vminor = Gtk.get_minor_version()
176
        vmicro = Gtk.get_micro_version()
177
        self.log.info("Found GTK+ Version: %d.%d.%d" % (vmajor, vminor, vmicro))
178
 
179
        if vmajor == 3 and vminor >= 18:
180
            return True
181
        else:
182
            return False
183
 
4 t00mlabs 184
    def check(self):
15 t00mlabs 185
        GTK_VERSION = self.check_gtk_version()
4 t00mlabs 186
 
15 t00mlabs 187
        if GTK_VERSION:
188
            self.log.debug("GTK+ version supported")
189
            run = True
190
        else:
191
            self.log.error("Please, install a modern version of GTK+ (>= 3.18)")
192
            run = False
4 t00mlabs 193
 
15 t00mlabs 194
        return run
195
        #~ sap = self.get_service('SAP')
196
        #~ found = sap.check_webdriver()
197
        #~ if not found:
198
            #~ self.log.error("No webdriver found. Exiting.")
199
        #~ return found
200
 
201
 
4 t00mlabs 202
    def stop(self):
203
        """For each service registered, it executes the 'end' method
204
        (if any) to finalize them properly.
205
        """
206
 
207
        # Deregister all services loaded
208
        self.deregister_service('GUI')
209
 
210
        for name in self.services:
211
            try:
212
                self.deregister_service(name)
213
            except: pass
214
        # Bye bye
215
        self.log.info("Basico finished")
216
 
217
 
218
    def get_traceback(self):
219
        return tb.format_exc()
220
 
221
 
222
    def run(self):
223
        try:
224
            self.gui = self.get_service('GUI')
225
            #~ self.log.debug("Basico ready to start")
226
            self.gui.run()
227
        except:
228
            self.log.error(self.get_traceback())
229
 
230
 
231
def main():
232
    #DOC: http://stackoverflow.com/questions/16410852/keyboard-interrupt-with-with-python-gtk
233
    signal.signal(signal.SIGINT, signal.SIG_DFL)
234
    basico = Basico()
15 t00mlabs 235
    run = basico.check()
4 t00mlabs 236
    if run:
237
        basico.run()
238
    sys.exit(0)