Config.py :  » Network » emesene » emesene-1.6.2 » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Network » emesene 
emesene » emesene 1.6.2 » Config.py
# -*- coding: utf-8 -*-

#
#    Emesene is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    emesene is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with emesene; if not, write to the Free Software
#    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

import os
import sys
import shutil
import gobject

import paths
import emesenelib.common

import random
id = 'emesene'+str(random.random()) #used for dp roaming

DEFAULT_GLOBAL_CONFIG = {
    'rememberMe': True,
    'rememberMyPassword': False,
    'debug': False,
    'binary': False,
    'httpMethod': False,
    'useProxy': False,
    'proxyHost': 'http://127.0.0.1',
    'proxyPort': 80,
    'proxyUsername' : '',
    'proxyPassword' : '',
    'mainWindowGeometry': '440x260+0+0',
    'autoLogin': False,
    'lastLoggedAccount': '',
    'rgbaColormap' : False,
    'disableTrayIcon' : False,
    'overrideDesktop' : '',
    'overrideMail' : '',
    'startup' : 'default',
    'Id' : id,
    'dontShowAvatarInLoginWindow' : 0,
}


DEFAULT_USER_CONFIG = {
    'theme': 'default',
    'smilieTheme': 'default',
    'conversationLayout' : 'default',
    'smallIcons': False,
    'showByNick': True,
    'showOffline': False,
    'showEmptyGroups': False,
    'orderByStatus': False,
    'collapsedGroups': '',
    'autoReply': False,
    'autoReplyMessage': _('I\'m not here (this is an autoreply)'),
    'rememberMyPassword': False,
    'fontFace': 'Sans',
    'fontColor': '#000000',
    'fontSize': 10,
    'fontUnderline' : False,
    'fontBold' : False,
    'fontItalic' : False,
    'fontStrike' : False,
    'showTimestamp': False, # XXX: check if this works
    'convWindowGeometry': '480x450+0+0',
    'convWindowWidth': '450',
    'convWindowHeight': '480',
    'convInputHeight' : 140,
    'convListWidth' : 130,
    'convMaximized' : False,
    'saveLogsAutomatically' : False,
    'activePlugins': 'Plus', # CSV of plugin names
    'emoticonDir': '',
    'avatarDir' : '',
    'avatarPath' : '',
    'parseSmilies' : True,
    'typingColor': '#339999',
    'messageWaitingColor': '#ef2929',
    'personalMessageColor': '#AAAAAA',
    'useFriendsUnifiedFormat' : False,
    'friendsUnifiedFont' : 'Sans',
    'friendsUnifiedColor' : '#000000',
    'windows' : False,
    'webcamDevice' : 'video0',
    'webcamContrast' : 1.0,
    'webcamSaturation' : 1.0,
    'webcamHue' : 0.0,
    'webcamBrightness' : 0.0,
    # almost every setting in this block has signals
    'showUserPanel' : True,
    'showSearchEntry' : True,
    'showStatusCombo' : True,
    #'statusComboOnTop' : False,
    'statusComboPos' : 0,
    'showMenubar' : True,
    'showMenu' : True,
    'showHeader' : True,
    'showToolbar' : True,
    'showAvatars' : True,
    'showStatusBar' : True,
    'showAvatarMine' : True, # signal not needed
    'showAvatarOther' : True, # signal not needed
    'showTabCloseButton' : True, # TODO: w/o signal
    'avatarsInUserList' : True, # TODO: w/o signal
    'avatarsInTaskbar' : False,
    'hideNewWindow' : False,
    'showMailTyping' : False,
    'dontDisturbOnBusy' : True,
    'showSendButton' : False,
    'showCountContact' : True,
    'showTabImageStatus' : False,
    'mediaEnabled' : False,
    'blinkTrayIcon' : True,
    'statusbarHighLight' : True,
    'sortNickGroupByContact' : 0, # 0 = sort by nickname | 1 = sort by mail
    'sortNickGroupByStatusPriority' : 0, # sort contact in group by status

    'statusTransformation' : 'corner|alpha|gray', # valid values are corner, pixelate, alpha, gray(seperated by | )

    'useAliasIfAvailable' : True, # show alias everywhere if an alias is set
    'sendTyping' : True, # send the is typing notification to other clients
    'userListAvatarSize': 32,

    'receivedFilesSortedByUser' : False,
    'receivedFilesDir' : '~/',
    'disableEsc' : False, # disable the esc key to close conversations
    'disableFormat': False,
    'convHeaderTemplate': "['<span foreground=\"%s\">%s</span>$\\n$<span "+ \
                     "foreground=\"%s\">%s</span>','color;pm;color;email']",
    'autoAcceptTransfer': False,
    'sendKeepalive': False,
    'canResizeEmoticons' : False,
    'avatarsOnRight' : True,
    'receiveP4context' : False,
    'preventClosingTime' : False,
    'showLastMessageReceivedAt' : True,
    'enableSounds' : True,
    'soundsplayOnline' : True,
    'soundsplayOffline' : True,
    'soundsmuteSound' : False,
    'soundsplayMessage' : True,
    'soundsplayNudge' : True,
    'soundsplayTransfer' : True,
    'soundsplayInactive' : True,
    'soundsplaySend' : False,
    'soundsplayError' : False,
    'soundsdisableBusy' : False,
    'soundstheme' : 'default',
    'soundsbeep' : False,
    'toolFontType' : True,
    'toolFontColor' : True,
    'toolFontStyle' : True,
    'toolSmilies' : True,
    'toolNudge' : True,
    'toolInvite' : True,
    'toolSendFile' : True,
    'toolWebcam' : True,
    'toolClear' : True,    
}

