kio: drop MIME type feature of slaves

the specialized one, stat() does it now because emitting MIME type while
also emitting data (in or out) interrupts the data flow

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2024-05-03 05:26:53 +03:00
parent bd9f76451d
commit e273741fdb
28 changed files with 87 additions and 504 deletions

View file

@ -327,7 +327,6 @@ install(
KIO/JobUiDelegate
KIO/ListJob
KIO/MetaData
KIO/MimetypeJob
KIO/NetAccess
KIO/PreviewJob
KIO/RenameDialog
@ -336,7 +335,6 @@ install(
KIO/SlaveBase
KIO/StatJob
KIO/StoredTransferJob
KIO/Task
KIO/TransferJob
DESTINATION ${KDE4_INCLUDE_INSTALL_DIR}/KDE/KIO
)

View file

@ -1 +0,0 @@
#include "../../kio/jobclasses.h"

View file

@ -1 +0,0 @@
#include "../../kio/connection.h"

View file

@ -580,9 +580,13 @@ bool KFilePlacesModel::dropMimeData(const QMimeData *data, Qt::DropAction action
KBookmarkGroup group = d->bookmarkManager->root();
foreach (const KUrl &url, urls) {
// TODO: use KIO::stat in order to get the UDS_DISPLAY_NAME too
KMimeType::Ptr mimetype = KMimeType::mimeType(KIO::NetAccess::mimetype(url, 0));
KIO::UDSEntry statentry;
if (!KIO::NetAccess::stat(url, statentry, nullptr)) {
kWarning() << "URL not added to Places as it could not be reached!";
continue;
}
KMimeType::Ptr mimetype = KMimeType::mimeType(statentry.stringValue(KIO::UDSEntry::UDS_MIME_TYPE));
if (!mimetype) {
kWarning() << "URL not added to Places as mimetype could not be determined!";
continue;

View file

@ -309,8 +309,6 @@ KIO_EXPORT QString KIO::unsupportedActionErrorString(const QString &protocol, in
return i18n("Listing folders is not supported for protocol %1.", protocol);
case CMD_GET:
return i18n("Retrieving data from %1 is not supported.", protocol);
case CMD_MIMETYPE:
return i18n("Retrieving mime type information from %1 is not supported.", protocol);
case CMD_RENAME:
return i18n("Renaming or moving files within %1 is not supported.", protocol);
case CMD_SYMLINK:

View file

@ -806,13 +806,6 @@ TransferJob::TransferJob(TransferJobPrivate &dd)
void TransferJob::slotData(const QByteArray &_data)
{
Q_D(TransferJob);
if (d->m_command == CMD_GET && !d->m_isMimetypeEmitted) {
kWarning(7007) << "mimeType() not emitted when sending first data!; job URL ="
<< d->m_url << "data size =" << _data.size();
}
// shut up the warning, HACK: downside is that it changes the meaning of the variable
d->m_isMimetypeEmitted = true;
if (d->m_redirectionURL.isEmpty() || !d->m_redirectionURL.isValid() || error()) {
emit data(this, _data);
}
@ -892,11 +885,6 @@ void TransferJob::slotFinished()
SimpleJob::slotFinished();
}
QString TransferJob::mimetype() const
{
return d_func()->m_mimetype;
}
// Slave requests data
void TransferJob::slotDataReq()
{
@ -924,19 +912,6 @@ void TransferJob::slotDataReq()
}
}
void TransferJob::slotMimetype(const QString &type)
{
Q_D(TransferJob);
d->m_mimetype = type;
if (d->m_command == CMD_GET && d->m_isMimetypeEmitted) {
kWarning(7007) << "mimetype() emitted again, or after sending first data!; job URL ="
<< d->m_url;
}
d->m_isMimetypeEmitted = true;
emit mimetype(this, type);
}
void TransferJobPrivate::internalSuspend()
{
m_internalSuspended = true;
@ -985,18 +960,12 @@ void TransferJobPrivate::start(SlaveInterface *slave)
SLOT(slotRedirection(KUrl))
);
q->connect(
slave, SIGNAL(mimeType(QString)),
SLOT(slotMimetype(QString))
);
q->connect(
slave, SIGNAL(canResume(KIO::filesize_t)),
SLOT(slotCanResume(KIO::filesize_t))
);
if (slave->suspended()) {
m_mimetype = "unknown";
// WABA: The slave was put on hold. Resume operation.
slave->resume();
}
@ -1153,73 +1122,6 @@ StoredTransferJob *KIO::storedPut(const QByteArray &arr, const KUrl &url, int pe
return job;
}
//////////
class KIO::MimetypeJobPrivate: public KIO::TransferJobPrivate
{
public:
MimetypeJobPrivate(const KUrl &url, int command, const QByteArray &packedArgs)
: TransferJobPrivate(url, command, packedArgs)
{
}
Q_DECLARE_PUBLIC(MimetypeJob)
static inline MimetypeJob *newJob(const KUrl &url, int command, const QByteArray &packedArgs,
JobFlags flags)
{
MimetypeJob *job = new MimetypeJob(*new MimetypeJobPrivate(url, command, packedArgs));
job->setUiDelegate(new JobUiDelegate());
if (!(flags & HideProgressInfo)) {
KIO::getJobTracker()->registerJob(job);
emitStating(job, url);
}
return job;
}
};
MimetypeJob::MimetypeJob(MimetypeJobPrivate &dd)
: TransferJob(dd)
{
}
void MimetypeJob::slotFinished()
{
Q_D(MimetypeJob);
// kDebug(7007);
if (error() == KIO::ERR_IS_DIRECTORY) {
// It is in fact a directory. This happens when HTTP redirects to FTP.
// Due to the "protocol doesn't support listing" code in KRun, we
// assumed it was a file.
kDebug(7007) << "It is in fact a directory!";
d->m_mimetype = QString::fromLatin1("inode/directory");
emit TransferJob::mimetype(this, d->m_mimetype);
setError(0);
}
if (!d->m_redirectionURL.isEmpty() && d->m_redirectionURL.isValid() && !error()) {
//kDebug(7007) << "Redirection to " << m_redirectionURL;
if (d->m_redirectionHandlingEnabled) {
d->m_internalSuspended = false;
d->m_packedArgs.truncate(0);
QDataStream stream(&d->m_packedArgs, QIODevice::WriteOnly);
stream << d->m_redirectionURL;
d->restartAfterRedirection(&d->m_redirectionURL);
return;
}
}
// Return slave to the scheduler
TransferJob::slotFinished();
}
MimetypeJob *KIO::mimetype(const KUrl &url, JobFlags flags)
{
KIO_ARGS << url;
return MimetypeJobPrivate::newJob(url, CMD_MIMETYPE, packedArgs, flags);
}
//////////////////////////
class KIO::DirectCopyJobPrivate: public KIO::SimpleJobPrivate
@ -1307,7 +1209,6 @@ public:
void slotStart();
void slotData(KIO::Job *, const QByteArray &data);
void slotDataReq(KIO::Job *, QByteArray &data);
void slotMimetype(KIO::Job*, const QString &type);
/**
* Forward signal from subjob
* @param job the job that emitted this signal
@ -1660,10 +1561,6 @@ void FileCopyJobPrivate::slotCanResume(KIO::Job *job, KIO::filesize_t offset)
m_getJob, SIGNAL(data(KIO::Job*,QByteArray)),
SLOT(slotData(KIO::Job*,QByteArray))
);
q->connect(
m_getJob, SIGNAL(mimetype(KIO::Job*,QString)),
SLOT(slotMimetype(KIO::Job*,QString))
);
} else {
// copyjob
jobSlave(m_copyJob)->sendResumeAnswer(offset != 0);
@ -1723,12 +1620,6 @@ void FileCopyJobPrivate::slotDataReq(KIO::Job * , QByteArray &data)
m_buffer = QByteArray();
}
void FileCopyJobPrivate::slotMimetype(KIO::Job *, const QString &type)
{
Q_Q(FileCopyJob);
emit q->mimetype(q, type);
}
void FileCopyJob::slotResult(KJob *job)
{
Q_D(FileCopyJob);

View file

@ -204,20 +204,6 @@ namespace KIO {
KIO_EXPORT StoredTransferJob *storedPut( const QByteArray& arr, const KUrl& url, int permissions,
JobFlags flags = DefaultFlags );
/**
* Find mimetype for one file or directory.
*
* If you are going to download the file right after determining its mimetype,
* then don't use this, prefer using a KIO::get() job instead. See the note
* about putting the job on hold once the mimetype is determined.
*
* @param url the URL of the file
* @param flags Can be HideProgressInfo here
* @return the job handling the operation.
*/
KIO_EXPORT MimetypeJob * mimetype( const KUrl& url,
JobFlags flags = DefaultFlags );
/**
* Copy a single file.
*

View file

@ -43,22 +43,21 @@ namespace KIO {
CMD_GET = '1',
CMD_PUT = '2',
CMD_STAT = 'A',
CMD_MIMETYPE = 'B',
CMD_LISTDIR = 'C',
CMD_MKDIR = 'D',
CMD_RENAME = 'E',
CMD_COPY = 'F',
CMD_DEL = 'G',
CMD_CHMOD = 'H',
CMD_SPECIAL = 'I',
CMD_SETMODIFICATIONTIME = 'J',
CMD_REPARSECONFIGURATION = 'K',
CMD_META_DATA = 'L',
CMD_SYMLINK = 'M',
CMD_MESSAGEBOXANSWER = 'N',
CMD_RESUMEANSWER = 'O',
CMD_CONFIG = 'P',
CMD_CHOWN = 'Q'
CMD_LISTDIR = 'B',
CMD_MKDIR = 'C',
CMD_RENAME = 'D',
CMD_COPY = 'E',
CMD_DEL = 'F',
CMD_CHMOD = 'G',
CMD_SPECIAL = 'H',
CMD_SETMODIFICATIONTIME = 'I',
CMD_REPARSECONFIGURATION = 'J',
CMD_META_DATA = 'K',
CMD_SYMLINK = 'L',
CMD_MESSAGEBOXANSWER = 'M',
CMD_RESUMEANSWER = 'N',
CMD_CONFIG = 'O',
CMD_CHOWN = 'P'
};
class JobPrivate: public KCompositeJobPrivate
@ -237,14 +236,12 @@ namespace KIO {
inline TransferJobPrivate(const KUrl& url, int command, const QByteArray &packedArgs)
: SimpleJobPrivate(url, command, packedArgs),
m_internalSuspended(false),
m_isMimetypeEmitted(false), m_subJob(0)
m_subJob(0)
{ }
bool m_internalSuspended;
KUrl m_redirectionURL;
KUrl::List m_redirectionList;
QString m_mimetype;
bool m_isMimetypeEmitted;
TransferJob *m_subJob;
/**

View file

@ -477,13 +477,6 @@ namespace KIO {
*/
void setModificationTime( const QDateTime& mtime );
/**
* Call this in the slot connected to result,
* and only after making sure no error happened.
* @return the mimetype of the URL
*/
QString mimetype() const;
/**
* Set the total size of data that we are going to send
* in a put job. Helps getting proper progress information.
@ -537,13 +530,6 @@ namespace KIO {
*/
void redirection( KIO::Job *job, const KUrl &url );
/**
* Mimetype determined.
* @param job the job that emitted this signal
* @param type the mime type
*/
void mimetype( KIO::Job *job, const QString &type );
/**
* @internal
* Emitted if the "put" job found an existing partial file
@ -559,7 +545,6 @@ namespace KIO {
virtual void slotFinished();
virtual void slotData( const QByteArray &data);
virtual void slotDataReq();
virtual void slotMimetype( const QString &mimetype );
protected:
TransferJob(TransferJobPrivate &dd);
@ -617,24 +602,6 @@ namespace KIO {
Q_DECLARE_PRIVATE(StoredTransferJob)
};
class MimetypeJobPrivate;
/**
* A MimetypeJob is a TransferJob that allows you to get
* the mime type of an URL. Don't create directly,
* but use KIO::mimetype() instead.
* @see KIO::mimetype()
*/
class KIO_EXPORT MimetypeJob : public TransferJob {
Q_OBJECT
protected Q_SLOTS:
virtual void slotFinished( );
protected:
MimetypeJob(MimetypeJobPrivate &dd);
private:
Q_DECLARE_PRIVATE(MimetypeJob)
};
/**
* The FileCopyJob copies data from one place to another.
* @see KIO::file_copy()
@ -675,19 +642,6 @@ namespace KIO {
bool doSuspend();
bool doResume();
Q_SIGNALS:
/**
* Mimetype determined during a file copy.
* This is never emitted during a move, and might not be emitted during
* a file copy, depending on the slave. But when a get and a put are
* being used (which is the common case), this signal forwards the
* mimetype information from the get job.
*
* @param job the job that emitted this signal
* @param type the mime type
*/
void mimetype( KIO::Job *job, const QString &type );
protected Q_SLOTS:
/**
* Called whenever a subjob finishes.
@ -702,7 +656,6 @@ namespace KIO {
Q_PRIVATE_SLOT(d_func(), void slotStart())
Q_PRIVATE_SLOT(d_func(), void slotData( KIO::Job *, const QByteArray &data))
Q_PRIVATE_SLOT(d_func(), void slotDataReq( KIO::Job *, QByteArray &data))
Q_PRIVATE_SLOT(d_func(), void slotMimetype( KIO::Job*, const QString& type ))
Q_PRIVATE_SLOT(d_func(), void slotProcessedSize( KJob *job, qulonglong size ))
Q_PRIVATE_SLOT(d_func(), void slotTotalSize( KJob *job, qulonglong size ))
Q_PRIVATE_SLOT(d_func(), void slotPercent( KJob *job, unsigned long pct ))

View file

@ -1206,12 +1206,10 @@ void KRun::scanFile()
kDebug(7010) << this << " Scanning file " << d->m_strURL.url();
KIO::JobFlags flags = d->m_bProgressInfo ? KIO::DefaultFlags : KIO::HideProgressInfo;
KIO::TransferJob *job = KIO::get(d->m_strURL, flags);
KIO::StatJob *job = KIO::stat(d->m_strURL, flags);
job->ui()->setWindow(d->m_window);
connect(job, SIGNAL(result(KJob*)),
this, SLOT(slotScanFinished(KJob*)));
connect(job, SIGNAL(mimetype(KIO::Job*,QString)),
this, SLOT(slotScanMimeType(KIO::Job*,QString)));
d->m_job = job;
kDebug(7010) << " Job " << job << " is about getting from " << d->m_strURL.url();
}
@ -1309,15 +1307,6 @@ void KRun::slotStatResult(KJob * job)
}
}
void KRun::slotScanMimeType(KIO::Job *, const QString &mimetype)
{
if (mimetype.isEmpty()) {
kWarning(7010) << "get() didn't emit a mimetype! Probably a kioslave bug, please check the implementation of" << url().protocol();
}
mimeTypeDetermined(mimetype);
d->m_job = 0;
}
void KRun::slotScanFinished(KJob *job)
{
d->m_job = 0;
@ -1338,7 +1327,21 @@ void KRun::slotScanFinished(KJob *job)
d->m_bFinished = true;
// will emit the error and autodelete this
d->startTimer();
return;
}
KIO::StatJob* statJob = qobject_cast<KIO::StatJob*>(job);
if (!statJob) {
kFatal() << "job is a " << typeid(*job).name() << " should be a StatJob";
}
const KIO::UDSEntry entry = statJob->statResult();
const QString mimetype = entry.stringValue(KIO::UDSEntry::UDS_MIME_TYPE);
if (mimetype.isEmpty()) {
kWarning(7010) << "get() didn't emit a mimetype! Probably a kioslave bug, please check the implementation of" << url().protocol();
}
mimeTypeDetermined(mimetype);
d->m_job = 0;
}
void KRun::mimeTypeDetermined(const QString& mimeType)

View file

@ -363,12 +363,6 @@ protected Q_SLOTS:
*/
void slotScanFinished(KJob *);
/**
* This slot is called when the scan job has found out
* the mime type.
*/
void slotScanMimeType(KIO::Job *, const QString &type);
/**
* Call this from subclasses when you have determined the mimetype.
* It will call foundMimeType, but also sets up protection against deletion during message boxes.

View file

@ -56,7 +56,6 @@ namespace KIO
, bJobOK(true)
{}
UDSEntry m_entry;
QString m_mimetype;
QByteArray m_data;
KUrl m_url;
MetaData *m_metaData;
@ -241,12 +240,6 @@ bool NetAccess::synchronousRun( Job* job, QWidget* window, QByteArray* data,
return ok;
}
QString NetAccess::mimetype( const KUrl& url, QWidget* window )
{
NetAccess kioNet;
return kioNet.mimetypeInternal( url, window );
}
QString NetAccess::lastErrorString()
{
return lastErrorMsg;
@ -336,25 +329,6 @@ bool NetAccess::mkdirInternal( const KUrl & url, int permissions,
return d->bJobOK;
}
QString NetAccess::mimetypeInternal( const KUrl & url, QWidget* window )
{
d->bJobOK = true; // success unless further error occurs
d->m_mimetype = QLatin1String("unknown");
KIO::Job * job = KIO::mimetype( url );
job->ui()->setWindow (window);
connect( job, SIGNAL(result(KJob*)),
this, SLOT(slotResult(KJob*)) );
connect( job, SIGNAL(mimetype(KIO::Job*,QString)),
this, SLOT(slotMimetype(KIO::Job*,QString)) );
enter_loop();
return d->m_mimetype;
}
void NetAccess::slotMimetype( KIO::Job *, const QString & type )
{
d->m_mimetype = type;
}
bool NetAccess::synchronousRunInternal( Job* job, QWidget* window, QByteArray* data,
KUrl* finalURL, MetaData* metaData )
{

View file

@ -333,27 +333,6 @@ public:
static bool synchronousRun( Job* job, QWidget* window, QByteArray* data=0,
KUrl* finalURL=0, MetaData* metaData=0 );
/**
* Determines the mimetype of a given URL.
*
* This is a convenience function for KIO::mimetype. You
* should call this only when really necessary.
* KMimeType::findByUrl can determine extension a lot faster, but
* less reliably for remote files. Only when findByUrl() returns
* unknown (application/octet-stream) then this one should be
* used.
*
* @param url The URL whose mimetype we are interested in.
* @param window main window associated with this job. This is used to
* automatically cache and discard authentication information
* as needed. If NULL, authentication information will be
* cached only for a short duration after which the user will
* again be prompted for passwords as needed.
* @return The mimetype name.
*/
static QString mimetype( const KUrl & url, QWidget* window );
/**
* Returns the error string for the last job, in case it failed.
* Note that this is already translated.
@ -394,12 +373,10 @@ private:
bool synchronousRunInternal( Job* job, QWidget* window, QByteArray* data,
KUrl* finalURL, MetaData* metaData );
QString mimetypeInternal(const KUrl & url, QWidget* window = 0);
void enter_loop();
private Q_SLOTS:
void slotResult( KJob * job );
void slotMimetype( KIO::Job * job, const QString & type );
void slotData( KIO::Job*, const QByteArray& );
void slotRedirection( KIO::Job*, const KUrl& );

View file

@ -472,41 +472,6 @@ static bool isSubCommand(int cmd)
(cmd == CMD_CONFIG));
}
void SlaveBase::mimeType(const QString &_type)
{
kDebug(7019) << _type;
int cmd = 0;
do {
// Send the meta-data each time we send the mime-type.
if (!d->m_outgoingMetaData.isEmpty()) {
// kDebug(7019) << "emitting meta data";
KIO_DATA << d->m_outgoingMetaData;
send(INF_META_DATA, data);
}
KIO_DATA << _type;
send(INF_MIME_TYPE, data);
while (true) {
cmd = 0;
int ret = -1;
if (d->appConnection.hasTaskAvailable() || d->appConnection.waitForIncomingTask(-1)) {
ret = d->appConnection.read(&cmd, data);
}
if (ret == -1) {
kDebug(7019) << "read error";
exit();
return;
}
// kDebug(7019) << "got" << cmd;
if (!isSubCommand(cmd)) {
break;
}
dispatch(cmd, data );
}
} while (cmd != CMD_NONE);
d->m_outgoingMetaData.clear();
}
void SlaveBase::exit()
{
d->exit_loop = true;
@ -592,8 +557,6 @@ void SlaveBase::listDir(KUrl const &)
{ error(ERR_UNSUPPORTED_ACTION, unsupportedActionErrorString(d->m_protocol, CMD_LISTDIR)); }
void SlaveBase::get(KUrl const & )
{ error(ERR_UNSUPPORTED_ACTION, unsupportedActionErrorString(d->m_protocol, CMD_GET)); }
void SlaveBase::mimetype(KUrl const &url)
{ get(url); }
void SlaveBase::rename(KUrl const &, KUrl const &, JobFlags)
{ error(ERR_UNSUPPORTED_ACTION, unsupportedActionErrorString(d->m_protocol, CMD_RENAME)); }
void SlaveBase::symlink(QString const &, KUrl const &, JobFlags)
@ -861,15 +824,6 @@ void SlaveBase::dispatch(int command, const QByteArray &data)
d->m_state = SlaveBasePrivate::Idle;
break;
}
case CMD_MIMETYPE: {
KUrl url;
stream >> url;
d->m_state = SlaveBasePrivate::InsideMethod;
mimetype(url);
d->verifyState("mimetype()");
d->m_state = SlaveBasePrivate::Idle;
break;
}
case CMD_LISTDIR: {
KUrl url;
stream >> url;

View file

@ -167,12 +167,6 @@ public:
*/
void redirection(const KUrl &_url);
/**
* Call this in mimetype() and in get(), when you know the mimetype.
* See mimetype about other ways to implement it.
*/
void mimeType(const QString &_type);
/**
* Call to signal a warning, to be displayed in a dialog box.
*/
@ -265,19 +259,7 @@ public:
* get, aka read.
* @param url the full url for this request.
*
* The slave should first "emit" the mimetype by calling mimeType(),
* and then "emit" the data using the data() method.
*
* The reason why we need get() to emit the mimetype is:
* when pasting a URL in krunner, or konqueror's location bar,
* we have to find out what is the mimetype of that URL.
* Rather than doing it with a call to mimetype(), then the app or part
* would have to do a second request to the same server, this is done
* like this: get() is called, and when it emits the mimetype, the job
* is put on hold and the right app or part is launched. When that app
* or part calls get(), the slave is magically reused, and the download
* can now happen. All with a single call to get() in the slave.
* This mechanism is also described in KIO::get().
* The slave should emit the data using the data() method.
*/
virtual void get(const KUrl &url);
@ -315,20 +297,6 @@ public:
*/
virtual void stat(const KUrl &url);
/**
* Finds mimetype for one file or directory.
*
* This method should either emit 'mimeType' or it
* should send a block of data big enough to be able
* to determine the mimetype.
*
* If the slave doesn't reimplement it, a get will
* be issued, i.e. the whole file will be downloaded before
* determining the mimetype on it - this is obviously not a
* good thing in most cases.
*/
virtual void mimetype(const KUrl &url);
/**
* Lists the contents of @p url.
* The slave should emit ERR_CANNOT_ENTER_DIRECTORY if it doesn't exist,

View file

@ -315,15 +315,6 @@ bool SlaveInterface::dispatch(int cmd, const QByteArray &rawdata)
emit redirection(url);
break;
}
case INF_MIME_TYPE: {
QDataStream stream(rawdata);
QString str;
stream >> str;
emit mimeType(str);
if (!m_connection->suspended())
m_connection->sendnow(CMD_NONE, QByteArray());
break;
}
case INF_WARNING: {
QDataStream stream(rawdata);
QString str;

View file

@ -40,7 +40,6 @@ enum Info {
INF_TOTAL_SIZE = 10,
INF_PROCESSED_SIZE = 11,
INF_REDIRECTION = 20,
INF_MIME_TYPE = 21,
INF_WARNING = 23,
INF_INFOMESSAGE,
INF_META_DATA,
@ -189,7 +188,6 @@ Q_SIGNALS:
void processedSize(KIO::filesize_t );
void redirection(const KUrl &);
void speed(unsigned long );
void mimeType(const QString &);
void warning(const QString &);
void infoMessage(const QString &);

View file

@ -985,12 +985,6 @@ void JobTest::getInvalidUrl()
QVERIFY( !ok ); // it should fail :)
}
void JobTest::slotMimetype(KIO::Job* job, const QString& type)
{
QVERIFY( job != 0 );
m_mimetype = type;
}
void JobTest::deleteFile()
{
const QString dest = otherTmpDir() + "fileFromHome_copied";
@ -1211,46 +1205,6 @@ void JobTest::mostLocalUrl()
QCOMPARE(job->mostLocalUrl().toLocalFile(), filePath);
}
void JobTest::mimeType()
{
#if 1
const QString filePath = homeTmpDir() + "fileFromHome";
createTestFile( filePath );
KIO::MimetypeJob* job = KIO::mimetype(filePath, KIO::HideProgressInfo);
QVERIFY(job);
QSignalSpy spyMimeType(job, SIGNAL(mimetype(KIO::Job*,QString)));
bool ok = KIO::NetAccess::synchronousRun(job, 0);
QVERIFY(ok);
QCOMPARE(spyMimeType.count(), 1);
QCOMPARE(spyMimeType[0][0], QVariant::fromValue(static_cast<KIO::Job*>(job)));
QCOMPARE(spyMimeType[0][1].toString(), QString("application/octet-stream"));
#else
// Testing mimetype over HTTP
KIO::MimetypeJob* job = KIO::mimetype(KUrl("http://www.kde.org"), KIO::HideProgressInfo);
QVERIFY(job);
QSignalSpy spyMimeType(job, SIGNAL(mimetype(KIO::Job*,QString)));
bool ok = KIO::NetAccess::synchronousRun(job, 0);
QVERIFY(ok);
QCOMPARE(spyMimeType.count(), 1);
QCOMPARE(spyMimeType[0][0], QVariant::fromValue(static_cast<KIO::Job*>(job)));
QCOMPARE(spyMimeType[0][1].toString(), QString("text/html"));
#endif
}
void JobTest::mimeTypeError()
{
// KIO::mimetype() on a file that doesn't exist
const QString filePath = homeTmpDir() + "doesNotExist";
KIO::MimetypeJob* job = KIO::mimetype(QUrl::fromLocalFile(filePath), KIO::HideProgressInfo);
QVERIFY(job);
QSignalSpy spyMimeType(job, SIGNAL(mimetype(KIO::Job*,QString)));
QSignalSpy spyResult(job, SIGNAL(result(KJob*)));
bool ok = KIO::NetAccess::synchronousRun(job, 0);
QVERIFY(!ok);
QCOMPARE(spyMimeType.count(), 0);
QCOMPARE(spyResult.count(), 1);
}
void JobTest::moveFileDestAlreadyExists() // #157601
{
const QString file1 = homeTmpDir() + "fileFromHome";

View file

@ -68,8 +68,6 @@ private Q_SLOTS:
void rmdirNotEmpty();
void stat();
void mostLocalUrl();
void mimeType();
void mimeTypeError();
//void newApiPerformance();
void calculateRemainingSeconds();
void moveFileDestAlreadyExists();
@ -89,7 +87,6 @@ protected Q_SLOTS:
void slotGetResult( KJob* );
void slotDataReq( KIO::Job*, QByteArray& );
void slotResult( KJob* );
void slotMimetype(KIO::Job*, const QString&);
private:
void enterLoop();

View file

@ -367,7 +367,7 @@ int main(int argc, char **argv)
CurlProtocol::CurlProtocol(const QByteArray &app)
: SlaveBase("curl", app),
p_aborttransfer(false), p_upload(false),
m_emitmime(true), m_ishttp(false), m_isftp(false), m_collectdata(false),
m_firstchunk(true), m_ishttp(false), m_isftp(false), m_collectdata(false),
m_curl(nullptr), m_curlheaders(nullptr), m_curlquotes(nullptr)
{
m_curl = curl_easy_init();
@ -799,8 +799,8 @@ void CurlProtocol::slotData(const char* curldata, const size_t curldatasize)
const QByteArray bytedata = QByteArray::fromRawData(curldata, curldatasize);
if (m_emitmime) {
m_emitmime = false;
if (m_firstchunk) {
m_firstchunk = false;
if (m_ishttp) {
// if it's HTTP error do not send data and MIME, abort transfer
@ -809,21 +809,6 @@ void CurlProtocol::slotData(const char* curldata, const size_t curldatasize)
p_aborttransfer = true;
return;
}
QString httpmimetype = QString::fromLatin1("application/octet-stream");
char *curlcontenttype = nullptr;
CURLcode curlresult = curl_easy_getinfo(m_curl, CURLINFO_CONTENT_TYPE, &curlcontenttype);
if (curlresult == CURLE_OK) {
httpmimetype = HTTPMIMEType(QString::fromAscii(curlcontenttype));
} else {
kWarning(7103) << "Could not get content type info" << curl_easy_strerror(curlresult);
}
mimeType(httpmimetype);
} else {
KMimeType::Ptr kmimetype = KMimeType::findByNameAndContent(p_url.url(), bytedata);
// default MIME type should be returned in the worst case
Q_ASSERT(kmimetype);
mimeType(kmimetype->name());
}
}
@ -893,7 +878,7 @@ bool CurlProtocol::setupCurl(const KUrl &url, const bool ftp)
p_aborttransfer = false;
p_upload = false;
p_url = url;
m_emitmime = true;
m_firstchunk = true;
const QString urlprotocol = url.protocol();
m_ishttp = (urlprotocol == QLatin1String("http") || urlprotocol == QLatin1String("https"));
m_isftp = (urlprotocol == QLatin1String("ftp") || urlprotocol == QLatin1String("sftp"));

View file

@ -51,7 +51,7 @@ private:
CURLcode performCurl(const KUrl &url, KUrl *redirecturl);
QList<KIO::UDSEntry> udsEntries();
bool m_emitmime;
bool m_firstchunk;
bool m_ishttp;
bool m_isftp;
bool m_collectdata;

View file

@ -305,14 +305,6 @@ void FileProtocol::get(const KUrl &url)
posix_fadvise(fd, 0, 0, POSIX_FADV_SEQUENTIAL);
#endif
// Determine the mimetype of the file to be retrieved, and emit it.
// This is mandatory in all slaves (for KRun/BrowserRun to work)
// In real "remote" slaves, this is usually done using findByNameAndContent
// after receiving some data. But we don't know how much data the mimemagic rules
// need, so for local files, better use findByUrl with localUrl=true.
KMimeType::Ptr mt = KMimeType::findByUrl(url, buff.st_mode, true /* local URL */);
emit mimeType(mt->name());
// Emit total size AFTER mimetype
totalSize(buff.st_size);
KIO::filesize_t processed_size = 0;
@ -659,6 +651,14 @@ bool FileProtocol::createUDSEntry(const QString &filename, const QByteArray &pat
#endif
notype:
if (details > 1) {
// In real "remote" slaves, this is usually done using findByNameAndContent
// after receiving some data. But we don't know how much data the mimemagic rules
// need, so for local files, better use findByPath with mode.
KMimeType::Ptr mt = KMimeType::findByPath(filename, buff.st_mode);
entry.insert(KIO::UDSEntry::UDS_MIME_TYPE, mt->name());
}
if (details > 0) {
entry.insert(KIO::UDSEntry::UDS_MODIFICATION_TIME, buff.st_mtime);
entry.insert(KIO::UDSEntry::UDS_USER, getUserName(buff.st_uid));

View file

@ -611,13 +611,6 @@ void FileProtocol::stat(const KUrl &url)
return;
}
/* directories may not have a slash at the end if
* we want to stat() them; it requires that we
* change into it .. which may not be allowed
* stat("/is/unaccessible") -> rwx------
* stat("/is/unaccessible/") -> EPERM H.Z.
* This is the reason for the -1
*/
const QString path(url.path(KUrl::RemoveTrailingSlash));
const QByteArray _path(QFile::encodeName(path));
const QString sDetails = metaData(QLatin1String("details"));
@ -628,14 +621,6 @@ void FileProtocol::stat(const KUrl &url)
error(KIO::ERR_DOES_NOT_EXIST, path);
return;
}
#if 0
///////// debug code
MetaData::iterator it1 = mOutgoingMetaData.begin();
for (; it1 != mOutgoingMetaData.end(); it1++) {
kDebug(7101) << it1.key() << " = " << it1.data();
}
/////////
#endif
statEntry(entry);
finished();

View file

@ -284,7 +284,6 @@ public:
void _k_slotJobFinished(KJob *job);
void _k_slotStatJobFinished(KJob *job);
void _k_slotGotMimeType(KIO::Job *job, const QString &mime);
bool openLocalFile();
void openRemoteFile();
@ -494,10 +493,6 @@ void ReadOnlyPartPrivate::openRemoteFile()
m_job, SIGNAL(result(KJob*)),
q, SLOT(_k_slotJobFinished(KJob*))
);
QObject::connect(
m_job, SIGNAL(mimetype(KIO::Job*,QString)),
q, SLOT(_k_slotGotMimeType(KIO::Job*,QString))
);
}
void ReadOnlyPart::abortLoad()
@ -541,8 +536,15 @@ void ReadOnlyPartPrivate::_k_slotStatJobFinished(KJob * job)
// We could emit canceled on error, but we haven't even emitted started yet,
// this could maybe confuse some apps? So for now we'll just fallback to KIO::get
// and error again. Well, maybe this even helps with wrong stat results.
if (!job->error()) {
const KUrl localUrl = static_cast<KIO::StatJob*>(job)->mostLocalUrl();
if (job->error() != KJob::NoError) {
KIO::StatJob* statjob = static_cast<KIO::StatJob*>(job);
const KUrl localUrl = statjob->mostLocalUrl();
const QString mime = statjob->statResult().stringValue(KIO::UDSEntry::UDS_MIME_TYPE);
// set the mimetype only if it was not already set (for example, by the host application)
if (m_arguments.mimeType().isEmpty()) {
m_arguments.setMimeType(mime);
m_bAutoDetectedMime = true;
}
if (localUrl.isLocalFile()) {
m_file = localUrl.toLocalFile();
(void)openLocalFile();
@ -570,17 +572,6 @@ void ReadOnlyPartPrivate::_k_slotJobFinished(KJob *job)
}
}
void ReadOnlyPartPrivate::_k_slotGotMimeType(KIO::Job *job, const QString &mime)
{
kDebug() << mime;
Q_ASSERT(job == m_job); Q_UNUSED(job)
// set the mimetype only if it was not already set (for example, by the host application)
if (m_arguments.mimeType().isEmpty()) {
m_arguments.setMimeType(mime);
m_bAutoDetectedMime = true;
}
}
void ReadOnlyPart::guiActivateEvent(GUIActivateEvent *event)
{
Q_D(ReadOnlyPart);

View file

@ -503,7 +503,6 @@ protected:
private:
Q_PRIVATE_SLOT(d_func(), void _k_slotJobFinished( KJob * job ))
Q_PRIVATE_SLOT(d_func(), void _k_slotStatJobFinished(KJob*))
Q_PRIVATE_SLOT(d_func(), void _k_slotGotMimeType(KIO::Job *job, const QString &mime))
Q_DISABLE_COPY(ReadOnlyPart)
};

View file

@ -1252,7 +1252,7 @@ void ContainmentPrivate::dropData(QPointF scenePos, QPoint screenPos, QGraphicsS
kDebug() << "can decode" << mimeName << args;
// It may be a directory or a file, let's stat
KIO::MimetypeJob *job = KIO::mimetype(url, KIO::HideProgressInfo);
KIO::StatJob *job = KIO::stat(url, KIO::HideProgressInfo);
if (dropEvent) {
dropPoints[job] = dropEvent->pos();
} else {
@ -1260,8 +1260,6 @@ void ContainmentPrivate::dropData(QPointF scenePos, QPoint screenPos, QGraphicsS
}
QObject::connect(job, SIGNAL(result(KJob*)), q, SLOT(dropJobResult(KJob*)));
QObject::connect(job, SIGNAL(mimetype(KIO::Job*,QString)),
q, SLOT(mimeTypeRetrieved(KIO::Job*,QString)));
KMenu *choices = new KMenu("Content dropped");
choices->addAction(KIcon("process-working"), i18n("Fetching file type..."));
@ -1355,7 +1353,7 @@ void ContainmentPrivate::dropData(QPointF scenePos, QPoint screenPos, QGraphicsS
}
}
void ContainmentPrivate::clearDataForMimeJob(KIO::Job *job)
void ContainmentPrivate::clearDataForMimeJob(KJob *job)
{
QObject::disconnect(job, 0, q, 0);
dropPoints.remove(job);
@ -1366,47 +1364,39 @@ void ContainmentPrivate::clearDataForMimeJob(KIO::Job *job)
void ContainmentPrivate::dropJobResult(KJob *job)
{
KIO::TransferJob* tjob = qobject_cast<KIO::TransferJob*>(job);
if (!tjob) {
kDebug() << "job is not a KIO::TransferJob, won't handle the drop...";
clearDataForMimeJob(tjob);
return;
}
if (job->error()) {
kDebug() << "ERROR" << tjob->error() << ' ' << tjob->errorString();
}
// We call mimetypeRetrieved since there might be other mechanisms
// for finding suitable applets. Cleanup happens there as well.
mimeTypeRetrieved(qobject_cast<KIO::Job *>(job), QString());
}
void ContainmentPrivate::mimeTypeRetrieved(KIO::Job *job, const QString &mimetype)
{
kDebug() << "Mimetype Job returns." << mimetype;
KIO::TransferJob* tjob = qobject_cast<KIO::TransferJob*>(job);
if (!tjob) {
kDebug() << "job should be a TransferJob, but isn't";
KIO::StatJob* statjob = qobject_cast<KIO::StatJob*>(job);
if (!statjob) {
kDebug() << "job is not a KIO::StatJob, won't handle the drop...";
clearDataForMimeJob(job);
return;
}
KPluginInfo::List appletList = Applet::listAppletInfoForUrl(tjob->url());
if (job->error() != KJob::NoError) {
kDebug() << "ERROR" << statjob->error() << ' ' << statjob->errorString();
clearDataForMimeJob(job);
return;
}
const QString mimetype = statjob->statResult().stringValue(KIO::UDSEntry::UDS_MIME_TYPE);
kDebug() << "StatJob returns" << mimetype;
KPluginInfo::List appletList = Applet::listAppletInfoForUrl(statjob->url());
if (mimetype.isEmpty() && !appletList.count()) {
clearDataForMimeJob(job);
kDebug() << "No applets found matching the url (" << tjob->url() << ") or the mimetype (" << mimetype << ")";
kDebug() << "No applets found matching the url (" << statjob->url() << ") or the mimetype (" << mimetype << ")";
return;
} else {
QPointF posi; // will be overwritten with the event's position
if (dropPoints.keys().contains(tjob)) {
posi = dropPoints[tjob];
if (dropPoints.keys().contains(statjob)) {
posi = dropPoints[statjob];
kDebug() << "Received a suitable dropEvent at" << posi;
} else {
kDebug() << "Bailing out. Cannot find associated dropEvent related to the TransferJob";
kDebug() << "Bailing out. Cannot find associated dropEvent related to the StatJob";
clearDataForMimeJob(job);
return;
}
KMenu *choices = dropMenus.value(tjob);
KMenu *choices = dropMenus.value(statjob);
if (!choices) {
kDebug() << "Bailing out. No QMenu found for this job.";
clearDataForMimeJob(job);
@ -1414,7 +1404,7 @@ void ContainmentPrivate::mimeTypeRetrieved(KIO::Job *job, const QString &mimetyp
}
QVariantList args;
args << tjob->url().url() << mimetype;
args << statjob->url().url() << mimetype;
kDebug() << "Creating menu for:" << mimetype << posi << args;
@ -1474,13 +1464,13 @@ void ContainmentPrivate::mimeTypeRetrieved(KIO::Job *job, const QString &mimetyp
//set wallpapery stuff
plugin = actionsToWallpapers.value(choice);
if (!wallpaper || plugin != wallpaper->pluginName()) {
kDebug() << "Wallpaper dropped:" << tjob->url();
kDebug() << "Wallpaper dropped:" << statjob->url();
q->setWallpaper(plugin);
}
if (wallpaper) {
kDebug() << "Wallpaper dropped:" << tjob->url();
wallpaper->setUrls(KUrl::List() << tjob->url());
kDebug() << "Wallpaper dropped:" << statjob->url();
wallpaper->setUrls(KUrl::List() << statjob->url());
}
} else {
addApplet(actionsToApplets[choice], args, QRectF(posi, QSize()));
@ -1488,8 +1478,8 @@ void ContainmentPrivate::mimeTypeRetrieved(KIO::Job *job, const QString &mimetyp
// Put the job slave on hold so it can be recycled to fetch the actual content,
// which is to be expected when something's dropped onto the desktop and
// an applet is to be created with this URL
if (!mimetype.isEmpty() && !tjob->error()) {
tjob->kill(KJob::Quietly);
if (!mimetype.isEmpty() && !statjob->error()) {
statjob->kill(KJob::Quietly);
}
clearDataForMimeJob(job);

View file

@ -603,7 +603,6 @@ Q_SIGNALS:
/**
* This slot is called when the 'stat' after a job event has finished.
*/
Q_PRIVATE_SLOT(d, void mimeTypeRetrieved(KIO::Job *, const QString &))
Q_PRIVATE_SLOT(d, void dropJobResult(KJob *))
friend class Applet;

View file

@ -103,8 +103,7 @@ public:
void appletDestroyed(Applet*);
void appletAppearAnimationComplete();
void appletAppeared(Applet*);
void clearDataForMimeJob(KIO::Job *job);
void mimeTypeRetrieved(KIO::Job *job, const QString &mimetype);
void clearDataForMimeJob(KJob *job);
void dropJobResult(KJob *);
void addContainmentActions(KMenu &desktopMenu, QEvent *event);
void addAppletActions(KMenu &desktopMenu, Applet *applet, QEvent *event);