Skip to content
Snippets Groups Projects
Unverified Commit e4b74be5 authored by Matthias Schiffer's avatar Matthias Schiffer
Browse files

gluon-web: add package

The gluon-web package is basically a stripped-down and refactored version
of the LuCI base.
parent a0654162
No related branches found
No related tags found
No related merge requests found
Showing
with 541 additions and 0 deletions
#!/usr/bin/perl
use strict;
use warnings;
use Text::Balanced qw(extract_bracketed extract_delimited extract_tagged);
@ARGV >= 1 || die "Usage: $0 <source direcory>\n";
my %stringtable;
sub dec_lua_str
{
my $s = shift;
$s =~ s/[\s\n]+/ /g;
$s =~ s/\\n/\n/g;
$s =~ s/\\t/\t/g;
$s =~ s/\\(.)/$1/g;
$s =~ s/^ //;
$s =~ s/ $//;
return $s;
}
sub dec_tpl_str
{
my $s = shift;
$s =~ s/-$//;
$s =~ s/[\s\n]+/ /g;
$s =~ s/^ //;
$s =~ s/ $//;
$s =~ s/\\/\\\\/g;
return $s;
}
if( open F, "find @ARGV -type f '(' -name '*.html' -o -name '*.lua' ')' |" )
{
while( defined( my $file = readline F ) )
{
chomp $file;
if( open S, "< $file" )
{
local $/ = undef;
my $raw = <S>;
close S;
my $text = $raw;
while( $text =~ s/ ^ .*? (?:translate|translatef|i18n|_) [\n\s]* \( /(/sgx )
{
( my $code, $text ) = extract_bracketed($text, q{('")});
$code =~ s/\\\n/ /g;
$code =~ s/^\([\n\s]*//;
$code =~ s/[\n\s]*\)$//;
my $res = "";
my $sub = "";
if( $code =~ /^['"]/ )
{
while( defined $sub )
{
( $sub, $code ) = extract_delimited($code, q{'"}, q{\s*(?:\.\.\s*)?});
if( defined $sub && length($sub) > 2 )
{
$res .= substr $sub, 1, length($sub) - 2;
}
else
{
undef $sub;
}
}
}
elsif( $code =~ /^(\[=*\[)/ )
{
my $stag = quotemeta $1;
my $etag = $stag;
$etag =~ s/\[/]/g;
( $res ) = extract_tagged($code, $stag, $etag);
$res =~ s/^$stag//;
$res =~ s/$etag$//;
}
$res = dec_lua_str($res);
$stringtable{$res}++ if $res;
}
$text = $raw;
while( $text =~ s/ ^ .*? <% -? [:_] /<%/sgx )
{
( my $code, $text ) = extract_tagged($text, '<%', '%>');
if( defined $code )
{
$code = dec_tpl_str(substr $code, 2, length($code) - 4);
$stringtable{$code}++;
}
}
}
}
close F;
}
if( open C, "| msgcat -" )
{
printf C "msgid \"\"\nmsgstr \"Content-Type: text/plain; charset=UTF-8\"\n\n";
foreach my $key ( sort keys %stringtable )
{
if( length $key )
{
$key =~ s/"/\\"/g;
printf C "msgid \"%s\"\nmsgstr \"\"\n\n", $key;
}
}
close C;
}
include $(TOPDIR)/rules.mk
PKG_NAME:=gluon-web
PKG_VERSION:=1
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
include ../gluon.mk
PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG)
PKG_INSTALL:=1
define Package/gluon-web
SECTION:=gluon
CATEGORY:=Gluon
TITLE:=Minimal Lua web framework derived from LuCI
DEPENDS:=+luci-lib-jsonc +luci-lib-nixio
endef
define lang-config
config GLUON_WEB_LANG_$(1)
bool "$(GLUON_LANG_$(1)) language support for gluon-web"
depends on PACKAGE_gluon-web
endef
define Package/gluon-web/config
$(foreach lang,$(GLUON_SUPPORTED_LANGS),$(call lang-config,$(lang)))
endef
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
$(CP) ./src/* $(PKG_BUILD_DIR)/
endef
define Build/Compile
$(call Build/Compile/Default)
$(call GluonBuildI18N,gluon-web,i18n)
$(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/)
endef
define Package/gluon-web/install
$(CP) ./files/* $(1)/
$(CP) $(PKG_INSTALL_DIR)/* $(1)/
$(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/
$(call GluonInstallI18N,gluon-web,$(1))
endef
$(eval $(call BuildPackage,gluon-web))
<%#
Copyright 2015 Jo-Philipp Wich <jow@openwrt.org>
Licensed to the public under the Apache License 2.0.
-%>
<h2 name="content"><%:Form token mismatch%></h2>
<br />
<p class="alert-message"><%:The submitted security token is invalid or already expired!%></p>
<p><%:
In order to prevent unauthorized access to the system, your request has
been blocked.
%></p>
<%#
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <jow@openwrt.org>
Licensed to the public under the Apache License 2.0.
-%>
<h2 name="content">404 <%:Not Found%></h2>
<p><%:Sorry, the object you requested was not found.%></p>
<tt><%=pcdata(message)%></tt>
<%#
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <jow@openwrt.org>
Licensed to the public under the Apache License 2.0.
-%>
<h2 name="content">500 <%:Internal Server Error%></h2>
<p><%:Sorry, the server encountered an unexpected error.%></p>
<pre class="error500"><%=pcdata(message)%></pre>
<%
include("themes/" .. theme .. "/layout")
%>
<div<%=
attr("data-prefix", id) ..
attr("data-dynlist", {
type = self.datatype,
optional = self.datatype and self.optional,
}) ..
attr("data-size", self.size) ..
attr("data-placeholder", self.placeholder)
%>>
<%
for i, val in ipairs(self:cfgvalue()) do
%>
<input class="gluon-input-text" value="<%=pcdata(val)%>" data-update="change" type="text"<%=
attr("id", id .. "." .. i) ..
attr("name", id) ..
attr("size", self.size) ..
attr("placeholder", self.placeholder)
%> /><br />
<% end %>
</div>
<form method="post" enctype="multipart/form-data" action="<%=url(request)%>">
<input type="hidden" name="token" value="<%=token%>" />
<input type="hidden" name="<%=id%>" value="1" />
<div class="gluon-map" id="gluon-<%=self.config%>">
<% if self.title and #self.title > 0 then %><h2 name="content"><%=self.title%></h2><% end %>
<% if self.description and #self.description > 0 then %><div class="gluon-map-descr"><%=self.description%></div><% end %>
<% self:render_children(renderer) %>
</div>
<%- if self.message then %>
<div><%=self.message%></div>
<%- end %>
<%- if self.errmessage then %>
<div class="error"><%=self.errmessage%></div>
<%- end %>
<div class="gluon-page-actions">
<%- if self.submit ~= false then %>
<input class="gluon-button gluon-button-submit" type="submit" value="
<%- if not self.submit then -%><%-:Save-%><%-else-%><%=pcdata(self.submit)%><%end-%>
" />
<% end %>
<%- if self.reset ~= false then %>
<input class="gluon-button gluon-button-reset" type="reset" value="
<%- if not self.reset then -%><%-:Reset-%><%-else-%><%=pcdata(self.reset)%><%end-%>
" />
<% end %>
</div>
</form>
<input class="gluon-input-checkbox" data-update="click change" type="checkbox" value="1"<%=
attr("id", id) .. attr("name", id) ..
attr("checked", self:cfgvalue() and "checked")
%> />
<label<%= attr("for", id)%>></label>
<%
local i, key
local br = self.orientation == "horizontal" and '&#160;' or '<br />'
%>
<% if self.widget == "select" then %>
<select class="gluon-input-select" data-update="change"<%=
attr("id", id) ..
attr("name", id) ..
attr("size", self.size)
%>>
<% for i, key in pairs(self.keylist) do -%>
<option<%=
attr("id", id.."."..key) ..
attr("value", key) ..
attr("data-index", i) ..
attr("data-depends", self:deplist(self.valdeps[i])) ..
attr("selected", (self:cfgvalue() == key) and "selected")
%>><%=pcdata(self.vallist[i])%></option>
<%- end %>
</select>
<% elseif self.widget == "radio" then %>
<div>
<% for i, key in pairs(self.keylist) do %>
<label<%=
attr("data-index", i) ..
attr("data-depends", self:deplist(self.valdeps[i]))
%>>
<input class="gluon-input-radio" data-update="click change" type="radio"<%=
attr("id", id.."."..key) ..
attr("name", id) ..
attr("value", key) ..
attr("checked", (self:cfgvalue() == key) and "checked")
%> />
<label<%= attr("for", id.."-"..key)%>></label>
<%=pcdata(self.vallist[i])%>
</label>
<% if i == self.size then write(br) end %>
<% end %>
</div>
<% end %>
<fieldset class="gluon-section">
<% if self.title and #self.title > 0 then -%>
<legend><%=self.title%></legend>
<%- end %>
<% if self.description and #self.description > 0 then -%>
<div class="gluon-section-descr"><%=self.description%></div>
<%- end %>
<div class="gluon-section-node">
<div id="section-<%=id%>">
<% self:render_children(renderer, scope) %>
</div>
<% if self.error and self.error[1] then -%>
<div class="gluon-section-error">
<ul><% for _, e in ipairs(self.error[1]) do -%>
<li>
<%- if e == "invalid" then -%>
<%:One or more fields contain invalid values!%>
<%- elseif e == "missing" then -%>
<%:One or more required fields have no value!%>
<%- else -%>
<%=pcdata(e)%>
<%- end -%>
</li>
<%- end %></ul>
</div>
<%- end %>
</div>
</fieldset>
<textarea class="gluon-input-textarea" <% if not self.size then %> style="width: 100%"<% else %> cols="<%=self.size%>"<% end %> data-update="change"<%= attr("name", id) .. attr("id", id) .. attr("rows", self.rows) .. attr("wrap", self.wrap) %>>
<%-=pcdata(self:cfgvalue())-%>
</textarea>
<input data-update="change"<%=
attr("id", id) ..
attr("name", id) ..
attr("type", self.password and "password" or "text") ..
attr("class", self.password and "gluon-input-password" or "gluon-input-text") ..
attr("value", self:cfgvalue()) ..
attr("size", self.size) ..
attr("placeholder", self.placeholder) ..
attr("maxlength", self.maxlength) ..
attr("data-type", self.datatype) ..
attr("data-optional", self.datatype and self.optional)
%> />
<div class="gluon-value<% if self.error then %> gluon-value-error<% end %>" id="value-<%=id%>" data-index="<%=self.index%>"<%= attr("data-depends", self:deplist()) %>>
<%- if self.title and #self.title > 0 then -%>
<label class="gluon-value-title"<%= attr("for", id) %>>
<%-=self.title-%>
</label>
<div class="gluon-value-field">
<%- end -%>
<% if self.subtemplate then include(self.subtemplate) end %>
<% if self.description and #self.description > 0 then -%>
<br />
<div class="gluon-value-description">
<%=self.description%>
</div>
<%- end %>
<%- if self.title and #self.title > 0 then -%>
</div>
<%- end -%>
</div>
<%
for _, map in ipairs(maps) do
map:render(renderer)
end
%>
<script type="text/javascript" src="<%=resource%>/gluon-web.js"></script>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="refresh" content="0; URL=/cgi-bin/gluon" />
</head>
<body>
</body>
</html>
!function(){function e(e){return/^-?\d+$/.test(e)?+e:NaN}function t(e){return/^-?\d*\.?\d+?$/.test(e)?+e:NaN}function n(e){var t;return e.match(/^([^\(]+)\(([^,]+),([^\)]+)\)$/)&&void 0!==(t=s[RegExp.$1])?function(){return t(RegExp.$2,RegExp.$3)}:e.match(/^([^\(]+)\(([^,\)]+)\)$/)&&void 0!==(t=s[RegExp.$1])?function(){return t(RegExp.$2)}:s[e]}function r(e,t){var n,r=document.getElementById(e);return r&&(n="checkbox"==r.type?r.checked:r.value?r.value:""),n==t}function a(e){for(var t=0;t<e.length;t++){var n=!0;for(var a in e[t])n=n&&r(a,e[t][a]);if(n)return!0}return!1}function i(){var e=!1;for(var t in c){var n=c[t],r=document.getElementById(t),o=document.getElementById(n.parent);if(r&&r.parentNode&&!a(n.deps))r.parentNode.removeChild(r),e=!0;else if(o&&(!r||!r.parentNode)&&a(n.deps)){var u=void 0;for(u=o.firstChild;u&&!(u.getAttribute&&parseInt(u.getAttribute("data-index"),10)>n.index);u=u.nextSibling);u?o.insertBefore(n.node,u):o.appendChild(n.node),e=!0}o&&o.parentNode&&o.getAttribute("data-optionals")&&(o.parentNode.style.display=o.options.length<=1?"none":"")}e&&i()}function o(e,t,n,r){return e.addEventListener?e.addEventListener(t,n,!!r):e.attachEvent("on"+t,function(){var e=window.event;return!e.target&&e.srcElement&&(e.target=e.srcElement),!!n(e)}),e}function u(e,t,n){function r(r,s,p){for(var f=[];e.firstChild;){var v=e.firstChild,h=+v.index;h!=p&&("input"==v.nodeName.toLowerCase()?f.push(v.value||""):"select"==v.nodeName.toLowerCase()&&(f[f.length-1]=v.options[v.selectedIndex].value)),e.removeChild(v)}s>=0?(r=s+1,f.splice(s,0,"")):n||0!=f.length||f.push("");for(var h=1;h<=f.length;h++){var g=document.createElement("input");if(g.id=l+"."+h,g.name=l,g.value=f[h-1],g.type="text",g.index=h,g.className="gluon-input-text",c&&(g.placeholder=c),e.appendChild(g),t&&d(g,!1,t),o(g,"keydown",i),o(g,"keypress",a),h==r)g.focus();else if(-h==r){g.focus();var m=g.value;g.value=" ",g.value=m}if(n||f.length>1){var x=document.createElement("span");x.className="gluon-remove",e.appendChild(x),o(x,"click",u(!1)),e.appendChild(document.createElement("br"))}}var x=document.createElement("span");x.className="gluon-add",e.appendChild(x),o(x,"click",u(!0))}function a(e){e=e?e:window.event;var t=e.target?e.target:e.srcElement;switch(3==t.nodeType&&(t=t.parentNode),e.keyCode){case 8:case 46:return 0!=t.value.length||(e.preventDefault&&e.preventDefault(),!1);case 13:case 38:case 40:return e.preventDefault&&e.preventDefault(),!1}return!0}function i(e){e=e?e:window.event;var t,n,a=e.target?e.target:e.srcElement,i=0;if(a){for(3==a.nodeType&&(a=a.parentNode),i=a.index,t=a.previousSibling;t&&t.name!=l;)t=t.previousSibling;for(n=a.nextSibling;n&&n.name!=l;)n=n.nextSibling}switch(e.keyCode){case 8:case 46:var o="select"==a.nodeName.toLowerCase()||0==a.value.length;if(o){e.preventDefault&&e.preventDefault();var u=a.index;return 8==e.keyCode&&(u=-u+1),r(u,-1,i),!1}break;case 13:r(-1,i,-1);break;case 38:t&&t.focus();break;case 40:n&&n.focus()}return!0}function u(e){return function(t){t=t?t:window.event;for(var n=t.target?t.target:t.srcElement,r=n.previousSibling;r&&r.name!=l;)r=r.previousSibling;return e?i({target:r,keyCode:13}):(r.value="",i({target:r,keyCode:8})),!1}}var l=e.getAttribute("data-prefix"),c=e.getAttribute("data-placeholder");r(NaN,-1,-1)}function d(e,t,r){var a=n(r);if(a){var i=function(){if(e.form){e.className=e.className.replace(/ gluon-input-invalid/g,"");var n=e.options&&e.options.selectedIndex>-1?e.options[e.options.selectedIndex].value:e.value;0==n.length&&t||a.apply(n)||(e.className+=" gluon-input-invalid")}};o(e,"blur",i),o(e,"keyup",i),"SELECT"==e.nodeName&&(o(e,"change",i),o(e,"click",i)),i()}}function l(e,t,n){var r=c[e.id];r||(r={node:e,parent:e.parentNode.id,deps:[],index:n},c[e.id]=r),r.deps.push(t)}var c={},s={integer:function(){return!isNaN(e(this))},uinteger:function(){return e(this)>=0},"float":function(){return!isNaN(t(this))},ufloat:function(){return t(this)>=0},ipaddr:function(){return s.ip4addr.apply(this)||s.ip6addr.apply(this)},ip4addr:function(){return!!this.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/)&&(RegExp.$1>=0&&RegExp.$1<=255&&RegExp.$2>=0&&RegExp.$2<=255&&RegExp.$3>=0&&RegExp.$3<=255&&RegExp.$4>=0&&RegExp.$4<=255)},ip6addr:function(){return this.indexOf("::")<0?null!=this.match(/^(?:[a-f0-9]{1,4}:){7}[a-f0-9]{1,4}$/i):!(this.indexOf(":::")>=0||this.match(/::.+::/)||this.match(/^:[^:]/)||this.match(/[^:]:$/))&&(!!this.match(/^(?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}$/i)||(!!this.match(/^(?:[a-f0-9]{1,4}:){7}:$/i)||!!this.match(/^:(?::[a-f0-9]{1,4}){7}$/i)))},wpakey:function(){var e=this;return 64==e.length?null!=e.match(/^[a-f0-9]{64}$/i):e.length>=8&&e.length<=63},range:function(e,n){var r=t(this);return r>=+e&&r<=+n},min:function(e){return t(this)>=+e},max:function(e){return t(this)<=+e},irange:function(t,n){var r=e(this);return r>=+t&&r<=+n},imin:function(t){return e(this)>=+t},imax:function(t){return e(this)<=+t},minlength:function(e){return(""+this).length>=+e},maxlength:function(e){return(""+this).length<=+e}};!function(){var e;e=document.querySelectorAll("[data-depends]");for(var t,n=0;void 0!==(t=e[n]);n++){var r=parseInt(t.getAttribute("data-index"),10),a=JSON.parse(t.getAttribute("data-depends"));if(!isNaN(r)&&a.length>0)for(var c=0;c<a.length;c++)l(t,a[c],r)}e=document.querySelectorAll("[data-update]");for(var t,n=0;void 0!==(t=e[n]);n++)for(var s,p=t.getAttribute("data-update").split(" "),f=0;void 0!==(s=p[f]);f++)o(t,s,i);e=document.querySelectorAll("[data-type]");for(var t,n=0;void 0!==(t=e[n]);n++)d(t,"true"===t.getAttribute("data-optional"),t.getAttribute("data-type"));e=document.querySelectorAll("[data-dynlist]");for(var t,n=0;void 0!==(t=e[n]);n++){var v=JSON.parse(t.getAttribute("data-dynlist"));u(t,v.type,v.optional)}i()}()}();
\ No newline at end of file
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"PO-Revision-Date: 2013-03-29 12:13+0200\n"
"Last-Translator: Matthias Schiffer <mschiffer@universe-factory.net>\n"
"Language-Team: German\n"
"Language: de\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
msgid "Form token mismatch"
msgstr "Formular-Token ungültig"
msgid ""
"In order to prevent unauthorized access to the system, your request has been "
"blocked."
msgstr ""
"Die Anfrage wurde blockiert, um unauthorisierten Zugriff aufs System zu verhindern."
msgid "Internal Server Error"
msgstr "Interner Serverfehler"
msgid "JavaScript required!"
msgstr "JavaScript benötigt!"
msgid "Not Found"
msgstr "Nicht Gefunden"
msgid "One or more fields contain invalid values!"
msgstr "Ein oder mehrere Felder enthalten ungültige Werte!"
msgid "One or more required fields have no value!"
msgstr "Ein oder mehr benötigte Felder sind nicht ausgefüllt!"
msgid "Reset"
msgstr "Zurücksetzen"
msgid "Save"
msgstr "Speichern"
msgid "Sorry, the object you requested was not found."
msgstr "Entschuldigung, das anfgeforderte Objekt wurde nicht gefunden."
msgid "Sorry, the server encountered an unexpected error."
msgstr ""
"Entschuldigung, auf dem Server ist ein unerwarteter Fehler aufgetreten."
msgid "The submitted security token is invalid or already expired!"
msgstr "Das übermittelte Sicherheits-Token ist ungültig oder bereits abgelaufen!"
msgid ""
"You must enable JavaScript in your browser or the web interface will not "
"work properly."
msgstr ""
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"PO-Revision-Date: 2013-12-22 17:11+0200\n"
"Last-Translator: goofy <pierre.gaufillet@gmail.com>\n"
"Language-Team: French\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
msgid "Form token mismatch"
msgstr ""
msgid ""
"In order to prevent unauthorized access to the system, your request has been "
"blocked."
msgstr ""
msgid "Internal Server Error"
msgstr "Erreur Serveur Interne"
msgid "JavaScript required!"
msgstr ""
msgid "Not Found"
msgstr "Pas trouvé"
msgid "One or more fields contain invalid values!"
msgstr "Un ou plusieurs champs contiennent des valeurs incorrectes !"
msgid "One or more required fields have no value!"
msgstr "Un ou plusieurs champs n'ont pas de valeur !"
msgid "Reset"
msgstr "Remise à zéro"
msgid "Save"
msgstr "Soumettre"
msgid "Sorry, the object you requested was not found."
msgstr "Désolé, l'objet que vous avez demandé n'as pas été trouvé."
msgid "Sorry, the server encountered an unexpected error."
msgstr "Désolé, le serveur à rencontré une erreur inattendue."
msgid "The submitted security token is invalid or already expired!"
msgstr ""
msgid ""
"You must enable JavaScript in your browser or the web interface will not "
"work properly."
msgstr ""
msgid ""
msgstr "Content-Type: text/plain; charset=UTF-8"
msgid "Form token mismatch"
msgstr ""
msgid ""
"In order to prevent unauthorized access to the system, your request has been "
"blocked."
msgstr ""
msgid "Internal Server Error"
msgstr ""
msgid "JavaScript required!"
msgstr ""
msgid "Not Found"
msgstr ""
msgid "One or more fields contain invalid values!"
msgstr ""
msgid "One or more required fields have no value!"
msgstr ""
msgid "Reset"
msgstr ""
msgid "Save"
msgstr ""
msgid "Sorry, the object you requested was not found."
msgstr ""
msgid "Sorry, the server encountered an unexpected error."
msgstr ""
msgid "The submitted security token is invalid or already expired!"
msgstr ""
msgid ""
"You must enable JavaScript in your browser or the web interface will not "
"work properly."
msgstr ""
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment