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

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