MythTV  master
hardwareprofile.cpp
Go to the documentation of this file.
1 #include "hardwareprofile.h"
2 
3 // qt
4 #include <QStringList>
5 #include <QDir>
6 #include <QTextStream>
7 
8 // libmythbase
9 #include "mythcorecontext.h"
10 #include "mythdirs.h"
11 #include "mythlogging.h"
12 #include "mythsystemlegacy.h"
13 #include "exitcodes.h"
14 #include "mythdate.h"
15 
16 const QString SMOLT_SERVER_LOCATION =
17  QString("http://smolt.mythtv.org/");
18 const QString SMOLT_TOKEN =
19  QString("smolt_token-smolt.mythtv.org");
20 
22 {
23  m_enabled = (gCoreContext->GetNumSetting("HardwareProfileEnabled", 0) == 1);
24  m_uuid = gCoreContext->GetSetting("HardwareProfileUUID");
25  m_publicuuid = gCoreContext->GetSetting("HardwareProfilePublicUUID");
26 
27  if (m_enabled)
28  {
30 
31  query.prepare("SELECT lastrun FROM housekeeping"
32  " WHERE tag = 'HardwareProfiler'"
33  " AND hostname = :HOST");
34  query.bindValue(":HOST", gCoreContext->GetHostName());
35  if (query.exec() && query.next())
36  m_lastUpdate = MythDate::as_utc(query.value(0).toDateTime());
37  }
38 }
39 
41 {
42  if (m_uuid.isEmpty())
43  return;
44 
45  gCoreContext->SaveSettingOnHost("HardwareProfileEnabled", "1", "");
46 }
47 
49 {
50  gCoreContext->SaveSettingOnHost("HardwareProfileEnabled", "0", "");
51 }
52 
54 {
55  QString fileprefix = GetConfDir() + "/HardwareProfile";
56  QDir dir(fileprefix);
57  if (!dir.exists())
58  dir.mkdir(fileprefix);
59 
60  // Generate the Private Hardware UUID (or recover them from the DB or file)
61 
62  QString fileUUID = GetPrivateUUIDFromFile();
63 
64  if (fileUUID.isEmpty() && m_uuid.isEmpty())
65  {
66  LOG(VB_GENERAL, LOG_INFO,
67  "No UUID in DB or File, generating new UUID...");
68 
69  QString cmd = GetShareDir() + "hardwareprofile/sendProfile.py";
70  QStringList args;
71  args << "-p";
73 
74  system.Run();
75  system.Wait();
76  m_hardwareProfile = system.ReadAll();
78  }
79  else if (fileUUID.isEmpty())
80  {
81  LOG(VB_GENERAL, LOG_INFO,
82  QString("Writing Database UUID to local file: %1")
83  .arg(m_uuid));
85  }
86  else if (m_uuid.isEmpty())
87  {
88  LOG(VB_GENERAL, LOG_INFO,
89  QString("Profile UUID found in local file: %1")
90  .arg(fileUUID));
91  m_uuid = fileUUID;
92  }
93 
94  // Get the Public UUID from file
95 
97 }
98 
100 {
101  QString ret;
102 
103  QString hwuuid_file = GetConfDir() + "/HardwareProfile/hw-uuid";
104  QFile file(hwuuid_file);
105  if (file.open( QIODevice::ReadOnly ))
106  {
107  QTextStream stream(&file);
108  ret = stream.readLine();
109  file.close();
110  }
111 
112  return ret;
113 }
114 
116 {
117  QString ret;
118 
119  QString pubuuid_file = GetConfDir() + "/HardwareProfile/uuiddb.cfg";
120  QString pubuuid;
121  QFile pubfile(pubuuid_file);
122  if (pubfile.open( QIODevice::ReadOnly ))
123  {
124  QString s;
125  QTextStream stream(&pubfile);
126  while ( !stream.atEnd() )
127  {
128  s = stream.readLine();
129  if (s.contains(m_uuid))
130  {
131  ret = s.section("=",1,1);
132  ret = ret.trimmed();
133  }
134  }
135  pubfile.close();
136  }
137 
138  return ret;
139 }
140 
142 {
143  QString ret;
144 
145  if (gCoreContext->GetSetting("HardwareProfileUUID").isEmpty())
146  return ret;
147 
148  QString token_file = GetConfDir() + "/HardwareProfile/" + SMOLT_TOKEN;
149  QFile file(token_file);
150  if (file.open( QIODevice::ReadOnly ))
151  {
152  QTextStream stream(&file);
153  ret = stream.readLine();
154  file.close();
155  }
156 
157  return ret;
158 }
159 
161 {
162  QString hwuuid_file = GetConfDir() + "/HardwareProfile/hw-uuid";
163  QFile file(hwuuid_file);
164  if (file.open(QIODevice::WriteOnly))
165  {
166  QTextStream stream(&file);
167  stream << uuid;
168  file.close();
169  return true;
170  }
171  return false;
172 }
173 
175 {
176  if (!m_lastUpdate.isNull() &&
177  (m_lastUpdate.addMonths(1) < MythDate::current()) &&
178  !m_uuid.isEmpty())
179  {
180  LOG(VB_GENERAL, LOG_INFO,
181  "Last hardware profile update was > 30 days ago, update "
182  "required...");
183  return true;
184  }
185 
186  return false;
187 }
188 
189 bool HardwareProfile::SubmitProfile(bool updateTime)
190 {
191  if (m_uuid.isEmpty())
192  return false;
193 
194  if (!m_enabled)
195  Enable();
196 
197  if (!m_hardwareProfile.isEmpty())
198  LOG(VB_GENERAL, LOG_INFO,
199  QString("Submitting the following hardware profile: %1")
200  .arg(m_hardwareProfile));
201 
202  QString cmd = GetShareDir() + "hardwareprofile/sendProfile.py";
203  QStringList args;
204  args << "--submitOnly";
205  args << "-a";
206  MythSystemLegacy system(cmd, args, kMSRunShell | kMSStdOut);
207 
208  system.Run();
209  if (system.Wait() == GENERIC_EXIT_OK)
210  {
211  GenerateUUIDs();
212  gCoreContext->SaveSetting("HardwareProfileUUID", GetPrivateUUID());
213  gCoreContext->SaveSetting("HardwareProfilePublicUUID", GetPublicUUID());
214 
215  if (updateTime)
216  {
217  HardwareProfileTask task;
219  }
220 
221  return true;
222  }
223  return false;
224 }
225 
227 {
228  if (m_uuid.isEmpty())
229  return false;
230 
231  LOG(VB_GENERAL, LOG_INFO,
232  QString("Deleting the following hardware profile: %1")
233  .arg(m_uuid));
234 
235  QString cmd = GetShareDir() + "hardwareprofile/deleteProfile.py";
236  QStringList args;
237  MythSystemLegacy system(cmd, args, kMSRunShell | kMSStdOut);
238 
239  system.Run();
240  if (system.Wait() == GENERIC_EXIT_OK)
241  {
242  gCoreContext->SaveSetting("HardwareProfileUUID", "");
243  gCoreContext->SaveSetting("HardwareProfilePublicUUID", "");
244  Disable();
245  return true;
246  }
247  return false;
248 }
249 
251 {
252  QString ret;
253 
254  if (!gCoreContext->GetSetting("HardwareProfileUUID").isEmpty())
255  {
256  ret = SMOLT_SERVER_LOCATION + "client/show/?uuid=" + m_publicuuid;
257  }
258 
259  return ret;
260 }
261 
263 {
264  QString cmd = GetShareDir() + "hardwareprofile/sendProfile.py";
265  QStringList args;
266  args << "-p";
267  MythSystemLegacy system(cmd, args, kMSRunShell | kMSStdOut);
268 
269  system.Run();
270  system.Wait();
271  return system.ReadAll();
272 }
273 
275 {
276  if (gCoreContext->GetNumSetting("HardwareProfileEnabled", 0) == 0)
277  // global disable, we don't want to run
278  return false;
279 
280  // leave it up to the standard periodic calculation, 30 +-1 days
282 }
283 
285 {
286  HardwareProfile hp;
287  return hp.SubmitProfile(false);
288 }
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:782
void Run(time_t timeout=0)
Runs a command inside the /bin/sh shell. Returns immediately.
bool DoRun(void) override
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:863
QString GetPublicUUID(void) const
allow access to stdout
Definition: mythsystem.h:39
#define GENERIC_EXIT_OK
Exited with no error.
Definition: exitcodes.h:10
QDateTime m_lastUpdate
void SaveSetting(const QString &key, int newValue)
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:125
bool DoCheckRun(QDateTime now) override
QString GetPrivateUUIDFromFile(void) const
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
QDateTime as_utc(const QDateTime &old_dt)
Returns copy of QDateTime with TimeSpec set to UTC.
Definition: mythdate.cpp:23
QString m_hardwareProfile
QString GetConfDir(void)
Definition: mythdirs.cpp:224
QVariant value(int i) const
Definition: mythdbcon.h:198
QString GetAdminPasswordFromFile(void) const
run process through shell
Definition: mythsystem.h:41
QString GetPublicUUIDFromFile(void) const
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:10
QString GetSetting(const QString &key, const QString &defaultval="")
QByteArray & ReadAll()
QString GetShareDir(void)
Definition: mythdirs.cpp:222
static MSqlQueryInfo InitCon(ConnectionReuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:535
void GenerateUUIDs(void)
uint Wait(time_t timeout=0)
const QString SMOLT_TOKEN
bool DoCheckRun(QDateTime now) override
int GetNumSetting(const QString &key, int defaultval=0)
QString GetProfileURL(void) const
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:807
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
QString GetHardwareProfile(void) const
bool SubmitProfile(bool updateTime=true)
QDateTime UpdateLastRun(QDateTime last, bool successful=true) override
bool WritePrivateUUIDToFile(const QString &uuid)
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:603
QString GetPrivateUUID(void) const
bool SaveSettingOnHost(const QString &key, const QString &newValue, const QString &host)
bool NeedsUpdate(void) const
QString GetHostName(void)
bool DeleteProfile(void)
const QString SMOLT_SERVER_LOCATION