Example #1
0
void AlarmNotifyThread::run()
{
    RunProlog();

    while (!m_stop)
    {
        // get the alarm status for all monitors
        if (ZMClient::get()->connected() && ZMClient::get()->updateAlarmStates())
        {
            // at least one monitor changed state
            for (int x = 0; x < ZMClient::get()->getMonitorCount(); x++)
            {
                Monitor *mon = ZMClient::get()->getMonitorAt(x);

                if (mon->previousState != mon->state && (mon->state == ALARM || (mon->state == ALERT && mon->previousState != ALARM)))
                {
                    // have notifications been turned on for this monitor?
                    if (mon->showNotifications)
                    {
                        // we can't show a popup from the AlarmNotifyThread so send
                        // a message to ZMClient to do it for us
                        gCoreContext->dispatch(MythEvent(QString("ZONEMINDER_NOTIFICATION %1").arg(mon->id)));
                    }
                }
            }
        }

        usleep(999999);
    }

    RunEpilog();
}
Example #2
0
void SSDP::run()
{
    RunProlog();

    fd_set          read_set;
    struct timeval  timeout;

    LOG(VB_UPNP, LOG_INFO, "SSDP::Run - SSDP Thread Started." );

    // ----------------------------------------------------------------------
    // Listen for new Requests
    // ----------------------------------------------------------------------

    while ( ! m_bTermRequested )
    {
        int nMaxSocket = 0;

        FD_ZERO( &read_set );

        for (uint nIdx = 0; nIdx < NumberOfSockets; nIdx++ )
        {
            if (m_Sockets[nIdx] != NULL && m_Sockets[nIdx]->socket() >= 0)
            {
                FD_SET( m_Sockets[ nIdx ]->socket(), &read_set );
                nMaxSocket = max( m_Sockets[ nIdx ]->socket(), nMaxSocket );

#if 0
                if (m_Sockets[ nIdx ]->bytesAvailable() > 0)
                {
                    LOG(VB_GENERAL, LOG_DEBUG,
                        QString("Found Extra data before select: %1")
                        .arg(nIdx));
                    ProcessData( m_Sockets[ nIdx ] );
                }
#endif
            }
        }
        
        timeout.tv_sec  = 1;
        timeout.tv_usec = 0;

        int count;
        count = select(nMaxSocket + 1, &read_set, NULL, NULL, &timeout);
        for (int nIdx = 0; count && nIdx < (int)NumberOfSockets; nIdx++ )
        {
            if (m_Sockets[nIdx] != NULL && m_Sockets[nIdx]->socket() >= 0 &&
                FD_ISSET(m_Sockets[nIdx]->socket(), &read_set))
            {
#if 0
                LOG(VB_GENERAL, LOG_DEBUG, QString("FD_ISSET( %1 )").arg(nIdx));
#endif
                ProcessData(m_Sockets[nIdx]);
                count--;
            }
        }
    }

    RunEpilog();
}
Example #3
0
void MetadataLoadingThread::run()
{
    RunProlog();
    //if you want to simulate a big music collection load
    //sleep(3);
    parent->resync();
    RunEpilog();
}
Example #4
0
void MythSystemSignalManager::run(void)
{
    RunProlog();
    LOG(VB_GENERAL, LOG_INFO, "Starting process signal handler");
    while( run_system )
    {
        struct timespec ts;
        ts.tv_sec = 0;
        ts.tv_nsec = 50 * 1000 * 1000; // 50ms
        nanosleep(&ts, NULL); // sleep 50ms

        while( run_system )
        {
            // handle cleanup and signalling for closed processes
            listLock.lock();
            if( msList.isEmpty() )
            {
                listLock.unlock();
                break;
            }
            MythSystemUnix *ms = msList.takeFirst();
            listLock.unlock();

            // This can happen if it has been deleted already
            if (!ms)
                continue;

            ms->m_parent->HandlePostRun();

            if (ms->m_stdpipe[0] > 0)
                writeThread->remove(ms->m_stdpipe[0]);
            CLOSE(ms->m_stdpipe[0]);

            if (ms->m_stdpipe[1] > 0)
                readThread->remove(ms->m_stdpipe[1]);
            CLOSE(ms->m_stdpipe[1]);

            if (ms->m_stdpipe[2] > 0)
                readThread->remove(ms->m_stdpipe[2]);
            CLOSE(ms->m_stdpipe[2]);

            if( ms->GetStatus() == GENERIC_EXIT_OK )
                emit ms->finished();
            else
                emit ms->error(ms->GetStatus());

            ms->disconnect();

            bool cleanup = ms->m_parent->doAutoCleanup();

            ms->Unlock();

            if( cleanup )
                ms->deleteLater();
        }
    }
    RunEpilog();
}
Example #5
0
// spawn separate thread for signals to prevent manager
void MythSystemLegacySignalManager::run(void)
{
    RunProlog();

    LOG(VB_GENERAL, LOG_INFO, "Starting process signal handler");
    while( run_system )
    {
        usleep(50000); // sleep 50ms
        while( run_system )
        {
            // handle cleanup and signalling for closed processes
            listLock.lock();
            if( msList.isEmpty() )
            {
                listLock.unlock();
                break;
            }
            MythSystemLegacyWindows *ms = msList.takeFirst();
            listLock.unlock();

            if (!ms)
                continue;

            if (ms->m_parent)
            {
                ms->m_parent->HandlePostRun();
            }

            if (ms->m_stdpipe[0])
                writeThread->remove(ms->m_stdpipe[0]);
            CLOSE(ms->m_stdpipe[0]);

            if (ms->m_stdpipe[1])
                readThread->remove(ms->m_stdpipe[1]);
            CLOSE(ms->m_stdpipe[1]);

            if (ms->m_stdpipe[2])
                readThread->remove(ms->m_stdpipe[2]);
            CLOSE(ms->m_stdpipe[2]);

            if (ms->m_parent)
            {
                if( ms->GetStatus() == GENERIC_EXIT_OK )
                    emit ms->finished();
                else
                    emit ms->error(ms->GetStatus());

                ms->disconnect();
                ms->Unlock();
            }

            ms->DecrRef();
        }
    }

    RunEpilog();
}
void FetcherThread::run(void)
{
    RunProlog();
    LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Starting Fetcher thread."));
    if (m_dec)
        m_dec->FetchFrames();
    LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Stopping Fetcher thread."));
    RunEpilog();
}
void PlaylistLoadingThread::run()
{
    RunProlog();
    while (!all_music->doneLoading())
    {
        msleep(250);
    }
    parent->load();
    RunEpilog();
}
Example #8
0
void DVBStreamHandler::run(void)
{
    RunProlog();
    LOG(VB_RECORD, LOG_INFO, LOC + "run(): begin");

    if (!SupportsTSMonitoring() && _allow_section_reader)
        RunSR();
    else
        RunTS();

    LOG(VB_RECORD, LOG_INFO, LOC + "run(): end");
    RunEpilog();
}
Example #9
0
void MythSystemLegacyIOHandler::run(void)
{
    RunProlog();

    LOG(VB_GENERAL, LOG_INFO, QString("Starting IO manager (%1)")
        .arg(m_read ? "read" : "write"));

    while( run_system )
    {
        {
            QMutexLocker locker(&m_pWaitLock);
            m_pWait.wait(&m_pWaitLock);
        }

        while( run_system )
        {
            usleep(10000); // ~100x per second, for ~3MBps throughput
            m_pLock.lock();
            if( m_pMap.isEmpty() )
            {
                m_pLock.unlock();
                break;
            }

            bool datafound = true;
            m_pLock.unlock();

            while ( datafound && run_system )
            {
                m_pLock.lock();

                datafound = false;
                PMap_t::iterator i, next;
                for( i = m_pMap.begin(); i != m_pMap.end(); i = next )
                {
                    next = i + 1;

                    if( m_read )
                        datafound |= HandleRead(i.key(), i.value());
                    else
                        datafound |= HandleWrite(i.key(), i.value());
                }
                m_pLock.unlock();
            }
        }
    }
    RunEpilog();
}
Example #10
0
void GameScannerThread::run(void)
{
    RunProlog();

    LOG(VB_GENERAL, LOG_INFO, QString("Beginning Game Scan."));

    m_files.clear();
    m_remove.clear();
    m_dbgames = RomInfo::GetAllRomInfo();

    buildFileList();
    verifyFiles();
    updateDB();

    RunEpilog();
}
Example #11
0
void MythSignalingTimer::run(void)
{
    running = true;
    RunProlog();
    while (dorun)
    {
        QMutexLocker locker(&startStopLock);
        if (dorun && !timerWait.wait(locker.mutex(), millisec))
        {
            locker.unlock();
            emit timeout();
            locker.relock();
        }
    }
    RunEpilog();
    running = false;
}
Example #12
0
/** \class HouseKeepingThread
 *  \ingroup housekeeper
 *  \brief Thread used to perform queued HouseKeeper tasks.
 *
 *  This class is a long-running thread that pulls tasks out of the
 *  HouseKeeper queue and runs them sequentially. It performs one last check
 *  of the task to make sure something else in the same scope has not
 *  pre-empted it, before running the task.
 *
 */
