PDA

View Full Version : حرفه ای: آپلود فایل از طریق QNetwork access manager با pyside/pyqt



mohammadhzp
چهارشنبه 25 دی 1392, 12:15 عصر
سلام
من کلا با پایتون و پای ساید(کلا زبان سیستمی) مبتدی هستم و تاحالا کار نکردم بخاطره همین به ی سری مشکلا خوردم
دوستان من یک برنامه ای نوشتم و الان برنامه باید بتونه که بر روی xfilesharing فایل آپلود کنه !
این کار رو هم باید از طریق http انجام بده(یعنی api و هیچ چیزه دیگری نداریم)
سایت مقصد بر روی apache هستش(پورت ۸۰ یعنی) و یک فرم آپلود فایل داریم (برنامه باید ابتدا لوگین کنه و سپس فرم رو ارسال کنه,در اینجا بحث من فقط قسمت ارسال فرم هستش)
متاسفانه من هرچقدر تلاش کردم(خیلی جاها هم سوال و تحقیق کردم) ولی بازم به نتیجه نرسیدم
سوال من اینه که من باید چکار کنم که بتونم فایل رو جوری بفرستم که اونور request منو بگیره و فایل آپلود بشه(فکر کنم باید اینکار با دادن header های خاصی انجام بشه ولی من نمیدونم دقیقا باید چیکار کنم)
من کد برنامه رو اینجا میذارم(البته GUI برنامه این نیست ولی کد بخش Uploader کاملا اینجا آورده شده) تا دوستان بهتر بتونند به من کمک کنند


from PySide import QtCore, QtGui, QtNetwork

class Window(QtGui.QWidget):
def __init__(self, address):
QtGui.QWidget.__init__(self)
self.address = address
self.table = QtGui.QTableWidget(self)
header = self.table.horizontalHeader()
header.setStretchLastSection(True)
header.hide()
self.table.setColumnCount(2)
self.button = QtGui.QPushButton('Add Upload', self)
self.button.clicked.connect(self.handleAddUpload)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.table)
layout.addWidget(self.button)
self.netaccess = QtNetwork.QNetworkAccessManager(self)
self._uploaders = {}

def handleAddUpload(self):
stream = QtCore.QFile('files/sample.tar.bz2')
if stream.open(QtCore.QIODevice.ReadOnly):
data = stream.readAll()
stream.close()
row = self.table.rowCount()
button = QtGui.QPushButton('Abort', self.table)
button.clicked.connect(lambda: self.handleAbort(row))
progress = QtGui.QProgressBar(self.table)
progress.setRange(0, len(data))
self.table.setRowCount(row + 1)
self.table.setCellWidget(row, 0, button)
self.table.setCellWidget(row, 1, progress)
uploader = self._uploaders[row] = Uploader(row, self.netaccess)
uploader.uploadProgress.connect(self.handleUploadP rogress)
uploader.uploadFinished.connect(self.handleUploadF inished)
uploader.upload(data, self.address)

def handleUploadProgress(self, key, sent, total):
print('upload(%d): %d [%d]' % (key, sent, total))
progress = self.table.cellWidget(key, 1)
progress.setValue(sent)

def handleUploadFinished(self, key):
print('upload(%d) finished' % key)
button = self.table.cellWidget(key, 0)
button.setDisabled(True)
uploader = self._uploaders.pop(key)
uploader.deleteLater()

def handleAbort(self, key):
try:
self._uploaders[key].abort()
except (KeyError, AttributeError):
pass

class Uploader(QtCore.QObject):
uploadProgress = QtCore.Signal(object, int, int)
uploadFinished = QtCore.Signal(object)

def __init__(self, key, parent):
QtCore.QObject.__init__(self, parent)
self._key = key
self._reply = None

def abort(self):
if self._reply is not None:
self._reply.abort()

def upload(self, data, url):
if self._reply is None:
request = QtNetwork.QNetworkRequest(QtCore.QUrl(url))
request.setHeader(
QtNetwork.QNetworkRequest.ContentTypeHeader,
'application/x-www-form-urlencoded')
self._reply = self.parent().post(request, data)
self._reply.uploadProgress.connect(self.handleUplo adProgress)
self._reply.finished.connect(self.handleFinished)

def handleUploadProgress(self, sent, total):
self.uploadProgress.emit(self._key, sent, total)
if sent >= total:
# prevent duplicated uploads
self._reply.close()

def handleFinished(self):
self._reply.deleteLater()
self._reply = None
self.uploadFinished.emit(self._key)

if __name__ == '__main__':

import sys
app = QtGui.QApplication(sys.argv)
window = Window('http://localhost:54321/upload')
window.setGeometry(500, 300, 500, 300)
window.show()
sys.exit(app.exec_())

البته اگه pyside ندارین به راحتی میتونین این کد رو تبدیل به pyqt4 کنید.کافیه که خط اول رو تغییر بدین و PySide رو تبدیل به PyQt4 تبدیل کنید و در کلاس uploader باید QtCore.Signal رو به QtCore.pyqtSignal تبدیل کنید

دوستان واقعا به کمکتون هرچی که باشه لازم دارم

به روز رسانی ۱‌: من فکر کنم که باید از QHttpMultiPart استفاده کنم ولی بازم مطمئن نیسم,دوستان شاید بتونن بیشتر راهنمایی کنند

mohammadhzp
جمعه 27 دی 1392, 23:06 عصر
برنامه نویسای حرفه ای !!! خودشونو اذیت نکنند ! pyside اصلا QHttpMultiPart نداره و مجبور شدم سوییچ کنم روی PyQt,بعد از اینکه ی کدی که کار کنه رو آماده کردم اینجا میذارم تا اگه کسی دیگه مشکل داشت حل بشه
barnamenevis.org :D