NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

settings.py (11101B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\carbonui\util\settings.py
      2 import blue
      3 import log
      4 import os
      5 import signals
      6 import types
      7 import yaml
      8 import traceback
      9 import uthread
     10 import uthread2
     11 from carbon.common.script.util.timerstuff import AutoTimer
     12 from carbonui.util.settingsYamlLoader import UnicodeConvertingYamlLoader
     13 from carbonui.util.bunch import Bunch
     14 from carbonui.util.various_unsorted import GetAttrs
     15 from carbonui.util import defaultsetting
     16 from copy import deepcopy
     17 
     18 class SettingSection():
     19 
     20     def __init__(self, name, filepath, autoStoreInterval, service):
     21         self._name = name
     22         self._filepath = filepath
     23         self._dirty = False
     24         self._service = service
     25         self.datastore = {}
     26         self.timeoutTimer = None
     27         self._scatterSettingsChangedThreads = {}
     28         self._messenger = signals.Messenger()
     29         self.LoadFromFile(filepath, autoStoreInterval)
     30 
     31     def __str__(self):
     32         return '%s\nSetting section, %s; holding %s groups.\nFileLocation: %s' % ('-' * 60,
     33          self._name,
     34          len(self.datastore),
     35          repr(self._filepath))
     36 
     37     def __repr__(self):
     38         s = self.__str__() + '\n'
     39         for groupName, groupValue in self.datastore.iteritems():
     40             s += '%s:\n' % groupName
     41             for settingName, settingValue in groupValue.iteritems():
     42                 s += '    %s: %s\n' % (settingName, settingValue)
     43 
     44         return s
     45 
     46     class Group(dict):
     47 
     48         def __init__(self, name, section):
     49             self.__dict__['name'] = name
     50             self.__dict__['section'] = section
     51 
     52         def __getattr__(self, attrName):
     53             if hasattr(self, 'section'):
     54                 return self.section.Get(self.name, attrName)
     55 
     56         def Get(self, attrName, defValue = None):
     57             retVal = self.__getattr__(attrName)
     58             if retVal is None:
     59                 return defValue
     60             return retVal
     61 
     62         def __setattr__(self, attrName, value):
     63             if hasattr(self, 'section'):
     64                 self.section.Set(self.name, attrName, value)
     65 
     66         Set = __setattr__
     67 
     68         def Release(self):
     69             self.section = None
     70 
     71         def HasKey(self, attrName):
     72             return self.section.HasKey(self.name, attrName)
     73 
     74         def Delete(self, attrName):
     75             self.section.Delete(self.name, attrName)
     76 
     77         def GetValues(self):
     78             return self.section.GetValues(self.name)
     79 
     80     def LoadFromFile(self, filepath, autoStoreInterval):
     81         data = None
     82         try:
     83             fn = blue.paths.ResolvePath(filepath)
     84             data = blue.AtomicFileRead(fn)
     85         except:
     86             pass
     87 
     88         if data:
     89             try:
     90                 self.datastore = blue.marshal.Load(data)
     91                 for k, v in self.datastore.iteritems():
     92                     self.CreateGroup(k)
     93 
     94             except Exception:
     95                 log.LogException('Error loading settings data file')
     96 
     97         self.timeoutTimer = AutoTimer(autoStoreInterval * 1000, self.WriteToDisk)
     98 
     99     def GetValues(self, groupName):
    100         return self.datastore[groupName]
    101 
    102     def Get(self, groupName, settingName):
    103         if groupName not in self.datastore:
    104             self.CreateGroup(groupName)
    105         if settingName in self.datastore[groupName]:
    106             value = self.datastore[groupName][settingName][1]
    107             self.datastore[groupName][settingName] = (blue.os.GetWallclockTime(), value)
    108             return value
    109         else:
    110             n = settingName
    111             if type(n) == types.UnicodeType:
    112                 n = n.encode('UTF-8')
    113             return GetAttrs(defaultsetting, self._name, groupName, n)
    114 
    115     def HasKey(self, groupName, settingName):
    116         return settingName in self.datastore[groupName]
    117 
    118     def Delete(self, groupName, settingName):
    119         if self.HasKey(groupName, settingName):
    120             del self.datastore[groupName][settingName]
    121             self._ScatterSettingsChanged(groupName, settingName)
    122 
    123     def Set(self, groupName, settingName, value):
    124         if groupName not in self.datastore:
    125             self.CreateGroup(groupName)
    126         self.datastore[groupName][settingName] = (blue.os.GetWallclockTime(), value)
    127         self.FlagDirty()
    128         self._ScatterSettingsChanged(groupName, settingName)
    129 
    130     def Remove(self, groupName, settingName = None):
    131         if groupName in self.datastore:
    132             group = self.datastore[groupName]
    133             if settingName:
    134                 if settingName in group:
    135                     del group[settingName]
    136             else:
    137                 del self.datastore[groupName]
    138             self.FlagDirty()
    139 
    140     def HasGroup(self, groupName):
    141         return groupName in self.__dict__ and groupName in self.datastore
    142 
    143     def DuplicateGroup(self, oldGroupName, newGroupName):
    144         if not self.HasGroup(oldGroupName) or self.HasGroup(newGroupName):
    145             return
    146         self.CreateGroup(newGroupName)
    147         self.datastore[newGroupName] = deepcopy(self.datastore[oldGroupName])
    148         self.FlagDirty()
    149 
    150     def RenameGroup(self, oldGroupName, newGroupName):
    151         if not self.HasGroup(oldGroupName):
    152             return
    153         self.CreateGroup(newGroupName)
    154         self.datastore[newGroupName] = deepcopy(self.datastore[oldGroupName])
    155         del self.__dict__[oldGroupName]
    156         del self.datastore[oldGroupName]
    157         self.FlagDirty()
    158 
    159     def RemoveGroup(self, groupName):
    160         if not self.HasGroup(groupName):
    161             return
    162         del self.__dict__[groupName]
    163         del self.datastore[groupName]
    164         self.FlagDirty()
    165 
    166     def ClearGroup(self, groupName):
    167         if not self.HasGroup(groupName):
    168             return
    169         self.datastore[groupName] = {}
    170         self.FlagDirty()
    171 
    172     def CreateGroup(self, groupName):
    173         if groupName not in self.__dict__:
    174             self.__dict__[groupName] = self.Group(groupName, self)
    175         if groupName not in self.datastore:
    176             self.datastore[groupName] = {}
    177 
    178     def FlagDirty(self):
    179         self._dirty = True
    180 
    181     def WriteToDiskImmediate(self):
    182         self.WriteToDisk()
    183 
    184     def WriteToDisk(self):
    185         if self._dirty:
    186             self._dirty = False
    187             fn = blue.paths.ResolvePathForWriting(self._filepath)
    188             try:
    189                 if os.access(fn, os.F_OK) and not os.access(fn, os.W_OK):
    190                     os.chmod(fn, 438)
    191                 k = blue.marshal.Save(self.datastore)
    192                 blue.AtomicFileWrite(fn, k)
    193             except Exception as e:
    194                 log.LogError('Failed writing to disk', str(self), '-', repr(e))
    195 
    196     def Unload(self):
    197         self.timeoutTimer = None
    198         self.FlushOldEntries()
    199         self.WriteToDisk()
    200 
    201     def Save(self):
    202         self.FlushOldEntries()
    203         self.WriteToDisk()
    204 
    205     def FlushOldEntries(self):
    206         lastModified = blue.os.GetWallclockTime() - const.WEEK * 6
    207         for k, v in self.datastore.iteritems():
    208             for key in v.keys():
    209                 if v[key][0] <= lastModified:
    210                     del v[key]
    211 
    212         self.FlagDirty()
    213 
    214     def SetDatastore(self, datastore):
    215         self.datastore = datastore
    216 
    217     def GetDatastore(self):
    218         return self.datastore
    219 
    220     def KillTimer(self):
    221         if self.timeoutTimer is not None:
    222             self.timeoutTimer.KillTimer()
    223             self.timeoutTimer = None
    224 
    225     def Subscribe(self, groupName, settingName, handler):
    226         self._messenger.SubscribeToMessage(u'{}.{}'.format(groupName, settingName), handler)
    227 
    228     def Unsubscribe(self, groupName, settingName, handler):
    229         self._messenger.UnsubscribeFromMessage(u'{}.{}'.format(groupName, settingName), handler)
    230 
    231     def _ScatterSettingsChanged(self, groupName, settingName):
    232         self._messenger.SendMessage(u'{}.{}'.format(groupName, settingName))
    233         settingsID = (groupName, settingName)
    234         if settingsID not in self._scatterSettingsChangedThreads:
    235             self._scatterSettingsChangedThreads[settingsID] = uthread2.start_tasklet(self._ScatterSettingsChangedThread, groupName, settingName)
    236 
    237     def _ScatterSettingsChangedThread(self, groupName, settingName):
    238         uthread2.Sleep(0.1)
    239         self._scatterSettingsChangedThreads.pop((groupName, settingName), None)
    240         sm.ScatterEvent('OnClientSettingsChanged', self._name, groupName, settingName)
    241 
    242 
    243 class YAMLSettingSection(SettingSection):
    244 
    245     def __init__(self, name, filepath, autoStoreInterval, service):
    246         SettingSection.__init__(self, name, filepath, autoStoreInterval, service)
    247 
    248     def LoadFromFile(self, filepath, autoStoreInterval):
    249         data = None
    250         try:
    251             fn = blue.paths.ResolvePath(filepath)
    252             data = blue.AtomicFileRead(fn)
    253         except:
    254             pass
    255 
    256         if data:
    257             try:
    258                 self.datastore = yaml.load(data, Loader=UnicodeConvertingYamlLoader)
    259                 for k, v in self.datastore.iteritems():
    260                     self.CreateGroup(k)
    261 
    262             except:
    263                 log.LogError('Error loading settings data file -- ', traceback.format_exc())
    264 
    265         self.timeoutTimer = AutoTimer(autoStoreInterval * 1000, self.WriteToDisk)
    266 
    267     def WriteToDisk(self):
    268         uthread.new(self._WriterThreadFunc)
    269 
    270     def WriteToDiskImmediate(self):
    271         self._WriterThreadFunc()
    272 
    273     def _WriterThreadFunc(self):
    274         if self._dirty:
    275             self._dirty = False
    276             fn = blue.paths.ResolvePathForWriting(self._filepath)
    277             try:
    278                 if os.access(fn, os.F_OK) and not os.access(fn, os.W_OK):
    279                     os.chmod(fn, 438)
    280                 k = yaml.dump(self.datastore, Dumper=yaml.CSafeDumper)
    281                 blue.AtomicFileWrite(fn, k)
    282             except Exception as e:
    283                 log.LogError('Failed writing to disk', str(self), '-', repr(e))
    284 
    285 
    286 def LoadBaseSettings():
    287     import __builtin__
    288     if not hasattr(__builtin__, 'settings'):
    289         __builtin__.settings = Bunch()
    290     sections = (('user', session.userid, 'dat'), ('char', session.charid, 'dat'), ('public', None, 'yaml'))
    291 
    292     def _LoadSettingsIntoBuiltins(sectionName, identifier, settingsClass, extension):
    293         key = '%s%s' % (sectionName, identifier)
    294         filePath = blue.paths.ResolvePathForWriting(u'settings:/core_%s_%s.%s' % (sectionName, identifier or '_', extension))
    295         section = settingsClass(sectionName, filePath, 62, service=None)
    296         __builtin__.settings.Set(sectionName, section)
    297 
    298     for sectionName, identifier, format in sections:
    299         _LoadSettingsIntoBuiltins(sectionName, identifier, SettingSection, 'dat')
    300 
    301     settings.public.CreateGroup('generic')
    302     settings.public.CreateGroup('device')
    303     settings.public.CreateGroup('ui')
    304     settings.public.CreateGroup('audio')
    305     settings.user.CreateGroup('tabgroups')
    306     settings.user.CreateGroup('windows')
    307     settings.user.CreateGroup('suppress')
    308     settings.user.CreateGroup('ui')
    309     settings.user.CreateGroup('cmd')
    310     settings.user.CreateGroup('localization')
    311     settings.char.CreateGroup('windows')
    312     settings.char.CreateGroup('ui')
    313     settings.char.CreateGroup('zaction')