00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "ripping.h"
00022 #include "settings_general.h"
00023 #define AND &&
00024 #define OR ||
00025 #define NOT !
00026 #define EQUAL ==
00027
00028 #include <KGlobal>
00029 #include <KLocale>
00030 #include <QFileInfo>
00031 #include "versionnumber.h"
00032
00033 ripping::ripping(const QPointer<QObject> parent) : streamripper_base(parent)
00034 {
00035 internal_splitBehavior = QString::SkipEmptyParts;
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 resetStreamripperProperties();
00057
00058
00059
00060
00061 QObject::connect(&m_process,
00062 SIGNAL(stateChanged(QProcess::ProcessState)),
00063 this,
00064 SLOT(streamripperStateChange(QProcess::ProcessState)));
00065 QObject::connect(&m_process,
00066 SIGNAL(error(QProcess::ProcessError)),
00067 this,
00068 SLOT(errorOccured(QProcess::ProcessError)));
00069 }
00070
00071 ripping::~ripping()
00072 {
00073 }
00074
00075 void ripping::resetStreamripperProperties()
00076 {
00077 setBitrate(default_value_of_bitrate());
00078 setDataSize(default_value_of_dataSize());
00079 setError(default_value_of_error());
00080 setMetaInterval(default_value_of_metaInterval());
00081 setRelayPort(default_value_of_relayPort());
00082 setServerName(default_value_of_serverName());
00083 setSong(default_value_of_song());
00084 setStatus(default_value_of_status());
00085 setStreamName(default_value_of_streamName());
00086 }
00087
00088 void ripping::interpretate_console_output(QStringList & stringList)
00089 {
00090
00091 QString my_line;
00092
00093
00094 bool statusSet=false;
00095 bool relayPortSet=false;
00096 bool streamNameSet=false;
00097 bool serverNameSet=false;
00098 bool bitrateSet=false;
00099 bool metaIntervalSet=false;
00100 bool errorSet=false;
00101
00102 QString help_string;
00103 bool okay;
00104 qint64 helper_qint64;
00105
00106
00107
00108 while (!stringList.isEmpty()) {
00109 my_line = stringList.takeLast();
00110
00111
00112
00113
00114 if (my_line.toLower().startsWith(QString("[ripping... ] "))) {
00115 if (!statusSet) {
00116 setStatus(is_ripping);
00117
00118 my_line = my_line.remove(0, 17);
00119 helper_interpretate_metainfo_and_datasize(my_line);
00120 statusSet = true;
00121 };
00122 }
00123 else if (my_line.toLower().startsWith(QString("[buffering - | ] "))) {
00124 if (!statusSet) {
00125 setStatus(is_buffering);
00126
00127 my_line = my_line.remove(0, 17);
00128 helper_interpretate_metainfo_and_datasize(my_line);
00129 statusSet = true;
00130 };
00131 }
00132 else if (my_line.toLower().startsWith(QString("[skipping... ] "))) {
00133 if (!statusSet) {
00134 setStatus(is_skipping);
00135
00136 my_line = my_line.remove(0, 17);
00137 helper_interpretate_metainfo_and_datasize(my_line);
00138 statusSet = true;
00139 };
00140 }
00141 else if (my_line.toLower().startsWith(QString("connecting")) ||
00142 my_line.toLower().startsWith(QString("[getting track name"))) {
00143 if (!statusSet) {
00144 setStatus(is_connecting);
00145 setSong(default_value_of_song());
00146 setDataSize(default_value_of_dataSize());
00147 statusSet = true;
00148 };
00149 }
00150 else if (my_line.toLower().startsWith(QString("shutting down")) ||
00151 my_line.toLower().startsWith(QString("bye.."))) {
00152 if (!statusSet) {
00153 setStatus(is_saving);
00154 setSong(default_value_of_song());
00155 setDataSize(default_value_of_dataSize());
00156 statusSet = true;
00157 };
00158 }
00159 else if (my_line.toLower().startsWith(QString("relay port: "))) {
00160 if (!relayPortSet) {
00161 helper_qint64 = my_line.right(my_line.size()-12).toLongLong(&okay);
00162 if (NOT okay) {
00163 setRelayPort(-1);
00164 } else {
00165 setRelayPort(helper_qint64);
00166 };
00167 relayPortSet = true;
00168 };
00169 }
00170 else if (my_line.toLower().startsWith(QString("stream: "))) {
00171 if (!streamNameSet) {
00172 setStreamName(my_line.right(my_line.size()-8));
00173 streamNameSet = true;
00174 };
00175 }
00176 else if (my_line.toLower().startsWith(QString("server name: "))) {
00177 if (!serverNameSet) {
00178 setServerName(my_line.right(my_line.size()-13));
00179 serverNameSet = true;
00180 };
00181 }
00182 else if (my_line.toLower().startsWith(QString("bitrate: "))) {
00183 if (!bitrateSet) {
00184 helper_qint64 = my_line.right(my_line.size()-9).toLongLong(&okay);
00185 if (NOT okay) {
00186 setBitrate(-1);
00187 } else {
00188 setBitrate(helper_qint64);
00189 };
00190 bitrateSet = true;
00191 };
00192 }
00193 else if (my_line.toLower().startsWith(QString("declared bitrate: "))) {
00194 if (!bitrateSet) {
00195 helper_qint64 = my_line.right(my_line.size()-18).toLongLong(&okay);
00196 if (NOT okay) {
00197 setBitrate(-1);
00198 } else {
00199 setBitrate(helper_qint64);
00200 };
00201 bitrateSet = true;
00202 };
00203 }
00204 else if (my_line.toLower().startsWith(QString("meta interval: "))) {
00205 if (!metaIntervalSet) {
00206 helper_qint64 = my_line.right(my_line.size()-15).toLongLong(&okay);
00207 if (NOT okay) {
00208 setMetaInterval(-1);
00209 } else {
00210 setMetaInterval(helper_qint64);
00211 };
00212 metaIntervalSet = true;
00213 }
00214 }
00215 else if (my_line.toLower().startsWith(QString("error -"))) {
00216 if (!errorSet) {
00217 setError(my_line);
00218 errorSet = true;
00219 };
00220 } else {
00221 kDebug()
00222 << "Konnte folgenden String nicht erkennen:"
00223 << my_line
00224 << "size:"
00225 << my_line.size();
00226 };
00227 };
00228 }
00229
00230 void ripping::helper_interpretate_metainfo_and_datasize(QString my_line)
00231
00232 {
00233
00234 QString help_string;
00235 bool okay;
00236 qint64 dataSize;
00237
00238
00239 help_string = my_line.section('[', -1);
00240
00241
00242
00243 my_line.truncate(my_line.size() - help_string.size() - 2);
00244
00245
00246
00247
00248
00249 setSong(my_line);
00250
00251
00252
00253 help_string=help_string.remove(']').simplified().toUpper();
00254 if (help_string.endsWith(QString("KB")) OR help_string.endsWith('K')) {
00255 if (help_string.endsWith(QString("KB"))) {
00256 help_string.truncate(help_string.size() - 2);
00257 } else {
00258 help_string.truncate(help_string.size() - 1);
00259 };
00260 dataSize = help_string.toLongLong(&okay) * 1024;
00261 } else {
00262 if (help_string.endsWith(QString("MB")) OR help_string.endsWith('M')) {
00263 if (help_string.endsWith(QString("MB"))) {
00264 help_string.truncate(help_string.size() - 2);
00265 } else {
00266 help_string.truncate(help_string.size() - 1);
00267 };
00268 dataSize = help_string.toDouble(&okay) * 1024 * 1024;
00269 } else {
00270 if (help_string.endsWith('B')) {
00271
00272 help_string.truncate(help_string.size() - 1);
00273 dataSize = help_string.toLongLong(&okay);
00274 } else {
00275 okay = false;
00276 };
00277 };
00278 };
00279 if (NOT okay) {
00280 setDataSize(-1);
00281 } else {
00282 setDataSize(dataSize);
00283 };
00284 }
00285
00286 PropertyValue ripping::streamName() const
00287 {
00288 return internal_streamName;
00289 }
00290
00291 PropertyValue ripping::formatedStreamName(const QString theStreamName)
00292 {
00293
00294 PropertyValue temp_streamName;
00295
00296 temp_streamName.internalValue = theStreamName;
00297 if (theStreamName == "Streamripper_rips") {
00298 temp_streamName.formatedValue = theStreamName;
00299 temp_streamName.type = PropertyValue::error;
00300 temp_streamName.toolTip = i18nc(
00301 "@info:tooltip Leave Streamripper_rips unchanged, it is a generic name of a directory",
00302 "Nameless stream. Using <emphasis>Streamripper_rips</emphasis> as replacement.");
00303 temp_streamName.whatsThis = i18nc(
00304 "@info:whatsthis Leave Streamripper_rips unchanged, it is a generic name of a directory",
00305 "This stream does not send a name in his meta data. "
00306 "<emphasis>Streamripper_rips</emphasis> is used as replacement, and "
00307 "you find the recorded files in the directory of the same name.");
00308 } else {
00309 if (theStreamName.isEmpty()) {
00310 temp_streamName.formatedValue = i18nc("@item", "not recognized");
00311 temp_streamName.type = PropertyValue::unset;
00312 temp_streamName.toolTip = i18nc(
00313 "@info:tooltip",
00314 "Could not connect to server.");
00315 temp_streamName.whatsThis = i18nc(
00316 "@info:whatsthis",
00317 "Could not connect to the specified server. So the stream name could not be recognized.");
00318 } else {
00319 temp_streamName.formatedValue = theStreamName;
00320 temp_streamName.type = PropertyValue::value;
00321 };
00322 };
00323
00324 return temp_streamName;
00325 }
00326
00327 void ripping::setStreamName(const QString newStreamName)
00328 {
00329 if (internal_streamName.internalValue.toString() != newStreamName) {
00330 internal_streamName = formatedStreamName(newStreamName);
00331 emit streamNameChanged(index(), internal_streamName);
00332 };
00333 }
00334
00335 QString ripping::default_value_of_streamName()
00336 {
00337 return QString();
00338 }
00339
00340 PropertyValue ripping::formatedServerName(const QString theServerName)
00341 {
00342
00343 PropertyValue temp_serverName;
00344
00345
00346 temp_serverName.internalValue = theServerName;
00347 temp_serverName.formatedValue = theServerName;
00348 if (theServerName.isEmpty()) {
00349 temp_serverName.type = PropertyValue::unset;
00350 } else {
00351 temp_serverName.type = PropertyValue::value;
00352 };
00353
00354
00355 return temp_serverName;
00356 }
00357
00358 PropertyValue ripping::serverName() const
00359 {
00360 return internal_serverName;
00361 }
00362
00363 void ripping::setServerName(const QString newServerName)
00364 {
00365 if (internal_serverName.internalValue.toString() != newServerName) {
00366 internal_serverName = formatedServerName(newServerName);
00367 emit serverNameChanged(index(), internal_serverName);
00368 };
00369 }
00370
00371 QString ripping::default_value_of_serverName()
00372 {
00373 return QString();
00374 }
00375
00376 PropertyValue ripping::status() const
00377 {
00378 return internal_status;
00379 }
00380
00381 PropertyValue ripping::formatedStatus(const statusType theStatus)
00382 {
00383
00384 PropertyValue temp_status;
00385
00386
00387 temp_status.internalValue.setValue(theStatus);
00388 if (theStatus == idle) {
00389 temp_status.type = PropertyValue::unset;
00390 } else {
00391 temp_status.type = PropertyValue::value;
00392 };
00393 switch (theStatus) {
00394 case idle:
00395 temp_status.formatedValue.clear();
00396 temp_status.toolTip.clear();
00397 temp_status.whatsThis.clear();
00398 break;
00399 case is_starting:
00400 temp_status.formatedValue = i18nc("@item status of streamripper", "Starting...");
00401 temp_status.toolTip = i18nc("@info:tooltip", "Invocing Streamripper...");
00402 temp_status.whatsThis = i18nc(
00403 "@info:whatsthis",
00404 "KRadioRipper is invocing Streamripper, the program used to "
00405 "perform the recording process.");
00406 break;
00407 case is_connecting:
00408 temp_status.formatedValue = i18nc("@item status of Streamripper", "Connecting...");
00409 temp_status.toolTip = i18nc("@info:tooltip", "Connecting with the stream server...");
00410 temp_status.whatsThis = i18nc("@info:whatsthis",
00411 "Streamripper is connecting with the stream server.");
00412 break;
00413 case is_buffering:
00414 temp_status.formatedValue = i18nc("@item status of Streamripper", "Buffering...");
00415 temp_status.toolTip = i18nc("@info:tooltip", "Buffering stream data...");
00416 temp_status.whatsThis = i18nc(
00417 "@info:whatsthis",
00418 "Stream data is buffered before starting the recording process.");
00419 break;
00420 case is_skipping:
00421 temp_status.formatedValue = i18nc("@item status of Streamripper", "Skipping...");
00422 temp_status.toolTip = i18nc("@info:tooltip", "Skipping the actual track...");
00423 temp_status.whatsThis = i18nc(
00424 "@info:whatsthis",
00425 "<para>KRadioRipper skips by default the first track, because this track will lack "
00426 "the begin.</para><para>You can change this behavior by editing the settings of the "
00427 "stream.</para>");
00428 break;
00429 case is_ripping:
00430 temp_status.formatedValue = i18nc("@item status of Streamripper", "Recording...");
00431 temp_status.toolTip = i18nc("@info:tooltip", "Recording the stream...");
00432 temp_status.whatsThis = i18nc("@info:whatsthis", "KRadioRipper is recording the stream.");
00433 break;
00434 case is_saving:
00435 temp_status.formatedValue = i18nc("@item status of Streamripper", "Saving...");
00436 temp_status.toolTip = i18nc("@info:tooltip", "Saving files...");
00437 temp_status.whatsThis = i18nc(
00438 "@info:whatsthis",
00439 "The buffer is processed and the last files are saved.");
00440 break;
00441 };
00442
00443 return temp_status;
00444 }
00445
00446 void ripping::setStatus(const statusType newStatus)
00447 {
00448 if (internal_status.internalValue.value<statusType>() != newStatus) {
00449 internal_status = formatedStatus(newStatus);
00450 emit statusChanged(index(), internal_status);
00451 };
00452
00453 bool newIsRunning = (newStatus != idle);
00454 if (internal_isRunning != newIsRunning) {
00455 internal_isRunning = newIsRunning;
00456 if (newIsRunning) {
00457 emit running();
00458 } else {
00459 emit not_running();
00460 };
00461 };
00462 }
00463
00464 ripping::statusType ripping::default_value_of_status()
00465 {
00466 return idle;
00467 }
00468
00469 PropertyValue ripping::error() const
00470 {
00471 return internal_error;
00472 }
00473
00474 PropertyValue ripping::formatedError(const QString theError)
00475 {
00476
00477 PropertyValue temp_error;
00478 QString streamripper_error_number;
00479
00480
00481 temp_error.internalValue = theError;
00482
00483 if (theError.isEmpty()) {
00484 temp_error.type = PropertyValue::unset;
00485 } else {
00486 temp_error.type = PropertyValue::value;
00487 };
00488
00489 if (theError.startsWith(QString("error -"))) {
00490 streamripper_error_number = theError.right(theError.size() - 7);
00491 streamripper_error_number = streamripper_error_number.section(' ', 0, 0);
00492 switch (streamripper_error_number.toLongLong()) {
00493 case 3:
00494 case 6:
00495 temp_error.formatedValue = i18nc("@item error message", "connection failed");
00496 temp_error.toolTip = i18nc("@info:tooltip error message", "Could not connect to server");
00497 temp_error.whatsThis = i18nc(
00498 "@info:whatsthis error message",
00499 "Either the URL is invalid or the corresponding server does not exist.");
00500 break;
00501 case 7:
00502 temp_error.formatedValue = i18nc("@item error message", "incompatible stream");
00503 temp_error.toolTip = i18nc("@info:tooltip error message",
00504 "KRadioRipper can not record this type of stream.");
00505 temp_error.whatsThis = i18nc("@info:whatsthis error message",
00506 "Streamripper (and so also KRadioRipper) can only "
00507 "record shoutcast and icecast streams.");
00508 break;
00509 case 36:
00510 temp_error.formatedValue = i18nc("@item error message", "Could not write file");
00511 temp_error.toolTip = i18nc(
00512 "@info:tooltip error message",
00513 "KRadioRipper could not write the file because the download directory is not writable.");
00514 break;
00515 case 56:
00516 temp_error.formatedValue = i18nc("@item error message", "connection refused");
00517 temp_error.toolTip = i18nc("@info:tooltip error message",
00518 "Try changing the user agent string");
00519 temp_error.whatsThis = i18nc(
00520 "@info:whatsthis error message",
00521 "<para>The server has refused the connection.</para><para>You can try to use another "
00522 "user agent string - maybe the server will accept this.</para>");
00523 break;
00524 case 64:
00525 temp_error.formatedValue = i18nc("@item error message", "no stream");
00526 temp_error.toolTip = i18nc("@info:tooltip error message", "invalid playlist");
00527 temp_error.whatsThis = i18nc("@info:whatsthis error message",
00528 "The URL does not point directly to a stream, but to a "
00529 "playlist. And the playlist is invalid.");
00530 break;
00531 case 1001:
00532 temp_error.formatedValue = i18nc("@item error message", "bad download directory");
00533 temp_error.toolTip = i18nc("@info:tooltip error message",
00534 "The download directory is not accessible.");
00535 temp_error.whatsThis = i18nc(
00536 "@info:whatsthis error message",
00537 "<para>The download directory (<filename>%1</filename>) is not accessible. Either "
00538 "it does not exist or you do not have sufficient access rights.</para><para>You "
00539 "can change the download direcoty at <emphasis>Settings</emphasis>, <emphasis>"
00540 "Configure KRadioRipper...</emphasis>, <emphasis>Saving</emphasis>"
00541 "</para>", settings_general::saveDirectory().prettyUrl());
00542 break;
00543 default:
00544 temp_error.formatedValue = theError;
00545 break;
00546 };
00547 } else {
00548 temp_error.formatedValue = theError;
00549 };
00550
00551 return temp_error;
00552 }
00553
00554 void ripping::setError(const QString newError)
00555 {
00556 if ((internal_error.internalValue.toString() != newError)) {
00557
00558
00559
00560 internal_error = formatedError(newError);
00561 emit errorChanged(index(), internal_error);
00562 };
00563 }
00564
00565 QString ripping::default_value_of_error()
00566 {
00567 return QString();
00568 }
00569
00570 PropertyValue ripping::song() const
00571 {
00572 return internal_song;
00573 }
00574
00575 PropertyValue ripping::formatedSong(const QString theSong)
00576 {
00577
00578 PropertyValue temp_song;
00579
00580
00581 temp_song.internalValue = theSong;
00582 if ((theSong.isEmpty()) OR (theSong EQUAL " - ")) {
00583 temp_song.type = PropertyValue::unset;
00584 temp_song.formatedValue.clear();
00585 } else {
00586 temp_song.type = PropertyValue::value;
00587 temp_song.formatedValue = theSong;
00588 };
00589
00590 return temp_song;
00591 }
00592
00593 void ripping::setSong(const QString newSong)
00594 {
00595 if (internal_song.internalValue.toString() != newSong) {
00596 internal_song = formatedSong(newSong);
00597 emit songChanged(index(), internal_song);
00598 };
00599 }
00600
00601 QString ripping::default_value_of_song()
00602 {
00603 return QString();
00604 }
00605
00606 PropertyValue ripping::dataSize() const
00607 {
00608 return internal_dataSize;
00609 }
00610
00611 PropertyValue ripping::formatedDataSize(const qint64 theDataSize)
00612 {
00613
00614 PropertyValue temp_dataSize;
00615
00616
00617 temp_dataSize.internalValue = theDataSize;
00618 if (theDataSize == (-1)) {
00619 temp_dataSize.type = PropertyValue::error;
00620 temp_dataSize.formatedValue = i18nc("@item", "error");
00621 temp_dataSize.toolTip = i18nc ("@info:tooltip", "Error determinating track size");
00622 temp_dataSize.whatsThis = i18nc (
00623 "@info:whatsthis",
00624 "The track size could not be determinated. Please report this as a bug.");
00625 } else {
00626 if (theDataSize >= 0) {
00627 temp_dataSize.type = PropertyValue::value;
00628 temp_dataSize.formatedValue = ki18nc("@item The unit is MiB instead of MB. See "
00629 "http://en.wikipedia.org/wiki/Binary_prefix "
00630 "for details.",
00631 "%1 MiB")
00632 .subs(double(theDataSize) / (1024 * 1024), 0, 'f', 2).toString();
00633 temp_dataSize.whatsThis = i18nc("@info:whatsthis",
00634 "<para>The size of the track in MiB.</para><para>MiB "
00635 "has a binary prefix which means 1024 * 1024 B = "
00636 "1048576 B (different from MB which would mean "
00637 "1000000 B).</para>");
00638 } else {
00639 temp_dataSize.type = PropertyValue::unset;
00640 temp_dataSize.formatedValue.clear();
00641 temp_dataSize.whatsThis.clear();
00642 };
00643 temp_dataSize.toolTip.clear();
00644 };
00645 temp_dataSize.formatedValueAlignment = (Qt::AlignRight | Qt::AlignVCenter);
00646
00647 return temp_dataSize;
00648 }
00649
00650 void ripping::setDataSize(qint64 newDataSize)
00651 {
00652 if (internal_dataSize.internalValue.toLongLong() != newDataSize) {
00653 internal_dataSize = formatedDataSize(newDataSize);
00654 emit dataSizeChanged(index(), internal_dataSize);
00655 };
00656 }
00657
00658 qint64 ripping::default_value_of_dataSize()
00659 {
00660 return (-2);
00661 }
00662
00663 bool ripping::default_value_of_isRunning()
00664 {
00665 return false;
00666 }
00667
00668 bool ripping::isRunning() const
00669 {
00670 return internal_isRunning;
00671 }
00672
00673 PropertyValue ripping::relayPort() const
00674 {
00675 return internal_relayPort;
00676 }
00677
00678 PropertyValue ripping::formatedRelayPort(qint64 theRelayPort)
00679 {
00680
00681 PropertyValue temp_relayPort;
00682
00683
00684 temp_relayPort.internalValue = theRelayPort;
00685 if (theRelayPort == (-1)) {
00686 temp_relayPort.type = PropertyValue::error;
00687 temp_relayPort.formatedValue = i18nc(
00688 "@item",
00689 "error");
00690 temp_relayPort.toolTip = i18nc (
00691 "@info:tooltip",
00692 "Error determinating relay server port");
00693 temp_relayPort.whatsThis = i18nc (
00694 "@info:whatsthis",
00695 "The port of the relay server could not be determinated. Please report this as a bug.");
00696 } else {
00697 if (theRelayPort >= 0) {
00698 temp_relayPort.type = PropertyValue::value;
00699 temp_relayPort.formatedValue = KGlobal::locale()->formatLong(theRelayPort);
00700 } else {
00701 temp_relayPort.type = PropertyValue::unset;
00702 temp_relayPort.formatedValue.clear();
00703 };
00704 temp_relayPort.toolTip.clear();
00705 temp_relayPort.whatsThis.clear();
00706 };
00707 temp_relayPort.formatedValueAlignment = (Qt::AlignRight | Qt::AlignVCenter);
00708
00709 return temp_relayPort;
00710 }
00711
00712 void ripping::setRelayPort(qint64 newRelayPort)
00713 {
00714 if (internal_relayPort.internalValue.toLongLong() != newRelayPort) {
00715 internal_relayPort = formatedRelayPort(newRelayPort);
00716 emit relayPortChanged(index(), internal_relayPort);
00717 };
00718 }
00719
00720 qint64 ripping::default_value_of_relayPort()
00721 {
00722 return (-2);
00723 }
00724
00725 PropertyValue ripping::bitrate() const
00726 {
00727 return internal_bitrate;
00728 }
00729
00730 PropertyValue ripping::formatedBitrate(qint64 theBitrate)
00731 {
00732
00733 PropertyValue temp_bitrate;
00734
00735
00736 temp_bitrate.internalValue=theBitrate;
00737
00738 if (theBitrate >= 1) {
00739 temp_bitrate.formatedValue = i18ncp(
00740 "@item This makes a nicly formated string for the bitrate of a stream - %1 is an integer. "
00741 "WARNING: Unit has changed! It is now kbit instead of Kibit. "
00742 "This means 1000 bit (NOT 1024).",
00743 "%1 kbit/s",
00744 "%1 kbit/s",
00745 theBitrate);
00746 temp_bitrate.type = PropertyValue::value;
00747 temp_bitrate.toolTip = i18nc("@info:tooltip", "bit rate");
00748 temp_bitrate.whatsThis = i18nc(
00749 "@info:whatsthis WARNING Unit has changed from binary prefix to SI prefix",
00750 "<para>The bit rate of the stream in kbit/s.</para><para>kbit has an SI prefix which "
00751 "means 1000 bit (different from kbit which would mean 1024 bit). So 1 kbit/s means "
00752 "1000 bits per second.</para>");
00753 } else {
00754 if (theBitrate >= -1) {
00755 temp_bitrate.formatedValue = i18nc(
00756 "@item This makes a nicly formated string for the bitrate of a stream.",
00757 "Unable to recognize bitrate.");
00758 temp_bitrate.type = PropertyValue::error;
00759 temp_bitrate.toolTip = i18nc (
00760 "@info:tooltip",
00761 "Error determinating bit rate");
00762 temp_bitrate.whatsThis = i18nc (
00763 "@info:whatsthis",
00764 "The bit rate could not be determinated. Please report this as a bug.");
00765 } else {
00766 temp_bitrate.formatedValue.clear();
00767 temp_bitrate.type = PropertyValue::unset;
00768 temp_bitrate.toolTip.clear();
00769 temp_bitrate.whatsThis.clear();
00770 }
00771 };
00772
00773 temp_bitrate.formatedValueAlignment = (Qt::AlignRight | Qt::AlignVCenter);
00774
00775 return temp_bitrate;
00776 }
00777
00778 void ripping::setBitrate(const qint64 newBitrate)
00779 {
00780 kDebug() << "new bitrate:" << newBitrate ;
00781
00782 if (internal_bitrate.internalValue != newBitrate) {
00783 internal_bitrate = formatedBitrate(newBitrate);
00784 emit bitrateChanged(index(), internal_bitrate);
00785 };
00786 }
00787
00788 qint64 ripping::default_value_of_bitrate()
00789 {
00790 return (-2);
00791 }
00792
00793 PropertyValue ripping::metaInterval() const
00794 {
00795 return internal_metaInterval;
00796 }
00797
00798 PropertyValue ripping::formatedMetaInterval(const qint64 theMetaInterval)
00799 {
00800
00801 PropertyValue temp_metaInterval;
00802
00803
00804 temp_metaInterval.internalValue = theMetaInterval;
00805 if (theMetaInterval > 0) {
00806 temp_metaInterval.formatedValue = KGlobal::locale()->formatLong(theMetaInterval);
00807
00808 temp_metaInterval.type = PropertyValue::value;
00809 } else {
00810 if (theMetaInterval >= -1) {
00811 temp_metaInterval.formatedValue = i18nc(
00812 "@item",
00813 "error");
00814 temp_metaInterval.type = PropertyValue::error;
00815 } else {
00816 temp_metaInterval.formatedValue.clear();
00817 temp_metaInterval.type = PropertyValue::unset;
00818 };
00819 };
00820 temp_metaInterval.formatedValueAlignment = (Qt::AlignRight | Qt::AlignVCenter);
00821
00822
00823 return temp_metaInterval;
00824 }
00825
00826 void ripping::setMetaInterval(const qint64 newMetaInterval)
00827 {
00828 if (internal_metaInterval.internalValue != newMetaInterval) {
00829 internal_metaInterval = formatedMetaInterval(newMetaInterval);
00830 emit metaIntervalChanged(index(), internal_metaInterval);
00831 };
00832 }
00833
00834 qint64 ripping::default_value_of_metaInterval()
00835 {
00836 return (-2);
00837 }
00838
00839 void ripping::errorOccured(QProcess::ProcessError error)
00840 {
00841
00842 QFileInfo m_file_info(settings_general::streamripperCommand());
00843
00844
00845 switch (error) {
00846 case QProcess::FailedToStart:
00847 if (m_file_info.exists()) {
00848 setError(i18nc(
00849 "@item streamripper error",
00850 "Insufficient permissions to invoke Streamripper."));
00851 } else {
00852 setError(i18nc("@item streamripper error", "Streamripper binary not found."));
00853 };
00854 break;
00855 case QProcess::Crashed:
00856 setError(i18nc("@item streamripper error", "Streamripper crashed."));
00857 break;
00858 case QProcess::Timedout:
00859 setError(i18nc("@item streamripper error", "Streamripper does not react."));
00860 break;
00861 default:
00862 setError(i18nc("@item streamripper error", "Error accessing Streamripper."));
00863 break;
00864 };
00865 }
00866
00867 void ripping::streamripperStateChange(QProcess::ProcessState newState)
00868 {
00869 if (newState == QProcess::NotRunning) {
00870 setStatus(default_value_of_status());
00871 setSong(default_value_of_song());
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884 setDataSize(default_value_of_dataSize());
00885 setRelayPort(default_value_of_relayPort());
00886 };
00887 }
00888
00889 QStringList ripping::parameterList() const
00890 {
00891
00892 QStringList parameters;
00893
00894
00895 parameters.append(serverUri());
00896
00897 parameters.append(QString("-t"));
00898
00899
00900
00901
00902 if (NOT (settings_general::proxyServer().isEmpty())) {
00903
00904 parameters.append(QString("-p"));
00905 parameters.append(settings_general::proxyServer());
00906 }
00907
00908 if (settings_general::createRelayServer()) {
00909
00910 parameters.append(QString("-r"));
00911 parameters.append(QString::number(settings_general::preferedPortForRelayServer()));
00912
00913
00914 parameters.append(QString("-R"));
00915 if (settings_general::limitConnections()) {
00916 parameters.append(QString::number(settings_general::limitConnectionsToX()));
00917 } else {
00918 parameters.append(QString("0"));
00919 };
00920 };
00921
00922 parameters.append(QString("-c"));
00923
00924 return parameters;
00925 }
00926
00927 QString ripping::streamripperCommand() const
00928 {
00929 return settings_general::streamripperCommand();
00930 }
00931
00932 void ripping::startStreamripper()
00933 {
00934
00935 QFileInfo * dir;
00936
00937
00938 VersionNumber * testnumber = new VersionNumber("1.2.3");
00939
00940
00941 if (m_process.state() == QProcess::NotRunning) {
00942
00943 setError(QString());
00944 setStatus(is_starting);
00945
00946
00947
00948 dir = new QFileInfo(settings_general::saveDirectory().toLocalFile());
00949 if (dir->exists() && dir->isAbsolute() && dir->isDir() &&
00950 dir->isReadable() && dir->isWritable()) {
00951 m_process.setWorkingDirectory(settings_general::saveDirectory().toLocalFile());
00952 streamripper_base::startStreamripper();
00953 } else {
00954
00955 setError("error -1001 [BAD_DOWNLOAD_DIRECTORY]");
00956 setStatus(idle);
00957 };
00958 };
00959 }
00960
00961 void ripping::shutDown()
00962 {
00963 m_process.terminate();
00964
00965
00966
00967 }
00968
00969 bool ripping::doesTheUserWantsThatTheStreamIsRipping(ripping::statusType theStatus)
00970 {
00971 return (!((theStatus == ripping::idle) OR (theStatus == ripping::is_saving)));
00972 }
00973
00974 bool ripping::doesTheUserWantsThatTheStreamIsRipping()
00975 {
00976 return doesTheUserWantsThatTheStreamIsRipping(
00977 internal_status.internalValue.value<statusType>());
00978 }