~ubuntu-branches/ubuntu/lucid/lastfm/lucid

« back to all changes in this revision

Viewing changes to src/ITunesPluginInstaller.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Devid Filoni
  • Date: 2008-07-14 16:46:20 UTC
  • mfrom: (1.1.7 upstream) (3.1.1 lenny)
  • Revision ID: james.westby@ubuntu.com-20080714164620-67hoz9fs177wpgmr
Tags: 1:1.5.1.31879.dfsg-1ubuntu1
* Merge from Debian unstable (LP: #248100), remaining changes:
  - debian/rules: add dh_icons call
  + debian/control:
    - switch iceweasel to firefox in Recommends field
    - modify debhelper version to >= 5.0.51~
    - modify Maintainer to Ubuntu MOTU Developers

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
 *   Copyright (C) 2005 - 2008 by                                          *
 
3
 *      Last.fm Ltd <client@last.fm>                                       *
 
4
 *                                                                         *
 
5
 *   This program is free software; you can redistribute it and/or modify  *
 
6
 *   it under the terms of the GNU General Public License as published by  *
 
7
 *   the Free Software Foundation; either version 2 of the License, or     *
 
8
 *   (at your option) any later version.                                   *
 
9
 *                                                                         *
 
10
 *   This program is distributed in the hope that it will be useful,       *
 
11
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 
12
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 
13
 *   GNU General Public License for more details.                          *
 
14
 *                                                                         *
 
15
 *   You should have received a copy of the GNU General Public License     *
 
16
 *   along with this program; if not, write to the                         *
 
17
 *   Free Software Foundation, Inc.,                                       *
 
18
 *   51 Franklin Steet, Fifth Floor, Boston, MA  02110-1301, USA.          *
 
19
 ***************************************************************************/
 
20
 
 
21
#include "ITunesPluginInstaller.h"
 
22
 
 
23
#include "MooseCommon.h"
 
24
#include "UnicornCommon.h"
 
25
#include "UnicornCommonMac.h"
 
26
#include "logger.h"
 
27
#include "ITunesScript.h"
 
28
#include "LastMessageBox.h"
 
29
 
 
30
#include <QDir>
 
31
#include <QProcess>
 
32
 
 
33
static const char* kBundleName = "AudioScrobbler.bundle";
 
34
static const char* kPListFile = "Contents/Info.plist";
 
35
 
 
36
 
 
37
ITunesPluginInstaller::ITunesPluginInstaller()
 
38
        : k_shippedPluginDir( qApp->applicationDirPath() + "/PlugIns/" + kBundleName + "/" ),
 
39
          k_iTunesPluginDir( QDir::homePath() + "/Library/iTunes/iTunes Plug-ins/" + kBundleName + "/" ),
 
40
          m_needsTwiddlyBootstrap( false )
 
41
{}
 
42
 
 
43
 
 
44
void
 
45
ITunesPluginInstaller::install()
 
46
{
 
47
    qDebug() << "Found installed iTunes plugin?" << isPluginInstalled();
 
48
 
 
49
    QString installedVersion;
 
50
    QString shippedVersion;
 
51
 
 
52
    disableLegacyHelperApp();
 
53
 
 
54
    if ( isPluginInstalled() ) 
 
55
    {
 
56
        installedVersion = pListVersion( k_iTunesPluginDir + kPListFile );
 
57
        qDebug() << "Found installed iTunes plugin version:" << installedVersion;
 
58
    }
 
59
    else
 
60
        //TODO don't bootstrap if installation fails
 
61
        m_needsTwiddlyBootstrap = true;
 
62
 
 
63
    shippedVersion = pListVersion( k_shippedPluginDir + kPListFile );
 
64
    if ( shippedVersion.isEmpty() )
 
65
    {
 
66
        qDebug() << "Could not locate shipped iTunes plugin!";
 
67
    }
 
68
    else
 
69
    {
 
70
        qDebug() << "Found shipped iTunes plugin version:" << shippedVersion;
 
71
 
 
72
        if ( installedVersion != shippedVersion )
 
73
        {
 
74
            qDebug() << "Installing shipped iTunes plugin...";
 
75
 
 
76
            if ( !removeInstalledPlugin() )
 
77
            {
 
78
                qDebug() << "Removing installed plugin from" << k_iTunesPluginDir << "failed!";
 
79
            }
 
80
            else
 
81
            {
 
82
                qDebug() << "Successfully removed installed plugin.";
 
83
 
 
84
                if ( installPlugin() )
 
85
                {
 
86
                    qDebug() << "Successfully installed the plugin.";
 
87
                }
 
88
                else
 
89
                    qDebug() << "Installing the plugin failed!";
 
90
            }
 
91
        }
 
92
        else
 
93
            qDebug() << "Installed iTunes plugin is up-to-date.";
 
94
    }
 
95
}
 
96
 
 
97
 
 
98
bool
 
99
ITunesPluginInstaller::isPluginInstalled()
 
100
{
 
101
    return QDir( k_iTunesPluginDir ).exists();
 
102
}
 
103
 
 
104
 
 
105
QString
 
106
ITunesPluginInstaller::pListVersion( const QString& file )
 
107
{
 
108
    QFile f( file );
 
109
    if ( !f.open( QIODevice::ReadOnly ) )
 
110
        return "";
 
111
 
 
112
    const QString key( "<key>CFBundleVersion</key>" );
 
113
    const QString begin( "<string>" );
 
114
    const QString end( "</string>" );
 
115
 
 
116
    while ( !f.atEnd() )
 
117
    {
 
118
        QString line = f.readLine();
 
119
        if ( line.contains( key ) && !f.atEnd() )
 
120
        {
 
121
            QString versionLine = QString( ( f.readLine() ) ).trimmed();
 
122
            QString version = versionLine.section( begin, 1 );
 
123
            version = version.left( version.length() - end.length() );
 
124
 
 
125
            f.close();
 
126
            return version;
 
127
        }
 
128
    }
 
129
 
 
130
    f.close();
 
131
    return "";
 
132
}
 
133
 
 
134
 
 
135
static bool
 
136
deleteDir( QString path )
 
137
{
 
138
    if ( !path.endsWith( "/" ) )
 
139
        path += "/";
 
140
 
 
141
    QDir d( path );
 
142
 
 
143
    // Remove all files
 
144
    const QStringList files = d.entryList( QDir::Files );
 
145
    foreach( QString file, files )
 
146
    {
 
147
        if ( !d.remove( file ) )
 
148
            return false;
 
149
    }
 
150
 
 
151
    // Remove all dirs (recursive)
 
152
    const QStringList dirs = d.entryList( QDir::Dirs | QDir::NoDotAndDotDot );
 
153
    foreach( QString dir, dirs )
 
154
    {
 
155
        if ( !deleteDir( path + dir ) )
 
156
            return false;
 
157
    }
 
158
 
 
159
    return d.rmdir( path );
 
160
}
 
161
 
 
162
 
 
163
bool
 
164
ITunesPluginInstaller::removeInstalledPlugin()
 
165
{
 
166
    if ( !isPluginInstalled() )
 
167
        return true;
 
168
 
 
169
    return deleteDir( k_iTunesPluginDir );
 
170
}
 
171
 
 
172
 
 
173
static bool
 
174
copyDir( QString path, QString dest )
 
175
{
 
176
    if ( !path.endsWith( '/' ) )
 
177
        path += '/';
 
178
    if ( !dest.endsWith( '/' ) )
 
179
        dest += '/';
 
180
 
 
181
    QDir( dest ).mkpath( "." );
 
182
    QDir d( path );
 
183
 
 
184
    const QStringList files = d.entryList( QDir::Files );
 
185
    foreach( QString file, files )
 
186
    {
 
187
        QFile f( path + file );
 
188
        if ( !f.copy( dest + file ) )
 
189
            return false;
 
190
    }
 
191
 
 
192
    const QStringList dirs = d.entryList( QDir::Dirs | QDir::NoDotAndDotDot );
 
193
    foreach( QString dir, dirs )
 
194
    {
 
195
        if ( !copyDir( path + dir, dest + dir ) )
 
196
            return false;
 
197
    }
 
198
 
 
199
    return true;
 
200
}
 
201
 
 
202
 
 
203
bool
 
204
ITunesPluginInstaller::installPlugin()
 
205
{
 
206
    return copyDir( k_shippedPluginDir, k_iTunesPluginDir );
 
207
}
 
208
 
 
209
 
 
210
void
 
211
ITunesPluginInstaller::disableLegacyHelperApp()
 
212
{
 
213
    qDebug() << "Disabling old LastFmHelper";
 
214
 
 
215
    // EVEN MORE LEGACY: disable oldest helper auto-launch!
 
216
    QString oldplist = QDir::homePath() + "/Library/LaunchAgents/fm.last.lastfmhelper.plist";
 
217
    if ( QFile::exists( oldplist ) )
 
218
    {
 
219
        QProcess::execute( "/bin/launchctl", QStringList() << "unload" << oldplist );
 
220
        QFile::remove( oldplist );
 
221
    }
 
222
 
 
223
    // REMOVE LastFmHelper from loginwindow.plist
 
224
    CFArrayRef prefCFArrayRef = (CFArrayRef)CFPreferencesCopyValue( CFSTR( "AutoLaunchedApplicationDictionary" ), 
 
225
                                                                    CFSTR( "loginwindow" ), 
 
226
                                                                    kCFPreferencesCurrentUser, 
 
227
                                                                    kCFPreferencesAnyHost );
 
228
    if ( prefCFArrayRef == NULL ) return;
 
229
    CFMutableArrayRef tCFMutableArrayRef = CFArrayCreateMutableCopy( NULL, 0, prefCFArrayRef );
 
230
    if ( tCFMutableArrayRef == NULL ) return;
 
231
 
 
232
    for ( int i = CFArrayGetCount( prefCFArrayRef ) - 1; i >= 0 ; i-- )
 
233
    {
 
234
        CFDictionaryRef dict = (CFDictionaryRef)CFArrayGetValueAtIndex( prefCFArrayRef, i );
 
235
        QString path = UnicornUtils::CFStringToQString( (CFStringRef) CFDictionaryGetValue( dict, CFSTR( "Path" ) ) );
 
236
 
 
237
        if ( path.toLower().contains( "lastfmhelper" ) )
 
238
        {
 
239
            // Better make sure LastFmHelper is really dead
 
240
            QProcess::execute( "/usr/bin/killall", QStringList() << "LastFmHelper" );
 
241
 
 
242
            qDebug() << "Removing helper from LoginItems at position" << i;
 
243
            CFArrayRemoveValueAtIndex( tCFMutableArrayRef, (CFIndex)i );
 
244
        }
 
245
    }
 
246
 
 
247
    CFPreferencesSetValue( CFSTR( "AutoLaunchedApplicationDictionary" ), 
 
248
                           tCFMutableArrayRef, 
 
249
                           CFSTR( "loginwindow" ), 
 
250
                           kCFPreferencesCurrentUser, 
 
251
                           kCFPreferencesAnyHost );
 
252
    CFPreferencesSynchronize( CFSTR( "loginwindow" ), 
 
253
                              kCFPreferencesCurrentUser, 
 
254
                              kCFPreferencesAnyHost );
 
255
 
 
256
    CFRelease( prefCFArrayRef );
 
257
    CFRelease( tCFMutableArrayRef );
 
258
}
 
259
 
 
260
 
 
261
void
 
262
ITunesPluginInstaller::uninstall()
 
263
{
 
264
    QDir d = k_iTunesPluginDir + "Contents/Resources";
 
265
    
 
266
    // always use absolute paths to tools! - muesli
 
267
    QProcess::startDetached( "/bin/sh", 
 
268
                             QStringList() << d.filePath( "uninstall.sh" ),
 
269
                             d.path() );
 
270
}