Implement online mode: now qcma can connect to the Internet to check and download update files.
Update embedded xml file. Updated translations.
This commit is contained in:
		
							
								
								
									
										6
									
								
								qcma.pro
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								qcma.pro
									
									
									
									
									
								
							@@ -35,7 +35,8 @@ SOURCES += src/main.cpp \
 | 
			
		||||
    src/forms/configwidget.cpp \
 | 
			
		||||
    src/forms/confirmdialog.cpp \
 | 
			
		||||
    src/forms/pinform.cpp \
 | 
			
		||||
    src/forms/progressform.cpp
 | 
			
		||||
    src/forms/progressform.cpp \
 | 
			
		||||
    src/httpdownloader.cpp
 | 
			
		||||
 | 
			
		||||
HEADERS += \
 | 
			
		||||
    src/capability.h \
 | 
			
		||||
@@ -59,7 +60,8 @@ HEADERS += \
 | 
			
		||||
    src/forms/configwidget.h \
 | 
			
		||||
    src/forms/confirmdialog.h \
 | 
			
		||||
    src/forms/pinform.h \
 | 
			
		||||
    src/forms/progressform.h
 | 
			
		||||
    src/forms/progressform.h \
 | 
			
		||||
    src/httpdownloader.h
 | 
			
		||||
 | 
			
		||||
INCLUDEPATH += src/
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -120,12 +120,12 @@
 | 
			
		||||
        <translation>No se pudo inicializar VitaMTP</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/clientmanager.cpp" line="114"/>
 | 
			
		||||
        <location filename="../../src/clientmanager.cpp" line="116"/>
 | 
			
		||||
        <source>Cannot refresh the database while is in use</source>
 | 
			
		||||
        <translation>No se puede actualizar la base de datos mientras se encuentre en uso</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/clientmanager.cpp" line="116"/>
 | 
			
		||||
        <location filename="../../src/clientmanager.cpp" line="118"/>
 | 
			
		||||
        <source>No PS Vita system has been registered</source>
 | 
			
		||||
        <translation>Nigún sistema PS Vita ha sido registrado</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
@@ -239,37 +239,37 @@
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="240"/>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="237"/>
 | 
			
		||||
        <source>Offline Mode</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
        <translation>Modo desconectado</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="253"/>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="250"/>
 | 
			
		||||
        <source>Skip metadata extraction</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="263"/>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="260"/>
 | 
			
		||||
        <source>Update database automatically when files on the PC are changed</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="273"/>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="270"/>
 | 
			
		||||
        <source>Disable USB monitoring</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="283"/>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="280"/>
 | 
			
		||||
        <source>Disable Wi-Fi monitoring</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="292"/>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="289"/>
 | 
			
		||||
        <source>Database backend</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="303"/>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="300"/>
 | 
			
		||||
        <source>In Memory</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
@@ -322,6 +322,14 @@
 | 
			
		||||
        <translation>Filtro</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>HTTPDownloader</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/httpdownloader.cpp" line="154"/>
 | 
			
		||||
        <source>Network error: %1</source>
 | 
			
		||||
        <translation>Error de red: %1</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>MainWidget</name>
 | 
			
		||||
    <message>
 | 
			
		||||
 
 | 
			
		||||
@@ -120,12 +120,12 @@
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/clientmanager.cpp" line="114"/>
 | 
			
		||||
        <location filename="../../src/clientmanager.cpp" line="116"/>
 | 
			
		||||
        <source>Cannot refresh the database while is in use</source>
 | 
			
		||||
        <translation>使用中にはデータベースを更新できません</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/clientmanager.cpp" line="116"/>
 | 
			
		||||
        <location filename="../../src/clientmanager.cpp" line="118"/>
 | 
			
		||||
        <source>No PS Vita system has been registered</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
