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  {
199  LOG(VB_GENERAL, LOG_INFO,
200  QString("Submitting the following hardware profile: %1")
201  .arg(m_hardwareProfile));
202  }
203 
204  QString cmd = GetShareDir() + "hardwareprofile/sendProfile.py";
205  QStringList args;
206  args << "--submitOnly";
207  args << "-a";
208  MythSystemLegacy system(cmd, args, kMSRunShell | kMSStdOut);
209 
210  system.Run();
211  if (system.Wait() == GENERIC_EXIT_OK)
212  {
213  GenerateUUIDs();
214  gCoreContext->SaveSetting("HardwareProfileUUID", GetPrivateUUID());
215  gCoreContext->SaveSetting("HardwareProfilePublicUUID", GetPublicUUID());
216 
217  if (updateTime)
218  {
219  HardwareProfileTask task;
221  }
222 
223  return true;
224  }
225  return false;
226 }
227 
229 {
230  if (m_uuid.isEmpty())
231  return false;
232 
233  LOG(VB_GENERAL, LOG_INFO,
234  QString("Deleting the following hardware profile: %1")
235  .arg(m_uuid));
236 
237  QString cmd = GetShareDir() + "hardwareprofile/deleteProfile.py";
238  QStringList args;
239  MythSystemLegacy system(cmd, args, kMSRunShell | kMSStdOut);
240 
241  system.Run();
242  if (system.Wait() == GENERIC_EXIT_OK)
243  {
244  gCoreContext->SaveSetting("HardwareProfileUUID", "");
245  gCoreContext->SaveSetting("HardwareProfilePublicUUID", "");
246  Disable();
247  return true;
248  }
249  return false;
250 }
251 
253 {
254  QString ret;
255 
256  if (!gCoreContext->GetSetting("HardwareProfileUUID").isEmpty())
257  {
258  ret = SMOLT_SERVER_LOCATION + "client/show/?uuid=" + m_publicuuid;
259  }
260 
261  return ret;
262 }
263 
265 {
266  QString cmd = GetShareDir() + "hardwareprofile/sendProfile.py";
267  QStringList args;
268  args << "-p";
269  MythSystemLegacy system(cmd, args, kMSRunShell | kMSStdOut);
270 
271  system.Run();
272  system.Wait();
273  return system.ReadAll();
274 }
275 
276 bool HardwareProfileTask::DoCheckRun(const QDateTime& now)
277 {
278  if (gCoreContext->GetNumSetting("HardwareProfileEnabled", 0) == 0)
279  // global disable, we don't want to run
280  return false;
281 
282  // leave it up to the standard periodic calculation, 30 +-1 days
284 }
285 
287 {
288  HardwareProfile hp;
289  return hp.SubmitProfile(false);
290 }
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:783
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:864
QString GetPublicUUID(void) const
#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
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
bool DoCheckRun(const QDateTime &now) override
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 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 _reuse=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
run process through shell
Definition: mythsystem.h:41
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:808
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
bool SubmitProfile(bool updateTime=true)
QDateTime UpdateLastRun(const QDateTime &last, bool successful=true) override
static bool WritePrivateUUIDToFile(const QString &uuid)
static QString GetAdminPasswordFromFile(void)
static QString GetPrivateUUIDFromFile(void)
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
static void Disable(void)
QString GetHostName(void)
bool DeleteProfile(void)
const QString SMOLT_SERVER_LOCATION
bool DoCheckRun(const QDateTime &now) override
allow access to stdout
Definition: mythsystem.h:39
static QString GetHardwareProfile(void)