PYTHON   64

elFinder py

Guest on 16th July 2022 04:04:41 PM

  1. #!/usr/bin/env python
  2. #
  3. # Connector for elFinder File Manager
  4. # author Troex Nevelin
  5.  
  6. import hashlib
  7. import mimetypes
  8. import os
  9. import os.path
  10. import re
  11. import shutil
  12. import time
  13. from datetime import datetime
  14.  
  15. class connector():
  16.         """Connector for elFinder"""
  17.  
  18.         _options = {
  19.                 'root': '',
  20.                 'URL': '',
  21.                 'rootAlias': 'Home',
  22.                 'dotFiles': False,
  23.                 'dirSize': True,
  24.                 'fileMode': 0644,
  25.                 'dirMode': 0755,
  26.                 'imgLib': 'auto',
  27.                 'tmbDir': '.tmb',
  28.                 'tmbAtOnce': 5,
  29.                 'tmbSize': 48,
  30.                 'fileURL': True,
  31.                 'uploadMaxSize': 256,
  32.                 'uploadWriteChunk': 8192,
  33.                 'uploadAllow': [],
  34.                 'uploadDeny': [],
  35.                 'uploadOrder': ['deny', 'allow'],
  36.                 # 'aclObj': None, # TODO
  37.                 # 'aclRole': 'user', # TODO
  38.                 'defaults': {
  39.                         'read': True,
  40.                         'write': True,
  41.                         'rm': True
  42.                 },
  43.                 'perms': {},
  44.                 'archiveMimes': {},
  45.                 'archivers': {},
  46.                 'disabled': [],
  47.                 'debug': False
  48.         }
  49.  
  50.         _commands = {
  51.                 'open': '__open',
  52.                 'reload': '__reload',
  53.                 'mkdir': '__mkdir',
  54.                 'mkfile': '__mkfile',
  55.                 'rename': '__rename',
  56.                 'upload': '__upload',
  57.                 'paste': '__paste',
  58.                 'rm': '__rm',
  59.                 'duplicate': '__duplicate',
  60.                 'read': '__read',
  61.                 'edit': '__edit',
  62.                 'extract': '__extract',
  63.                 'archive': '__archive',
  64.                 'resize': '__resize',
  65.                 'tmb': '__thumbnails',
  66.                 'ping': '__ping'
  67.         }
  68.  
  69.         _mimeType = {
  70.                 # text
  71.                 'txt': 'text/plain',
  72.                 'conf': 'text/plain',
  73.                 'ini': 'text/plain',
  74.                 'php': 'text/x-php',
  75.                 'html': 'text/html',
  76.                 'htm': 'text/html',
  77.                 'js' : 'text/javascript',
  78.                 'css': 'text/css',
  79.                 'rtf': 'text/rtf',
  80.                 'rtfd': 'text/rtfd',
  81.                 'py' : 'text/x-python',
  82.                 'java': 'text/x-java-source',
  83.                 'rb' : 'text/x-ruby',
  84.                 'sh' : 'text/x-shellscript',
  85.                 'pl' : 'text/x-perl',
  86.                 'sql': 'text/x-sql',
  87.                 # apps
  88.                 'doc': 'application/msword',
  89.                 'ogg': 'application/ogg',
  90.                 '7z': 'application/x-7z-compressed',
  91.                 # video
  92.                 'ogm': 'appllication/ogm',
  93.                 'mkv': 'video/x-matroska'
  94.         }
  95.  
  96.         _time = 0
  97.         _request = {}
  98.         _response = {}
  99.         _errorData = {}
  100.         _form = {}
  101.         _im = None
  102.         _sp = None
  103.         _today = 0
  104.         _yesterday = 0
  105.  
  106.         # public variables
  107.         httpAllowedParameters = ('cmd', 'target', 'targets[]', 'current', 'tree', 'name',
  108.                 'content', 'src', 'dst', 'cut', 'init', 'type', 'width', 'height', 'upload[]')
  109.         # return variables
  110.         httpStatusCode = 0
  111.         httpHeader = {}
  112.         httpResponse = None
  113.  
  114.         def __init__(self, opts):
  115.                 for opt in opts:
  116.                         self._options[opt] = opts.get(opt)
  117.  
  118.                 self._response['debug'] = {}
  119.  
  120.                 self._options['URL'] = self._options['URL'].rstrip('/')
  121.                 self._options['root'] = self._options['root'].rstrip(os.sep)
  122.                 self.__debug('URL', self._options['URL'])
  123.                 self.__debug('root', self._options['root'])
  124.  
  125.                 for cmd in self._options['disabled']:
  126.                         if cmd in self._commands:
  127.                                 del self._commands[cmd]
  128.  
  129.                 if self._options['tmbDir']:
  130.                         self._options['tmbDir'] = os.path.join(self._options['root'], self._options['tmbDir'])
  131.                         if not os.path.exists(self._options['tmbDir']):
  132.                                 self._options['tmbDir'] = False
  133.  
  134.  
  135.         def __reset(self):
  136.                 """Flush per request variables"""
  137.                 self.httpStatusCode = 0
  138.                 self.httpHeader = {}
  139.                 self.httpResponse = None
  140.                 self._request = {}
  141.                 self._response = {}
  142.                 self._errorData = {}
  143.                 self._form = {}
  144.  
  145.                 self._time = time.time()
  146.                 t = datetime.fromtimestamp(self._time)
  147.                 self._today = time.mktime(datetime(t.year, t.month, t.day).timetuple())
  148.                 self._yesterday = self._today - 86400
  149.  
  150.                 self._response['debug'] = {}
  151.  
  152.  
  153.         def run(self, httpRequest = []):
  154.                 """main function"""
  155.                 self.__reset()
  156.                 rootOk = True
  157.                 if not os.path.exists(self._options['root']) or self._options['root'] == '':
  158.                         rootOk = False
  159.                         self._response['error'] = 'Invalid backend configuration'
  160.                 elif not self.__isAllowed(self._options['root'], 'read'):
  161.                         rootOk = False
  162.                         self._response['error'] = 'Access denied'
  163.  
  164.                 for field in self.httpAllowedParameters:
  165.                         if field in httpRequest:
  166.                                 self._request[field] = httpRequest[field]
  167.  
  168.                 if rootOk is True:
  169.                         if 'cmd' in self._request:
  170.                                 if self._request['cmd'] in self._commands:
  171.                                         cmd = self._commands[self._request['cmd']]
  172.                                         func = getattr(self, '_' + self.__class__.__name__ + cmd, None)
  173.                                         if callable(func):
  174.                                                 try:
  175.                                                         func()
  176.                                                 except Exception, e:
  177.                                                         self._response['error'] = 'Command Failed'
  178.                                                         self.__debug('exception', str(e))
  179.                                 else:
  180.                                         self._response['error'] = 'Unknown command'
  181.                         else:
  182.                                 self.__open()
  183.  
  184.                         if 'init' in self._request:
  185.                                 self.__checkArchivers()
  186.                                 self._response['disabled'] = self._options['disabled']
  187.                                 if not self._options['fileURL']:
  188.                                         url = ''
  189.                                 else:
  190.                                         url = self._options['URL']
  191.                                 self._response['params'] = {
  192.                                         'dotFiles': self._options['dotFiles'],
  193.                                         'uplMaxSize': str(self._options['uploadMaxSize']) + 'M',
  194.                                         'archives': self._options['archiveMimes'],
  195.                                         'extract': self._options['archivers']['extract'].keys(),
  196.                                         'url': url
  197.                                 }
  198.  
  199.                 if self._errorData:
  200.                         self._response['errorData'] = self._errorData
  201.  
  202.                 if self._options['debug']:
  203.                         self.__debug('time', (time.time() - self._time))
  204.                 else:
  205.                         if 'debug' in self._response:
  206.                                 del self._response['debug']
  207.  
  208.                 if self.httpStatusCode < 100:
  209.                         self.httpStatusCode = 200
  210.  
  211.                 if not 'Content-type' in self.httpHeader:
  212.                         if ('cmd' in self._request and self._request['cmd'] == 'upload') or self._options['debug']:
  213.                                 self.httpHeader['Content-type'] = 'text/html'
  214.                         else:
  215.                                 self.httpHeader['Content-type'] = 'application/json'
  216.  
  217.                 self.httpResponse = self._response
  218.  
  219.                 return self.httpStatusCode, self.httpHeader, self.httpResponse
  220.  
  221.  
  222.         def __open(self):
  223.                 """Open file or directory"""
  224.                 # try to open file
  225.                 if 'current' in self._request:
  226.                         curDir = self.__findDir(self._request['current'], None)
  227.                         curFile = self.__find(self._request['target'], curDir)
  228.  
  229.                         if not curDir or not curFile or os.path.isdir(curFile):
  230.                                 self.httpStatusCode = 404
  231.                                 self.httpHeader['Content-type'] = 'text/html'
  232.                                 self.httpResponse = 'File not found'
  233.                                 return
  234.                         if not self.__isAllowed(curDir, 'read') or not self.__isAllowed(curFile, 'read'):
  235.                                 self.httpStatusCode = 403
  236.                                 self.httpHeader['Content-type'] = 'text/html'
  237.                                 self.httpResponse = 'Access denied'
  238.                                 return
  239.  
  240.                         if os.path.islink(curFile):
  241.                                 curFile = self.__readlink(curFile)
  242.                                 if not curFile or os.path.isdir(curFile):
  243.                                         self.httpStatusCode = 404
  244.                                         self.httpHeader['Content-type'] = 'text/html'
  245.                                         self.httpResponse = 'File not found'
  246.                                         return
  247.                                 if (
  248.                                         not self.__isAllowed(os.path.dirname(curFile), 'read')
  249.                                         or not self.__isAllowed(curFile, 'read')
  250.                                         ):
  251.                                         self.httpStatusCode = 403
  252.                                         self.httpHeader['Content-type'] = 'text/html'
  253.                                         self.httpResponse = 'Access denied'
  254.                                         return
  255.  
  256.                         mime = self.__mimetype(curFile)
  257.                         parts = mime.split('/', 2)
  258.                         if parts[0] == 'image': disp = 'image'
  259.                         elif parts[0] == 'text': disp = 'inline'
  260.                         else: disp = 'attachments'
  261.  
  262.                         self.httpStatusCode = 200
  263.                         self.httpHeader['Content-type'] = mime
  264.                         self.httpHeader['Content-Disposition'] = disp + '; filename=' + os.path.basename(curFile)
  265.                         self.httpHeader['Content-Location'] = curFile.replace(self._options['root'], '')
  266.                         self.httpHeader['Content-Transfer-Encoding'] = 'binary'
  267.                         self.httpHeader['Content-Length'] = str(os.lstat(curFile).st_size)
  268.                         self.httpHeader['Connection'] = 'close'
  269.                         self._response['file'] = open(curFile, 'r')
  270.                         return
  271.                 # try dir
  272.                 else:
  273.                         path = self._options['root']
  274.  
  275.                         if 'target' in self._request:
  276.                                 target = self.__findDir(self._request['target'], None)
  277.                                 if not target:
  278.                                         self._response['error'] = 'Invalid parameters'
  279.                                 elif not self.__isAllowed(target, 'read'):
  280.                                         self._response['error'] = 'Access denied'
  281.                                 else:
  282.                                         path = target
  283.  
  284.                         self.__content(path, 'tree' in self._request)
  285.                 pass
  286.  
  287.  
  288.         def __rename(self):
  289.                 """Rename file or dir"""
  290.                 current = name = target = None
  291.                 curDir = curName = newName = None
  292.                 if 'name' in self._request and 'current' in self._request and 'target' in self._request:
  293.                         name = self._request['name']
  294.                         current = self._request['current']
  295.                         target = self._request['target']
  296.                         curDir = self.__findDir(current, None)
  297.                         curName = self.__find(target, curDir)
  298.                         newName = os.path.join(curDir, name)
  299.  
  300.                 if not curDir or not curName:
  301.                         self._response['error'] = 'File not found'
  302.                 elif not self.__isAllowed(curDir, 'write') and self.__isAllowed(curName, 'rm'):
  303.                         self._response['error'] = 'Access denied'
  304.                 elif not self.__checkName(name):
  305.                         self._response['error'] = 'Invalid name'
  306.                 elif os.path.exists(newName):
  307.                         self._response['error'] = 'File or folder with the same name already exists'
  308.                 else:
  309.                         self.__rmTmb(curName)
  310.                         try:
  311.                                 os.rename(curName, newName)
  312.                                 self._response['select'] = [self.__hash(newName)]
  313.                                 self.__content(curDir, os.path.isdir(newName))
  314.                         except:
  315.                                 self._response['error'] = 'Unable to rename file'
  316.  
  317.  
  318.         def __mkdir(self):
  319.                 """Create new directory"""
  320.                 current = None
  321.                 path = None
  322.                 newDir = None
  323.                 if 'name' in self._request and 'current' in self._request:
  324.                         name = self._request['name']
  325.                         current = self._request['current']
  326.                         path = self.__findDir(current, None)
  327.                         newDir = os.path.join(path, name)
  328.  
  329.                 if not path:
  330.                         self._response['error'] = 'Invalid parameters'
  331.                 elif not self.__isAllowed(path, 'write'):
  332.                         self._response['error'] = 'Access denied'
  333.                 elif not self.__checkName(name):
  334.                         self._response['error'] = 'Invalid name'
  335.                 elif os.path.exists(newDir):
  336.                         self._response['error'] = 'File or folder with the same name already exists'
  337.                 else:
  338.                         try:
  339.                                 os.mkdir(newDir, int(self._options['dirMode']))
  340.                                 self._response['select'] = [self.__hash(newDir)]
  341.                                 self.__content(path, True)
  342.                         except:
  343.                                 self._response['error'] = 'Unable to create folder'
  344.  
  345.  
  346.         def __mkfile(self):
  347.                 """Create new file"""
  348.                 name = current = None
  349.                 curDir = newFile = None
  350.                 if 'name' in self._request and 'current' in self._request:
  351.                         name = self._request['name']
  352.                         current = self._request['current']
  353.                         curDir = self.__findDir(current, None)
  354.                         newFile = os.path.join(curDir, name)
  355.  
  356.                 if not curDir or not name:
  357.                         self._response['error'] = 'Invalid parameters'
  358.                 elif not self.__isAllowed(curDir, 'write'):
  359.                         self._response['error'] = 'Access denied'
  360.                 elif not self.__checkName(name):
  361.                         self._response['error'] = 'Invalid name'
  362.                 elif os.path.exists(newFile):
  363.                         self._response['error'] = 'File or folder with the same name already exists'
  364.                 else:
  365.                         try:
  366.                                 open(newFile, 'w').close()
  367.                                 self._response['select'] = [self.__hash(newFile)]
  368.                                 self.__content(curDir, False)
  369.                         except:
  370.                                 self._response['error'] = 'Unable to create file'
  371.  
  372.  
  373.         def __rm(self):
  374.                 """Delete files and directories"""
  375.                 current = rmList = None
  376.                 curDir = rmFile = None
  377.                 if 'current' in self._request and 'targets[]' in self._request:
  378.                         current = self._request['current']
  379.                         rmList = self._request['targets[]']
  380.                         curDir = self.__findDir(current, None)
  381.  
  382.                 if not rmList or not curDir:
  383.                         self._response['error'] = 'Invalid parameters'
  384.                         return False
  385.  
  386.                 if not isinstance(rmList, list):
  387.                         rmList = [rmList]
  388.  
  389.                 for rm in rmList:
  390.                         rmFile = self.__find(rm, curDir)
  391.                         if not rmFile: continue
  392.                         self.__remove(rmFile)
  393.                 # TODO if errorData not empty return error
  394.                 self.__content(curDir, True)
  395.  
  396.  
  397.         def __upload(self):
  398.                 """Upload files"""
  399.                 try: # Windows needs stdio set for binary mode.
  400.                         import msvcrt
  401.                         msvcrt.setmode (0, os.O_BINARY) # stdin  = 0
  402.                         msvcrt.setmode (1, os.O_BINARY) # stdout = 1
  403.                 except ImportError:
  404.                         pass
  405.  
  406.                 if 'current' in self._request:
  407.                         curDir = self.__findDir(self._request['current'], None)
  408.                         if not curDir:
  409.                                 self._response['error'] = 'Invalid parameters'
  410.                                 return
  411.                         if not self.__isAllowed(curDir, 'write'):
  412.                                 self._response['error'] = 'Access denied'
  413.                                 return
  414.                         if not 'upload[]' in self._request:
  415.                                 self._response['error'] = 'No file to upload'
  416.                                 return
  417.  
  418.                         upFiles = self._request['upload[]']
  419.                         # invalid format
  420.                         # must be dict('filename1': 'filedescriptor1', 'filename2': 'filedescriptor2', ...)
  421.                         if not isinstance(upFiles, dict):
  422.                                 self._response['error'] = 'Invalid parameters'
  423.                                 return
  424.  
  425.                         self._response['select'] = []
  426.                         total = 0
  427.                         upSize = 0
  428.                         maxSize = self._options['uploadMaxSize'] * 1024 * 1024
  429.                         for name, data in upFiles.iteritems():
  430.                                 if name:
  431.                                         total += 1
  432.                                         name = os.path.basename(name)
  433.                                         if not self.__checkName(name):
  434.                                                 self.__errorData(name, 'Invalid name')
  435.                                         else:
  436.                                                 name = os.path.join(curDir, name)
  437.                                                 try:
  438.                                                         f = open(name, 'wb', self._options['uploadWriteChunk'])
  439.                                                         for chunk in self.__fbuffer(data):
  440.                                                                 f.write(chunk)
  441.                                                         f.close()
  442.                                                         upSize += os.lstat(name).st_size
  443.                                                         if self.__isUploadAllow(name):
  444.                                                                 os.chmod(name, self._options['fileMode'])
  445.                                                                 self._response['select'].append(self.__hash(name))
  446.                                                         else:
  447.                                                                 self.__errorData(name, 'Not allowed file type')
  448.                                                                 try:
  449.                                                                         os.unlink(name)
  450.                                                                 except:
  451.                                                                         pass
  452.                                                 except:
  453.                                                         self.__errorData(name, 'Unable to save uploaded file')
  454.                                                 if upSize > maxSize:
  455.                                                         try:
  456.                                                                 os.unlink(name)
  457.                                                                 self.__errorData(name, 'File exceeds the maximum allowed filesize')
  458.                                                         except:
  459.                                                                 pass
  460.                                                                 # TODO ?
  461.                                                                 self.__errorData(name, 'File was only partially uploaded')
  462.                                                         break
  463.  
  464.                         if self._errorData:
  465.                                 if len(self._errorData) == total:
  466.                                         self._response['error'] = 'Unable to upload files'
  467.                                 else:
  468.                                         self._response['error'] = 'Some files was not uploaded'
  469.  
  470.                         self.__content(curDir, False)
  471.                         return
  472.  
  473.  
  474.         def __paste(self):
  475.                 """Copy or cut files/directories"""
  476.                 if 'current' in self._request and 'src' in self._request and 'dst' in self._request:
  477.                         curDir = self.__findDir(self._request['current'], None)
  478.                         src = self.__findDir(self._request['src'], None)
  479.                         dst = self.__findDir(self._request['dst'], None)
  480.                         if not curDir or not src or not dst or not 'targets[]' in self._request:
  481.                                 self._response['error'] = 'Invalid parameters'
  482.                                 return
  483.                         files = self._request['targets[]']
  484.                         if not isinstance(files, list):
  485.                                 files = [files]
  486.  
  487.                         cut = False
  488.                         if 'cut' in self._request:
  489.                                 if self._request['cut'] == '1':
  490.                                         cut = True
  491.  
  492.                         if not self.__isAllowed(src, 'read') or not self.__isAllowed(dst, 'write'):
  493.                                 self._response['error'] = 'Access denied'
  494.                                 return
  495.  
  496.                         for fhash in files:
  497.                                 f = self.__find(fhash, src)
  498.                                 if not f:
  499.                                         self._response['error'] = 'File not found'
  500.                                         return
  501.                                 newDst = os.path.join(dst, os.path.basename(f))
  502.                                 if dst.find(f) == 0:
  503.                                         self._response['error'] = 'Unable to copy into itself'
  504.                                         return
  505.  
  506.                                 if cut:
  507.                                         if not self.__isAllowed(f, 'rm'):
  508.                                                 self._response['error'] = 'Move failed'
  509.                                                 self._errorData(f, 'Access denied')
  510.                                                 self.__content(curDir, True)
  511.                                                 return
  512.                                         # TODO thumbs
  513.                                         if os.path.exists(newDst):
  514.                                                 self._response['error'] = 'Unable to move files'
  515.                                                 self._errorData(f, 'File or folder with the same name already exists')
  516.                                                 self.__content(curDir, True)
  517.                                                 return
  518.                                         try:
  519.                                                 os.rename(f, newDst)
  520.                                                 self.__rmTmb(f)
  521.                                                 continue
  522.                                         except:
  523.                                                 self._response['error'] = 'Unable to move files'
  524.                                                 self._errorData(f, 'Unable to move')
  525.                                                 self.__content(curDir, True)
  526.                                                 return
  527.                                 else:
  528.                                         if not self.__copy(f, newDst):
  529.                                                 self._response['error'] = 'Unable to copy files'
  530.                                                 self.__content(curDir, True)
  531.                                                 return
  532.                                         continue
  533.                         self.__content(curDir, True)
  534.                 else:
  535.                         self._response['error'] = 'Invalid parameters'
  536.  
  537.                 return
  538.  
  539.  
  540.         def __duplicate(self):
  541.                 """Create copy of files/directories"""
  542.                 if 'current' in self._request and 'target' in self._request:
  543.                         curDir = self.__findDir(self._request['current'], None)
  544.                         target = self.__find(self._request['target'], curDir)
  545.                         if not curDir or not target:
  546.                                 self._response['error'] = 'Invalid parameters'
  547.                                 return
  548.                         if not self.__isAllowed(target, 'read') or not self.__isAllowed(curDir, 'write'):
  549.                                 self._response['error'] = 'Access denied'
  550.                         newName = self.__uniqueName(target)
  551.                         if not self.__copy(target, newName):
  552.                                 self._response['error'] = 'Unable to create file copy'
  553.                                 return
  554.  
  555.                 self.__content(curDir, True)
  556.                 return
  557.  
  558.  
  559.         def __resize(self):
  560.                 """Scale image size"""
  561.                 if not (
  562.                         'current' in self._request and 'target' in self._request
  563.                         and 'width' in self._request and 'height' in self._request
  564.                         ):
  565.                         self._response['error'] = 'Invalid parameters'
  566.                         return
  567.  
  568.                 width = int(self._request['width'])
  569.                 height = int(self._request['height'])
  570.                 curDir = self.__findDir(self._request['current'], None)
  571.                 curFile = self.__find(self._request['target'], curDir)
  572.  
  573.                 if width < 1 or height < 1 or not curDir or not curFile:
  574.                         self._response['error'] = 'Invalid parameters'
  575.                         return
  576.                 if not self.__isAllowed(curFile, 'write'):
  577.                         self._response['error'] = 'Access denied'
  578.                         return
  579.                 if not self.__mimetype(curFile).find('image') == 0:
  580.                         self._response['error'] = 'File is not an image'
  581.                         return
  582.  
  583.                 self.__debug('resize ' + curFile, str(width) + ':' + str(height))
  584.                 self.__initImgLib()
  585.                 try:
  586.                         im = self._im.open(curFile)
  587.                         imResized = im.resize((width, height), self._im.ANTIALIAS)
  588.                         imResized.save(curFile)
  589.                 except Exception, e:
  590.                         self.__debug('resizeFailed_' + path, str(e))
  591.                         self._response['error'] = 'Unable to resize image'
  592.                         return
  593.  
  594.                 self._response['select'] = [self.__hash(curFile)]
  595.                 self.__content(curDir, False)
  596.                 return
  597.  
  598.  
  599.         def __thumbnails(self):
  600.                 """Create previews for images"""
  601.                 if 'current' in self._request:
  602.                         curDir = self.__findDir(self._request['current'], None)
  603.                         if not curDir or curDir == self._options['tmbDir']:
  604.                                 return False
  605.                 else:
  606.                         return False
  607.  
  608.                 self.__initImgLib()
  609.                 if self.__canCreateTmb():
  610.                         if self._options['tmbAtOnce'] > 0:
  611.                                 tmbMax = self._options['tmbAtOnce']
  612.                         else:
  613.                                 tmbMax = 5
  614.                         self._response['current'] = self.__hash(curDir)
  615.                         self._response['images'] = {}
  616.                         i = 0
  617.                         for f in os.listdir(curDir):
  618.                                 path = os.path.join(curDir, f)
  619.                                 fhash = self.__hash(path)
  620.                                 if self.__canCreateTmb(path) and self.__isAllowed(path, 'read'):
  621.                                         tmb = os.path.join(self._options['tmbDir'], fhash + '.png')
  622.                                         if not os.path.exists(tmb):
  623.                                                 if self.__tmb(path, tmb):
  624.                                                         self._response['images'].update({
  625.                                                                 fhash: self.__path2url(tmb)
  626.                                                         })
  627.                                                         i += 1
  628.                                 if i >= tmbMax:
  629.                                         self._response['tmb'] = True
  630.                                         break
  631.                 else:
  632.                         return False
  633.  
  634.                 return
  635.  
  636.  
  637.         def __content(self, path, tree):
  638.                 """CWD + CDC + maybe(TREE)"""
  639.                 self.__cwd(path)
  640.                 self.__cdc(path)
  641.  
  642.                 if tree:
  643.                         self._response['tree'] = self.__tree(self._options['root'])
  644.  
  645.  
  646.         def __cwd(self, path):
  647.                 """Current Working Directory"""
  648.                 name = os.path.basename(path)
  649.                 if path == self._options['root']:
  650.                         name = self._options['rootAlias']
  651.                         root = True
  652.                 else:
  653.                         root = False
  654.  
  655.                 if self._options['rootAlias']:
  656.                         basename = self._options['rootAlias']
  657.                 else:
  658.                         basename = os.path.basename(self._options['root'])
  659.  
  660.                 rel = basename + path[len(self._options['root']):]
  661.  
  662.                 self._response['cwd'] = {
  663.                         'hash': self.__hash(path),
  664.                         'name': self.__checkUtf8(name),
  665.                         'mime': 'directory',
  666.                         'rel': self.__checkUtf8(rel),
  667.                         'size': 0,
  668.                         'date': datetime.fromtimestamp(os.stat(path).st_mtime).strftime("%d %b %Y %H:%M"),
  669.                         'read': True,
  670.                         'write': self.__isAllowed(path, 'write'),
  671.                         'rm': not root and self.__isAllowed(path, 'rm')
  672.                 }
  673.  
  674.  
  675.         def __cdc(self, path):
  676.                 """Current Directory Content"""
  677.                 files = []
  678.                 dirs = []
  679.  
  680.                 for f in sorted(os.listdir(path)):
  681.                         if not self.__isAccepted(f): continue
  682.                         pf = os.path.join(path, f)
  683.                         info = {}
  684.                         info = self.__info(pf)
  685.                         info['hash'] = self.__hash(pf)
  686.                         if info['mime'] == 'directory':
  687.                                 dirs.append(info)
  688.                         else:
  689.                                 files.append(info)
  690.  
  691.                 dirs.extend(files)
  692.                 self._response['cdc'] = dirs
  693.  
  694.  
  695.         def __info(self, path):
  696.                 mime = ''
  697.                 filetype = 'file'
  698.                 if os.path.isfile(path): filetype = 'file'
  699.                 if os.path.isdir(path): filetype = 'dir'
  700.                 if os.path.islink(path): filetype = 'link'
  701.  
  702.                 stat = os.lstat(path)
  703.                 statDate = datetime.fromtimestamp(stat.st_mtime)
  704.  
  705.                 fdate = ''
  706.                 if stat.st_mtime >= self._today:
  707.                         fdate = 'Today ' + statDate.strftime("%H:%M")
  708.                 elif stat.st_mtime >= self._yesterday and stat.st_mtime < self._today:
  709.                         fdate = 'Yesterday ' + statDate.strftime("%H:%M")
  710.                 else:
  711.                         fdate = statDate.strftime("%d %b %Y %H:%M")
  712.  
  713.                 info = {
  714.                         'name': self.__checkUtf8(os.path.basename(path)),
  715.                         'hash': self.__hash(path),
  716.                         'mime': 'directory' if filetype == 'dir' else self.__mimetype(path),
  717.                         'date': fdate,
  718.                         'size': self.__dirSize(path) if filetype == 'dir' else stat.st_size,
  719.                         'read': self.__isAllowed(path, 'read'),
  720.                         'write': self.__isAllowed(path, 'write'),
  721.                         'rm': self.__isAllowed(path, 'rm')
  722.                 }
  723.  
  724.                 if filetype == 'link':
  725.                         lpath = self.__readlink(path)
  726.                         if not lpath:
  727.                                 info['mime'] = 'symlink-broken'
  728.                                 return info
  729.  
  730.                         if os.path.isdir(lpath):
  731.                                 info['mime'] = 'directory'
  732.                         else:
  733.                                 info['parent'] = self.__hash(os.path.dirname(lpath))
  734.                                 info['mime'] = self.__mimetype(lpath)
  735.  
  736.                         if self._options['rootAlias']:
  737.                                 basename = self._options['rootAlias']
  738.                         else:
  739.                                 basename = os.path.basename(self._options['root'])
  740.  
  741.                         info['link'] = self.__hash(lpath)
  742.                         info['linkTo'] = basename + lpath[len(self._options['root']):]
  743.                         info['read'] = info['read'] and self.__isAllowed(lpath, 'read')
  744.                         info['write'] = info['write'] and self.__isAllowed(lpath, 'write')
  745.                         info['rm'] = self.__isAllowed(lpath, 'rm')
  746.                 else:
  747.                         lpath = False
  748.  
  749.                 if not info['mime'] == 'directory':
  750.                         if self._options['fileURL'] and info['read'] is True:
  751.                                 if lpath:
  752.                                         info['url'] = self.__path2url(lpath)
  753.                                 else:
  754.                                         info['url'] = self.__path2url(path)
  755.                         if info['mime'][0:5] == 'image':
  756.                                 if self.__canCreateTmb():
  757.                                         dim = self.__getImgSize(path)
  758.                                         if dim:
  759.                                                 info['dim'] = dim
  760.                                                 info['resize'] = True
  761.  
  762.                                         # if we are in tmb dir, files are thumbs itself
  763.                                         if os.path.dirname(path) == self._options['tmbDir']:
  764.                                                 info['tmb'] = self.__path2url(path)
  765.                                                 return info
  766.  
  767.                                         tmb = os.path.join(self._options['tmbDir'], info['hash'] + '.png')
  768.  
  769.                                         if os.path.exists(tmb):
  770.                                                 tmbUrl = self.__path2url(tmb)
  771.                                                 info['tmb'] = tmbUrl
  772.                                         else:
  773.                                                 self._response['tmb'] = True
  774.  
  775.                 return info
  776.  
  777.  
  778.         def __tree(self, path):
  779.                 """Return directory tree starting from path"""
  780.  
  781.                 if not os.path.isdir(path): return ''
  782.                 if os.path.islink(path): return ''
  783.  
  784.                 if path == self._options['root'] and self._options['rootAlias']:
  785.                         name = self._options['rootAlias']
  786.                 else:
  787.                         name = os.path.basename(path)
  788.                 tree = {
  789.                         'hash': self.__hash(path),
  790.                         'name': self.__checkUtf8(name),
  791.                         'read': self.__isAllowed(path, 'read'),
  792.                         'write': self.__isAllowed(path, 'write'),
  793.                         'dirs': []
  794.                 }
  795.  
  796.                 if self.__isAllowed(path, 'read'):
  797.                         for d in sorted(os.listdir(path)):
  798.                                 pd = os.path.join(path, d)
  799.                                 if os.path.isdir(pd) and not os.path.islink(pd) and self.__isAccepted(d):
  800.                                         tree['dirs'].append(self.__tree(pd))
  801.  
  802.                 return tree
  803.  
  804.         def __uniqueName(self, path, copy = ' copy'):
  805.                 """Generate unique name for file copied file"""
  806.                 curDir = os.path.dirname(path)
  807.                 curName = os.path.basename(path)
  808.                 lastDot = curName.rfind('.')
  809.                 ext = newName = ''
  810.  
  811.                 if not os.path.isdir(path) and re.search(r'\..{3}\.(gz|bz|bz2)$', curName):
  812.                         pos = -7
  813.                         if curName[-1:] == '2':
  814.                                 pos -= 1
  815.                         ext = curName[pos:]
  816.                         oldName = curName[0:pos]
  817.                         newName = oldName + copy
  818.                 elif os.path.isdir(path) or lastDot <= 0:
  819.                         oldName = curName
  820.                         newName = oldName + copy
  821.                         pass
  822.                 else:
  823.                         ext = curName[lastDot:]
  824.                         oldName = curName[0:lastDot]
  825.                         newName = oldName + copy
  826.  
  827.                 pos = 0
  828.  
  829.                 if oldName[-len(copy):] == copy:
  830.                         newName = oldName
  831.                 elif re.search(r'' + copy +'\s\d+$', oldName):
  832.                         pos = oldName.rfind(copy) + len(copy)
  833.                         newName = oldName[0:pos]
  834.                 else:
  835.                         newPath = os.path.join(curDir, newName + ext)
  836.                         if not os.path.exists(newPath):
  837.                                 return newPath
  838.  
  839.                 # if we are here then copy already exists or making copy of copy
  840.                 # we will make new indexed copy *black magic*
  841.                 idx = 1
  842.                 if pos > 0: idx = int(oldName[pos:])
  843.                 while True:
  844.                         idx += 1
  845.                         newNameExt = newName + ' ' + str(idx) + ext
  846.                         newPath = os.path.join(curDir, newNameExt)
  847.                         if not os.path.exists(newPath):
  848.                                 return newPath
  849.                         # if idx >= 1000: break # possible loop
  850.  
  851.                 return
  852.  
  853.         def __remove(self, target):
  854.                 """Internal remove procedure"""
  855.                 if not self.__isAllowed(target, 'rm'):
  856.                         self.__errorData(target, 'Access denied')
  857.  
  858.                 if not os.path.isdir(target):
  859.                         try:
  860.                                 os.unlink(target)
  861.                                 return True
  862.                         except:
  863.                                 self.__errorData(target, 'Remove failed')
  864.                                 return False
  865.                 else:
  866.                         for i in os.listdir(target):
  867.                                 if self.__isAccepted(i):
  868.                                         self.__remove(os.path.join(target, i))
  869.  
  870.                         try:
  871.                                 os.rmdir(target)
  872.                                 return True
  873.                         except:
  874.                                 self.__errorData(target, 'Remove failed')
  875.                                 return False
  876.                 pass
  877.  
  878.         def __copy(self, src, dst):
  879.                 """Internal copy procedure"""
  880.                 dstDir = os.path.dirname(dst)
  881.                 if not self.__isAllowed(src, 'read'):
  882.                         self.__errorData(src, 'Access denied')
  883.                         return False
  884.                 if not self.__isAllowed(dstDir, 'write'):
  885.                         self.__errorData(dstDir, 'Access denied')
  886.                         return False
  887.                 if os.path.exists(dst):
  888.                         self.__errorData(dst, 'File or folder with the same name already exists')
  889.                         return False
  890.  
  891.                 if not os.path.isdir(src):
  892.                         try:
  893.                                 shutil.copyfile(src, dst)
  894.                                 shutil.copymode(src, dst)
  895.                                 return True
  896.                         except:
  897.                                 self.__errorData(src, 'Unable to copy files')
  898.                                 return False
  899.                 else:
  900.                         try:
  901.                                 os.mkdir(dst)
  902.                                 shutil.copymode(src, dst)
  903.                         except:
  904.                                 self.__errorData(src, 'Unable to copy files')
  905.                                 return False
  906.  
  907.                         for i in os.listdir(src):
  908.                                 newSrc = os.path.join(src, i)
  909.                                 newDst = os.path.join(dst, i)
  910.                                 if not self.__copy(newSrc, newDst):
  911.                                         self.__errorData(newSrc, 'Unable to copy files')
  912.                                         return False
  913.  
  914.                 return True
  915.  
  916.         def __checkName(self, name):
  917.                 """Check for valid file/dir name"""
  918.                 pattern = r'[\/\\\:\<\>]'
  919.                 if re.search(pattern, name):
  920.                         return False
  921.                 return True
  922.  
  923.         def __findDir(self, fhash, path):
  924.                 """Find directory by hash"""
  925.                 fhash = str(fhash)
  926.                 if not path:
  927.                         path = self._options['root']
  928.                         if fhash == self.__hash(path):
  929.                                 return path
  930.  
  931.                 if not os.path.isdir(path):
  932.                         return None
  933.  
  934.                 for d in os.listdir(path):
  935.                         pd = os.path.join(path, d)
  936.                         if os.path.isdir(pd) and not os.path.islink(pd):
  937.                                 if fhash == self.__hash(pd):
  938.                                         return pd
  939.                                 else:
  940.                                         ret = self.__findDir(fhash, pd)
  941.                                         if ret:
  942.                                                 return ret
  943.                 return None
  944.  
  945.         def __find(self, fhash, parent):
  946.                 """Find file/dir by hash"""
  947.                 fhash = str(fhash)
  948.                 if os.path.isdir(parent):
  949.                         for i in os.listdir(parent):
  950.                                 path = os.path.join(parent, i)
  951.                                 if fhash == self.__hash(path):
  952.                                         return path
  953.                 return None
  954.  
  955.         def __read(self):
  956.                 if 'current' in self._request and 'target' in self._request:
  957.                         curDir = self.__findDir(self._request['current'], None)
  958.                         curFile = self.__find(self._request['target'], curDir)
  959.                         if curDir and curFile:
  960.                                 if self.__isAllowed(curFile, 'read'):
  961.                                         self._response['content'] = open(curFile, 'r').read()
  962.                                 else:
  963.                                         self._response['error'] = 'Access denied'
  964.                                 return
  965.  
  966.                 self._response['error'] = 'Invalid parameters'
  967.                 return
  968.  
  969.         def __edit(self):
  970.                 """Save content in file"""
  971.                 error = ''
  972.                 if 'current' in self._request and 'target' in self._request and 'content' in self._request:
  973.                         curDir = self.__findDir(self._request['current'], None)
  974.                         curFile = self.__find(self._request['target'], curDir)
  975.                         error = curFile
  976.                         if curFile and curDir:
  977.                                 if self.__isAllowed(curFile, 'write'):
  978.                                         try:
  979.                                                 f = open(curFile, 'w+')
  980.                                                 f.write(self._request['content'])
  981.                                                 f.close()
  982.                                                 self._response['target'] = self.__info(curFile)
  983.                                         except:
  984.                                                 self._response['error'] = 'Unable to write to file'
  985.                                 else:
  986.                                         self._response['error'] = 'Access denied'
  987.                         return
  988.  
  989.                 self._response['error'] = 'Invalid parameters'
  990.                 return
  991.  
  992.         def __archive(self):
  993.                 """Compress files/directories to archive"""
  994.                 self.__checkArchivers()
  995.  
  996.                 if (
  997.                         not self._options['archivers']['create'] or not 'type' in self._request
  998.                         or not 'current' in self._request
  999.                         or not 'targets[]' in self._request
  1000.                         or not 'name' in self._request
  1001.                         ):
  1002.                         self._response['error'] = 'Invalid parameters'
  1003.                         return
  1004.  
  1005.                 curDir = self.__findDir(self._request['current'], None)
  1006.                 archiveType = self._request['type']
  1007.                 if (
  1008.                         not archiveType in self._options['archivers']['create']
  1009.                         or not archiveType in self._options['archiveMimes']
  1010.                         or not curDir
  1011.                         or not self.__isAllowed(curDir, 'write')
  1012.                         ):
  1013.                         self._response['error'] = 'Unable to create archive'
  1014.                         return
  1015.  
  1016.                 files = self._request['targets[]']
  1017.                 if not isinstance(files, list):
  1018.                         files = [files]
  1019.  
  1020.                 realFiles = []
  1021.                 for fhash in files:
  1022.                         curFile = self.__find(fhash, curDir)
  1023.                         if not curFile:
  1024.                                 self._response['error'] = 'File not found'
  1025.                                 return
  1026.                         realFiles.append(os.path.basename(curFile))
  1027.  
  1028.                 arc = self._options['archivers']['create'][archiveType]
  1029.                 if len(realFiles) > 1:
  1030.                         archiveName = self._request['name']
  1031.                 else:
  1032.                         archiveName = realFiles[0]
  1033.                 archiveName += '.' + arc['ext']
  1034.                 archiveName = self.__uniqueName(archiveName, '')
  1035.                 archivePath = os.path.join(curDir, archiveName)
  1036.  
  1037.                 cmd = [arc['cmd']]
  1038.                 for a in arc['argc'].split():
  1039.                         cmd.append(a)
  1040.                 cmd.append(archiveName)
  1041.                 for f in realFiles:
  1042.                         cmd.append(f)
  1043.  
  1044.                 curCwd = os.getcwd()
  1045.                 os.chdir(curDir)
  1046.                 self.__runSubProcess(cmd)
  1047.                 os.chdir(curCwd)
  1048.  
  1049.                 if os.path.exists(archivePath):
  1050.                         self.__content(curDir, False)
  1051.                         self._response['select'] = [self.__hash(archivePath)]
  1052.                 else:
  1053.                         self._response['error'] = 'Unable to create archive'
  1054.  
  1055.                 return
  1056.  
  1057.         def __extract(self):
  1058.                 """Uncompress archive"""
  1059.                 if not 'current' in self._request or not 'target' in self._request:
  1060.                         self._response['error'] = 'Invalid parameters'
  1061.                         return
  1062.  
  1063.                 curDir = self.__findDir(self._request['current'], None)
  1064.                 curFile = self.__find(self._request['target'], curDir)
  1065.                 mime = self.__mimetype(curFile)
  1066.                 self.__checkArchivers()
  1067.  
  1068.                 if (
  1069.                         not mime in self._options['archivers']['extract']
  1070.                         or not curDir
  1071.                         or not curFile
  1072.                         or not self.__isAllowed(curDir, 'write')
  1073.                         ):
  1074.                         self._response['error'] = 'Invalid parameters'
  1075.                         return
  1076.  
  1077.                 arc = self._options['archivers']['extract'][mime]
  1078.  
  1079.                 cmd = [arc['cmd']]
  1080.                 for a in arc['argc'].split():
  1081.                         cmd.append(a)
  1082.                 cmd.append(curFile)
  1083.  
  1084.                 curCwd = os.getcwd()
  1085.                 os.chdir(curDir)
  1086.                 ret = self.__runSubProcess(cmd)
  1087.                 os.chdir(curCwd)
  1088.  
  1089.                 if ret:
  1090.                         self.__content(curDir, True)
  1091.                 else:
  1092.                         self._response['error'] = 'Unable to extract files from archive'
  1093.  
  1094.                 return
  1095.  
  1096.  
  1097.         def __ping(self):
  1098.                 """Workaround for Safari"""
  1099.                 self.httpStatusCode = 200
  1100.                 self.httpHeader['Connection'] = 'close'
  1101.                 return
  1102.  
  1103.         def __mimetype(self, path):
  1104.                 """Detect mimetype of file"""
  1105.                 mime = mimetypes.guess_type(path)[0] or 'unknown'
  1106.                 ext = path[path.rfind('.') + 1:]
  1107.  
  1108.                 if mime == 'unknown' and ('.' + ext) in mimetypes.types_map:
  1109.                         mime = mimetypes.types_map['.' + ext]
  1110.  
  1111.                 if mime == 'text/plain' and ext == 'pl':
  1112.                         mime = self._mimeType[ext]
  1113.  
  1114.                 if mime == 'application/vnd.ms-office' and ext == 'doc':
  1115.                         mime = self._mimeType[ext]
  1116.  
  1117.                 if mime == 'unknown':
  1118.                         if os.path.basename(path) in ['README', 'ChangeLog']:
  1119.                                 mime = 'text/plain'
  1120.                         else:
  1121.                                 if ext in self._mimeType:
  1122.                                         mime = self._mimeType[ext]
  1123.  
  1124.                 # self.__debug('mime ' + os.path.basename(path), ext + ' ' + mime)
  1125.                 return mime
  1126.  
  1127.         def __tmb(self, path, tmb):
  1128.                 """Internal thumbnail create procedure"""
  1129.                 try:
  1130.                         im = self._im.open(path).copy()
  1131.                         size = self._options['tmbSize'], self._options['tmbSize']
  1132.                         box = self.__cropTuple(im.size)
  1133.                         if box:
  1134.                                 im = im.crop(box)
  1135.                         im.thumbnail(size, self._im.ANTIALIAS)
  1136.                         im.save(tmb, 'PNG')
  1137.                 except Exception, e:
  1138.                         self.__debug('tmbFailed_' + path, str(e))
  1139.                         return False
  1140.                 return True
  1141.  
  1142.         def __rmTmb(self, path):
  1143.                 tmb = self.__tmbPath(path)
  1144.                 if self._options['tmbDir']:
  1145.                         if os.path.exists(tmb):
  1146.                                 try:
  1147.                                         os.unlink(tmb)
  1148.                                 except:
  1149.                                         pass
  1150.  
  1151.         def __cropTuple(self, size):
  1152.                 w, h = size
  1153.                 if w > h: # landscape
  1154.                         l = int((w - h) / 2)
  1155.                         u = 0
  1156.                         r = l + h
  1157.                         d = h
  1158.                         return (l, u, r, d)
  1159.                 elif h > w: # portrait
  1160.                         l = 0
  1161.                         u = int((h - w) / 2)
  1162.                         r = w
  1163.                         d = u + w
  1164.                         return (l, u, r, d)
  1165.                 else: # cube
  1166.                         pass
  1167.  
  1168.                 return False
  1169.  
  1170.         def __readlink(self, path):
  1171.                 """Read link and return real path if not broken"""
  1172.                 target = os.readlink(path);
  1173.                 if not target[0] == '/':
  1174.                         target = os.path.join(os.path.dirname(path), target)
  1175.                 target = os.path.normpath(target)
  1176.                 if os.path.exists(target):
  1177.                         if not target.find(self._options['root']) == -1:
  1178.                                 return target
  1179.                 return False
  1180.  
  1181.  
  1182.         def __dirSize(self, path):
  1183.                 total_size = 0
  1184.                 if self._options['dirSize']:
  1185.                         for dirpath, dirnames, filenames in os.walk(path):
  1186.                                 for f in filenames:
  1187.                                         fp = os.path.join(dirpath, f)
  1188.                                         if os.path.exists(fp):
  1189.                                                 total_size += os.stat(fp).st_size
  1190.                 else:
  1191.                         total_size = os.lstat(path).st_size
  1192.                 return total_size
  1193.  
  1194.         def __fbuffer(self, f, chunk_size = _options['uploadWriteChunk']):
  1195.                 while True:
  1196.                         chunk = f.read(chunk_size)
  1197.                         if not chunk: break
  1198.                         yield chunk
  1199.  
  1200.  
  1201.         def __canCreateTmb(self, path = None):
  1202.                 if self._options['imgLib'] and self._options['tmbDir']:
  1203.                         if path is not None:
  1204.                                 mime = self.__mimetype(path)
  1205.                                 if not mime[0:5] == 'image':
  1206.                                         return False
  1207.                         return True
  1208.                 else:
  1209.                         return False
  1210.  
  1211.         def __tmbPath(self, path):
  1212.                 tmb = False
  1213.                 if self._options['tmbDir']:
  1214.                         if not os.path.dirname(path) == self._options['tmbDir']:
  1215.                                 tmb = os.path.join(self._options['tmbDir'], self.__hash(path) + '.png')
  1216.                 return tmb
  1217.  
  1218.         def __isUploadAllow(self, name):
  1219.                 allow = False
  1220.                 deny = False
  1221.                 mime = self.__mimetype(name)
  1222.  
  1223.                 if 'all' in self._options['uploadAllow']:
  1224.                         allow = True
  1225.                 else:
  1226.                         for a in self._options['uploadAllow']:
  1227.                                 if mime.find(a) == 0:
  1228.                                         allow = True
  1229.  
  1230.                 if 'all' in self._options['uploadDeny']:
  1231.                         deny = True
  1232.                 else:
  1233.                         for d in self._options['uploadDeny']:
  1234.                                 if mime.find(d) == 0:
  1235.                                         deny = True
  1236.  
  1237.                 if self._options['uploadOrder'][0] == 'allow': # ,deny
  1238.                         if deny is True:
  1239.                                 return False
  1240.                         elif allow is True:
  1241.                                 return True
  1242.                         else:
  1243.                                 return False
  1244.                 else: # deny,allow
  1245.                         if allow is True:
  1246.                                 return True
  1247.                         elif deny is True:
  1248.                                 return False
  1249.                         else:
  1250.                                 return True
  1251.  
  1252.         def __isAccepted(self, target):
  1253.                 if target == '.' or target == '..':
  1254.                         return False
  1255.                 if target[0:1] == '.' and not self._options['dotFiles']:
  1256.                         return False
  1257.                 return True
  1258.  
  1259.         def __isAllowed(self, path, access):
  1260.                 if not os.path.exists(path):
  1261.                         return False
  1262.  
  1263.                 if access == 'read':
  1264.                         if not os.access(path, os.R_OK):
  1265.                                 self.__errorData(path, access)
  1266.                                 return False
  1267.                 elif access == 'write':
  1268.                         if not os.access(path, os.W_OK):
  1269.                                 self.__errorData(path, access)
  1270.                                 return False
  1271.                 elif access == 'rm':
  1272.                         if not os.access(os.path.dirname(path), os.W_OK):
  1273.                                 self.__errorData(path, access)
  1274.                                 return False
  1275.                 else:
  1276.                         return False
  1277.  
  1278.                 path = path[len(os.path.normpath(self._options['root'])):]
  1279.                 for ppath in self._options['perms']:
  1280.                         regex = r'' + ppath
  1281.                         if re.search(regex, path) and access in self._options['perms'][ppath]:
  1282.                                 return self._options['perms'][ppath][access]
  1283.  
  1284.                 return self._options['defaults'][access]
  1285.  
  1286.         def __hash(self, path):
  1287.                 """Hash of the path"""
  1288.                 m = hashlib.md5()
  1289.                 m.update(path)
  1290.                 return str(m.hexdigest())
  1291.  
  1292.         def __path2url(self, path):
  1293.                 curDir = path
  1294.                 length = len(self._options['root'])
  1295.                 url = str(self._options['URL'] + curDir[length:]).replace(os.sep, '/')
  1296.  
  1297.                 try:
  1298.                         import urllib
  1299.                         url = urllib.quote(url, '/:~')
  1300.                 except:
  1301.                         pass
  1302.                 return url
  1303.  
  1304.         def __errorData(self, path, msg):
  1305.                 """Collect error/warning messages"""
  1306.                 self._errorData[path] = msg
  1307.  
  1308.         def __initImgLib(self):
  1309.                 if not self._options['imgLib'] is False and self._im is None:
  1310.                         try:
  1311.                                 import Image
  1312.                                 Image
  1313.                                 self._im = Image
  1314.                                 self._options['imgLib'] = 'PIL'
  1315.                         except:
  1316.                                 self._options['imgLib'] = False
  1317.                                 self._im = False
  1318.  
  1319.                 self.__debug('imgLib', self._options['imgLib'])
  1320.                 return self._options['imgLib']
  1321.  
  1322.         def __getImgSize(self, path):
  1323.                 self.__initImgLib();
  1324.                 if self.__canCreateTmb():
  1325.                         try:
  1326.                                 im = self._im.open(path)
  1327.                                 return str(im.size[0]) + 'x' + str(im.size[1])
  1328.                         except:
  1329.                                 pass
  1330.  
  1331.                 return False
  1332.  
  1333.         def __debug(self, k, v):
  1334.                 if self._options['debug']:
  1335.                         self._response['debug'].update({k: v})
  1336.                 return
  1337.  
  1338.         def __checkArchivers(self):
  1339.                 # import subprocess
  1340.                 # sp = subprocess.Popen(['tar', '--version'], shell = False,
  1341.                 # stdout = subprocess.PIPE, stderr=subprocess.PIPE)
  1342.                 # out, err = sp.communicate()
  1343.                 # print 'out:', out, '\nerr:', err, '\n'
  1344.                 archive = { 'create': {}, 'extract': {} }
  1345.                 c = archive['create']
  1346.                 e = archive['extract']
  1347.  
  1348.                 tar = self.__runSubProcess(['tar', '--version'])
  1349.                 gzip = self.__runSubProcess(['gzip', '--version'])
  1350.                 bzip2 = self.__runSubProcess(['bzip2', '--version'])
  1351.                 zipc = self.__runSubProcess(['zip', '--version'])
  1352.                 unzip = self.__runSubProcess(['unzip', '--help'])
  1353.                 rar = self.__runSubProcess(['rar', '--version'], validReturn = [0, 7])
  1354.                 unrar = self.__runSubProcess(['unrar'], validReturn = [0, 7])
  1355.                 p7z = self.__runSubProcess(['7z', '--help'])
  1356.                 p7za = self.__runSubProcess(['7za', '--help'])
  1357.                 p7zr = self.__runSubProcess(['7zr', '--help'])
  1358.  
  1359.                 # tar = False
  1360.                 # tar = gzip = bzip2 = zipc = unzip = rar = unrar = False
  1361.                 # print tar, gzip, bzip2, zipc, unzip, rar, unrar, p7z, p7za, p7zr
  1362.  
  1363.                 if tar:
  1364.                         mime = 'application/x-tar'
  1365.                         c.update({mime: {'cmd': 'tar', 'argc': '-cf', 'ext': 'tar'}})
  1366.                         e.update({mime: {'cmd': 'tar', 'argc': '-xf', 'ext': 'tar'}})
  1367.  
  1368.                 if tar and gzip:
  1369.                         mime = 'application/x-gzip'
  1370.                         c.update({mime: {'cmd': 'tar', 'argc': '-czf', 'ext': 'tar.gz'}})
  1371.                         e.update({mime: {'cmd': 'tar', 'argc': '-xzf', 'ext': 'tar.gz'}})
  1372.  
  1373.                 if tar and bzip2:
  1374.                         mime = 'application/x-bzip2'
  1375.                         c.update({mime: {'cmd': 'tar', 'argc': '-cjf', 'ext': 'tar.bz2'}})
  1376.                         e.update({mime: {'cmd': 'tar', 'argc': '-xjf', 'ext': 'tar.bz2'}})
  1377.  
  1378.                 mime = 'application/zip'
  1379.                 if zipc:
  1380.                         c.update({mime: {'cmd': 'zip', 'argc': '-r9', 'ext': 'zip'}})
  1381.                 if unzip:
  1382.                         e.update({mime: {'cmd': 'unzip', 'argc': '', 'ext': 'zip'}})
  1383.  
  1384.                 mime = 'application/x-rar'
  1385.                 if rar:
  1386.                         c.update({mime: {'cmd': 'rar', 'argc': 'a -inul', 'ext': 'rar'}})
  1387.                         e.update({mime: {'cmd': 'rar', 'argc': 'x -y', 'ext': 'rar'}})
  1388.                 elif unrar:
  1389.                         e.update({mime: {'cmd': 'unrar', 'argc': 'x -y', 'ext': 'rar'}})
  1390.  
  1391.                 p7zip = None
  1392.                 if p7z:
  1393.                         p7zip = '7z'
  1394.                 elif p7za:
  1395.                         p7zip = '7za'
  1396.                 elif p7zr:
  1397.                         p7zip = '7zr'
  1398.  
  1399.                 if p7zip:
  1400.                         mime = 'application/x-7z-compressed'
  1401.                         c.update({mime: {'cmd': p7zip, 'argc': 'a -t7z', 'ext': '7z'}})
  1402.                         e.update({mime: {'cmd': p7zip, 'argc': 'e -y', 'ext': '7z'}})
  1403.  
  1404.                         mime = 'application/x-tar'
  1405.                         if not mime in c:
  1406.                                 c.update({mime: {'cmd': p7zip, 'argc': 'a -ttar', 'ext': 'tar'}})
  1407.                         if not mime in e:
  1408.                                 e.update({mime: {'cmd': p7zip, 'argc': 'e -y', 'ext': 'tar'}})
  1409.  
  1410.                         mime = 'application/x-gzip'
  1411.                         if not mime in c:
  1412.                                 c.update({mime: {'cmd': p7zip, 'argc': 'a -tgzip', 'ext': 'gz'}})
  1413.                         if not mime in e:
  1414.                                 e.update({mime: {'cmd': p7zip, 'argc': 'e -y', 'ext': 'tar.gz'}})
  1415.  
  1416.                         mime = 'application/x-bzip2'
  1417.                         if not mime in c:
  1418.                                 c.update({mime: {'cmd': p7zip, 'argc': 'a -tbzip2', 'ext': 'bz2'}})
  1419.                         if not mime in e:
  1420.                                 e.update({mime: {'cmd': p7zip, 'argc': 'e -y', 'ext': 'tar.bz2'}})
  1421.                         mime = 'application/zip'
  1422.                         if not mime in c:
  1423.                                 c.update({mime: {'cmd': p7zip, 'argc': 'a -tzip', 'ext': 'zip'}})
  1424.                         if not mime in e:
  1425.                                 e.update({mime: {'cmd': p7zip, 'argc': 'e -y', 'ext': 'zip'}})
  1426.  
  1427.                 if not self._options['archiveMimes']:
  1428.                         self._options['archiveMimes'] = c.keys()
  1429.                 else:
  1430.                         pass
  1431.  
  1432.                 self._options['archivers'] = archive
  1433.                 pass
  1434.  
  1435.         def __runSubProcess(self, cmd, validReturn = [0]):
  1436.                 if self._sp is None:
  1437.                         import subprocess
  1438.                         self._sp = subprocess
  1439.                 try:
  1440.                         sp = self._sp.Popen(cmd, shell = False, stdout = self._sp.PIPE, stderr = self._sp.PIPE, stdin = self._sp.PIPE)
  1441.                         out, err = sp.communicate('')
  1442.                         ret = sp.returncode
  1443.                         # print cmd, ret, out, err
  1444.                 except:
  1445.                         return False
  1446.  
  1447.                 if not ret in validReturn:
  1448.                         return False
  1449.  
  1450.                 return True
  1451.         def __checkUtf8(self, name):
  1452.                 try:
  1453.                         name.decode('utf-8')
  1454.                 except UnicodeDecodeError:
  1455.                         name = unicode(name, 'utf-8', 'replace')
  1456.                         self.__debug('invalid encoding', name)
  1457.                         #name += ' (invalid encoding)'
  1458.                 return name

Raw Paste


Login or Register to edit or fork this paste. It's free.