Уведомления

Группа в Telegram: @pythonsu

#1 Ноя. 25, 2011 05:09:16

rustamakhmetov
От:
Зарегистрирован: 2011-07-12
Сообщения: 14
Репутация: +  0  -
Профиль   Отправить e-mail  

PyQt4. Свой кэш на QAbstractNetworkCache приводит к падению Питона

Питон падает с ошибкой. Скриншот: http://gyazo.com/3706ede656c1ce7ea74d4c1bc62316ee
QNetworkDiskCache не подходит, т.к. не сохраняет ресурсы у которых установлен запрет кэширования.

PyQt: 4.8.6
OS: WinXP 32bit
Python: 2.7

Код

# coding: utf-8
try:
from hashlib import md5, sha1
except:
import md5, sha1

import os,sys
from PyQt4.QtNetwork import *
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtWebKit import *

def l(msg):
print >> sys.stderr, msg

class MyCache1(QAbstractNetworkCache):
def __init__(self, basedir, uid=None):
QAbstractNetworkCache.__init__(self)
self.basedir = basedir
if not os.path.exists(self.basedir):
os.mkdir(self.basedir)
self.uid = uid

def get_filename(self, url):
m = md5(url.toString()).hexdigest()
f = os.path.join(str(self.basedir), m)
return f + ".meta", f + ".data"

def cacheSize(self):
l("cacheSize")
return 100 * 1024 * 1024 # fake

def clear(self):
l("clear")
return 0

def data(self, url):
l("get data: " + url.toString())
mfn, dfn = self.get_filename(url)
try:
df = QFile(dfn)
df.open(QIODevice.ReadOnly)
return df
except:
l("get_data rturn 0")
return 0

def metaData(self, url):
l("metaData " + url.toString())
return QNetworkCacheMetaData()

def insert(self, device):
l("insert")
device.close()

def prepare(self, metaData):
l("get url: " + metaData.url().toString())
mfn, dfn = self.get_filename(metaData.url())
l("open file " + dfn)
df = QFile(dfn)
df.open(QIODevice.WriteOnly)
l("file opened " + dfn)
return df

def remove(self, url):
l("remove")
return True

def updateMetaData(self, metaData):
l("updateMetaData")
return

app = QApplication(sys.argv)
view = QWebView()
webpage = QWebPage()
view.setPage(webpage)
# устанавливаем свой кэш
c = MyCache1(os.path.join(os.getcwd(),"my_cache"))
webpage.networkAccessManager().setCache(c)
url ="http://qt.nokia.com/"
view.load(QUrl(url))
view.show()
app.exec_()
sys.exit()



Отредактировано (Ноя. 25, 2011 05:13:16)

Офлайн

#2 Ноя. 25, 2011 12:26:44

Isem
От:
Зарегистрирован: 2010-08-27
Сообщения: 447
Репутация: +  7  -
Профиль   Отправить e-mail  

PyQt4. Свой кэш на QAbstractNetworkCache приводит к падению Питона

Питон тут - козёл отпущения. Падает PyQt4. Больше ничего сказать не могу.



Офлайн

#3 Ноя. 29, 2011 08:26:36

rustamakhmetov
От:
Зарегистрирован: 2011-07-12
Сообщения: 14
Репутация: +  0  -
Профиль   Отправить e-mail  

PyQt4. Свой кэш на QAbstractNetworkCache приводит к падению Питона

Нет, дело было в кривом коде.
Вот рабочий вариант:

MyCache.py

# coding: utf-8
try:
from hashlib import md5, sha1
except:
import md5, sha1

import os,sys
from PyQt4.QtNetwork import *
from PyQt4.QtCore import *


def l(msg):
print >> sys.stderr, msg

class QCacheItem:
pass

class MyCache(QAbstractNetworkCache):
def __init__(self, basedir, uid=None):
QAbstractNetworkCache.__init__(self)
self.basedir = basedir
if not os.path.exists(self.basedir):
os.mkdir(self.basedir)
self.uid = uid
self.inserting = {}

def get_filename(self, url):
m = md5(url.toString()).hexdigest()
f = os.path.join(str(self.basedir), m)
return f + ".meta", f + ".data"

def cacheSize(self):
l("cacheSize")
return 100 * 1024 * 1024 # fake

def clear(self):
l("clear")
return 0

def data(self, url):
l("get data: " + url.toString())
mfn, dfn = self.get_filename(url)
try:
df = QFile(dfn)
df.open(QIODevice.ReadOnly)
return df
except IOError:
l("get_data rturn 0")
return 0

def metaData(self, url):
l("metaData " + url.toString())
return QNetworkCacheMetaData()

def insert(self, device):
l("insert")
if not device in self.inserting:
print "MyCache::insert() called on a device we don't know about: %s" % str(device)
item = self.inserting[device]
device.close()
del item

def prepare(self, metaData):
if not metaData.isValid() or not metaData.url().isValid(): # or not metaData.saveToDisk()
return None

l("get url: " + metaData.url().toString())
mfn, dfn = self.get_filename(metaData.url())
l("open file " + dfn)
l("file opened " + dfn)

cacheItem = QCacheItem()
cacheItem.metaData = metaData

try:
cacheItem.file = QFile(dfn)
cacheItem.file.open(QIODevice.ReadWrite)
except:
cacheItem.file = None

if not cacheItem.file:
print "MyCache::prepare() unable to open temporary file"
return None
device = cacheItem.file
self.inserting[device] = cacheItem
return device

def remove(self, url):
l("remove")
return True

def updateMetaData(self, metaData):
l("updateMetaData")
return
Test.py
# coding: utf-8
import os,sys
from PyQt4.QtNetwork import *
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtWebKit import *
from MyCache import MyCache

app = QApplication(sys.argv)

manager = QNetworkAccessManager()
diskCache = MyCache(QString(os.path.join(os.getcwd(),"cache")))
manager.setCache(diskCache)

view = QWebView()
webpage = QWebPage()
view.setPage(webpage)

webpage.setNetworkAccessManager(manager)

url = "http://qt.nokia.com/"
view.load(QUrl(url))
view.show()
app.exec_()
sys.exit()



Офлайн

#4 Ноя. 30, 2011 13:49:49

Isem
От:
Зарегистрирован: 2010-08-27
Сообщения: 447
Репутация: +  7  -
Профиль   Отправить e-mail  

PyQt4. Свой кэш на QAbstractNetworkCache приводит к падению Питона

rustamakhmetov
Нет, дело было в кривом коде
Кривой код на питоне не может привести к падению питона. (если нет, приведите пример). Значит кривой код плюс кривой PQ4 - два брата-близнеца.



Офлайн

#5 Ноя. 30, 2011 17:18:38

rustamakhmetov
От:
Зарегистрирован: 2011-07-12
Сообщения: 14
Репутация: +  0  -
Профиль   Отправить e-mail  

PyQt4. Свой кэш на QAbstractNetworkCache приводит к падению Питона

Isem
rustamakhmetov
Нет, дело было в кривом коде
Кривой код на питоне не может привести к падению питона. (если нет, приведите пример). Значит кривой код плюс кривой PQ4 - два брата-близнеца.
я пробовал тоже самое реализовать на PySide и это также приводило к падению.



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version