void HouseKeepingThread::run(void)
{
    RunProlog();
    m_waitMutex.lock();
    HouseKeeperTask *task = NULL;

    while (m_keepRunning)
    {
        m_idle = false;

        while ((task = m_parent->GetQueuedTask()))
        {
            // pull task from housekeeper and process it
            ReferenceLocker rlock(task);

            if (!task->ConfirmRun())
            {
                // something else has caused the lastrun time to
                // change since this was requested to run. abort.
                task = NULL;
                continue;
            }

            task->UpdateLastRun();
            task->Run();
            task = NULL;

            if (!m_keepRunning)
                // thread has been discarded, don't try to start another task
                break;
        }

        m_idle = true;

        if (!m_keepRunning)
            // short out rather than potentially hitting another sleep cycle
            break;

        m_waitCondition.wait(&m_waitMutex);
    }

    m_waitMutex.unlock();
    RunEpilog();
}
Example #13
0
/// \brief Basic signal monitoring loop
void SignalMonitor::run(void)
{
    RunProlog();

    QMutexLocker locker(&startStopLock);
    running = true;
    startStopWait.wakeAll();

    while (!exit)
    {
        locker.unlock();

        UpdateValues();

        if (notify_frontend && capturecardnum>=0)
        {
            QStringList slist = GetStatusList();
            MythEvent me(QString("SIGNAL %1").arg(capturecardnum), slist);
            gCoreContext->dispatch(me);
        }

        locker.relock();
        startStopWait.wait(locker.mutex(), update_rate);
    }

    // We need to send a last informational message because a
    // signal update may have come in while we were sleeping
    // if we are using the multithreaded dtvsignalmonitor.
    locker.unlock();
    if (notify_frontend && capturecardnum>=0)
    {
        QStringList slist = GetStatusList();
        MythEvent me(QString("SIGNAL %1").arg(capturecardnum), slist);
        gCoreContext->dispatch(me);
    }
    locker.relock();

    running = false;
    startStopWait.wakeAll();

    RunEpilog();
}
Example #14
0
void TaskQueue::run( )
{
    RunProlog();

    Task *pTask;

    LOG(VB_UPNP, LOG_INFO, "TaskQueue Thread Running.");

    while ( !m_bTermRequested )
    {
        // ------------------------------------------------------------------
        // Process Any Tasks that may need to be executed.
        // ------------------------------------------------------------------

        TaskTime ttNow;
        gettimeofday( (&ttNow), nullptr );

        if ((pTask = GetNextExpiredTask( ttNow )) != nullptr)
        {
            try
            {
                pTask->Execute( this );
                pTask->DecrRef();
            }
            catch( ... )
            {
                LOG(VB_GENERAL, LOG_ERR, "Call to Execute threw an exception.");
            }

        }
        // Make sure to throttle our processing.

        msleep( 100 );
    }

    RunEpilog();
}
Example #15
0
void HLSStreamHandler::run(void)
{
    RunProlog();

    int cnt = 0;

    LOG(VB_GENERAL, LOG_INFO, LOC + "run() -- begin");

    SetRunning(true, false, false);

    if (!m_hls)
        return;
    m_hls->Throttle(false);

    while (_running_desired)
    {
        if (!m_hls->IsOpen(m_tuning.GetURL(0).toString()))
        {
            if (!m_hls->Open(m_tuning.GetURL(0).toString()))
            {
                LOG(VB_CHANNEL, LOG_INFO, LOC +
                    "run: HLS OpenFile() failed");
                usleep(500000);
                continue;
            }
            m_hls->Throttle(true);
        }

        int size = m_hls->Read(m_buffer, BUFFER_SIZE);

        if (size < 0)
        {
            // error
            if (++cnt > 10)
            {
                Stop();
                break;
            }
            continue;
        }
        else
            cnt = 0;

        if (size == 0)
        {
            usleep(250000);  // .25 second
            continue;
        }

        if (m_buffer[0] != 0x47)
        {
            LOG(VB_RECORD, LOG_INFO, LOC +
                QString("Packet not starting with SYNC Byte (got 0x%1)")
                .arg((char)m_buffer[0], 2, QLatin1Char('0')));
            continue;
        }

        int remainder = 0;
        {
            QMutexLocker locker(&_listener_lock);
            HLSStreamHandler::StreamDataList::const_iterator sit;
            sit = _stream_data_list.begin();
            for (; sit != _stream_data_list.end(); ++sit)
            {
                remainder = sit.key()->ProcessData(m_buffer, size);
            }
        }

        if (remainder != 0)
        {
            LOG(VB_RECORD, LOG_INFO, LOC +
                QString("data_length = %1 remainder = %2")
                .arg(size).arg(remainder));
        }

        if (m_hls->IsThrottled())
            usleep(1000000);
        else if (size < BUFFER_SIZE)
            usleep(100000); // tenth of a second.
        else
            usleep(1000);
    }

    m_hls->Throttle(false);

    SetRunning(false, false, false);
    RunEpilog();

    LOG(VB_GENERAL, LOG_INFO, LOC + "run() -- done");
}
Example #16
0
void MythSystemIOHandler::run(void)
{
    RunProlog();
    LOG(VB_GENERAL, LOG_INFO, QString("Starting IO manager (%1)")
                .arg(m_read ? "read" : "write"));

    m_pLock.lock();
    BuildFDs();
    m_pLock.unlock();

    while( run_system )
    {
        {
            QMutexLocker locker(&m_pWaitLock);
            m_pWait.wait(&m_pWaitLock);
        }

        while( run_system )
        {
            usleep(10000); // ~100x per second, for ~3MBps throughput
            m_pLock.lock();
            if( m_pMap.isEmpty() )
            {
                m_pLock.unlock();
                break;
            }
            
            timeval tv;
            tv.tv_sec = 0; tv.tv_usec = 0;
          
            int retval;
            fd_set fds = m_fds;

            if( m_read )
                retval = select(m_maxfd+1, &fds, NULL, NULL, &tv);
            else
                retval = select(m_maxfd+1, NULL, &fds, NULL, &tv);

            if( retval == -1 )
                LOG(VB_SYSTEM, LOG_ERR,
                    QString("MythSystemIOHandler: select(%1, %2) failed: %3")
                        .arg(m_maxfd+1).arg(m_read).arg(strerror(errno)));

            else if( retval > 0 )
            {
                PMap_t::iterator i, next;
                for( i = m_pMap.begin(); i != m_pMap.end(); i = next )
                {
                    next = i+1;
                    int fd = i.key();
                    if( FD_ISSET(fd, &fds) )
                    {
                        if( m_read )
                            HandleRead(i.key(), i.value());
                        else
                            HandleWrite(i.key(), i.value());
                    }
                }
            }
            m_pLock.unlock();
        }
    }

    RunEpilog();
}
Example #17
0
void ExternalStreamHandler::run(void)
{
    QString    cmd;
    QString    result;
    QString    xon;
    QByteArray buffer;
    uint       len;

    RunProlog();

    LOG(VB_RECORD, LOG_INFO, LOC + "run(): begin");

    SetRunning(true, true, false);

    if (m_poll_mode)
        xon = QString("SendBytes:%1").arg(PACKET_SIZE);
    else
        xon = "XON";

    uint remainder = 0;
    while (_running_desired && !_error)
    {
        if (!IsOpen())
        {
            if (!Open())
            {
                LOG(VB_RECORD, LOG_WARNING, LOC + QString("TS not open yet: %1")
                    .arg(m_error));
                usleep(750000);
                continue;
            }
        }

        if (StreamingCount() == 0)
        {
            usleep(5000);
            continue;
        }

        UpdateFiltersFromStreamData();

        ProcessCommand(xon, 1000, result);
        if (result.startsWith("ERR"))
        {
            LOG(VB_GENERAL, LOG_ERR, LOC + QString("Aborting: %1 -> %2")
                .arg(xon).arg(result));
            _error = true;
        }

        while ((len = m_IO->Read(buffer, PACKET_SIZE, 10)) > 0 ||
               buffer.size() > 188*50)
        {
            if (m_IO->Error())
            {
                m_error = m_IO->ErrorString();
                _error = true;
                LOG(VB_GENERAL, LOG_ERR, LOC +
                    QString("Failed to read from Extern recorder: %1")
                    .arg(m_error));
                break;
            }

            if (!_running_desired)
                break;

            if (!_listener_lock.tryLock())
                continue;

            if (_stream_data_list.empty())
            {
                LOG(VB_GENERAL, LOG_ERR, LOC + "_stream_data_list is empty");
                _listener_lock.unlock();
                continue;
            }

            if (!m_poll_mode)
            {
                ProcessCommand(QString("XOFF"), 50, result);
                if (result.startsWith("ERR"))
                {
                    LOG(VB_GENERAL, LOG_ERR, LOC + QString("Aborting: %1 -> %2")
                        .arg(xon).arg(result));
                    _error = true;
                }
            }

            StreamDataList::const_iterator sit = _stream_data_list.begin();
            for (; sit != _stream_data_list.end(); ++sit)
                remainder = sit.key()->ProcessData
                            (reinterpret_cast<const uint8_t *>
                             (buffer.constData()), buffer.size());

            _listener_lock.unlock();

            len = buffer.size();

            if (m_replay)
            {
                m_replay_buffer += buffer.left(len - remainder);
                if (m_replay_buffer.size() > (5000 * PACKET_SIZE))
                {
                    m_replay_buffer.remove(0, len - remainder);
                    LOG(VB_RECORD, LOG_WARNING, LOC +
                        QString("Replay size truncated to %1 bytes")
                        .arg(m_replay_buffer.size()));
                }
            }

            if (remainder > 0 && (len > remainder)) // leftover bytes
                buffer.remove(0, len - remainder);
            else
                buffer.clear();
        }
        usleep(10);
    }
    LOG(VB_RECORD, LOG_INFO, LOC + "run(): " + "shutdown");

    RemoveAllPIDFilters();
    SetRunning(false, true, false);

    LOG(VB_RECORD, LOG_INFO, LOC + "run(): " + "end");

    RunEpilog();
}
Example #18
0
void IPTVTableMonitorThread::run(void)
{
    RunProlog();
    m_parent->RunTableMonitor();
    RunEpilog();
}
Example #19
0
void CetonStreamHandler::run(void)
{
    RunProlog();
    bool _error = false;

    QFile file(_device_path);
    CetonRTP rtp(_ip_address, _tuner);

    if (_using_rtp)
    {
        if (!(rtp.Init() && rtp.StartStreaming()))
        {
            LOG(VB_RECORD, LOG_ERR, LOC +
                "Starting recording (RTP initialization failed). Aborting.");
            _error = true;
        }
    }
    else
    {
        if (!file.open(QIODevice::ReadOnly))
        {
            LOG(VB_RECORD, LOG_ERR, LOC +
                "Starting recording (file open failed). Aborting.");
            _error = true;
        }

        int flags = fcntl(file.handle(), F_GETFL, 0);
        if (flags == -1) flags = 0;
        fcntl(file.handle(), F_SETFL, flags | O_NONBLOCK);
    }

    if (_error)
    {
        RunEpilog();
        return;
    }

    SetRunning(true, false, false);

    int buffer_size = (64 * 1024); // read about 64KB
    buffer_size /= TSPacket::kSize;
    buffer_size *= TSPacket::kSize;
    char *buffer = new char[buffer_size];

    LOG(VB_RECORD, LOG_INFO, LOC + "RunTS(): begin");

    _read_timer.start();

    int remainder = 0;
    while (_running_desired && !_error)
    {
        int bytes_read;
        if (_using_rtp)
            bytes_read = rtp.Read(buffer, buffer_size);
        else
            bytes_read = file.read(buffer, buffer_size);

        if (bytes_read <= 0)
        {
            if (_read_timer.elapsed() >= 5000)
            {
                LOG(VB_RECORD, LOG_WARNING, LOC +
                    "No data received for 5 seconds...checking tuning");
                if (!VerifyTuning())
                    RepeatTuning();
                _read_timer.start();
            }

            usleep(5000);
            continue;
        }

        _read_timer.start();

        _listener_lock.lock();

        if (_stream_data_list.empty())
        {
            _listener_lock.unlock();
            continue;
        }

        StreamDataList::const_iterator sit = _stream_data_list.begin();
        for (; sit != _stream_data_list.end(); ++sit)
            remainder = sit.key()->ProcessData(
                reinterpret_cast<unsigned char*>(buffer), bytes_read);

        _listener_lock.unlock();
        if (remainder != 0)
        {
            LOG(VB_RECORD, LOG_INFO, LOC +
                QString("RunTS(): bytes_read = %1 remainder = %2")
                    .arg(bytes_read).arg(remainder));
        }
    }
    LOG(VB_RECORD, LOG_INFO, LOC + "RunTS(): " + "shutdown");

    if (_using_rtp)
        rtp.StopStreaming();
    else
        file.close();

    delete[] buffer;

    LOG(VB_RECORD, LOG_INFO, LOC + "RunTS(): " + "end");

    SetRunning(false, false, false);
    RunEpilog();
}
Example #20
0
void ASIStreamHandler::run(void)
{
    RunProlog();

    LOG(VB_RECORD, LOG_INFO, LOC + "run(): begin");

    if (!Open())
    {
        LOG(VB_GENERAL, LOG_ERR, LOC + QString("Failed to open device %1 : %2")
                .arg(_device).arg(strerror(errno)));
        _error = true;
        return;
    }

    DeviceReadBuffer *drb = new DeviceReadBuffer(this, true, false);
    bool ok = drb->Setup(_device, _fd, _packet_size, _buf_size);
    if (!ok)
    {
        LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to allocate DRB buffer");
        delete drb;
        drb = NULL;
        Close();
        _error = true;
        RunEpilog();
        return;
    }

    uint buffer_size = _packet_size * 15000;
    unsigned char *buffer = new unsigned char[buffer_size];
    if (!buffer)
    {
        LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to allocate buffer");
        delete drb;
        drb = NULL;
        Close();
        _error = true;
        RunEpilog();
        return;
    }
    memset(buffer, 0, buffer_size);

    SetRunning(true, true, false);

    drb->Start();

    {
        QMutexLocker locker(&_start_stop_lock);
        _drb = drb;
    }

    int remainder = 0;
    while (_running_desired && !_error)
    {
        UpdateFiltersFromStreamData();

        ssize_t len = 0;

        len = drb->Read(
            &(buffer[remainder]), buffer_size - remainder);

        if (!_running_desired)
            break;

        // Check for DRB errors
        if (drb->IsErrored())
        {
            LOG(VB_GENERAL, LOG_ERR, LOC + "Device error detected");
            _error = true;
        }

        if (drb->IsEOF())
        {
            LOG(VB_GENERAL, LOG_ERR, LOC + "Device EOF detected");
            _error = true;
        }

        if ((0 == len) || (-1 == len))
        {
            usleep(100);
            continue;
        }

        len += remainder;

        if (len < 10) // 10 bytes = 4 bytes TS header + 6 bytes PES header
        {
            remainder = len;
            continue;
        }

        if (!_listener_lock.tryLock())
        {
            remainder = len;
            continue;
        }

        if (_stream_data_list.empty())
        {
            _listener_lock.unlock();
            continue;
        }

        StreamDataList::const_iterator sit = _stream_data_list.begin();
        for (; sit != _stream_data_list.end(); ++sit)
            remainder = sit.key()->ProcessData(buffer, len);

        if (_mpts != NULL)
            _mpts->Write(buffer, len - remainder);

        _listener_lock.unlock();

        if (remainder > 0 && (len > remainder)) // leftover bytes
            memmove(buffer, &(buffer[len - remainder]), remainder);
    }
    LOG(VB_RECORD, LOG_INFO, LOC + "run(): " + "shutdown");

    RemoveAllPIDFilters();

    {
        QMutexLocker locker(&_start_stop_lock);
        _drb = NULL;
    }

    if (drb->IsRunning())
        drb->Stop();

    delete drb;
    delete[] buffer;
    Close();

    LOG(VB_RECORD, LOG_INFO, LOC + "run(): " + "end");

    SetRunning(false, true, false);
    RunEpilog();
}
Example #21
0
/** \fn HDHRStreamHandler::run(void)
 *  \brief Reads HDHomeRun socket for tables & data
 */
