#!/usr/bin/env python
#
# Connector for elFinder File Manager
# author Troex Nevelin <troex@fury.scancode.ru>
import hashlib
import mimetypes
import os
import os.path
import re
import shutil
import time
from datetime import datetime
class connector():
"""Connector for elFinder"""
_options = {
'root': '',
'URL': '',
'rootAlias': 'Home',
'dotFiles': False,
'dirSize': True,
'fileMode': 0644,
'dirMode': 0755,
'imgLib': 'auto',
'tmbDir': '.tmb',
'tmbAtOnce': 5,
'tmbSize': 48,
'fileURL': True,
'uploadMaxSize': 256,
'uploadWriteChunk': 8192,
'uploadAllow': [],
'uploadDeny': [],
'uploadOrder': ['deny', 'allow'],
# 'aclObj': None, # TODO
# 'aclRole': 'user', # TODO
'defaults': {
'read': True,
'write': True,
'rm': True
},
'perms': {},
'archiveMimes': {},
'archivers': {},
'disabled': [],
'debug': False
}
_commands = {
'open': '__open',
'reload': '__reload',
'mkdir': '__mkdir',
'mkfile': '__mkfile',
'rename': '__rename',
'upload': '__upload',
'paste': '__paste',
'rm': '__rm',
'duplicate': '__duplicate',
'read': '__read',
'edit': '__edit',
'extract': '__extract',
'archive': '__archive',
'resize': '__resize',
'tmb': '__thumbnails',
'ping': '__ping'
}
_mimeType = {
# text
'txt': 'text/plain',
'conf': 'text/plain',
'ini': 'text/plain',
'php': 'text/x-php',
'html': 'text/html',
'htm': 'text/html',
'js' : 'text/javascript',
'css': 'text/css',
'rtf': 'text/rtf',
'rtfd': 'text/rtfd',
'py' : 'text/x-python',
'java': 'text/x-java-source',
'rb' : 'text/x-ruby',
'sh' : 'text/x-shellscript',
'pl' : 'text/x-perl',
'sql': 'text/x-sql',
# apps
'doc': 'application/msword',
'ogg': 'application/ogg',
'7z': 'application/x-7z-compressed',
# video
'ogm': 'appllication/ogm',
'mkv': 'video/x-matroska'
}
_time = 0
_request = {}
_response = {}
_errorData = {}
_form = {}
_im = None
_sp = None
_today = 0
_yesterday = 0
# public variables
httpAllowedParameters = ('cmd', 'target', 'targets[]', 'current', 'tree', 'name',
'content', 'src', 'dst', 'cut', 'init', 'type', 'width', 'height', 'upload[]')
# return variables
httpStatusCode = 0
httpHeader = {}
httpResponse = None
def __init__(self, opts):
for opt in opts:
self._options[opt] = opts.get(opt)
self._response['debug'] = {}
self._options['URL'] = self._options['URL'].rstrip('/')
self._options['root'] = self._options['root'].rstrip(os.sep)
self.__debug('URL', self._options['URL'])
self.__debug('root', self._options['root'])
for cmd in self._options['disabled']:
if cmd in self._commands:
del self._commands[cmd]
if self._options['tmbDir']:
self._options['tmbDir'] = os.path.join(self._options['root'], self._options['tmbDir'])
if not os.path.exists(self._options['tmbDir']):
self._options['tmbDir'] = False
def __reset(self):
"""Flush per request variables"""
self.httpStatusCode = 0
self.httpHeader = {}
self.httpResponse = None
self._request = {}
self._response = {}
self._errorData = {}
self._form = {}
self._time = time.time()
t = datetime.fromtimestamp(self._time)
self._today = time.mktime(datetime(t.year, t.month, t.day).timetuple())
self._yesterday = self._today - 86400
self._response['debug'] = {}
def run(self, httpRequest = []):
"""main function"""
self.__reset()
rootOk = True
if not os.path.exists(self._options['root']) or self._options['root'] == '':
rootOk = False
self._response['error'] = 'Invalid backend configuration'
elif not self.__isAllowed(self._options['root'], 'read'):
rootOk = False
self._response['error'] = 'Access denied'
for field in self.httpAllowedParameters:
if field in httpRequest:
self._request[field] = httpRequest[field]
if rootOk is True:
if 'cmd' in self._request:
if self._request['cmd'] in self._commands:
cmd = self._commands[self._request['cmd']]
func = getattr(self, '_' + self.__class__.__name__ + cmd, None)
if callable(func):
try:
func()
except Exception, e:
self._response['error'] = 'Command Failed'
self.__debug('exception', str(e))
else:
self._response['error'] = 'Unknown command'
else:
self.__open()
if 'init' in self._request:
self.__checkArchivers()
self._response['disabled'] = self._options['disabled']
if not self._options['fileURL']:
url = ''
else:
url = self._options['URL']
self._response['params'] = {
'dotFiles': self._options['dotFiles'],
'uplMaxSize': str(self._options['uploadMaxSize']) + 'M',
'archives': self._options['archiveMimes'],
'extract': self._options['archivers']['extract'].keys(),
'url': url
}
if self._errorData:
self._response['errorData'] = self._errorData
if self._options['debug']:
self.__debug('time', (time.time() - self._time))
else:
if 'debug' in self._response:
del self._response['debug']
if self.httpStatusCode < 100:
self.httpStatusCode = 200
if not 'Content-type' in self.httpHeader:
if ('cmd' in self._request and self._request['cmd'] == 'upload') or self._options['debug']:
self.httpHeader['Content-type'] = 'text/html'
else:
self.httpHeader['Content-type'] = 'application/json'
self.httpResponse = self._response
return self.httpStatusCode, self.httpHeader, self.httpResponse
def __open(self):
"""Open file or directory"""
# try to open file
if 'current' in self._request:
curDir = self.__findDir(self._request['current'], None)
curFile = self.__find(self._request['target'], curDir)
if not curDir or not curFile or os.path.isdir(curFile):
self.httpStatusCode = 404
self.httpHeader['Content-type'] = 'text/html'
self.httpResponse = 'File not found'
return
if not self.__isAllowed(curDir, 'read') or not self.__isAllowed(curFile, 'read'):
self.httpStatusCode = 403
self.httpHeader['Content-type'] = 'text/html'
self.httpResponse = 'Access denied'
return
if os.path.islink(curFile):
curFile = self.__readlink(curFile)
if not curFile or os.path.isdir(curFile):
self.httpStatusCode = 404
self.httpHeader['Content-type'] = 'text/html'
self.httpResponse = 'File not found'
return
if (
not self.__isAllowed(os.path.dirname(curFile), 'read')
or not self.__isAllowed(curFile, 'read')
):
self.httpStatusCode = 403
self.httpHeader['Content-type'] = 'text/html'
self.httpResponse = 'Access denied'
return
mime = self.__mimetype(curFile)
parts = mime.split('/', 2)
if parts[0] == 'image': disp = 'image'
elif parts[0] == 'text': disp = 'inline'
else: disp = 'attachments'
self.httpStatusCode = 200
self.httpHeader['Content-type'] = mime
self.httpHeader['Content-Disposition'] = disp + '; filename=' + os.path.basename(curFile)
self.httpHeader['Content-Location'] = curFile.replace(self._options['root'], '')
self.httpHeader['Content-Transfer-Encoding'] = 'binary'
self.httpHeader['Content-Length'] = str(os.lstat(curFile).st_size)
self.httpHeader['Connection'] = 'close'
self._response['file'] = open(curFile, 'r')
return
# try dir
else:
path = self._options['root']
if 'target' in self._request:
target = self.__findDir(self._request['target'], None)
if not target:
self._response['error'] = 'Invalid parameters'
elif not self.__isAllowed(target, 'read'):
self._response['error'] = 'Access denied'
else:
path = target
self.__content(path, 'tree' in self._request)
pass
def __rename(self):
"""Rename file or dir"""
current = name = target = None
curDir = curName = newName = None
if 'name' in self._request and 'current' in self._request and 'target' in self._request:
name = self._request['name']
current = self._request['current']
target = self._request['target']
curDir = self.__findDir(current, None)
curName = self.__find(target, curDir)
newNa
没有合适的资源?快使用搜索试试~ 我知道了~
深灰色皮革条纹后台模板是一款高端大气的网站后台模板。.rar
共2912个文件
png:2533个
js:189个
css:62个
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 156 浏览量
2023-04-28
08:21:04
上传
评论
收藏 7.25MB RAR 举报
温馨提示
深灰色皮革条纹后台模板是一款高端大气的网站后台模板。
资源推荐
资源详情
资源评论
收起资源包目录
深灰色皮革条纹后台模板是一款高端大气的网站后台模板。.rar (2912个子文件)
Changelog 1KB
ic.css 93KB
ic-16.css 36KB
jquery-ui-1.8.13.custom.css 33KB
jquery-ui-1.8.13.custom.css 33KB
i-24.css 29KB
elfinder.css 19KB
jquery.ui.theme.css 16KB
elrte.full.css 16KB
elrte.min.css 12KB
fullcalendar.css 11KB
core.css 11KB
elrte.css 11KB
form.css 10KB
table.css 7KB
jquery.ui.datepicker.css 6KB
misc.css 4KB
button.css 4KB
jquery.jgrowl.css 4KB
jquery.plupload.queue.css 4KB
jquery.plupload.queue.css 4KB
stylesheet.css 3KB
colorpicker.css 3KB
jquery.ui.plupload.css 3KB
elrte-inner.css 3KB
elrte-inner.css 3KB
panels.css 2KB
themer.css 2KB
fluid.css 2KB
tipsy.css 2KB
jquery.ui.dialog.css 2KB
jquery.ui.tabs.css 2KB
report.css 2KB
spinner.css 2KB
reset.css 2KB
Sourcerer-1.2.css 2KB
jquery.ui.slider.css 2KB
jquery.ui.accordion.css 2KB
jquery.ui.core.css 1KB
eldialogform.css 1KB
login.css 1KB
jquery.ui.autocomplete.css 1KB
fullcalendar.print.css 1KB
elcommon.css 1KB
elreset.css 1KB
mws.theme.css 1KB
jquery.ui.resizable.css 1KB
text.css 1KB
elselect.css 1KB
demo.css 1009B
gallery.css 987B
elcolorpicker.css 856B
imgareaselect-animated.css 789B
imgareaselect-default.css 775B
imgareaselect-deprecated.css 651B
jquery.ui.progressbar.css 540B
error.css 413B
jquery.ui.base.css 357B
mws.style.css 353B
jquery.ui.css 316B
elpaddinginput.css 170B
icons.css 141B
inner-example.css 86B
Thumbs.db 800KB
Thumbs.db 342KB
Thumbs.db 54KB
Thumbs.db 52KB
Thumbs.db 36KB
Thumbs.db 36KB
Thumbs.db 34KB
Thumbs.db 20KB
Thumbs.db 18KB
Thumbs.db 18KB
Thumbs.db 11KB
Thumbs.db 8KB
Thumbs.db 6KB
Thumbs.db 5KB
PTS56F-webfontd41d.eot 30KB
PTS56F-webfont.eot 30KB
PTS76F-webfontd41d.eot 29KB
PTS76F-webfont.eot 29KB
PTC55F-webfont.eot 27KB
PTC55F-webfontd41d.eot 27KB
PTS55F-webfont.eot 26KB
PTS55F-webfontd41d.eot 26KB
PTC75F-webfontd41d.eot 26KB
PTC75F-webfont.eot 26KB
PTN57F-webfontd41d.eot 25KB
PTN57F-webfont.eot 25KB
PTS75F-webfont.eot 25KB
PTS75F-webfontd41d.eot 25KB
PTN77F-webfont.eot 24KB
PTN77F-webfontd41d.eot 24KB
spinner.gif 11KB
backgrounds.gif 3KB
throbber.gif 2KB
throbber.gif 2KB
loading.gif 1KB
loading.gif 1KB
done.gif 1024B
共 2912 条
- 1
- 2
- 3
- 4
- 5
- 6
- 30
资源评论
紫微前端
- 粉丝: 4324
- 资源: 869
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功