static void Get(cDBusObject *Object, GVariant *Parameters, GDBusMethodInvocation *Invocation) { // only update recordings list if empty // so we don't mess around with the index values returned by List if (recordings.Count() == 0) recordings.Update(true); cRecording *recording = NULL; GVariant *first = g_variant_get_child_value(Parameters, 0); GVariant *refValue = first; if (g_variant_is_of_type(first, G_VARIANT_TYPE_VARIANT)) refValue = g_variant_get_child_value(first, 0); if (g_variant_is_of_type(refValue, G_VARIANT_TYPE_STRING)) { const char *path = NULL; g_variant_get(refValue, "&s", &path); if ((path != NULL) && *path) recording = recordings.GetByName(path); } else if (g_variant_is_of_type(refValue, G_VARIANT_TYPE_INT32)) { int number = 0; g_variant_get(refValue, "i", &number); if ((number > 0) && (number <= recordings.Count())) recording = recordings.Get(number - 1); } if (refValue != first) g_variant_unref(refValue); g_variant_unref(first); GVariant *rec = BuildRecording(recording); g_dbus_method_invocation_return_value(Invocation, g_variant_new_tuple(&rec, 1)); };
static void List(cDBusObject *Object, GVariant *Parameters, GDBusMethodInvocation *Invocation) { recordings.Update(true); GVariantBuilder *array = g_variant_builder_new(G_VARIANT_TYPE("a(ia(sv))")); for (cRecording *r = recordings.First(); r; r = recordings.Next(r)) g_variant_builder_add_value(array, BuildRecording(r)); GVariant *a = g_variant_builder_end(array); g_dbus_method_invocation_return_value(Invocation, g_variant_new_tuple(&a, 1)); g_variant_builder_unref(array); };
void AssertFreeDiskSpace(int Priority, bool Force) { static cMutex Mutex; cMutexLock MutexLock(&Mutex); // With every call to this function we try to actually remove // a file, or mark a file for removal ("delete" it), so that // it will get removed during the next call. static time_t LastFreeDiskCheck = 0; int Factor = (Priority == -1) ? 10 : 1; if (Force || time(NULL) - LastFreeDiskCheck > DISKCHECKDELTA / Factor) { if (!VideoFileSpaceAvailable(MINDISKSPACE)) { // Make sure only one instance of VDR does this: cLockFile LockFile(VideoDirectory); if (!LockFile.Lock()) return; // Remove the oldest file that has been "deleted": isyslog("low disk space while recording, trying to remove a deleted recording..."); cThreadLock DeletedRecordingsLock(&DeletedRecordings); if (DeletedRecordings.Count()) { cRecording *r = DeletedRecordings.First(); cRecording *r0 = NULL; while (r) { if (IsOnVideoDirectoryFileSystem(r->FileName())) { // only remove recordings that will actually increase the free video disk space if (!r0 || r->start < r0->start) r0 = r; } r = DeletedRecordings.Next(r); } if (r0 && r0->Remove()) { DeletedRecordings.Del(r0); LastFreeDiskCheck += REMOVELATENCY / Factor; return; } } else { // DeletedRecordings was empty, so to be absolutely sure there are no // deleted recordings we need to double check: DeletedRecordings.Update(true); if (DeletedRecordings.Count()) return; // the next call will actually remove it } // No "deleted" files to remove, so let's see if we can delete a recording: isyslog("...no deleted recording found, trying to delete an old recording..."); cThreadLock RecordingsLock(&Recordings); if (Recordings.Count()) { cRecording *r = Recordings.First(); cRecording *r0 = NULL; while (r) { if (IsOnVideoDirectoryFileSystem(r->FileName())) { // only delete recordings that will actually increase the free video disk space if (!r->IsEdited() && r->lifetime < MAXLIFETIME) { // edited recordings and recordings with MAXLIFETIME live forever if ((r->lifetime == 0 && Priority > r->priority) || // the recording has no guaranteed lifetime and the new recording has higher priority (r->lifetime > 0 && (time(NULL) - r->start) / SECSINDAY >= r->lifetime)) { // the recording's guaranteed lifetime has expired if (r0) { if (r->priority < r0->priority || (r->priority == r0->priority && r->start < r0->start)) r0 = r; // in any case we delete the one with the lowest priority (or the older one in case of equal priorities) } else r0 = r; } } } r = Recordings.Next(r); } if (r0 && r0->Delete()) { Recordings.Del(r0); return; } } // Unable to free disk space, but there's nothing we can do about that... isyslog("...no old recording found, giving up"); Skins.QueueMessage(mtWarning, tr("Low disk space!"), 5, -1); } LastFreeDiskCheck = time(NULL); } }
static void Play(cDBusObject *Object, GVariant *Parameters, GDBusMethodInvocation *Invocation) { int replyCode = 501; cString replyMessage; cRecording *recording = NULL; int position = -1; // default: resume const char *hmsf = NULL; GVariant *first = g_variant_get_child_value(Parameters, 0); GVariant *refFirst = first; if (g_variant_is_of_type(first, G_VARIANT_TYPE_VARIANT)) refFirst = g_variant_get_child_value(first, 0); GVariant *second = g_variant_get_child_value(Parameters, 1); GVariant *refSecond = first; if (g_variant_is_of_type(first, G_VARIANT_TYPE_VARIANT)) refSecond = g_variant_get_child_value(first, 0); if (g_variant_is_of_type(refFirst, G_VARIANT_TYPE_STRING)) { const char *path = NULL; g_variant_get(refFirst, "&s", &path); if ((path != NULL) && *path) { recording = recordings.GetByName(path); if (recording == NULL) { recordings.Update(true); recording = recordings.GetByName(path); if (recording == NULL) replyMessage = cString::sprintf("recording \"%s\" not found", path); } } } else if (g_variant_is_of_type(refFirst, G_VARIANT_TYPE_INT32)) { int number = 0; g_variant_get(refFirst, "i", &number); if (number > 0) { recording = recordings.Get(number - 1); if (recording == NULL) { recordings.Update(true); recording = recordings.Get(number - 1); if (recording == NULL) replyMessage = cString::sprintf("recording \"%d\" not found", number); } } } if (recording != NULL) { if (g_variant_is_of_type(refSecond, G_VARIANT_TYPE_STRING)) { g_variant_get(refSecond, "&s", &hmsf); if ((hmsf != NULL) && *hmsf) { if (strcasecmp(hmsf, "begin") == 0) { position = 0; hmsf = NULL; } else position = HMSFToIndex(hmsf, recording->FramesPerSecond()); } else hmsf = NULL; } else if (g_variant_is_of_type(refSecond, G_VARIANT_TYPE_INT32)) g_variant_get(refSecond, "i", &position); replyCode = 250; #if VDRVERSNUM < 10728 cReplayControl::SetRecording(NULL, NULL); #else cReplayControl::SetRecording(NULL); #endif cControl::Shutdown(); if (position >= 0) { cResumeFile resume(recording->FileName(), recording->IsPesRecording()); if (position == 0) resume.Delete(); else resume.Save(position); } #if VDRVERSNUM < 10728 cReplayControl::SetRecording(recording->FileName(), recording->Title()); #else cReplayControl::SetRecording(recording->FileName()); #endif cControl::Launch(new cReplayControl); cControl::Attach(); if (hmsf != NULL) replyMessage = cString::sprintf("Playing recording \"%s\" from position %s", recording->FileName(), hmsf); else if (position >= 0) replyMessage = cString::sprintf("Playing recording \"%s\" from position %d", recording->FileName(), position); else replyMessage = cString::sprintf("Resume playing recording \"%s\"", recording->FileName()); } cDBusHelper::SendReply(Invocation, replyCode, *replyMessage); if (refFirst != first) g_variant_unref(refFirst); g_variant_unref(first); if (refSecond != second) g_variant_unref(refSecond); g_variant_unref(second); };