void HDHRStreamHandler::run(void)
{
    RunProlog();
    /* Create TS socket. */
    if (!hdhomerun_device_stream_start(_hdhomerun_device))
    {
        LOG(VB_GENERAL, LOG_ERR, LOC +
            "Starting recording (set target failed). Aborting.");
        _error = true;
        RunEpilog();
        return;
    }
    hdhomerun_device_stream_flush(_hdhomerun_device);

    SetRunning(true, false, false);

    LOG(VB_RECORD, LOG_INFO, LOC + "RunTS(): begin");

    int remainder = 0;
    QTime last_update;
    while (_running_desired && !_error)
    {
        int elapsed = !last_update.isValid() ? -1 : last_update.elapsed();
        elapsed = (elapsed < 0) ? 1000 : elapsed;
        if (elapsed > 100)
        {
            UpdateFiltersFromStreamData();
            if (_tune_mode != hdhrTuneModeVChannel)
                UpdateFilters();
            last_update.restart();
        }

        size_t read_size = 64 * 1024; // read about 64KB
        read_size /= VIDEO_DATA_PACKET_SIZE;
        read_size *= VIDEO_DATA_PACKET_SIZE;

        size_t data_length;
        unsigned char *data_buffer = hdhomerun_device_stream_recv(
            _hdhomerun_device, read_size, &data_length);

        if (!data_buffer)
        {
            usleep(20000);
            continue;
        }

        // Assume data_length is a multiple of 188 (packet size)

        _listener_lock.lock();

        if (_stream_data_list.empty())
        {
            _listener_lock.unlock();
            continue;
        }

        StreamDataList::const_iterator sit = _stream_data_list.begin();
        for (; sit != _stream_data_list.end(); ++sit)
            remainder = sit.key()->ProcessData(data_buffer, data_length);

        _listener_lock.unlock();
        if (remainder != 0)
        {
            LOG(VB_RECORD, LOG_INFO, LOC +
                QString("RunTS(): data_length = %1 remainder = %2")
                    .arg(data_length).arg(remainder));
        }
    }
    LOG(VB_RECORD, LOG_INFO, LOC + "RunTS(): " + "shutdown");

    RemoveAllPIDFilters();

    hdhomerun_device_stream_stop(_hdhomerun_device);
    LOG(VB_RECORD, LOG_INFO, LOC + "RunTS(): " + "end");

    SetRunning(false, false, false);
    RunEpilog();
}
Example #22
0
void MetadataDownload::run()
{
    RunProlog();

    MetadataLookup* lookup;
    while ((lookup = moreWork()) != NULL)
    {
        MetadataLookupList list;
        // Go go gadget Metadata Lookup
        if (lookup->GetType() == kMetadataVideo)
        {
            if (lookup->GetSubtype() == kProbableTelevision)
                list = handleTelevision(lookup);
            else if (lookup->GetSubtype() == kProbableMovie)
                list = handleMovie(lookup);
            else
                list = handleVideoUndetermined(lookup);

            if (!list.size() &&
                lookup->GetSubtype() == kUnknownVideo)
            {
                list = handleMovie(lookup);
            }
        }
        else if (lookup->GetType() == kMetadataRecording)
        {
            if (lookup->GetSubtype() == kProbableTelevision)
            {
                if (lookup->GetSeason() > 0 || lookup->GetEpisode() > 0)
                    list = handleTelevision(lookup);
                else if (!lookup->GetSubtitle().isEmpty())
                    list = handleVideoUndetermined(lookup);

                if (!list.size())
                    list = handleRecordingGeneric(lookup);
            }
            else if (lookup->GetSubtype() == kProbableMovie)
            {
                list = handleMovie(lookup);
                if (lookup->GetInetref().isEmpty())
                    list.append(handleRecordingGeneric(lookup));
            }
            else
            {
                list = handleRecordingGeneric(lookup);
                if (lookup->GetInetref().isEmpty())
                    list.append(handleMovie(lookup));
            }
        }
        else if (lookup->GetType() == kMetadataGame)
            list = handleGame(lookup);

        // inform parent we have lookup ready for it
        if (m_parent && list.count() >= 1)
        {
            // If there's only one result, don't bother asking
            // our parent about it, just add it to the back of
            // the queue in kLookupData mode.
            if (list.count() == 1 && list.at(0)->GetStep() == kLookupSearch)
            {
                MetadataLookup *newlookup = list.takeFirst();
                newlookup->SetStep(kLookupData);
                prependLookup(newlookup);
                continue;
            }

            // If we're in automatic mode, we need to make
            // these decisions on our own.  Pass to title match.
            if (list.at(0)->GetAutomatic() && list.count() > 1)
            {
                if (!findBestMatch(list, lookup->GetTitle()))
                    QCoreApplication::postEvent(m_parent,
                        new MetadataLookupFailure(MetadataLookupList() << lookup));
                continue;
            }

            LOG(VB_GENERAL, LOG_INFO,
                QString("Returning Metadata Results: %1 %2 %3")
                    .arg(lookup->GetTitle()).arg(lookup->GetSeason())
                    .arg(lookup->GetEpisode()));
            QCoreApplication::postEvent(m_parent,
                new MetadataLookupEvent(list));
        }
        else
        {
            list.append(lookup);
            QCoreApplication::postEvent(m_parent,
                new MetadataLookupFailure(list));
        }
    }

    RunEpilog();
}
Example #23
0
void VideoScannerThread::run()
{
    RunProlog();

    VideoMetadataListManager::metadata_list ml;
    VideoMetadataListManager::loadAllFromDatabase(ml);
    m_dbmetadata->setList(ml);

    QList<QByteArray> image_types = QImageReader::supportedImageFormats();
    QStringList imageExtensions;
    for (QList<QByteArray>::const_iterator p = image_types.begin();
         p != image_types.end(); ++p)
    {
        imageExtensions.push_back(QString(*p));
    }

    LOG(VB_GENERAL, LOG_INFO, QString("Beginning Video Scan."));

    uint counter = 0;
    FileCheckList fs_files;

    if (m_HasGUI)
        SendProgressEvent(counter, (uint)m_directories.size(),
                          tr("Searching for video files"));
    for (QStringList::const_iterator iter = m_directories.begin();
         iter != m_directories.end(); ++iter)
    {
        if (!buildFileList(*iter, imageExtensions, fs_files))
        {
            if (iter->startsWith("myth://"))
            {
                QUrl sgurl = *iter;
                QString host = sgurl.host().toLower();
                QString path = sgurl.path();

                m_liveSGHosts.removeAll(host);

                LOG(VB_GENERAL, LOG_ERR,
                    QString("Failed to scan :%1:").arg(*iter));
            }
        }
        if (m_HasGUI)
            SendProgressEvent(++counter);
    }

    PurgeList db_remove;
    verifyFiles(fs_files, db_remove);
    m_DBDataChanged = updateDB(fs_files, db_remove);

    if (m_DBDataChanged)
    {
        QCoreApplication::postEvent(m_parent,
            new VideoScanChanges(m_addList, m_movList,
                                 m_delList));

        QStringList slist;

        QList<int>::const_iterator i;
        for (i = m_addList.begin(); i != m_addList.end(); ++i)
            slist << QString("added::%1").arg(*i);
        for (i = m_movList.begin(); i != m_movList.end(); ++i)
            slist << QString("moved::%1").arg(*i);
        for (i = m_delList.begin(); i != m_delList.end(); ++i)
            slist << QString("deleted::%1").arg(*i);

        MythEvent me("VIDEO_LIST_CHANGE", slist);

        gCoreContext->SendEvent(me);
    }
    else
        gCoreContext->SendMessage("VIDEO_LIST_NO_CHANGE");

    RunEpilog();
}
void MetadataImageDownload::run()
{
    RunProlog();

    // Always handle thumbnails first, they're higher priority.
    ThumbnailData *thumb;
    while ((thumb = moreThumbs()) != NULL)
    {
        QString sFilename = getDownloadFilename(thumb->title, thumb->url);

        bool exists = QFile::exists(sFilename);
        if (!exists && !thumb->url.isEmpty())
        {
            if (!GetMythDownloadManager()->download(thumb->url, sFilename))
            {
                LOG(VB_GENERAL, LOG_ERR,
                    QString("MetadataImageDownload: failed to download thumbnail from: %1")
                    .arg(thumb->url));

                delete thumb;
                continue;
            }
        }

        // inform parent we have thumbnail ready for it
        if (QFile::exists(sFilename) && m_parent)
        {
            LOG(VB_GENERAL, LOG_DEBUG,
                    QString("Threaded Image Thumbnail Download: %1")
                    .arg(sFilename));
            thumb->url = sFilename;
            QCoreApplication::postEvent(m_parent,
                           new ThumbnailDLEvent(thumb));
        }
        else
            delete thumb;
    }

    MetadataLookup *lookup;
    while ((lookup = moreDownloads()) != NULL)
    {
        DownloadMap downloads = lookup->GetDownloads();
        DownloadMap downloaded;

        for (DownloadMap::iterator i = downloads.begin();
                i != downloads.end(); ++i)
        {
            VideoArtworkType type = i.key();
            ArtworkInfo info = i.value();
            QString filename = getDownloadFilename( type, lookup,
                                   info.url );
            if (lookup->GetHost().isEmpty())
            {
                QString path = getLocalWritePath(lookup->GetType(), type);
                QDir dirPath(path);
                if (!dirPath.exists())
                    if (!dirPath.mkpath(path))
                    {
                        LOG(VB_GENERAL, LOG_ERR,
                            QString("Metadata Image Download: Unable to create "
                                    "path %1, aborting download.").arg(path));
                        QCoreApplication::postEvent(m_parent,
                                    new ImageDLFailureEvent(lookup));
                        continue;
                    }
                QString finalfile = path + "/" + filename;
                QString oldurl = info.url;
                info.url = finalfile;
                if (!QFile::exists(finalfile) || lookup->GetAllowOverwrites())
                {
                    QFile dest_file(finalfile);
                    if (dest_file.exists())
                    {
                        QFileInfo fi(finalfile);
                        GetMythUI()->RemoveFromCacheByFile(fi.fileName());
                        dest_file.remove();
                    }

                    LOG(VB_GENERAL, LOG_INFO,
                        QString("Metadata Image Download: %1 ->%2")
                         .arg(oldurl).arg(finalfile));
                    QByteArray *download = new QByteArray();
                    GetMythDownloadManager()->download(oldurl, download);

                    QImage testImage;
                    bool didLoad = testImage.loadFromData(*download);
                    if (!didLoad)
                    {
                        LOG(VB_GENERAL, LOG_ERR,
                            QString("Tried to write %1, but it appears to be "
                                    "an HTML redirect (filesize %2).")
                                .arg(oldurl).arg(download->size()));
                        delete download;
                        download = NULL;
                        QCoreApplication::postEvent(m_parent,
                                    new ImageDLFailureEvent(lookup));
                        continue;
                    }

                    if (dest_file.open(QIODevice::WriteOnly))
                    {
                        off_t size = dest_file.write(*download,
                                                     download->size());
                        if (size != download->size())
                        {
                            LOG(VB_GENERAL, LOG_ERR,
                                QString("Image Download: Error Writing Image "
                                        "to file: %1").arg(finalfile));
                            QCoreApplication::postEvent(m_parent,
                                        new ImageDLFailureEvent(lookup));
                        }
                        else
                            downloaded.insert(type, info);
                    }

                    delete download;
                }
                else
                    downloaded.insert(type, info);
            }
            else
            {
                QString path = getStorageGroupURL(type, lookup->GetHost());
                QString finalfile = path + filename;
                QString oldurl = info.url;
                info.url = finalfile;
                bool exists = false;
                bool onMaster = false;
                QString resolvedFN;
                if ((lookup->GetHost().toLower() == gCoreContext->GetHostName().toLower()) ||
                    (gCoreContext->IsThisHost(lookup->GetHost())))
                {
                    StorageGroup sg;
                    resolvedFN = sg.FindFile(filename);
                    exists = QFile::exists(resolvedFN);
                    if (!exists)
                    {
                        resolvedFN = getLocalStorageGroupPath(type,
                                                 lookup->GetHost()) + "/" + filename;
                    }
                    onMaster = true;
                }
                else
                    exists = RemoteFile::Exists(finalfile);

                if (!exists || lookup->GetAllowOverwrites())
                {

                    if (exists && !onMaster)
                    {
                        QFileInfo fi(finalfile);
                        GetMythUI()->RemoveFromCacheByFile(fi.fileName());
                        RemoteFile::DeleteFile(finalfile);
                    }
                    else if (exists)
                        QFile::remove(resolvedFN);

                    LOG(VB_GENERAL, LOG_INFO,
                        QString("Metadata Image Download: %1 -> %2")
                            .arg(oldurl).arg(finalfile));
                    QByteArray *download = new QByteArray();
                    GetMythDownloadManager()->download(oldurl, download);

                    QImage testImage;
                    bool didLoad = testImage.loadFromData(*download);
                    if (!didLoad)
                    {
                        LOG(VB_GENERAL, LOG_ERR,
                            QString("Tried to write %1, but it appears to be "
                                    "an HTML redirect or corrupt file "
                                    "(filesize %2).")
                                .arg(oldurl).arg(download->size()));
                        delete download;
                        download = NULL;
                        QCoreApplication::postEvent(m_parent,
                                    new ImageDLFailureEvent(lookup));
                        continue;
                    }

                    if (!onMaster)
                    {
                        RemoteFile *outFile = new RemoteFile(finalfile, true);
                        if (!outFile->isOpen())
                        {
                            LOG(VB_GENERAL, LOG_ERR,
                                QString("Image Download: Failed to open "
                                        "remote file (%1) for write.  Does "
                                        "Storage Group Exist?")
                                        .arg(finalfile));
                            delete outFile;
                            outFile = NULL;
                            QCoreApplication::postEvent(m_parent,
                                        new ImageDLFailureEvent(lookup));
                        }
                        else
                        {
                            off_t written = outFile->Write(*download,
                                                           download->size());
                            if (written != download->size())
                            {
                                LOG(VB_GENERAL, LOG_ERR,
                                    QString("Image Download: Error Writing Image "
                                            "to file: %1").arg(finalfile));
                                QCoreApplication::postEvent(m_parent,
                                        new ImageDLFailureEvent(lookup));
                            }
                            else
                                downloaded.insert(type, info);
                            delete outFile;
                            outFile = NULL;
                        }
                    }
                    else
                    {
                        QFile dest_file(resolvedFN);
                        if (dest_file.open(QIODevice::WriteOnly))
                        {
                            off_t size = dest_file.write(*download,
                                                         download->size());
                            if (size != download->size())
                            {
                                LOG(VB_GENERAL, LOG_ERR,
                                    QString("Image Download: Error Writing Image "
                                            "to file: %1").arg(finalfile));
                                QCoreApplication::postEvent(m_parent,
                                            new ImageDLFailureEvent(lookup));
                            }
                            else
                                downloaded.insert(type, info);
                        }
                    }

                    delete download;
                }
                else
                    downloaded.insert(type, info);
            }
        }
        lookup->SetDownloads(downloaded);
        QCoreApplication::postEvent(m_parent, new ImageDLEvent(lookup));
    }

    RunEpilog();
}
Example #25
0
/** \fn     ImageScanThread::run()
 *  \brief  Called when the thread is started. Loads all storage groups files
 *          and directories and also from the database and syncronizes them.
 *  \return void
 */
