1 /*
2     SPDX-FileCopyrightText: 2019 Dan Leinir Turthra Jensen <admin@leinir.dk>
3 
4     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5 */
6 
7 #include "author.h"
8 
9 #include "quickengine.h"
10 
11 #include "core/author.h"
12 #include "core/engine.h"
13 #include "core/provider.h"
14 
15 #include "knewstuffquick_debug.h"
16 
17 #include <memory>
18 
19 namespace KNewStuffQuick
20 {
21 // This caching will want to eventually go into the Provider level (and be more generalised)
22 typedef QHash<QString, std::shared_ptr<KNSCore::Author>> AllAuthorsHash;
23 Q_GLOBAL_STATIC(AllAuthorsHash, allAuthors)
24 
25 class Author::Private
26 {
27 public:
Private(Author * qq)28     Private(Author *qq)
29         : q(qq)
30     {
31     }
32     Author *const q;
33     bool componentCompleted{false};
34     Engine *engine{nullptr};
35     QString providerId;
36     QString username;
37 
38     QSharedPointer<KNSCore::Provider> provider;
resetConnections()39     void resetConnections()
40     {
41         if (!componentCompleted) {
42             return;
43         }
44         if (provider) {
45             provider->disconnect(q);
46         }
47         if (engine && engine->engine()) {
48             KNSCore::Engine *coreEngine = qobject_cast<KNSCore::Engine *>(engine->engine());
49             if (coreEngine) {
50                 provider = coreEngine->provider(providerId);
51             }
52             if (!provider) {
53                 provider = coreEngine->defaultProvider();
54             }
55         }
56         if (provider) {
57             connect(provider.get(), &KNSCore::Provider::personLoaded, q, [=](const std::shared_ptr<KNSCore::Author> author) {
58                 allAuthors()->insert(QStringLiteral("%1 %2").arg(provider->id(), author->id()), author);
59                 Q_EMIT q->dataChanged();
60             });
61             author(); // Check and make sure...
62         }
63     }
64 
author()65     std::shared_ptr<KNSCore::Author> author()
66     {
67         std::shared_ptr<KNSCore::Author> ret;
68         if (provider && !username.isEmpty()) {
69             ret = allAuthors()->value(QStringLiteral("%1 %2").arg(provider->id(), username));
70             if (!ret.get()) {
71                 Q_EMIT provider->loadPerson(username);
72             }
73         }
74         return ret;
75     }
76 };
77 }
78 
79 using namespace KNewStuffQuick;
80 
Author(QObject * parent)81 Author::Author(QObject *parent)
82     : QObject(parent)
83     , d(new Private(this))
84 {
85     connect(this, &Author::engineChanged, &Author::dataChanged);
86     connect(this, &Author::providerIdChanged, &Author::dataChanged);
87     connect(this, &Author::usernameChanged, &Author::dataChanged);
88 }
89 
~Author()90 Author::~Author()
91 {
92     delete d;
93 }
94 
classBegin()95 void Author::classBegin()
96 {
97 }
98 
componentComplete()99 void Author::componentComplete()
100 {
101     d->componentCompleted = true;
102     d->resetConnections();
103 }
104 
engine() const105 QObject *Author::engine() const
106 {
107     return d->engine;
108 }
109 
setEngine(QObject * newEngine)110 void Author::setEngine(QObject *newEngine)
111 {
112     if (d->engine != newEngine) {
113         d->engine = qobject_cast<Engine *>(newEngine);
114         d->resetConnections();
115         Q_EMIT engineChanged();
116     }
117 }
118 
providerId() const119 QString Author::providerId() const
120 {
121     return d->providerId;
122 }
123 
setProviderId(const QString & providerId)124 void Author::setProviderId(const QString &providerId)
125 {
126     if (d->providerId != providerId) {
127         d->providerId = providerId;
128         d->resetConnections();
129         Q_EMIT providerIdChanged();
130     }
131 }
132 
username() const133 QString Author::username() const
134 {
135     return d->username;
136 }
137 
setUsername(const QString & username)138 void Author::setUsername(const QString &username)
139 {
140     if (d->username != username) {
141         d->username = username;
142         d->resetConnections();
143         Q_EMIT usernameChanged();
144     }
145 }
146 
name() const147 QString Author::name() const
148 {
149     std::shared_ptr<KNSCore::Author> author = d->author();
150     if (author.get() && !author->name().isEmpty()) {
151         return author->name();
152     }
153     return d->username;
154 }
155 
description() const156 QString Author::description() const
157 {
158     std::shared_ptr<KNSCore::Author> author = d->author();
159     if (author.get()) {
160         return author->description();
161     }
162     return QString{};
163 }
164 
homepage() const165 QString Author::homepage() const
166 {
167     std::shared_ptr<KNSCore::Author> author = d->author();
168     if (author.get()) {
169         return author->homepage();
170     }
171     return QString{};
172 }
173 
profilepage() const174 QString Author::profilepage() const
175 {
176     std::shared_ptr<KNSCore::Author> author = d->author();
177     if (author.get()) {
178         return author->profilepage();
179     }
180     return QString{};
181 }
182 
avatarUrl() const183 QUrl Author::avatarUrl() const
184 {
185     std::shared_ptr<KNSCore::Author> author = d->author();
186     if (author.get()) {
187         return author->avatarUrl();
188     }
189     return QUrl{};
190 }
191