mirror of
				https://git.openwrt.org/project/luci.git
				synced 2025-10-31 10:49:03 +08:00 
			
		
		
		
	* new project: ff-luci - Freifunk Lua Configuration Interface
This commit is contained in:
		
							
								
								
									
										5
									
								
								.buildpath
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								.buildpath
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <buildpath> | ||||
| 	<buildpathentry kind="src" path="src"/> | ||||
| 	<buildpathentry kind="con" path="org.eclipse.dltk.launching.INTERPRETER_CONTAINER"/> | ||||
| </buildpath> | ||||
							
								
								
									
										12
									
								
								.project
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								.project
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <projectDescription> | ||||
| 	<name>ffluci</name> | ||||
| 	<comment></comment> | ||||
| 	<projects> | ||||
| 	</projects> | ||||
| 	<buildSpec> | ||||
| 	</buildSpec> | ||||
| 	<natures> | ||||
| 		<nature>org.eclipse.dltk.lua.core.nature</nature> | ||||
| 	</natures> | ||||
| </projectDescription> | ||||
							
								
								
									
										201
									
								
								LICENSE
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										201
									
								
								LICENSE
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,201 @@ | ||||
|                                  Apache License | ||||
|                            Version 2.0, January 2004 | ||||
|                         http://www.apache.org/licenses/ | ||||
|  | ||||
|    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION | ||||
|  | ||||
|    1. Definitions. | ||||
|  | ||||
|       "License" shall mean the terms and conditions for use, reproduction, | ||||
|       and distribution as defined by Sections 1 through 9 of this document. | ||||
|  | ||||
|       "Licensor" shall mean the copyright owner or entity authorized by | ||||
|       the copyright owner that is granting the License. | ||||
|  | ||||
|       "Legal Entity" shall mean the union of the acting entity and all | ||||
|       other entities that control, are controlled by, or are under common | ||||
|       control with that entity. For the purposes of this definition, | ||||
|       "control" means (i) the power, direct or indirect, to cause the | ||||
|       direction or management of such entity, whether by contract or | ||||
|       otherwise, or (ii) ownership of fifty percent (50%) or more of the | ||||
|       outstanding shares, or (iii) beneficial ownership of such entity. | ||||
|  | ||||
|       "You" (or "Your") shall mean an individual or Legal Entity | ||||
|       exercising permissions granted by this License. | ||||
|  | ||||
|       "Source" form shall mean the preferred form for making modifications, | ||||
|       including but not limited to software source code, documentation | ||||
|       source, and configuration files. | ||||
|  | ||||
|       "Object" form shall mean any form resulting from mechanical | ||||
|       transformation or translation of a Source form, including but | ||||
|       not limited to compiled object code, generated documentation, | ||||
|       and conversions to other media types. | ||||
|  | ||||
|       "Work" shall mean the work of authorship, whether in Source or | ||||
|       Object form, made available under the License, as indicated by a | ||||
|       copyright notice that is included in or attached to the work | ||||
|       (an example is provided in the Appendix below). | ||||
|  | ||||
|       "Derivative Works" shall mean any work, whether in Source or Object | ||||
|       form, that is based on (or derived from) the Work and for which the | ||||
|       editorial revisions, annotations, elaborations, or other modifications | ||||
|       represent, as a whole, an original work of authorship. For the purposes | ||||
|       of this License, Derivative Works shall not include works that remain | ||||
|       separable from, or merely link (or bind by name) to the interfaces of, | ||||
|       the Work and Derivative Works thereof. | ||||
|  | ||||
|       "Contribution" shall mean any work of authorship, including | ||||
|       the original version of the Work and any modifications or additions | ||||
|       to that Work or Derivative Works thereof, that is intentionally | ||||
|       submitted to Licensor for inclusion in the Work by the copyright owner | ||||
|       or by an individual or Legal Entity authorized to submit on behalf of | ||||
|       the copyright owner. For the purposes of this definition, "submitted" | ||||
|       means any form of electronic, verbal, or written communication sent | ||||
|       to the Licensor or its representatives, including but not limited to | ||||
|       communication on electronic mailing lists, source code control systems, | ||||
|       and issue tracking systems that are managed by, or on behalf of, the | ||||
|       Licensor for the purpose of discussing and improving the Work, but | ||||
|       excluding communication that is conspicuously marked or otherwise | ||||
|       designated in writing by the copyright owner as "Not a Contribution." | ||||
|  | ||||
|       "Contributor" shall mean Licensor and any individual or Legal Entity | ||||
|       on behalf of whom a Contribution has been received by Licensor and | ||||
|       subsequently incorporated within the Work. | ||||
|  | ||||
|    2. Grant of Copyright License. Subject to the terms and conditions of | ||||
|       this License, each Contributor hereby grants to You a perpetual, | ||||
|       worldwide, non-exclusive, no-charge, royalty-free, irrevocable | ||||
|       copyright license to reproduce, prepare Derivative Works of, | ||||
|       publicly display, publicly perform, sublicense, and distribute the | ||||
|       Work and such Derivative Works in Source or Object form. | ||||
|  | ||||
|    3. Grant of Patent License. Subject to the terms and conditions of | ||||
|       this License, each Contributor hereby grants to You a perpetual, | ||||
|       worldwide, non-exclusive, no-charge, royalty-free, irrevocable | ||||
|       (except as stated in this section) patent license to make, have made, | ||||
|       use, offer to sell, sell, import, and otherwise transfer the Work, | ||||
|       where such license applies only to those patent claims licensable | ||||
|       by such Contributor that are necessarily infringed by their | ||||
|       Contribution(s) alone or by combination of their Contribution(s) | ||||
|       with the Work to which such Contribution(s) was submitted. If You | ||||
|       institute patent litigation against any entity (including a | ||||
|       cross-claim or counterclaim in a lawsuit) alleging that the Work | ||||
|       or a Contribution incorporated within the Work constitutes direct | ||||
|       or contributory patent infringement, then any patent licenses | ||||
|       granted to You under this License for that Work shall terminate | ||||
|       as of the date such litigation is filed. | ||||
|  | ||||
|    4. Redistribution. You may reproduce and distribute copies of the | ||||
|       Work or Derivative Works thereof in any medium, with or without | ||||
|       modifications, and in Source or Object form, provided that You | ||||
|       meet the following conditions: | ||||
|  | ||||
|       (a) You must give any other recipients of the Work or | ||||
|           Derivative Works a copy of this License; and | ||||
|  | ||||
|       (b) You must cause any modified files to carry prominent notices | ||||
|           stating that You changed the files; and | ||||
|  | ||||
|       (c) You must retain, in the Source form of any Derivative Works | ||||
|           that You distribute, all copyright, patent, trademark, and | ||||
|           attribution notices from the Source form of the Work, | ||||
|           excluding those notices that do not pertain to any part of | ||||
|           the Derivative Works; and | ||||
|  | ||||
|       (d) If the Work includes a "NOTICE" text file as part of its | ||||
|           distribution, then any Derivative Works that You distribute must | ||||
|           include a readable copy of the attribution notices contained | ||||
|           within such NOTICE file, excluding those notices that do not | ||||
|           pertain to any part of the Derivative Works, in at least one | ||||
|           of the following places: within a NOTICE text file distributed | ||||
|           as part of the Derivative Works; within the Source form or | ||||
|           documentation, if provided along with the Derivative Works; or, | ||||
|           within a display generated by the Derivative Works, if and | ||||
|           wherever such third-party notices normally appear. The contents | ||||
|           of the NOTICE file are for informational purposes only and | ||||
|           do not modify the License. You may add Your own attribution | ||||
|           notices within Derivative Works that You distribute, alongside | ||||
|           or as an addendum to the NOTICE text from the Work, provided | ||||
|           that such additional attribution notices cannot be construed | ||||
|           as modifying the License. | ||||
|  | ||||
|       You may add Your own copyright statement to Your modifications and | ||||
|       may provide additional or different license terms and conditions | ||||
|       for use, reproduction, or distribution of Your modifications, or | ||||
|       for any such Derivative Works as a whole, provided Your use, | ||||
|       reproduction, and distribution of the Work otherwise complies with | ||||
|       the conditions stated in this License. | ||||
|  | ||||
|    5. Submission of Contributions. Unless You explicitly state otherwise, | ||||
|       any Contribution intentionally submitted for inclusion in the Work | ||||
|       by You to the Licensor shall be under the terms and conditions of | ||||
|       this License, without any additional terms or conditions. | ||||
|       Notwithstanding the above, nothing herein shall supersede or modify | ||||
|       the terms of any separate license agreement you may have executed | ||||
|       with Licensor regarding such Contributions. | ||||
|  | ||||
|    6. Trademarks. This License does not grant permission to use the trade | ||||
|       names, trademarks, service marks, or product names of the Licensor, | ||||
|       except as required for reasonable and customary use in describing the | ||||
|       origin of the Work and reproducing the content of the NOTICE file. | ||||
|  | ||||
|    7. Disclaimer of Warranty. Unless required by applicable law or | ||||
|       agreed to in writing, Licensor provides the Work (and each | ||||
|       Contributor provides its Contributions) on an "AS IS" BASIS, | ||||
|       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | ||||
|       implied, including, without limitation, any warranties or conditions | ||||
|       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A | ||||
|       PARTICULAR PURPOSE. You are solely responsible for determining the | ||||
|       appropriateness of using or redistributing the Work and assume any | ||||
|       risks associated with Your exercise of permissions under this License. | ||||
|  | ||||
|    8. Limitation of Liability. In no event and under no legal theory, | ||||
|       whether in tort (including negligence), contract, or otherwise, | ||||
|       unless required by applicable law (such as deliberate and grossly | ||||
|       negligent acts) or agreed to in writing, shall any Contributor be | ||||
|       liable to You for damages, including any direct, indirect, special, | ||||
|       incidental, or consequential damages of any character arising as a | ||||
|       result of this License or out of the use or inability to use the | ||||
|       Work (including but not limited to damages for loss of goodwill, | ||||
|       work stoppage, computer failure or malfunction, or any and all | ||||
|       other commercial damages or losses), even if such Contributor | ||||
|       has been advised of the possibility of such damages. | ||||
|  | ||||
|    9. Accepting Warranty or Additional Liability. While redistributing | ||||
|       the Work or Derivative Works thereof, You may choose to offer, | ||||
|       and charge a fee for, acceptance of support, warranty, indemnity, | ||||
|       or other liability obligations and/or rights consistent with this | ||||
|       License. However, in accepting such obligations, You may act only | ||||
|       on Your own behalf and on Your sole responsibility, not on behalf | ||||
|       of any other Contributor, and only if You agree to indemnify, | ||||
|       defend, and hold each Contributor harmless for any liability | ||||
|       incurred by, or claims asserted against, such Contributor by reason | ||||
|       of your accepting any such warranty or additional liability. | ||||
|  | ||||
|    END OF TERMS AND CONDITIONS | ||||
|  | ||||
|    APPENDIX: How to apply the Apache License to your work. | ||||
|  | ||||
|       To apply the Apache License to your work, attach the following | ||||
|       boilerplate notice, with the fields enclosed by brackets "[]" | ||||
|       replaced with your own identifying information. (Don't include | ||||
|       the brackets!)  The text should be enclosed in the appropriate | ||||
|       comment syntax for the file format. We also recommend that a | ||||
|       file or class name and description of purpose be included on the | ||||
|       same "printed page" as the copyright notice for easier | ||||
|       identification within third-party archives. | ||||
|  | ||||
|    Copyright [yyyy] [name of copyright owner] | ||||
|  | ||||
|    Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|    you may not use this file except in compliance with the License. | ||||
|    You may obtain a copy of the License at | ||||
|  | ||||
|        http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  | ||||
|    Unless required by applicable law or agreed to in writing, software | ||||
|    distributed under the License is distributed on an "AS IS" BASIS, | ||||
|    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|    See the License for the specific language governing permissions and | ||||
|    limitations under the License. | ||||
							
								
								
									
										40
									
								
								Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								Makefile
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,40 @@ | ||||
| LUAC = luac | ||||
| LUAC_OPTIONS = -s | ||||
|  | ||||
| FILES = ffluci/config.lua | ||||
|  | ||||
| CFILES = ffluci/util.lua ffluci/http.lua \ | ||||
| ffluci/fs.lua ffluci/i18n.lua ffluci/model/uci.lua \ | ||||
| ffluci/template.lua ffluci/dispatcher.lua ffluci/menu.lua ffluci/init.lua | ||||
|  | ||||
| DIRECTORIES = dist/ffluci/model dist/ffluci/controller/public dist/ffluci/controller/admin dist/ffluci/i18n dist/ffluci/view | ||||
|  | ||||
| INFILES = $(CFILES:%=src/%) | ||||
| OUTFILE = ffluci/init.lua | ||||
|  | ||||
| all: compile | ||||
|  | ||||
| dist-compile: compile examples | ||||
| dist-source: source examples | ||||
|  | ||||
| examples: | ||||
| 	cp src/ffluci/controller/public/* dist/ffluci/controller/public/ | ||||
| 	cp src/ffluci/controller/admin/* dist/ffluci/controller/admin/ | ||||
| 	cp src/ffluci/i18n/* dist/ffluci/i18n/ | ||||
| 	cp src/ffluci/view/* dist/ffluci/view/ -R | ||||
|  | ||||
| compile: | ||||
| 	mkdir -p $(DIRECTORIES) | ||||
| 	$(LUAC) $(LUAC_OPTIONS) -o dist/$(OUTFILE) $(INFILES) | ||||
| 	for i in $(CFILES); do [ -f dist/$$i ] || ln -s `dirname $$i | cut -s -d / -f 2- | sed -e 's/[^/]*\/*/..\//g'``basename $(OUTFILE)` dist/$$i; done | ||||
| 	for i in $(FILES); do cp src/$$i dist/$$i; done | ||||
|  | ||||
| source: | ||||
| 	mkdir -p $(DIRECTORIES) | ||||
| 	for i in $(CFILES); do cp src/$$i dist/$$i; done | ||||
| 	for i in $(FILES); do cp src/$$i dist/$$i; done | ||||
| 	 | ||||
|  | ||||
| .PHONY: clean | ||||
| clean: | ||||
| 	rm dist -rf | ||||
							
								
								
									
										56
									
								
								README
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								README
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,56 @@ | ||||
| FFLuCI - Freifunk Lua Configuration Interface | ||||
|  | ||||
| This is a leightweight MVC-Webframework for small embedded device. | ||||
| It uses the the Lua programming language and relies on Haserl. | ||||
|  | ||||
| It consists of several parts: | ||||
|  | ||||
| MVC Dispatcher | ||||
| 	Simple PATH_INFO based dispatching mechanism using Lua modules | ||||
| 	 | ||||
| 	> See src/ffluci/dispatcher.lua for a detailed description | ||||
| 	> See src/ffluci/controller for example controllers | ||||
|  | ||||
|  | ||||
| Template engine | ||||
| 	Support for plain and compiled templates, on-demand compiling support | ||||
| 	Short markups: | ||||
| 		<% Lua-Code %>  | ||||
| 		<%= Lua-Code with return value %> | ||||
| 		<%:i18nkey default translation%> | ||||
| 		<%+template-to-be-included%> | ||||
| 		<%~uci.short.cut%> | ||||
|  | ||||
| 	Predefined variables for controller dir and media dir | ||||
|  | ||||
| 	> See src/ffluci/template.lua for details | ||||
| 	> See src/view/ for examples | ||||
|  | ||||
|  | ||||
| i18n Translation support | ||||
| 	Simple multi-language per-module internationalization support | ||||
| 	 | ||||
| 	> See src/ffluci/i18n.lua for details | ||||
| 	> See src/i18n/ for examples | ||||
|  | ||||
|  | ||||
| UCI wrapper support | ||||
| 	Lua UCI-Wrapper adapting the CLI of the uci binary | ||||
|  | ||||
| 	> See src/model/uci.lua for details | ||||
|  | ||||
|  | ||||
| Menu Building support | ||||
| 	Supports menu building for modules and exported actions | ||||
|  | ||||
| 	> See src/ffluci/menu.lua for details | ||||
| 	> See src/ffluci/view/menu.htm, src/ffluci/controller for examples | ||||
|  | ||||
|  | ||||
| HTTP-Abstraction and Formvalue validation support | ||||
| 	HTTP-Redirect, Statuscode, Content-Type abstraction | ||||
| 	Dynamic formvalue validation support including varaible type and | ||||
| 	value range validation | ||||
|  | ||||
| 	> See src/ffluci/http.lua for details | ||||
| 	> See src/ffluci/controller/public/example-action.lua for examples | ||||
							
								
								
									
										5
									
								
								contrib/ffluci
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										5
									
								
								contrib/ffluci
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,5 @@ | ||||
| #!/usr/bin/haserl --shell=luac | ||||
| package.path  = "/usr/lib/lua/?.lua;/usr/lib/lua/?/init.lua;" .. package.path | ||||
| package.cpath = "/usr/lib/lua/?.so;" .. package.cpath | ||||
| require("ffluci").dispatch() | ||||
|  | ||||
							
								
								
									
										3
									
								
								contrib/index.cgi
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										3
									
								
								contrib/index.cgi
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,3 @@ | ||||
| #!/usr/bin/haserl --shell=luac | ||||
| print("Status: 302 Found") | ||||
| print("Location: /cgi-bin/ffluci\n") | ||||
							
								
								
									
										43
									
								
								contrib/package/ffluci/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								contrib/package/ffluci/Makefile
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,43 @@ | ||||
| include $(TOPDIR)/rules.mk | ||||
|  | ||||
| PKG_NAME:=ffluci | ||||
| PKG_VERSION:=0.1 | ||||
| PKG_RELEASE:=1 | ||||
|  | ||||
| PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) | ||||
| PKG_INSTALL_DIR:=$(PKG_BUILD_DIR)/ipkg-install | ||||
|  | ||||
| MAKE_ACTION:=dist-source | ||||
|  | ||||
| include $(INCLUDE_DIR)/package.mk | ||||
|  | ||||
| define Package/ffluci | ||||
|   SECTION:=admin | ||||
|   CATEGORY:=Administration | ||||
|   TITLE:=FFLuCI | ||||
|   DEPENDS:=+liblua +luafilesystem +haserl | ||||
|   MAINTAINER:=Steven Barth <steven-at-midlink-dot-org> | ||||
| endef | ||||
|  | ||||
| define Build/Prepare | ||||
| 	mkdir -p $(PKG_BUILD_DIR) | ||||
| 	$(CP) ./src/* $(PKG_BUILD_DIR)/ -R | ||||
| endef | ||||
|  | ||||
| define Build/Configure | ||||
| endef | ||||
|  | ||||
| define Build/Compile | ||||
| 	$(MAKE) -C $(PKG_BUILD_DIR) dist-source | ||||
| endef | ||||
|  | ||||
| define Package/ffluci/install		 | ||||
| 	$(INSTALL_DIR) $(1)/usr/lib/lua | ||||
| 	$(INSTALL_DIR) $(1)/www/cgi-bin | ||||
| 	$(CP) $(PKG_BUILD_DIR)/dist/* $(1)/usr/lib/lua/ -R | ||||
| 	$(INSTALL_BIN) $(PKG_BUILD_DIR)/contrib/ffluci $(1)/www/cgi-bin | ||||
| 	$(INSTALL_BIN) $(PKG_BUILD_DIR)/contrib/index.cgi $(1)/www/cgi-bin | ||||
| 	$(CP) -a ./ipkg/ffluci.postinst $(1)/CONTROL/postinst | ||||
| endef | ||||
|  | ||||
| $(eval $(call BuildPackage,ffluci)) | ||||
							
								
								
									
										4
									
								
								contrib/package/ffluci/ipkg/ffluci.postinst
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										4
									
								
								contrib/package/ffluci/ipkg/ffluci.postinst
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,4 @@ | ||||
| #!/bin/sh | ||||
| PATTERN='/cgi-bin/ffluci/admin:root:$p$root' | ||||
| grep $PATTERN ${IPKG_INSTROOT}/etc/httpd.conf >/dev/null 2>/dev/null || echo $PATTERN >> ${IPKG_INSTROOT}/etc/httpd.conf  | ||||
| [ -z ${IPKG_INSTROOT} ] && /etc/init.d/httpd restart | ||||
							
								
								
									
										1
									
								
								contrib/package/ffluci/src
									
									
									
									
									
										Symbolic link
									
								
							
							
						
						
									
										1
									
								
								contrib/package/ffluci/src
									
									
									
									
									
										Symbolic link
									
								
							| @ -0,0 +1 @@ | ||||
| ../../.. | ||||
							
								
								
									
										39
									
								
								contrib/package/haserl-devel/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								contrib/package/haserl-devel/Makefile
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,39 @@ | ||||
| #  | ||||
| # Copyright (C) 2006 OpenWrt.org | ||||
| # | ||||
| # This is free software, licensed under the GNU General Public License v2. | ||||
| # See /LICENSE for more information. | ||||
| # | ||||
| # $Id$ | ||||
|  | ||||
| include $(TOPDIR)/rules.mk | ||||
|  | ||||
| PKG_NAME:=haserl | ||||
| PKG_VERSION:=0.9.22 | ||||
| PKG_RELEASE:=1 | ||||
|  | ||||
| PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz | ||||
| PKG_SOURCE_URL:=@SF/haserl | ||||
| PKG_MD5SUM:=b791150f2e5704d03b1fb698f4edc6c0 | ||||
|  | ||||
|  | ||||
| include $(INCLUDE_DIR)/package.mk | ||||
|  | ||||
| define Package/haserl | ||||
|   SECTION:=utils | ||||
|   CATEGORY:=Utilities | ||||
|   TITLE:=A CGI wrapper to embed shell scripts in HTML documents | ||||
|   URL:=http://haserl.sourceforge.net/ | ||||
|   DEPENDS:=+liblua | ||||
| endef | ||||
|  | ||||
| CONFIGURE_ARGS += \ | ||||
|         --with-lua | ||||
|  | ||||
| define Package/haserl/install | ||||
| 	$(INSTALL_DIR) $(1)/usr/bin | ||||
| 	$(STRIP) $(PKG_BUILD_DIR)/src/haserl | ||||
| 	$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/haserl $(1)/usr/bin/ | ||||
| endef | ||||
|  | ||||
| $(eval $(call BuildPackage,haserl)) | ||||
							
								
								
									
										44
									
								
								contrib/package/luafilesystem/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								contrib/package/luafilesystem/Makefile
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,44 @@ | ||||
| include $(TOPDIR)/rules.mk | ||||
|  | ||||
| PKG_NAME:=luafilesystem | ||||
| PKG_VERSION:=1.4.0 | ||||
| PKG_RELEASE:=1 | ||||
|  | ||||
| PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz | ||||
| PKG_SOURCE_URL:=http://luaforge.net/frs/download.php/3158 | ||||
| PKG_MD5SUM:=6f3d247f27820b8f045431ad81bcd3ad | ||||
|  | ||||
| PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) | ||||
| PKG_INSTALL_DIR:=$(PKG_BUILD_DIR)/ipkg-install | ||||
|  | ||||
| include $(INCLUDE_DIR)/package.mk | ||||
|  | ||||
| define Package/luafilesystem | ||||
|   SECTION:=lib | ||||
|   CATEGORY:=Libraries | ||||
|   TITLE:=Lua FS library | ||||
|   URL:=http://www.keplerproject.org/luafilesystem/ | ||||
|   DEPENDS:=+liblua | ||||
|   MAINTAINER:=Steven Barth <steven-at-midlink-dot-org> | ||||
| endef | ||||
|  | ||||
| define Build/Configure | ||||
| endef | ||||
|  | ||||
| define Build/Compile | ||||
| 	$(MAKE) -C $(PKG_BUILD_DIR) \ | ||||
| 		CC="$(TARGET_CROSS)gcc" \ | ||||
| 		LD="$(TARGET_CROSS)ld" \ | ||||
| 		AR="$(TARGET_CROSS)ar rcu" \ | ||||
| 		RANLIB="$(TARGET_CROSS)ranlib" \ | ||||
| 		INSTALL_ROOT=/usr \ | ||||
| 		LUA_INC=$(STAGING_DIR)/usr/include | ||||
| endef | ||||
|  | ||||
| define Package/luafilesystem/install		 | ||||
| 	$(INSTALL_DIR) $(1)/usr/lib/lua | ||||
| 	$(STRIP) $(PKG_BUILD_DIR)/src/lfs.so | ||||
| 	$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/lfs.so $(1)/usr/lib/lua | ||||
| endef | ||||
|  | ||||
| $(eval $(call BuildPackage,luafilesystem)) | ||||
							
								
								
									
										37
									
								
								src/ffluci/config.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								src/ffluci/config.lua
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,37 @@ | ||||
| --[[ | ||||
| FFLuCI - Configuration | ||||
|  | ||||
| Description: | ||||
| Some FFLuCI configuration values | ||||
|  | ||||
| ToDo: | ||||
| Port over to UCI | ||||
|  | ||||
| FileId: | ||||
| $Id$ | ||||
|  | ||||
| License: | ||||
| Copyright 2008 Steven Barth <steven@midlink.org> | ||||
|  | ||||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| you may not use this file except in compliance with the License. | ||||
| You may obtain a copy of the License at  | ||||
|  | ||||
| 	http://www.apache.org/licenses/LICENSE-2.0  | ||||
|  | ||||
| Unless required by applicable law or agreed to in writing, software | ||||
| distributed under the License is distributed on an "AS IS" BASIS, | ||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| See the License for the specific language governing permissions and | ||||
| limitations under the License. | ||||
|  | ||||
| ]]-- | ||||
|  | ||||
| module("ffluci.config", package.seeall) | ||||
|  | ||||
| -- This is where stylesheets and images go | ||||
| mediaurlbase = "/ffluci/media" | ||||
|  | ||||
| -- Does anybody think about browser autodetect here? | ||||
| -- Too bad busybox doesn't populate HTTP_ACCEPT_LANGUAGE | ||||
| lang = "de" | ||||
							
								
								
									
										15
									
								
								src/ffluci/controller/admin/index.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/ffluci/controller/admin/index.lua
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | ||||
| module(..., package.seeall) | ||||
|  | ||||
| function dispatcher(request) | ||||
| 	require("ffluci.template").render("header") | ||||
| 	print("Hello there, Mr. Administrator") | ||||
| 	require("ffluci.template").render("footer") | ||||
| end | ||||
|  | ||||
| menu = { | ||||
| 	descr   = "Administrative", | ||||
| 	order   = 10, | ||||
| 	entries = { | ||||
| 		{action = "index", descr = "Hello"} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										49
									
								
								src/ffluci/controller/public/example-action.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								src/ffluci/controller/public/example-action.lua
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,49 @@ | ||||
| -- This example demonstrates the action dispatcher which invokes | ||||
| -- an appropriate action function named action_"action" | ||||
|  | ||||
| -- This example consists of: | ||||
| -- ffluci/controller/index/example-action.lua (this file) | ||||
|  | ||||
| -- Try the following address(es) in your browser: | ||||
| -- ffluci/index/example-action | ||||
| -- ffluci/index/example-action/sp | ||||
| -- ffluci/index/example-action/redir | ||||
|  | ||||
| module(..., package.seeall) | ||||
|  | ||||
| dispatcher = require("ffluci.dispatcher").action | ||||
|  | ||||
| menu  = { | ||||
| 	descr   = "Example Action", | ||||
| 	order   = 30, | ||||
| 	entries = { | ||||
| 		{action = "index", descr = "Action-Dispatcher Example"}, | ||||
| 		{action = "sp", descr = "Simple View Template Stealing"}, | ||||
| 		{action = "redir", descr = "Hello World Redirector"} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| function action_index() | ||||
| 	require("ffluci.template").render("header") | ||||
| 	local formvalue = require("ffluci.http").formvalue | ||||
| 	 | ||||
| 	local x = formvalue("x", nil, true) | ||||
| 	 | ||||
| 	print(x and "x*x: "..tostring(x*x) or "Set ?x= any number") | ||||
| 	require("ffluci.template").render("footer")  | ||||
| end | ||||
|  | ||||
| function action_sp() | ||||
| 	require("ffluci.http") | ||||
| 	require("ffluci.i18n") | ||||
| 	require("ffluci.config") | ||||
| 	require("ffluci.template") | ||||
| 	 | ||||
| 	-- Try uncommenting the next line | ||||
| 	-- ffluci.i18n.loadc("example-simpleview") | ||||
| 	ffluci.template.render("example-simpleview/index") | ||||
| end | ||||
|  | ||||
| function action_redir() | ||||
| 	require("ffluci.http").request_redirect("public", "index", "foobar") | ||||
| end | ||||
							
								
								
									
										27
									
								
								src/ffluci/controller/public/example-simpleview.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/ffluci/controller/public/example-simpleview.lua
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | ||||
| -- This example demonstrates the simple view dispatcher which is the | ||||
| -- most simple way to provide content as it directly renders the | ||||
| -- associated template | ||||
|  | ||||
| -- This example consists of: | ||||
| -- ffluci/controller/index/example-simpleview.lua (this file) | ||||
| -- ffluci/view/example-simpleview/index.htm (the template for action "index") | ||||
| -- ffluci/view/example-simpleview/foo.htm (the template for action "foo") | ||||
| -- ffluci/i18n/example-simpleview.de (the german language file for this module) | ||||
|  | ||||
| -- Try the following address(es) in your browser: | ||||
| -- ffluci/index/example-simpleview | ||||
| -- ffluci/index/example-simpleview/index | ||||
| -- ffluci/index/example-simpleview/foo | ||||
|  | ||||
| module(..., package.seeall) | ||||
|  | ||||
| dispatcher = require("ffluci.dispatcher").simpleview | ||||
|  | ||||
| menu = { | ||||
| 	descr = "Example Simpleview", | ||||
| 	order = 20, | ||||
| 	entries = { | ||||
| 		{action = "index", descr = "Simpleview Index"}, | ||||
| 		{action = "foo", descr = "Simpleview Foo"} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										32
									
								
								src/ffluci/controller/public/index.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								src/ffluci/controller/public/index.lua
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | ||||
| -- This is a very simple example Hello World FFLuCI controller | ||||
| -- See the other examples for more automated controllers | ||||
|  | ||||
| -- Initialise Lua module system | ||||
| module(..., package.seeall) | ||||
|  | ||||
| -- This is the module dispatcher. It implements the last step of the | ||||
| -- dispatching process. | ||||
| function dispatcher(request) | ||||
| 	require("ffluci.template").render("header") | ||||
| 	print("<h2>Hello World!</h2>") | ||||
| 	for k,v in pairs(request) do | ||||
| 		print("<div>" .. k .. ": " .. v .. "</div>") | ||||
| 	end | ||||
| 	require("ffluci.template").render("footer") | ||||
| end | ||||
|  | ||||
| -- The following part is optional it could be useful for menu generators | ||||
| -- An example menu generator is implemented in the template "menu" | ||||
|  | ||||
| menu  = {	 | ||||
| 	-- This is the menu item description | ||||
| 	descr = "Hello World", | ||||
| 	 | ||||
| 	-- This is the order level of the menu entry (lowest goes first) | ||||
| 	order = 10, | ||||
|  | ||||
| 	-- A list of menu entries in the form action => "description" | ||||
| 	entries      = { | ||||
| 		{action = "index", descr = "Hello World"}, | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										175
									
								
								src/ffluci/dispatcher.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										175
									
								
								src/ffluci/dispatcher.lua
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,175 @@ | ||||
| --[[ | ||||
| FFLuCI - Dispatcher | ||||
|  | ||||
| Description: | ||||
| The request dispatcher and module dispatcher generators | ||||
|  | ||||
|  | ||||
| The dispatching process: | ||||
|     For a detailed explanation of the dispatching process we assume: | ||||
|     You have installed the FFLuCI CGI-Dispatcher in /cgi-bin/ffluci | ||||
| 	 | ||||
| 	To enforce a higher level of security only the CGI-Dispatcher | ||||
| 	resides inside the web server's document root, everything else | ||||
| 	stays inside an external directory, we assume this is /lua/ffluci | ||||
| 	for this explanation. | ||||
|  | ||||
|     All controllers and action are reachable as sub-objects of /cgi-bin/ffluci | ||||
|     as if they were virtual folders and files | ||||
| 	e.g.: /cgi-bin/ffluci/public/info/about | ||||
| 	      /cgi-bin/ffluci/admin/network/interfaces | ||||
| 	and so on. | ||||
|  | ||||
|     The PATH_INFO variable holds the dispatch path and | ||||
| 	will be split into three parts: /category/module/action | ||||
|     | ||||
|     Category:	This is the category in which modules are stored in | ||||
|    				By default there are two categories: | ||||
| 				"public" - which is the default public category | ||||
| 				"admin"  - which is the default protected category | ||||
| 				 | ||||
| 				As FFLuCI itself does not implement authentication | ||||
| 				you should make sure that "admin" and other sensitive | ||||
| 				categories are protected by the webserver. | ||||
| 				 | ||||
| 				E.g. for busybox add a line like: | ||||
| 				/cgi-bin/ffluci/admin:root:$p$root | ||||
| 				to /etc/httpd.conf to protect the "admin" category | ||||
| 				 | ||||
| 	 | ||||
| 	Module:		This is the controller which will handle the request further | ||||
| 				It is always a submodule of ffluci.controller, so a module | ||||
| 				called "helloworld" will be stored in | ||||
| 				/lua/ffluci/controller/helloworld.lua | ||||
| 				You are free to submodule your controllers any further. | ||||
| 				 | ||||
| 	Action:		This is action that will be invoked after loading the module. | ||||
| 	            The kind of how the action will be dispatched depends on | ||||
| 				the module dispatcher that is defined in the controller. | ||||
| 				See the description of the default module dispatcher down | ||||
| 				on this page for some examples. | ||||
|  | ||||
|  | ||||
|     The main dispatcher at first searches for the module by trying to | ||||
| 	include ffluci.controller.category.module | ||||
| 	(where "category" is the category name and "module" is the module name) | ||||
| 	If this fails a 404 status code will be send to the client and FFLuCI exits | ||||
| 	 | ||||
| 	Then the main dispatcher calls the module dispatcher | ||||
| 	ffluci.controller.category.module.dispatcher with the request object | ||||
| 	as the only argument. The module dispatcher is then responsible | ||||
| 	for the further dispatching process. | ||||
|  | ||||
|  | ||||
| FileId: | ||||
| $Id$ | ||||
|  | ||||
| License: | ||||
| Copyright 2008 Steven Barth <steven@midlink.org> | ||||
|  | ||||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| you may not use this file except in compliance with the License. | ||||
| You may obtain a copy of the License at  | ||||
|  | ||||
| 	http://www.apache.org/licenses/LICENSE-2.0  | ||||
|  | ||||
| Unless required by applicable law or agreed to in writing, software | ||||
| distributed under the License is distributed on an "AS IS" BASIS, | ||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| See the License for the specific language governing permissions and | ||||
| limitations under the License. | ||||
|  | ||||
| ]]-- | ||||
|  | ||||
| module("ffluci.dispatcher", package.seeall) | ||||
| require("ffluci.http") | ||||
| require("ffluci.template") | ||||
|  | ||||
|  | ||||
| -- Dispatches the "request" | ||||
| function dispatch(req) | ||||
| 	request = req | ||||
| 	local m = "ffluci.controller." .. request.category .. "." .. request.module | ||||
| 	local stat, module = pcall(require, m) | ||||
| 	if not stat then | ||||
| 		return error404() | ||||
| 	else | ||||
| 		module.request = request | ||||
| 		setfenv(module.dispatcher, module) | ||||
| 		return module.dispatcher(request) | ||||
| 	end	 | ||||
| end | ||||
|  | ||||
|  | ||||
| -- Sends a 404 error code and renders the "error404" template if available | ||||
| function error404(message) | ||||
| 	message = message or "Not Found" | ||||
| 	 | ||||
| 	ffluci.http.status(404, "Not Found") | ||||
| 	 | ||||
| 	if not pcall(ffluci.template.render, "error404") then | ||||
| 		ffluci.http.textheader() | ||||
| 		print(message)		 | ||||
| 	end | ||||
| 	return false	 | ||||
| end | ||||
|  | ||||
| -- Sends a 500 error code and renders the "error500" template if available | ||||
| function error500(message) | ||||
| 	ffluci.http.status(500, "Internal Server Error") | ||||
| 	 | ||||
| 	if not pcall(ffluci.template.render, "error500") then | ||||
| 		ffluci.http.textheader() | ||||
| 		print(message) | ||||
| 	end | ||||
| 	return false	 | ||||
| end | ||||
|  | ||||
|  | ||||
| -- Dispatches a request depending on the PATH_INFO variable | ||||
| function httpdispatch() | ||||
| 	local pathinfo = os.getenv("PATH_INFO") or "" | ||||
| 	local parts = pathinfo:gmatch("/[%w-]+") | ||||
| 	 | ||||
| 	local sanitize = function(s, default) | ||||
| 		return s and s:sub(2) or default | ||||
| 	end | ||||
| 	 | ||||
| 	local cat = sanitize(parts(), "public") | ||||
| 	local mod = sanitize(parts(), "index") | ||||
| 	local act = sanitize(parts(), "index") | ||||
| 	 | ||||
| 	dispatch({category=cat, module=mod, action=act}) | ||||
| end | ||||
|  | ||||
| -- The Simple View Dispatcher directly renders the template | ||||
| -- which is placed in ffluci/views/"request.module"/"request.action"  | ||||
| function simpleview(request) | ||||
| 	local i18n = require("ffluci.i18n") | ||||
| 	local tmpl = require("ffluci.template") | ||||
| 	local conf = require("ffluci.config") | ||||
| 	local disp = require("ffluci.dispatcher") | ||||
| 	 | ||||
| 	pcall(i18n.load, request.module .. "." .. conf.lang) | ||||
| 	if not pcall(tmpl.get, request.module .. "/" .. request.action) then | ||||
| 		disp.error404() | ||||
| 	else | ||||
| 		tmpl.render(request.module .. "/" .. request.action) | ||||
| 	end | ||||
| end | ||||
|  | ||||
| -- The Action Dispatcher searches the module for any function called | ||||
| -- action_"request.action" and calls it | ||||
| function action(request) | ||||
| 	local i18n = require("ffluci.i18n") | ||||
| 	local conf = require("ffluci.config") | ||||
| 	local disp = require("ffluci.dispatcher") | ||||
| 	 | ||||
| 	pcall(i18n.load, request.module .. "." .. conf.lang) | ||||
| 	local action = getfenv()["action_" .. request.action:gsub("-", "_")] | ||||
| 	if action then | ||||
| 		action() | ||||
| 	else | ||||
| 		disp.error404() | ||||
| 	end | ||||
| end | ||||
							
								
								
									
										71
									
								
								src/ffluci/fs.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								src/ffluci/fs.lua
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,71 @@ | ||||
| --[[ | ||||
| FFLuCI - Filesystem tools | ||||
|  | ||||
| Description: | ||||
| A module offering often needed filesystem manipulation functions | ||||
|  | ||||
| FileId: | ||||
| $Id$ | ||||
|  | ||||
| License: | ||||
| Copyright 2008 Steven Barth <steven@midlink.org> | ||||
|  | ||||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| you may not use this file except in compliance with the License. | ||||
| You may obtain a copy of the License at  | ||||
|  | ||||
| 	http://www.apache.org/licenses/LICENSE-2.0  | ||||
|  | ||||
| Unless required by applicable law or agreed to in writing, software | ||||
| distributed under the License is distributed on an "AS IS" BASIS, | ||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| See the License for the specific language governing permissions and | ||||
| limitations under the License. | ||||
|  | ||||
| ]]-- | ||||
|  | ||||
| module("ffluci.fs", package.seeall) | ||||
|  | ||||
| require("lfs") | ||||
|  | ||||
| -- Returns the content of file | ||||
| function readfile(filename) | ||||
| 	local fp = io.open(filename) | ||||
| 	if fp == nil then | ||||
| 		error("Unable to open file for reading: " .. filename) | ||||
| 	end | ||||
| 	local data = fp:read("*a") | ||||
| 	fp:close() | ||||
| 	return data	 | ||||
| end | ||||
|  | ||||
| -- Writes given data to a file | ||||
| function writefile(filename, data) | ||||
| 	local fp = io.open(filename, "w") | ||||
| 	if fp == nil then | ||||
| 		error("Unable to open file for writing: " .. filename) | ||||
| 	end | ||||
| 	fp:write(data) | ||||
| 	fp:close() | ||||
| end | ||||
|  | ||||
| -- Returns the file modification date/time of "path" | ||||
| function mtime(path) | ||||
| 	return lfs.attributes(path, "modification") | ||||
| end | ||||
|  | ||||
| -- Simplified dirname function | ||||
| function dirname(file) | ||||
| 	return string.gsub(file, "[^/]+$", "") | ||||
| end | ||||
|  | ||||
| -- Diriterator - alias for lfs.dir - filter . and .. | ||||
| function dir(path) | ||||
| 	local e = {} | ||||
| 	for entry in lfs.dir(path) do | ||||
| 		if not(entry == "." or entry == "..") then | ||||
| 			table.insert(e, entry) | ||||
| 		end | ||||
| 	end | ||||
| 	return e | ||||
| end | ||||
							
								
								
									
										118
									
								
								src/ffluci/http.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								src/ffluci/http.lua
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,118 @@ | ||||
| --[[ | ||||
| FFLuCI - HTTP-Interaction | ||||
|  | ||||
| Description: | ||||
| HTTP-Header manipulator and form variable preprocessor | ||||
|  | ||||
| FileId: | ||||
| $Id$ | ||||
|  | ||||
| ToDo: | ||||
| - Cookie handling | ||||
|  | ||||
| License: | ||||
| Copyright 2008 Steven Barth <steven@midlink.org> | ||||
|  | ||||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| you may not use this file except in compliance with the License. | ||||
| You may obtain a copy of the License at  | ||||
|  | ||||
| 	http://www.apache.org/licenses/LICENSE-2.0  | ||||
|  | ||||
| Unless required by applicable law or agreed to in writing, software | ||||
| distributed under the License is distributed on an "AS IS" BASIS, | ||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| See the License for the specific language governing permissions and | ||||
| limitations under the License. | ||||
|  | ||||
| ]]-- | ||||
|  | ||||
| module("ffluci.http", package.seeall) | ||||
|  | ||||
| require("ffluci.util") | ||||
|  | ||||
| -- Sets HTTP-Status-Header | ||||
| function status(code, message) | ||||
| 	print("Status: " .. tostring(code) .. " " .. message) | ||||
| end | ||||
|  | ||||
|  | ||||
| -- Asks the browser to redirect to "url" | ||||
| function redirect(url) | ||||
| 	status(302, "Found") | ||||
| 	print("Location: " .. url .. "\n") | ||||
| end | ||||
|  | ||||
|  | ||||
| -- Same as redirect but accepts category, module and action for internal use | ||||
| function request_redirect(category, module, action) | ||||
| 	category = category or "public" | ||||
| 	module   = module   or "index" | ||||
| 	action   = action   or "index" | ||||
| 	 | ||||
| 	local pattern = os.getenv("SCRIPT_NAME") .. "/%s/%s/%s" | ||||
| 	redirect(pattern:format(category, module, action)) | ||||
| end | ||||
|  | ||||
| -- Form validation function: | ||||
| -- Gets a form variable "key". | ||||
| -- If it does not exist: return "default" | ||||
| -- If cast_number is true and "key" is not a number: return "default" | ||||
| -- If valid is a table and "key" is not in it: return "default" | ||||
| -- If valid is a function and returns nil: return "default" | ||||
| -- Else return the value of "key" | ||||
| -- | ||||
| -- Examples: | ||||
| -- Get a form variable "foo" and return "bar" if it is not set | ||||
| -- 		= formvalue("foo", "bar") | ||||
| -- | ||||
| -- Get "foo" and make sure it is either "bar" or "baz" | ||||
| --      = formvalue("foo", nil, nil, {"bar", "baz"}) | ||||
| -- | ||||
| -- Get "foo", make sure its a number and below 10 else return 5 | ||||
| --      = formvalue("foo", 5, true, function(a) return a < 10 and a or nil end) | ||||
| function formvalue(key, default, cast_number, valid, table) | ||||
| 	table = table or formvalues() | ||||
| 	 | ||||
| 	if table[key] == nil then | ||||
| 		return default | ||||
| 	else | ||||
| 		local value = table[key] | ||||
| 	 | ||||
| 		value = cast_number and tonumber(value) or not cast_number and nil | ||||
| 		 | ||||
| 		if type(valid) == "function" then | ||||
| 			value = valid(value) | ||||
| 		elseif type(valid) == "table" then | ||||
| 			if not ffluci.util.contains(valid, value) then | ||||
| 				value = nil | ||||
| 			end | ||||
| 		end | ||||
| 		 | ||||
| 		return value or default | ||||
| 	end | ||||
| end | ||||
|  | ||||
|  | ||||
| -- Returns a table of all COOKIE, GET and POST Parameters | ||||
| function formvalues() | ||||
| 	return FORM | ||||
| end | ||||
|  | ||||
|  | ||||
| -- Prints plaintext content-type header | ||||
| function textheader() | ||||
| 	print("Content-Type: text/plain\n") | ||||
| end | ||||
|  | ||||
|  | ||||
| -- Prints html content-type header | ||||
| function htmlheader() | ||||
| 	print("Content-Type: text/html\n") | ||||
| end | ||||
|  | ||||
|  | ||||
| -- Prints xml content-type header | ||||
| function xmlheader() | ||||
| 	print("Content-Type: text/xml\n") | ||||
| end | ||||
							
								
								
									
										61
									
								
								src/ffluci/i18n.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								src/ffluci/i18n.lua
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,61 @@ | ||||
| --[[ | ||||
| FFLuCI - Internationalisation | ||||
|  | ||||
| Description: | ||||
| A very minimalistic but yet effective internationalisation module | ||||
|  | ||||
| FileId: | ||||
| $Id$ | ||||
|  | ||||
| License: | ||||
| Copyright 2008 Steven Barth <steven@midlink.org> | ||||
|  | ||||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| you may not use this file except in compliance with the License. | ||||
| You may obtain a copy of the License at  | ||||
|  | ||||
| 	http://www.apache.org/licenses/LICENSE-2.0  | ||||
|  | ||||
| Unless required by applicable law or agreed to in writing, software | ||||
| distributed under the License is distributed on an "AS IS" BASIS, | ||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| See the License for the specific language governing permissions and | ||||
| limitations under the License. | ||||
|  | ||||
| ]]-- | ||||
|  | ||||
| module("ffluci.i18n", package.seeall) | ||||
|  | ||||
| require("ffluci.fs") | ||||
| require("ffluci.util") | ||||
| require("ffluci.config") | ||||
|  | ||||
| table   = {} | ||||
| i18ndir = ffluci.fs.dirname(ffluci.util.__file__()) .. "i18n/" | ||||
|  | ||||
| -- Clears the translation table | ||||
| function clear() | ||||
| 	table = {} | ||||
| end | ||||
|  | ||||
| -- Loads a translation and copies its data into the global translation table | ||||
| function load(file) | ||||
| 	local f = loadfile(i18ndir .. file) | ||||
| 	if f then | ||||
| 		setfenv(f, table) | ||||
| 		f() | ||||
| 		return true | ||||
| 	else | ||||
| 		return false | ||||
| 	end | ||||
| end | ||||
|  | ||||
| -- Same as load but autocompletes the filename with .LANG from config.lang | ||||
| function loadc(file) | ||||
| 	return load(file .. "." .. ffluci.config.lang) | ||||
| end | ||||
|  | ||||
| -- Returns the i18n-value defined by "key" or if there is no such: "default" | ||||
| function translate(key, default) | ||||
| 	return table[key] or default | ||||
| end | ||||
							
								
								
									
										6
									
								
								src/ffluci/i18n/example-simpleview.de
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								src/ffluci/i18n/example-simpleview.de
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | ||||
| descr = [[Dies ist das Simple View-Beispiel.<br /> | ||||
| Dieses Template ist: ffluci/view/example-simpleview/index.htm und gehoert | ||||
| zur Aktion "index".<br /> | ||||
| Diese Uebersetzung ist: ffluci/i18n/example-simpleview.de]] | ||||
|  | ||||
| lan = "Die LAN IP-Adresse des Routers lautet:" | ||||
							
								
								
									
										33
									
								
								src/ffluci/init.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								src/ffluci/init.lua
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,33 @@ | ||||
| --[[ | ||||
| FFLuCI - Freifunk Lua Configuration Interface | ||||
|  | ||||
| Description: | ||||
| This is the init file | ||||
|  | ||||
| FileId: | ||||
| $Id$ | ||||
|  | ||||
| License: | ||||
| Copyright 2008 Steven Barth <steven@midlink.org> | ||||
|  | ||||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| you may not use this file except in compliance with the License. | ||||
| You may obtain a copy of the License at  | ||||
|  | ||||
| 	http://www.apache.org/licenses/LICENSE-2.0  | ||||
|  | ||||
| Unless required by applicable law or agreed to in writing, software | ||||
| distributed under the License is distributed on an "AS IS" BASIS, | ||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| See the License for the specific language governing permissions and | ||||
| limitations under the License. | ||||
|  | ||||
| ]]-- | ||||
| module("ffluci", package.seeall) | ||||
|  | ||||
| __version__ = "0.1" | ||||
| __appname__ = "FFLuCI" | ||||
|  | ||||
| dispatch = require("ffluci.dispatcher").httpdispatch | ||||
| env = ENV | ||||
| form = FORM | ||||
							
								
								
									
										124
									
								
								src/ffluci/menu.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								src/ffluci/menu.lua
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,124 @@ | ||||
| --[[ | ||||
| FFLuCI - Menu Builder | ||||
|  | ||||
| Description: | ||||
| Collects menu building information from controllers | ||||
|  | ||||
| FileId: | ||||
| $Id$ | ||||
|  | ||||
| License: | ||||
| Copyright 2008 Steven Barth <steven@midlink.org> | ||||
|  | ||||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| you may not use this file except in compliance with the License. | ||||
| You may obtain a copy of the License at  | ||||
|  | ||||
| 	http://www.apache.org/licenses/LICENSE-2.0  | ||||
|  | ||||
| Unless required by applicable law or agreed to in writing, software | ||||
| distributed under the License is distributed on an "AS IS" BASIS, | ||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| See the License for the specific language governing permissions and | ||||
| limitations under the License. | ||||
|  | ||||
| ]]-- | ||||
| module("ffluci.menu", package.seeall) | ||||
|  | ||||
| require("ffluci.fs") | ||||
| require("ffluci.util") | ||||
| require("ffluci.template") | ||||
|  | ||||
| ctrldir   = ffluci.fs.dirname(ffluci.util.__file__()) .. "controller/" | ||||
| modelpath = ffluci.fs.dirname(ffluci.util.__file__()) .. "model/menudata.lua" | ||||
|  | ||||
| -- Cache menudata into a Luafile instead of recollecting it at every pageload | ||||
| -- Warning: Make sure the menudata cache gets deleted everytime you update | ||||
| -- the menu information of any module or add or remove a module | ||||
| builder_enable_cache = false | ||||
|  | ||||
|  | ||||
| -- Builds the menudata file | ||||
| function build() | ||||
| 	local data = collect() | ||||
| 	ffluci.fs.writefile(modelpath, dump(data, "m")) | ||||
| 	return data | ||||
| end | ||||
|  | ||||
|  | ||||
| -- Collect all menu information provided in the controller modules | ||||
| function collect() | ||||
| 	local m = {} | ||||
| 	for k,cat in pairs(ffluci.fs.dir(ctrldir)) do | ||||
| 		m[cat] = {} | ||||
| 		for k,con in pairs(ffluci.fs.dir(ctrldir .. "/" .. cat)) do | ||||
| 			if con:sub(-4) == ".lua" then | ||||
| 				con = con:sub(1, con:len()-4) | ||||
| 				local mod = require("ffluci.controller." .. cat .. "." .. con) | ||||
| 				if mod.menu and mod.menu.descr | ||||
| 				and mod.menu.entries and mod.menu.order then | ||||
| 					local entry = {} | ||||
| 					entry[".descr"] = mod.menu.descr | ||||
| 					entry[".order"] = mod.menu.order | ||||
| 					entry[".contr"] = con | ||||
| 					for k,v in pairs(mod.menu.entries) do | ||||
| 						entry[k] = v | ||||
| 					end | ||||
| 					local i = 0			 | ||||
| 					for k,v in ipairs(m[cat]) do | ||||
| 						if v[".order"] > entry[".order"] then | ||||
| 							break | ||||
| 						end   | ||||
| 						i = k | ||||
| 					end	 | ||||
| 					table.insert(m[cat], i+1, entry) | ||||
| 				end | ||||
| 			end | ||||
| 		end | ||||
| 	end | ||||
| 	return m | ||||
| end | ||||
|  | ||||
|  | ||||
| -- Dumps a table into a string of Lua code | ||||
| function dump(tbl, name) | ||||
| 	local src = name .. "={}\n" | ||||
| 	for k,v in pairs(tbl) do | ||||
| 		if type(k) == "string" then | ||||
| 			k = ffluci.util.escape(k) | ||||
| 			k = "'" .. ffluci.util.escape(k, "'") .. "'" | ||||
| 		end		 | ||||
| 		if type(v) == "string" then | ||||
| 			v = ffluci.util.escape(v) | ||||
| 			v = ffluci.util.escape(v, "'") | ||||
| 			src = src .. name .. "[" .. k .. "]='" .. v .. "'\n" | ||||
| 		elseif type(v) == "number" then | ||||
| 			src = src .. name .. "[" .. k .. "]=" .. v .. "\n" | ||||
| 		elseif type(v) == "table" then | ||||
| 			src = src .. dump(v, name .. "[" .. k .. "]") | ||||
| 		end | ||||
| 	end | ||||
| 	return src | ||||
| end | ||||
|  | ||||
| -- Returns the menu information | ||||
| function get() | ||||
| 	if builder_enable_cache then | ||||
| 		local cachemt = ffluci.fs.mtime(modelpath) | ||||
| 		local data = nil | ||||
| 		 | ||||
| 		if cachemt == nil then | ||||
| 			data = build() | ||||
| 		else | ||||
| 			local fenv = {} | ||||
| 			local f    = loadfile(modelpath) | ||||
| 			setfenv(f, fenv) | ||||
| 			f() | ||||
| 			data = fenv.m | ||||
| 		end | ||||
| 		 | ||||
| 		return data | ||||
| 	else | ||||
| 		return collect() | ||||
| 	end | ||||
| end | ||||
							
								
								
									
										139
									
								
								src/ffluci/model/uci.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								src/ffluci/model/uci.lua
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,139 @@ | ||||
| --[[ | ||||
| FFLuCI - UCI wrapper library | ||||
|  | ||||
| Description: | ||||
| Wrapper for the /sbin/uci application, syntax of implemented functions | ||||
| is comparable to the syntax of the uci application | ||||
|  | ||||
| Any return value of false or nil can be interpreted as an error | ||||
|  | ||||
| FileId: | ||||
| $Id$ | ||||
|  | ||||
| License: | ||||
| Copyright 2008 Steven Barth <steven@midlink.org> | ||||
|  | ||||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| you may not use this file except in compliance with the License. | ||||
| You may obtain a copy of the License at  | ||||
|  | ||||
| 	http://www.apache.org/licenses/LICENSE-2.0  | ||||
|  | ||||
| Unless required by applicable law or agreed to in writing, software | ||||
| distributed under the License is distributed on an "AS IS" BASIS, | ||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| See the License for the specific language governing permissions and | ||||
| limitations under the License. | ||||
|  | ||||
| ]]-- | ||||
| module("ffluci.model.uci", package.seeall) | ||||
| require("ffluci.util") | ||||
|  | ||||
| ucicmd = "uci" | ||||
|  | ||||
| -- Wrapper for "uci add" | ||||
| function add(config, section_type) | ||||
| 	return _uci("add " .. _path(config) .. " " .. _path(section_type)) | ||||
| end | ||||
|  | ||||
|  | ||||
| -- Wrapper for "uci changes" | ||||
| function changes(config) | ||||
| 	return _uci3("changes " .. _path(config)) | ||||
| end | ||||
|  | ||||
|  | ||||
| -- Wrapper for "uci commit" | ||||
| function commit(config) | ||||
| 	return _uci2("commit " .. _path(config)) | ||||
| end | ||||
|  | ||||
|  | ||||
| -- Wrapper for "uci get" | ||||
| function get(config, section, option) | ||||
| 	return _uci("get " .. _path(config, section, option)) | ||||
| end | ||||
|  | ||||
|  | ||||
| -- Wrapper for "uci revert" | ||||
| function revert(config) | ||||
| 	return _uci2("revert " .. _path(config)) | ||||
| end | ||||
|  | ||||
|  | ||||
| -- Wrapper for "uci show" | ||||
| function show(config) | ||||
| 	return _uci3("show " .. _path(config)) | ||||
| end | ||||
|  | ||||
|  | ||||
| -- Wrapper for "uci set" | ||||
| function set(config, section, option, value) | ||||
| 	return _uci2("set " .. _path(config, section, option, value)) | ||||
| end | ||||
|  | ||||
|  | ||||
| -- Internal functions -- | ||||
|  | ||||
| function _uci(cmd) | ||||
| 	local res = ffluci.util.exec(ucicmd .. " 2>/dev/null " .. cmd) | ||||
| 	 | ||||
| 	if res:len() == 0 then | ||||
| 		return nil | ||||
| 	else | ||||
| 		return res:sub(1, res:len()-1) | ||||
| 	end	 | ||||
| end | ||||
|  | ||||
| function _uci2(cmd) | ||||
| 	local res = ffluci.util.exec(ucicmd .. " 2>&1 " .. cmd) | ||||
| 	 | ||||
| 	if res:len() > 0 then | ||||
| 		return false, res | ||||
| 	else | ||||
| 		return true | ||||
| 	end	 | ||||
| end | ||||
|  | ||||
| function _uci3(cmd) | ||||
| 	local res = ffluci.util.exec(ucicmd .. " 2>&1 " .. cmd, true) | ||||
| 	if res[1]:sub(1, ucicmd:len() + 1) == ucicmd .. ":" then | ||||
| 		return nil, res[1] | ||||
| 	end | ||||
|  | ||||
| 	table = {} | ||||
| 	 | ||||
| 	for k,line in pairs(res) do | ||||
| 		c, s, t = line:match("^([^.]-)%.([^.]-)=(.-)$") | ||||
| 		if c then | ||||
| 			table[c] = table[c] or {} | ||||
| 			table[c][s] = {} | ||||
| 			table[c][s][".type"] = t | ||||
| 		end | ||||
| 	 | ||||
| 		c, s, o, v = line:match("^([^.]-)%.([^.]-)%.([^.]-)=(.-)$") | ||||
| 		if c then | ||||
| 			table[c][s][o] = v | ||||
| 		end | ||||
| 	end | ||||
| 	 | ||||
| 	return table | ||||
| end | ||||
|  | ||||
| -- Build path (config.section.option=value) and prevent command injection | ||||
| function _path(...) | ||||
| 	local result = "" | ||||
| 	 | ||||
| 	-- Not using ipairs because it is not reliable in case of nil arguments | ||||
| 	arg.n = nil | ||||
| 	for k,v in pairs(arg) do | ||||
| 		if k == 1 then | ||||
| 			result = "'" .. v:gsub("['.]", "") .. "'" | ||||
| 		elseif k < 4 then | ||||
| 			result = result .. ".'" .. v:gsub("['.]", "") .. "'" | ||||
| 		elseif k == 4 then | ||||
| 			result = result .. "='" .. v:gsub("'", "") .. "'" | ||||
| 		end | ||||
| 	end | ||||
| 	return result | ||||
| end | ||||
							
								
								
									
										189
									
								
								src/ffluci/template.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										189
									
								
								src/ffluci/template.lua
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,189 @@ | ||||
| --[[ | ||||
| FFLuCI - Template Parser | ||||
|  | ||||
| Description: | ||||
| A template parser supporting includes, translations, Lua code blocks | ||||
| and more. It can be used either as a compiler or as an interpreter. | ||||
|  | ||||
| FileId: $Id$ | ||||
|  | ||||
| License: | ||||
| Copyright 2008 Steven Barth <steven@midlink.org> | ||||
|  | ||||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| you may not use this file except in compliance with the License. | ||||
| You may obtain a copy of the License at  | ||||
|  | ||||
| 	http://www.apache.org/licenses/LICENSE-2.0  | ||||
|  | ||||
| Unless required by applicable law or agreed to in writing, software | ||||
| distributed under the License is distributed on an "AS IS" BASIS, | ||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| See the License for the specific language governing permissions and | ||||
| limitations under the License. | ||||
|  | ||||
| ]]-- | ||||
| module("ffluci.template", package.seeall) | ||||
|  | ||||
| require("ffluci.config") | ||||
| require("ffluci.util") | ||||
| require("ffluci.fs") | ||||
| require("ffluci.i18n") | ||||
| require("ffluci.model.uci") | ||||
|  | ||||
| viewdir = ffluci.fs.dirname(ffluci.util.__file__()) .. "view/" | ||||
|  | ||||
|  | ||||
| -- Compile modes: | ||||
| -- none:	Never compile, only render precompiled | ||||
| -- memory:	Always compile, do not save compiled files, ignore precompiled  | ||||
| -- always:  Same as "memory" but also saves compiled files | ||||
| -- smart:	Compile on demand, save compiled files, update precompiled | ||||
| compiler_mode = "smart" | ||||
|  | ||||
|  | ||||
| -- This applies to compiler modes "always" and "smart" | ||||
| -- | ||||
| -- Produce compiled lua code rather than lua sourcecode | ||||
| -- WARNING: Increases template size heavily!!! | ||||
| -- This produces the same bytecode as luac but does not have a strip option | ||||
| compiler_enable_bytecode = false | ||||
|  | ||||
|  | ||||
| -- Define the namespace for template modules | ||||
| viewns = { | ||||
| 	translate  = ffluci.i18n.translate, | ||||
| 	config     = ffluci.model.uci.get, | ||||
| 	controller = os.getenv("SCRIPT_NAME"), | ||||
| 	media      = ffluci.config.mediaurlbase, | ||||
| 	include    = function(name) return render(name, getfenv(2)) end,  | ||||
| 	write      = io.write | ||||
| } | ||||
|  | ||||
|  | ||||
| -- Compiles and builds a given template | ||||
| function build(template, compiled)	 | ||||
| 	local template = compile(ffluci.fs.readfile(template)) | ||||
| 	 | ||||
| 	if compiled then | ||||
| 		ffluci.fs.writefile(compiled, template) | ||||
| 	end | ||||
| 	 | ||||
| 	return template | ||||
| end | ||||
|  | ||||
|  | ||||
| -- Compiles a given template into an executable Lua module | ||||
| function compile(template) | ||||
| 	-- Search all <% %> expressions (remember: Lua table indexes begin with #1) | ||||
| 	local function expr_add(command) | ||||
| 		table.insert(expr, command) | ||||
| 		return "<%" .. tostring(#expr) .. "%>" | ||||
| 	end | ||||
| 	 | ||||
| 	-- As "expr" should be local, we have to assign it to the "expr_add" scope  | ||||
| 	local expr = {} | ||||
| 	ffluci.util.extfenv(expr_add, "expr", expr) | ||||
| 	 | ||||
| 	-- Save all expressiosn to table "expr" | ||||
| 	template = template:gsub("<%%(.-)%%>", expr_add) | ||||
| 	 | ||||
| 	local function sanitize(s) | ||||
| 		s = ffluci.util.escape(s) | ||||
| 		s = ffluci.util.escape(s, "'") | ||||
| 		s = ffluci.util.escape(s, "\n") | ||||
| 		return s | ||||
| 	end | ||||
| 	 | ||||
| 	-- Escape and sanitize all the template (all non-expressions) | ||||
| 	template = sanitize(template) | ||||
|  | ||||
| 	-- Template module header/footer declaration | ||||
| 	local header = "write('" | ||||
| 	local footer = "')" | ||||
| 	 | ||||
| 	template = header .. template .. footer | ||||
| 	 | ||||
| 	-- Replacements | ||||
| 	local r_include = "')\ninclude('%s')\nwrite('" | ||||
| 	local r_i18n    = "'..translate('%1','%2')..'" | ||||
| 	local r_uci     = "'..config('%1','%2','%3')..'" | ||||
| 	local r_pexec   = "'..%s..'" | ||||
| 	local r_exec    = "')\n%s\nwrite('" | ||||
| 	 | ||||
| 	-- Parse the expressions | ||||
| 	for k,v in pairs(expr) do | ||||
| 		local p = v:sub(1, 1) | ||||
| 		local re = nil | ||||
| 		if p == "+" then | ||||
| 			re = r_include:format(sanitize(string.sub(v, 2))) | ||||
| 		elseif p == ":" then | ||||
| 			re = sanitize(v):gsub(":(.-) (.+)", r_i18n) | ||||
| 		elseif p == "~" then | ||||
| 			re = sanitize(v):gsub("~(.-)%.(.-)%.(.+)", r_uci) | ||||
| 		elseif p == "=" then | ||||
| 			re = r_pexec:format(string.sub(v, 2)) | ||||
| 		else | ||||
| 			re = r_exec:format(v) | ||||
| 		end | ||||
| 		template = template:gsub("<%%"..tostring(k).."%%>", re) | ||||
| 	end | ||||
|  | ||||
| 	if compiler_enable_bytecode then  | ||||
| 		tf = loadstring(template) | ||||
| 		template = string.dump(tf) | ||||
| 	end | ||||
| 	 | ||||
| 	return template | ||||
| end | ||||
|  | ||||
|  | ||||
| -- Returns and builds the template for "name" depending on the compiler mode | ||||
| function get(name)	 | ||||
| 	local templatefile = viewdir .. name .. ".htm" | ||||
| 	local compiledfile = viewdir .. name .. ".lua" | ||||
| 	local template = nil | ||||
| 	 | ||||
| 	if compiler_mode == "smart" then | ||||
| 		local tplmt = ffluci.fs.mtime(templatefile) | ||||
| 		local commt = ffluci.fs.mtime(compiledfile) | ||||
| 				 | ||||
| 		-- Build if there is no compiled file or if compiled file is outdated | ||||
| 		if ((commt == nil) and not (tplmt == nil)) | ||||
| 		or (not (commt == nil) and not (tplmt == nil) and commt < tplmt) then | ||||
| 			template = loadstring(build(templatefile, compiledfile)) | ||||
| 		else | ||||
| 			template = loadfile(compiledfile) | ||||
| 		end | ||||
| 		 | ||||
| 	elseif compiler_mode == "none" then | ||||
| 		template = loadfile(compiledfile) | ||||
| 		 | ||||
| 	elseif compiler_mode == "memory" then | ||||
| 		template = loadstring(build(templatefile)) | ||||
| 		 | ||||
| 	elseif compiler_mode == "always" then | ||||
| 		template = loadstring(build(templatefile, compiledfile)) | ||||
| 				 | ||||
| 	else | ||||
| 		error("Invalid compiler mode: " .. compiler_mode) | ||||
| 		 | ||||
| 	end | ||||
| 	 | ||||
| 	return template or error("Unable to load template: " .. name) | ||||
| end | ||||
|  | ||||
| -- Renders a template | ||||
| function render(name, scope) | ||||
| 	scope = scope or getfenv(2) | ||||
| 	 | ||||
| 	-- Our template module | ||||
| 	local view = get(name) | ||||
| 	 | ||||
| 	-- Put our predefined objects in the scope of the template | ||||
| 	ffluci.util.updfenv(view, scope) | ||||
| 	ffluci.util.updfenv(view, viewns) | ||||
| 	 | ||||
| 	-- Now finally render the thing | ||||
| 	return view() | ||||
| end | ||||
							
								
								
									
										102
									
								
								src/ffluci/util.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								src/ffluci/util.lua
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,102 @@ | ||||
| --[[ | ||||
| FFLuCI - Utility library | ||||
|  | ||||
| Description: | ||||
| Several common useful Lua functions | ||||
|  | ||||
| FileId: | ||||
| $Id$ | ||||
|  | ||||
| License: | ||||
| Copyright 2008 Steven Barth <steven@midlink.org> | ||||
|  | ||||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| you may not use this file except in compliance with the License. | ||||
| You may obtain a copy of the License at  | ||||
|  | ||||
| 	http://www.apache.org/licenses/LICENSE-2.0  | ||||
|  | ||||
| Unless required by applicable law or agreed to in writing, software | ||||
| distributed under the License is distributed on an "AS IS" BASIS, | ||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| See the License for the specific language governing permissions and | ||||
| limitations under the License. | ||||
|  | ||||
| ]]-- | ||||
|  | ||||
| module("ffluci.util", package.seeall) | ||||
|  | ||||
| -- Checks whether a table has an object "value" in it | ||||
| function contains(table, value) | ||||
| 	for k,v in pairs(table) do | ||||
| 		if value == v then | ||||
| 			return true | ||||
| 		end | ||||
| 	end | ||||
| 	return false | ||||
| end | ||||
|  | ||||
|  | ||||
| -- Dumps a table to stdout (useful for testing and debugging) | ||||
| function dumptable(t, i) | ||||
| 	i = i or 0 | ||||
| 	for k,v in pairs(t) do | ||||
| 		print(string.rep("\t", i) .. k, v) | ||||
| 		if type(v) == "table" then | ||||
| 			dumptable(v, i+1) | ||||
| 		end | ||||
| 	end | ||||
| end | ||||
|  | ||||
|  | ||||
| -- Escapes all occurences of c in s | ||||
| function escape(s, c) | ||||
| 	c = c or "\\" | ||||
| 	return s:gsub(c, "\\" .. c) | ||||
| end | ||||
|  | ||||
|  | ||||
| -- Runs "command" and returns its output | ||||
| function exec(command, return_array) | ||||
| 	local pp   = io.popen(command) | ||||
| 	local data = nil | ||||
| 	 | ||||
| 	if return_array then | ||||
| 		local line = "" | ||||
| 		data = {} | ||||
| 		 | ||||
| 		while true do | ||||
| 			line = pp:read() | ||||
| 			if (line == nil) then break end | ||||
| 			table.insert(data, line) | ||||
| 		end  | ||||
| 		pp:close()		 | ||||
| 	else | ||||
| 		data = pp:read("*a") | ||||
| 		pp:close() | ||||
| 	end | ||||
| 	 | ||||
| 	return data | ||||
| end | ||||
|  | ||||
| -- Populate obj in the scope of f as key  | ||||
| function extfenv(f, key, obj) | ||||
| 	local scope = getfenv(f) | ||||
| 	scope[key] = obj | ||||
| 	setfenv(f, scope) | ||||
| end | ||||
|  | ||||
|  | ||||
| -- Updates the scope of f with "extscope" | ||||
| function updfenv(f, extscope) | ||||
| 	local scope = getfenv(f) | ||||
| 	for k, v in pairs(extscope) do | ||||
| 		scope[k] = v | ||||
| 	end | ||||
| 	setfenv(f, scope) | ||||
| end | ||||
|  | ||||
| -- Returns the filename of the calling script | ||||
| function __file__() | ||||
| 	return debug.getinfo(2, 'S').source:sub(2) | ||||
| end | ||||
							
								
								
									
										3
									
								
								src/ffluci/view/example-simpleview/foo.htm
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										3
									
								
								src/ffluci/view/example-simpleview/foo.htm
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,3 @@ | ||||
| <%+header%> | ||||
| <h1>bar</h1> | ||||
| <%+footer%> | ||||
							
								
								
									
										6
									
								
								src/ffluci/view/example-simpleview/index.htm
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										6
									
								
								src/ffluci/view/example-simpleview/index.htm
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,6 @@ | ||||
| <%+header%> | ||||
| <p><%:descr This is the Simple View-Example.<br /> | ||||
| This template is ffluci/view/example-simpleview/index.htm and belongs | ||||
| to the index-Action.%></p> | ||||
| <p><%:lan The router's LAN IP-Address is:%> <%~network.lan.ipaddr%></p> | ||||
| <%+footer%> | ||||
							
								
								
									
										3
									
								
								src/ffluci/view/footer.htm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/ffluci/view/footer.htm
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| </div> | ||||
| </body> | ||||
| </html> | ||||
							
								
								
									
										9
									
								
								src/ffluci/view/header.htm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/ffluci/view/header.htm
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | ||||
| <% require("ffluci.http").htmlheader() %> | ||||
| <html> | ||||
| <head> | ||||
| <title>FFLuCI Examples</title> | ||||
| </head> | ||||
| <body> | ||||
| <h1>FFLuCI</h1> | ||||
| <%+menu%> | ||||
| <div id="content"> | ||||
							
								
								
									
										1
									
								
								src/ffluci/view/hello.htm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/ffluci/view/hello.htm
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | ||||
| A very little Hello <%=muh%> | ||||
							
								
								
									
										25
									
								
								src/ffluci/view/menu.htm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/ffluci/view/menu.htm
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,25 @@ | ||||
| <% | ||||
| local req  = require("ffluci.dispatcher").request | ||||
| local menu = require("ffluci.menu").get()[req.category] | ||||
| local menu_module = nil | ||||
| require("ffluci.i18n").loadc("default") | ||||
| %> | ||||
| <div id="menu" style="font-size: 0.8em; padding-bottom: 20px"> | ||||
|   <div id="menu_categories"> | ||||
|     <span style="<% if "public" == req.category then write("font-weight: bold") end %>"><a href="<%=controller%>/public"><%:public Public%></a></span> | ||||
|     <span style="<% if "admin" == req.category then write("font-weight: bold") end %>"><a href="<%=controller%>/admin"><%:admin Admin%></a></span> | ||||
|   </div> | ||||
|   <div id="menu_modules"> | ||||
| <% for k,v in pairs(menu) do  | ||||
| if v[".contr"] == req.module then menu_module = v end %> | ||||
|     <span style="<% if v[".contr"] == req.module then write("font-weight: bold") end %>"><a href="<%=controller.."/"..req.category.."/"..v[".contr"]%>"><%=translate(v[".contr"], v[".descr"])%></a></span> | ||||
| <% end %> | ||||
|   </div> | ||||
| <% if menu_module then %> | ||||
|   <div id="menu_actions"> | ||||
| <% for k,v in ipairs(menu_module) do %> | ||||
|     <span style="<% if v.action == req.action then write("font-weight: bold") end %>"><a href="<%=controller.."/"..req.category.."/"..req.module.."/"..v.action%>"><%=translate(v.action, v.descr)%></a></span> | ||||
| <% end %> | ||||
|   </div> | ||||
| <% end %> | ||||
| </div> | ||||
		Reference in New Issue
	
	Block a user
	 Jo-Philipp Wich
					Jo-Philipp Wich