void ImageScanThread::run()
{
    RunProlog();

    if (!m_continue)
    {
        LOG(VB_GENERAL, LOG_DEBUG,
            QString("Image scanning thread not allowed to start."));
        return;
    }

    LOG(VB_GENERAL, LOG_DEBUG, "Syncronisation started");

    m_progressCount       = 0;
    m_progressTotalCount  = 0;
    
    // Load all available directories and files from the database so that
    // they can be compared against the ones on the filesystem.
    ImageUtils *iu = ImageUtils::getInstance();
    iu->LoadDirectoriesFromDB(m_dbDirList);
    iu->LoadFilesFromDB(m_dbFileList);

    QStringList paths = iu->GetStorageDirs();

    // Get the total list of directories that will be synced.
    // This is only an additional information that the themer can show.
    for (int i = 0; i < paths.size(); ++i)
    {
        QString path = paths.at(i);
        QDirIterator it(path, QDirIterator::Subdirectories);

        while(it.hasNext())
        {
            it.next();
            ++m_progressTotalCount;
        }
    }

    // Now start the actual syncronization
    for (int i = 0; i < paths.size(); ++i)
    {
        QString path = paths.at(i);
        QString base = path;
        if (!base.endsWith('/'))
            base.append('/');
        SyncFilesFromDir(path, 0, base);
    }

    // Adding or updating directories have been completed.
    // The directory list still contains the remaining directories
    // that are not in the filesystem anymore. Remove them from the database
    QMap<QString, ImageMetadata *>::iterator i;
    for (i = m_dbDirList->begin(); i != m_dbDirList->end(); ++i)
    {
        iu->RemoveDirectoryFromDB(m_dbDirList->value(i.key()));
    }

    // Repeat the same for the file list.
    for (i = m_dbFileList->begin(); i != m_dbFileList->end(); ++i)
    {
        iu->RemoveFileFromDB(m_dbFileList->value(i.key()));
    }

    m_continue = false;
    m_progressCount       = 0;
    m_progressTotalCount  = 0;

    LOG(VB_GENERAL, LOG_DEBUG, "Syncronisation complete");

    RunEpilog();
}
void ThumbGenerator::run()
{
    RunProlog();

    m_cancel = false;
    while (moreWork() && !m_cancel)
    {
        QString file, dir;
        bool    isGallery;

        m_mutex.lock();
        dir       = m_directory;
        isGallery = m_isGallery;
        file = m_fileList.first();
        if (!m_fileList.isEmpty())
            m_fileList.pop_front();
        m_mutex.unlock();
        if (file.isEmpty())
            continue;

        QString   filePath = dir + QString("/") + file;
        QFileInfo fileInfo(filePath);
        if (!fileInfo.exists())
            continue;

        if (isGallery)
        {
            if (fileInfo.isDir())
                isGallery = checkGalleryDir(fileInfo);
            else
                isGallery = checkGalleryFile(fileInfo);
        }

        if (!isGallery)
        {
            QString cachePath = QString("%1%2.jpg").arg(getThumbcacheDir(dir))
                                                   .arg(file);
            QFileInfo cacheInfo(cachePath);

            if (cacheInfo.exists() &&
                cacheInfo.lastModified() >= fileInfo.lastModified())
            {
                continue;
            }
            else
            {
                // cached thumbnail not there or out of date
                QImage image;

                // Remove the old one if it exists
                if (cacheInfo.exists())
                    QFile::remove(cachePath);

                if (fileInfo.isDir())
                    loadDir(image, fileInfo);
                else
                    loadFile(image, fileInfo);

                if (image.isNull())
                    continue; // give up;

                // if the file is a movie save the image to use as a screenshot
                if (GalleryUtil::IsMovie(fileInfo.filePath()))
                {
                    QString screenshotPath = QString("%1%2-screenshot.jpg")
                            .arg(getThumbcacheDir(dir))
                            .arg(file);
                    image.save(screenshotPath, "JPEG", 95);
                }

                image = image.scaled(m_width,m_height,
                                Qt::KeepAspectRatio, Qt::SmoothTransformation);
                image.save(cachePath, "JPEG", 95);

                // deep copies all over
                ThumbData *td = new ThumbData;
                td->directory = dir;
                td->fileName  = file;
                td->thumb     = image.copy();

                // inform parent we have thumbnail ready for it
                QApplication::postEvent(m_parent, new ThumbGenEvent(td));

            }
        }
    }

    RunEpilog();
}
Example #27
0
void MetadataImageDownload::run()
{
    RunProlog();

    // Always handle thumbnails first, they're higher priority.
    ThumbnailData *thumb;
    while ((thumb = moreThumbs()) != NULL)
    {
        QString sFilename = getDownloadFilename(thumb->title, thumb->url);

        bool exists = QFile::exists(sFilename);
        if (!exists && !thumb->url.isEmpty())
        {
            if (!GetMythDownloadManager()->download(thumb->url, sFilename))
            {
                LOG(VB_GENERAL, LOG_ERR,
                    QString("MetadataImageDownload: failed to download thumbnail from: %1")
                    .arg(thumb->url));

                delete thumb;
                continue;
            }
        }

        // inform parent we have thumbnail ready for it
        if (QFile::exists(sFilename) && m_parent)
        {
            LOG(VB_GENERAL, LOG_DEBUG,
                QString("Threaded Image Thumbnail Download: %1")
                .arg(sFilename));
            thumb->url = sFilename;
            QCoreApplication::postEvent(m_parent,
                                        new ThumbnailDLEvent(thumb));
        }
        else
            delete thumb;
    }

    while (true)
    {
        m_mutex.lock();
        if (m_downloadList.isEmpty())
        {
            // no more to process, we're done
            m_mutex.unlock();
            break;
        }
        // Ref owns the MetadataLookup object for the duration of the loop
        // and it will be deleted automatically when the loop completes
        RefCountHandler<MetadataLookup> ref = m_downloadList.takeFirstAndDecr();
        m_mutex.unlock();
        MetadataLookup *lookup = ref;
        DownloadMap downloads = lookup->GetDownloads();
        DownloadMap downloaded;

        bool errored = false;
        for (DownloadMap::iterator i = downloads.begin();
                i != downloads.end(); ++i)
        {
            VideoArtworkType type = i.key();
            ArtworkInfo info = i.value();
            QString filename = getDownloadFilename( type, lookup,
                                                    info.url );
            if (lookup->GetHost().isEmpty())
            {
                QString path = getLocalWritePath(lookup->GetType(), type);
                QDir dirPath(path);
                if (!dirPath.exists())
                {
                    if (!dirPath.mkpath(path))
                    {
                        LOG(VB_GENERAL, LOG_ERR,
                            QString("Metadata Image Download: Unable to create "
                                    "path %1, aborting download.").arg(path));
                        errored = true;
                        break;
                    }
                }
                QString finalfile = path + "/" + filename;
                QString oldurl = info.url;
                info.url = finalfile;
                if (!QFile::exists(finalfile) || lookup->GetAllowOverwrites())
                {
                    QFile dest_file(finalfile);
                    if (dest_file.exists())
                    {
                        QFileInfo fi(finalfile);
                        GetMythUI()->RemoveFromCacheByFile(fi.fileName());
                        dest_file.remove();
                    }

                    LOG(VB_GENERAL, LOG_INFO,
                        QString("Metadata Image Download: %1 ->%2")
                        .arg(oldurl).arg(finalfile));
                    QByteArray download;
                    GetMythDownloadManager()->download(oldurl, &download);

                    QImage testImage;
                    bool didLoad = testImage.loadFromData(download);
                    if (!didLoad)
                    {
                        LOG(VB_GENERAL, LOG_ERR,
                            QString("Tried to write %1, but it appears to be "
                                    "an HTML redirect (filesize %2).")
                            .arg(oldurl).arg(download.size()));
                        errored = true;
                        break;
                    }

                    if (dest_file.open(QIODevice::WriteOnly))
                    {
                        off_t size = dest_file.write(download,
                                                     download.size());
                        dest_file.close();
                        if (size != download.size())
                        {
                            // File creation failed for some reason, delete it
                            RemoteFile::DeleteFile(finalfile);
                            LOG(VB_GENERAL, LOG_ERR,
                                QString("Image Download: Error Writing Image "
                                        "to file: %1").arg(finalfile));
                            errored = true;
                            break;
                        }
                    }
                }
            }
            else
            {
                QString path = getStorageGroupURL(type, lookup->GetHost());
                QString finalfile = path + filename;
                QString oldurl = info.url;
                info.url = finalfile;
                bool exists = false;
                bool onMaster = false;
                QString resolvedFN;
                if (gCoreContext->IsMasterBackend() &&
                        gCoreContext->IsThisHost(lookup->GetHost()))
                {
                    StorageGroup sg(getStorageGroupName(type), lookup->GetHost());
                    resolvedFN = sg.FindFile(filename);
                    exists = !resolvedFN.isEmpty() && QFile::exists(resolvedFN);
                    if (!exists)
                    {
                        resolvedFN = getLocalStorageGroupPath(type,
                                                              lookup->GetHost()) + "/" + filename;
                    }
                    onMaster = true;
                }
                else
                    exists = RemoteFile::Exists(finalfile);

                if (!exists || lookup->GetAllowOverwrites())
                {
                    if (exists && !onMaster)
                    {
                        QFileInfo fi(finalfile);
                        GetMythUI()->RemoveFromCacheByFile(fi.fileName());
                        RemoteFile::DeleteFile(finalfile);
                    }
                    else if (exists)
                        QFile::remove(resolvedFN);

                    LOG(VB_GENERAL, LOG_INFO,
                        QString("Metadata Image Download: %1 -> %2")
                        .arg(oldurl).arg(finalfile));
                    QByteArray download;
                    GetMythDownloadManager()->download(oldurl, &download);

                    QImage testImage;
                    bool didLoad = testImage.loadFromData(download);
                    if (!didLoad)
                    {
                        LOG(VB_GENERAL, LOG_ERR,
                            QString("Tried to write %1, but it appears to be "
                                    "an HTML redirect or corrupt file "
                                    "(filesize %2).")
                            .arg(oldurl).arg(download.size()));
                        errored = true;
                        break;
                    }

                    if (!onMaster)
                    {
                        RemoteFile outFile(finalfile, true);

                        if (!outFile.isOpen())
                        {
                            LOG(VB_GENERAL, LOG_ERR,
                                QString("Image Download: Failed to open "
                                        "remote file (%1) for write.  Does "
                                        "Storage Group Exist?")
                                .arg(finalfile));
                            errored = true;
                            break;
                        }
                        off_t written = outFile.Write(download,
                                                      download.size());
                        if (written != download.size())
                        {
                            // File creation failed for some reason, delete it
                            RemoteFile::DeleteFile(finalfile);

                            LOG(VB_GENERAL, LOG_ERR,
                                QString("Image Download: Error Writing Image "
                                        "to file: %1").arg(finalfile));
                            errored = true;
                            break;
                        }
                    }
                    else
                    {
                        QFile dest_file(resolvedFN);
                        if (dest_file.open(QIODevice::WriteOnly))
                        {
                            off_t size = dest_file.write(download,
                                                         download.size());
                            dest_file.close();
                            if (size != download.size())
                            {
                                // File creation failed for some reason, delete it
                                RemoteFile::DeleteFile(resolvedFN);
                                LOG(VB_GENERAL, LOG_ERR,
                                    QString("Image Download: Error Writing Image "
                                            "to file: %1").arg(finalfile));
                                errored = true;
                                break;
                            }
                        }
                    }
                }
            }
            if (!errored)
            {
                // update future Artwork Map with what we've successfully
                // retrieved (either downloaded or already existing
                downloaded.insert(type, info);
            }
        }
        if (errored)
        {
            QCoreApplication::postEvent(m_parent,
                                        new ImageDLFailureEvent(lookup));
            errored = false;
        }
        lookup->SetDownloads(downloaded);
        QCoreApplication::postEvent(m_parent, new ImageDLEvent(lookup));
    }

    RunEpilog();
}
Example #28
0
/// \brief Runs ThreadedFileWriter::DiskLoop(void)
void TFWWriteThread::run(void)
{
    RunProlog();
    m_parent->DiskLoop();
    RunEpilog();
}
Example #29
0
void FileScannerThread::run()
{
    RunProlog();
    m_parent->doScan();
    RunEpilog();
}
Example #30
0
/// \brief Runs ThreadedFileWriter::SyncLoop(void)
void TFWSyncThread::run(void)
{
    RunProlog();
    m_parent->SyncLoop();
    RunEpilog();
}