@@ -239,37 +239,37 @@
 | 
			
		||||
        <translation><html><head/><body><p align="center"><span style=" font-size:14pt; font-weight:600;">詳細設定</span></p></body></html></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="240"/>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="237"/>
 | 
			
		||||
        <source>Offline Mode</source>
 | 
			
		||||
        <translation>オフラインモード</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="253"/>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="250"/>
 | 
			
		||||
        <source>Skip metadata extraction</source>
 | 
			
		||||
        <translation>メタデータの展開をスキップする</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="263"/>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="260"/>
 | 
			
		||||
        <source>Update database automatically when files on the PC are changed</source>
 | 
			
		||||
        <translation>PCのファイルが変更された際にデータベースを自動的に更新する</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="273"/>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="270"/>
 | 
			
		||||
        <source>Disable USB monitoring</source>
 | 
			
		||||
        <translation>USBの監視を無効にする</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="283"/>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="280"/>
 | 
			
		||||
        <source>Disable Wi-Fi monitoring</source>
 | 
			
		||||
        <translation>Wi-Fiの監視を無効にする</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="292"/>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="289"/>
 | 
			
		||||
        <source>Database backend</source>
 | 
			
		||||
        <translation>データベース保存</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="303"/>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="300"/>
 | 
			
		||||
        <source>In Memory</source>
 | 
			
		||||
        <translation>メモリ内</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
@@ -323,6 +323,14 @@
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>HTTPDownloader</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/httpdownloader.cpp" line="154"/>
 | 
			
		||||
        <source>Network error: %1</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>MainWidget</name>
 | 
			
		||||
    <message>
 | 
			
		||||
 
 | 
			
		||||
@@ -2,38 +2,83 @@
 | 
			
		||||
<update_data_list>
 | 
			
		||||
<region id="au">
 | 
			
		||||
    <np level0_system_version="00.000.000" level1_system_version="00.000.000" level2_system_version="00.000.000" map="00.000.000" />
 | 
			
		||||
    <version system_version="00.000.000" label="0.00"></version>
 | 
			
		||||
    <np_d level0_system_version="00.000.000" level1_system_version="00.000.000" level2_system_version="00.000.000" map="00.000.000" />
 | 
			
		||||
    <version system_version="00.000.000" label="0.00">
 | 
			
		||||
      <update_data update_type="full">
 | 
			
		||||
        <image size="0">http://www.example.com/PSP2UPDAT.PUP</image>
 | 
			
		||||
      </update_data>
 | 
			
		||||
    </version>
 | 
			
		||||
</region>
 | 
			
		||||
<region id="eu">
 | 
			
		||||
    <np level0_system_version="00.000.000" level1_system_version="00.000.000" level2_system_version="00.000.000" map="00.000.000" />
 | 
			
		||||
    <version system_version="00.000.000" label="0.00"></version>
 | 
			
		||||
    <np_d level0_system_version="00.000.000" level1_system_version="00.000.000" level2_system_version="00.000.000" map="00.000.000" />
 | 
			
		||||
    <version system_version="00.000.000" label="0.00">
 | 
			
		||||
      <update_data update_type="full">
 | 
			
		||||
        <image size="0">http://www.example.com/PSP2UPDAT.PUP</image>
 | 
			
		||||
      </update_data>
 | 
			
		||||
    </version>
 | 
			
		||||
</region>
 | 
			
		||||
<region id="jp">
 | 
			
		||||
    <np level0_system_version="00.000.000" level1_system_version="00.000.000" level2_system_version="00.000.000" map="00.000.000" />
 | 
			
		||||
    <version system_version="00.000.000" label="0.00"></version>
 | 
			
		||||
    <np_d level0_system_version="00.000.000" level1_system_version="00.000.000" level2_system_version="00.000.000" map="00.000.000" />
 | 
			
		||||
    <version system_version="00.000.000" label="0.00">
 | 
			
		||||
      <update_data update_type="full">
 | 
			
		||||
        <image size="0">http://www.example.com/PSP2UPDAT.PUP</image>
 | 
			
		||||
      </update_data>
 | 
			
		||||
    </version>
 | 
			
		||||
</region>
 | 
			
		||||
<region id="kr">
 | 
			
		||||
    <np level0_system_version="00.000.000" level1_system_version="00.000.000" level2_system_version="00.000.000" map="00.000.000" />
 | 
			
		||||
    <version system_version="00.000.000" label="0.00"></version>
 | 
			
		||||
    <np_d level0_system_version="00.000.000" level1_system_version="00.000.000" level2_system_version="00.000.000" map="00.000.000" />
 | 
			
		||||
    <version system_version="00.000.000" label="0.00">
 | 
			
		||||
      <update_data update_type="full">
 | 
			
		||||
        <image size="0">http://www.example.com/PSP2UPDAT.PUP</image>
 | 
			
		||||
      </update_data>
 | 
			
		||||
    </version>
 | 
			
		||||
