📄 cachemgr.pyc_dis
字号:
#! /usr/bin/env python
# emacs-mode: -*- python-*-
import md5
import string
import os
import urlparse
import logging
import os.path
import time
import stat
import twisted.web.client
import config
import const
miCacheFileMode = ((stat.S_IRWXO | stat.S_IRWXU) | stat.S_IRWXG)
miCacheReqCounter = 0
miCacheHitCounter = 0
miCacheTime = config.image_cache_default_min
if (miCacheTime == 999):
miCacheTime = ((((10 * 12) * 30) * 24) * 60)
log = logging.getLogger(const.CONST_APP_LOGGER)
class Image:
def __init__(self, asContent = None, aiRWidth = None, aiRHeight = None, asColor = None, asSrc = None):
self.csContent = asContent
self.csColor = asColor
self.csSrc = asSrc
self.ciCacheTime = 999
self.cbStaticImage = True
self.cbCacheable = True
self.csRSize = None
self.csType = None
self.csScheme = None
self.ciPort = None
self.ciRWidth = aiRWidth
self.ciRHeight = aiRHeight
self.ciAWidth = None
self.ciAHeight = None
self.ciFWidth = None
self.ciFHeight = None
self.csFormat = None
self.csCacheLoc = None
def cnSetASize(self, aiWidth, aiHeight):
"""
设定图片的实际大小
"""
self.ciAWidth = aiWidth
self.ciAHeight = aiHeight
liWidthRatio = (float(self.ciAWidth) / self.ciRWidth)
liHeightRatio = (float(self.ciAHeight) / self.ciRHeight)
liRatio = max(liWidthRatio, liHeightRatio)
if (liRatio <= 1):
self.ciFWidth = self.ciAWidth
self.ciFHeight = self.ciAHeight
else:
self.ciFWidth = int((self.ciAWidth / liRatio))
self.ciFHeight = int((self.ciAHeight / liRatio))
def csGetContent(self):
"""
读取图片的内容
"""
if ((not self.csContent) and self.csCacheLoc):
self.csContent = open(self.csCacheLoc, "rb").read()
return self.csContent
def cnSetRSize(self, asSize):
self.csRSize = asSize
lsSep = "x"
(lsWidth, lsHeight,) = asSize.split(lsSep)
self.ciRWidth = int(lsWidth)
self.ciRHeight = int(lsHeight)
if (self.ciRWidth == 0):
self.ciRWidth = 1
if (self.ciRHeight == 0):
self.ciRHeight = 1
def cnSetColor(self, asColor):
self.csColor = asColor
def cnParseURL(self):
if (self.csSrc[-9:-3] == ":cache"):
self.ciCacheTime = int(self.csSrc[-3:])
self.csSrc = self.csSrc[:-9]
(self.csScheme, self.csHost, self.ciPort, self.csPath,) = twisted.web.client._parse(self.csSrc)
lsSuffix = self.csPath[-4:]
if (lsSuffix.lower() not in config.mlStaticImage):
self.cbStaticImage = False
if (self.csScheme == "https"):
self.cbStaticImage = False
if (lsSuffix.lower() in config.mlNoCacheSuffix):
self.cbStaticImage = False
self.cbCacheable = False
if (self.csPath.find("?") != -1):
self.cbStaticImage = False
if (config.cache_dynamic_url_image == 0):
self.cbCacheable = False
else:
self.cbCacheable = True
def cnSetCacheControl(self, alPragma, alCacheControl, alLastModified, alETag):
"""
对于从web上获得的图片处理其header中对cache管理的信息
"""
for value in alPragma:
if (value.lower() == "no-cache"):
self.cbCacheable = False
return
if ((len(alLastModified) != 0) or (len(alETag) != 0)):
self.cbCacheable = True
return
if (len(alCacheControl) == 0):
self.cbCacheable = False
for value in alCacheControl:
if (value.lower() in config.mlNoCacheControl):
self.cbCacheable = False
return
elif (value.lower() in config.mlYesCacheControl):
self.cbCacheable = True
return
def mlSrcToFile(asBaseDir, asSrc, aiHashLevel, aiFirstLevel, asPrefix = "", asSuffix = "", aiNameLen = 16):
"""
根据字符串, 生成hash文件的路径
asBaseDir,最上曾层的路径
asSrc, 用于生成hash文件的源字符串, 可以是 url 或者其它的任意字符串
aiHashLevel, 支持 0,1,2,3三种层次的hash层次
aiFirstLevel, 第一层次的hash目录分为多少个子目录,例如可以制造出16x256的目录结构
asPrefix, 文件名前面,可以增加任意前缀
asSuffix, 文件名后面,可以增加任意后缀
aiNameLen, 文件名的md5部分,的长度可选
返回 :
路径:例如4/16
文件名:例如"e98u723lasdzx98u"
全路径:路径+文件名
"""
lsPath = ""
lsFileName = ""
llPath = [asBaseDir]
lsMD5 = md5.new(asSrc).hexdigest()[:aiNameLen]
lsFileName = ((asPrefix + lsMD5) + asSuffix)
if (aiHashLevel >= 1):
llPath.append(`(int(lsFileName[:2], 16) % aiFirstLevel)`)
if (aiHashLevel >= 2):
llPath.append(`int(lsFileName[2:4], 16)`)
if (aiHashLevel >= 3):
llPath.append(`int(lsFileName[4:6], 16)`)
lsPath = string.join(llPath, os.sep)
return ((lsPath + os.sep) + lsFileName)
class CacheManager:
"""
管理resize的cache
"""
def __init__(self):
self.csPath = config.image_cache_path
def csGetSrcCache(self, aoImage):
"""
获取一个图片的转换前cache
"""
global miCacheHitCounter
global miCacheReqCounter
return
miCacheReqCounter += 1
lsResultPath = None
liCacheTime = min(aoImage.ciCacheTime, miCacheTime)
lsFullPath = mlSrcToFile(self.csPath, aoImage.csSrc, config.image_cache_hash_level, config.image_cache_first_level)
liSize = -1
try:
liSize = os.path.getsize(lsFullPath)
except:
pass
if (liSize != -1):
if (liSize == 0):
liCacheTime = config.image_cache_error_min
liCacheTime = (liCacheTime * 60)
if ((time.time() - os.path.getmtime(lsFullPath)) < liCacheTime):
lsResultPath = lsFullPath
else:
log.debug(("%s cache expired" % lsFullPath))
if lsResultPath:
miCacheHitCounter += 1
return lsResultPath
def cbWriteCache(self, aoImage):
"""
写一幅图片的cache
"""
return
lbRet = True
log.debug(("save cache for %s,size(%d)" % (aoImage.csSrc,
len(aoImage.csContent))))
if (not aoImage.cbCacheable):
log.debug("dynamic image,ignore saving")
return True
lsFullPath = mlSrcToFile(self.csPath, aoImage.csSrc, config.image_cache_hash_level, config.image_cache_first_level)
try:
lsDir = os.path.dirname(lsFullPath)
if (not os.path.exists(lsDir)):
os.makedirs(lsDir)
open(lsFullPath, "wb").write(aoImage.csContent)
except Exception,e:
import traceback
traceback.print_exc()
lbRet = False
log.error(("write failed,exception is %s" % e))
return lbRet
def cbWriteZeroCache(self, aoImage):
"""
对错误的图片保存空的cache
"""
lsContent = aoImage.csContent
aoImage.csContent = ""
lbRet = self.cbWriteCache(aoImage)
aoImage.csContent = lsContent
return lbRet
def cnCheckCache(self, aoImage):
"""
检查图片的cache情况,如果有转换后图片,则返回转换后图片
如果没有返回转换前图片,如果还没有只能返回空
返回:
(转换前图片,转换后图片)
"""
if (not aoImage.cbCacheable):
log.debug("dynamic image,no cache apply")
return (None, None)
lsSrc = self.csGetSrcCache(aoImage)
if (lsSrc is None):
log.debug(("cache miss:%s(%s)" % (aoImage.csSrc,
lsSrc)))
else:
log.debug(("cache hit:%s(%s)" % (aoImage.csSrc,
lsSrc)))
return (lsSrc,
None)
CacheMgr = CacheManager()
if (__name__ == "__main__"):
print mlSrcToFile("abcd", 2, 16)
# local variables:
# tab-width: 4
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -