~ubuntu-branches/ubuntu/precise/ark/precise-proposed

« back to all changes in this revision

Viewing changes to kerfuffle/archive.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2011-12-15 14:20:40 UTC
  • Revision ID: package-import@ubuntu.com-20111215142040-v5d1fjy6vqmq3nuc
Tags: upstream-4.7.90
ImportĀ upstreamĀ versionĀ 4.7.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2007 Henrique Pinto <henrique.pinto@kdemail.net>
 
3
 * Copyright (c) 2008 Harald Hvaal <haraldhv@stud.ntnu.no>
 
4
 * Copyright (c) 2009 Raphael Kubo da Costa <kubito@gmail.com>
 
5
 *
 
6
 * Redistribution and use in source and binary forms, with or without
 
7
 * modification, are permitted provided that the following conditions
 
8
 * are met:
 
9
 *
 
10
 * 1. Redistributions of source code must retain the above copyright
 
11
 *    notice, this list of conditions and the following disclaimer.
 
12
 * 2. Redistributions in binary form must reproduce the above copyright
 
13
 *    notice, this list of conditions and the following disclaimer in the
 
14
 *    documentation and/or other materials provided with the distribution.
 
15
 *
 
16
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 
17
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 
18
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 
19
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 
20
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ( INCLUDING, BUT
 
21
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 
22
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
 
23
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
24
 * ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
 
25
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
26
 */
 
27
#include "archive.h"
 
28
#include "archivebase.h"
 
29
#include "archiveinterface.h"
 
30
 
 
31
#include <QByteArray>
 
32
#include <QFile>
 
33
#include <QFileInfo>
 
34
 
 
35
#include <KDebug>
 
36
#include <KPluginLoader>
 
37
#include <KMimeType>
 
38
#include <KMimeTypeTrader>
 
39
#include <KServiceTypeTrader>
 
40
 
 
41
static bool comparePlugins(const KService::Ptr &p1, const KService::Ptr &p2)
 
42
{
 
43
    return (p1->property(QLatin1String( "X-KDE-Priority" )).toInt()) > (p2->property(QLatin1String( "X-KDE-Priority" )).toInt());
 
44
}
 
45
 
 
46
static QString determineMimeType(const QString& filename)
 
47
{
 
48
    if (!QFile::exists(filename)) {
 
49
        return KMimeType::findByPath(filename)->name();
 
50
    }
 
51
 
 
52
    QFile file(filename);
 
53
    if (!file.open(QIODevice::ReadOnly)) {
 
54
        return QString();
 
55
    }
 
56
 
 
57
    const qint64 maxSize = 0x100000; // 1MB
 
58
    const qint64 bufferSize = qMin(maxSize, file.size());
 
59
    const QByteArray buffer = file.read(bufferSize);
 
60
 
 
61
    return KMimeType::findByNameAndContent(filename, buffer)->name();
 
62
}
 
63
 
 
64
static KService::List findPluginOffers(const QString& filename, const QString& fixedMimeType)
 
65
{
 
66
    KService::List offers;
 
67
 
 
68
    const QString mimeType = fixedMimeType.isEmpty() ? determineMimeType(filename) : fixedMimeType;
 
69
 
 
70
    if (!mimeType.isEmpty()) {
 
71
        offers = KMimeTypeTrader::self()->query(mimeType, QLatin1String( "Kerfuffle/Plugin" ), QLatin1String( "(exist Library)" ));
 
72
        qSort(offers.begin(), offers.end(), comparePlugins);
 
73
    }
 
74
 
 
75
    return offers;
 
76
}
 
77
 
 
78
namespace Kerfuffle
 
79
{
 
80
 
 
81
Archive *factory(const QString& filename, const QString& fixedMimeType)
 
82
{
 
83
    qRegisterMetaType<ArchiveEntry>("ArchiveEntry");
 
84
 
 
85
    const KService::List offers = findPluginOffers(filename, fixedMimeType);
 
86
 
 
87
    if (offers.isEmpty()) {
 
88
        kDebug() << "Could not find a plugin to handle" << filename;
 
89
        return NULL;
 
90
    }
 
91
 
 
92
    const QString pluginName = offers.first()->library();
 
93
    kDebug() << "Loading plugin" << pluginName;
 
94
 
 
95
    KPluginFactory * const factory = KPluginLoader(pluginName).factory();
 
96
    if (!factory) {
 
97
        kDebug() << "Invalid plugin factory for" << pluginName;
 
98
        return NULL;
 
99
    }
 
100
 
 
101
    QVariantList args;
 
102
    args.append(QVariant(QFileInfo(filename).absoluteFilePath()));
 
103
 
 
104
    ReadOnlyArchiveInterface * const iface = factory->create<ReadOnlyArchiveInterface>(0, args);
 
105
    if (!iface) {
 
106
        kDebug() << "Could not create plugin instance" << pluginName << "for" << filename;
 
107
        return NULL;
 
108
    }
 
109
 
 
110
    return new ArchiveBase(iface);
 
111
}
 
112
 
 
113
QStringList supportedMimeTypes()
 
114
{
 
115
    const QLatin1String constraint("(exist Library)");
 
116
    const QLatin1String basePartService("Kerfuffle/Plugin");
 
117
 
 
118
    const KService::List offers = KServiceTypeTrader::self()->query(basePartService, constraint);
 
119
    KService::List::ConstIterator it = offers.constBegin();
 
120
    KService::List::ConstIterator itEnd = offers.constEnd();
 
121
 
 
122
    QStringList supported;
 
123
 
 
124
    for (; it != itEnd; ++it) {
 
125
        KService::Ptr service = *it;
 
126
        QStringList mimeTypes = service->serviceTypes();
 
127
 
 
128
        foreach (const QString& mimeType, mimeTypes) {
 
129
            if (mimeType != basePartService && !supported.contains(mimeType)) {
 
130
                supported.append(mimeType);
 
131
            }
 
132
        }
 
133
    }
 
134
 
 
135
    kDebug() << "Returning" << supported;
 
136
 
 
137
    return supported;
 
138
}
 
139
 
 
140
QStringList supportedWriteMimeTypes()
 
141
{
 
142
    const QLatin1String constraint("(exist Library) and ([X-KDE-Kerfuffle-ReadWrite] == true)");
 
143
    const QLatin1String basePartService("Kerfuffle/Plugin");
 
144
 
 
145
    const KService::List offers = KServiceTypeTrader::self()->query(basePartService, constraint);
 
146
    KService::List::ConstIterator it = offers.constBegin();
 
147
    KService::List::ConstIterator itEnd = offers.constEnd();
 
148
 
 
149
    QStringList supported;
 
150
 
 
151
    for (; it != itEnd; ++it) {
 
152
        KService::Ptr service = *it;
 
153
        QStringList mimeTypes = service->serviceTypes();
 
154
 
 
155
        foreach (const QString& mimeType, mimeTypes) {
 
156
            if (mimeType != basePartService && !supported.contains(mimeType)) {
 
157
                supported.append(mimeType);
 
158
            }
 
159
        }
 
160
    }
 
161
 
 
162
    kDebug() << "Returning" << supported;
 
163
 
 
164
    return supported;
 
165
}
 
166
 
 
167
} // namespace Kerfuffle