1 /* This file is part of Clementine.
2    Copyright 2010, David Sansome <me@davidsansome.com>
3 
4    Clementine is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, either version 3 of the License, or
7    (at your option) any later version.
8 
9    Clementine is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License
15    along with Clementine.  If not, see <http://www.gnu.org/licenses/>.
16 */
17 
18 #include "connecteddevice.h"
19 #include "gpodloader.h"
20 #include "core/logging.h"
21 #include "core/song.h"
22 #include "core/taskmanager.h"
23 #include "library/librarybackend.h"
24 
25 #include <gpod/itdb.h>
26 
27 #include <QDir>
28 #include <QtDebug>
29 
GPodLoader(const QString & mount_point,TaskManager * task_manager,LibraryBackend * backend,std::shared_ptr<ConnectedDevice> device)30 GPodLoader::GPodLoader(const QString& mount_point, TaskManager* task_manager,
31                        LibraryBackend* backend,
32                        std::shared_ptr<ConnectedDevice> device)
33     : QObject(nullptr),
34       device_(device),
35       mount_point_(mount_point),
36       type_(Song::Type_Unknown),
37       task_manager_(task_manager),
38       backend_(backend) {
39   original_thread_ = thread();
40 }
41 
~GPodLoader()42 GPodLoader::~GPodLoader() {}
43 
LoadDatabase()44 void GPodLoader::LoadDatabase() {
45   int task_id = task_manager_->StartTask(tr("Loading iPod database"));
46   emit TaskStarted(task_id);
47 
48   // Load the iTunes database
49   GError* error = nullptr;
50   Itdb_iTunesDB* db =
51       itdb_parse(QDir::toNativeSeparators(mount_point_).toLocal8Bit(), &error);
52 
53   // Check for errors
54   if (!db) {
55     if (error) {
56       qLog(Error) << "loading database failed:"
57                   << QString::fromUtf8(error->message);
58       emit Error(QString::fromUtf8(error->message));
59       g_error_free(error);
60     } else {
61       emit Error(tr("An error occurred loading the iTunes database"));
62     }
63 
64     task_manager_->SetTaskFinished(task_id);
65     return;
66   }
67 
68   // Convert all the tracks from libgpod structs into Song classes
69   const QString prefix = path_prefix_.isEmpty()
70                              ? QDir::fromNativeSeparators(mount_point_)
71                              : path_prefix_;
72 
73   SongList songs;
74   for (GList* tracks = db->tracks; tracks != nullptr; tracks = tracks->next) {
75     Itdb_Track* track = static_cast<Itdb_Track*>(tracks->data);
76 
77     Song song;
78     song.InitFromItdb(track, prefix);
79     song.set_directory_id(1);
80 
81     if (type_ != Song::Type_Unknown) song.set_filetype(type_);
82     songs << song;
83   }
84 
85   // Need to remove all the existing songs in the database first
86   backend_->DeleteSongs(backend_->FindSongsInDirectory(1));
87 
88   // Add the songs we've just loaded
89   backend_->AddOrUpdateSongs(songs);
90 
91   moveToThread(original_thread_);
92 
93   task_manager_->SetTaskFinished(task_id);
94   emit LoadFinished(db);
95 }
96