a b/rdpl2stream/RadioTray.py
1
##########################################################################
2
# Copyright 2009 Carlos Ribeiro
3
#
4
# This file is part of Radio Tray
5
#
6
# Radio Tray is free software: you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation, either version 1 of the License, or
9
# (at your option) any later version.
10
#
11
# Radio Tray is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
# GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with Radio Tray.  If not, see <http://www.gnu.org/licenses/>.
18
#
19
##########################################################################
20
from XmlDataProvider import XmlDataProvider
21
from XmlConfigProvider import XmlConfigProvider
22
from AudioPlayerGStreamer import AudioPlayerGStreamer
23
from SysTray import SysTray
24
from StateMediator import StateMediator
25
from NotificationManager import NotificationManager
26
from events.EventManager import EventManager
27
from events.EventMngNotificationWrapper import EventMngNotificationWrapper
28
from events.EventSubscriber import EventSubscriber
29
from DbusFacade import DbusFacade
30
from TooltipManager import TooltipManager
31
from PluginManager import PluginManager
32
import os
33
from shutil import move, copy2
34
from lib.common import APPDIRNAME, USER_CFG_PATH, CFG_NAME, OLD_USER_CFG_PATH,\
35
    DEFAULT_RADIO_LIST, OPTIONS_CFG_NAME, DEFAULT_CONFIG_FILE,\
36
    USER_PLUGIN_PATH, LOGFILE
37
import mpris
38
from GuiChooserConfiguration import GuiChooserConfiguration
39
import logging
40
from logging import handlers
41
42
class RadioTray(object):
43
44
    def __init__(self, url=None):
45
        
46
        self.loadConfiguration()
47
        
48
        self.logger.info('Starting Radio Tray...')
49
50
        # load configuration
51
        
52
        # load bookmarks data provider and initializes it
53
        self.provider = XmlDataProvider(self.filename)
54
        self.provider.loadFromFile()
55
56
        # load config data provider and initializes it
57
        self.cfg_provider = XmlConfigProvider(self.cfg_filename)
58
        self.cfg_provider.loadFromFile()
59
60
        # load default config data provider and initializes it
61
        self.default_cfg_provider = XmlConfigProvider(self.default_cfg_filename)
62
        self.default_cfg_provider.loadFromFile()
63
64
        # load Event Manager
65
        eventManager = EventManager()
66
        eventManagerWrapper = EventMngNotificationWrapper(eventManager)
67
68
        # mediator
69
        self.mediator = StateMediator(self.provider, self.cfg_provider, eventManager)
70
71
        # load audio player
72
        self.audio = AudioPlayerGStreamer(self.mediator, self.cfg_provider, eventManager)
73
74
        # tooltip manager
75
        tooltipManager = TooltipManager()
76
77
        # chooser
78
        if(url == '--config'):
79
            chooser = GuiChooserConfiguration()
80
            gui_engine = chooser.run()
81
            self.cfg_provider.setConfigValue("gui_engine", gui_engine)
82
            url = None
83
        # load gui
84
        self.systray = SysTray(self.mediator, self.provider, self.cfg_provider, self.default_cfg_provider, eventManager, tooltipManager)
85
        
86
        
87
        
88
        # notification manager
89
        self.notifManager = NotificationManager(eventManagerWrapper)
90
91
        # bind events
92
        eventSubscriber = EventSubscriber(eventManager)
93
        eventSubscriber.bind(EventManager.STATE_CHANGED, self.mediator.on_state_changed)
94
        eventSubscriber.bind(EventManager.STATE_CHANGED, self.systray.on_state_changed)
95
        eventSubscriber.bind(EventManager.STATE_CHANGED, self.notifManager.on_state_changed)
96
        eventSubscriber.bind(EventManager.SONG_CHANGED, self.notifManager.on_song_changed)
97
        eventSubscriber.bind(EventManager.SONG_CHANGED, self.mediator.on_song_changed)
98
        eventSubscriber.bind(EventManager.SONG_CHANGED, self.systray.on_song_changed)
99
        eventSubscriber.bind(EventManager.STATION_ERROR, self.notifManager.on_station_error)
100
        eventSubscriber.bind(EventManager.VOLUME_CHANGED, self.systray.on_volume_changed)
101
        eventSubscriber.bind(EventManager.BOOKMARKS_RELOADED, self.notifManager.on_bookmarks_reloaded)
102
103
        # config mediator
104
        self.mediator.init(self.audio)
105
106
107
        # start dbus facade
108
        dbus = DbusFacade(self.provider, self.mediator)
109
        #dbus_mpris = mpris.RadioTrayMpris(self.provider, self.mediator)
110
111
  #load plugin manager
112
        self.pluginManager = PluginManager(eventManagerWrapper, eventSubscriber, self.provider, self.cfg_provider, self.mediator, tooltipManager, self.systray.getPluginMenu())
113
        self.systray.setPluginManager(self.pluginManager)
114
        self.pluginManager.discoverPlugins()
115
        self.pluginManager.activatePlugins()
116
117
        if(url != None):
118
            if (url == "--resume"):
119
                self.mediator.playLast()                
120
            else:
121
                self.mediator.playUrl(url)
122
        # start app
123
        self.systray.run()
124
125
126
    def loadConfiguration(self):
127
128
        if not os.path.exists(USER_CFG_PATH):
129
            #self.logger.info("user's directory created")
130
            os.mkdir(USER_CFG_PATH)
131
            
132
        if not os.path.exists(USER_PLUGIN_PATH):
133
            os.mkdir(USER_PLUGIN_PATH)
134
        
135
        self.configLogging()
136
        
137
        self.logger.debug("Loading configuration...")
138
        
139
        self.filename = os.path.join(USER_CFG_PATH, CFG_NAME)
140
141
        self.cfg_filename = os.path.join(USER_CFG_PATH, OPTIONS_CFG_NAME)
142
143
        self.default_cfg_filename = DEFAULT_CONFIG_FILE
144
145
        if not os.access(self.filename, os.F_OK): # If bookmarks file doesn't exist
146
147
            self.logger.warn('bookmarks file could not be found. Using default...')
148
149
            #check if it exists an old bookmark file, and then move it to the new location
150
            oldfilename = os.path.join(OLD_USER_CFG_PATH, CFG_NAME)
151
            if os.access(oldfilename, os.R_OK|os.W_OK):
152
153
                self.logger.info('Found old bookmark configuration and moved it to new location: %s', USER_CFG_PATH)
154
                move(oldfilename, self.filename)
155
                os.rmdir(OLD_USER_CFG_PATH)
156
157
            else:
158
                self.logger.info('Copying default bookmarks file to user directory')
159
                copy2(DEFAULT_RADIO_LIST, self.filename)
160
161
        if not os.access(self.cfg_filename, os.R_OK|os.W_OK):
162
163
            self.logger.warn('Configuration file not found. Copying default configuration file to user directory')
164
            copy2(DEFAULT_CONFIG_FILE, self.cfg_filename)
165
166
167
    def configLogging(self):
168
        # config logging
169
        self.logger = logging.getLogger('radiotray')
170
        self.logger.setLevel(logging.DEBUG)
171
        handler = logging.handlers.RotatingFileHandler(LOGFILE, maxBytes=2000000, backupCount=1)
172
        formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
173
        handler.setFormatter(formatter)
174
        self.logger.addHandler(handler)
175
176
if __name__ == "__main__":
177
        radio = RadioTray()