• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

MerginMaps / input / 6274148729

22 Sep 2023 12:18PM UTC coverage: 61.904% (-0.1%) from 62.05%
6274148729

Pull #2797

github

PeterPetrik
fix code
Pull Request #2797: Profiler

7577 of 12240 relevant lines covered (61.9%)

102.31 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

35.0
/app/inputhelp.cpp
1
/***************************************************************************
2
 *                                                                         *
3
 *   This program is free software; you can redistribute it and/or modify  *
4
 *   it under the terms of the GNU General Public License as published by  *
5
 *   the Free Software Foundation; either version 2 of the License, or     *
6
 *   (at your option) any later version.                                   *
7
 *                                                                         *
8
 ***************************************************************************/
9

10
#include "inputhelp.h"
11
#include "merginuserauth.h"
12
#include "merginuserinfo.h"
13
#include "merginsubscriptioninfo.h"
14
#include "merginsubscriptionstatus.h"
15
#include "merginapi.h"
16
#include "inpututils.h"
17
#include "coreutils.h"
18

19
#include "inpututils.h"
20

21
#include <QNetworkReply>
22
#include <QSysInfo>
23

24
const QString helpRoot = QStringLiteral( "https://merginmaps.com/docs" );
25
const QString reportLogUrl = QStringLiteral( "https://g4pfq226j0.execute-api.eu-west-1.amazonaws.com/mergin_client_log_submit" );
26
const QString helpDeskMail = QStringLiteral( "support@merginmaps.com" );
27
const QString inputWeb = QStringLiteral( "https://merginmaps.com" );
28

29
const QString utmTagHelp = QStringLiteral( "?utm_source=input-help&utm_medium=help&utm_campaign=input" );
30
const QString utmTagSubscription = QStringLiteral( "?utm_source=input-subs&utm_medium=subs&utm_campaign=input" );
31
const QString utmTagOther = QStringLiteral( "?utm_source=input-other&utm_medium=other&utm_campaign=input" );
32
const QString utmTagAttention = QStringLiteral( "?utm_source=input-app&utm_medium=attention-required" );
33

34

35
InputHelp::InputHelp( MerginApi *merginApi, InputUtils *utils ):
18✔
36
  mMerginApi( merginApi ),
18✔
37
  mInputUtils( utils )
18✔
38
{
39
  connect( mMerginApi, &MerginApi::apiRootChanged, this, &InputHelp::merginLinkChanged );
18✔
40

41
  emit linkChanged();
18✔
42
}
18✔
43

44
QString InputHelp::helpRootLink() const
1✔
45
{
46
  return helpRoot + "/" + utmTagHelp;
2✔
47
}
48

49
QString InputHelp::inputWebLink() const
1✔
50
{
51
  return inputWeb + "/" +  utmTagOther;
2✔
52
}
53

54
QString InputHelp::merginWebLink() const
1✔
55
{
56
  if ( mMerginApi && mMerginApi->apiRoot() != MerginApi::defaultApiRoot() )
1✔
57
  {
58
    return mMerginApi->apiRoot(); // UTM tags are included only for production server
×
59
  }
60

61
  return MerginApi::defaultApiRoot() + utmTagOther;
2✔
62
}
63

64
QString InputHelp::merginDashboardLink() const
1✔
65
{
66
  if ( mMerginApi && mMerginApi->apiRoot() != MerginApi::defaultApiRoot() )
1✔
67
  {
68
    return mMerginApi->apiRoot() + "dashboard";  // UTM tags are included only for production server
×
69
  }
70

71
  return MerginApi::defaultApiRoot() + "dashboard" + utmTagAttention;
2✔
72
}
73

74
QString InputHelp::privacyPolicyLink() const
1✔
75
{
76
  return helpRoot + "/misc/privacy/" + utmTagOther;
2✔
77
}
78

79
QString InputHelp::merginSubscriptionDetailsLink() const
1✔
80
{
81
  return helpRoot + "/setup/subscriptions/" + utmTagSubscription;
2✔
82
}
83

84
QString InputHelp::howToEnableDigitizingLink() const
1✔
85
{
86
  return helpRoot + "/gis/enable_digitising/" + utmTagHelp;
2✔
87
}
88

