svvitch
digital signage player
D:/vs_workspace/switch_sf/src/svvitch/Configuration.cpp
Go to the documentation of this file.
00001 #include "Configuration.h"
00002 
00003 #include <Poco/Util/XMLConfiguration.h>
00004 #include <Poco/ConsoleChannel.h>
00005 #include <Poco/File.h>
00006 #include <Poco/FileStream.h>
00007 #include <Poco/format.h>
00008 #include <Poco/LineEndingConverter.h>
00009 #include <Poco/NullChannel.h>
00010 #include <Poco/FileChannel.h>
00011 #include <Poco/FormattingChannel.h>
00012 #include <Poco/PatternFormatter.h>
00013 #include <Poco/string.h>
00014 #include <Poco/UnicodeConverter.h>
00015 #include "Utils.h"
00016 
00017 
00018 Configuration::Configuration(): _log(Poco::Logger::get(""))
00019 {
00020 }
00021 
00022 Configuration::‾Configuration() {
00023     release();
00024 }
00025 
00026 void Configuration::release() {
00027 //  _log.shutdown();
00028     if (logFile) {
00029         try {
00030             //logFile->close();
00031             logFile->release();
00032             logFile = NULL;
00033         } catch (...) {
00034         }
00035     }
00036 }
00037 
00038 bool Configuration::initialize() {
00039     try {
00040         Poco::Util::XMLConfiguration* xml = new Poco::Util::XMLConfiguration("switch-config.xml");
00041         Poco::PatternFormatter* pat = new Poco::PatternFormatter(xml->getString("log.pattern", "%Y-%m-%d %H:%M:%S.%c %N[%T]:%t"));
00042         pat->setProperty(Poco::PatternFormatter::PROP_TIMES, "local");
00043         Poco::FormattingChannel* fc = new Poco::FormattingChannel(pat);
00044         string path = xml->getString("log.file", "switch.log");
00045         if (path.empty()) {
00046             logFile = new Poco::NullChannel();
00047         } else {
00048             logFile = new Poco::FileChannel(path);
00049         }
00050         fc->setChannel(logFile);
00051         _log.setChannel(fc);
00052         // ローカル時刻指定
00053         fc->setProperty(Poco::FileChannel::PROP_TIMES, "local");
00054         // アーカイブファイル名への付加文字列[number/timestamp] (日付)
00055         fc->setProperty(Poco::FileChannel::PROP_ARCHIVE, xml->getString("log.archive", "timestamp"));
00056         // 圧縮[true/false] (あり)
00057         fc->setProperty(Poco::FileChannel::PROP_COMPRESS, xml->getString("log.compress", "true"));
00058         // ローテーション単位[never/[day,][hh]:mm/daily/weekly/monthly/<n>minutes/hours/days/weeks/months/<n>/<n>K/<n>M] (日)
00059         fc->setProperty(Poco::FileChannel::PROP_ROTATION, xml->getString("log.rotation", "daily"));
00060         // 保持期間[<n>seconds/<n>minutes/<n>hours/<n>days/<n>weeks/<n>months] (5日間)
00061         fc->setProperty(Poco::FileChannel::PROP_PURGEAGE, xml->getString("log.purgeage", "5days"));
00062         fc->release();
00063         pat->release();
00064         _log.information("*** configuration");
00065 
00066         windowTitle = xml->getString("display.title", "switch");
00067         mainRect.left = xml->getInt("display.x", 0);
00068         mainRect.top = xml->getInt("display.y", 0);
00069         int w = xml->getInt("display.width", 1024);
00070         int h = xml->getInt("display.height", 768);
00071         mainRect.right = w;
00072         mainRect.bottom = h;
00073         mainRate = xml->getInt("display.rate", 0);
00074         subRect.left = xml->getInt("display[1].x", mainRect.left);
00075         subRect.top = xml->getInt("display[1].y", mainRect.top);
00076         subRect.right = xml->getInt("display[1].width", mainRect.right);
00077         subRect.bottom = xml->getInt("display[1].height", mainRect.bottom);
00078         subRate = xml->getInt("display[1].rate", mainRate);
00079         frameIntervals = xml->getInt("display.frameIntervals", 3);
00080         frame = xml->getBool("display.frame", true);
00081         fullsceen = xml->getBool("display.fullscreen", true);
00082         draggable = xml->getBool("display.draggable", !fullsceen);
00083         mouse = xml->getBool("display.mouse", !fullsceen);
00084         string windowStyles(fullsceen?"fullscreen":"window");
00085         _log.information(Poco::format("display %dx%d@%d %s", w, h, mainRate, windowStyles));
00086         useClip = xml->getBool("display.clip.use", false);
00087         clipRect.left = xml->getInt("display.clip.x1", 0);
00088         clipRect.top = xml->getInt("display.clip.y1", 0);
00089         clipRect.right = xml->getInt("display.clip.x2", 0);
00090         clipRect.bottom = xml->getInt("display.clip.y2", 0);
00091         string useClip(useClip?"use":"not use");
00092         _log.information(Poco::format("clip [%s] %ld,%ld %ldx%ld", useClip, clipRect.left, clipRect.top, clipRect.right, clipRect.bottom));
00093 
00094         name = xml->getString("stage.name", "");
00095         description = xml->getString("stage.description", "");
00096         int cw = xml->getInt("stage.split.width", w);
00097         int ch = xml->getInt("stage.split.height", h);
00098         int cycles = xml->getInt("stage.split.cycles", h / ch);
00099         splitSize.cx = cw;
00100         splitSize.cy = ch;
00101         stageRect.left = xml->getInt("stage.x", 0);
00102         stageRect.top = xml->getInt("stage.y", 0);
00103         stageRect.right = xml->getInt("stage.width", w * cycles);
00104         stageRect.bottom = xml->getInt("stage.height", ch);
00105         splitCycles = cycles;
00106         string st = xml->getString("stage.split.type", "none");
00107         if (st == "vertical" || st == "vertical-down") {
00108             splitType = 1;
00109         } else if (st == "vertical-up") {
00110             splitType = 2;
00111         } else if (st == "horizontal") {
00112             splitType = 11;
00113         } else if (st == "matrix") {
00114             splitType = 21;
00115         } else {
00116             splitType = 0;
00117         }
00118         _log.information(Poco::format("stage (%ld,%ld) %ldx%ld", stageRect.left, stageRect.top, stageRect.right, stageRect.bottom));
00119         if (splitType != 0) _log.information(Poco::format("split <%s:%d> %dx%d x%d", st, splitType, cw, ch, cycles));
00120 
00121         string engines = xml->getString("movieEngines", "ffmpeg");
00122         svvitch::split(engines, ',', movieEngines);
00123         string scenesParams = xml->getString("scenes", "");
00124         svvitch::split(scenesParams, ',', scenes);
00125         brightness = xml->getInt("stage.brightness", 100);
00126         dimmer = xml->getDouble("stage.dimmer", 1);
00127         viewStatus = xml->getBool("stage.viewStatus", false);
00128         captureQuality = xml->getDouble("stage.captureQuality", 0.25f);
00129         captureFilter = Poco::toLower(xml->getString("stage.captureQuality[@filter]", ""));
00130 
00131         imageSplitWidth = xml->getInt("stage.imageSplitWidth", 0);
00132         if (xml->hasProperty("stage.text")) {
00133             string s;
00134             Poco::UnicodeConverter::toUTF8(L"MS ゴシック", s);
00135             textFont = xml->getString("stage.text.font", s);
00136             textStyle = xml->getString("stage.text.style", "");
00137             textHeight = xml->getInt("stage.text.height", stageRect.bottom - 2);
00138         } else {
00139             string s;
00140             Poco::UnicodeConverter::toUTF8(L"MS ゴシック", s);
00141             textFont = s;
00142             textStyle = "";
00143             textHeight = stageRect.bottom - 2;
00144         }
00145 
00146         string font = xml->getString("ui.defaultFont", "");
00147         wstring ws;
00148         Poco::UnicodeConverter::toUTF16(font, ws);
00149         defaultFont = ws;
00150         asciiFont = xml->getString("ui.asciiFont", "Defactica");
00151         multiByteFont = xml->getString("ui.multiByteFont", "A-OTF-ShinGoPro-Regular.ttf");
00152 //      vpCommandFile = xml->getString("vpCommand", "");
00153 //      monitorFile = xml->getString("monitor", "");
00154         dataRoot = Path(xml->getString("data-root", "datas")).absolute();
00155         stockRoot = Path(xml->getString("stock-root", "stocks")).absolute();
00156         _log.information(Poco::format("data root: %s (stock:%s)", dataRoot.toString(), stockRoot.toString()));
00157         workspaceFile = Path(dataRoot, xml->getString("workspace", "workspace.xml"));
00158         _log.information(Poco::format("workspace: %s", workspaceFile.toString()));
00159         newsURL = xml->getString("newsURL", "https://led.avix.co.jp:8080/news");
00160 
00161         serverPort = xml->getInt("server.port", 9090);
00162         maxQueued = xml->getInt("server.max-queued", 50);
00163         maxThreads = xml->getInt("server.max-threads", 8);
00164 
00165         if (xml->hasProperty("schedule")) {
00166             outCastLog = xml->getBool("schedule.castingLog", true);
00167         } else {
00168             outCastLog = true;
00169         }
00170 
00171         xml->release();
00172         return true;
00173 
00174     } catch (Poco::Exception& ex) {
00175         string s;
00176         Poco::UnicodeConverter::toUTF8(L"設定ファイル(switch-config.xml)を確認してください¥n「%s」", s);
00177         wstring utf16;
00178         Poco::UnicodeConverter::toUTF16(Poco::format(s, ex.displayText()), utf16);
00179         ::MessageBox(HWND_DESKTOP, utf16.c_str(), L"エラー", MB_OK);
00180     }
00181     return false;
00182 }
00183 
00184 void Configuration::save() {
00185     _log.information("save configuration");
00186     string configPath = "switch-config.xml";
00187     Poco::File config(configPath);
00188     Poco::File save("switch-config-new.xml");
00189     bool update = false;
00190     try {
00191         Poco::Util::XMLConfiguration* xml = new Poco::Util::XMLConfiguration(config.path());
00192         if (xml) {
00193             if (xml->getInt("stage.brightness", -1) != brightness) {
00194                 xml->setInt("stage.brightness", brightness);
00195                 update = true;
00196             }
00197             if (xml->getBool("stage.viewStatus", !viewStatus) != viewStatus) {
00198                 xml->setBool("stage.viewStatus",  viewStatus);
00199                 update = true;
00200             }
00201             if (update) {
00202                 Poco::FileOutputStream fos(save.path());
00203                 Poco::OutputLineEndingConverter os(fos, Poco::LineEnding::NEWLINE_CRLF);
00204                 xml->save(os);
00205                 _log.information("saved configuration");
00206             }
00207             xml->release();
00208         }
00209     } catch (Poco::IOException& ex) {
00210         _log.warning(Poco::format("failed save configuration file: %s", ex.displayText()));
00211         return;
00212     } catch (...) {
00213         _log.warning("failed save configuration file(save step)");
00214     }
00215 
00216     try {
00217         if (update) {
00218             Poco::File old("switch-config-old.xml");
00219             if (old.exists()) old.remove();
00220             config.renameTo(old.path());
00221             save.renameTo(configPath);
00222         }
00223     } catch (Poco::IOException& ex) {
00224         _log.warning(Poco::format("failed save configuration file(rename step): %s", ex.displayText()));
00225     } catch (...) {
00226         _log.warning("failed save configuration file(rename step)");
00227     }
00228 }
00229 
00230 bool Configuration::hasScene(string s) {
00231     return std::find(scenes.begin(), scenes.end(), s) != scenes.end();
00232 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines