Beispiel #1
0
static int SendMessage(const MythUtilCommandLineParser &cmdline)
{
    QHostAddress address = QHostAddress::Broadcast;
    unsigned short port = 6948;

    QString message = kMessage;

    if (cmdline.toBool("udpport"))
        port = (unsigned short)cmdline.toUInt("udpport");
    if (cmdline.toBool("bcastaddr"))
        address.setAddress(cmdline.toString("bcastaddr"));

    QMap<QString,QString>::const_iterator i;
    QMap<QString,QString> extras = cmdline.GetExtra();
    for (i = extras.begin(); i != extras.end(); ++i)
    {
        QString name = i.key();
        QString value = i.value();

        name.replace("--", "");
        cerr << "name: " << name.toLocal8Bit().constData()
             << " -- value: " << value.toLocal8Bit().constData() << endl;

        name.append("%");
        name.prepend("%");
        message.replace(name, value);
    }

    cout << "output:\n" << message.toLocal8Bit().constData() << endl;

    QUdpSocket *sock = new QUdpSocket();
    QByteArray utf8 = message.toUtf8();

    int result = GENERIC_EXIT_OK;
    if (sock->writeDatagram(utf8, address, port) < 0)
    {
        cout << "Failed to send UDP/XML packet" << endl;
        result = GENERIC_EXIT_NOT_OK;
    }
    else
    {
        cout << "Sent UDP/XML packet to IP "
             << address.toString().toLocal8Bit().constData()
             << " and port: " << port << endl;
    }

    sock->deleteLater();
   
    return result;
}
Beispiel #2
0
static int ParseVideoFilename(const MythUtilCommandLineParser &cmdline)
{
    QString filename = cmdline.toString("parsevideo");
    cout << "Title:    " << VideoMetadata::FilenameToMeta(filename, 1)
                                            .toLocal8Bit().constData() << endl
         << "Season:   " << VideoMetadata::FilenameToMeta(filename, 2)
                                            .toLocal8Bit().constData() << endl
         << "Episode:  " << VideoMetadata::FilenameToMeta(filename, 3)
                                            .toLocal8Bit().constData() << endl
         << "Subtitle: " << VideoMetadata::FilenameToMeta(filename, 4)
                                            .toLocal8Bit().constData() << endl;

    return GENERIC_EXIT_OK;
}
Beispiel #3
0
bool GetProgramInfo(const MythUtilCommandLineParser &cmdline,
                    ProgramInfo &pginfo)
{
    if (cmdline.toBool("video"))
    {
        QString video = cmdline.toString("video");
        pginfo = ProgramInfo(video);
        return true;
    }
    if (!cmdline.toBool("chanid"))
    {
        LOG(VB_GENERAL, LOG_ERR, "No chanid specified");
        return false;
    }

    if (!cmdline.toBool("starttime"))
    {
        LOG(VB_GENERAL, LOG_ERR, "No start time specified");
        return false;
    }

    uint chanid = cmdline.toUInt("chanid");
    QDateTime starttime = cmdline.toDateTime("starttime");
    QString startstring = starttime.toString("yyyyMMddhhmmss");

    const ProgramInfo tmpInfo(chanid, starttime);

    if (!tmpInfo.GetChanID())
    {
        LOG(VB_GENERAL, LOG_ERR,
            QString("No program data exists for channel %1 at %2")
                .arg(chanid).arg(startstring));
        return false;
    }

    pginfo = tmpInfo;

    return true;
}
Beispiel #4
0
static int SetSkipList(const MythUtilCommandLineParser &cmdline)
{
    return SetMarkupList(cmdline, QString("skiplist"),
                         cmdline.toString("setskiplist"));
}
Beispiel #5
0
int main(int argc, char *argv[])
{
    MythUtilCommandLineParser cmdline;
    if (!cmdline.Parse(argc, argv))
    {
        cmdline.PrintHelp();
        return GENERIC_EXIT_INVALID_CMDLINE;
    }

    // default to quiet operation for pidcounter and pidfilter
    QString defaultVerbose = "general";
    LogLevel_t defaultLevel = LOG_INFO;
    if (cmdline.toBool("pidcounter") || cmdline.toBool("pidfilter"))
    {
        if (!cmdline.toBool("verbose"))
        {
            verboseString = defaultVerbose = "";
            verboseMask = 0;
        }
        if (!cmdline.toBool("loglevel"))
            logLevel = defaultLevel = LOG_ERR;
    }


    if (cmdline.toBool("showhelp"))
    {
        cmdline.PrintHelp();
        return GENERIC_EXIT_OK;
    }

    if (cmdline.toBool("showversion"))
    {
        cmdline.PrintVersion();
        return GENERIC_EXIT_OK;
    }

#ifndef _WIN32
    QCoreApplication a(argc, argv);
#else
    // MINGW application needs a window to receive messages
    // such as socket notifications :[
    QApplication a(argc, argv);
#endif

    QCoreApplication::setApplicationName(MYTH_APPNAME_MYTHUTIL);

    int retval;
    if ((retval = cmdline.ConfigureLogging(defaultVerbose)) != GENERIC_EXIT_OK)
        return retval;

    if (!cmdline.toBool("loglevel"))
        logLevel = defaultLevel;

#ifndef _WIN32
    QList<int> signallist;
    signallist << SIGINT << SIGTERM << SIGSEGV << SIGABRT;
    SignalHandler handler(signallist);
    signal(SIGHUP, SIG_IGN);
#endif

    gContext = new MythContext(MYTH_BINARY_VERSION);
    if (!gContext->Init(false))
    {
        LOG(VB_GENERAL, LOG_ERR, "Failed to init MythContext, exiting.");
        return GENERIC_EXIT_NO_MYTHCONTEXT;
    }

    cmdline.ApplySettingsOverride();

    UtilMap utilMap;

    registerBackendUtils(utilMap);
    registerFileUtils(utilMap);
    registerMPEGUtils(utilMap);
    registerJobUtils(utilMap);
    registerMarkupUtils(utilMap);
    registerMessageUtils(utilMap);

    bool cmdFound = false;
    int cmdResult = GENERIC_EXIT_OK;
    UtilMap::iterator i;
    for (i = utilMap.begin(); i != utilMap.end(); ++i)
    {
        if (cmdline.toBool(i.key()))
        {
            cmdResult = (i.value())(cmdline);
            cmdFound = true;
            break;
        }
    }

    if(!cmdFound)
    {
        cmdline.PrintHelp();
        cmdResult = GENERIC_EXIT_INVALID_CMDLINE;
    }

    delete gContext;

    return cmdResult;
}
Beispiel #6
0
static int QueueJob(const MythUtilCommandLineParser &cmdline)
{
    ProgramInfo pginfo;
    if (!GetProgramInfo(cmdline, pginfo))
        return GENERIC_EXIT_NO_RECORDING_DATA;

    bool rebuildSeektable = false;
    int jobType = JOB_NONE;

    if (cmdline.toString("queuejob") == "transcode")
        jobType = JOB_TRANSCODE;
    else if (cmdline.toString("queuejob") == "commflag")
        jobType = JOB_COMMFLAG;
    else if (cmdline.toString("queuejob") == "rebuild")
    {
        jobType = JOB_COMMFLAG;
        rebuildSeektable = true;
    }
    else if (cmdline.toString("queuejob") == "metadata")
        jobType = JOB_METADATA;
    else if (cmdline.toString("queuejob") == "userjob1")
        jobType = JOB_USERJOB1;
    else if (cmdline.toString("queuejob") == "userjob2")
        jobType = JOB_USERJOB1;
    else if (cmdline.toString("queuejob") == "userjob4")
        jobType = JOB_USERJOB1;
    else if (cmdline.toString("queuejob") == "userjob4")
        jobType = JOB_USERJOB1;
    else if (cmdline.toInt("queuejob") > 0)
        jobType = cmdline.toInt("queuejob");

    if (jobType == JOB_NONE)
    {
        LOG(VB_GENERAL, LOG_ERR,
            "Error, invalid job type given with queuejob option");
        return GENERIC_EXIT_INVALID_CMDLINE;
    }

    bool result = JobQueue::QueueJob(jobType,
                                     pginfo.GetChanID(), pginfo.GetRecordingStartTime(), "", "", "",
                                     rebuildSeektable, JOB_QUEUED, QDateTime());

    if (result)
    {
        QString tmp = QString("%1 Job Queued for chanid %2 @ %3")
                      .arg(cmdline.toString("queuejob"))
                      .arg(pginfo.GetChanID())
                      .arg(pginfo.GetRecordingStartTime().toString());
        cerr << tmp.toLocal8Bit().constData() << endl;
        return GENERIC_EXIT_OK;
    }

    QString tmp = QString("Error queueing job for chanid %1 @ %2")
                  .arg(pginfo.GetChanID())
                  .arg(pginfo.GetRecordingStartTime().toString());
    cerr << tmp.toLocal8Bit().constData() << endl;
    return GENERIC_EXIT_DB_ERROR;
}
Beispiel #7
0
static int SendSystemEvent(const MythUtilCommandLineParser &cmdline)
{
    return RawSendEvent(QStringList(QString("SYSTEM_EVENT %1 SENDER %2")
                                    .arg(cmdline.toString("systemevent"))
                                    .arg(gCoreContext->GetHostName())));
}
Beispiel #8
0
static int SendEvent(const MythUtilCommandLineParser &cmdline)
{
    return RawSendEvent(cmdline.toStringList("event"));
}
Beispiel #9
0
static int ExtractImage(const MythUtilCommandLineParser &cmdline)
{
    if (cmdline.toString("songid").isEmpty())
    {
        LOG(VB_GENERAL, LOG_ERR, "Missing --songid option");
        return GENERIC_EXIT_INVALID_CMDLINE;
    }

    if (cmdline.toString("imagetype").isEmpty())
    {
        LOG(VB_GENERAL, LOG_ERR, "Missing --imagetype option");
        return GENERIC_EXIT_INVALID_CMDLINE;
    }

    int songID = cmdline.toInt("songid");
    ImageType type = (ImageType)cmdline.toInt("imagetype");

    MusicMetadata *mdata = MusicMetadata::createFromID(songID);
    if (!mdata)
    {
        LOG(VB_GENERAL, LOG_ERR, QString("Cannot find metadata for trackid: %1").arg(songID));
        return GENERIC_EXIT_NOT_OK;
    }

    AlbumArtImage *image = mdata->getAlbumArtImages()->getImage(type);
    if (!image)
    {
        LOG(VB_GENERAL, LOG_ERR, QString("Cannot find image of type: %1").arg(type));
        return GENERIC_EXIT_NOT_OK;
    }

    MetaIO *tagger = mdata->getTagger();
    if (!tagger)
    {
        LOG(VB_GENERAL, LOG_ERR, QString("Cannot find a tagger for this file: %1").arg(mdata->Filename(false)));
        return GENERIC_EXIT_NOT_OK;
    }


    if (!image->embedded || !tagger->supportsEmbeddedImages())
    {
        LOG(VB_GENERAL, LOG_ERR, QString("Either the image isn't embedded or the tagger doesn't support embedded images"));
        return GENERIC_EXIT_NOT_OK;
    }

    // find the tracks actual filename
    StorageGroup musicGroup("Music", gCoreContext->GetHostName(), false);
    QString trackFilename =  musicGroup.FindFile(mdata->Filename(false));

    // where are we going to save the image
    QString path;
    StorageGroup artGroup("MusicArt", gCoreContext->GetHostName(), false);
    QStringList dirList = artGroup.GetDirList();
    if (dirList.size())
        path = artGroup.FindNextDirMostFree();

    if (!QDir(path).exists())
    {
        LOG(VB_GENERAL, LOG_ERR, "Cannot find a directory in the 'MusicArt' storage group to save to");
        return GENERIC_EXIT_NOT_OK;
    }

    path += "/AlbumArt/";
    QDir dir(path);

    QString filename = QString("%1-%2.jpg").arg(mdata->ID()).arg(AlbumArtImages::getTypeFilename(image->imageType));

    if (QFile::exists(path + filename))
        QFile::remove(path + filename);

    if (!dir.exists())
        dir.mkpath(path);

    QImage *saveImage = tagger->getAlbumArt(trackFilename, image->imageType);
    if (saveImage)
    {
        saveImage->save(path + filename, "JPEG");
        delete saveImage;
    }

    delete tagger;

    // tell any clients that the albumart for this track has changed
    gCoreContext->SendMessage(QString("MUSIC_ALBUMART_CHANGED %1 %2").arg(songID).arg(type));

    return GENERIC_EXIT_OK;
}
Beispiel #10
0
static int UpdateMeta(const MythUtilCommandLineParser &cmdline)
{
    bool ok = true;
    int result = GENERIC_EXIT_OK;

    if (cmdline.toString("songid").isEmpty())
    {
        LOG(VB_GENERAL, LOG_ERR, "Missing --songid option");
        return GENERIC_EXIT_INVALID_CMDLINE;
    }
    int songID = cmdline.toInt("songid");

    MusicMetadata *mdata = MusicMetadata::createFromID(songID);
    if (!mdata)
    {
        LOG(VB_GENERAL, LOG_ERR, QString("Cannot find metadata for trackid: %1").arg(songID));
        return GENERIC_EXIT_NOT_OK;
    }

    if (!cmdline.toString("title").isEmpty())
        mdata->setTitle(cmdline.toString("title"));

    if (!cmdline.toString("artist").isEmpty())
        mdata->setArtist(cmdline.toString("artist"));

    if (!cmdline.toString("album").isEmpty())
        mdata->setAlbum(cmdline.toString("album"));

    if (!cmdline.toString("genre").isEmpty())
        mdata->setGenre(cmdline.toString("genre"));

    if (!cmdline.toString("trackno").isEmpty())
        mdata->setTrack(cmdline.toInt("trackno"));

    if (!cmdline.toString("year").isEmpty())
        mdata->setYear(cmdline.toInt("year"));

    if (!cmdline.toString("rating").isEmpty())
        mdata->setRating(cmdline.toInt("rating"));

    if (!cmdline.toString("playcount").isEmpty())
        mdata->setPlaycount(cmdline.toInt("playcount"));

    if (!cmdline.toString("lastplayed").isEmpty())
        mdata->setLastPlay(cmdline.toDateTime("lastplayed"));

    mdata->dumpToDatabase();

    MetaIO *tagger = mdata->getTagger();
    if (tagger)
    {
        ok = tagger->write(mdata->getLocalFilename(), mdata);

        if (!ok)
            LOG(VB_GENERAL, LOG_ERR, QString("Failed to write to tag for trackid: %1").arg(songID));
    }

    // tell any clients that the metadata for this track has changed
    gCoreContext->SendMessage(QString("MUSIC_METADATA_CHANGED %1").arg(songID));

    if (!ok)
        result = GENERIC_EXIT_NOT_OK;

    return result;
}
Beispiel #11
0
static int CalcTrackLength(const MythUtilCommandLineParser &cmdline)
{
    if (cmdline.toString("songid").isEmpty())
    {
        LOG(VB_GENERAL, LOG_ERR, "Missing --songid option");
        return GENERIC_EXIT_INVALID_CMDLINE;
    }

    int songID = cmdline.toInt("songid");

    MusicMetadata *mdata = MusicMetadata::createFromID(songID);
    if (!mdata)
    {
        LOG(VB_GENERAL, LOG_ERR, QString("Cannot find metadata for trackid: %1").arg(songID));
        return GENERIC_EXIT_NOT_OK;
    }

    QString musicFile = mdata->getLocalFilename();

    if (musicFile.isEmpty() || !QFile::exists(musicFile))
    {
        LOG(VB_GENERAL, LOG_ERR, QString("Cannot find file for trackid: %1").arg(songID));
        return GENERIC_EXIT_NOT_OK;
    }

    av_register_all();

    AVFormatContext *inputFC = NULL;
    AVInputFormat *fmt = NULL;

    // Open track
    LOG(VB_GENERAL, LOG_DEBUG, QString("CalcTrackLength: Opening '%1'")
            .arg(musicFile));

    QByteArray inFileBA = musicFile.toLocal8Bit();

    int ret = avformat_open_input(&inputFC, inFileBA.constData(), fmt, NULL);

    if (ret)
    {
        LOG(VB_GENERAL, LOG_ERR, "CalcTrackLength: Couldn't open input file" +
                                  ENO);
        return GENERIC_EXIT_NOT_OK;
    }

    // Getting stream information
    ret = avformat_find_stream_info(inputFC, NULL);

    if (ret < 0)
    {
        LOG(VB_GENERAL, LOG_ERR,
            QString("CalcTrackLength: Couldn't get stream info, error #%1").arg(ret));
        avformat_close_input(&inputFC);
        inputFC = NULL;
        return GENERIC_EXIT_NOT_OK;;
    }

    int duration = 0;
    long long time = 0;

    for (uint i = 0; i < inputFC->nb_streams; i++)
    {
        AVStream *st = inputFC->streams[i];
        char buf[256];

        avcodec_string(buf, sizeof(buf), st->codec, false);

        switch (inputFC->streams[i]->codec->codec_type)
        {
            case AVMEDIA_TYPE_AUDIO:
            {
                AVPacket pkt;
                av_init_packet(&pkt);

                while (av_read_frame(inputFC, &pkt) >= 0)
                {
                    if (pkt.stream_index == (int)i)
                        time = time + pkt.duration;

                    av_free_packet(&pkt);
                }

                duration = time * av_q2d(inputFC->streams[i]->time_base);
                break;
            }

            default:
                LOG(VB_GENERAL, LOG_ERR,
                    QString("Skipping unsupported codec %1 on stream %2")
                        .arg(inputFC->streams[i]->codec->codec_type).arg(i));
                break;
        }
    }

    // Close input file
    avformat_close_input(&inputFC);
    inputFC = NULL;

    if (mdata->Length() / 1000 != duration)
    {
        LOG(VB_GENERAL, LOG_INFO, QString("The length of this track in the database was %1s "
                                          "it is now %2s").arg(mdata->Length() / 1000).arg(duration));

        // update the track length in the database
        mdata->setLength(duration * 1000);
        mdata->dumpToDatabase();

        // tell any clients that the metadata for this track has changed
        gCoreContext->SendMessage(QString("MUSIC_METADATA_CHANGED %1").arg(songID));
    }
    else
    {
        LOG(VB_GENERAL, LOG_INFO, QString("The length of this track is unchanged %1s")
                                          .arg(mdata->Length() / 1000));
    }

    return GENERIC_EXIT_OK;
}