89
QString InputHelp::howToEnableBrowsingDataLink() const
1✔
90
{
91
  return helpRoot + "/gis/enable_browsing/" + utmTagHelp;
2✔
92
}
93

94
QString InputHelp::howToSetupThemesLink() const
1✔
95
{
96
  return helpRoot + "/gis/setup_themes/" + utmTagHelp;
2✔
97
}
98

99
QString InputHelp::howToCreateNewProjectLink() const
1✔
100
{
101
  return helpRoot + "/manage/create-project/" + utmTagHelp;
2✔
102
}
103

104
QString InputHelp::howToDownloadProjectLink() const
1✔
105
{
106
  return helpRoot + "/manage/data_sync/" + utmTagHelp;
2✔
107
}
108

109
QString InputHelp::howToSetupProj() const
1✔
110
{
111
  return helpRoot + "/gis/proj/" + utmTagHelp;
2✔
112
}
113

114
QString InputHelp::gpsAccuracyHelpLink() const
1✔
115
{
116
  return helpRoot + "/field/gps_accuracy/" + utmTagHelp;
2✔
117
}
118

119
QString InputHelp::howToConnectGPSLink() const
1✔
120
{
121
  return helpRoot + "/field/external_gps/" + utmTagHelp;
2✔
122
}
123

124
QString InputHelp::merginTermsLink() const
1✔
125
{
126
  return MerginApi::marketingPageRoot() + "terms-of-service" + utmTagOther;
2✔
127
}
128

129
QString InputHelp::projectLoadingErrorHelpLink() const
1✔
130
{
131
  return helpRoot + "/field/broken-project/" + utmTagHelp;
2✔
132
}
133

134
QString InputHelp::whatsNewPostLink() const
1✔
135
{
136
  return inputWeb + "/blog/introducing-workspaces-simplified-collaboration" + utmTagOther;
2✔
137
}
138

139
bool InputHelp::submitReportPending() const
×
140
{
141
  return mSubmitReportPending;
×
142
}
143

144
QString InputHelp::fullLog( bool isHtml )
×
145
{
146
  qint64 limit = 500000;
×
147
  QVector<QString> retLines = logHeader( isHtml );
×
148

149
  QFile file( CoreUtils::logFilename() );
×
150
  if ( file.open( QIODevice::ReadOnly ) )
×
151
  {
152
    qint64 fileSize = file.size();
×
153
    if ( fileSize > limit )
×
154
      file.seek( file.size() - limit );
×
155

156
    QString line = file.readLine();
×
157
    while ( !line.isNull() )
×
158
    {
159
      retLines.push_back( line );
×
160
      line = file.readLine();
×
161
    }
162

163
    file.close();
×
164
  }
×
165
  else
166
  {
167
    retLines.push_back( QString( "Unable to open log file %1" ).arg( CoreUtils::logFilename() ) );
×
168
  }
169

170
  QString ret;
×
171
  int i = 0;
×
172
  for ( const QString &str : retLines )
×
173
  {
174
    ++i;
×
175
    if ( isHtml )
×
176
      ret += QStringLiteral( "<p class=\"%1\">" ).arg( i % 2 == 0 ? "odd" : "even" ) + str.trimmed() + "</p>";
×
177
    else
178
      ret += str.trimmed() + "\n";
×
179
  }
180

181
  return ret;
×
182
}
×
183

