Webadmin: Add GUI for character encoding

This commit is contained in:
Alexey Sokolov
2014-12-19 00:05:16 +00:00
parent 86e5ca3fd3
commit bd9450b99e
10 changed files with 189 additions and 3 deletions

1
NOTICE
View File

@@ -11,6 +11,7 @@ ZNC includes modified code of autoconf macro gl_VISIBILITY, licensed by FSF Unli
ZNC includes modified code of MD5 implementation by Christophe Devine, licensed by GPLv2+.
ZNC includes resized External Wikipedia icon (https://commons.wikimedia.org/wiki/File:External.svg), licensed by public domain license.
ZNC includes modified code for SSL verification by Alban Diquet (https://github.com/iSECPartners/ssl-conservatory/) and Daniel Stenberg (https://github.com/bagder/curl/blob/master/lib/), licensed by MIT.
ZNC includes code from jQuery, licensed by MIT.
ZNC is developed by these people:

View File

@@ -84,6 +84,7 @@ public:
static CString FormatTime(time_t t, const CString& sFormat, const CString& sTZ);
static CString FormatServerTime(const timeval& tv);
static SCString GetTimezones();
static SCString GetEncodings();
static MCString GetMessageTags(const CString& sLine);
static void SetMessageTags(CString& sLine, const MCString& mssTags);

View File

@@ -0,0 +1,8 @@
.encoding-placeholder-big {
text-decoration:underline;
font-style:italic;
}
.encoding-settings {
width: 500px;
}

View File

@@ -1,4 +1,5 @@
<? AddRow JSLoop HREF=/modfiles/global/webadmin/webadmin.js ?>
<? AddRow CSSLoop HREF=/modfiles/global/webadmin/webadmin.css ?>
<? INC Header.tmpl ?>
<div class="section">
@@ -83,7 +84,7 @@
<div class="inputlabel">Flood protection:</div>
<div class="checkbox">
<input type="checkbox" name="floodprotection" id="floodprotection_checkbox"
title="You might enable the flood protection. This prevents `excess flood' errors, which occur, when your IRC bot is command flooded or spammed."
title="You might enable the flood protection. This prevents `excess flood' errors, which occur, when your IRC bot is command flooded or spammed. After changing this, reconnect ZNC to server."
onchange="floodprotection_change();"
<? IF FloodProtection ?>checked="checked"<? ENDIF ?> />
<label for="floodprotection_checkbox">Enabled</label>
@@ -92,7 +93,7 @@
<div class="subsection">
<div class="inputlabel">Flood protection rate:</div>
<input type="number" name="floodrate" min="0.3" step="0.05" id="floodrate"
title="The number of seconds per line."
title="The number of seconds per line. After changing this, reconnect ZNC to server."
<? IF FloodProtection ?> value="<? VAR FloodRate ?>" <? ELSE ?> value="1.00" disabled="disabled" <? ENDIF ?>
/> seconds per line
</div>
@@ -100,7 +101,7 @@
<div class="subsection">
<div class="inputlabel">Flood protection burst:</div>
<input type="number" name="floodburst" min="1" id="floodburst"
title="Defines the number of lines, which can be sent immediately."
title="Defines the number of lines, which can be sent immediately. After changing this, reconnect ZNC to server."
<? IF FloodProtection ?> value="<? VAR FloodBurst ?>" <? ELSE ?> value="4" disabled="disabled" <? ENDIF ?>
/> lines can be sent immediately
</div>
@@ -113,6 +114,13 @@
/> seconds
</div>
<script type="text/javascript">floodprotection_change();</script>
<div style="clear:both;"></div>
<div class="subsection" title="Character encoding used between ZNC and IRC server. After changing this, reconnect ZNC to server.">
<div class="inputlabel">Server encoding:</div>
<? INC encoding_settings.tmpl ?>
</div>
<div style="clear: both;"></div>
</div>
</div>

View File

@@ -1,3 +1,4 @@
<? AddRow CSSLoop HREF=/modfiles/global/webadmin/webadmin.css ?>
<? INC Header.tmpl ?>
<form action="<? VAR URIPrefix TOP ?><? VAR ModPath TOP ?><? IF Edit ?>edituser<? ELSE ?>adduser<? ENDIF ?>" method="post">
@@ -281,6 +282,12 @@
<? ENDLOOP ?>
</datalist>
</div>
<div style="clear:both;"></div>
<div class="subsection" title="Character encoding used between IRC client and ZNC. After changing this, reconnect client to ZNC.">
<div class="inputlabel">Client encoding:</div>
<? INC encoding_settings.tmpl ?>
</div>
<div style="clear:both;"></div>
<div class="subsection">
<div class="inputlabel">Join Tries:</div>
<input type="number" name="jointries" value="<? VAR JoinTries ?>" class="third" min="0"

View File

@@ -0,0 +1,48 @@
<div class="encoding-settings">
<div>
<div class="checkboxandlabel checkbox">
<input type="radio" name="encoding_utf" id="encoding_utf_legacy" value="legacy" <? IF EncodingUtf == "legacy" ?>checked="checked"<? ENDIF ?> <? IF EncodingDisabled ?>disabled="disabled"<? ENDIF ?> />
<label for="encoding_utf_legacy">Don't ensure any encoding at all (legacy mode, not recommended)</label>
</div>
<div class="checkboxandlabel checkbox">
<input type="radio" name="encoding_utf" id="encoding_utf_send" value="send" <? IF EncodingUtf == "send" ?>checked="checked"<? ENDIF ?> <? IF EncodingDisabled ?>disabled="disabled"<? ENDIF ?> />
<label for="encoding_utf_send">Try to parse as UTF-8 and as <span class="encoding-placeholder-big">&nbsp;&nbsp;<span class="encoding-placeholder"></span>&nbsp;&nbsp;</span>, send as UTF-8</label>
</div>
<div class="checkboxandlabel checkbox">
<input type="radio" name="encoding_utf" id="encoding_utf_receive" value="receive" <? IF EncodingUtf == "receive" ?>checked="checked"<? ENDIF ?> <? IF EncodingDisabled ?>disabled="disabled"<? ENDIF ?> />
<label for="encoding_utf_receive">Try to parse as UTF-8 and as <span class="encoding-placeholder-big">&nbsp;&nbsp;<span class="encoding-placeholder"></span>&nbsp;&nbsp;</span>, send as <span class="encoding-placeholder-big">&nbsp;&nbsp;<span class="encoding-placeholder"></span >&nbsp;&nbsp;</span></label>
</div>
<div class="checkboxandlabel checkbox">
<input type="radio" name="encoding_utf" id="encoding_utf_simple" value="simple" <? IF EncodingUtf == "simple" ?>checked="checked"<? ENDIF ?> <? IF EncodingDisabled ?>disabled="disabled"<? ENDIF ?> />
<label for="encoding_utf_simple">Parse and send as <span class="encoding-placeholder-big">&nbsp;&nbsp;<span class="encoding-placeholder"></span>&nbsp;&nbsp;</span> only</label>
</div>
</div>
<div class="half">
<input type="text" name="encoding" value="<? VAR Encoding ?>" list="encoding_list"
<? IF EncodingDisabled ?>disabled="disabled"<? ENDIF ?> />
<br /><div class="third"><span class="info">E.g. <code>UTF-8</code>, or <code>ISO-8859-1</code></span></div>
<script type="text/javascript">
function updateEncodingText() {
var value = jQuery("input[name=encoding]").val();
jQuery(".encoding-placeholder").each(function(index, element) {
jQuery(element).text(value);
});
}
jQuery("input[name=encoding]").on("keyup change input", updateEncodingText);
updateEncodingText();
function updateEncodingLegacy() {
var disabled = jQuery("input:radio[name=encoding_utf]:checked").val() == "legacy";
jQuery("input[name=encoding]").prop("disabled", disabled);
}
jQuery("input:radio[name=encoding_utf]").change(updateEncodingLegacy);
updateEncodingLegacy();
</script>
<datalist id="encoding_list">
<? LOOP EncodingLoop ?>
<option value="<? VAR Encoding ?>"/>
<? ENDLOOP ?>
</datalist>
</div>
</div>

View File

@@ -280,6 +280,24 @@ public:
pNewUser->SetAutoClearQueryBuffer(WebSock.GetParam("autoclearquerybuffer").ToBool());
pNewUser->SetMaxQueryBuffers(WebSock.GetParam("maxquerybuffers").ToUInt());
#ifdef HAVE_ICU
CString sEncodingUtf = WebSock.GetParam("encoding_utf");
if (sEncodingUtf == "legacy") {
pNewUser->SetClientEncoding("");
}
CString sEncoding = WebSock.GetParam("encoding");
if (sEncoding.empty()) {
sEncoding = "UTF-8";
}
if (sEncodingUtf == "send") {
pNewUser->SetClientEncoding("^" + sEncoding);
} else if (sEncodingUtf == "receive") {
pNewUser->SetClientEncoding("*" + sEncoding);
} else if (sEncodingUtf == "simple") {
pNewUser->SetClientEncoding(sEncoding);
}
#endif
if (spSession->IsAdmin()) {
pNewUser->SetDenyLoadMod(WebSock.GetParam("denyloadmod").ToBool());
pNewUser->SetDenySetBindHost(WebSock.GetParam("denysetbindhost").ToBool());
@@ -825,6 +843,29 @@ public:
Tmpl["IRCConnectEnabled"] = CString(pNetwork->GetIRCConnectEnabled());
#ifdef HAVE_ICU
for (const CString& sEncoding : CUtils::GetEncodings()) {
CTemplate& l = Tmpl.AddRow("EncodingLoop");
l["Encoding"] = sEncoding;
}
const CString& sEncoding = pNetwork->GetEncoding();
if (sEncoding.empty()) {
Tmpl["EncodingUtf"] = "legacy";
} else if (sEncoding[0] == '*') {
Tmpl["EncodingUtf"] = "receive";
Tmpl["Encoding"] = sEncoding.substr(1);
} else if (sEncoding[0] == '^') {
Tmpl["EncodingUtf"] = "send";
Tmpl["Encoding"] = sEncoding.substr(1);
} else {
Tmpl["EncodingUtf"] = "simple";
Tmpl["Encoding"] = sEncoding;
}
#else
Tmpl["EncodingDisabled"] = "true";
Tmpl["EncodingUtf"] = "legacy";
#endif
const vector<CServer*>& vServers = pNetwork->GetServers();
for (unsigned int a = 0; a < vServers.size(); a++) {
CTemplate& l = Tmpl.AddRow("ServerLoop");
@@ -951,6 +992,24 @@ public:
pNetwork->SetJoinDelay(WebSock.GetParam("joindelay").ToUShort());
#ifdef HAVE_ICU
CString sEncodingUtf = WebSock.GetParam("encoding_utf");
if (sEncodingUtf == "legacy") {
pNetwork->SetEncoding("");
}
CString sEncoding = WebSock.GetParam("encoding");
if (sEncoding.empty()) {
sEncoding = "UTF-8";
}
if (sEncodingUtf == "send") {
pNetwork->SetEncoding("^" + sEncoding);
} else if (sEncodingUtf == "receive") {
pNetwork->SetEncoding("*" + sEncoding);
} else if (sEncodingUtf == "simple") {
pNetwork->SetEncoding(sEncoding);
}
#endif
VCString vsArgs;
pNetwork->DelServers();
@@ -1166,6 +1225,29 @@ public:
l["TZ"] = *i;
}
#ifdef HAVE_ICU
for (const CString& sEncoding : CUtils::GetEncodings()) {
CTemplate& l = Tmpl.AddRow("EncodingLoop");
l["Encoding"] = sEncoding;
}
const CString& sEncoding = pUser->GetClientEncoding();
if (sEncoding.empty()) {
Tmpl["EncodingUtf"] = "legacy";
} else if (sEncoding[0] == '*') {
Tmpl["EncodingUtf"] = "receive";
Tmpl["Encoding"] = sEncoding.substr(1);
} else if (sEncoding[0] == '^') {
Tmpl["EncodingUtf"] = "send";
Tmpl["Encoding"] = sEncoding.substr(1);
} else {
Tmpl["EncodingUtf"] = "simple";
Tmpl["Encoding"] = sEncoding;
}
#else
Tmpl["EncodingDisabled"] = "true";
Tmpl["EncodingUtf"] = "legacy";
#endif
// To change BindHosts be admin or don't have DenySetBindHost
if (spSession->IsAdmin() || !spSession->GetUser()->DenySetBindHost()) {
Tmpl["BindHostEdit"] = "true";

View File

@@ -22,6 +22,11 @@
#endif /* HAVE_LIBSSL */
#include <unistd.h>
#ifdef HAVE_ICU
#include <unicode/ucnv.h>
#include <unicode/errorcode.h>
#endif
// Required with GCC 4.3+ if openssl is disabled
#include <cstring>
#include <cstdlib>
@@ -477,6 +482,27 @@ SCString CUtils::GetTimezones() {
return result;
}
SCString CUtils::GetEncodings() {
static SCString ssResult;
#ifdef HAVE_ICU
if (ssResult.empty()) {
for (int i = 0; i < ucnv_countAvailable(); ++i) {
const char* pConvName = ucnv_getAvailableName(i);
ssResult.insert(pConvName);
icu::ErrorCode e;
for (int st = 0; st < ucnv_countStandards(); ++st) {
const char* pStdName = ucnv_getStandard(st, e);
icu::LocalUEnumerationPointer ue(ucnv_openStandardNames(pConvName, pStdName, e));
while (const char* pStdConvNameEnum = uenum_next(ue.getAlias(), NULL, e)) {
ssResult.insert(pStdConvNameEnum);
}
}
}
}
#endif
return ssResult;
}
MCString CUtils::GetMessageTags(const CString& sLine) {
if (sLine.StartsWith("@")) {
VCString vsTags;

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +1,7 @@
<? INC DocType.tmpl ?>
<? INC Options.tmpl ?>
<? ADDROW CSSLoop HREF=/skinfiles/_default_/global.css ?>
<? ADDROW JSLoop HREF=/pub/jquery-1.11.2.min.js ?>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta charset="UTF-8" />