def _readdir(self, path): # logger.debug('[BasicTree._readdir] started for path %s' % \ # self.normalize(path)) # _readdir возвращает только список файлов в директории pth = self.normalize(path).split('/') logger.debug('[BasicTree._readdir] path len %s, path %s', len(pth), pth) if pth[0] == '': ptrt = dict((x, {}) for x in self.tree) if '__dirstat__' in ptrt: del ptrt['__dirstat__'] logger.debug('[BasicTree._readdir] return full tree %s', ptrt) return ptrt elif len(pth) > 1: if pth[1] in self.tree[pth[0]]: return self.tree[pth[0]][pth[1]] else: return -errno.ENOENT elif pth[0] in self.tree: ptrt = dict((x, {}) for x in self.tree[pth[0]]) logger.debug('[BasicTree._readdir] return part tree %s', ptrt) return ptrt else: return -errno.ENOENT
def _findobj(self, path): pth = self.normalize(path).split('/') logger.debug('[%s._findobj] InPath %s', self.name, path) try: fulltree = json.loads(self.mpd[self.dictpart]) except: fulltree = {} parttree = fulltree if pth[0] == '': logger.debug('[%s._findobj] Request Root tree', self.name) # print type(parttree),parttree ptrt = dict( (x.encode('utf-8', 'replace'), {}) for x in parttree.keys()) ptrt.update(self.direntry) for customs in '_online', '_offline': ptrt.update({customs: self.direntry['__dirstat__']}) logger.debug('[%s._findobj] Returned Tree %s:%s', self.name, type(ptrt), ptrt) return ptrt else: logger.debug('[%s._findobj] Requested PartTree %s:%s', self.name, type(pth), pth) if len(pth) == 1 and pth[0] in parttree: # self.peerstruct={'credentials': [], 'full': [], \ # 'codecs': [], 'huntgroups': [], 'contexts': []} logger.debug('[%s._findobj] Request info for peer %s', self.name, pth[0]) peerstruct = {} peerstruct.update(self.infotree['sip']) peerstruct.update(self.direntry) return peerstruct elif len(pth) >= 2 and pth[0] in parttree \ and pth[1] in self.infotree['sip']: # self.peerstruct={'credentials': [], 'full': [], \ # 'codecs': [], 'huntgroups': [], 'contexts': []} if pth[1] != 'full': return [ self.filestruct, self._infotree(parttree[pth[0]], self.infotree['sip'][pth[1]]) ] else: return [ self.filestruct, self._infotree(parttree[pth[0]], parttree[pth[0]].keys()) ] elif len(pth) >= 1 and pth[0] in ['_online', '_offline']: logger.debug('[%s._findobj] Request info for peer %s', self.name, pth) if len(pth) >= 2 and pth[1] in parttree.keys(): if (parttree[pth[1]]['fullcontact'] != '' and pth[0] == '_online') or (parttree[pth[1]]['fullcontact'] == '' and pth[0] == '_offline'): peerstruct = {} peerstruct.update(stat_info['def']) peerstruct.update(stat_info['link']) logger.debug('[%s._findobj] peerstruct %s', self.name, peerstruct) return [peerstruct, '../%s' % pth[1]] else: return -errno.ENOENT # self._infotree(parttree[pt[0]],parttree[pt[0]].keys()) ] else: peerstruct = {} # peerstruct.update(self.peerstruct) # peerstruct.update(self.infotree['sip']) peerstruct.update(self.direntry) for peer in parttree.keys(): if pth[0] == '_online': # > 0 and parttree[peer]['lastms'] < 4294967295: # and parttree[peer]['status'] == 'OK': if parttree[peer]['fullcontact'] != '': peerstruct.update({peer: {}}) elif pth[0] == '_offline': # or parttree[peer]['fullcontact'] == None: # #parttree[peer]['lastms'] == 0 or # parttree[peer]['lastms'] == 4294967295 : if parttree[peer]['fullcontact'] == '': peerstruct.update({peer: {}}) return peerstruct else: return -errno.ENOENT
'nullfile': [{}, ''], 'demotreeclass': fsstruct.BasicTree('/demotreeclass', mpd, ''), 'tree': { 'peer': [{ 'st_mode': 0x8000 | int('0644', 8) }, 'contents of peer'], 'friend': {}, 'user': {} } } pcore = mp.current_process() logger.info('[fusefsprocess] started. PID:%s', pcore.pid) mpd['fusefsprocess'] = pcore.pid logger.debug('[fusefsprocess] Shared Dict: %s', dict(mpd)) Fuse.fuse_python_api = (0, 2) usage = """Asterisk Realtime Filesystem""" + Fuse.fusage server = fusefscore.AstFS(version="%prog ", usage=usage, dash_s_do='setsingle') server.parse([ '/mnt', '-f', '-oac_attr_timeout=1,remember=1,allow_other,entry_timeout=1' ], errex=1) server.logger = logger server.root = root server.mpd = mpd server.main() logger.info('[fusefsprocess] main stopped. PID:%s', pcore.pid)
def recursepath(self, path, tree, withdata): """ recursive search a path in existing tree """ # print 'Path %s length %s tree %s'%(path,len(path),tree) # !logger.debug('[recursepath] Path %s length %s WithData: # %s'%(path,len(path),withdata)) if path[0] not in tree: # print 'Path not found' return None else: # print 'Tree %s'%tree if not isobject(tree[path[0]]): if len(path) == 1: if isobject(tree[path[0]]): logger.debug( '[FuseFSCore.recursepath] object found %s', tree[path[0]]) return tree[path[0]] elif callable(tree[path[0]]): logger.debug( '[FuseFSCore.recursepath] callable dir %s', dir(tree[path[0]])) # return { '1234' : { '12345' : [stat_info['def'],None] } } logger.debug( '[FuseFSCore.recursepath] Callable \ Path found %s at %s:%s', path, tree[path[0]], withdata) dictpath = dict( (x, {}) for x in tree[path[0]](withdata)) logger.debug( '[FuseFSCore.recursepath] --------- Callable \ Path result %s', len(dictpath)) return dictpath else: return tree[path[0]] else: for part in path: # print '\n[recursepath] Path part %s'%part # print '\n[recursepath] Path %s length # %s:%s'%(path,len(path),withdata) if callable(tree[part]): # print '[recursepath] callable %s at path # %s'%(tree[part],path) data = tree[part](withdata, path[1:]) # print '[recursepath] Plain callable data for # path %s tree %s'%(path,data) return data else: # print 'recurse %s tree %s'%(part,tree[part]) # pathkey = '/'.join(path) # if pathkey in cache: # data = cache[pathkey] # print '\n%s\n[recursepath] Cached data tree # for path %s is %s'%('='*30,path,data) # else: # cache.expire() data = self.recursepath(path[1:], tree[part], withdata) # cache.set(pathkey, data, expire=15) # print '\n%s\n[recursepath] Plain ordinal data # tree for path %s is %s'%('='*30,path,data) return data else: return tree[path[0]]
def returntree(self, path, tree, withdata=False): """ return filetree as dict for fusefs functions """ # global lpd # lpd=mpd # logger.debug('[returntree] MPD %s'%mpd) pathlist = [pathpart for pathpart in path.split('/') if pathpart != ''] # перепаковываем непустые элементы пути в массив if len(pathlist) == 0: # если длина массива = 0, то обрабатываем всё дерево data = tree else: # если длина массива отлична от 0, то ищем ветку в дереве data = self.recursepath(pathlist, tree, withdata) # dirtree = {} if isinstance(data, dict): # logger.debug('[returntree] Dict Data %s'%data) # # если результат поиска "словарь", значит это ветка файловой # системы со списком директорий и файлов. dirstat = {} map(lambda x: dirstat.update(x), [stat_info['def'], stat_info['dir']]) # # процедура обхода дерева файлов универсальна и используется # в различных процедурах # # readdir - возвращает системе список объектов # в запрошенной ветке файловой системы # getattr - возвращает системе структуру tuple # с характеристиками объекта # # ВАЖНО! readdir не передаёт никаких характеристик объектов # вся информация получается путём дальнейшего опроса данных # объектов процедурой getattr # # для хранения информации используется древовидная структура # в виде словаря dict() # # в поле значения которой, для каждого объекта используется # список list() # # первым элементом которого хранится именованный словарь # параметров для файловой системы объекта, во втором элементе # хранится содержимое объекта: # # directory - первый элемент объекта это словарь параметров, # второй элемент равен None # # regular file - первый элемент объекта это словарь параметров, # второй элемент - содержимое файла # # symlink - первый элемент объекта это словарь параметров, # второй элемент - путь до реального объекта # # т.к. информация о запрашиваемой директории не хранится в явном # виде в дереве объектов, необходимо при возврате данных описать # параметры директории. Для этого, для корня указанного "словаря" # необходимо добавить ключ __dirstat__, содержащий описанную выше # структуру параметров для директории retdict = dict((k, []) for k in data) retdict['__dirstat__'] = [] retdict['__dirstat__'].append(dirstat) logger.debug( '[FuseFSCore.returntree] Instance Dict > retdict: %s\n', retdict) return retdict elif isinstance(data, list): # если результатом поиска объекта в дереве является список list(), # значит данный объект не содержит дочерних объектов и является # файлом. Для статичных файлов и объектов типа symlink, размер # файла может меняться, поэтому при возврате атрибутов файла # необходимо скорректировать параметр 'st_size'. Т.к. symlink не # отличается от обычного файла, то в дереве объектов в его # параметрах необходимо добавить структуру stat_info['link'] # после чего данная структура автоматом будет дополнена # необходимыми параметрами itemstat = {} itemstat.update(data[0]) map(lambda x: data[0].update(x), [stat_info['def'], stat_info['file'], itemstat]) logger.debug('[FuseFSCore.returntree] Instance List > itemstat:%s', itemstat) logger.debug('[FuseFSCore.returntree] data: %s\n', data) # print path,data return data
def _getfile(self, path): logger.debug('[BasicTree._getfile] started for path %s', self.normalize(path)) return 'just a file\n'
def _readlink(self, path): logger.debug('[BasicTree._readlink] started for path %s', self.normalize(path)) return '#'