184
QVector<QString> InputHelp::logHeader( bool isHtml )
×
185
{
186
  QVector<QString> retLines;
×
187
  retLines.push_back( QStringLiteral( "Input App: %1 - %2 (%3)" ).arg( CoreUtils::appVersion() ).arg( InputUtils::appPlatform() ).arg( CoreUtils::appVersionCode() ) );
×
188
  retLines.push_back( QStringLiteral( "System: %1" ).arg( QSysInfo::prettyProductName() ) );
×
189
  retLines.push_back( QStringLiteral( "Mergin URL: %1" ).arg( mMerginApi->apiRoot() ) );
×
190
  retLines.push_back( QStringLiteral( "Mergin User: %1" ).arg( mMerginApi->userAuth()->username() ) );
×
191
  if ( !mMerginApi->userInfo()->email().isEmpty() )
×
192
  {
193
    retLines.push_back( QStringLiteral( "Mergin Data: %1/%2 Bytes" )
×
194
                        .arg( InputUtils::bytesToHumanSize( mMerginApi->workspaceInfo()->diskUsage() ) )
×
195
                        .arg( InputUtils::bytesToHumanSize( mMerginApi->workspaceInfo()->storageLimit() ) ) );
×
196
    retLines.push_back( QStringLiteral( "Subscription plan: %1" ).arg( mMerginApi->subscriptionInfo()->planAlias() ) );
×
197
    retLines.push_back( QStringLiteral( "Subscription Status: %1" ).arg( MerginSubscriptionStatus::toString( static_cast<MerginSubscriptionStatus::SubscriptionStatus>( mMerginApi->subscriptionInfo()->subscriptionStatus() ) ) ) );
×
198
  }
199
  else
200
  {
201
    retLines.push_back( QStringLiteral( "%1Mergin User Profile not available. To include it, open you Profile Page in InputApp%2" ).arg( isHtml ? "<b>" : "" ).arg( isHtml ? "</b>" : "" ) );
×
202
  }
203
  retLines.push_back( QStringLiteral( "------------------------------------------" ) );
×
204
  retLines.push_back( QStringLiteral( "Screen Info:" ) );
×
205
  retLines.append( InputUtils().dumpScreenInfo().split( "\n" ).toVector() );
×
206
  retLines.push_back( QStringLiteral( "------------------------------------------" ) );
×
207
  retLines.push_back( QStringLiteral( "Profiler Data:" ) );
×
208
  retLines.append( InputUtils().qgisProfilerLog() );
×
209
  retLines.push_back( QStringLiteral( "------------------------------------------" ) );
×
210

211
  return retLines;
×
212
}
×
213

214

215
void InputHelp::submitReport()
×
216
{
217
  // There is a limit of 1MB on the remote service, send less, let say half of that
218
  QString log = fullLog( false );
×
219
  QByteArray logArr = log.toUtf8();
×
220
  QString app = QStringLiteral( "input-%1-%2" ).arg( InputUtils::appPlatform() ).arg( CoreUtils::appVersion() );
×
221
  QString username = mMerginApi->userAuth()->username().toHtmlEscaped();
×
222
  if ( username.isEmpty() )
×
223
    username = "unknown";
×
224
  QString params = QStringLiteral( "?app=%1&username=%2" ).arg( app ).arg( username );
×
225
  QNetworkRequest req( reportLogUrl + params );
×
226
  req.setRawHeader( "User-Agent", "InputApp" );
×
227
  req.setRawHeader( "Content-Type", "text/plain" );
×
228
  QNetworkReply *reply = mManager.post( req, logArr );
×
229
  qDebug() << "Report to " << reportLogUrl;
×
230

231
  mSubmitReportPending = true;
×
232
  emit submitReportPendingChanged();
×
233
  connect( reply, &QNetworkReply::finished, this, &InputHelp::onSubmitReportReplyFinished );
×
234
}
×
235

236
void InputHelp::onSubmitReportReplyFinished()
×
237
{
238
  mSubmitReportPending = false;
×
239
  emit submitReportPendingChanged();
×
240

241
  QNetworkReply *r = qobject_cast<QNetworkReply *>( sender() );
×
242
  Q_ASSERT( r );
×
243

244
  if ( r->error() == QNetworkReply::NoError )
×
245
  {
246
    CoreUtils::log( "submit report", "Report submitted!" );
×
247
    emit mInputUtils->showNotification( tr( "Report submitted.%1Please contact us on%1%2" ).arg( "<br />" ).arg( helpDeskMail ) );
×
248
  }
249
  else
250
  {
251
    CoreUtils::log( "submit report", QStringLiteral( "FAILED - %1" ).arg( r->errorString() ) );
×
252
    emit mInputUtils->showNotification( tr( "Failed to submit report.%1Please check your internet connection." ).arg( "<br>" ) );
×
253
  }
254
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc