int main( int argc, const char** argv ) { daemon_active = true; bool noDaemon = false; bool clockOn = false; std::string logFile; int topn; std::string configFile; std::string country; TCLAP::CmdLine cmd("OpenAlpr Daemon", ' ', Alpr::getVersion()); TCLAP::ValueArg<std::string> countryCodeArg("c","country","Country code to identify (either us for USA or eu for Europe). Default=us",false, "us" ,"country_code"); TCLAP::ValueArg<std::string> configFileArg("","config","Path to the openalpr.conf file.",false, "" ,"config_file"); TCLAP::ValueArg<int> topNArg("n","topn","Max number of possible plate numbers to return. Default=25",false, 25 ,"topN"); TCLAP::ValueArg<std::string> logFileArg("l","log","Log file to write to. Default=" + DEFAULT_LOG_FILE_PATH,false, DEFAULT_LOG_FILE_PATH ,"topN"); TCLAP::SwitchArg daemonOffSwitch("f","foreground","Set this flag for debugging. Disables forking the process as a daemon and runs in the foreground. Default=off", cmd, false); TCLAP::SwitchArg clockSwitch("","clock","Display timing information to log. Default=off", cmd, false); try { cmd.add( countryCodeArg ); cmd.add( topNArg ); cmd.add( configFileArg ); cmd.add( logFileArg ); if (cmd.parse( argc, argv ) == false) { // Error occured while parsing. Exit now. return 1; } country = countryCodeArg.getValue(); configFile = configFileArg.getValue(); logFile = logFileArg.getValue(); topn = topNArg.getValue(); noDaemon = daemonOffSwitch.getValue(); clockOn = clockSwitch.getValue(); } catch (TCLAP::ArgException &e) // catch any exceptions { std::cerr << "error: " << e.error() << " for arg " << e.argId() << std::endl; return 1; } log4cplus::BasicConfigurator config; config.configure(); if (noDaemon == false) { // Fork off into a separate daemon daemon(0, 0); log4cplus::SharedAppenderPtr myAppender(new log4cplus::RollingFileAppender(logFile)); myAppender->setName("alprd_appender"); // Redirect std out to log file logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("alprd")); logger.addAppender(myAppender); LOG4CPLUS_INFO(logger, "Running OpenALPR daemon in daemon mode."); } else { //log4cplus::SharedAppenderPtr myAppender(new log4cplus::ConsoleAppender()); //myAppender->setName("alprd_appender"); // Redirect std out to log file logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("alprd")); //logger.addAppender(myAppender); LOG4CPLUS_INFO(logger, "Running OpenALPR daemon in the foreground."); } CSimpleIniA ini; ini.SetMultiKey(); ini.LoadFile(DAEMON_CONFIG_FILE_PATH.c_str()); std::vector<std::string> stream_urls; CSimpleIniA::TNamesDepend values; ini.GetAllValues("daemon", "stream", values); // sort the values into the original load order values.sort(CSimpleIniA::Entry::LoadOrder()); // output all of the items CSimpleIniA::TNamesDepend::const_iterator i; for (i = values.begin(); i != values.end(); ++i) { stream_urls.push_back(i->pItem); } if (stream_urls.size() == 0) { LOG4CPLUS_FATAL(logger, "No video streams defined in the configuration."); return 1; } bool storePlates = ini.GetBoolValue("daemon", "store_plates", false); std::string imageFolder = ini.GetValue("daemon", "store_plates_location", "/tmp/"); bool uploadData = ini.GetBoolValue("daemon", "upload_data", false); std::string upload_url = ini.GetValue("daemon", "upload_address", ""); std::string site_id = ini.GetValue("daemon", "site_id", ""); LOG4CPLUS_INFO(logger, "Using: " << imageFolder << " for storing valid plate images"); pid_t pid; for (int i = 0; i < stream_urls.size(); i++) { pid = fork(); if (pid == (pid_t) 0) { // This is the child process, kick off the capture data and upload threads CaptureThreadData* tdata = new CaptureThreadData(); tdata->stream_url = stream_urls[i]; tdata->camera_id = i + 1; tdata->config_file = configFile; tdata->output_images = storePlates; tdata->output_image_folder = imageFolder; tdata->country_code = country; tdata->site_id = site_id; tdata->top_n = topn; tdata->clock_on = clockOn; tthread::thread* thread_recognize = new tthread::thread(streamRecognitionThread, (void*) tdata); if (uploadData) { // Kick off the data upload thread UploadThreadData* udata = new UploadThreadData(); udata->upload_url = upload_url; tthread::thread* thread_upload = new tthread::thread(dataUploadThread, (void*) udata ); } break; } // Parent process will continue and spawn more children } while (daemon_active) { usleep(30000); } }
int main(int argc, char *argv[]) { QString title; title = title + " ****************************************************************** \n"; title = title + " * odkdatatomysql 1.0 * \n"; title = title + " * This tool converts ODK data into MySQL. * \n"; title = title + " * The tool uses manifest xml file and ODK xml data file * \n"; title = title + " * Outputs data into a MySQL database and generates a log file * \n"; title = title + " * This tool is part of ODK Tools (c) ILRI, 2014 * \n"; title = title + " ****************************************************************** \n"; TCLAP::CmdLine cmd(title.toLatin1().constData(), ' ', "1.0 (Beta 1)"); //Required arguments TCLAP::ValueArg<std::string> mysqlHostArg("H","mysqlHost","MySQL server host",true,"","string"); TCLAP::ValueArg<std::string> userNameArg("u","userName","MySQL server user name",true,"","string"); TCLAP::ValueArg<std::string> passwordArg("p","password","MySQL server user password",true,"","string"); TCLAP::ValueArg<std::string> schemaArg("s","schema","Schema name in MySQL host",true,"","string"); TCLAP::ValueArg<std::string> manifestMainTableArg("t","manifestMainTable","Manifest main table within the schema",true,"","string"); TCLAP::ValueArg<std::string> manifestMainVariableArg("v","manifestMainVariable","Manifest main variable in main table. Identifies unique record",true,"","string"); TCLAP::ValueArg<std::string> manifestXMLArg("f","manifestXML","ODK manifest XML file",true,"","string"); TCLAP::ValueArg<std::string> datafileXMLArg("d","datafileXML","ODK data XML file",true,"","string"); TCLAP::ValueArg<std::string> datafileBaseNodeArg("b","datafileBaseNode","ODK data file XML base node. Node just after the <?xml version=1.0?>",true,"","string"); TCLAP::ValueArg<std::string> sqlInsertsFileArg("q","sqlInsertsFile","SQL output file. Default ./sqlInsertFile.sql",true,"./sqlInsertFile.sql","string"); TCLAP::ValueArg<std::string> logFileArg("l","logFile","Log file for errors. Default ./logfile.csv",true,"./logFile.csv","string"); TCLAP::ValueArg<std::string> prefixArg("r","prefix","Prefix for each table. _ is added to the prefix. Default no prefix",false,"","string"); cmd.add(mysqlHostArg); cmd.add(userNameArg); cmd.add(passwordArg); cmd.add(schemaArg); cmd.add(manifestMainTableArg); cmd.add(manifestMainVariableArg); cmd.add(manifestXMLArg); cmd.add(datafileXMLArg); cmd.add(datafileBaseNodeArg); cmd.add(sqlInsertsFileArg); cmd.add(logFileArg); cmd.add(prefixArg); //Parsing the command lines cmd.parse( argc, argv ); vMysqlHost = QString::fromUtf8(mysqlHostArg.getValue().c_str()); vUserName = QString::fromUtf8(userNameArg.getValue().c_str()); vPassword = QString::fromUtf8(passwordArg.getValue().c_str()); vSchema = QString::fromUtf8(schemaArg.getValue().c_str()); vManifestMainTable = QString::fromUtf8(manifestMainTableArg.getValue().c_str()); vManifestMainVariable = QString::fromUtf8(manifestMainVariableArg.getValue().c_str()); vManifestXML = QString::fromUtf8(manifestXMLArg.getValue().c_str()); vDatafileXML = QString::fromUtf8(datafileXMLArg.getValue().c_str()); vDatafileBaseNode = QString::fromUtf8(datafileBaseNodeArg.getValue().c_str()); vSqlInsertsFile = QString::fromUtf8(sqlInsertsFileArg.getValue().c_str()); vLogFile = QString::fromUtf8(logFileArg.getValue().c_str()); vPrefix = QString::fromUtf8(prefixArg.getValue().c_str()); //Check if any prefix specified and if not clear prefix vPrefix = vPrefix + "_"; if (vPrefix == "_") vPrefix = ""; count = 0; //Call the processing of the manifest file processManifestXML(); return 0; }