</region>
 | 
			
		||||
<region id="mx">
 | 
			
		||||
    <np level0_system_version="00.000.000" level1_system_version="00.000.000" level2_system_version="00.000.000" map="00.000.000" />
 | 
			
		||||
    <version system_version="00.000.000" label="0.00"></version>
 | 
			
		||||
    <np_d level0_system_version="00.000.000" level1_system_version="00.000.000" level2_system_version="00.000.000" map="00.000.000" />
 | 
			
		||||
    <version system_version="00.000.000" label="0.00">
 | 
			
		||||
      <update_data update_type="full">
 | 
			
		||||
        <image size="0">http://www.example.com/PSP2UPDAT.PUP</image>
 | 
			
		||||
      </update_data>
 | 
			
		||||
    </version>
 | 
			
		||||
</region>
 | 
			
		||||
<region id="ru">
 | 
			
		||||
    <np level0_system_version="00.000.000" level1_system_version="00.000.000" level2_system_version="00.000.000" map="00.000.000" />
 | 
			
		||||
    <version system_version="00.000.000" label="0.00"></version>
 | 
			
		||||
    <np_d level0_system_version="00.000.000" level1_system_version="00.000.000" level2_system_version="00.000.000" map="00.000.000" />
 | 
			
		||||
    <version system_version="00.000.000" label="0.00">
 | 
			
		||||
      <update_data update_type="full">
 | 
			
		||||
        <image size="0">http://www.example.com/PSP2UPDAT.PUP</image>
 | 
			
		||||
      </update_data>
 | 
			
		||||
    </version>
 | 
			
		||||
</region>
 | 
			
		||||
<region id="tw">
 | 
			
		||||
    <np level0_system_version="00.000.000" level1_system_version="00.000.000" level2_system_version="00.000.000" map="00.000.000" />
 | 
			
		||||
    <version system_version="00.000.000" label="0.00"></version>
 | 
			
		||||
    <np_d level0_system_version="00.000.000" level1_system_version="00.000.000" level2_system_version="00.000.000" map="00.000.000" />
 | 
			
		||||
    <version system_version="00.000.000" label="0.00">
 | 
			
		||||
      <update_data update_type="full">
 | 
			
		||||
        <image size="0">http://www.example.com/PSP2UPDAT.PUP</image>
 | 
			
		||||
      </update_data>
 | 
			
		||||
    </version>
 | 
			
		||||
</region>
 | 
			
		||||
<region id="uk">
 | 
			
		||||
    <np level0_system_version="00.000.000" level1_system_version="00.000.000" level2_system_version="00.000.000" map="00.000.000" />
 | 
			
		||||
    <version system_version="00.000.000" label="0.00"></version>
 | 
			
		||||
    <np_d level0_system_version="00.000.000" level1_system_version="00.000.000" level2_system_version="00.000.000" map="00.000.000" />
 | 
			
		||||
    <version system_version="00.000.000" label="0.00">
 | 
			
		||||
      <update_data update_type="full">
 | 
			
		||||
        <image size="0">http://www.example.com/PSP2UPDAT.PUP</image>
 | 
			
		||||
      </update_data>
 | 
			
		||||
    </version>
 | 
			
		||||
</region>
 | 
			
		||||
<region id="us">
 | 
			
		||||
    <np level0_system_version="00.000.000" level1_system_version="00.000.000" level2_system_version="00.000.000" map="00.000.000" />
 | 
			
		||||
    <version system_version="00.000.000" label="0.00"></version>
 | 
			
		||||
    <np_d level0_system_version="00.000.000" level1_system_version="00.000.000" level2_system_version="00.000.000" map="00.000.000" />
 | 
			
		||||
    <version system_version="00.000.000" label="0.00">
 | 
			
		||||
      <update_data update_type="full">
 | 
			
		||||
        <image size="0">http://www.example.com/PSP2UPDAT.PUP</image>
 | 
			
		||||
      </update_data>
 | 
			
		||||
    </version>
 | 
			
		||||