class Config(gobject.GObject):
    '''This class contains all the stuff relative to the configuration of
    emesene. You can get or set configuration values and will be saved to
    a file for persistence'''

    __gsignals__ = {
        # value, oldvalue
        'change' : (gobject.SIGNAL_RUN_LAST | gobject.SIGNAL_DETAILED, \
          gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT)),
    }


    # -- GLOBAL CONFIG -- #
    def __init__(self):
        '''Constructor : this will create needed files for global configuration'''
        gobject.GObject.__init__(self)

        self.currentUser = ''
        self.glob = {}
        self.user = {}

        # This dict is a bit different from the two others
        # It's not a key : value dict but a plugin_name : [ key : value ] dict
        # Also it's a plain old dict, don't use it directly
        self.pluginsConfigDict = {}

        if os.name != 'nt' or hasattr(sys, "frozen"):
            # home dirs don't work outside py2exe (!)
            _mkdir('', paths.HOME_DIR, '.config')
            _mkdir('Config dir', paths.CONFIG_DIR)
            _mkdir('Theme dir in config', paths.THEME_HOME_PATH)
            _mkdir('Smilies dir in config', paths.SMILIES_HOME_PATH)
            _mkdir('Convthemes dir in config', paths.CONVTHEMES_HOME_PATH)
            _mkdir('Theme dir in config', paths.THEME_HOME_PATH)
            _mkdir('Plugins dir in config', paths.PLUGIN_HOME_PATH)
            open(os.path.join(paths.PLUGIN_HOME_PATH, '__init__.py'), 'w')\
                .write("__path__.append('%s')" % paths.PLUGIN_SYSTEM_WIDE_PATH)

        if _mkfile('Config file', paths.CONFIG_DIR, 'config'):
            self.glob = ConfigDict(self, self.writeGlobalConfig, \
                DEFAULT_GLOBAL_CONFIG)
            self.writeGlobalConfig()

        self.readGlobalConfig()

    def readGlobalConfig(self):
        '''read the config file and create a dictionarie with key and value
        of all the key=value\n in the config file'''

        globalConfigDict = DEFAULT_GLOBAL_CONFIG.copy()
        conf = None
        try:
            conf = open(paths.CONFIG_DIR + '/config', 'r')
            string = conf.read()

            for i in string.splitlines():
                if i != '':
                    try:
                        delim = i.find('=')
                        key = i[:delim]
                        value = i[delim+1:]
                        if key in DEFAULT_GLOBAL_CONFIG:
                            globalConfigDict[ key ] = value
                        else:
                            emesenelib.common.debug(key + ' is not a valid config key, ignored')
                    except Exception, e:
                        emesenelib.common.debug(key + ' config value is incorrect')

            conf.close()
        except:
            if conf:
                conf.close()

        self.glob = ConfigDict(self, self.writeGlobalConfig, DEFAULT_GLOBAL_CONFIG, globalConfigDict)

    def writeGlobalConfig(self):
        '''write the config to the file, overwrite current config file'''

        try:
            conf = open(paths.CONFIG_DIR + '/config', 'w')

            for k, v in self.glob:
                if type(v) == bool:
                    conf.write(k + '=' + str(int(v)) + '\n')
                else:
                    conf.write(k + '=' + str(v) + '\n')

            conf.close()
        except Exception, e:
            emesenelib.common.debug('exception writing config:\n')
            emesenelib.common.debug(e)

    # -- USER CONFIG -- #
    def setCurrentUser(self, email):
        ''' Create and/or read needed file for user config
        /!\ This function MUST be called before any set/getUserConfig'''

        self.currentUser = email.replace('@', '_').replace('.', '_')
        self.glob['lastLoggedAccount'] = email


        if email != '':

            _mkdir('User config dir', paths.CONFIG_DIR, self.currentUser)

            if _mkfile('Config file created: ', paths.CONFIG_DIR, \
               self.currentUser, 'config'):
                self.user = ConfigDict(self, self.writeUserConfig, \
                    DEFAULT_USER_CONFIG)
                self.writeUserConfig()

            _mkdir('', paths.CONFIG_DIR, self.currentUser, 'logs')
            _mkdir('', paths.CONFIG_DIR, self.currentUser, 'cache')
            _mkdir('', paths.CONFIG_DIR, self.currentUser, 'avatars')
            _mkdir('', paths.CONFIG_DIR, self.currentUser, 'custom_emoticons')
            self.readUserConfig()

        else:
            self.user = {}

    def getCurrentUser(self):
        return self.currentUser

    def readUserConfig(self):
        '''read the config file and create a dictionarie with key and value
        of all the key=value\n in the config file'''

        userConfigDict = DEFAULT_USER_CONFIG.copy()
        conf = None
        try:
            conf = open(paths.CONFIG_DIR + '/' + self.currentUser + '/config', 'r')
            string = conf.read()

            for i in string.splitlines():
                if i != '':
                    try:
                        delim = i.find('=')
                        key = i[:delim]
                        value = i[delim+1:]
                        if key in DEFAULT_USER_CONFIG:
                            userConfigDict[ key ] = value
                        else:
                            emesenelib.common.debug(key + ' is not a valid config key, ignored')
                    except Exception, e:
                        emesenelib.common.debug(key + ' config value is incorrect')

            conf.close()
        except:
            if conf:
                conf.close()

        self.user = ConfigDict(self, self.writeUserConfig, DEFAULT_USER_CONFIG, userConfigDict)

    def writeUserConfig(self):
        '''write the config to the file, overwrite current config file'''

        try:
            conf = open(paths.CONFIG_DIR + '/' + self.currentUser + '/config', 'w')

            for k, v in self.user:
                if type(v) == bool:
                    conf.write(k + '=' + str(int(v)) + '\n')
                else:
                    conf.write(k + '=' + str(v) + '\n')

            conf.close()
        except Exception, e:
            emesenelib.common.debug('exception writing config:\n')
            emesenelib.common.debug(e)

    # --- PLUGINS CONFIG --- work in progress - #
    def readPluginConfig(self, pluginName):
        '''read the plugin config file and create a dict with key and value
        of all the key=value\n in the config file'''

        self.pluginsConfigDict[pluginName] = {}
        conf = None
        try:
            conf = open(self.getUserConfigPath() + os.sep + pluginName + '.conf', 'r')
            string = conf.read()

            for i in string.splitlines():
                if i != '':
                    try:
                        delim = i.find('=')
                        key = i[:delim]
                        value = i[delim+1:]
                        self.pluginsConfigDict[pluginName][key] = value
                    except Exception, e:
                        emesenelib.common.debug(key + ' config value is incorrect')

            conf.close()
        except:
            if conf:
                conf.close()

    def writePluginConfig(self, pluginName):
        '''write the config to the file, overwrite current plugin config file'''

        try:
            conf = open(self.getUserConfigPath() + os.sep + pluginName + '.conf', 'w')

            for k, v in self.pluginsConfigDict[pluginName].iteritems(): # TODO
                conf.write(k + '=' + str(v) + '\n')

            conf.close()
        except Exception, e:
            emesenelib.common.debug('exception writing config:\n')
            emesenelib.common.debug(e)

    def setPluginValue(self, pluginName, key, value):
        self.pluginsConfigDict[pluginName][key] = str(value)
        self.writePluginConfig(pluginName) # TODO: config transactions?

    def getPluginValue(self, pluginName, key, default):
        if pluginName in self.pluginsConfigDict:
            if key in self.pluginsConfigDict[pluginName]:
                return self.pluginsConfigDict[pluginName][key]

        return default

    # --- OTHER STUFF --- #
    def _explorePath( self, path ):
        result = []
        for root, dirs, files in os.walk(path, True):
            if root != path: continue
            for dir in dirs:
                if not dir.startswith('.') and dir not in result:
                    result.append(dir)
            # stops walking the tree
            dirs = []
        return result

    def getThemes(self):
        '''this method is here because i dont know where to put it,
        it return a list of dirs in the theme directory'''

        return self._explorePath(paths.THEME_HOME_PATH) + \
               self._explorePath(paths.THEME_SYSTEM_WIDE_PATH)

    def getSmilieThemes(self):
        '''the same with smilie themes'''

        return self._explorePath(paths.SMILIES_HOME_PATH) + \
               self._explorePath(paths.SMILIES_SYSTEM_WIDE_PATH)

    def getLogPath(self):
        logPath = self.user['logPath']
        if logPath != '':
            return logPath
        else:
            return paths.CONFIG_DIR + os.sep + self.currentUser + os.sep + 'logs'

    def getCachePath(self):
        return paths.CONFIG_DIR + os.sep + self.currentUser + os.sep + 'cache'

    def getUserConfigPath(self):
        return paths.CONFIG_DIR + os.sep + self.currentUser

    def getAvatarsCachePath(self):
        return paths.CONFIG_DIR + os.sep + self.currentUser + os.sep + 'avatars'

    def getCustomEmoticonsPath(self):
        return paths.CONFIG_DIR + os.sep + self.currentUser + os.sep + 'custom_emoticons'

    def getConversationThemesPath(self):
        return paths.CONFIG_DIR + os.sep + 'conversation_themes'


