玉兔远程控制 0.1.0-bate5
载入中...
搜索中...
未找到
StatsAppUsage.cpp
1// Author: Kang Lin <kl222@126.com>
2
3#include <QStandardPaths>
4#include <QCoreApplication>
5#include <QSettings>
6#include <QLoggingCategory>
7#include <QRegularExpression>
8#include <QRegularExpressionMatch>
9#include "RabbitCommonDir.h"
10#include "RabbitCommonTools.h"
11#include "WorkerFileTransfer.h"
12#include "StatsAppUsage.h"
13
14static Q_LOGGING_CATEGORY(log, "Stats.App")
15CStatsAppUsage::CStatsAppUsage(const QString& szVersion,
16 const QString& szUrl, QObject *parent)
17 : QObject{parent}
18 , m_szVersion(szVersion)
19 , m_szUrl(szUrl)
20 , m_szExt("txt")
21 , m_bRunOneDay(false)
22{
23 qDebug(log) << Q_FUNC_INFO;
24 if(m_szUrl.isEmpty()) {
25 m_szUrl = "https://github.com/KangLin/"
26 + QCoreApplication::applicationName() + "/releases/download";
27 }
28 bool check = connect(&m_Timer, &QTimer::timeout,
29 this, &CStatsAppUsage::slotTimeout);
30 Q_ASSERT(check);
31 check = connect(&m_ThreadPool, &CThreadPool::sigRunning,
32 this, &CStatsAppUsage::Start);
33 Q_ASSERT(check);
34 check = connect(&m_ThreadPool, &CThreadPool::sigFinished,
35 this, &CStatsAppUsage::sigFinished);
36 Q_ASSERT(check);
37 m_ThreadPool.Start(CreateWorkerFileTransfer);
38}
39
40CStatsAppUsage::~CStatsAppUsage()
41{
42 qDebug(log) << Q_FUNC_INFO;
43}
44
45void CStatsAppUsage::SetUrl(const QString &szUrl)
46{
47 m_szUrl = szUrl;
48}
49
50void CStatsAppUsage::SetVersion(const QString &szVersion)
51{
52 m_szVersion = szVersion;
53}
54
55void CStatsAppUsage::Start()
56{
57 Q_ASSERT_X(!m_szUrl.isEmpty(), "Stats.App",
58 "Please call SetUrl() and SetVersion() first");
59 m_tmStart = QDateTime::currentDateTime();
60 Download("Start");
61 StartDay();
62 StartOnce();
63 m_Timer.start(24 * 3600 * 1000);
64}
65
66void CStatsAppUsage::Stop()
67{
68 Download("End");
69 StopDay();
70 StopOnce();
71 m_Timer.stop();
72 m_ThreadPool.Stop();
73}
74
75void CStatsAppUsage::slotTimeout()
76{
77 RunOneDay();
78}
79
84{
85 QSettings set(RabbitCommon::CDir::Instance()->GetFileUserConfigure(),
86 QSettings::IniFormat);
87 bool bOnce = set.value("Stats/App/Start/Once", false).toBool();
88 if(bOnce)
89 return;
90 Download("StartOnce");
91 set.setValue("Stats/App/Start/Once", true);
92}
93
94void CStatsAppUsage::StopOnce()
95{
96 QSettings set(RabbitCommon::CDir::Instance()->GetFileUserConfigure(),
97 QSettings::IniFormat);
98 bool bOnce = set.value("Stats/App/End/Once", false).toBool();
99 if(bOnce)
100 return;
101 Download("EndOnce");
102 set.setValue("Stats/App/End/Once", true);
103}
104
109{
110 QSettings set(RabbitCommon::CDir::Instance()->GetFileUserConfigure(),
111 QSettings::IniFormat);
112 QDateTime tm = set.value("Stats/App/Start/Day").toDateTime();
113 qDebug(log) << "daysTo:" << tm.daysTo(QDateTime::currentDateTime())
114 << tm.isValid() << tm.isNull() << tm;
115 if(tm.isValid() && !tm.isNull()
116 && tm.daysTo(QDateTime::currentDateTime()) < 1)
117 return;
118 Download("StartDay");
119 set.setValue("Stats/App/Start/Day", QDateTime::currentDateTime());
120}
121
122void CStatsAppUsage::StopDay()
123{
124 QSettings set(RabbitCommon::CDir::Instance()->GetFileUserConfigure(),
125 QSettings::IniFormat);
126 QDateTime tm = set.value("Stats/App/End/Day").toDateTime();
127 qDebug(log) << "daysTo:" << tm.daysTo(QDateTime::currentDateTime())
128 << tm.isValid() << tm.isNull() << tm;
129 if(tm.isValid() && !tm.isNull()
130 && tm.daysTo(QDateTime::currentDateTime()) < 1)
131 return;
132 Download("EndDay");
133 set.setValue("Stats/App/End/Day", QDateTime::currentDateTime());
134}
135
140{
141 qDebug(log) << "secsTo:" << m_tmStart.secsTo(QDateTime::currentDateTime());
142 if(m_tmStart.secsTo(QDateTime::currentDateTime()) >= 24 * 3600
143 && !m_bRunOneDay) {
144 m_bRunOneDay = true;
145 Download("RunOneDay");
146 }
147}
148
149void CStatsAppUsage::Download(const QString &szFile)
150{
151 QString file = "Stats" + szFile;
152 if(m_szUrl.isEmpty()) return;
153 QString szUrl = m_szUrl + "/";
154 QString szVersion = m_szVersion;
155 if(!szVersion.isEmpty()) {
156 if(RabbitCommon::CTools::VersionValid(szVersion)) {
157 auto map = RabbitCommon::CTools::GetVersion(szVersion);
158 if(!map.value("PreRelease").isEmpty()
159 || !map.value("Build").isEmpty()) {
160 file += "Dev";
161 static QRegularExpression regex("[-|+]");
162 szVersion = szVersion.left(szVersion.indexOf(regex));
163 qDebug(log) << "Version:" << szVersion;
164 }
165 } else
166 szVersion = QString();
167 if(!szVersion.isEmpty())
168 szUrl += szVersion + "/";
169 }
170
171 szUrl += file;
172 if(!m_szExt.isEmpty())
173 szUrl += "." + m_szExt;
174 qDebug(log) << Q_FUNC_INFO << szUrl;
175
176 // Download
177 CWorkerFileTransfer* pWorker =
178 qobject_cast<CWorkerFileTransfer*>(m_ThreadPool.ChooseWorker());
179 if(pWorker) {
180 QUrl url(szUrl);
181 QString szDownload;
182 if(!url.fileName().isEmpty()) {
183 szDownload = QStandardPaths::writableLocation(
184 QStandardPaths::TempLocation);
185 if(szDownload.right(1) != "/" && szDownload.right(1) != "\\")
186 szDownload += QDir::separator();
187 szDownload += QString("Rabbit") + QDir::separator()
188 + QCoreApplication::applicationName()
189 + QDir::separator();
190 szDownload += url.fileName();
191 }
192 CTaskFileTransfer* task = new CTaskFileTransfer(szUrl, szDownload);
193 bool check = connect(task, &CTaskFileTransfer::sigFinished,
194 this, [task, pWorker]() {
195 qDebug(log) << "Download finished:" << task->Title();
196 task->deleteLater();
197 });
198 check = connect(task, &CTaskFileTransfer::sigError,
199 this, [task, pWorker](int nErr, const QString& szError){
200 qDebug(log) << "Download fail:" << nErr << szError << task->Title();
201 });
202 pWorker->AddTask(task);
203 }
204}
void RunOneDay()
运行超过一天的计为一次
void StartDay()
程序每天所有启动计为一次
void StartOnce()
程序安装后,同一用户所有启动计为一次
void SetVersion(const QString &szVersion)
Semantic Versioning: https://semver.org/