Add ipps support
This commit is contained in:
parent
cb6f836282
commit
01e7e02bcd
15 changed files with 315 additions and 92 deletions
|
@ -5,6 +5,7 @@ import Nemo.Notifications 1.0
|
||||||
import Nemo.Configuration 1.0
|
import Nemo.Configuration 1.0
|
||||||
import seaprint.mimer 1.0
|
import seaprint.mimer 1.0
|
||||||
import seaprint.settings 1.0
|
import seaprint.settings 1.0
|
||||||
|
|
||||||
import "pages"
|
import "pages"
|
||||||
import "components"
|
import "components"
|
||||||
|
|
||||||
|
@ -151,9 +152,11 @@ ApplicationWindow
|
||||||
defaultValue: SeaPrintSettings.alwaysUseMediaColDefault
|
defaultValue: SeaPrintSettings.alwaysUseMediaColDefault
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted:
|
ConfigurationValue
|
||||||
{
|
{
|
||||||
console.log(SeaPrintSettings.ignoreSslErrorsPath, SeaPrintSettings.ignoreSslErrorsDefault)
|
id: ignoreSslErrorsSetting
|
||||||
|
key: SeaPrintSettings.ignoreSslErrorsPath
|
||||||
|
defaultValue: SeaPrintSettings.ignoreSslErrorsDefault
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,6 @@ Page {
|
||||||
else {
|
else {
|
||||||
IppDiscovery.favourites = []
|
IppDiscovery.favourites = []
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
property bool initialSSIDchange: true
|
property bool initialSSIDchange: true
|
||||||
|
|
|
@ -53,6 +53,15 @@ Page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TextSwitch {
|
||||||
|
text: qsTr("Ignore SSL errors")
|
||||||
|
description: qsTr("In order to work with self-signed certificates of printers and CUPS instances, SSL errors needs to be ignored.")
|
||||||
|
checked: ignoreSslErrorsSetting.value
|
||||||
|
onCheckedChanged: {
|
||||||
|
ignoreSslErrorsSetting.value = checked
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "ippdiscovery.h"
|
#include "ippdiscovery.h"
|
||||||
#include "ippprinter.h"
|
#include "ippprinter.h"
|
||||||
|
#include "settings.h"
|
||||||
#include <seaprint_version.h>
|
#include <seaprint_version.h>
|
||||||
|
|
||||||
#define A 1
|
#define A 1
|
||||||
|
@ -10,16 +11,6 @@
|
||||||
|
|
||||||
#define ALL 255 //for querying
|
#define ALL 255 //for querying
|
||||||
|
|
||||||
void put_addr(Bytestream& bts, QStringList addr)
|
|
||||||
{
|
|
||||||
for(int i = 0; i < addr.length(); i++)
|
|
||||||
{
|
|
||||||
QString elem = addr[i];
|
|
||||||
bts << (quint8)elem.size() << elem.toStdString();
|
|
||||||
}
|
|
||||||
bts << (quint8)0;
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList get_addr(Bytestream& bts)
|
QStringList get_addr(Bytestream& bts)
|
||||||
{
|
{
|
||||||
QStringList addr;
|
QStringList addr;
|
||||||
|
@ -50,10 +41,9 @@ QStringList get_addr(Bytestream& bts)
|
||||||
IppDiscovery::IppDiscovery() : QStringListModel(), QQuickImageProvider(QQuickImageProvider::Image, ForceAsynchronousImageLoading)
|
IppDiscovery::IppDiscovery() : QStringListModel(), QQuickImageProvider(QQuickImageProvider::Image, ForceAsynchronousImageLoading)
|
||||||
{
|
{
|
||||||
socket = new QUdpSocket(this);
|
socket = new QUdpSocket(this);
|
||||||
connect(socket, SIGNAL(readyRead()),
|
connect(socket, &QUdpSocket::readyRead, this, &IppDiscovery::readPendingDatagrams);
|
||||||
this, SLOT(readPendingDatagrams()));
|
connect(this, &IppDiscovery::favouritesChanged, this, &IppDiscovery::cleanUpdate);
|
||||||
connect(this, SIGNAL(favouritesChanged()),
|
_transactionid = 0;
|
||||||
this, SLOT(update()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IppDiscovery::~IppDiscovery() {
|
IppDiscovery::~IppDiscovery() {
|
||||||
|
@ -79,67 +69,201 @@ IppDiscovery* IppDiscovery::instance()
|
||||||
}
|
}
|
||||||
|
|
||||||
void IppDiscovery::discover() {
|
void IppDiscovery::discover() {
|
||||||
sendQuery(PTR, {"_ipp","_tcp","local"});
|
sendQuery(PTR, {"_ipp._tcp.local", "_ipps._tcp.local"});
|
||||||
}
|
}
|
||||||
|
|
||||||
void IppDiscovery::reset() {
|
void IppDiscovery::reset() {
|
||||||
_ipp = QStringList();
|
_ipp.clear();
|
||||||
_rps = QMap<QString,QString>();
|
_rps.clear();
|
||||||
_ports = QMap<QString,quint16>();
|
_ports.clear();
|
||||||
_targets = QMap<QString,QString>();
|
_targets.clear();
|
||||||
|
|
||||||
_AAs = QMultiMap<QString,QString>();
|
_AAs.clear();
|
||||||
_AAAAs = QMultiMap<QString,QString>();
|
_AAAAs.clear();
|
||||||
|
|
||||||
|
_outstandingQueries.clear();
|
||||||
|
|
||||||
|
setStringList({});
|
||||||
discover();
|
discover();
|
||||||
}
|
}
|
||||||
|
|
||||||
void IppDiscovery::sendQuery(quint16 qtype, QStringList addr) {
|
|
||||||
qDebug() << "discovering" << qtype << addr;
|
void IppDiscovery::sendQuery(quint16 qtype, QStringList addrs) {
|
||||||
|
addrs.removeDuplicates();
|
||||||
|
|
||||||
|
QTime now = QTime::currentTime();
|
||||||
|
QTime aWhileAgo = now.addSecs(-1);
|
||||||
|
|
||||||
|
foreach(QString oq, _outstandingQueries.keys())
|
||||||
|
{
|
||||||
|
if(_outstandingQueries[oq] < aWhileAgo)
|
||||||
|
{ // Housekeeping for _outstandingQueries
|
||||||
|
_outstandingQueries.remove(oq);
|
||||||
|
}
|
||||||
|
else if(addrs.contains(oq))
|
||||||
|
{ // we recently asked about this, remove it
|
||||||
|
addrs.removeOne(oq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(addrs.empty())
|
||||||
|
{
|
||||||
|
qDebug() << "nothing to do";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "discovering" << qtype << addrs;
|
||||||
|
|
||||||
Bytestream query;
|
Bytestream query;
|
||||||
quint16 transactionid = 0;
|
QMap<QString, quint16> suffixPositions;
|
||||||
quint16 flags = 0;
|
|
||||||
quint16 questions = 1;
|
quint16 flags = 0;
|
||||||
|
quint16 questions = addrs.length();
|
||||||
|
|
||||||
|
query << _transactionid++ << flags << questions << (quint16)0 << (quint16)0 << (quint16)0;
|
||||||
|
|
||||||
|
foreach(QString addr, addrs)
|
||||||
|
{
|
||||||
|
_outstandingQueries.insert(addr, now);
|
||||||
|
|
||||||
|
QStringList addrParts = addr.split(".");
|
||||||
|
QString addrPart, restAddr;
|
||||||
|
while(!addrParts.isEmpty())
|
||||||
|
{
|
||||||
|
restAddr = addrParts.join(".");
|
||||||
|
if(suffixPositions.contains(restAddr))
|
||||||
|
{
|
||||||
|
query << (quint16)(0xc000 | (0x0fff & suffixPositions[restAddr]));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// We are putting in at least one part of the address, remember where that was
|
||||||
|
suffixPositions.insert(restAddr, query.size());
|
||||||
|
addrPart = addrParts.takeFirst();
|
||||||
|
query << (quint8)addrPart.size() << addrPart.toStdString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(addrParts.isEmpty())
|
||||||
|
{
|
||||||
|
// Whole addr was put in without c-pointers, 0-terminate it
|
||||||
|
query << (quint8)0;
|
||||||
|
}
|
||||||
|
|
||||||
query << transactionid << flags << questions << (quint16)0 << (quint16)0 << (quint16)0;
|
|
||||||
put_addr(query, addr);
|
|
||||||
query << qtype << (quint16)0x0001;
|
query << qtype << (quint16)0x0001;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
QByteArray bytes((char*)(query.raw()), query.size());
|
QByteArray bytes((char*)(query.raw()), query.size());
|
||||||
socket->writeDatagram(bytes, QHostAddress("224.0.0.251"), 5353);
|
socket->writeDatagram(bytes, QHostAddress("224.0.0.251"), 5353);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString make_addr(QString proto, int defaultPort, quint16 port, QString ip, QString rp)
|
||||||
|
{
|
||||||
|
QString maybePort = port != defaultPort ? ":"+QString::number(port) : "";
|
||||||
|
QString addr = proto+"://"+ip+maybePort+"/"+rp;
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString make_ipp_addr(quint16 port, QString ip, QString rp)
|
||||||
|
{
|
||||||
|
return make_addr("ipp", 631, port, ip, rp);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString make_ipps_addr(quint16 port, QString ip, QString rp)
|
||||||
|
{
|
||||||
|
return make_addr("ipps", 443, port, ip, rp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IppDiscovery::cleanUpdate()
|
||||||
|
{
|
||||||
|
setStringList(_favourites);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
void IppDiscovery::update()
|
void IppDiscovery::update()
|
||||||
{
|
{
|
||||||
QStringList found;
|
QStringList found;
|
||||||
|
QList<QPair<QString,QString>> ippsIpRps;
|
||||||
|
|
||||||
for(QStringList::Iterator it = _ipp.begin(); it != _ipp.end(); it++)
|
foreach(QString it, _ipps)
|
||||||
{
|
{
|
||||||
quint16 port = _ports[*it];
|
quint16 port = _ports[it];
|
||||||
QString target = _targets[*it];
|
QString target = _targets[it];
|
||||||
QString rp = _rps[*it];
|
QString rp = _rps[it];
|
||||||
|
|
||||||
for(QMultiMap<QString,QString>::Iterator ait = _AAs.begin(); ait != _AAs.end(); ait++)
|
for(QMultiMap<QString,QString>::Iterator ait = _AAs.begin(); ait != _AAs.end(); ait++)
|
||||||
{
|
{
|
||||||
if(ait.key() == target)
|
if(ait.key() == target)
|
||||||
{
|
{
|
||||||
QString ip = ait.value();
|
QString ip = ait.value();
|
||||||
QString maybePort = port != 631 ? ":"+QString::number(port) : "";
|
QString addr = make_ipps_addr(port, ip, rp);
|
||||||
QString addr = "ipp://"+ip+maybePort+"/"+rp;
|
|
||||||
if(!found.contains(addr))
|
if(!found.contains(addr))
|
||||||
{
|
{
|
||||||
|
ippsIpRps.append({ip, rp});
|
||||||
found.append(addr);
|
found.append(addr);
|
||||||
found.sort(Qt::CaseInsensitive);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << _favourites << found;
|
foreach(QString it, _ipp)
|
||||||
this->setStringList(_favourites+found);
|
{
|
||||||
|
quint16 port = _ports[it];
|
||||||
|
QString target = _targets[it];
|
||||||
|
QString rp = _rps[it];
|
||||||
|
|
||||||
|
for(QMultiMap<QString,QString>::Iterator ait = _AAs.begin(); ait != _AAs.end(); ait++)
|
||||||
|
{
|
||||||
|
if(ait.key() == target)
|
||||||
|
{
|
||||||
|
QString ip = ait.value();
|
||||||
|
QString addr = make_ipp_addr(port, ip, rp);
|
||||||
|
|
||||||
|
// IP+RP assumed unique, don't add ipp version of the printer if ipps already added
|
||||||
|
if(!found.contains(addr) && !ippsIpRps.contains({ip, rp}))
|
||||||
|
{
|
||||||
|
found.append(addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
found.sort(Qt::CaseInsensitive);
|
||||||
|
|
||||||
|
// Counting on that _ipp duplicates doesn't resolve fully any erlier than their _ipps counterpart
|
||||||
|
|
||||||
|
// TODO?: replace this with some logica that can bpoth add and remove
|
||||||
|
// and it can consider _favourites, so we can drop cleanUpdate
|
||||||
|
foreach(QString f, found)
|
||||||
|
{
|
||||||
|
if(!this->stringList().contains(f))
|
||||||
|
{
|
||||||
|
if(this->insertRow(this->rowCount()))
|
||||||
|
{
|
||||||
|
QModelIndex index = this->index(this->rowCount() - 1, 0);
|
||||||
|
this->setData(index, f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IppDiscovery::updateAndQueryPtrs(QStringList& ptrs, QStringList new_ptrs)
|
||||||
|
{
|
||||||
|
new_ptrs.removeDuplicates();
|
||||||
|
foreach(QString ptr, new_ptrs)
|
||||||
|
{
|
||||||
|
if(!ptrs.contains(ptr))
|
||||||
|
{
|
||||||
|
ptrs.append(ptr);
|
||||||
|
}
|
||||||
|
// If pointer does not resolve to a target or is missing information, query about it
|
||||||
|
if(!_targets.contains(ptr) || !_ports.contains(ptr) || !_rps.contains(ptr))
|
||||||
|
{ // if the PTR doesn't already resolve, ask for everything about it
|
||||||
|
sendQuery(ALL, {ptr});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IppDiscovery::readPendingDatagrams()
|
void IppDiscovery::readPendingDatagrams()
|
||||||
|
@ -152,6 +276,7 @@ void IppDiscovery::readPendingDatagrams()
|
||||||
quint16 senderPort;
|
quint16 senderPort;
|
||||||
|
|
||||||
QStringList new_ipp_ptrs;
|
QStringList new_ipp_ptrs;
|
||||||
|
QStringList new_ipps_ptrs;
|
||||||
QStringList new_targets;
|
QStringList new_targets;
|
||||||
|
|
||||||
socket->readDatagram((char*)(resp.raw()), size, &sender, &senderPort);
|
socket->readDatagram((char*)(resp.raw()), size, &sender, &senderPort);
|
||||||
|
@ -186,6 +311,10 @@ void IppDiscovery::readPendingDatagrams()
|
||||||
{
|
{
|
||||||
new_ipp_ptrs.append(tmpname);
|
new_ipp_ptrs.append(tmpname);
|
||||||
}
|
}
|
||||||
|
else if(aaddr.endsWith("_ipps._tcp.local"))
|
||||||
|
{
|
||||||
|
new_ipps_ptrs.append(tmpname);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if(atype == TXT)
|
else if(atype == TXT)
|
||||||
{
|
{
|
||||||
|
@ -208,15 +337,21 @@ void IppDiscovery::readPendingDatagrams()
|
||||||
QString target = get_addr(resp).join(".");
|
QString target = get_addr(resp).join(".");
|
||||||
_ports[aaddr] = port;
|
_ports[aaddr] = port;
|
||||||
_targets[aaddr] = target;
|
_targets[aaddr] = target;
|
||||||
|
if(!new_targets.contains(target))
|
||||||
|
{
|
||||||
new_targets.append(target);
|
new_targets.append(target);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if(atype == A)
|
else if(atype == A)
|
||||||
{
|
{
|
||||||
quint32 addr;
|
quint32 addr;
|
||||||
resp >> addr;
|
resp >> addr;
|
||||||
QHostAddress haddr(addr);
|
QHostAddress haddr(addr);
|
||||||
|
if(!_AAs.contains(aaddr, haddr.toString()))
|
||||||
|
{
|
||||||
_AAs.insert(aaddr, haddr.toString());
|
_AAs.insert(aaddr, haddr.toString());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
resp += len;
|
resp += len;
|
||||||
|
@ -231,7 +366,9 @@ void IppDiscovery::readPendingDatagrams()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
qDebug() << "new ipp ptrs" << new_ipp_ptrs;
|
qDebug() << "new ipp ptrs" << new_ipp_ptrs;
|
||||||
|
qDebug() << "new ipps ptrs" << new_ipps_ptrs;
|
||||||
qDebug() << "ipp ptrs" << _ipp;
|
qDebug() << "ipp ptrs" << _ipp;
|
||||||
|
qDebug() << "ipp ptrs" << _ipps;
|
||||||
qDebug() << "rps" << _rps;
|
qDebug() << "rps" << _rps;
|
||||||
qDebug() << "ports" << _ports;
|
qDebug() << "ports" << _ports;
|
||||||
qDebug() << "new targets" << new_targets;
|
qDebug() << "new targets" << new_targets;
|
||||||
|
@ -239,27 +376,27 @@ void IppDiscovery::readPendingDatagrams()
|
||||||
qDebug() << "AAs" << _AAs;
|
qDebug() << "AAs" << _AAs;
|
||||||
qDebug() << "AAAAs" << _AAAAs;
|
qDebug() << "AAAAs" << _AAAAs;
|
||||||
|
|
||||||
for(QStringList::Iterator it = new_ipp_ptrs.begin(); it != new_ipp_ptrs.end(); it++)
|
// These will send one query per unique new ptr.
|
||||||
{
|
// some responders doesn't give TXT records for more than one thing at at time :(
|
||||||
if(!_ipp.contains(*it))
|
updateAndQueryPtrs(_ipp, new_ipp_ptrs);
|
||||||
{
|
updateAndQueryPtrs(_ipps, new_ipps_ptrs);
|
||||||
_ipp.append(*it);
|
|
||||||
}
|
QStringList unresolvedAddrs;
|
||||||
// If pointer does not resolve to a target or is missing information, query about it
|
|
||||||
if( !_targets.contains(*it) || !_ports.contains(*it) || !_rps.contains(*it))
|
foreach(QString target, new_targets)
|
||||||
{ // if the PTR doesn't already resolve, ask for everything about it
|
|
||||||
sendQuery(ALL, it->split('.'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for(QStringList::Iterator it = new_targets.begin(); it != new_targets.end(); it++)
|
|
||||||
{
|
{
|
||||||
// If target does not resolve to an address, query about it
|
// If target does not resolve to an address, query about it
|
||||||
if(!_AAs.contains(*it))
|
if(!_AAs.contains(target))
|
||||||
{
|
{
|
||||||
sendQuery(ALL, it->split('.'));
|
unresolvedAddrs.append(target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!unresolvedAddrs.empty())
|
||||||
|
{
|
||||||
|
sendQuery(A, unresolvedAddrs);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
this->update();
|
this->update();
|
||||||
|
|
||||||
|
@ -290,9 +427,7 @@ QImage IppDiscovery::requestImage(const QString &id, QSize *size, const QSize &r
|
||||||
|
|
||||||
QNetworkRequest request(url);
|
QNetworkRequest request(url);
|
||||||
request.setHeader(QNetworkRequest::UserAgentHeader, "SeaPrint " SEAPRINT_VERSION);
|
request.setHeader(QNetworkRequest::UserAgentHeader, "SeaPrint " SEAPRINT_VERSION);
|
||||||
|
connect(nam, &QNetworkAccessManager::sslErrors, &IppPrinter::onSslErrors);
|
||||||
connect(nam, &QNetworkAccessManager::sslErrors,
|
|
||||||
&IppPrinter::ignoreKnownSslErrors);
|
|
||||||
|
|
||||||
QNetworkReply* reply = nam->get(request);
|
QNetworkReply* reply = nam->get(request);
|
||||||
|
|
||||||
|
|
|
@ -17,20 +17,25 @@ public:
|
||||||
static IppDiscovery* instance();
|
static IppDiscovery* instance();
|
||||||
|
|
||||||
Q_PROPERTY(QStringList favourites MEMBER _favourites NOTIFY favouritesChanged)
|
Q_PROPERTY(QStringList favourites MEMBER _favourites NOTIFY favouritesChanged)
|
||||||
|
|
||||||
Q_INVOKABLE void discover();
|
Q_INVOKABLE void discover();
|
||||||
Q_INVOKABLE void reset();
|
Q_INVOKABLE void reset();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void favouritesChanged();
|
void favouritesChanged();
|
||||||
|
void ignoreSslErrorsChanged();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void readPendingDatagrams();
|
void readPendingDatagrams();
|
||||||
|
void cleanUpdate();
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
private:
|
private:
|
||||||
static IppDiscovery* m_Instance;
|
static IppDiscovery* m_Instance;
|
||||||
|
|
||||||
|
quint16 _transactionid;
|
||||||
|
|
||||||
IppDiscovery();
|
IppDiscovery();
|
||||||
~IppDiscovery();
|
~IppDiscovery();
|
||||||
IppDiscovery(const IppDiscovery &);
|
IppDiscovery(const IppDiscovery &);
|
||||||
|
@ -38,9 +43,15 @@ private:
|
||||||
|
|
||||||
void sendQuery(quint16 qtype, QStringList addr);
|
void sendQuery(quint16 qtype, QStringList addr);
|
||||||
|
|
||||||
|
void sendQuery(quint16 qtype, QStringList prefixes, QStringList suffixes);
|
||||||
|
|
||||||
|
void updateAndQueryPtrs(QStringList& ptrs, QStringList new_ptrs);
|
||||||
|
|
||||||
|
|
||||||
QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize) override;
|
QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize) override;
|
||||||
|
|
||||||
QStringList _ipp;
|
QStringList _ipp;
|
||||||
|
QStringList _ipps;
|
||||||
QMap<QString,QString> _rps;
|
QMap<QString,QString> _rps;
|
||||||
QMap<QString,quint16> _ports;
|
QMap<QString,quint16> _ports;
|
||||||
QMap<QString,QString> _targets;
|
QMap<QString,QString> _targets;
|
||||||
|
@ -48,6 +59,8 @@ private:
|
||||||
QMultiMap<QString,QString> _AAs;
|
QMultiMap<QString,QString> _AAs;
|
||||||
QMultiMap<QString,QString> _AAAAs;
|
QMultiMap<QString,QString> _AAAAs;
|
||||||
|
|
||||||
|
QMap<QString, QTime> _outstandingQueries;
|
||||||
|
|
||||||
QStringList _favourites;
|
QStringList _favourites;
|
||||||
QUdpSocket* socket;
|
QUdpSocket* socket;
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,16 +13,16 @@ IppPrinter::IppPrinter()
|
||||||
_job_cancel_nam = new QNetworkAccessManager(this);
|
_job_cancel_nam = new QNetworkAccessManager(this);
|
||||||
|
|
||||||
connect(_nam, &QNetworkAccessManager::finished, this, &IppPrinter::getPrinterAttributesFinished);
|
connect(_nam, &QNetworkAccessManager::finished, this, &IppPrinter::getPrinterAttributesFinished);
|
||||||
connect(_nam, &QNetworkAccessManager::sslErrors, this, &IppPrinter::ignoreKnownSslErrors);
|
connect(_nam, &QNetworkAccessManager::sslErrors, &IppPrinter::onSslErrors);
|
||||||
|
|
||||||
connect(_print_nam, &QNetworkAccessManager::finished, this, &IppPrinter::printRequestFinished);
|
connect(_print_nam, &QNetworkAccessManager::finished, this, &IppPrinter::printRequestFinished);
|
||||||
connect(_print_nam, &QNetworkAccessManager::sslErrors, this, &IppPrinter::ignoreKnownSslErrors);
|
connect(_print_nam, &QNetworkAccessManager::sslErrors, &IppPrinter::onSslErrors);
|
||||||
|
|
||||||
connect(_jobs_nam, &QNetworkAccessManager::finished,this, &IppPrinter::getJobsRequestFinished);
|
connect(_jobs_nam, &QNetworkAccessManager::finished,this, &IppPrinter::getJobsRequestFinished);
|
||||||
connect(_jobs_nam, &QNetworkAccessManager::sslErrors, this, &IppPrinter::ignoreKnownSslErrors);
|
connect(_jobs_nam, &QNetworkAccessManager::sslErrors, &IppPrinter::onSslErrors);
|
||||||
|
|
||||||
connect(_job_cancel_nam, &QNetworkAccessManager::finished,this, &IppPrinter::cancelJobFinished);
|
connect(_job_cancel_nam, &QNetworkAccessManager::finished,this, &IppPrinter::cancelJobFinished);
|
||||||
connect(_job_cancel_nam, &QNetworkAccessManager::sslErrors, this, &IppPrinter::ignoreKnownSslErrors);
|
connect(_job_cancel_nam, &QNetworkAccessManager::sslErrors, &IppPrinter::onSslErrors);
|
||||||
|
|
||||||
QObject::connect(this, &IppPrinter::urlChanged, this, &IppPrinter::onUrlChanged);
|
QObject::connect(this, &IppPrinter::urlChanged, this, &IppPrinter::onUrlChanged);
|
||||||
qRegisterMetaType<QTemporaryFile*>("QTemporaryFile*");
|
qRegisterMetaType<QTemporaryFile*>("QTemporaryFile*");
|
||||||
|
@ -68,9 +68,9 @@ void IppPrinter::setUrl(QString url_s)
|
||||||
|
|
||||||
qDebug() << url.scheme();
|
qDebug() << url.scheme();
|
||||||
|
|
||||||
if(url.scheme() != "ipp" /* or ipps */ && url.scheme() != "file")
|
// If not already a good scheme, try to fixup, or give an empty url
|
||||||
|
if(url.scheme() != "ipp" && url.scheme() != "ipps" && url.scheme() != "file")
|
||||||
{
|
{
|
||||||
//if https -> ipps, else:
|
|
||||||
if(url.scheme() == "")
|
if(url.scheme() == "")
|
||||||
{
|
{
|
||||||
url = QUrl("ipp://"+url_s); // Why isn't setScheme working?
|
url = QUrl("ipp://"+url_s); // Why isn't setScheme working?
|
||||||
|
@ -78,6 +78,9 @@ void IppPrinter::setUrl(QString url_s)
|
||||||
else if (url.scheme() == "http") {
|
else if (url.scheme() == "http") {
|
||||||
url.setScheme("ipp");
|
url.setScheme("ipp");
|
||||||
}
|
}
|
||||||
|
else if (url.scheme() == "https") {
|
||||||
|
url.setScheme("ipps");
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
url = QUrl();
|
url = QUrl();
|
||||||
}
|
}
|
||||||
|
@ -104,6 +107,12 @@ void IppPrinter::refresh() {
|
||||||
// _additionalDocumentFormats = QStringList();
|
// _additionalDocumentFormats = QStringList();
|
||||||
// emit additionalDocumentFormatsChanged();
|
// emit additionalDocumentFormatsChanged();
|
||||||
|
|
||||||
|
// FFFFUUUU
|
||||||
|
_nam->clearAccessCache();
|
||||||
|
_jobs_nam->clearAccessCache();
|
||||||
|
_job_cancel_nam->clearAccessCache();
|
||||||
|
_print_nam->clearAccessCache();
|
||||||
|
|
||||||
if(_url.scheme() == "file")
|
if(_url.scheme() == "file")
|
||||||
{
|
{
|
||||||
_attrs = QJsonObject();
|
_attrs = QJsonObject();
|
||||||
|
@ -163,7 +172,7 @@ void IppPrinter::UpdateAdditionalDocumentFormats()
|
||||||
|
|
||||||
void IppPrinter::getPrinterAttributesFinished(QNetworkReply *reply)
|
void IppPrinter::getPrinterAttributesFinished(QNetworkReply *reply)
|
||||||
{
|
{
|
||||||
qDebug() << reply->error() << reply->errorString() << reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toString();
|
qDebug() << reply->request().url() << reply->error() << reply->errorString() << reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toString();
|
||||||
_attrs = QJsonObject();
|
_attrs = QJsonObject();
|
||||||
|
|
||||||
if(reply->error() == QNetworkReply::NoError)
|
if(reply->error() == QNetworkReply::NoError)
|
||||||
|
@ -254,26 +263,15 @@ void IppPrinter::cancelJobFinished(QNetworkReply *reply)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void IppPrinter::onSslErrors(QNetworkReply *reply, const QList<QSslError> &errors)
|
||||||
void IppPrinter::ignoreKnownSslErrors(QNetworkReply *reply, const QList<QSslError> &errors)
|
{
|
||||||
|
bool ignore = Settings::instance()->ignoreSslErrors();
|
||||||
|
qDebug() << reply->request().url() << "SSL handshake failed" << errors << ignore;
|
||||||
|
if(ignore)
|
||||||
{
|
{
|
||||||
QList<QSslError> IgnoredSslErrors = {QSslError::NoError,
|
|
||||||
QSslError::SelfSignedCertificate,
|
|
||||||
QSslError::HostNameMismatch,
|
|
||||||
QSslError::UnableToGetLocalIssuerCertificate,
|
|
||||||
QSslError::UnableToVerifyFirstCertificate
|
|
||||||
};
|
|
||||||
|
|
||||||
qDebug() << errors;
|
|
||||||
for (QList<QSslError>::const_iterator it = errors.constBegin(); it != errors.constEnd(); it++) {
|
|
||||||
if(!IgnoredSslErrors.contains(it->error())) {
|
|
||||||
qDebug() << "Bad error: " << int(it->error()) << it->error();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// For whatever reason, it doesn't work to pass IgnoredSslErrors here
|
|
||||||
reply->ignoreSslErrors(errors);
|
reply->ignoreSslErrors(errors);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void IppPrinter::convertDone(QNetworkRequest request, QTemporaryFile* data)
|
void IppPrinter::convertDone(QNetworkRequest request, QTemporaryFile* data)
|
||||||
{
|
{
|
||||||
|
@ -600,11 +598,22 @@ bool IppPrinter::cancelJob(qint32 jobId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
QUrl IppPrinter::httpUrl() {
|
QUrl IppPrinter::httpUrl() {
|
||||||
|
qDebug() << _url;
|
||||||
QUrl url = _url;
|
QUrl url = _url;
|
||||||
|
if(url.scheme() == "ipps")
|
||||||
|
{
|
||||||
|
url.setScheme("https");
|
||||||
|
if(url.port() == -1) {
|
||||||
|
url.setPort(443);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
url.setScheme("http");
|
url.setScheme("http");
|
||||||
if(url.port() == -1) {
|
if(url.port() == -1) {
|
||||||
url.setPort(631);
|
url.setPort(631);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -614,6 +623,7 @@ QNetworkRequest IppPrinter::mkReq() {
|
||||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/ipp");
|
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/ipp");
|
||||||
request.setHeader(QNetworkRequest::UserAgentHeader, "SeaPrint " SEAPRINT_VERSION);
|
request.setHeader(QNetworkRequest::UserAgentHeader, "SeaPrint " SEAPRINT_VERSION);
|
||||||
request.setRawHeader("Accept-Encoding", "identity");
|
request.setRawHeader("Accept-Encoding", "identity");
|
||||||
|
request.setSslConfiguration(QSslConfiguration());
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <QNetworkAccessManager>
|
#include <QNetworkAccessManager>
|
||||||
#include "ippmsg.h"
|
#include "ippmsg.h"
|
||||||
#include "convertworker.h"
|
#include "convertworker.h"
|
||||||
|
#include <mlite5/MGConfItem>
|
||||||
|
|
||||||
class IppPrinter : public QObject
|
class IppPrinter : public QObject
|
||||||
{
|
{
|
||||||
|
@ -17,7 +18,6 @@ class IppPrinter : public QObject
|
||||||
Q_PROPERTY(QString busyMessage MEMBER _busyMessage NOTIFY busyMessageChanged)
|
Q_PROPERTY(QString busyMessage MEMBER _busyMessage NOTIFY busyMessageChanged)
|
||||||
Q_PROPERTY(QString progress MEMBER _progress NOTIFY progressChanged)
|
Q_PROPERTY(QString progress MEMBER _progress NOTIFY progressChanged)
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
IppPrinter();
|
IppPrinter();
|
||||||
~IppPrinter();
|
~IppPrinter();
|
||||||
|
@ -73,7 +73,7 @@ public slots:
|
||||||
void getJobsRequestFinished(QNetworkReply* reply);
|
void getJobsRequestFinished(QNetworkReply* reply);
|
||||||
void cancelJobFinished(QNetworkReply* reply);
|
void cancelJobFinished(QNetworkReply* reply);
|
||||||
|
|
||||||
static void ignoreKnownSslErrors(QNetworkReply *reply, const QList<QSslError> &errors);
|
static void onSslErrors(QNetworkReply *reply, const QList<QSslError> &errors);
|
||||||
|
|
||||||
void convertDone(QNetworkRequest request, QTemporaryFile* data);
|
void convertDone(QNetworkRequest request, QTemporaryFile* data);
|
||||||
void convertFailed(QString message);
|
void convertFailed(QString message);
|
||||||
|
@ -108,7 +108,6 @@ private:
|
||||||
|
|
||||||
QThread _workerThread;
|
QThread _workerThread;
|
||||||
ConvertWorker* _worker;
|
ConvertWorker* _worker;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // IPPPRINTER_H
|
#endif // IPPPRINTER_H
|
||||||
|
|
|
@ -7,7 +7,6 @@ Overrider::Overrider()
|
||||||
{
|
{
|
||||||
// QFile file(QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation)+"/overrides");
|
// QFile file(QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation)+"/overrides");
|
||||||
QFile file(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)+"/.seaprint_overrides");
|
QFile file(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)+"/.seaprint_overrides");
|
||||||
qDebug() << "AAAAAAAAAAAAAAA" << file.fileName();
|
|
||||||
if(file.open(QIODevice::ReadOnly))
|
if(file.open(QIODevice::ReadOnly))
|
||||||
{
|
{
|
||||||
QJsonDocument JsonDocument = QJsonDocument::fromJson(file.readAll());
|
QJsonDocument JsonDocument = QJsonDocument::fromJson(file.readAll());
|
||||||
|
|
|
@ -511,6 +511,14 @@
|
||||||
<source>Settings</source>
|
<source>Settings</source>
|
||||||
<translation>Einstellungen</translation>
|
<translation>Einstellungen</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Ignore SSL errors</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>In order to work with self-signed certificates of printers and CUPS instances, SSL errors needs to be ignored.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SupplyItem</name>
|
<name>SupplyItem</name>
|
||||||
|
|
|
@ -511,6 +511,14 @@
|
||||||
<source>Settings</source>
|
<source>Settings</source>
|
||||||
<translation type="unfinished">Ajustes</translation>
|
<translation type="unfinished">Ajustes</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Ignore SSL errors</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>In order to work with self-signed certificates of printers and CUPS instances, SSL errors needs to be ignored.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SupplyItem</name>
|
<name>SupplyItem</name>
|
||||||
|
|
|
@ -511,6 +511,14 @@
|
||||||
<source>Settings</source>
|
<source>Settings</source>
|
||||||
<translation>Paramètres</translation>
|
<translation>Paramètres</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Ignore SSL errors</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>In order to work with self-signed certificates of printers and CUPS instances, SSL errors needs to be ignored.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SupplyItem</name>
|
<name>SupplyItem</name>
|
||||||
|
|
|
@ -511,6 +511,14 @@
|
||||||
<source>Settings</source>
|
<source>Settings</source>
|
||||||
<translation>Instellingen</translation>
|
<translation>Instellingen</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Ignore SSL errors</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>In order to work with self-signed certificates of printers and CUPS instances, SSL errors needs to be ignored.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SupplyItem</name>
|
<name>SupplyItem</name>
|
||||||
|
|
|
@ -511,6 +511,14 @@
|
||||||
<source>Use the attribute media-col instead of media for paper sizes. I.e. do parametric selection of print media rather than by name. If you use zero print margins, parametric selection will be used regardless of this setting.</source>
|
<source>Use the attribute media-col instead of media for paper sizes. I.e. do parametric selection of print media rather than by name. If you use zero print margins, parametric selection will be used regardless of this setting.</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Ignore SSL errors</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>In order to work with self-signed certificates of printers and CUPS instances, SSL errors needs to be ignored.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SupplyItem</name>
|
<name>SupplyItem</name>
|
||||||
|
|
|
@ -511,6 +511,14 @@
|
||||||
<source>Settings</source>
|
<source>Settings</source>
|
||||||
<translation>设置</translation>
|
<translation>设置</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Ignore SSL errors</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>In order to work with self-signed certificates of printers and CUPS instances, SSL errors needs to be ignored.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SupplyItem</name>
|
<name>SupplyItem</name>
|
||||||
|
|
|
@ -511,6 +511,14 @@
|
||||||
<source>Settings</source>
|
<source>Settings</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Ignore SSL errors</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>In order to work with self-signed certificates of printers and CUPS instances, SSL errors needs to be ignored.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SupplyItem</name>
|
<name>SupplyItem</name>
|
||||||
|
|
Loading…
Reference in a new issue