class ConfigDict(dict):
    '''A dictionary that handles type conversion, fallbacks to default, config
    file writing, etc'''

    def __init__(self, config, writeFunc, defaults, store=None):
        self.config = config
        self.writeFunc = writeFunc
        self.defaults = defaults

        if store == None:
            store = defaults.copy()

        self.store = {}
        for key, value in store.iteritems():
            if type(value) == bool:
                self.store[key] = str(int(value))
            else:
                self.store[key] = str(value)

    def __repr__(self):
        return '<ConfigDict based on ' + repr(store) + '>'

    def getDefault(self, name):
        if name in self.defaults:
            return self.defaults[name]
        else:
            return ''

    def __getitem__(self, name):
        '''returns a item from self.store.itavailablethat import 
        item from defaults import 
        also does some type conversion and bool checks'''

        if name in self.store:
            newType = type(self.getDefault(name))
            if newType == bool:
                if str(self.store[name]).lower() in ('true', 'false'):
                    # workaround for some buggy configs..
                    boolValue = (str(self.store[name]).lower() == 'true')
                    self.store[name] = str(int(boolValue))
                    return boolValue
                else:
                    try:
                        # >>> int('0') == True
                        return bool(int(self.store[name]))
                    except ValueError:
                        return self.getDefault(name)
            else:
                try:
                    return newType(self.store[name])
                except ValueError:
                    return self.getDefault(name)
        else:
            emesenelib.common.debug('Config value was not found: ' + str(name))
            return self.getDefault(name)

    def __setitem__(self, name, value):
        '''sets a config key "name" to the string "value", emits
        callbacks and writes config'''

        if type(value) == bool:
            value = str(int(value))
        else:
            value = str(value)

        oldValue = None
        if name in self.store:
            oldValue = self.store[name]

        self.store[name] = value

        self.config.emit('change::' + name, value, oldValue)
        self.writeFunc() # TODO: config transactions?

    def __iter__(self):
        '''for key, value in configDict'''
        return self.store.iteritems()


def _mkbase(check, make, message, *components):
    '''base function for _mkdir and _mkfile'''
    path = os.path.join(*components)
    if not check(path):
        make(path)
        if message:
            emesenelib.common.debug(message + ' created: ' + path)
        return True
    return False

def _mkdir(message, *components):
    '''makes a directory and prints a message'''
    return _mkbase(os.path.isdir, os.mkdir, message, *components)

def _mkfile(message, *components):
    '''checks if the file exists and prints a message'''
    return _mkbase(os.path.isfile, lambda x: None, message, *components)
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.