1/*
2 This file is part of the KDE libraries
3 Copyright (C) 1997 Torben Weis (weis@kde.org)
4 Copyright (C) 1998 Matthias Ettrich (ettrich@kde.org)
5 Copyright (C) 1999-2004 David Faure (faure@kde.org)
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details.
16
17 You should have received a copy of the GNU Library General Public License
18 along with this library; see the file COPYING.LIB. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA.
21*/
22
23#ifndef KIO_NETACCESS_h
24#define KIO_NETACCESS_h
25
26#include <QtCore/QObject>
27#include <QtCore/QString>
28#include <kio/global.h>
29#include <kio/udsentry.h>
30#include <kurl.h>
31#include <kio/jobclasses.h> // for KIO::JobFlags
32
33class QStringList;
34class QWidget;
35
36template<typename T, typename K> class QMap;
37
38class KJob;
39namespace KIO {
40
41 class Job;
42
43 class NetAccessPrivate;
44 /**
45 * Net Transparency.
46 *
47 * NetAccess allows you to do simple file operation (load, save,
48 * copy, delete...) without working with KIO::Job directly.
49 * Whereas a KIO::Job is asynchronous, meaning that the
50 * developer has to connect slots for it, KIO::NetAccess provides
51 * synchronous downloads and uploads, as well as temporary file
52 * creation and removal. The functions appear to be blocking,
53 * but the Qt event loop continues running while the operations
54 * are handled. More precisely, the GUI will still repaint, but no user
55 * interaction will be possible. If you can, please use async KIO jobs instead!
56 * See the documentation of KJob::exec() for more about the dangers of NetAccess.
57 *
58 * This class isn't meant to be used as a class but only as a simple
59 * namespace for static functions, though an instance of the class
60 * is built for internal purposes. TODO KDE5: turn into namespace,
61 * and make the qobject class private.
62 *
63 * Port to kio done by David Faure, faure@kde.org
64 *
65 * @short Provides a blocking interface to KIO file operations.
66 */
67class KIO_EXPORT NetAccess : public QObject
68{
69 Q_OBJECT
70
71public:
72 enum StatSide {
73 SourceSide,
74 DestinationSide
75 };
76
77 /**
78 * Downloads a file from an arbitrary URL (@p src) to a
79 * temporary file on the local filesystem (@p target).
80 *
81 * If the argument
82 * for @p target is an empty string, download will generate a
83 * unique temporary filename in /tmp. Since @p target is a reference
84 * to QString you can access this filename easily. Download will
85 * return true if the download was successful, otherwise false.
86 *
87 * Special case:
88 * If the URL is of kind file:, then no downloading is
89 * processed but the full filename is returned in @p target.
90 * That means you @em have to take care about the @p target argument.
91 * (This is very easy to do, please see the example below.)
92 *
93 * Download is synchronous. That means you can use it like this:
94 * (assuming your application has a loadFile() function)
95 *
96 * \code
97 * QString tmpFile;
98 * if( KIO::NetAccess::download(url, tmpFile, window)) {
99 * loadFile(tmpFile);
100 * KIO::NetAccess::removeTempFile(tmpFile);
101 * } else {
102 * KMessageBox::error(this, KIO::NetAccess::lastErrorString());
103 * }
104 * \endcode
105 *
106 * Of course, your user interface will still process exposure/repaint
107 * events during the download.
108 *
109 * If the download fails, lastError() and lastErrorString() will be set.
110 *
111 * If the url is always remote, then you could also just write the more usual way:
112 * \code
113 * KTemporaryFile tmpFile;
114 * if (tmpFile.open()) {
115 * KIO::Job* getJob = KIO::file_copy(url, KUrl(tmpFile.fileName()), -1, KIO::Overwrite | KIO::HideProgressInfo);
116 * getJob->ui()->setWindow(window);
117 * if (KIO::NetAccess::synchronousRun(getJob, 0)) {
118 * loadFile(tmpFile.fileName());
119 * } else {
120 * getJob->ui()->showErrorMessage();
121 * }
122 * }
123 * \endcode
124 *
125 * @param src URL Reference to the file to download.
126 * @param target String containing the final local location of the
127 * file. If you insert an empty string, it will
128 * return a location in a temporary spot. <B>Note:</B>
129 * you are responsible for the removal of this file when
130 * you are finished reading it using removeTempFile.
131 * @param window main window associated with this job. This is used to
132 * automatically cache and discard authentication information
133 * as needed. If NULL, authentication information will be
134 * cached only for a short duration after which the user will
135 * again be prompted for passwords as needed.
136 * @return true if successful, false for failure. Use lastErrorString() to
137 * get the reason it failed.
138 *
139 * @see lastErrorString()
140 */
141 static bool download(const KUrl& src, QString & target, QWidget* window);
142
143 /**
144 * Removes the specified file if and only if it was created
145 * by KIO::NetAccess as a temporary file for a former download.
146 *
147 * Note: This means that if you created your temporary with KTempFile,
148 * use KTempFile::unlink() or KTempFile::setAutoDelete() to have
149 * it removed.
150 *
151 * @param name Path to temporary file to remove. May not be
152 * empty.
153 */
154 static void removeTempFile(const QString& name);
155
156 /**
157 * Uploads file @p src to URL @p target.
158 *
159 * Both must be specified, unlike download.
160 * Note that this is assumed to be used for saving a file over
161 * the network, so overwriting is set to true. This is not the
162 * case with copy.
163 *
164 * @param src URL Referencing the file to upload.
165 * @param target URL containing the final location of the file.
166 * @param window main window associated with this job. This is used to
167 * automatically cache and discard authentication information
168 * as needed. If NULL, authentication information will be cached
169 * only for a short duration after which the user will again be
170 * prompted for passwords as needed.
171 *
172 * @return true if successful, false for failure
173 */
174 static bool upload(const QString& src, const KUrl& target, QWidget* window);
175
176 /**
177 * Alternative to upload for copying over the network.
178 * Overwrite is false, so this will fail if @p target exists.
179 *
180 * This one takes two URLs and is a direct equivalent of KIO::file_copy.
181 *
182 * @param src URL Referencing the file to upload.
183 * @param target URL containing the final location of the file.
184 * @param window main window associated with this job. This is used to
185 * automatically cache and discard authentication information
186 * as needed. If NULL, authentication information will be cached
187 * only for a short duration after which the user will again be
188 * prompted for passwords as needed.
189 *
190 * @return true if successful, false for failure
191 */
192 static bool file_copy( const KUrl& src, const KUrl& target, QWidget* window = 0 );
193 /// @deprecated, use file_copy instead
194#ifndef KDE_NO_DEPRECATED
195 static KDE_DEPRECATED bool copy( const KUrl& src, const KUrl& target,
196 QWidget* window = 0 );
197#endif
198
199 /**
200 * Alternative method for copying over the network.
201 *
202 * This one takes two URLs and is a direct equivalent
203 * of KIO::copy!.
204 * This means that it can copy files and directories alike
205 * (it should have been named copy()).
206 *
207 * This method will bring up a dialog if the destination already exists.
208 *
209 * @param src URL Referencing the file to upload.
210 * @param target URL containing the final location of the
211 * file.
212 * @param window main window associated with this job. This is used to
213 * automatically cache and discard authentication information
214 * as needed. If NULL, authentication information will be cached
215 * only for a short duration after which the user will again be
216 * prompted for passwords as needed.
217 * @return true if successful, false for failure
218 */
219 static bool dircopy( const KUrl& src, const KUrl& target, QWidget* window ); // TODO deprecate in favor of KIO::copy + synchronousRun (or job->exec())
220
221 /**
222 * Overloaded method, which takes a list of source URLs
223 */
224 static bool dircopy( const KUrl::List& src, const KUrl& target, QWidget* window = 0L ); // TODO deprecate in favor of KIO::copy + synchronousRun (or job->exec())
225
226 /**
227 * Full-fledged equivalent of KIO::move.
228 * Moves or renames one file or directory.
229 * @deprecated use KIO::move and then KIO::NetAccess::synchronousRun (or job->exec())
230 */
231#ifndef KDE_NO_DEPRECATED
232 static KDE_DEPRECATED bool move( const KUrl& src, const KUrl& target, QWidget* window = 0L );
233#endif
234
235 /**
236 * Full-fledged equivalent of KIO::move.
237 * Moves or renames a list of files or directories.
238 * @deprecated use KIO::move and then KIO::NetAccess::synchronousRun (or job->exec())
239 */
240#ifndef KDE_NO_DEPRECATED
241 static KDE_DEPRECATED bool move( const KUrl::List& src, const KUrl& target, QWidget* window = 0L );
242#endif
243
244 /**
245 * Tests whether a URL exists.
246 *
247 * @param url the URL we are testing
248 * @param source if true, we want to read from that URL.
249 * If false, we want to write to it.
250 * IMPORTANT: see documentation for KIO::stat for more details about this.
251 * @param window main window associated with this job. This is used to
252 * automatically cache and discard authentication information
253 * as needed. If NULL, authentication information will be
254 * cached only for a short duration after which the user will
255 * again be prompted for passwords as needed.
256 * @return true if the URL exists and we can do the operation specified by
257 * @p source, false otherwise
258 *
259 * @deprecated use the StatSide enum instead of the bool source
260 */
261#ifndef KDE_NO_DEPRECATED
262 static KDE_DEPRECATED bool exists(const KUrl& url, bool source, QWidget* window);
263#endif
264
265 /**
266 * Tests whether a URL exists.
267 *
268 * @param url the URL we are testing
269 * @param statSide determines if we want to read or write.
270 * IMPORTANT: see documentation for KIO::stat for more details about this.
271 * @param window main window associated with this job. This is used to
272 * automatically cache and discard authentication information
273 * as needed. If NULL, authentication information will be
274 * cached only for a short duration after which the user will
275 * again be prompted for passwords as needed.
276 * @return true if the URL exists and we can do the operation specified by
277 * @p source, false otherwise
278 */
279 static bool exists(const KUrl& url, StatSide statSide, QWidget* window);
280
281 /**
282 * Tests whether a URL exists and return information on it.
283 *
284 * This is a convenience function for KIO::stat
285 * (it saves creating a slot and testing for the job result).
286 *
287 * @param url The URL we are testing.
288 * @param entry The result of the stat. Iterate over the list
289 * of atoms to get hold of name, type, size, etc., or use KFileItem.
290 * @param window main window associated with this job. This is used to
291 * automatically cache and discard authentication information
292 * as needed. If NULL, authentication information will be
293 * cached only for a short duration after which the user will
294 * again be prompted for passwords as needed.
295 * @return true if successful, false for failure
296 */
297 static bool stat(const KUrl& url, KIO::UDSEntry & entry, QWidget* window);
298
299
300 /**
301 * Tries to map a local URL for the given URL.
302 *
303 * This is a convenience function for KIO::stat + parsing the
304 * resulting UDSEntry.
305 *
306 * @param url The URL we are testing.
307 * @param window main window associated with this job. This is used to
308 * automatically cache and discard authentication information
309 * as needed. If NULL, authentication information will be
310 * cached only for a short duration after which the user will
311 * again be prompted for passwords as needed.
312 * @return a local URL corresponding to the same resource than the
313 * original URL, or the original URL if no local URL can be mapped
314 */
315 static KUrl mostLocalUrl(const KUrl& url, QWidget* window);
316
317 /**
318 * Deletes a file or a directory in a synchronous way.
319 *
320 * This is a convenience function for KIO::del
321 * (it saves creating a slot and testing for the job result).
322 *
323 * @param url The file or directory to delete.
324 * @param window main window associated with this job. This is used to
325 * automatically cache and discard authentication information
326 * as needed. If NULL, authentication information will be
327 * cached only for a short duration after which the user will
328 * again be prompted for passwords as needed.
329 * @return true on success, false on failure.
330 */
331 static bool del( const KUrl & url, QWidget* window );
332
333 /**
334 * Creates a directory in a synchronous way.
335 *
336 * This is a convenience function for @p KIO::mkdir
337 * (it saves creating a slot and testing for the job result).
338 *
339 * @param url The directory to create.
340 * @param window main window associated with this job. This is used to
341 * automatically cache and discard authentication information
342 * as needed. If NULL, authentication information will be
343 * cached only for a short duration after which the user will
344 * again be prompted for passwords as needed.
345 * @param permissions directory permissions.
346 * @return true on success, false on failure.
347 */
348 static bool mkdir( const KUrl & url, QWidget* window, int permissions = -1 );
349
350 /**
351 * Executes a remote process via the fish ioslave in a synchronous way.
352 *
353 * @param url The remote machine where the command should be executed.
354 * e.g. fish://someuser\@somehost:sshport/
355 * some special cases exist.
356 * fish://someuser\@localhost/
357 * will use su instead of ssh to connect and execute the command.
358 * fish://someuser\@localhost:port/
359 * will use ssh to connect and execute the command.
360 * @param command The command to be executed.
361 * @param window main window associated with this job. This is used to
362 * automatically cache and discard authentication information
363 * as needed. If NULL, authentication information will be
364 * cached only for a short duration after which the user will
365 * again be prompted for passwords as needed.
366 * @return The resulting output of the @p command that is executed.
367 */
368 static QString fish_execute( const KUrl & url, const QString &command, QWidget* window );
369
370 /**
371 * This function executes a job in a synchronous way.
372 * If a job fetches some data, pass a QByteArray pointer as data parameter to this function
373 * and after the function returns it will contain all the data fetched by this job.
374 *
375 * @code
376 * KIO::Job *job = KIO::get( url );
377 * QMap<QString, QString> metaData;
378 * metaData.insert( "PropagateHttpHeader", "true" );
379 * if ( NetAccess::synchronousRun( job, 0, &data, &url, &metaData ) ) {
380 * QString responseHeaders = metaData[ "HTTP-Headers" ];
381 * kDebug()<<"Response header = "<< responseHeaders;
382 * }
383 * @endcode
384 *
385 * @param job job which the function will run. Note that after this function
386 * finishes running, job is deleted and you can't access it anymore!
387 * @param window main window associated with this job. This is used to
388 * automatically cache and discard authentication information
389 * as needed. If NULL, authentication information will be
390 * cached only for a short duration after which the user will
391 * again be prompted for passwords as needed.
392 * @param data if passed and relevant to this job then it will contain the data
393 * that was fetched by the job
394 * @param finalURL if passed will contain the final url of this job (it might differ
395 * from the one it was created with if there was a redirection)
396 * @param metaData you can pass a pointer to the map with meta data you wish to
397 * set on the job. After the job finishes this map will hold all the
398 * meta data from the job.
399 *
400 * @return true on success, false on failure.
401 */
402 static bool synchronousRun( Job* job, QWidget* window, QByteArray* data=0,
403 KUrl* finalURL=0, QMap<QString,QString>* metaData=0 );
404
405 /**
406 * Determines the mimetype of a given URL.
407 *
408 * This is a convenience function for KIO::mimetype. You
409 * should call this only when really necessary.
410 * KMimeType::findByUrl can determine extension a lot faster, but
411 * less reliably for remote files. Only when findByUrl() returns
412 * unknown (application/octet-stream) then this one should be
413 * used.
414 *
415 * @param url The URL whose mimetype we are interested in.
416 * @param window main window associated with this job. This is used to
417 * automatically cache and discard authentication information
418 * as needed. If NULL, authentication information will be
419 * cached only for a short duration after which the user will
420 * again be prompted for passwords as needed.
421 * @return The mimetype name.
422 */
423 static QString mimetype( const KUrl & url, QWidget* window );
424
425
426 /**
427 * Returns the error string for the last job, in case it failed.
428 * Note that this is already translated.
429 * @return the last error string, or QString()
430 */
431 static QString lastErrorString();
432
433 /**
434 * Returns the error code for the last job, in case it failed.
435 * @return the last error code
436 */
437 static int lastError();
438
439Q_SIGNALS:
440 void leaveModality();
441private:
442 /**
443 * Private constructor
444 */
445 NetAccess();
446
447 /**
448 * Private destructor
449 */
450 ~NetAccess();
451
452 /**
453 * Internal methods
454 */
455 bool filecopyInternal(const KUrl& src, const KUrl& target, int permissions,
456 KIO::JobFlags flags, QWidget* window, bool move);
457 bool dircopyInternal(const KUrl::List& src, const KUrl& target,
458 QWidget* window, bool move);
459 bool statInternal(const KUrl & url, int details, StatSide side, QWidget* window = 0);
460
461 bool delInternal(const KUrl & url, QWidget* window = 0);
462 bool mkdirInternal(const KUrl & url, int permissions, QWidget* window = 0);
463 QString fish_executeInternal(const KUrl & url, const QString &command, QWidget* window = 0);
464 bool synchronousRunInternal( Job* job, QWidget* window, QByteArray* data,
465 KUrl* finalURL, QMap<QString,QString>* metaData );
466
467 QString mimetypeInternal(const KUrl & url, QWidget* window = 0);
468 void enter_loop();
469
470 friend class I_like_this_class;
471
472private Q_SLOTS:
473 void slotResult( KJob * job );
474 void slotMimetype( KIO::Job * job, const QString & type );
475 void slotData( KIO::Job*, const QByteArray& );
476 void slotRedirection( KIO::Job*, const KUrl& );
477
478private:
479 NetAccessPrivate * const d;
480};
481
482}
483
484#endif
485