1 #include <QEventLoop>
2 #include <QFile>
3 #include <QFileInfo>
4 #include <QTextStream>
5 #include <QRegExp>
6 #include <QString>
7 #include <QStringList>
8
9 #ifdef __QTKEYCHAIN__
10 #include <qt5keychain/keychain.h>
11 using namespace QKeychain;
12 #endif // __QTKEYCHAIN__
13
14 #include "broadcast/defs_broadcast.h"
15 #include "broadcastprofile.h"
16 #include "defs_urls.h"
17 #include "moc_broadcastprofile.cpp"
18 #include "recording/defs_recording.h"
19 #include "util/compatibility.h"
20 #include "util/logger.h"
21 #include "util/memory.h"
22 #include "util/xml.h"
23
24 namespace {
25 constexpr const char* kDoctype = "broadcastprofile";
26 constexpr const char* kDocumentRoot = "BroadcastProfile";
27 constexpr const char* kSecureCredentials = "SecureCredentialsStorage";
28 constexpr const char* kBitrate = "Bitrate";
29 constexpr const char* kChannels = "Channels";
30 constexpr const char* kCustomArtist = "CustomArtist";
31 constexpr const char* kCustomTitle = "CustomTitle";
32 constexpr const char* kEnableMetadata = "EnableMetadata";
33 constexpr const char* kEnableReconnect = "EnableReconnect";
34 constexpr const char* kEnabled = "Enabled";
35 constexpr const char* kFormat = "Format";
36 constexpr const char* kHost = "Host";
37 constexpr const char* kLimitReconnects = "LimitReconnects";
38 constexpr const char* kLogin = "Login";
39 constexpr const char* kMaximumRetries = "MaximumRetries";
40 constexpr const char* kMetadataCharset = "MetadataCharset";
41 constexpr const char* kMetadataFormat = "MetadataFormat";
42 constexpr const char* kMountPoint = "Mountpoint";
43 constexpr const char* kNoDelayFirstReconnect = "NoDelayFirstReconnect";
44 constexpr const char* kOggDynamicUpdate = "OggDynamicUpdate";
45 constexpr const char* kPassword = "Password";
46 constexpr const char* kPort = "Port";
47 constexpr const char* kProfileName = "ProfileName";
48 constexpr const char* kReconnectFirstDelay = "ReconnectFirstDelay";
49 constexpr const char* kReconnectPeriod = "ReconnectPeriod";
50 constexpr const char* kServertype = "Servertype";
51 constexpr const char* kStreamDesc = "StreamDesc";
52 constexpr const char* kStreamGenre = "StreamGenre";
53 constexpr const char* kStreamName = "StreamName";
54 constexpr const char* kStreamIRC = "StreamIRC";
55 constexpr const char* kStreamAIM = "StreamAIM";
56 constexpr const char* kStreamICQ = "StreamICQ";
57 constexpr const char* kStreamPublic = "StreamPublic";
58 constexpr const char* kStreamWebsite = "StreamWebsite";
59
60 #ifdef __QTKEYCHAIN__
61 constexpr const char* kKeychainPrefix = "Mixxx - ";
62 #endif
63
64 constexpr int kDefaultBitrate = 128;
65 constexpr int kDefaultChannels = 2;
66 constexpr bool kDefaultEnableMetadata = false;
67 constexpr bool kDefaultEnableReconnect = true;
68 constexpr bool kDefaultLimitReconnects = true;
69 constexpr int kDefaultMaximumRetries = 10;
70 // No tr() here, see https://bugs.launchpad.net/mixxx/+bug/1419500
71 const QString kDefaultMetadataFormat("$artist - $title");
72 constexpr bool kDefaultNoDelayFirstReconnect = true;
73 constexpr bool kDefaultOggDynamicupdate = false;
74 constexpr double kDefaultReconnectFirstDelay = 0.0;
75 constexpr double kDefaultReconnectPeriod = 5.0;
76 const QString kDefaultStreamName = QStringLiteral("Mixxx");
77 const QString kDefaultStreamDesc =
78 QObject::tr("This stream is online for testing purposes!");
79 const QString kDefaultStreamGenre = QObject::tr("Live Mix");
80 constexpr bool kDefaultStreamPublic = false;
81
82 const QRegExp kForbiddenChars =
83 QRegExp("[<>:\"\\/|?*\\\\]|(\\.\\.)"
84 "|CON|AUX|PRN|COM(\\d+)|LPT(\\d+)|NUL");
85
86 const mixxx::Logger kLogger("BroadcastProfile");
87 } // anonymous namespace
88
BroadcastProfile(const QString & profileName,QObject * parent)89 BroadcastProfile::BroadcastProfile(const QString& profileName,
90 QObject* parent)
91 : QObject(parent) {
92 adoptDefaultValues();
93
94 // Direct assignment to avoid triggering the
95 // profileNameChanged signal
96 m_profileName = QString(profileName);
97 }
98
validName(const QString & str)99 bool BroadcastProfile::validName(const QString& str) {
100 return !str.contains(kForbiddenChars);
101 }
102
stripForbiddenChars(const QString & str)103 QString BroadcastProfile::stripForbiddenChars(const QString& str) {
104 QString sourceText(str);
105 return sourceText.replace(kForbiddenChars, " ");
106 }
107
loadFromFile(const QString & filename)108 BroadcastProfilePtr BroadcastProfile::loadFromFile(
109 const QString& filename) {
110 QFileInfo xmlFile(filename);
111 if (!xmlFile.exists()) {
112 return BroadcastProfilePtr(nullptr);
113 }
114
115 QString profileFilename = xmlFile.baseName();
116 // The profile filename (without extension) is used to create the instance
117 // but the real profile name (with forbidden chars but suitable for
118 // non-filesystem uses) will be fetched from the XML file and set in the
119 // object during the call to loadValues()
120 BroadcastProfilePtr profile(new BroadcastProfile(profileFilename));
121 profile->loadValues(filename);
122 return profile;
123 }
124
getLastFilename() const125 QString BroadcastProfile::getLastFilename() const {
126 return m_filename;
127 }
128
equals(BroadcastProfilePtr other)129 bool BroadcastProfile::equals(BroadcastProfilePtr other) {
130 return ((getProfileName() == other->getProfileName())
131 && valuesEquals(other));
132 }
133
valuesEquals(BroadcastProfilePtr other)134 bool BroadcastProfile::valuesEquals(BroadcastProfilePtr other) {
135 if (getEnabled() == other->getEnabled()
136 && secureCredentialStorage() == other->secureCredentialStorage()
137 && getHost() == other->getHost()
138 && getPort() == other->getPort()
139 && getServertype() == other->getServertype()
140 && getLogin() == other->getLogin()
141 && getPassword() == other->getPassword()
142 && getEnableReconnect() == other->getEnableReconnect()
143 && getReconnectPeriod() == other->getReconnectPeriod()
144 && getLimitReconnects() == other->getLimitReconnects()
145 && getMaximumRetries() == other->getMaximumRetries()
146 && getNoDelayFirstReconnect() == other->getNoDelayFirstReconnect()
147 && getReconnectFirstDelay() == other->getReconnectFirstDelay()
148 && getFormat() == other->getFormat()
149 && getBitrate() == other->getBitrate()
150 && getChannels() == other->getChannels()
151 && getMountpoint() == other->getMountpoint()
152 && getStreamName() == other->getStreamName()
153 && getStreamDesc() == other->getStreamDesc()
154 && getStreamGenre() == other->getStreamGenre()
155 && getStreamPublic() == other->getStreamPublic()
156 && getStreamWebsite() == other->getStreamWebsite()
157 && getStreamIRC() == other->getStreamIRC()
158 && getStreamAIM() == other->getStreamAIM()
159 && getStreamICQ() == other->getStreamICQ()
160 && getEnableMetadata() == other->getEnableMetadata()
161 && getMetadataCharset() == other->getMetadataCharset()
162 && getCustomArtist() == other->getCustomArtist()
163 && getCustomTitle() == other->getCustomTitle()
164 && getMetadataFormat() == other->getMetadataFormat()
165 && getOggDynamicUpdate() == other->getOggDynamicUpdate()) {
166 return true;
167 }
168
169 return false;
170 }
171
valuesCopy()172 BroadcastProfilePtr BroadcastProfile::valuesCopy() {
173 BroadcastProfilePtr newProfile(
174 new BroadcastProfile(getProfileName()));
175 copyValuesTo(newProfile);
176 return newProfile;
177 }
178
copyValuesTo(BroadcastProfilePtr other)179 void BroadcastProfile::copyValuesTo(BroadcastProfilePtr other) {
180 other->setSecureCredentialStorage(this->secureCredentialStorage());
181
182 other->setHost(this->getHost());
183 other->setPort(this->getPort());
184
185 other->setServertype(this->getServertype());
186 other->setLogin(this->getLogin());
187 other->setPassword(this->getPassword());
188
189 other->setEnableReconnect(this->getEnableReconnect());
190 other->setReconnectPeriod(this->getReconnectPeriod());
191
192 other->setLimitReconnects(this->getLimitReconnects());
193 other->setMaximumRetries(this->getMaximumRetries());
194
195 other->setNoDelayFirstReconnect(this->getNoDelayFirstReconnect());
196 other->setReconnectFirstDelay(this->getReconnectFirstDelay());
197
198 other->setFormat(this->getFormat());
199 other->setBitrate(this->getBitrate());
200 other->setChannels(this->getChannels());
201
202 other->setMountPoint(this->getMountpoint());
203 other->setStreamName(this->getStreamName());
204 other->setStreamDesc(this->getStreamDesc());
205 other->setStreamGenre(this->getStreamGenre());
206 other->setStreamPublic(this->getStreamPublic());
207 other->setStreamWebsite(this->getStreamWebsite());
208 other->setStreamIRC(this->getStreamIRC());
209 other->setStreamAIM(this->getStreamAIM());
210 other->setStreamICQ(this->getStreamICQ());
211
212 other->setEnableMetadata(this->getEnableMetadata());
213 other->setMetadataCharset(this->getMetadataCharset());
214 other->setCustomArtist(this->getCustomArtist());
215 other->setCustomTitle(this->getCustomTitle());
216 other->setMetadataFormat(this->getMetadataFormat());
217 other->setOggDynamicUpdate(this->getOggDynamicUpdate());
218
219 other->setEnabled(this->getEnabled());
220 }
221
adoptDefaultValues()222 void BroadcastProfile::adoptDefaultValues() {
223 m_secureCredentials = false;
224 m_enabled = false;
225
226 m_host = QString();
227 m_port = BROADCAST_DEFAULT_PORT;
228 m_serverType = QString();
229 m_login = QString();
230 m_password = QString();
231
232 m_enableReconnect = kDefaultEnableReconnect;
233 m_reconnectPeriod = kDefaultReconnectPeriod;
234 m_limitReconnects = kDefaultLimitReconnects;
235
236 m_mountpoint = QString();
237 m_streamDesc = kDefaultStreamDesc;
238 m_streamGenre = kDefaultStreamGenre;
239 m_streamName = kDefaultStreamName;
240 m_streamPublic = kDefaultStreamPublic;
241 m_streamWebsite = MIXXX_WEBSITE_URL;
242 m_streamIRC.clear();
243 m_streamAIM.clear();
244 m_streamICQ.clear();
245
246 m_enableMetadata = kDefaultEnableMetadata;
247 m_metadataCharset = QString();
248 m_customArtist = QString();
249 m_customTitle = QString();
250 m_metadataFormat = kDefaultMetadataFormat;
251 m_oggDynamicUpdate = kDefaultOggDynamicupdate;
252
253 m_bitrate = kDefaultBitrate;
254 m_channels = kDefaultChannels;
255 m_format = QString();
256
257 m_noDelayFirstReconnect = kDefaultNoDelayFirstReconnect;
258 m_reconnectFirstDelay = kDefaultReconnectFirstDelay;
259 m_maximumRetries = kDefaultMaximumRetries;
260 }
261
loadValues(const QString & filename)262 bool BroadcastProfile::loadValues(const QString& filename) {
263 QDomElement doc = XmlParse::openXMLFile(filename, kDoctype);
264 if (doc.childNodes().size() < 1) {
265 return false;
266 }
267
268 m_filename = filename;
269
270 #ifdef __QTKEYCHAIN__
271 m_secureCredentials = (bool)XmlParse::selectNodeInt(doc, kSecureCredentials);
272 #else
273 // Secure credentials storage can't be enabled nor disabled from the UI,
274 // so force it to disabled to avoid issues if enabled.
275 m_secureCredentials = false;
276 #endif
277
278 // ProfileName is special because it was not previously saved in the file.
279 // When loading old files, we need to use the file name (set in the
280 // constructor) as the profile name and only load it if present in the
281 // file.
282 QDomNode node = XmlParse::selectNode(doc, kProfileName);
283 if (!node.isNull()) {
284 m_profileName = node.toElement().text();
285 }
286
287 m_enabled = (bool)XmlParse::selectNodeInt(doc, kEnabled);
288
289 m_host = XmlParse::selectNodeQString(doc, kHost);
290 m_port = XmlParse::selectNodeInt(doc, kPort);
291 m_serverType = XmlParse::selectNodeQString(doc, kServertype);
292
293 m_login = XmlParse::selectNodeQString(doc, kLogin);
294 if (m_secureCredentials) {
295 m_password = getSecurePassword(m_login);
296 } else {
297 m_password = XmlParse::selectNodeQString(doc, kPassword);
298 }
299
300 m_enableReconnect =
301 (bool)XmlParse::selectNodeInt(doc, kEnableReconnect);
302 m_reconnectPeriod =
303 XmlParse::selectNodeDouble(doc, kReconnectPeriod);
304
305 m_limitReconnects =
306 (bool)XmlParse::selectNodeInt(doc, kLimitReconnects);
307 m_maximumRetries =
308 XmlParse::selectNodeInt(doc, kMaximumRetries);
309
310 m_noDelayFirstReconnect =
311 (bool)XmlParse::selectNodeInt(doc, kNoDelayFirstReconnect);
312 m_reconnectFirstDelay =
313 XmlParse::selectNodeDouble(doc, kReconnectFirstDelay);
314
315 m_mountpoint = XmlParse::selectNodeQString(doc, kMountPoint);
316 m_streamName = XmlParse::selectNodeQString(doc, kStreamName);
317 m_streamDesc = XmlParse::selectNodeQString(doc, kStreamDesc);
318 m_streamGenre = XmlParse::selectNodeQString(doc, kStreamGenre);
319 m_streamPublic = (bool)XmlParse::selectNodeInt(doc, kStreamPublic);
320 m_streamWebsite = XmlParse::selectNodeQString(doc, kStreamWebsite);
321 m_streamIRC = XmlParse::selectNodeQString(doc, kStreamIRC);
322 m_streamAIM = XmlParse::selectNodeQString(doc, kStreamAIM);
323 m_streamICQ = XmlParse::selectNodeQString(doc, kStreamICQ);
324
325 m_format = XmlParse::selectNodeQString(doc, kFormat);
326 if (m_format == BROADCAST_FORMAT_OV_LEGACY) {
327 // Upgrade to have the same codec name than the recording define.
328 m_format = ENCODING_OGG;
329 }
330 m_bitrate = XmlParse::selectNodeInt(doc, kBitrate);
331 m_channels = XmlParse::selectNodeInt(doc, kChannels);
332
333 m_enableMetadata = (bool)XmlParse::selectNodeInt(doc, kEnableMetadata);
334 m_metadataCharset = XmlParse::selectNodeQString(doc, kMetadataCharset);
335 m_customArtist = XmlParse::selectNodeQString(doc, kCustomArtist);
336 m_customTitle = XmlParse::selectNodeQString(doc, kCustomTitle);
337 m_metadataFormat = XmlParse::selectNodeQString(doc, kMetadataFormat);
338 m_oggDynamicUpdate =
339 (bool)XmlParse::selectNodeInt(doc, kOggDynamicUpdate);
340
341 return true;
342 }
343
save(const QString & filename)344 bool BroadcastProfile::save(const QString& filename) {
345 QDomDocument doc(kDoctype);
346 QDomElement docRoot = doc.createElement(kDocumentRoot);
347
348 XmlParse::addElement(doc, docRoot, kProfileName, m_profileName);
349
350 XmlParse::addElement(doc, docRoot,
351 kSecureCredentials, QString::number((int)m_secureCredentials));
352 XmlParse::addElement(doc, docRoot,
353 kEnabled, QString::number((int)m_enabled));
354
355 XmlParse::addElement(doc, docRoot, kHost, m_host);
356 XmlParse::addElement(doc, docRoot, kPort, QString::number(m_port));
357 XmlParse::addElement(doc, docRoot, kServertype, m_serverType);
358
359 XmlParse::addElement(doc, docRoot, kLogin, m_login);
360 if (m_secureCredentials) {
361 setSecurePassword(m_login, m_password);
362 } else {
363 XmlParse::addElement(doc, docRoot, kPassword, m_password);
364 }
365
366 XmlParse::addElement(doc, docRoot, kEnableReconnect,
367 QString::number((int)m_enableReconnect));
368 XmlParse::addElement(doc, docRoot, kReconnectPeriod,
369 QString::number(m_reconnectPeriod));
370
371 XmlParse::addElement(doc, docRoot, kLimitReconnects,
372 QString::number((int)m_limitReconnects));
373 XmlParse::addElement(doc, docRoot, kMaximumRetries,
374 QString::number(m_maximumRetries));
375
376 XmlParse::addElement(doc, docRoot, kNoDelayFirstReconnect,
377 QString::number((int)m_noDelayFirstReconnect));
378 XmlParse::addElement(doc, docRoot, kReconnectFirstDelay,
379 QString::number(m_reconnectFirstDelay));
380
381 XmlParse::addElement(doc, docRoot, kMountPoint, m_mountpoint);
382 XmlParse::addElement(doc, docRoot, kStreamName, m_streamName);
383 XmlParse::addElement(doc, docRoot, kStreamDesc, m_streamDesc);
384 XmlParse::addElement(doc, docRoot, kStreamGenre, m_streamGenre);
385 XmlParse::addElement(doc, docRoot, kStreamPublic,
386 QString::number((int)m_streamPublic));
387 XmlParse::addElement(doc, docRoot, kStreamWebsite, m_streamWebsite);
388 XmlParse::addElement(doc, docRoot, kStreamIRC, m_streamIRC);
389 XmlParse::addElement(doc, docRoot, kStreamAIM, m_streamAIM);
390 XmlParse::addElement(doc, docRoot, kStreamICQ, m_streamICQ);
391
392 XmlParse::addElement(doc, docRoot, kFormat, m_format);
393 XmlParse::addElement(doc, docRoot, kBitrate,
394 QString::number(m_bitrate));
395 XmlParse::addElement(doc, docRoot, kChannels,
396 QString::number(m_channels));
397
398 XmlParse::addElement(doc, docRoot, kEnableMetadata,
399 QString::number((int)m_enableMetadata));
400 XmlParse::addElement(doc, docRoot, kMetadataCharset, m_metadataCharset);
401 XmlParse::addElement(doc, docRoot, kCustomArtist, m_customArtist);
402 XmlParse::addElement(doc, docRoot, kCustomTitle, m_customTitle);
403 XmlParse::addElement(doc, docRoot, kMetadataFormat, m_metadataFormat);
404 XmlParse::addElement(doc, docRoot, kOggDynamicUpdate,
405 QString::number((int)m_oggDynamicUpdate));
406
407 doc.appendChild(docRoot);
408
409 QFile xmlFile(filename);
410 if (xmlFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
411 m_filename = filename;
412 QTextStream fileStream(&xmlFile);
413 doc.save(fileStream, 4);
414 xmlFile.close();
415
416 return true;
417 }
418 return false;
419 }
420
setProfileName(const QString & profileName)421 void BroadcastProfile::setProfileName(const QString &profileName) {
422 QString oldName(m_profileName);
423 m_profileName = QString(profileName);
424
425 emit profileNameChanged(oldName, m_profileName);
426 }
427
getProfileName() const428 QString BroadcastProfile::getProfileName() const {
429 return m_profileName;
430 }
431
setConnectionStatus(int newState)432 void BroadcastProfile::setConnectionStatus(int newState) {
433 m_connectionStatus = newState;
434 emit connectionStatusChanged(connectionStatus());
435 }
436
connectionStatus()437 int BroadcastProfile::connectionStatus() {
438 return atomicLoadRelaxed(m_connectionStatus);
439 }
440
setSecureCredentialStorage(bool value)441 void BroadcastProfile::setSecureCredentialStorage(bool value) {
442 m_secureCredentials = value;
443 }
444
secureCredentialStorage()445 bool BroadcastProfile::secureCredentialStorage() {
446 return m_secureCredentials;
447 }
448
setSecurePassword(const QString & login,const QString & password)449 bool BroadcastProfile::setSecurePassword(const QString& login, const QString& password) {
450 #ifdef __QTKEYCHAIN__
451 QString serviceName = QString(kKeychainPrefix) + getProfileName();
452
453 WritePasswordJob writeJob(serviceName);
454 writeJob.setAutoDelete(false);
455 writeJob.setKey(login);
456 writeJob.setTextData(password);
457
458 QEventLoop loop;
459 writeJob.connect(&writeJob, &WritePasswordJob::finished, &loop, &QEventLoop::quit);
460 writeJob.start();
461 loop.exec();
462
463 if (writeJob.error() == Error::NoError) {
464 kLogger.debug() << "setSecureValue: write successful";
465 return true;
466 } else {
467 kLogger.warning() << "setSecureValue: write job failed with error:"
468 << writeJob.errorString();
469 errorDialog(tr("Can't use secure password storage: keychain access failed."),
470 writeJob.errorString());
471 return false;
472 }
473 #else
474 Q_UNUSED(login);
475 Q_UNUSED(password);
476 return false;
477 #endif
478 }
479
getSecurePassword(const QString & login)480 QString BroadcastProfile::getSecurePassword(const QString& login) {
481 #ifdef __QTKEYCHAIN__
482 QString serviceName = QString(kKeychainPrefix) + getProfileName();
483
484 ReadPasswordJob readJob(serviceName);
485 readJob.setAutoDelete(false);
486 readJob.setKey(login);
487
488 QEventLoop loop;
489 readJob.connect(&readJob, &ReadPasswordJob::finished, &loop, &QEventLoop::quit);
490 readJob.start();
491 loop.exec();
492
493 if (readJob.error() == Error::NoError) {
494 kLogger.debug() << "getSecureValue: read successful";
495 return readJob.textData();
496 } else {
497 kLogger.warning() << "getSecureValue: read job failed with error:"
498 << readJob.errorString();
499 errorDialog(tr("Secure password retrieval unsuccessful: keychain access failed."),
500 readJob.errorString());
501 }
502 #else
503 Q_UNUSED(login);
504 #endif
505 return QString();
506 }
507
errorDialog(const QString & text,const QString & detailedError)508 void BroadcastProfile::errorDialog(const QString& text, const QString& detailedError) {
509 ErrorDialogProperties* props = ErrorDialogHandler::instance()->newDialogProperties();
510 props->setType(DLG_WARNING);
511 props->setTitle(tr("Settings error"));
512 props->setText(tr("<b>Error with settings for '%1':</b><br>")
513 .arg(getProfileName()) + text);
514 props->setDetails(detailedError);
515 props->setKey(detailedError); // To prevent multiple windows for the same error
516 props->setDefaultButton(QMessageBox::Close);
517 props->setModal(false);
518 ErrorDialogHandler::instance()->requestErrorDialog(props);
519 }
520
relayStatus(bool newStatus)521 void BroadcastProfile::relayStatus(bool newStatus) {
522 setEnabled(newStatus);
523 }
524
525 // Used by BroadcastSettings to relay connection status
526 // to copies in BroadcastSettingsModel
relayConnectionStatus(int newConnectionStatus)527 void BroadcastProfile::relayConnectionStatus(int newConnectionStatus) {
528 setConnectionStatus(newConnectionStatus);
529 }
530
531 // This was useless before, but now comes in handy for multi-broadcasting,
532 // where it means "this connection is enabled and will be started by Mixxx"
getEnabled() const533 bool BroadcastProfile::getEnabled() const {
534 return m_enabled;
535 }
536
setEnabled(bool value)537 void BroadcastProfile::setEnabled(bool value) {
538 m_enabled = value;
539 emit statusChanged(m_enabled);
540 }
541
getHost() const542 QString BroadcastProfile::getHost() const {
543 return m_host;
544 }
545
setHost(const QString & value)546 void BroadcastProfile::setHost(const QString& value) {
547 m_host = QString(value);
548 }
549
getPort() const550 int BroadcastProfile::getPort() const {
551 // Valid port numbers are 0 .. 65535 (16 bit unsigned)
552 if (m_port < 0 || m_port > 0xFFFF) {
553 return BROADCAST_DEFAULT_PORT;
554 }
555
556 return m_port;
557 }
558
setPort(int value)559 void BroadcastProfile::setPort(int value) {
560 m_port = value;
561 }
562
getServertype() const563 QString BroadcastProfile::getServertype() const {
564 return m_serverType;
565 }
566
setServertype(const QString & value)567 void BroadcastProfile::setServertype(const QString& value) {
568 m_serverType = QString(value);
569 }
570
getLogin() const571 QString BroadcastProfile::getLogin() const {
572 return m_login;
573 }
574
setLogin(const QString & value)575 void BroadcastProfile::setLogin(const QString& value) {
576 m_login = QString(value);
577 }
578
579 // TODO(Palakis, June 2nd 2017): implement secure password storage
getPassword() const580 QString BroadcastProfile::getPassword() const {
581 return m_password;
582 }
583
setPassword(const QString & value)584 void BroadcastProfile::setPassword(const QString& value) {
585 m_password = QString(value);
586 }
587
getEnableReconnect() const588 bool BroadcastProfile::getEnableReconnect() const {
589 return m_enableReconnect;
590 }
591
setEnableReconnect(bool value)592 void BroadcastProfile::setEnableReconnect(bool value) {
593 m_enableReconnect = value;
594 }
595
getReconnectPeriod() const596 double BroadcastProfile::getReconnectPeriod() const {
597 return m_reconnectPeriod;
598 }
599
setReconnectPeriod(double value)600 void BroadcastProfile::setReconnectPeriod(double value) {
601 m_reconnectPeriod = value;
602 }
603
getLimitReconnects() const604 bool BroadcastProfile::getLimitReconnects() const {
605 return m_limitReconnects;
606 }
607
setLimitReconnects(bool value)608 void BroadcastProfile::setLimitReconnects(bool value) {
609 m_limitReconnects = value;
610 }
611
getMaximumRetries() const612 int BroadcastProfile::getMaximumRetries() const {
613 return m_maximumRetries;
614 }
615
setMaximumRetries(int value)616 void BroadcastProfile::setMaximumRetries(int value) {
617 m_maximumRetries = value;
618 }
619
getNoDelayFirstReconnect() const620 bool BroadcastProfile::getNoDelayFirstReconnect() const {
621 return m_noDelayFirstReconnect;
622 }
623
setNoDelayFirstReconnect(bool value)624 void BroadcastProfile::setNoDelayFirstReconnect(bool value) {
625 m_noDelayFirstReconnect = value;
626 }
627
getReconnectFirstDelay() const628 double BroadcastProfile::getReconnectFirstDelay() const {
629 return m_reconnectFirstDelay;
630 }
631
setReconnectFirstDelay(double value)632 void BroadcastProfile::setReconnectFirstDelay(double value) {
633 m_reconnectFirstDelay = value;
634 }
635
getMountpoint() const636 QString BroadcastProfile::getMountpoint() const {
637 return m_mountpoint;
638 }
639
setMountPoint(const QString & value)640 void BroadcastProfile::setMountPoint(const QString& value) {
641 m_mountpoint = QString(value);
642 }
643
getStreamName() const644 QString BroadcastProfile::getStreamName() const {
645 return m_streamName;
646 }
647
setStreamName(const QString & value)648 void BroadcastProfile::setStreamName(const QString& value) {
649 m_streamName = QString(value);
650 }
651
getStreamDesc() const652 QString BroadcastProfile::getStreamDesc() const {
653 return m_streamDesc;
654 }
655
setStreamDesc(const QString & value)656 void BroadcastProfile::setStreamDesc(const QString& value) {
657 m_streamDesc = QString(value);
658 }
659
getStreamGenre() const660 QString BroadcastProfile::getStreamGenre() const {
661 return m_streamGenre;
662 }
663
setStreamGenre(const QString & value)664 void BroadcastProfile::setStreamGenre(const QString& value) {
665 m_streamGenre = QString(value);
666 }
667
getStreamPublic() const668 bool BroadcastProfile::getStreamPublic() const {
669 return m_streamPublic;
670 }
671
setStreamPublic(bool value)672 void BroadcastProfile::setStreamPublic(bool value) {
673 m_streamPublic = value;
674 }
675
getStreamWebsite() const676 QString BroadcastProfile::getStreamWebsite() const {
677 return m_streamWebsite;
678 }
679
setStreamWebsite(const QString & value)680 void BroadcastProfile::setStreamWebsite(const QString& value) {
681 m_streamWebsite = QString(value);
682 }
683
getStreamIRC() const684 QString BroadcastProfile::getStreamIRC() const {
685 return m_streamIRC;
686 }
687
setStreamIRC(const QString & value)688 void BroadcastProfile::setStreamIRC(const QString& value) {
689 m_streamIRC = value;
690 }
691
getStreamAIM() const692 QString BroadcastProfile::getStreamAIM() const {
693 return m_streamAIM;
694 }
695
setStreamAIM(const QString & value)696 void BroadcastProfile::setStreamAIM(const QString& value) {
697 m_streamAIM = value;
698 }
699
getStreamICQ() const700 QString BroadcastProfile::getStreamICQ() const {
701 return m_streamICQ;
702 }
703
setStreamICQ(const QString & value)704 void BroadcastProfile::setStreamICQ(const QString& value) {
705 m_streamICQ = value;
706 }
707
getFormat() const708 QString BroadcastProfile::getFormat() const {
709 return m_format;
710 }
711
setFormat(const QString & value)712 void BroadcastProfile::setFormat(const QString& value) {
713 m_format = QString(value);
714 }
715
getBitrate() const716 int BroadcastProfile::getBitrate() const {
717 return m_bitrate;
718 }
719
setBitrate(int value)720 void BroadcastProfile::setBitrate(int value) {
721 m_bitrate = value;
722 }
723
getChannels() const724 int BroadcastProfile::getChannels() const {
725 return m_channels;
726 }
727
setChannels(int value)728 void BroadcastProfile::setChannels(int value) {
729 m_channels = value;
730 }
731
getEnableMetadata() const732 bool BroadcastProfile::getEnableMetadata() const {
733 return m_enableMetadata;
734 }
735
setEnableMetadata(bool value)736 void BroadcastProfile::setEnableMetadata(bool value) {
737 m_enableMetadata = value;
738 }
739
getMetadataCharset() const740 QString BroadcastProfile::getMetadataCharset() const {
741 return m_metadataCharset;
742 }
743
setMetadataCharset(const QString & value)744 void BroadcastProfile::setMetadataCharset(const QString& value) {
745 m_metadataCharset = QString(value);
746 }
747
getCustomArtist() const748 QString BroadcastProfile::getCustomArtist() const {
749 return m_customArtist;
750 }
751
setCustomArtist(const QString & value)752 void BroadcastProfile::setCustomArtist(const QString& value) {
753 m_customArtist = QString(value);
754 }
755
getCustomTitle() const756 QString BroadcastProfile::getCustomTitle() const {
757 return m_customTitle;
758 }
759
setCustomTitle(const QString & value)760 void BroadcastProfile::setCustomTitle(const QString& value) {
761 m_customTitle = QString(value);
762 }
763
getMetadataFormat() const764 QString BroadcastProfile::getMetadataFormat() const {
765 return m_metadataFormat;
766 }
767
setMetadataFormat(const QString & value)768 void BroadcastProfile::setMetadataFormat(const QString& value) {
769 m_metadataFormat = QString(value);
770 }
771
getOggDynamicUpdate() const772 bool BroadcastProfile::getOggDynamicUpdate() const {
773 return m_oggDynamicUpdate;
774 }
775
setOggDynamicUpdate(bool value)776 void BroadcastProfile::setOggDynamicUpdate(bool value) {
777 m_oggDynamicUpdate = value;
778 }
779