svvitch
digital signage player
|
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 }