</region>
 | 
			
		||||
</update_data_list>
 | 
			
		||||
 
 | 
			
		||||
@@ -73,6 +73,7 @@ void ClientManager::start()
 | 
			
		||||
    client = new CmaClient();
 | 
			
		||||
    usb_thread->setObjectName("usb_thread");
 | 
			
		||||
    connect(usb_thread, SIGNAL(started()), client, SLOT(connectUsb()));
 | 
			
		||||
    connect(client, SIGNAL(messageSent(QString)), this, SIGNAL(messageSent(QString)));
 | 
			
		||||
    connect(client, SIGNAL(finished()), usb_thread, SLOT(quit()), Qt::DirectConnection);
 | 
			
		||||
    connect(usb_thread, SIGNAL(finished()), usb_thread, SLOT(deleteLater()));
 | 
			
		||||
    connect(usb_thread, SIGNAL(finished()), this, SLOT(threadStopped()));
 | 
			
		||||
@@ -90,6 +91,7 @@ void ClientManager::start()
 | 
			
		||||
    client = new CmaClient();
 | 
			
		||||
    wireless_thread->setObjectName("wireless_thread");
 | 
			
		||||
    connect(wireless_thread, SIGNAL(started()), client, SLOT(connectWireless()));
 | 
			
		||||
    connect(client, SIGNAL(messageSent(QString)), this, SIGNAL(messageSent(QString)));
 | 
			
		||||
    connect(client, SIGNAL(receivedPin(QString,int)), this, SLOT(showPinDialog(QString,int)));
 | 
			
		||||
    connect(client, SIGNAL(finished()), wireless_thread, SLOT(quit()), Qt::DirectConnection);
 | 
			
		||||
    connect(wireless_thread, SIGNAL(finished()), wireless_thread, SLOT(deleteLater()));
 | 
			
		||||
 
 | 
			
		||||
@@ -193,6 +193,7 @@ void CmaClient::enterEventLoop(vita_device_t *device)
 | 
			
		||||
    connect(&thread, SIGNAL(started()), &eventLoop, SLOT(process()));
 | 
			
		||||
    connect(&eventLoop, SIGNAL(refreshDatabase()), this, SIGNAL(refreshDatabase()), Qt::DirectConnection);
 | 
			
		||||
    connect(&eventLoop, SIGNAL(finishedEventLoop()), &thread, SLOT(quit()), Qt::DirectConnection);
 | 
			
		||||
    connect(&eventLoop, SIGNAL(messageSent(QString)), this, SIGNAL(messageSent(QString)), Qt::DirectConnection);
 | 
			
		||||
    thread.start();
 | 
			
		||||
 | 
			
		||||
    while(isActive()) {
 | 
			
		||||
 
 | 
			
		||||
@@ -73,6 +73,7 @@ signals:
 | 
			
		||||
    void pinComplete();
 | 
			
		||||
    void deviceDetected();
 | 
			
		||||
    void deviceConnected(QString);
 | 
			
		||||
    void messageSent(QString);
 | 
			
		||||
    void deviceDisconnected();
 | 
			
		||||
    void refreshDatabase();
 | 
			
		||||
    void finished();
 | 
			
		||||
 
 | 
			
		||||
@@ -23,6 +23,7 @@
 | 
			
		||||
#include <QDateTime>
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
#include <QDir>
 | 
			
		||||
#include <QNetworkAccessManager>
 | 
			
		||||
#include <QSettings>
 | 
			
		||||
#include <QUrl>
 | 
			
		||||
 | 
			
		||||
@@ -486,20 +487,51 @@ void CmaEvent::vitaEventSendHttpObjectFromURL(vita_event_t *event, int eventId)
 | 
			
		||||
    QFile file(QDir(urlpath).absoluteFilePath(basename));
 | 
			
		||||
 | 
			
		||||
    QByteArray data;
 | 
			
		||||
    QSettings settings;
 | 
			
		||||
 | 
			
		||||
    bool offlineMode = settings.value("offlineMode", true).toBool();
 | 
			
		||||
 | 
			
		||||
    if(!file.open(QIODevice::ReadOnly)) {
 | 
			
		||||
        if(basename == "psp2-updatelist.xml") {
 | 
			
		||||
        if(offlineMode && basename == "psp2-updatelist.xml") {
 | 
			
		||||
            qDebug("Found request for update list. Sending cached data");
 | 
			
		||||
            QFile res(":/main/resources/xml/psp2-updatelist.xml");
 | 
			
		||||
            res.open(QIODevice::ReadOnly);
 | 
			
		||||
            data = res.readAll();
 | 
			
		||||
        } else {
 | 
			
		||||
            qWarning("Failed to download %s", url);
 | 
			
		||||
            VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Failed_Download);
 | 
			
		||||
 | 
			
		||||
        } else if(!offlineMode) {
 | 
			
		||||
            HTTPDownloader downloader(url);
 | 
			
		||||
            QThread *http_thread = new QThread();
 | 
			
		||||
            http_thread->setObjectName("http_thread");
 | 
			
		||||
            connect(http_thread, SIGNAL(started()), &downloader, SLOT(downloadFile()));
 | 
			
		||||
            connect(&downloader, SIGNAL(messageSent(QString)), SIGNAL(messageSent(QString)), Qt::DirectConnection);
 | 
			
		||||
            downloader.moveToThread(http_thread);
 | 
			
		||||
            http_thread->start();
 | 
			
		||||
 | 
			
		||||
            int remote_size = (int)downloader.getFileSize();
 | 
			
		||||
 | 
			
		||||
            if(remote_size != -1) {
 | 
			
		||||
                // add the size of the file length to the total filesize
 | 
			
		||||
                remote_size += 8;
 | 
			
		||||
                qDebug("Sending %i bytes of data for HTTP request %s", remote_size, url);
 | 
			
		||||
 | 
			
		||||
                if(VitaMTP_SendData_Callback(device, eventId, PTP_OC_VITA_SendHttpObjectFromURL, remote_size, HTTPDownloader::readCallback) != PTP_RC_OK) {
 | 
			
		||||
                    qWarning("Failed to send HTTP object");
 | 
			
		||||
                } else {
 | 
			
		||||
                    VitaMTP_ReportResult(device, eventId, PTP_RC_OK);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            } else {
 | 
			
		||||
                qWarning("No valid content-length in header, aborting");
 | 
			
		||||
                VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Failed_Download);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            free(url);
 | 
			
		||||
            http_thread->quit();
 | 
			
		||||
            http_thread->deleteLater();
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        qDebug("Reading from local file");
 | 
			
		||||
        data = file.readAll();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -913,18 +945,18 @@ void CmaEvent::vitaEventCheckExistance(vita_event_t *event, int eventId)
 | 
			
		||||
    VitaMTP_ReportResult(device, eventId, PTP_RC_OK);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int CmaEvent::readCallback(unsigned char *data, unsigned long wantlen, unsigned long *gotlen)
 | 
			
		||||
int CmaEvent::readCallback(unsigned char *data, int64_t wantlen, int64_t *gotlen)
 | 
			
		||||
{
 | 
			
		||||
    QByteArray qdata = m_file->read(wantlen);
 | 
			
		||||
    *gotlen = qdata.size();
 | 
			
		||||
    if(*gotlen) {
 | 
			
		||||
        memcpy(data, qdata.constData(), qdata.size());
 | 
			
		||||
    *gotlen = m_file->read((char *)data, wantlen);
 | 
			
		||||
 | 
			
		||||
    if(*gotlen == -1) {
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return PTP_RC_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int CmaEvent::writeCallback(const unsigned char *data, unsigned long size, unsigned long *written)
 | 
			
		||||
int CmaEvent::writeCallback(const unsigned char *data, int64_t size, int64_t *written)
 | 
			
		||||
{
 | 
			
		||||
    int ret = m_file->write((const char *)data, size);
 | 
			
		||||
    if(ret != -1) {
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,9 @@
 | 
			
		||||
 | 
			
		||||
#include "cmaobject.h"
 | 
			
		||||
#include "database.h"
 | 
			
		||||
#include "httpdownloader.h"
 | 
			
		||||
 | 
			
		||||
#include <QNetworkReply>
 | 
			
		||||
#include <QObject>
 | 
			
		||||
#include <QSemaphore>
 | 
			
		||||
 | 
			
		||||
@@ -61,8 +63,9 @@ private:
 | 
			
		||||
    void vitaEventSendObjectMetadataItems(vita_event_t *event, int eventId);
 | 
			
		||||
    void vitaEventSendNPAccountInfo(vita_event_t *event, int eventId);
 | 
			
		||||
 | 
			
		||||
    static int readCallback(unsigned char *data, unsigned long wantlen, unsigned long *gotlen);
 | 
			
		||||
    static int writeCallback(const unsigned char *data, unsigned long size, unsigned long *written);
 | 
			
		||||
    static int readCallback(unsigned char *data, int64_t wantlen, int64_t *gotlen);
 | 
			
		||||
    static int writeCallback(const unsigned char *data, int64_t size, int64_t *written);
 | 
			
		||||
    static int readHTTPCallback(unsigned char *data, int64_t wantlen, int64_t *gotlen);
 | 
			
		||||
 | 
			
		||||
    void processEvent();
 | 
			
		||||
    bool isActive();
 | 
			
		||||
@@ -83,6 +86,7 @@ private:
 | 
			
		||||
signals:
 | 
			
		||||
    void finishedEventLoop();
 | 
			
		||||
    void refreshDatabase();
 | 
			
		||||
    void messageSent(QString);
 | 
			
		||||
 | 
			
		||||
public slots:
 | 
			
		||||
    void process();
 | 
			
		||||
 
 | 
			
		||||
@@ -145,6 +145,7 @@ void ConfigWidget::accept()
 | 
			
		||||
    savePath(settings, ui->videoPath, "videoPath");
 | 
			
		||||
    savePath(settings, ui->appPath, "appsPath");
 | 
			
		||||
    savePath(settings, ui->urlPath, "urlPath");
 | 
			
		||||
    settings.setValue("offlineMode", ui->offlineCheck->isChecked());
 | 
			
		||||
    settings.sync();
 | 
			
		||||
    done(Accepted);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -232,10 +232,7 @@
 | 
			
		||||
            </widget>
 | 
			
		||||
           </item>
 | 
			
		||||
           <item>
 | 
			
		||||
            <widget class="QCheckBox" name="checkBox">
 | 
			
		||||
             <property name="enabled">
 | 
			
		||||
              <bool>false</bool>
 | 
			
		||||
             </property>
 | 
			
		||||
            <widget class="QCheckBox" name="offlineCheck">
 | 
			
		||||
             <property name="text">
 | 
			
		||||
              <string>Offline Mode</string>
 | 
			
		||||
             </property>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										161
									
								
								src/httpdownloader.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										161
									
								
								src/httpdownloader.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,161 @@
 | 
			
		||||
/*
 | 
			
		||||
 *  QCMA: Cross-platform content manager assistant for the PS Vita
 | 
			
		||||
 *
 | 
			
		||||
 *  Copyright (C) 2014  Codestation
 | 
			
		||||
 *
 | 
			
		||||
 *  This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 *  it under the terms of the GNU General Public License as published by
 | 
			
		||||
 *  the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 *  (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 *  This program is distributed in the hope that it will be useful,
 | 
			
		||||
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 *  GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 *  You should have received a copy of the GNU General Public License
 | 
			
		||||
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "httpdownloader.h"
 | 
			
		||||
 | 
			
		||||
#include <QThread>
 | 
			
		||||
 | 
			
		||||
#include <inttypes.h>
 | 
			
		||||
#include <vitamtp.h>
 | 
			
		||||
 | 
			
		||||
QNetworkReply *HTTPDownloader::reply = NULL;
 | 
			
		||||
volatile qint64 HTTPDownloader::m_contentLength = -1;
 | 
			
		||||
 | 
			
		||||
QMutex HTTPDownloader::dataAvailable;
 | 
			
		||||
QMutex HTTPDownloader::dataRead;
 | 
			
		||||
 | 
			
		||||
char *HTTPDownloader::buffer = NULL;
 | 
			
		||||
qint64 HTTPDownloader::bufferSize = 0;
 | 
			
		||||
qint64 HTTPDownloader::downloadLeft = 0;
 | 
			
		||||
 | 
			
		||||
HTTPDownloader::HTTPDownloader(const QString &url, QObject *parent) :
 | 
			
		||||
    QObject(parent), remote_url(url), firstRead(true)
 | 
			
		||||
{
 | 
			
		||||
    lengthMutex.lock();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
HTTPDownloader::~HTTPDownloader()
 | 
			
		||||
{
 | 
			
		||||
    lengthMutex.unlock();
 | 
			
		||||
    free(buffer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HTTPDownloader::downloadFile()
 | 
			
		||||
{
 | 
			
		||||
    dataAvailable.lock();
 | 
			
		||||
    qDebug("Starting http_thread: 0x%016" PRIxPTR, (uintptr_t)QThread::currentThreadId());
 | 
			
		||||
    request = new QNetworkAccessManager(this);
 | 
			
		||||
    reply = request->get(QNetworkRequest(QUrl(remote_url)));
 | 
			
		||||
    connect(reply, SIGNAL(metaDataChanged()), this, SLOT(metadataChanged()));
 | 
			
		||||
    connect(reply, SIGNAL(readyRead()), this, SLOT(readyRead()));
 | 
			
		||||
    connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
 | 
			
		||||
            this, SLOT(error(QNetworkReply::NetworkError)));
 | 
			
		||||
    connect(reply, SIGNAL(finished()), reply, SLOT(deleteLater()));
 | 
			
		||||
    connect(reply, SIGNAL(finished()), request, SLOT(deleteLater()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HTTPDownloader::metadataChanged()
 | 
			
		||||
{
 | 
			
		||||
    QVariant len = reply->header(QNetworkRequest::ContentLengthHeader);
 | 
			
		||||
    if(len.isValid()) {
 | 
			
		||||
        m_contentLength = len.toInt();
 | 
			
		||||
        downloadLeft = m_contentLength + 8;
 | 
			
		||||
    } else {
 | 
			
		||||
        m_contentLength = -1;
 | 
			
		||||
    }
 | 
			
		||||
    lengthMutex.unlock();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
qint64 HTTPDownloader::getFileSize()
 | 
			
		||||
{
 | 
			
		||||
    lengthMutex.lock();
 | 
			
		||||
    return m_contentLength;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HTTPDownloader::readyRead()
 | 
			
		||||
{
 | 
			
		||||
    dataRead.lock();
 | 
			
		||||
 | 
			
		||||
    int currOffset = bufferSize;
 | 
			
		||||
    if(bufferSize == 0) {
 | 
			
		||||
        bufferSize = reply->bytesAvailable();
 | 
			
		||||
        if(firstRead) {
 | 
			
		||||
            bufferSize += 8;
 | 
			
		||||
            currOffset += 8;
 | 
			
		||||
        }
 | 
			
		||||
        // start with a 16KiB buffer
 | 
			
		||||
        buffer = (char *)malloc(16384 + 2048);
 | 
			
		||||
        if(firstRead) {
 | 
			
		||||
            *(uint64_t *)buffer = m_contentLength;
 | 
			
		||||
            firstRead = false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    } else {
 | 
			
		||||
        bufferSize += reply->bytesAvailable();
 | 
			
		||||
        if(bufferSize > 16384 + 2048) {
 | 
			
		||||
            buffer = (char *)realloc(buffer, bufferSize);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    reply->read(buffer + currOffset, reply->bytesAvailable());
 | 
			
		||||
 | 
			
		||||
    downloadLeft -= bufferSize;
 | 
			
		||||
 | 
			
		||||
    if(bufferSize > 16384 || downloadLeft == 0) {
 | 
			
		||||
        dataAvailable.unlock();
 | 
			
		||||
    }
 | 
			
		||||
    dataRead.unlock();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int HTTPDownloader::readCallback(unsigned char *data, int64_t wantlen, int64_t *gotlen)
 | 
			
		||||
{
 | 
			
		||||
    if(!dataAvailable.tryLock(30000)) {
 | 
			
		||||
        qWarning("Connection timeout while receiving data from network, aborting");
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    dataRead.lock();
 | 
			
		||||
 | 
			
		||||
    if(bufferSize == 0) {
 | 
			
		||||
        dataRead.unlock();
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(bufferSize < wantlen) {
 | 
			
		||||
        wantlen = bufferSize;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    memcpy(data, buffer, wantlen);
 | 
			
		||||
    bufferSize -= wantlen;
 | 
			
		||||
    *gotlen = wantlen;
 | 
			
		||||
 | 
			
		||||
    if(bufferSize > 0) {
 | 
			
		||||
        memmove(buffer, buffer + wantlen, bufferSize);
 | 
			
		||||
        if(bufferSize >= 16384 || downloadLeft == 0) {
 | 
			
		||||
            dataAvailable.unlock();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    *gotlen = wantlen;
 | 
			
		||||
    dataRead.unlock();
 | 
			
		||||
 | 
			
		||||
    return PTP_RC_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HTTPDownloader::error(QNetworkReply::NetworkError errorCode)
 | 
			
		||||
{
 | 
			
		||||
    Q_UNUSED(errorCode);
 | 
			
		||||
 | 
			
		||||
    emit messageSent(tr("Network error: %1").arg(reply->errorString()));
 | 
			
		||||
 | 
			
		||||
    // set buffer to zero so a read callback can be aborted
 | 
			
		||||
    dataRead.lock();
 | 
			
		||||
    bufferSize = 0;
 | 
			
		||||
    dataRead.unlock();
 | 
			
		||||
    lengthMutex.unlock();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										63
									
								
								src/httpdownloader.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								src/httpdownloader.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,63 @@
 | 
			
		||||
/*
 | 
			
		||||
 *  QCMA: Cross-platform content manager assistant for the PS Vita
 | 
			
		||||
 *
 | 
			
		||||
 *  Copyright (C) 2014  Codestation
 | 
			
		||||
 *
 | 
			
		||||
 *  This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 *  it under the terms of the GNU General Public License as published by
 | 
			
		||||
 *  the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 *  (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 *  This program is distributed in the hope that it will be useful,
 | 
			
		||||
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 *  GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 *  You should have received a copy of the GNU General Public License
 | 
			
		||||
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef HTTPDOWNLOADER_H
 | 
			
		||||
#define HTTPDOWNLOADER_H
 | 
			
		||||
 | 
			
		||||
#include <QMutex>
 | 
			
		||||
#include <QNetworkReply>
 | 
			
		||||
#include <QObject>
 | 
			
		||||
#include <QWaitCondition>
 | 
			
		||||
 | 
			
		||||
class HTTPDownloader : public QObject
 | 
			
		||||
{
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
public:
 | 
			
		||||
    explicit HTTPDownloader(const QString &url, QObject *parent = 0);
 | 
			
		||||
    ~HTTPDownloader();
 | 
			
		||||
    qint64 getFileSize();
 | 
			
		||||
 | 
			
		||||
signals:
 | 
			
		||||
    void messageSent(QString);
 | 
			
		||||
 | 
			
		||||
public slots:
 | 
			
		||||
    void downloadFile();
 | 
			
		||||
    static int readCallback(unsigned char *data, int64_t wantlen, int64_t *gotlen);
 | 
			
		||||
    void metadataChanged();
 | 
			
		||||
    void readyRead();
 | 
			
		||||
    void error(QNetworkReply::NetworkError);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    QString remote_url;
 | 
			
		||||
    QNetworkAccessManager *request;
 | 
			
		||||
    QMutex lengthMutex;
 | 
			
		||||
    bool firstRead;
 | 
			
		||||
 | 
			
		||||
    static QMutex dataAvailable;
 | 
			
		||||
    static QMutex dataRead;
 | 
			
		||||
 | 
			
		||||
    static QNetworkReply *reply;
 | 
			
		||||
    volatile static qint64 m_contentLength;
 | 
			
		||||
 | 
			
		||||
    static char *buffer;
 | 
			
		||||
    static qint64 bufferSize;
 | 
			
		||||
    static qint64 downloadLeft;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // HTTPDOWNLOADER_H
 | 
			
		||||
		Reference in New Issue
	
	Block a user