1/*
2 SPDX-FileCopyrightText: 2013 Marco Martin <mart@kde.org>
3 SPDX-FileCopyrightText: 2014 Sebastian Kügler <sebas@kde.org>
4
5 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
6*/
7
8#include "kuserproxy.h"
9#include <QDir>
10#include <QFile>
11#include <QHostInfo>
12#include <QTextStream>
13#include <QUrl>
14
15// clazy:excludeall=non-pod-global-static
16const QString etcPasswd = QStringLiteral("/etc/passwd");
17const QString accountsServiceIconPath = QStringLiteral("/var/lib/AccountsService/icons");
18
19KUserProxy::KUserProxy(QObject *parent)
20 : QObject(parent)
21 , m_temporaryEmptyFaceIconPath(false)
22{
23 QString pathToFaceIcon(m_user.faceIconPath());
24 if (pathToFaceIcon.isEmpty()) {
25 // KUser returns null if the current faceIconPath is empty
26 // so we should explicitly watch ~/.face.icon rather than faceIconPath()
27 // as we want to watch for this file being created
28 pathToFaceIcon = QDir::homePath() + QStringLiteral("/.face.icon");
29 }
30
31 m_dirWatch.addFile(file: pathToFaceIcon);
32 m_dirWatch.addFile(file: accountsServiceIconPath + QLatin1Char('/') + m_user.loginName());
33 if (QFile::exists(fileName: etcPasswd)) {
34 m_dirWatch.addFile(file: etcPasswd);
35 }
36
37 connect(sender: &m_dirWatch, signal: &KDirWatch::dirty, context: this, slot: &KUserProxy::update);
38 connect(sender: &m_dirWatch, signal: &KDirWatch::created, context: this, slot: &KUserProxy::update);
39 connect(sender: &m_dirWatch, signal: &KDirWatch::deleted, context: this, slot: &KUserProxy::update);
40}
41
42KUserProxy::~KUserProxy()
43{
44}
45
46void KUserProxy::update(const QString &path)
47{
48 if (path == m_user.faceIconPath() || path == QDir::homePath() + QLatin1String("/.face.icon")
49 || path == accountsServiceIconPath + QLatin1Char('/') + m_user.loginName()) {
50 // we need to force updates, even when the path doesn't change,
51 // but the underlying image does. Change path temporarily, to
52 // make the Image reload.
53 // Needs cache: false in the Image item to actually reload
54 m_temporaryEmptyFaceIconPath = true;
55 Q_EMIT faceIconUrlChanged();
56 m_temporaryEmptyFaceIconPath = false;
57 Q_EMIT faceIconUrlChanged();
58 } else if (path == etcPasswd) {
59 m_user = KUser();
60 Q_EMIT nameChanged();
61 }
62}
63
64QString KUserProxy::fullName() const
65{
66 QString fullName = m_user.property(which: KUser::FullName).toString();
67 if (!fullName.isEmpty()) {
68 return fullName;
69 }
70 return loginName();
71}
72
73QString KUserProxy::loginName() const
74{
75 return m_user.loginName();
76}
77
78QUrl KUserProxy::faceIconUrl() const
79{
80 if (m_temporaryEmptyFaceIconPath) {
81 return QUrl();
82 }
83 const QString u = m_user.faceIconPath();
84 const QFile f(u);
85 if (f.exists(fileName: u)) {
86 // We need to return a file URL, not a simple path
87 return QUrl::fromLocalFile(localfile: u);
88 }
89 return QUrl();
90}
91
92QString KUserProxy::os()
93{
94 if (m_os.isEmpty()) {
95 QFile osfile(QStringLiteral("/etc/os-release"));
96 if (osfile.exists()) {
97 if (!osfile.open(flags: QIODevice::ReadOnly | QIODevice::Text)) {
98 return QString();
99 }
100
101 QTextStream in(&osfile);
102 while (!in.atEnd()) {
103 QString line = in.readLine();
104 if (line.startsWith(s: QLatin1String("PRETTY_NAME"))) {
105 QStringList fields = line.split(sep: QLatin1String("PRETTY_NAME=\""));
106 if (fields.count() == 2) {
107 osfile.close();
108 QString pretty = fields.at(i: 1);
109 pretty.chop(n: 1);
110 m_os = pretty;
111 return pretty;
112 }
113 }
114 }
115 }
116 }
117 return m_os;
118}
119
120QString KUserProxy::host() const
121{
122 return QHostInfo::localHostName();
123}
124
125#include "moc_kuserproxy.cpp"
126

source code of kcoreaddons/src/qml/kuserproxy.cpp