liquid_feedback_frontend
changeset 0:3bfb2fcf7ab9 alpha1
Version alpha1
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/LICENSE Wed Nov 18 12:00:00 2009 +0100 1.3 @@ -0,0 +1,27 @@ 1.4 +Copyright (c) 2009 Public Software Group e. V., Berlin, Germany 1.5 + 1.6 +Permission is hereby granted, free of charge, to any person obtaining a 1.7 +copy of this software and associated documentation files (the "Software"), 1.8 +to deal in the Software without restriction, including without limitation 1.9 +the rights to use, copy, modify, merge, publish, distribute, sublicense, 1.10 +and/or sell copies of the Software, and to permit persons to whom the 1.11 +Software is furnished to do so, subject to the following conditions: 1.12 + 1.13 +The above copyright notice and this permission notice shall be included in 1.14 +all copies or substantial portions of the Software. 1.15 + 1.16 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1.17 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1.18 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1.19 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1.20 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 1.21 +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 1.22 +DEALINGS IN THE SOFTWARE. 1.23 + 1.24 + 1.25 +3rd party license information: 1.26 + 1.27 +The icons used in Liquid Feedback (except national flags) are from Silk 1.28 +icon set 1.3 by Mark James. [ http://www.famfamfam.com/lab/icons/silk/ ] 1.29 +His work is licensed under a Creative Commons Attribution 2.5 License. 1.30 +[ http://creativecommons.org/licenses/by/2.5/ ] 1.31 \ No newline at end of file
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/Makefile Wed Nov 18 12:00:00 2009 +0100 2.3 @@ -0,0 +1,14 @@ 2.4 +default: 2.5 + 2.6 + 2.7 +db: 2.8 + create_db liquid_feedback 2.9 + psql liquid_feedback -f db/core.sql 2.10 + 2.11 +demo-db: db 2.12 + psql liquid_feedback -f db/demo.sql 2.13 + 2.14 + 2.15 +translations-de: 2.16 + cd ../webmcp/framework/bin/ && ./langtool.lua ~/workspace/liquid_feedback/locale/translations.de.lua ~/workspace/liquid_feedback/app ~/workspace/liquid_feedback/locale/translations.de.lua 2.17 +
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/app/main/_filter/20_session.lua Wed Nov 18 12:00:00 2009 +0100 3.3 @@ -0,0 +1,13 @@ 3.4 +if cgi.cookies.liquid_feedback_session then 3.5 + app.session = Session:by_ident(cgi.cookies.liquid_feedback_session) 3.6 +end 3.7 +if not app.session then 3.8 + app.session = Session:new() 3.9 + cgi.add_header('Set-Cookie: liquid_feedback_session=' .. app.session.ident .. '; path=/' ) 3.10 +end 3.11 + 3.12 +request.set_csrf_secret(app.session.additional_secret) 3.13 + 3.14 +locale.set{lang = app.session.lang or "en"} 3.15 + 3.16 +execute.inner()
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/app/main/_filter/21_auth.lua Wed Nov 18 12:00:00 2009 +0100 4.3 @@ -0,0 +1,33 @@ 4.4 +local auth_needed = not ( 4.5 + request.get_module() == 'index' 4.6 + and ( 4.7 + request.get_view() == 'login' 4.8 + or request.get_action() == 'login' 4.9 + or request.get_view() == "about" 4.10 + ) 4.11 +) 4.12 + 4.13 +-- if not app.session.user_id then 4.14 +-- trace.debug("DEBUG: AUTHENTICATION BYPASS ENABLED") 4.15 +-- app.session.user_id = 1 4.16 +-- end 4.17 + 4.18 +if auth_needed and app.session.member == nil then 4.19 + trace.debug("Not authenticated yet.") 4.20 + request.redirect{ module = 'index', view = 'login' } 4.21 +elseif auth_needed and app.session.member.locked then 4.22 + trace.debug("Member locked.") 4.23 + request.redirect{ module = 'index', view = 'login' } 4.24 +else 4.25 + if auth_needed then 4.26 + trace.debug("Authentication accepted.") 4.27 + else 4.28 + trace.debug("No authentication needed.") 4.29 + end 4.30 + 4.31 + --db:query("SELECT check_everything()") 4.32 + 4.33 + execute.inner() 4.34 + trace.debug("End of authentication filter.") 4.35 +end 4.36 +
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/app/main/_filter_view/30_navigation.lua Wed Nov 18 12:00:00 2009 +0100 5.3 @@ -0,0 +1,94 @@ 5.4 +slot.put_into("app_name", config.app_title) 5.5 + 5.6 +-- display navigation only, if user is logged in 5.7 +if app.session.member == nil then 5.8 + slot.select('navigation', function() 5.9 + ui.link{ 5.10 + content = function() 5.11 + ui.image{ static = "icons/16/key.png" } 5.12 + slot.put('Login') 5.13 + end, 5.14 + module = 'index', 5.15 + view = 'login' 5.16 + } 5.17 + ui.link{ 5.18 + content = function() 5.19 + ui.image{ static = "icons/16/information.png" } 5.20 + slot.put('About / Impressum') 5.21 + end, 5.22 + module = 'index', 5.23 + view = 'about' 5.24 + } 5.25 + end) 5.26 + execute.inner() 5.27 + return 5.28 +end 5.29 + 5.30 +slot.select('navigation', function() 5.31 + 5.32 + ui.link{ 5.33 + content = function() 5.34 + ui.image{ static = "icons/16/house.png" } 5.35 + slot.put(_'Home') 5.36 + end, 5.37 + module = 'index', 5.38 + view = 'index' 5.39 + } 5.40 + 5.41 + ui.link{ 5.42 + content = function() 5.43 + ui.image{ static = "icons/16/package.png" } 5.44 + slot.put(_'Areas') 5.45 + end, 5.46 + module = 'area', 5.47 + view = 'list' 5.48 + } 5.49 + 5.50 + ui.link{ 5.51 + content = function() 5.52 + ui.image{ static = "icons/16/group.png" } 5.53 + slot.put(_'Members') 5.54 + end, 5.55 + module = 'member', 5.56 + view = 'list' 5.57 + } 5.58 + 5.59 + ui.link{ 5.60 + content = function() 5.61 + ui.image{ static = "icons/16/book_edit.png" } 5.62 + slot.put(_'Contacts') 5.63 + end, 5.64 + module = 'contact', 5.65 + view = 'list' 5.66 + } 5.67 + 5.68 + ui.link{ 5.69 + content = function() 5.70 + ui.image{ static = "icons/16/information.png" } 5.71 + slot.put(_'About') 5.72 + end, 5.73 + module = 'index', 5.74 + view = 'about' 5.75 + } 5.76 + 5.77 + if app.session.member.admin then 5.78 + 5.79 + slot.put(" ") 5.80 + 5.81 + ui.link{ 5.82 + attr = { class = { "admin_only" } }, 5.83 + content = function() 5.84 + ui.image{ static = "icons/16/cog.png" } 5.85 + slot.put(_'Admin') 5.86 + end, 5.87 + module = 'admin', 5.88 + view = 'index' 5.89 + } 5.90 + 5.91 + end 5.92 + 5.93 +end) 5.94 + 5.95 +execute.inner() 5.96 + 5.97 +
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/app/main/_filter_view/31_logout_button.lua Wed Nov 18 12:00:00 2009 +0100 6.3 @@ -0,0 +1,17 @@ 6.4 +if app.session.member == nil then 6.5 + execute.inner() 6.6 + return 6.7 +end 6.8 + 6.9 +slot.select('logout_button', function() 6.10 + ui.link{ 6.11 + content = function() 6.12 + ui.image{ static = "icons/16/stop.png" } 6.13 + slot.put(_'Logout') 6.14 + end, 6.15 + module = 'index', 6.16 + action = 'logout' 6.17 + } 6.18 +end) 6.19 + 6.20 +execute.inner()
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/app/main/_filter_view/32_searchbox.lua Wed Nov 18 12:00:00 2009 +0100 7.3 @@ -0,0 +1,34 @@ 7.4 +if app.session.member == nil then 7.5 + execute.inner() 7.6 + return 7.7 +end 7.8 + 7.9 +slot.select('searchbox', function() 7.10 + 7.11 + ui.form{ 7.12 + module = "index", 7.13 + view = "search", 7.14 + method = "get", 7.15 + content = function() 7.16 + 7.17 + ui.field.select{ 7.18 + name = "search_for", 7.19 + foreign_records = { 7.20 + { key = "global", name = _"Search" }, 7.21 + { key = "member", name = _"Search members" }, 7.22 + { key = "initiative", name = _"Search initiatives" }, 7.23 + { key = "issue", name = _"Search issues" }, 7.24 + }, 7.25 + foreign_id = "key", 7.26 + foreign_name = "name" 7.27 + } 7.28 + 7.29 + ui.field.text{ name = "search", value = "" } 7.30 + ui.submit{ text = _"OK" } 7.31 + 7.32 + end 7.33 + } 7.34 + 7.35 +end) 7.36 + 7.37 +execute.inner(); 7.38 \ No newline at end of file
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/app/main/_layout/default.html Wed Nov 18 12:00:00 2009 +0100 8.3 @@ -0,0 +1,68 @@ 8.4 +<html> 8.5 + <head> 8.6 + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> 8.7 + <title><!-- WEBMCP SLOTNODIV app_name --></title> 8.8 + <link rel="stylesheet" type="text/css" media="screen" href="__BASEURL__/static/trace.css" /> 8.9 + <link rel="stylesheet" type="text/css" media="screen" href="__BASEURL__/static/style.css" /> 8.10 + <!-- WEBMCP SLOTNODIV html_head --> 8.11 + </head> 8.12 + <body> 8.13 + <div class="topbar"> 8.14 + <div class="logout_button" id="logout_button"> 8.15 + <!-- WEBMCP SLOT logout_button --> 8.16 + </div> 8.17 + <div class="searchbox" id="searchbox"> 8.18 + <!-- WEBMCP SLOT searchbox --> 8.19 + </div> 8.20 + <div class="navigation" id="navigation"> 8.21 + <!-- WEBMCP SLOT navigation --> 8.22 + </div> 8.23 + </div> 8.24 + <div class="infobox" id="infobox"> 8.25 + <div class="interest" id="interest"> 8.26 + <!-- WEBMCP SLOT interest --> 8.27 + </div> 8.28 + <div class="support" id="support"> 8.29 + <!-- WEBMCP SLOT support --> 8.30 + </div> 8.31 + <div class="delegation" id="delegation"> 8.32 + <!-- WEBMCP SLOT delegation --> 8.33 + </div> 8.34 + </div> 8.35 + <div class="title_bar"> 8.36 + <div class="path" id="path"> 8.37 + <!-- WEBMCP SLOT path --> 8.38 + </div> 8.39 + <div class="title" id="title"> 8.40 + <!-- WEBMCP SLOT title --> 8.41 + </div> 8.42 + <div class="actions" id="actions"> 8.43 + <!-- WEBMCP SLOT actions --> 8.44 + </div> 8.45 + </div> 8.46 + <div class="main" id="default"> 8.47 + <!-- WEBMCP SLOT default --> 8.48 + </div> 8.49 + <div class="layout_trace" id="layout_trace" style="xdisplay: none"> 8.50 + <div id="trace_show" onclick="document.getElementById('trace_content').style.display='block';this.style.display='none';">TRACE</div> 8.51 + <div id="trace_content" style="display: none;"> 8.52 + <!-- WEBMCP SLOT trace --> 8.53 + <div class="trace_close" onclick="document.getElementById('trace_show').style.display='block';document.getElementById('trace_content').style.display='none';"> 8.54 + close 8.55 + </div> 8.56 + </div> 8.57 + </div> 8.58 + </div> 8.59 + <div class="layout_notice" id="layout_notice" onclick="document.getElementById('layout_notice').style.display='none';"> 8.60 + <!-- WEBMCP SLOT notice --> 8.61 + </div> 8.62 + <div class="layout_warning" id="layout_warning" onclick="document.getElementById('layout_warning').style.display='none';"> 8.63 + <!-- WEBMCP SLOT warning --> 8.64 + </div> 8.65 + <div class="layout_error" id="layout_error" onclick="document.getElementById('layout_error').style.display='none';"> 8.66 + <!-- WEBMCP SLOT error --> 8.67 + </div> 8.68 + </body> 8.69 + <script> 8.70 + </script> 8.71 +</html> 8.72 \ No newline at end of file
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/app/main/_layout/rss.html Wed Nov 18 12:00:00 2009 +0100 9.3 @@ -0,0 +1,7 @@ 9.4 +<?xml version="1.0" encoding="utf-8"?> 9.5 + 9.6 +<rss version="2.0"> 9.7 + <channel> 9.8 + <!-- WEBMCP SLOTNODIV default --> 9.9 + </channel> 9.10 +</rss>
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/app/main/_layout/system_error.html Wed Nov 18 12:00:00 2009 +0100 10.3 @@ -0,0 +1,41 @@ 10.4 +<html> 10.5 + <head> 10.6 + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> 10.7 + <title>Liquid Democracy System Error</title> 10.8 + <link rel="stylesheet" type="text/css" media="screen" href="__BASEURL__/static/trace.css" /> 10.9 + <link rel="stylesheet" type="text/css" media="screen" href="__BASEURL__/static/style.css" /> 10.10 + </head> 10.11 + <body class="system_error"> 10.12 + <div class="layout_content"> 10.13 + <div class="layout_title"> 10.14 + <div class="title"> 10.15 + <br /> 10.16 + <br /> 10.17 + System message 10.18 + </div> 10.19 + </div> 10.20 + <br style="clear: left;"> 10.21 + <div class="layout_actions"> 10.22 + 10.23 + </div> 10.24 + <div class="layout_main"> 10.25 + <div class="main"> 10.26 + <tt><!-- WEBMCP SLOT system_error --></tt> 10.27 + <br /> 10.28 + <br /> 10.29 + <br /> 10.30 + <br /> 10.31 + <button onclick="window.location.reload()">Retry request</button> 10.32 + <a href="__BASEURL__">index</a> 10.33 + </div> 10.34 + </div> 10.35 + </div> 10.36 + <div class="layout_trace" id="layout_trace" style="xdisplay: none"> 10.37 + <div id="trace_show" onclick="document.getElementById('trace_content').style.display='block';this.style.display='none';" style="display: none;">TRACE</div> 10.38 + <div id="trace_content"> 10.39 + <!-- WEBMCP SLOT trace --> 10.40 + <div class="trace_close" onclick="document.getElementById('trace_show').style.display='block';document.getElementById('trace_content').style.display='none';">close</div> 10.41 + </div> 10.42 + </div> 10.43 + </body> 10.44 +</html> 10.45 \ No newline at end of file
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/app/main/admin/_action/member_update.lua Wed Nov 18 12:00:00 2009 +0100 11.3 @@ -0,0 +1,37 @@ 11.4 +if not app.session.member.admin then 11.5 + error('access denied') 11.6 +end 11.7 + 11.8 +local id = param.get_id() 11.9 + 11.10 +local member 11.11 + 11.12 +if id then 11.13 + member = Member:new_selector():add_where{"id = ?", id}:single_object_mode():exec() 11.14 +else 11.15 + member = Member:new() 11.16 +end 11.17 + 11.18 +param.update(member, "login", "admin", "name", "ident_number", "active") 11.19 + 11.20 +local password = param.get("password") 11.21 +if password == "********" or #password == 0 then 11.22 + password = nil 11.23 +end 11.24 + 11.25 +if password then 11.26 + member:set_password(password) 11.27 +end 11.28 + 11.29 +local err = member:try_save() 11.30 + 11.31 +if err then 11.32 + slot.put_into("error", (_("Error while updating member, database reported:<br /><br /> (#{errormessage})"):gsub("#{errormessage}", tostring(err.message)))) 11.33 + return false 11.34 +else 11.35 + if id then 11.36 + slot.put_into("notice", _"Member successfully updated") 11.37 + else 11.38 + slot.put_into("notice", _"Member successfully registered") 11.39 + end 11.40 +end 11.41 \ No newline at end of file
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/app/main/admin/area_list.lua Wed Nov 18 12:00:00 2009 +0100 12.3 @@ -0,0 +1,62 @@ 12.4 +local show_not_in_use = param.get("show_not_in_use", atom.boolean) 12.5 + 12.6 +local selector = Area:new_selector() 12.7 +if show_not_in_use then 12.8 + selector:add_where("NOT active") 12.9 +else 12.10 + selector:add_where("active") 12.11 +end 12.12 + 12.13 +local areas = selector:exec() 12.14 + 12.15 +slot.put_into("title", _"Area list") 12.16 + 12.17 +if app.session.member.admin then 12.18 + slot.select("actions", function() 12.19 + if show_not_in_use then 12.20 + ui.link{ 12.21 + attr = { class = { "admin_only" } }, 12.22 + text = _"Show areas in use", 12.23 + module = "admin", 12.24 + view = "area_list" 12.25 + } 12.26 + else 12.27 + ui.link{ 12.28 + attr = { class = { "admin_only" } }, 12.29 + text = _"Create new area", 12.30 + module = "admin", 12.31 + view = "area_show" 12.32 + } 12.33 + ui.link{ 12.34 + attr = { class = { "admin_only" } }, 12.35 + text = _"Show areas not in use", 12.36 + module = "admin", 12.37 + view = "area_list", 12.38 + params = { show_not_in_use = true } 12.39 + } 12.40 + end 12.41 + end) 12.42 +end 12.43 + 12.44 +ui.list{ 12.45 + records = areas, 12.46 + columns = { 12.47 + { 12.48 + label = _"Area", 12.49 + name = "name" 12.50 + }, 12.51 + { 12.52 + content = function(record) 12.53 + if app.session.member.admin then 12.54 + ui.link{ 12.55 + attr = { class = { "action admin_only" } }, 12.56 + text = _"Edit", 12.57 + module = "admin", 12.58 + view = "area_show", 12.59 + id = record.id 12.60 + } 12.61 + end 12.62 + end 12.63 + } 12.64 + } 12.65 +} 12.66 \ No newline at end of file
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 13.2 +++ b/app/main/admin/area_show.lua Wed Nov 18 12:00:00 2009 +0100 13.3 @@ -0,0 +1,29 @@ 13.4 +local id = param.get_id() 13.5 + 13.6 +local area 13.7 +if id then 13.8 + area = Area:new_selector():add_where{ "id = ?", id }:single_object_mode():exec() 13.9 +end 13.10 + 13.11 +slot.put_into("title", _"Create new area") 13.12 + 13.13 +ui.form{ 13.14 + attr = { class = "vertical" }, 13.15 + record = area, 13.16 + module = "area", 13.17 + action = "update", 13.18 + routing = { 13.19 + default = { 13.20 + mode = "redirect", 13.21 + module = "admin", 13.22 + view = "area_list" 13.23 + } 13.24 + }, 13.25 + id = area and area.id or nil, 13.26 + content = function() 13.27 + ui.field.text{ label = _"Name", name = "name" } 13.28 + ui.field.boolean{ label = _"Active?", name = "active" } 13.29 + ui.field.text{ label = _"Description", name = "description", multiline = true } 13.30 + ui.submit{ text = _"Save" } 13.31 + end 13.32 +}
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 14.2 +++ b/app/main/admin/index.lua Wed Nov 18 12:00:00 2009 +0100 14.3 @@ -0,0 +1,25 @@ 14.4 +slot.put_into("title", _"Admin menu") 14.5 + 14.6 +ui.link{ 14.7 + text = "Members", 14.8 + module = "admin", 14.9 + view = "member_list", 14.10 +} 14.11 + 14.12 +slot.put("<br />") 14.13 + 14.14 +ui.link{ 14.15 + text = "Areas", 14.16 + module = "admin", 14.17 + view = "area_list", 14.18 +} 14.19 + 14.20 +slot.put("<br />") 14.21 + 14.22 + 14.23 +ui.link{ 14.24 + text = "Policies", 14.25 + module = "admin", 14.26 + view = "policy_list", 14.27 +} 14.28 +
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 15.2 +++ b/app/main/admin/member_edit.lua Wed Nov 18 12:00:00 2009 +0100 15.3 @@ -0,0 +1,34 @@ 15.4 +local id = param.get_id() 15.5 + 15.6 +local member 15.7 +if id then 15.8 + member = Member:new_selector():add_where{"id = ?", id}:optional_object_mode():exec() 15.9 + slot.put_into("title", encode.html(_("Member: '#{login}' (#{name})", { login = member.login, name = member.name }))) 15.10 +else 15.11 + slot.put_into("title", encode.html(_"Register new member")) 15.12 +end 15.13 + 15.14 +ui.form{ 15.15 + attr = { class = "vertical" }, 15.16 + module = "admin", 15.17 + action = "member_update", 15.18 + id = member and member.id, 15.19 + record = member, 15.20 + readonly = not app.session.member.admin, 15.21 + routing = { 15.22 + default = { 15.23 + mode = "redirect", 15.24 + modules = "admin", 15.25 + view = "member_list" 15.26 + } 15.27 + }, 15.28 + content = function() 15.29 + ui.field.text{ label = _"Login", name = "login" } 15.30 + ui.field.text{ label = _"Name", name = "name" } 15.31 + ui.field.password{ label = _"Password", name = "password", value = (member and member.password) and "********" or "" } 15.32 + ui.field.boolean{ label = _"Admin?", name = "admin" } 15.33 + ui.field.boolean{ label = _"Active?", name = "active" } 15.34 + ui.field.text{ label = _"Ident number", name = "ident_number" } 15.35 + ui.submit{ text = _"Save" } 15.36 + end 15.37 +}
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 16.2 +++ b/app/main/admin/member_list.lua Wed Nov 18 12:00:00 2009 +0100 16.3 @@ -0,0 +1,92 @@ 16.4 +slot.put_into("title", _"Member list") 16.5 + 16.6 +slot.select("actions", function() 16.7 + ui.link{ 16.8 + attr = { class = { "admin_only" } }, 16.9 + text = _"Register new member", 16.10 + module = "admin", 16.11 + view = "member_edit" 16.12 + } 16.13 + if param.get("show_locked") then 16.14 + ui.link{ 16.15 + attr = { class = { "admin_only" } }, 16.16 + text = _"Show active members", 16.17 + module = "admin", 16.18 + view = "member_list" 16.19 + } 16.20 + else 16.21 + ui.link{ 16.22 + attr = { class = { "admin_only" } }, 16.23 + text = _"Show locked members", 16.24 + module = "admin", 16.25 + view = "member_list", 16.26 + params = { show_locked = true } 16.27 + } 16.28 + end 16.29 +end) 16.30 + 16.31 +local members_selector 16.32 + 16.33 +if param.get("show_locked", atom.boolean) then 16.34 + members_selector = Member:new_selector() 16.35 + :add_where("not active") 16.36 + :add_order_by("login") 16.37 +else 16.38 + members_selector = Member:new_selector() 16.39 + :add_where("active") 16.40 + :add_order_by("login") 16.41 +end 16.42 + 16.43 +ui.paginate{ 16.44 + selector = members_selector, 16.45 + content = function() 16.46 + ui.list{ 16.47 + records = members_selector:exec(), 16.48 + columns = { 16.49 + { 16.50 + field_attr = { style = "text-align: right;" }, 16.51 + label = _"Id", 16.52 + name = "id" 16.53 + }, 16.54 + { 16.55 + label = _"Login", 16.56 + name = "login" 16.57 + }, 16.58 + { 16.59 + label = _"Name", 16.60 + content = function(record) 16.61 + util.put_highlighted_string(record.name) 16.62 + end 16.63 + }, 16.64 + { 16.65 + label = _"Ident number", 16.66 + name = "ident_number" 16.67 + }, 16.68 + { 16.69 + label = _"Admin?", 16.70 + name = "admin" 16.71 + }, 16.72 + { 16.73 + content = function(record) 16.74 + if app.session.member.admin and not record.active then 16.75 + ui.field.text{ value = "locked" } 16.76 + end 16.77 + end 16.78 + }, 16.79 + { 16.80 + content = function(record) 16.81 + if app.session.member.admin then 16.82 + ui.link{ 16.83 + attr = { class = "action admin_only" }, 16.84 + text = _"Edit", 16.85 + module = "admin", 16.86 + view = "member_edit", 16.87 + id = record.id 16.88 + } 16.89 + end 16.90 + end 16.91 + } 16.92 + } 16.93 + } 16.94 + end 16.95 +} 16.96 \ No newline at end of file
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 17.2 +++ b/app/main/area/_action/update.lua Wed Nov 18 12:00:00 2009 +0100 17.3 @@ -0,0 +1,15 @@ 17.4 +local id = param.get_id() 17.5 + 17.6 +local area 17.7 +if id then 17.8 + area = Area:new_selector():add_where{ "id = ?", id }:single_object_mode():exec() 17.9 +else 17.10 + area = Area:new() 17.11 +end 17.12 + 17.13 + 17.14 +param.update(area, "name", "description", "active") 17.15 + 17.16 +area:save() 17.17 + 17.18 +slot.put_into("notice", _"Area successfully updated")
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 18.2 +++ b/app/main/area/_list.lua Wed Nov 18 12:00:00 2009 +0100 18.3 @@ -0,0 +1,61 @@ 18.4 +local areas_selector = param.get("areas_selector", "table") 18.5 + 18.6 +ui.order{ 18.7 + name = name, 18.8 + selector = areas_selector, 18.9 + options = { 18.10 + { 18.11 + name = "member_weight", 18.12 + label = _"Population", 18.13 + order_by = "area.member_weight DESC" 18.14 + }, 18.15 + { 18.16 + name = "direct_member_count", 18.17 + label = _"Direct member count", 18.18 + order_by = "area.direct_member_count DESC" 18.19 + }, 18.20 + { 18.21 + name = "az", 18.22 + label = _"A-Z", 18.23 + order_by = "area.name" 18.24 + }, 18.25 + { 18.26 + name = "za", 18.27 + label = _"Z-A", 18.28 + order_by = "area.name DESC" 18.29 + } 18.30 + }, 18.31 + content = function() 18.32 + ui.list{ 18.33 + records = areas_selector:exec(), 18.34 + columns = { 18.35 + { 18.36 + content = function(record) 18.37 + if record.member_weight and record.direct_member_count then 18.38 + local max_value = MemberCount:get() 18.39 + ui.bargraph{ 18.40 + max_value = max_value, 18.41 + width = 100, 18.42 + bars = { 18.43 + { color = "#444", value = record.direct_member_count }, 18.44 + { color = "#777", value = record.member_weight - record.direct_member_count }, 18.45 + { color = "#ddd", value = max_value - record.member_weight }, 18.46 + } 18.47 + } 18.48 + end 18.49 + end 18.50 + }, 18.51 + { 18.52 + content = function(record) 18.53 + ui.link{ 18.54 + text = record.name, 18.55 + module = "area", 18.56 + view = "show", 18.57 + id = record.id 18.58 + } 18.59 + end 18.60 + } 18.61 + } 18.62 + } 18.63 + end 18.64 +} 18.65 \ No newline at end of file
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 19.2 +++ b/app/main/area/list.lua Wed Nov 18 12:00:00 2009 +0100 19.3 @@ -0,0 +1,14 @@ 19.4 +slot.put_into("title", _'Area list') 19.5 + 19.6 +local areas_selector = Area:new_selector():add_where("active") 19.7 + 19.8 +execute.view{ 19.9 + module = "area", 19.10 + view = "_list", 19.11 + params = { areas_selector = areas_selector } 19.12 +} 19.13 + 19.14 +execute.view{ 19.15 + module = "delegation", 19.16 + view = "_show_box" 19.17 +} 19.18 \ No newline at end of file
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 20.2 +++ b/app/main/area/show.lua Wed Nov 18 12:00:00 2009 +0100 20.3 @@ -0,0 +1,114 @@ 20.4 +local area = Area:new_selector():add_where{ "id = ?", param.get_id() }:single_object_mode():exec() 20.5 + 20.6 +slot.put_into("title", encode.html(_"Area '#{name}'":gsub("#{name}", area.name))) 20.7 + 20.8 +ui.container{ 20.9 + attr = { class = "vertical"}, 20.10 + content = function() 20.11 + ui.field.text{ value = area.description } 20.12 + end 20.13 +} 20.14 + 20.15 + 20.16 +slot.select("actions", function() 20.17 + ui.link{ 20.18 + content = function() 20.19 + ui.image{ static = "icons/16/folder_add.png" } 20.20 + slot.put(_"Create new issue") 20.21 + end, 20.22 + module = "initiative", 20.23 + view = "new", 20.24 + params = { area_id = area.id } 20.25 + } 20.26 + ui.link{ 20.27 + content = function() 20.28 + ui.image{ static = "icons/16/table_go.png" } 20.29 + slot.put(_"Delegate") 20.30 + end, 20.31 + module = "delegation", 20.32 + view = "new", 20.33 + params = { area_id = area.id } 20.34 + } 20.35 +end) 20.36 + 20.37 +execute.view{ 20.38 + module = "membership", 20.39 + view = "_show_box", 20.40 + params = { area = area } 20.41 +} 20.42 + 20.43 +execute.view{ 20.44 + module = "delegation", 20.45 + view = "_show_box", 20.46 + params = { area_id = area.id } 20.47 +} 20.48 + 20.49 +ui.tabs{ 20.50 + { 20.51 + name = "new", 20.52 + label = _"New", 20.53 + content = function() 20.54 + execute.view{ 20.55 + module = "issue", 20.56 + view = "_list", 20.57 + params = { issues_selector = area:get_reference_selector("issues"):add_where("issue.accepted ISNULL AND issue.closed ISNULL"), for_area_list = true } 20.58 + } 20.59 + end 20.60 + }, 20.61 + { 20.62 + name = "accepted", 20.63 + label = _"In discussion", 20.64 + content = function() 20.65 + execute.view{ 20.66 + module = "issue", 20.67 + view = "_list", 20.68 + params = { issues_selector = area:get_reference_selector("issues"):add_where("issue.accepted NOTNULL AND issue.half_frozen ISNULL AND issue.closed ISNULL"), for_area_list = true } 20.69 + } 20.70 + end 20.71 + }, 20.72 + { 20.73 + name = "half_frozen", 20.74 + label = _"Frozen", 20.75 + content = function() 20.76 + execute.view{ 20.77 + module = "issue", 20.78 + view = "_list", 20.79 + params = { issues_selector = area:get_reference_selector("issues"):add_where("issue.half_frozen NOTNULL AND issue.closed ISNULL"), for_area_list = true } 20.80 + } 20.81 + end 20.82 + }, 20.83 + { 20.84 + name = "frozen", 20.85 + label = _"Voting", 20.86 + content = function() 20.87 + execute.view{ 20.88 + module = "issue", 20.89 + view = "_list", 20.90 + params = { issues_selector = area:get_reference_selector("issues"):add_where("issue.fully_frozen NOTNULL AND issue.closed ISNULL"), for_area_list = true } 20.91 + } 20.92 + end 20.93 + }, 20.94 + { 20.95 + name = "finished", 20.96 + label = _"Finished", 20.97 + content = function() 20.98 + execute.view{ 20.99 + module = "issue", 20.100 + view = "_list", 20.101 + params = { issues_selector = area:get_reference_selector("issues"):add_where("issue.closed NOTNULL AND ranks_available"), for_area_list = true } 20.102 + } 20.103 + end 20.104 + }, 20.105 + { 20.106 + name = "cancelled", 20.107 + label = _"Cancelled", 20.108 + content = function() 20.109 + execute.view{ 20.110 + module = "issue", 20.111 + view = "_list", 20.112 + params = { issues_selector = area:get_reference_selector("issues"):add_where("issue.closed NOTNULL AND NOT ranks_available"), for_area_list = true } 20.113 + } 20.114 + end 20.115 + }, 20.116 +} 20.117 +
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 21.2 +++ b/app/main/contact/_action/add_member.lua Wed Nov 18 12:00:00 2009 +0100 21.3 @@ -0,0 +1,27 @@ 21.4 +local member = app.session.member 21.5 +local other_member = Member:by_id(param.get_id()) 21.6 + 21.7 +local public = param.get("public", atom.boolean) 21.8 + 21.9 +local contact = Contact:by_pk(member.id, other_member.id) 21.10 + 21.11 +if public == nil and contact then 21.12 + slot.put_into("error", _"Member is already saved in your contacts!") 21.13 + return false 21.14 +end 21.15 + 21.16 +if contact then 21.17 + contact:destroy() 21.18 +end 21.19 + 21.20 +contact = Contact:new() 21.21 +contact.member_id = member.id 21.22 +contact.other_member_id = other_member.id 21.23 +contact.public = public or false 21.24 +contact:save() 21.25 + 21.26 +if public then 21.27 + slot.put_into("notice", _"Member has been saved as public contact") 21.28 +else 21.29 + slot.put_into("notice", _"Member has been saved as private contact") 21.30 +end
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 22.2 +++ b/app/main/contact/_action/remove_member.lua Wed Nov 18 12:00:00 2009 +0100 22.3 @@ -0,0 +1,7 @@ 22.4 +local member = app.session.member 22.5 +local other_member = Member:by_id(param.get_id()) 22.6 + 22.7 +local contact = Contact:by_pk(member.id, other_member.id) 22.8 +contact:destroy() 22.9 + 22.10 +slot.put_into("notice", _"Member has been removed from your contacts")
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 23.2 +++ b/app/main/contact/_list.lua Wed Nov 18 12:00:00 2009 +0100 23.3 @@ -0,0 +1,132 @@ 23.4 + 23.5 +local contacts_selector = Contact:new_selector() 23.6 + :add_where{ "member_id = ?", app.session.member.id } 23.7 + :join("member", nil, "member.id = contact.other_member_id") 23.8 + :add_order_by("member.login") 23.9 + 23.10 +ui.paginate{ 23.11 + selector = contacts_selector, 23.12 + content = function() 23.13 + local contacts = contacts_selector:exec() 23.14 + if #contacts == 0 then 23.15 + ui.field.text{ value = _"You didn't saved any member as contact yet." } 23.16 + else 23.17 + ui.list{ 23.18 + records = contacts, 23.19 + columns = { 23.20 + { 23.21 + label = _"Login", 23.22 + content = function(record) 23.23 + ui.link{ 23.24 + text = record.other_member.login, 23.25 + module = "member", 23.26 + view = "show", 23.27 + id = record.other_member_id 23.28 + } 23.29 + end 23.30 + }, 23.31 + { 23.32 + label = _"Name", 23.33 + content = function(record) 23.34 + ui.link{ 23.35 + text = record.other_member.name, 23.36 + module = "member", 23.37 + view = "show", 23.38 + id = record.other_member_id 23.39 + } 23.40 + end 23.41 + }, 23.42 + { 23.43 + label = _"Published", 23.44 + content = function(record) 23.45 + ui.field.boolean{ value = record.public } 23.46 + end 23.47 + }, 23.48 + { 23.49 + content = function(record) 23.50 + if record.public then 23.51 + ui.link{ 23.52 + attr = { class = "action" }, 23.53 + text = _"Hide", 23.54 + module = "contact", 23.55 + action = "add_member", 23.56 + id = record.other_member_id, 23.57 + params = { public = false }, 23.58 + routing = { 23.59 + default = { 23.60 + mode = "redirect", 23.61 + module = request.get_module(), 23.62 + view = request.get_view(), 23.63 + id = param.get_id_cgi(), 23.64 + params = param.get_all_cgi() 23.65 + } 23.66 + } 23.67 + } 23.68 + else 23.69 + ui.link{ 23.70 + attr = { class = "action" }, 23.71 + text = _"Publish", 23.72 + module = "contact", 23.73 + action = "add_member", 23.74 + id = record.other_member_id, 23.75 + params = { public = true }, 23.76 + routing = { 23.77 + default = { 23.78 + mode = "redirect", 23.79 + module = request.get_module(), 23.80 + view = request.get_view(), 23.81 + id = param.get_id_cgi(), 23.82 + params = param.get_all_cgi() 23.83 + } 23.84 + } 23.85 + } 23.86 + end 23.87 + end 23.88 + }, 23.89 + { 23.90 + content = function(record) 23.91 + ui.link{ 23.92 + attr = { class = "action" }, 23.93 + text = _"Remove", 23.94 + module = "contact", 23.95 + action = "remove_member", 23.96 + id = record.other_member_id, 23.97 + routing = { 23.98 + default = { 23.99 + mode = "redirect", 23.100 + module = request.get_module(), 23.101 + view = request.get_view(), 23.102 + id = param.get_id_cgi(), 23.103 + params = param.get_all_cgi() 23.104 + } 23.105 + } 23.106 + } 23.107 + end 23.108 + }, 23.109 + { 23.110 + content = function(record) 23.111 + ui.link{ 23.112 + attr = { class = "action" }, 23.113 + text = _"Global delegation", 23.114 + module = "delegation", 23.115 + action = "update", 23.116 + params = { 23.117 + trustee_id = record.other_member_id, 23.118 + }, 23.119 + routing = { 23.120 + default = { 23.121 + mode = "redirect", 23.122 + module = request.get_module(), 23.123 + view = request.get_view(), 23.124 + id = param.get_id_cgi(), 23.125 + params = param.get_all_cgi() 23.126 + } 23.127 + } 23.128 + } 23.129 + end 23.130 + } 23.131 + } 23.132 + } 23.133 + end 23.134 + end 23.135 +} 23.136 \ No newline at end of file
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 24.2 +++ b/app/main/contact/list.lua Wed Nov 18 12:00:00 2009 +0100 24.3 @@ -0,0 +1,7 @@ 24.4 +slot.put_into("title", _"Contacts") 24.5 + 24.6 +execute.view{ 24.7 + module = "contact", 24.8 + view = "_list", 24.9 + params = { contacts_selector = app.session.member:get_reference_selector("contacts") } 24.10 +}
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 25.2 +++ b/app/main/delegation/_action/update.lua Wed Nov 18 12:00:00 2009 +0100 25.3 @@ -0,0 +1,53 @@ 25.4 +local truster_id = app.session.member.id 25.5 + 25.6 +local trustee_id = param.get("trustee_id", atom.integer) 25.7 + 25.8 +local area_id = param.get("area_id", atom.integer) 25.9 + 25.10 +local issue_id = param.get("issue_id", atom.integer) 25.11 + 25.12 +if issue_id then 25.13 + area_id = nil 25.14 +end 25.15 + 25.16 +local delegation = Delegation:by_pk(truster_id, area_id, issue_id) 25.17 + 25.18 +if param.get("delete") then 25.19 + 25.20 + if delegation then 25.21 + 25.22 + delegation:destroy() 25.23 + 25.24 + if issue_id then 25.25 + slot.put_into("notice", _"Your delegation for this issue has been deleted.") 25.26 + elseif area_id then 25.27 + slot.put_into("notice", _"Your delegation for this area has been deleted.") 25.28 + else 25.29 + slot.put_into("notice", _"Your global delegation has been deleted.") 25.30 + end 25.31 + 25.32 + end 25.33 + 25.34 +else 25.35 + 25.36 + if not delegation then 25.37 + delegation = Delegation:new() 25.38 + delegation.truster_id = truster_id 25.39 + delegation.area_id = area_id 25.40 + delegation.issue_id = issue_id 25.41 + end 25.42 + 25.43 + delegation.trustee_id = trustee_id 25.44 + 25.45 + delegation:save() 25.46 + 25.47 + if issue_id then 25.48 + slot.put_into("notice", _"Your delegation for this issue has been updated.") 25.49 + elseif area_id then 25.50 + slot.put_into("notice", _"Your delegation for this area has been updated.") 25.51 + else 25.52 + slot.put_into("notice", _"Your global delegation has been updated.") 25.53 + end 25.54 + 25.55 +end 25.56 +
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 26.2 +++ b/app/main/delegation/_list.lua Wed Nov 18 12:00:00 2009 +0100 26.3 @@ -0,0 +1,50 @@ 26.4 +local selector = param.get("selector", "table") 26.5 + 26.6 +ui.paginate{ 26.7 + selector = selector, 26.8 + content = function() 26.9 + ui.list{ 26.10 + records = selector:exec(), 26.11 + columns = { 26.12 + { 26.13 + label = _"Truster", 26.14 + content = function(record) 26.15 + ui.link{ 26.16 + content = record.truster.name, 26.17 + module = "member", 26.18 + view = "show", 26.19 + id = record.truster.id 26.20 + } 26.21 + end 26.22 + }, 26.23 + { 26.24 + label = _"Trustee", 26.25 + content = function(record) 26.26 + ui.link{ 26.27 + content = record.trustee.name, 26.28 + module = "member", 26.29 + view = "show", 26.30 + id = record.trustee.id 26.31 + } 26.32 + end 26.33 + }, 26.34 + { 26.35 + label = _"Area", 26.36 + content = function(record) 26.37 + if record.area then 26.38 + ui.field.text{ value = record.area.name } 26.39 + end 26.40 + end 26.41 + }, 26.42 + { 26.43 + label = _"Issue", 26.44 + content = function(record) 26.45 + if record.issue then 26.46 + ui.field.text{ value = record.issue.id } 26.47 + end 26.48 + end 26.49 + }, 26.50 + } 26.51 + } 26.52 + end 26.53 +}
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 27.2 +++ b/app/main/delegation/_show_box.lua Wed Nov 18 12:00:00 2009 +0100 27.3 @@ -0,0 +1,114 @@ 27.4 +slot.select("delegation", function() 27.5 + 27.6 + local delegation 27.7 + local area_id 27.8 + local issue_id 27.9 + 27.10 + local scope = "global" 27.11 + 27.12 + if param.get("initiative_id", atom.integer) then 27.13 + issue_id = Initiative:by_id(param.get("initiative_id", atom.integer)).issue_id 27.14 + scope = "issue" 27.15 + end 27.16 + 27.17 + if param.get("issue_id", atom.integer) then 27.18 + issue_id = param.get("issue_id", atom.integer) 27.19 + scope = "issue" 27.20 + end 27.21 + 27.22 + if param.get("area_id", atom.integer) then 27.23 + area_id = param.get("area_id", atom.integer) 27.24 + scope = "area" 27.25 + end 27.26 + 27.27 + 27.28 + 27.29 + local delegation 27.30 + 27.31 + if issue_id then 27.32 + delegation = Delegation:by_pk(app.session.member.id, nil, issue_id) 27.33 + if not delegation then 27.34 + local issue = Issue:by_id(issue_id) 27.35 + delegation = Delegation:by_pk(app.session.member.id, issue.area_id) 27.36 + end 27.37 + elseif area_id then 27.38 + delegation = Delegation:by_pk(app.session.member.id, area_id) 27.39 + end 27.40 + 27.41 + if not delegation then 27.42 + delegation = Delegation:by_pk(app.session.member.id) 27.43 + end 27.44 + if delegation then 27.45 + ui.container{ 27.46 + attr = { 27.47 + class = "head", 27.48 + style = "cursor: pointer;", 27.49 + onclick = "document.getElementById('delegation_content').style.display = 'block';" 27.50 + }, 27.51 + content = _"Your vote is delegated. [more]" 27.52 + } 27.53 + ui.container{ 27.54 + attr = { class = "content", id = "delegation_content" }, 27.55 + content = function() 27.56 + 27.57 + local delegation_chain = db:query{ "SELECT * FROM delegation_chain(?, ?, ?) JOIN member ON member.id = member_id ORDER BY index", app.session.member.id, area_id, issue_id } 27.58 + 27.59 + for i, record in ipairs(delegation_chain) do 27.60 + local style 27.61 + if record.participation then 27.62 + style = "font-weight: bold;" 27.63 + end 27.64 + if record.overridden then 27.65 + style = "color: #777;" 27.66 + end 27.67 + if not record.active then 27.68 + style = "text-decoration: line-through;" 27.69 + end 27.70 + if record.scope_in then 27.71 + ui.field.text{ 27.72 + value = " v " .. record.scope_in .. " v " 27.73 + } 27.74 + end 27.75 + local name = record.name 27.76 + if record.member_id == app.session.member.id then 27.77 + name = _"Me" 27.78 + end 27.79 + ui.field.text{ 27.80 + attr = { style = style }, 27.81 + value = name 27.82 + } 27.83 + end 27.84 + 27.85 + ui.link{ 27.86 + attr = { class = "revoke" }, 27.87 + content = function() 27.88 + ui.image{ static = "icons/16/delete.png" } 27.89 + slot.put(_"Revoke") 27.90 + end, 27.91 + module = "delegation", 27.92 + action = "update", 27.93 + params = { issue_id = delegation.issue_id, area_id = delegation.area_id, delete = true }, 27.94 + routing = { 27.95 + default = { 27.96 + mode = "redirect", 27.97 + module = request.get_module(), 27.98 + view = request.get_view(), 27.99 + id = param.get_id_cgi(), 27.100 + params = param.get_all_cgi() 27.101 + } 27.102 + } 27.103 + } 27.104 + 27.105 + ui.container{ 27.106 + attr = { 27.107 + class = "head", 27.108 + style = "cursor: pointer;", 27.109 + onclick = "document.getElementById('delegation_content').style.display = 'none';" 27.110 + }, 27.111 + content = _"Click here to close." 27.112 + } 27.113 + end 27.114 + } 27.115 + end 27.116 + 27.117 +end)
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 28.2 +++ b/app/main/delegation/new.lua Wed Nov 18 12:00:00 2009 +0100 28.3 @@ -0,0 +1,45 @@ 28.4 +local area = Area:by_id(param.get("area_id", atom.integer)) 28.5 +if area then 28.6 + slot.put_into("title", encode.html(_"Set delegation for Area '#{name}'":gsub("#{name}", area.name))) 28.7 +end 28.8 + 28.9 +local issue = Issue:by_id(param.get("issue_id", atom.integer)) 28.10 +if issue then 28.11 + slot.put_into("title", encode.html(_"Set delegation for Issue ##{number} in Area '#{area_name}'":gsub("#{number}", issue.id):gsub("#{area_name}", issue.area.name))) 28.12 +end 28.13 + 28.14 + 28.15 +local contact_members = Member:new_selector() 28.16 + :add_where{ "contact.member_id = ?", app.session.member.id } 28.17 + :join("contact", nil, "member.id = contact.other_member_id") 28.18 + :add_order_by("member.login") 28.19 + :exec() 28.20 + 28.21 + 28.22 +ui.form{ 28.23 + attr = { class = "vertical" }, 28.24 + module = "delegation", 28.25 + action = "update", 28.26 + params = { 28.27 + area_id = area and area.id or nil, 28.28 + issue_id = issue and issue.id or nil, 28.29 + }, 28.30 + routing = { 28.31 + default = { 28.32 + mode = "redirect", 28.33 + module = area and "area" or "issue", 28.34 + view = "show", 28.35 + id = area and area.id or issue.id, 28.36 + } 28.37 + }, 28.38 + content = function() 28.39 + ui.field.select{ 28.40 + label = _"Trustee", 28.41 + name = "trustee_id", 28.42 + foreign_records = contact_members, 28.43 + foreign_id = "id", 28.44 + foreign_name = "name" 28.45 + } 28.46 + ui.submit{ text = _"Save" } 28.47 + end 28.48 +} 28.49 \ No newline at end of file
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 29.2 +++ b/app/main/draft/_action/add.lua Wed Nov 18 12:00:00 2009 +0100 29.3 @@ -0,0 +1,14 @@ 29.4 +local initiative = Initiative:by_id(param.get("initiative_id", atom.integer)) 29.5 + 29.6 +if Initiator:by_pk(initiative.id, app.session.member.id) then 29.7 + local draft = Draft:new() 29.8 + draft.author_id = app.session.member.id 29.9 + draft.initiative_id = initiative.id 29.10 + draft.content = param.get("content") 29.11 + draft:save() 29.12 + 29.13 + slot.put_into("notice", _"New draft has been added to initiative") 29.14 + 29.15 +else 29.16 + error('access denied') 29.17 +end
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 30.2 +++ b/app/main/draft/_list.lua Wed Nov 18 12:00:00 2009 +0100 30.3 @@ -0,0 +1,30 @@ 30.4 +ui.list{ 30.5 + records = param.get("drafts", "table"), 30.6 + columns = { 30.7 + { 30.8 + label = _"Id", 30.9 + name = "id" 30.10 + }, 30.11 + { 30.12 + label = _"Created at", 30.13 + content = function(record) 30.14 + ui.field.text{ value = format.timestamp(record.created) } 30.15 + end 30.16 + }, 30.17 + { 30.18 + label = _"Author", 30.19 + name = "author_name" 30.20 + }, 30.21 + { 30.22 + content = function(record) 30.23 + ui.link{ 30.24 + attr = { class = "action" }, 30.25 + text = _"Show", 30.26 + module = "draft", 30.27 + view = "show", 30.28 + id = record.id 30.29 + } 30.30 + end 30.31 + } 30.32 + } 30.33 +}
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 31.2 +++ b/app/main/draft/_show.lua Wed Nov 18 12:00:00 2009 +0100 31.3 @@ -0,0 +1,14 @@ 31.4 +local draft = param.get("draft", "table") 31.5 + 31.6 +ui.form{ 31.7 + attr = { class = "vertical" }, 31.8 + record = draft, 31.9 + readonly = true, 31.10 + content = function() 31.11 + 31.12 + ui.field.text{ label = _"Initiative", value = draft.initiative.name } 31.13 + ui.field.text{ label = _"Author", name = "author_name" } 31.14 + ui.field.text{ label = _"Content", name = "content" } 31.15 + 31.16 + end 31.17 +}
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 32.2 +++ b/app/main/draft/new.lua Wed Nov 18 12:00:00 2009 +0100 32.3 @@ -0,0 +1,25 @@ 32.4 +slot.put_into("title", _"Add new draft") 32.5 + 32.6 +local initiative_id = param.get("initiative_id") 32.7 + 32.8 +ui.form{ 32.9 + attr = { class = "vertical" }, 32.10 + module = "draft", 32.11 + action = "add", 32.12 + params = { initiative_id = initiative_id }, 32.13 + routing = { 32.14 + default = { 32.15 + mode = "redirect", 32.16 + module = "initiative", 32.17 + view = "show", 32.18 + id = initiative_id 32.19 + } 32.20 + }, 32.21 + content = function() 32.22 + 32.23 + ui.field.text{ label = _"Author", value = app.session.member.name, readonly = true } 32.24 + ui.field.text{ label = _"Content", name = "content", multiline = true } 32.25 + 32.26 + ui.submit{ text = _"Save" } 32.27 + end 32.28 +}
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 33.2 +++ b/app/main/draft/show.lua Wed Nov 18 12:00:00 2009 +0100 33.3 @@ -0,0 +1,7 @@ 33.4 +local draft = Draft:new_selector():add_where{ "id = ?", param.get_id() }:single_object_mode():exec() 33.5 + 33.6 +execute.view{ 33.7 + module = "draft", 33.8 + view = "_show", 33.9 + params = { draft = draft } 33.10 +} 33.11 \ No newline at end of file
34.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 34.2 +++ b/app/main/index/_action/login.lua Wed Nov 18 12:00:00 2009 +0100 34.3 @@ -0,0 +1,16 @@ 34.4 +local member = Member:by_login_and_password(param.get('login'), param.get('password')) 34.5 + 34.6 +if member then 34.7 + app.session.member = member 34.8 + app.session:save() 34.9 + slot.select("notice", function() 34.10 + ui.tag{ content = _'Login successful!' } 34.11 + end) 34.12 + trace.debug('User authenticated') 34.13 +else 34.14 + slot.select("notice", function() 34.15 + ui.tag{ content = _'Invalid username or password!' } 34.16 + end) 34.17 + trace.debug('User NOT authenticated') 34.18 + return false 34.19 +end
35.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 35.2 +++ b/app/main/index/_action/logout.lua Wed Nov 18 12:00:00 2009 +0100 35.3 @@ -0,0 +1,4 @@ 35.4 +if app.session then 35.5 + app.session:destroy() 35.6 + slot.put_into("notice", _"Logout successful") 35.7 +end
36.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 36.2 +++ b/app/main/index/_action/set_lang.lua Wed Nov 18 12:00:00 2009 +0100 36.3 @@ -0,0 +1,3 @@ 36.4 +app.session.lang = param.get("lang") 36.5 + 36.6 +app.session:save() 36.7 \ No newline at end of file
37.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 37.2 +++ b/app/main/index/_action/update_password.lua Wed Nov 18 12:00:00 2009 +0100 37.3 @@ -0,0 +1,23 @@ 37.4 +local old_password = param.get("old_password") 37.5 +local new_password1 = param.get("new_password1") 37.6 +local new_password2 = param.get("new_password2") 37.7 + 37.8 +if not Member:by_login_and_password(app.session.member.login, old_password) then 37.9 + slot.put_into("error", _"Old password is wrong") 37.10 + return false 37.11 +end 37.12 + 37.13 +if new_password1 ~= new_password2 then 37.14 + slot.put_into("error", _"New passwords does not match.") 37.15 + return false 37.16 +end 37.17 + 37.18 +if #new_password1 < 8 then 37.19 + slot.put_into("error", _"New passwords is too short.") 37.20 + return false 37.21 +end 37.22 + 37.23 +app.session.member:set_password(new_password1) 37.24 +app.session.member:save() 37.25 + 37.26 +slot.put_into("notice", _"Your password has been updated successfully")
38.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 38.2 +++ b/app/main/index/about.lua Wed Nov 18 12:00:00 2009 +0100 38.3 @@ -0,0 +1,92 @@ 38.4 +slot.put_into("title", encode.html(_"About LiquidFeedback")) 38.5 + 38.6 + 38.7 +slot.put("<br />") 38.8 +ui.field.text{ attr = { style = "font-weight: bold;" }, value = "Diensteanbieter:" } 38.9 +slot.put("<br />") 38.10 + 38.11 +slot.put(config.app_service_provider) 38.12 + 38.13 +slot.put("<br />") 38.14 +slot.put("<br />") 38.15 +slot.put("<br />") 38.16 + 38.17 + 38.18 +ui.field.text{ attr = { style = "font-weight: bold;" }, value = "Dieser Dienst ist mit folgender Software realisiert worden:" } 38.19 +slot.put("<br />") 38.20 + 38.21 +local tmp = { 38.22 + { 38.23 + name = "LiquidFeedback Frontend", 38.24 + url = "http://www.public-software-group.org/liquid_feedback", 38.25 + version = config.app_version, 38.26 + license = "MIT/X11", 38.27 + license_url = "http://www.public-software-group.org/licenses" 38.28 + }, 38.29 + { 38.30 + name = "LiquidFeedback Core", 38.31 + url = "http://www.public-software-group.org/liquid_feedback", 38.32 + version = db:query("SELECT * from liquid_feedback_version;")[1].string, 38.33 + license = "MIT/X11", 38.34 + license_url = "http://www.public-software-group.org/licenses" 38.35 + }, 38.36 + { 38.37 + name = "WebMCP", 38.38 + url = "http://www.public-software-group.org/webmcp", 38.39 + version = _WEBMCP_VERSION, 38.40 + license = "MIT/X11", 38.41 + license_url = "http://www.public-software-group.org/licenses" 38.42 + }, 38.43 + { 38.44 + name = "Lua", 38.45 + url = "http://www.lua.org", 38.46 + version = _VERSION:gsub("Lua ", ""), 38.47 + license = "MIT/X11", 38.48 + license_url = "http://www.lua.org/license.html" 38.49 + }, 38.50 + { 38.51 + name = "PostgreSQL", 38.52 + url = "http://www.postgresql.org/", 38.53 + version = db:query("SELECT version();")[1].version:gsub("PostgreSQL ", ""):gsub("on.*", ""), 38.54 + license = "BSD", 38.55 + license_url = "http://www.postgresql.org/about/licence" 38.56 + }, 38.57 +} 38.58 + 38.59 +ui.list{ 38.60 + records = tmp, 38.61 + columns = { 38.62 + { 38.63 + label = _"Software", 38.64 + content = function(record) 38.65 + ui.link{ 38.66 + content = record.name, 38.67 + external = record.url 38.68 + } 38.69 + end 38.70 + }, 38.71 + { 38.72 + label = _"Version", 38.73 + content = function(record) ui.field.text{ value = record.version } end 38.74 + }, 38.75 + { 38.76 + label = _"License", 38.77 + content = function(record) 38.78 + ui.link{ 38.79 + content = record.license, 38.80 + external = record.license_url 38.81 + } 38.82 + end 38.83 + 38.84 + } 38.85 + } 38.86 +} 38.87 + 38.88 +slot.put("<br />") 38.89 +slot.put("<br />") 38.90 +slot.put("<br />") 38.91 + 38.92 +ui.field.text{ attr = { style = "font-weight: bold;" }, value = "3rd party license information:" } 38.93 +slot.put("<br />") 38.94 +slot.put('The icons used in Liquid Feedback (except national flags) are from <a href="http://www.famfamfam.com/lab/icons/silk/">Silk icon set 1.3</a> by Mark James. His work is licensed under a <a href="http://creativecommons.org/licenses/by/2.5/">Creative Commons Attribution 2.5 License.</a>') 38.95 +
39.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 39.2 +++ b/app/main/index/change_password.lua Wed Nov 18 12:00:00 2009 +0100 39.3 @@ -0,0 +1,32 @@ 39.4 + 39.5 +slot.put_into("title", _"Change password") 39.6 + 39.7 +slot.select("actions", function() 39.8 + ui.link{ 39.9 + content = function() 39.10 + ui.image{ static = "icons/16/cancel.png" } 39.11 + slot.put(_"Cancel") 39.12 + end, 39.13 + module = "index", 39.14 + view = "index" 39.15 + } 39.16 +end) 39.17 + 39.18 +ui.form{ 39.19 + attr = { class = "vertical" }, 39.20 + module = "index", 39.21 + action = "update_password", 39.22 + routing = { 39.23 + ok = { 39.24 + mode = "redirect", 39.25 + module = "index", 39.26 + view = "index" 39.27 + } 39.28 + }, 39.29 + content = function() 39.30 + ui.field.password{ label = _"Old password", name = "old_password" } 39.31 + ui.field.password{ label = _"New password", name = "new_password1" } 39.32 + ui.field.password{ label = _"Repeat new password", name = "new_password2" } 39.33 + ui.submit{ value = _"Change password" } 39.34 + end 39.35 +} 39.36 \ No newline at end of file
40.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 40.2 +++ b/app/main/index/index.lua Wed Nov 18 12:00:00 2009 +0100 40.3 @@ -0,0 +1,82 @@ 40.4 +slot.select("title", function() 40.5 + ui.image{ 40.6 + attr = { class = "avatar" }, 40.7 + module = "member", 40.8 + view = "avatar", 40.9 + extension = "jpg", 40.10 + id = app.session.member.id 40.11 + } 40.12 +end) 40.13 + 40.14 +slot.select("title", function() 40.15 + ui.container{ 40.16 + attr = { class = "lang_chooser" }, 40.17 + content = function() 40.18 + for i, lang in ipairs{"en", "de"} do 40.19 + ui.link{ 40.20 + content = function() 40.21 + ui.image{ 40.22 + static = "lang/" .. lang .. ".png", 40.23 + attr = { style = "margin-left: 0.5em;", alt = lang } 40.24 + } 40.25 + end, 40.26 + module = "index", 40.27 + action = "set_lang", 40.28 + params = { lang = lang }, 40.29 + routing = { 40.30 + default = { 40.31 + mode = "redirect", 40.32 + module = request.get_module(), 40.33 + view = request.get_view(), 40.34 + id = param.get_id_cgi(), 40.35 + params = param.get_all_cgi() 40.36 + } 40.37 + } 40.38 + } 40.39 + end 40.40 + end 40.41 + } 40.42 +end) 40.43 + 40.44 +slot.put_into("title", encode.html(config.app_title)) 40.45 + 40.46 +slot.select("actions", function() 40.47 + slot.put(_"Logged in as:") 40.48 + slot.put(" <b>") 40.49 + slot.put(app.session.member.login) 40.50 + slot.put("</b> | ") 40.51 + 40.52 + ui.link{ 40.53 + content = function() 40.54 + ui.image{ static = "icons/16/user_gray.png" } 40.55 + slot.put(_"Upload avatar") 40.56 + end, 40.57 + module = "member", 40.58 + view = "edit_avatar" 40.59 + } 40.60 + 40.61 + ui.link{ 40.62 + content = function() 40.63 + ui.image{ static = "icons/16/application_form.png" } 40.64 + slot.put(_"Edit my page") 40.65 + end, 40.66 + module = "member", 40.67 + view = "edit" 40.68 + } 40.69 + 40.70 + ui.link{ 40.71 + content = function() 40.72 + ui.image{ static = "icons/16/key.png" } 40.73 + slot.put(_"Change password") 40.74 + end, 40.75 + module = "index", 40.76 + view = "change_password" 40.77 + } 40.78 +end) 40.79 + 40.80 +execute.view{ 40.81 + module = "member", 40.82 + view = "_show", 40.83 + params = { member = app.session.member } 40.84 +} 40.85 +
41.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 41.2 +++ b/app/main/index/login.lua Wed Nov 18 12:00:00 2009 +0100 41.3 @@ -0,0 +1,41 @@ 41.4 +slot.put_into("title", encode.html(config.app_title)) 41.5 + 41.6 +ui.tag{ 41.7 + tag = 'p', 41.8 + content = 'You need to be logged in, to use this system.' 41.9 +} 41.10 + 41.11 +ui.form{ 41.12 + attr = { class = "login" }, 41.13 + module = 'index', 41.14 + action = 'login', 41.15 + routing = { 41.16 + ok = { 41.17 + mode = 'redirect', 41.18 + module = 'index', 41.19 + view = 'index' 41.20 + }, 41.21 + error = { 41.22 + mode = 'forward', 41.23 + module = 'index', 41.24 + view = 'login', 41.25 + } 41.26 + }, 41.27 + content = function() 41.28 + ui.field.text{ 41.29 + attr = { id = "username_field" }, 41.30 + label = _'Username', 41.31 + html_name = 'login', 41.32 + value = '' 41.33 + } 41.34 + ui.script{ script = 'document.getElementById("username_field").focus();' } 41.35 + ui.field.password{ 41.36 + label = _'Password', 41.37 + html_name = 'password', 41.38 + value = '' 41.39 + } 41.40 + ui.submit{ 41.41 + text = _'Login' 41.42 + } 41.43 + end 41.44 +}
42.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 42.2 +++ b/app/main/index/search.lua Wed Nov 18 12:00:00 2009 +0100 42.3 @@ -0,0 +1,53 @@ 42.4 +local search_for = param.get("search_for", atom.string) 42.5 +local search_string = param.get("search", atom.string) 42.6 + 42.7 +search_for = search_for or "global" 42.8 + 42.9 +slot.put_into("title", _("Search results for: '#{search}'", { search = search_string })) 42.10 + 42.11 + 42.12 +local members = {} 42.13 +local issues = {} 42.14 +local initiatives = {} 42.15 + 42.16 + 42.17 +if search_for == "global" or search_for == "member" then 42.18 + members = Member:search(search_string) 42.19 +end 42.20 + 42.21 +if search_for == "global" or search_for == "issue" then 42.22 + issues = Issue:search(search_string) 42.23 +end 42.24 + 42.25 +if search_for == "initiative" then 42.26 + initiatives = Initiative:search(search_string) 42.27 +end 42.28 + 42.29 + 42.30 +if #members > 0 then 42.31 + ui.heading{ content = _"Members" } 42.32 + execute.view{ 42.33 + module = "member", 42.34 + view = "_list", 42.35 + params = { members = members, highlight_string = search_string }, 42.36 + } 42.37 +end 42.38 + 42.39 +if #issues > 0 then 42.40 + ui.heading{ content = _"Issues" } 42.41 + execute.view{ 42.42 + module = "issue", 42.43 + view = "_list", 42.44 + params = { issues = issues, highlight_string = search_string }, 42.45 + } 42.46 +end 42.47 + 42.48 +if #initiatives > 0 then 42.49 + ui.heading{ content = _"Initiatives" } 42.50 + execute.view{ 42.51 + module = "initiative", 42.52 + view = "_list", 42.53 + params = { initiatives = initiatives, highlight_string = search_string }, 42.54 + } 42.55 +end 42.56 +
43.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 43.2 +++ b/app/main/initiative/_action/add_support.lua Wed Nov 18 12:00:00 2009 +0100 43.3 @@ -0,0 +1,27 @@ 43.4 +local initiative = Initiative:new_selector():add_where{ "id = ?", param.get_id()}:single_object_mode():exec() 43.5 + 43.6 +local member = app.session.member 43.7 + 43.8 +local supporter = Supporter:by_pk(initiative.id, member.id) 43.9 + 43.10 +local last_draft = Draft:new_selector() 43.11 + :add_where{ "initiative_id = ?", initiative.id } 43.12 + :add_order_by("id DESC") 43.13 + :limit(1) 43.14 + :single_object_mode() 43.15 + :exec() 43.16 + 43.17 +if not supporter then 43.18 + supporter = Supporter:new() 43.19 + supporter.member_id = member.id 43.20 + supporter.initiative_id = initiative.id 43.21 + supporter.draft_id = last_draft.id 43.22 + supporter:save() 43.23 + slot.put_into("notice", _"Your support has been added to this initiative") 43.24 +elseif supporter.draft_id ~= last_draft.id then 43.25 + supporter.draft_id = last_draft.id 43.26 + supporter:save() 43.27 + slot.put_into("notice", _"Your support has been updated to the latest draft") 43.28 +else 43.29 + slot.put_into("notice", _"You are already supporting the latest draft") 43.30 +end 43.31 \ No newline at end of file
44.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 44.2 +++ b/app/main/initiative/_action/create.lua Wed Nov 18 12:00:00 2009 +0100 44.3 @@ -0,0 +1,54 @@ 44.4 +local issue 44.5 +local area 44.6 + 44.7 +db:query("BEGIN") 44.8 + 44.9 +local issue_id = param.get("issue_id", atom.integer) 44.10 +if issue_id then 44.11 + issue = Issue:new_selector():add_where{"id=?",issue_id}:single_object_mode():exec() 44.12 + area = issue.area 44.13 + 44.14 +else 44.15 + local area_id = param.get("area_id", atom.integer) 44.16 + area = Area:new_selector():add_where{"id=?",area_id}:single_object_mode():exec() 44.17 +end 44.18 + 44.19 +local initiative = Initiative:new() 44.20 + 44.21 +if not issue then 44.22 + issue = Issue:new() 44.23 + issue.area_id = area.id 44.24 + issue.policy_id = param.get("policy_id", atom.integer) 44.25 + issue:save() 44.26 +end 44.27 + 44.28 +initiative.issue_id = issue.id 44.29 +param.update(initiative, "name") 44.30 +initiative:save() 44.31 + 44.32 +local draft = Draft:new() 44.33 +draft.initiative_id = initiative.id 44.34 +draft.content = param.get("draft") 44.35 +draft.author_id = app.session.member.id 44.36 +draft:save() 44.37 + 44.38 +local initiator = Initiator:new() 44.39 +initiator.initiative_id = initiative.id 44.40 +initiator.member_id = app.session.member.id 44.41 +initiator:save() 44.42 + 44.43 +local supporter = Supporter:new() 44.44 +supporter.initiative_id = initiative.id 44.45 +supporter.member_id = app.session.member.id 44.46 +supporter.draft_id = draft.id 44.47 +supporter:save() 44.48 + 44.49 +db:query("COMMIT") 44.50 + 44.51 +slot.put_into("notice", _"Initiative successfully created") 44.52 + 44.53 +request.redirect{ 44.54 + module = "initiative", 44.55 + view = "show", 44.56 + id = initiative.id 44.57 +} 44.58 \ No newline at end of file
45.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 45.2 +++ b/app/main/initiative/_action/remove_support.lua Wed Nov 18 12:00:00 2009 +0100 45.3 @@ -0,0 +1,12 @@ 45.4 +local initiative = Initiative:new_selector():add_where{ "id = ?", param.get_id()}:single_object_mode():exec() 45.5 + 45.6 +local member = app.session.member 45.7 + 45.8 +local supporter = Supporter:by_pk(initiative.id, member.id) 45.9 + 45.10 +if supporter then 45.11 + supporter:destroy() 45.12 + slot.put_into("notice", _"Your support has been removed from this initiative") 45.13 +else 45.14 + slot.put_into("notice", _"You are already not supporting this initiative") 45.15 +end 45.16 \ No newline at end of file
46.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 46.2 +++ b/app/main/initiative/_list.lua Wed Nov 18 12:00:00 2009 +0100 46.3 @@ -0,0 +1,116 @@ 46.4 +local initiatives_selector = param.get("initiatives_selector", "table") 46.5 +initiatives_selector:join("issue", nil, "issue.id = initiative.issue_id") 46.6 + 46.7 +local issue = param.get("issue", "table") 46.8 + 46.9 +local order_options = {} 46.10 + 46.11 +if issue and issue.ranks_available then 46.12 + order_options[#order_options+1] = { 46.13 + name = "rank", 46.14 + label = _"Rank", 46.15 + order_by = "initiative.rank" 46.16 + } 46.17 +end 46.18 + 46.19 +order_options[#order_options+1] = { 46.20 + name = "support", 46.21 + label = _"Support", 46.22 + order_by = "initiative.supporter_count::float / issue.population::float DESC" 46.23 +} 46.24 + 46.25 +order_options[#order_options+1] = { 46.26 + name = "support_si", 46.27 + label = _"Support S+I", 46.28 + order_by = "initiative.satisfied_informed_supporter_count::float / issue.population::float DESC" 46.29 +} 46.30 + 46.31 +order_options[#order_options+1] = { 46.32 + name = "newest", 46.33 + label = _"Newest", 46.34 + order_by = "initiative.created DESC" 46.35 +} 46.36 + 46.37 +order_options[#order_options+1] = { 46.38 + name = "oldest", 46.39 + label = _"Oldest", 46.40 + order_by = "initiative.created" 46.41 +} 46.42 + 46.43 +local name = "initiative_list" 46.44 +if issue then 46.45 + name = "issue_" .. tostring(issue.id) .. "_initiative_list" 46.46 +end 46.47 + 46.48 +ui.order{ 46.49 + name = name, 46.50 + selector = initiatives_selector, 46.51 + options = order_options, 46.52 + content = function() 46.53 + ui.paginate{ 46.54 + selector = initiatives_selector, 46.55 + content = function() 46.56 + local initiatives = initiatives_selector:exec() 46.57 + local columns = {} 46.58 + local issue = initiatives[1] and initiatives[1].issue or {} 46.59 + if issue.accepted and issue.closed and issue.ranks_available then 46.60 + columns[#columns+1] = { 46.61 + content = function(record) 46.62 + ui.field.rank{ value = record.rank } 46.63 + end 46.64 + } 46.65 + columns[#columns+1] = { 46.66 + content = function(record) 46.67 + if record.negative_votes and record.positive_votes then 46.68 + local max_value = record.issue.voter_count 46.69 + trace.debug(record.issue.voter_count) 46.70 + ui.bargraph{ 46.71 + max_value = max_value, 46.72 + width = 100, 46.73 + bars = { 46.74 + { color = "#0a0", value = record.positive_votes }, 46.75 + { color = "#aaa", value = max_value - record.negative_votes - record.positive_votes }, 46.76 + { color = "#a00", value = record.negative_votes }, 46.77 + } 46.78 + } 46.79 + end 46.80 + end 46.81 + } 46.82 + else 46.83 + columns[#columns+1] = { 46.84 + content = function(record) 46.85 + local max_value = (record.issue.population or 0) 46.86 + ui.bargraph{ 46.87 + max_value = max_value, 46.88 + width = 100, 46.89 + bars = { 46.90 + { color = "#0a0", value = (record.satisfied_informed_supporter_count or 0) }, 46.91 + { color = "#8f8", value = (record.supporter_count or 0) - (record.satisfied_informed_supporter_count or 0) }, 46.92 + { color = "#ddd", value = max_value - (record.supporter_count or 0) }, 46.93 + } 46.94 + } 46.95 + end 46.96 + } 46.97 + end 46.98 + columns[#columns+1] = { 46.99 + content = function(record) 46.100 + ui.link{ 46.101 + content = function() 46.102 + util.put_highlighted_string(record.shortened_name) 46.103 + end, 46.104 + module = "initiative", 46.105 + view = "show", 46.106 + id = record.id 46.107 + } 46.108 + end 46.109 + } 46.110 + 46.111 + ui.list{ 46.112 + attr = { class = "initiatives" }, 46.113 + records = initiatives, 46.114 + columns = columns 46.115 + } 46.116 + end 46.117 + } 46.118 + end 46.119 +} 46.120 \ No newline at end of file
47.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 47.2 +++ b/app/main/initiative/new.lua Wed Nov 18 12:00:00 2009 +0100 47.3 @@ -0,0 +1,45 @@ 47.4 +local issue 47.5 +local area 47.6 + 47.7 +local issue_id = param.get("issue_id", atom.integer) 47.8 +if issue_id then 47.9 + issue = Issue:new_selector():add_where{"id=?",issue_id}:single_object_mode():exec() 47.10 + area = issue.area 47.11 + 47.12 +else 47.13 + local area_id = param.get("area_id", atom.integer) 47.14 + area = Area:new_selector():add_where{"id=?",area_id}:single_object_mode():exec() 47.15 +end 47.16 + 47.17 +if issue_id then 47.18 + slot.put_into("title", _"Add new initiative to issue") 47.19 +else 47.20 + slot.put_into("title", _"Create new issue") 47.21 +end 47.22 + 47.23 +ui.form{ 47.24 + module = "initiative", 47.25 + action = "create", 47.26 + params = { 47.27 + area_id = area.id, 47.28 + issue_id = issue and issue.id or nil 47.29 + }, 47.30 + attr = { class = "vertical" }, 47.31 + content = function() 47.32 + ui.field.text{ label = _"Area", value = area.name } 47.33 + if issue_id then 47.34 + ui.field.text{ label = _"Issue", value = issue_id } 47.35 + else 47.36 + ui.field.select{ 47.37 + label = _"Policy", 47.38 + name = "policy_id", 47.39 + foreign_records = Policy:new_selector():exec(), 47.40 + foreign_id = "id", 47.41 + foreign_name = "name" 47.42 + } 47.43 + end 47.44 + ui.field.text{ label = _"Name", name = "name" } 47.45 + ui.field.text{ label = _"Draft", name = "draft", multiline = true } 47.46 + ui.submit{ text = _"Save" } 47.47 + end 47.48 +} 47.49 \ No newline at end of file
48.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 48.2 +++ b/app/main/initiative/show.lua Wed Nov 18 12:00:00 2009 +0100 48.3 @@ -0,0 +1,176 @@ 48.4 +local initiative = Initiative:new_selector():add_where{ "id = ?", param.get_id()}:single_object_mode():exec() 48.5 + 48.6 +slot.put_into("html_head", '<link rel="alternate" type="application/rss+xml" title="RSS" href="../show/' .. tostring(initiative.id) .. '.rss" />') 48.7 + 48.8 +execute.view{ 48.9 + module = "supporter", 48.10 + view = "_show_box", 48.11 + params = { initiative = initiative } 48.12 +} 48.13 + 48.14 +execute.view{ 48.15 + module = "delegation", 48.16 + view = "_show_box", 48.17 + params = { issue_id = initiative.issue_id } 48.18 +} 48.19 + 48.20 + 48.21 +slot.select("path", function() 48.22 + ui.link{ 48.23 + content = _"Area '#{name}'":gsub("#{name}", initiative.issue.area.name), 48.24 + module = "area", 48.25 + view = "show", 48.26 + id = initiative.issue.area.id 48.27 + } 48.28 + ui.container{ content = "::" } 48.29 + ui.link{ 48.30 + content = _"Issue ##{id} (#{policy_name})":gsub("#{id}", initiative.issue.id):gsub("#{policy_name}", initiative.issue.policy.name), 48.31 + module = "issue", 48.32 + view = "show", 48.33 + id = initiative.issue.id 48.34 + } 48.35 +end) 48.36 + 48.37 +slot.put_into("title", encode.html(_"Initiative: '#{name}'":gsub("#{name}", initiative.shortened_name) )) 48.38 + 48.39 +slot.select("actions", function() 48.40 + 48.41 + ui.twitter("http://example.com/i" .. tostring(initiative.id) .. " " .. initiative.name) 48.42 + 48.43 +end) 48.44 + 48.45 + 48.46 +ui.container{ 48.47 + attr = { id = "add_suggestion_form", class = "hidden_inline_form" }, 48.48 + content = function() 48.49 + 48.50 + ui.link{ 48.51 + content = _"Close", 48.52 + attr = { 48.53 + onclick = "document.getElementById('add_suggestion_form').style.display='none';return(false)", 48.54 + style = "float: right;" 48.55 + } 48.56 + } 48.57 + 48.58 + ui.field.text{ attr = { class = "head" }, value = _"Add new suggestion" } 48.59 + 48.60 + 48.61 + ui.form{ 48.62 + module = "suggestion", 48.63 + action = "add", 48.64 + params = { initiative_id = initiative.id }, 48.65 + routing = { 48.66 + default = { 48.67 + mode = "redirect", 48.68 + module = "initiative", 48.69 + view = "show", 48.70 + id = initiative.id, 48.71 + params = { tab = "suggestion" } 48.72 + } 48.73 + }, 48.74 + attr = { class = "vertical" }, 48.75 + content = function() 48.76 + ui.field.text{ label = _"Name", name = "name" } 48.77 + ui.field.text{ label = _"Description", name = "description", multiline = true } 48.78 + ui.field.select{ 48.79 + label = _"Degree", 48.80 + name = "degree", 48.81 + foreign_records = { 48.82 + { id = 1, name = _"should"}, 48.83 + { id = 2, name = _"must"}, 48.84 + }, 48.85 + foreign_id = "id", 48.86 + foreign_name = "name" 48.87 + } 48.88 + ui.submit{ text = _"Commit suggestion" } 48.89 + end 48.90 + } 48.91 + end 48.92 +} 48.93 + 48.94 + 48.95 +ui.tabs{ 48.96 + { 48.97 + name = "current_draft", 48.98 + label = _"Current draft", 48.99 + content = function() 48.100 + execute.view{ module = "draft", view = "_show", params = { draft = initiative.current_draft } } 48.101 + if Initiator:by_pk(initiative.id, app.session.member.id) then 48.102 + ui.link{ 48.103 + content = function() 48.104 + ui.image{ static = "icons/16/script_add.png" } 48.105 + slot.put(_"Add new draft") 48.106 + end, 48.107 + module = "draft", 48.108 + view = "new", 48.109 + params = { initiative_id = initiative.id } 48.110 + } 48.111 + end 48.112 + end 48.113 + }, 48.114 + { 48.115 + name = "details", 48.116 + label = _"Details", 48.117 + content = function() 48.118 + ui.form{ 48.119 + attr = { class = "vertical" }, 48.120 + record = initiative, 48.121 + readonly = true, 48.122 + content = function() 48.123 + ui.field.text{ label = _"Issue policy", value = initiative.issue.policy.name } 48.124 + ui.field.text{ 48.125 + label = _"Created at", 48.126 + value = tostring(initiative.created) 48.127 + } 48.128 + ui.field.text{ 48.129 + label = _"Created at", 48.130 + value = format.timestamp(initiative.created) 48.131 + } 48.132 + ui.field.date{ label = _"Revoked at", name = "revoked" } 48.133 + ui.field.boolean{ label = _"Admitted", name = "admitted" } 48.134 + end 48.135 + } 48.136 + end 48.137 + }, 48.138 + { 48.139 + name = "suggestion", 48.140 + label = _"Suggestions", 48.141 + content = function() 48.142 + execute.view{ module = "suggestion", view = "_list", params = { suggestions_selector = initiative:get_reference_selector("suggestions") } } 48.143 + slot.put("<br />") 48.144 + if not initiative.issue.frozen and not initiative.issue.closed then 48.145 + ui.link{ 48.146 + content = function() 48.147 + ui.image{ static = "icons/16/comment_add.png" } 48.148 + slot.put(_"Add new suggestion") 48.149 + end, 48.150 + attr = { onclick = "document.getElementById('add_suggestion_form').style.display='block';return(false)" }, 48.151 + static = "#" 48.152 + } 48.153 + end 48.154 + end 48.155 + }, 48.156 + { 48.157 + name = "supporter", 48.158 + label = _"Supporter", 48.159 + content = function() 48.160 + execute.view{ module = "member", view = "_list", params = { members_selector = initiative:get_reference_selector("supporting_members") } } 48.161 + end 48.162 + }, 48.163 + { 48.164 + name = "initiators", 48.165 + label = _"Initiators", 48.166 + content = function() 48.167 + execute.view{ module = "member", view = "_list", params = { members_selector = initiative:get_reference_selector("initiating_members") } } 48.168 + end 48.169 + }, 48.170 + { 48.171 + name = "drafts", 48.172 + label = _"Old drafts", 48.173 + content = function() 48.174 + execute.view{ module = "draft", view = "_list", params = { drafts = initiative.drafts } } 48.175 + end 48.176 + }, 48.177 +} 48.178 + 48.179 +
49.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 49.2 +++ b/app/main/initiative/show.rss.lua Wed Nov 18 12:00:00 2009 +0100 49.3 @@ -0,0 +1,49 @@ 49.4 +slot.set_layout("rss") 49.5 + 49.6 +local function rss_channel(channel) 49.7 + for key, val in pairs(channel) do 49.8 + slot.put("<", key, ">", val, "</", key, ">") 49.9 + end 49.10 +end 49.11 + 49.12 +local function rss_item(item) 49.13 + slot.put("<item>") 49.14 + for key, val in pairs(item) do 49.15 + slot.put("<", key, ">", val, "</", key, ">") 49.16 + end 49.17 + slot.put("</item>") 49.18 +end 49.19 + 49.20 + 49.21 +local initiative = Initiative:by_id(param.get_id()) 49.22 + 49.23 +rss_channel{ 49.24 + title = initiative.name, 49.25 + description = initiative.current_draft.content, 49.26 + language = "de", 49.27 + copyright = initiative.current_draft.author.name, 49.28 + pubDate = "Tue, 8 Jul 2008 2:43:19" 49.29 +} 49.30 + 49.31 +for i, suggestion in ipairs(initiative.suggestions) do 49.32 + 49.33 + local text = suggestion.name 49.34 + 49.35 + text = text .. " (" 49.36 + text = text .. tostring(suggestion.plus2_unfulfilled_count + suggestion.plus2_unfulfilled_count) .. "++ " 49.37 + text = text .. tostring(suggestion.plus1_unfulfilled_count + suggestion.plus1_unfulfilled_count) .. "+ " 49.38 + text = text .. tostring(suggestion.minus1_unfulfilled_count + suggestion.minus1_unfulfilled_count) .. "- " 49.39 + text = text .. tostring(suggestion.minus2_unfulfilled_count + suggestion.minus2_unfulfilled_count) .. "--" 49.40 + 49.41 + text = text .. ")" 49.42 + 49.43 + rss_item{ 49.44 + title = text, 49.45 + description = suggestion.content, 49.46 + link = "http://localhost/lf/suggestion/show/" .. tostring(suggestion.id) .. ".html", 49.47 + author = "", 49.48 + guid = "guid", 49.49 + pubDate = "Tue, 8 Jul 2008 2:43:19" 49.50 + } 49.51 + 49.52 +end 49.53 \ No newline at end of file
50.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 50.2 +++ b/app/main/interest/_action/update.lua Wed Nov 18 12:00:00 2009 +0100 50.3 @@ -0,0 +1,28 @@ 50.4 +local issue_id = assert(param.get("issue_id", atom.integer), "no issue id given") 50.5 +local interest = Interest:by_pk(issue_id, app.session.member.id) 50.6 + 50.7 +if param.get("delete", atom.boolean) then 50.8 + if interest then 50.9 + interest:destroy() 50.10 + slot.put_into("notice", _"Interest removed") 50.11 + else 50.12 + slot.put_into("notice", _"Interest not existant") 50.13 + end 50.14 + return 50.15 +end 50.16 + 50.17 +if not interest then 50.18 + interest = Interest:new() 50.19 + interest.issue_id = issue_id 50.20 + interest.member_id = app.session.member_id 50.21 + interest.autoreject = false 50.22 +end 50.23 + 50.24 +local autoreject = param.get("autoreject", atom.boolean) 50.25 +if autoreject ~= nil then 50.26 + interest.autoreject = autoreject 50.27 +end 50.28 + 50.29 +interest:save() 50.30 + 50.31 +slot.put_into("notice", _"Interest updated")
51.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 51.2 +++ b/app/main/interest/_show_box.lua Wed Nov 18 12:00:00 2009 +0100 51.3 @@ -0,0 +1,71 @@ 51.4 + 51.5 +local issue = param.get("issue", "table") 51.6 + 51.7 + 51.8 +slot.select("interest", function() 51.9 + local interest = Interest:by_pk(issue.id, app.session.member.id) 51.10 + 51.11 + ui.container{ 51.12 + attr = { 51.13 + class = "head", 51.14 + onclick = "document.getElementById('interest_content').style.display = 'block';" 51.15 + }, 51.16 + content = function() 51.17 + if interest then 51.18 + ui.field.text{ value = _"You are interested. [more]" } 51.19 + else 51.20 + ui.field.text{ value = _"You are not interested. [more]" } 51.21 + end 51.22 + end 51.23 + } 51.24 + 51.25 + ui.container{ 51.26 + attr = { class = "content", id = "interest_content" }, 51.27 + content = function() 51.28 + if interest then 51.29 + ui.link{ 51.30 + content = _"Remove my interest", 51.31 + module = "interest", 51.32 + action = "update", 51.33 + params = { issue_id = issue.id, delete = true }, 51.34 + routing = { default = { mode = "redirect", module = "issue", view = "show", id = issue.id } } 51.35 + } 51.36 + if interest.autoreject then 51.37 + ui.field.text{ value = _"Autoreject is on." } 51.38 + ui.link{ 51.39 + content = _"Remove autoreject", 51.40 + module = "interest", 51.41 + action = "update", 51.42 + params = { issue_id = issue.id, autoreject = false }, 51.43 + routing = { default = { mode = "redirect", module = "issue", view = "show", id = issue.id } } 51.44 + } 51.45 + else 51.46 + ui.field.text{ value = _"Autoreject is off." } 51.47 + ui.link{ 51.48 + content = _"Set autoreject", 51.49 + module = "interest", 51.50 + action = "update", 51.51 + params = { issue_id = issue.id, autoreject = true }, 51.52 + routing = { default = { mode = "redirect", module = "issue", view = "show", id = issue.id } } 51.53 + } 51.54 + end 51.55 + else 51.56 + ui.link{ 51.57 + content = _"Add my interest to this issue", 51.58 + module = "interest", 51.59 + action = "update", 51.60 + params = { issue_id = issue.id }, 51.61 + routing = { default = { mode = "redirect", module = "issue", view = "show", id = issue.id } } 51.62 + } 51.63 + end 51.64 + ui.container{ 51.65 + attr = { 51.66 + class = "head", 51.67 + style = "cursor: pointer;", 51.68 + onclick = "document.getElementById('interest_content').style.display = 'none';" 51.69 + }, 51.70 + content = _"Click here to close." 51.71 + } 51.72 + end 51.73 + } 51.74 +end)
52.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 52.2 +++ b/app/main/issue/_list.lua Wed Nov 18 12:00:00 2009 +0100 52.3 @@ -0,0 +1,89 @@ 52.4 +local issues_selector = param.get("issues_selector", "table") 52.5 + 52.6 +local paginate = ui.paginate 52.7 + 52.8 +local issues 52.9 + 52.10 +if not issues_selector then 52.11 + issues = param.get("issues", "table") 52.12 + paginate = function(args) 52.13 + args.content() 52.14 + end 52.15 +end 52.16 + 52.17 +ui.order{ 52.18 + name = "issue_list", 52.19 + selector = issues_selector, 52.20 + options = { 52.21 + { 52.22 + name = "population", 52.23 + label = _"Population", 52.24 + order_by = "issue.population DESC" 52.25 + }, 52.26 + { 52.27 + name = "newest", 52.28 + label = _"Newest", 52.29 + order_by = "issue.created DESC" 52.30 + }, 52.31 + { 52.32 + name = "oldest", 52.33 + label = _"Oldest", 52.34 + order_by = "issue.created" 52.35 + } 52.36 + }, 52.37 + content = function() 52.38 + paginate{ 52.39 + selector = issues_selector, 52.40 + content = function() 52.41 + local highlight_string = param.get("highlight_string", "string") 52.42 + ui.list{ 52.43 + attr = { class = "issues" }, 52.44 + records = issues or issues_selector:exec(), 52.45 + columns = { 52.46 + { 52.47 + label = _"Issue", 52.48 + content = function(record) 52.49 + if not param.get("for_area_list", atom.boolean) then 52.50 + ui.field.text{ 52.51 + value = record.area.name 52.52 + } 52.53 + slot.put("<br />") 52.54 + end 52.55 + ui.link{ 52.56 + text = _"Issue ##{id}":gsub("#{id}", tostring(record.id)), 52.57 + module = "issue", 52.58 + view = "show", 52.59 + id = record.id 52.60 + } 52.61 + slot.put("<br />") 52.62 + slot.put("<br />") 52.63 + end 52.64 + }, 52.65 + { 52.66 + label = _"State", 52.67 + content = function(record) 52.68 + ui.field.issue_state{ value = record.state } 52.69 + end 52.70 + }, 52.71 + { 52.72 + label = _"Initiatives", 52.73 + content = function(record) 52.74 + execute.view{ 52.75 + module = "initiative", 52.76 + view = "_list", 52.77 + params = { 52.78 + issue = record, 52.79 + initiatives_selector = record:get_reference_selector("initiatives"), 52.80 + highlight_string = highlight_string, 52.81 + limit = 3 52.82 + } 52.83 + } 52.84 + end 52.85 + }, 52.86 + } 52.87 + } 52.88 + 52.89 + end 52.90 + } 52.91 + end 52.92 +} 52.93 \ No newline at end of file
53.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 53.2 +++ b/app/main/issue/list.lua Wed Nov 18 12:00:00 2009 +0100 53.3 @@ -0,0 +1,7 @@ 53.4 +local issues_selector = Issue:new_selector() 53.5 + 53.6 +execute.view{ 53.7 + module = "issue", 53.8 + view = "_list", 53.9 + params = { issues_selector = issues_selector } 53.10 +} 53.11 \ No newline at end of file
54.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 54.2 +++ b/app/main/issue/show.lua Wed Nov 18 12:00:00 2009 +0100 54.3 @@ -0,0 +1,110 @@ 54.4 +local issue = Issue:by_id(param.get_id()) 54.5 + 54.6 +slot.put_into("html_head", '<link rel="alternate" type="application/rss+xml" title="RSS" href="../show/' .. tostring(issue.id) .. '.rss" />') 54.7 + 54.8 +slot.select("path", function() 54.9 + ui.link{ 54.10 + content = _"Area '#{name}'":gsub("#{name}", issue.area.name), 54.11 + module = "area", 54.12 + view = "show", 54.13 + id = issue.area.id 54.14 + } 54.15 +end) 54.16 + 54.17 +slot.put_into("title", encode.html(_"Issue ##{id} (#{policy_name})":gsub("#{id}", issue.id):gsub("#{policy_name}", issue.policy.name))) 54.18 + 54.19 +slot.select("actions", function() 54.20 + if not issue.closed then 54.21 + ui.link{ 54.22 + content = function() 54.23 + ui.image{ static = "icons/16/table_go.png" } 54.24 + slot.put(_"Delegate") 54.25 + end, 54.26 + module = "delegation", 54.27 + view = "new", 54.28 + params = { issue_id = issue.id } 54.29 + } 54.30 + end 54.31 + 54.32 + ui.twitter("http://example.com/t" .. tostring(issue.id)) 54.33 + 54.34 +end) 54.35 + 54.36 +execute.view{ 54.37 + module = "interest", 54.38 + view = "_show_box", 54.39 + params = { issue = issue } 54.40 +} 54.41 + 54.42 +execute.view{ 54.43 + module = "delegation", 54.44 + view = "_show_box", 54.45 + params = { issue_id = issue.id } 54.46 +} 54.47 + 54.48 +ui.tabs{ 54.49 + { 54.50 + name = "initiatives", 54.51 + label = _"Initiatives", 54.52 + content = function() 54.53 + execute.view{ 54.54 + module = "initiative", 54.55 + view = "_list", 54.56 + params = { 54.57 + issue = issue, 54.58 + initiatives_selector = issue:get_reference_selector("initiatives") 54.59 + } 54.60 + } 54.61 + slot.put("<br />") 54.62 + if not issue.frozen and not issue.closed then 54.63 + ui.link{ 54.64 + attr = { class = "action" }, 54.65 + content = function() 54.66 + ui.image{ static = "icons/16/script_add.png" } 54.67 + slot.put(_"Add new initiative to issue") 54.68 + end, 54.69 + module = "initiative", 54.70 + view = "new", 54.71 + params = { issue_id = issue.id } 54.72 + } 54.73 + end 54.74 + end 54.75 + }, 54.76 +--[[ { 54.77 + name = "voting_requests", 54.78 + label = _"Voting requests", 54.79 + content = function() 54.80 + execute.view{ 54.81 + module = "issue_voting_request", 54.82 + view = "_list", 54.83 + params = { issue = issue } 54.84 + } 54.85 + end 54.86 + }, 54.87 +--]] 54.88 + { 54.89 + name = "details", 54.90 + label = _"Details", 54.91 + content = function() 54.92 + ui.form{ 54.93 + record = issue, 54.94 + readonly = true, 54.95 + attr = { class = "vertical" }, 54.96 + content = function() 54.97 + trace.debug(issue.created) 54.98 + ui.field.text{ label = _"State", name = "state" } 54.99 + ui.field.timestamp{ label = _"Created at", name = "created" } 54.100 + ui.field.timestamp{ label = _"Accepted", name = "accepted" } 54.101 + ui.field.timestamp{ label = _"Half frozen", name = "half_frozen" } 54.102 + ui.field.timestamp{ label = _"Fully frozen", name = "fully_frozen" } 54.103 + ui.field.timestamp{ label = _"Closed", name = "closed" } 54.104 + ui.field.potential_issue_weight{ label = _"Potential weight", name = "potential_weight" } 54.105 + ui.field.vote_now{ label = _"Vote now", name = "vote_now" } 54.106 + ui.field.vote_later{ label = _"Vote later", name = "vote_later" } 54.107 + end 54.108 + } 54.109 + end 54.110 + }, 54.111 +} 54.112 + 54.113 +
55.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 55.2 +++ b/app/main/issue/show.rss.lua Wed Nov 18 12:00:00 2009 +0100 55.3 @@ -0,0 +1,35 @@ 55.4 +slot.set_layout("rss") 55.5 + 55.6 +local function rss_channel(channel) 55.7 + for key, val in pairs(channel) do 55.8 + slot.put("<", key, ">", encode.html(val), "</", key, ">") 55.9 + end 55.10 +end 55.11 + 55.12 +local function rss_item(item) 55.13 + slot.put("<item>") 55.14 + for key, val in pairs(item) do 55.15 + slot.put("<", key, ">", encode.html(val), "</", key, ">") 55.16 + end 55.17 + slot.put("</item>") 55.18 +end 55.19 + 55.20 + 55.21 +local issue = Issue:by_id(param.get_id()) 55.22 + 55.23 +rss_channel{ 55.24 + title = issue.area.name .. " :: Issue #" .. tostring(issue.id), 55.25 + language = "de", 55.26 + pubDate = "Tue, 8 Jul 2008 2:43:19" 55.27 +} 55.28 + 55.29 +for i, initiative in ipairs(issue.initiatives) do 55.30 + rss_item{ 55.31 + title = initiative.name, 55.32 + description = initiative.current_draft.content, 55.33 + link = "http://localhost/lf/initiative/show/" .. tostring(initiative.id) .. ".html", 55.34 + author = initiative.current_draft.author.name, 55.35 + guid = "guid", 55.36 + pubDate = "Tue, 8 Jul 2008 2:43:19" 55.37 + } 55.38 +end 55.39 \ No newline at end of file
56.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 56.2 +++ b/app/main/member/_action/update.lua Wed Nov 18 12:00:00 2009 +0100 56.3 @@ -0,0 +1,6 @@ 56.4 +param.update(app.session.member, "name") 56.5 + 56.6 +app.session.member:save() 56.7 + 56.8 + 56.9 +slot.put_into("notice", _"Your page has been updated") 56.10 \ No newline at end of file
57.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 57.2 +++ b/app/main/member/_action/update_avatar.lua Wed Nov 18 12:00:00 2009 +0100 57.3 @@ -0,0 +1,20 @@ 57.4 +local data = param.get("avatar") 57.5 + 57.6 +if param.get("avatar_delete", atom.boolean) then 57.7 + app.session.member.avatar = nil 57.8 + app.session.member:save() 57.9 + slot.put_into("notice", _"Avatar has been deleted") 57.10 + return 57.11 +end 57.12 + 57.13 +local data, err, status = os.pfilter(data, "convert", "-", "-thumbnail", "48x48", "-") 57.14 + 57.15 +if status ~= 0 or data == nil then 57.16 + error("error while converting image") 57.17 +end 57.18 + 57.19 +if data and #data > 0 then 57.20 + db:query{ 'UPDATE member SET avatar = $ WHERE id = ?', { db:quote_binary(data) }, app.session.member.id } 57.21 +end 57.22 + 57.23 +slot.put_into("notice", _"Avatar has been updated")
58.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 58.2 +++ b/app/main/member/_list.lua Wed Nov 18 12:00:00 2009 +0100 58.3 @@ -0,0 +1,81 @@ 58.4 +local members_selector = param.get("members_selector", "table") 58.5 + 58.6 +ui.paginate{ 58.7 + selector = members_selector, 58.8 + content = function() 58.9 + ui.list{ 58.10 + records = members_selector:exec(), 58.11 + columns = { 58.12 + { 58.13 + content = function(record) 58.14 + ui.image{ 58.15 + attr = { style="height: 24px;" }, 58.16 + module = "member", 58.17 + view = "avatar", 58.18 + extension = "jpg", 58.19 + id = record.id 58.20 + } 58.21 + end 58.22 + }, 58.23 + { 58.24 + label = _"Login", 58.25 + content = function(record) 58.26 + ui.link{ 58.27 + text = record.login, 58.28 + module = "member", 58.29 + view = "show", 58.30 + id = record.id 58.31 + } 58.32 + end 58.33 + }, 58.34 + { 58.35 + label = _"Name", 58.36 + content = function(record) 58.37 + ui.link{ 58.38 + content = function() 58.39 + util.put_highlighted_string(record.name) 58.40 + end, 58.41 + module = "member", 58.42 + view = "show", 58.43 + id = record.id 58.44 + } 58.45 + end 58.46 + }, 58.47 + { 58.48 + label = _"Ident number", 58.49 + name = "ident_number" 58.50 + }, 58.51 + { 58.52 + label = _"Admin?", 58.53 + name = "admin" 58.54 + }, 58.55 + { 58.56 + label = "Locked?", 58.57 + content = function(record) 58.58 + ui.field.boolean{ value = record.locked } 58.59 + end 58.60 + }, 58.61 + { 58.62 + content = function(record) 58.63 + ui.link{ 58.64 + attr = { class = "action" }, 58.65 + text = _"Add to my contacts", 58.66 + module = "contact", 58.67 + action = "add_member", 58.68 + id = record.id, 58.69 + routing = { 58.70 + default = { 58.71 + mode = "redirect", 58.72 + module = request.get_module(), 58.73 + view = request.get_view(), 58.74 + id = param.get_id_cgi(), 58.75 + params = param.get_all_cgi() 58.76 + } 58.77 + } 58.78 + } 58.79 + end 58.80 + } 58.81 + } 58.82 + } 58.83 + end 58.84 +} 58.85 \ No newline at end of file
59.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 59.2 +++ b/app/main/member/_show.lua Wed Nov 18 12:00:00 2009 +0100 59.3 @@ -0,0 +1,84 @@ 59.4 +local member = param.get("member", "table") 59.5 + 59.6 +ui.form{ 59.7 + attr = { class = "vertical" }, 59.8 + record = member, 59.9 + readonly = true, 59.10 + content = function() 59.11 + ui.field.text{ label = _"Login", name = "login" } 59.12 + ui.field.text{ label = _"Name", name = "name" } 59.13 + ui.field.boolean{ label = _"Admin?", name = "admin" } 59.14 + ui.field.boolean{ label = _"Locked?", name = "locked" } 59.15 + ui.field.text{ label = _"Ident number", name = "ident_number" } 59.16 + ui.submit{ text = _"Save" } 59.17 + end 59.18 +} 59.19 + 59.20 +ui.tabs{ 59.21 + { 59.22 + name = "areas", 59.23 + label = _"Areas", 59.24 + content = function() 59.25 + execute.view{ 59.26 + module = "area", 59.27 + view = "_list", 59.28 + params = { areas_selector = member:get_reference_selector("areas") } 59.29 + } 59.30 + end 59.31 + }, 59.32 + { 59.33 + name = "issues", 59.34 + label = _"Issues", 59.35 + content = function() 59.36 + execute.view{ 59.37 + module = "issue", 59.38 + view = "_list", 59.39 + params = { issues_selector = member:get_reference_selector("issues") } 59.40 + } 59.41 + end 59.42 + }, 59.43 + { 59.44 + name = "initiatives", 59.45 + label = _"Initiatives", 59.46 + content = function() 59.47 + execute.view{ 59.48 + module = "initiative", 59.49 + view = "_list", 59.50 + params = { initiatives_selector = member:get_reference_selector("supported_initiatives") } 59.51 + } 59.52 + end 59.53 + }, 59.54 + { 59.55 + name = "incoming_delegations", 59.56 + label = _"Incoming delegations", 59.57 + content = function() 59.58 + execute.view{ 59.59 + module = "delegation", 59.60 + view = "_list", 59.61 + params = { selector = member:get_reference_selector("incoming_delegations") } 59.62 + } 59.63 + end 59.64 + }, 59.65 + { 59.66 + name = "outgoing_delegations", 59.67 + label = _"Outgoing delegations", 59.68 + content = function() 59.69 + execute.view{ 59.70 + module = "delegation", 59.71 + view = "_list", 59.72 + params = { selector = member:get_reference_selector("outgoing_delegations") } 59.73 + } 59.74 + end 59.75 + }, 59.76 + { 59.77 + name = "contacts", 59.78 + label = _"Published contacts", 59.79 + content = function() 59.80 + execute.view{ 59.81 + module = "member", 59.82 + view = "_list", 59.83 + params = { members_selector = member:get_reference_selector("saved_members"):add_where("public") } 59.84 + } 59.85 + end 59.86 + }, 59.87 +}
60.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 60.2 +++ b/app/main/member/avatar.lua Wed Nov 18 12:00:00 2009 +0100 60.3 @@ -0,0 +1,15 @@ 60.4 +local record = Member:by_id(param.get_id()) 60.5 + 60.6 +if false and (not record or not record.avatar) then 60.7 + print('Location: ' .. encode.url{ static = 'no_image.png' } .. '\n\n') 60.8 + exit() 60.9 +end 60.10 + 60.11 +print('Content-type: image/jpg\n') 60.12 + 60.13 +if record then 60.14 + io.stdout:write(record.avatar) 60.15 +else 60.16 +end 60.17 + 60.18 +exit()
61.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 61.2 +++ b/app/main/member/edit.lua Wed Nov 18 12:00:00 2009 +0100 61.3 @@ -0,0 +1,30 @@ 61.4 +slot.put_into("title", _"Edit my page") 61.5 + 61.6 +slot.select("actions", function() 61.7 + ui.link{ 61.8 + content = function() 61.9 + ui.image{ static = "icons/16/cancel.png" } 61.10 + slot.put(_"Cancel") 61.11 + end, 61.12 + module = "index", 61.13 + view = "index" 61.14 + } 61.15 +end) 61.16 + 61.17 +ui.form{ 61.18 + record = app.session.member, 61.19 + attr = { class = "vertical" }, 61.20 + module = "member", 61.21 + action = "update", 61.22 + routing = { 61.23 + ok = { 61.24 + mode = "redirect", 61.25 + module = "index", 61.26 + view = "index" 61.27 + } 61.28 + }, 61.29 + content = function() 61.30 + ui.field.text{ label = _"Name", name = "name" } 61.31 + ui.submit{ value = _"Save" } 61.32 + end 61.33 +} 61.34 \ No newline at end of file
62.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 62.2 +++ b/app/main/member/edit_avatar.lua Wed Nov 18 12:00:00 2009 +0100 62.3 @@ -0,0 +1,33 @@ 62.4 +slot.put_into("title", _"Upload avatar") 62.5 + 62.6 +slot.select("actions", function() 62.7 + ui.link{ 62.8 + content = function() 62.9 + ui.image{ static = "icons/16/cancel.png" } 62.10 + slot.put(_"Cancel") 62.11 + end, 62.12 + module = "index", 62.13 + view = "index" 62.14 + } 62.15 +end) 62.16 + 62.17 +ui.form{ 62.18 + record = app.session.member, 62.19 + attr = { 62.20 + class = "vertical", 62.21 + enctype = 'multipart/form-data' 62.22 + }, 62.23 + module = "member", 62.24 + action = "update_avatar", 62.25 + routing = { 62.26 + ok = { 62.27 + mode = "redirect", 62.28 + module = "index", 62.29 + view = "index" 62.30 + } 62.31 + }, 62.32 + content = function() 62.33 + ui.field.image{ field_name = "avatar", label = _"Avatar" } 62.34 + ui.submit{ value = _"Save" } 62.35 + end 62.36 +} 62.37 \ No newline at end of file
63.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 63.2 +++ b/app/main/member/list.lua Wed Nov 18 12:00:00 2009 +0100 63.3 @@ -0,0 +1,7 @@ 63.4 +slot.put_into("title", _"Member list") 63.5 + 63.6 +execute.view{ 63.7 + module = "member", 63.8 + view = "_list", 63.9 + params = { members_selector = Member:new_selector():add_order_by("login") } 63.10 +}
64.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 64.2 +++ b/app/main/member/show.lua Wed Nov 18 12:00:00 2009 +0100 64.3 @@ -0,0 +1,37 @@ 64.4 +local member = Member:by_id(param.get_id()) 64.5 + 64.6 +slot.select("title", function() 64.7 + ui.image{ 64.8 + attr = { class = "avatar" }, 64.9 + module = "member", 64.10 + view = "avatar", 64.11 + extension = "jpg", 64.12 + id = member.id 64.13 + } 64.14 +end) 64.15 + 64.16 +slot.put_into("title", encode.html(_"Member '#{member}'":gsub("#{member}", member.name))) 64.17 + 64.18 +if member.id == app.session.member.id then 64.19 + slot.put_into("actions", _"That's me!") 64.20 +else 64.21 + slot.select("actions", function() 64.22 + ui.link{ 64.23 + content = function() 64.24 + ui.image{ static = "icons/16/book_add.png" } 64.25 + slot.put(encode.html(_"Add to my contacts")) 64.26 + end, 64.27 + module = "contact", 64.28 + action = "add_member", 64.29 + id = member.id 64.30 + } 64.31 + end) 64.32 +end 64.33 + 64.34 + 64.35 +execute.view{ 64.36 + module = "member", 64.37 + view = "_show", 64.38 + params = { member = member } 64.39 +} 64.40 +
65.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 65.2 +++ b/app/main/membership/_action/update.lua Wed Nov 18 12:00:00 2009 +0100 65.3 @@ -0,0 +1,28 @@ 65.4 +local area_id = assert(param.get("area_id", atom.integer), "no area id given") 65.5 +local membership = Membership:by_pk(area_id, app.session.member.id) 65.6 + 65.7 +if param.get("delete", atom.boolean) then 65.8 + if membership then 65.9 + membership:destroy() 65.10 + slot.put_into("notice", _"Membership removed") 65.11 + else 65.12 + slot.put_into("notice", _"Membership not existant") 65.13 + end 65.14 + return 65.15 +end 65.16 + 65.17 +if not membership then 65.18 + membership = Membership:new() 65.19 + membership.area_id = area_id 65.20 + membership.member_id = app.session.member_id 65.21 + membership.autoreject = false 65.22 +end 65.23 + 65.24 +local autoreject = param.get("autoreject", atom.boolean) 65.25 +if autoreject ~= nil then 65.26 + membership.autoreject = autoreject 65.27 +end 65.28 + 65.29 +membership:save() 65.30 + 65.31 +slot.put_into("notice", _"Membership updated")
66.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 66.2 +++ b/app/main/membership/_show_box.lua Wed Nov 18 12:00:00 2009 +0100 66.3 @@ -0,0 +1,69 @@ 66.4 +local area = param.get("area", "table") 66.5 + 66.6 +slot.select("interest", function() 66.7 + local membership = Membership:by_pk(area.id, app.session.member.id) 66.8 + 66.9 + ui.container{ 66.10 + attr = { 66.11 + class = "head", 66.12 + onclick = "document.getElementById('interest_content').style.display = 'block';" 66.13 + }, 66.14 + content = function() 66.15 + if membership then 66.16 + ui.field.text{ value = _"You are member. [more]" } 66.17 + else 66.18 + ui.field.text{ value = _"You are not a member. [more]" } 66.19 + end 66.20 + end 66.21 + } 66.22 + 66.23 + ui.container{ 66.24 + attr = { class = "content", id = "interest_content" }, 66.25 + content = function() 66.26 + if membership then 66.27 + ui.link{ 66.28 + content = _"Remove my membership", 66.29 + module = "membership", 66.30 + action = "update", 66.31 + params = { area_id = area.id, delete = true }, 66.32 + routing = { default = { mode = "redirect", module = "area", view = "show", id = area.id } } 66.33 + } 66.34 + if membership.autoreject then 66.35 + ui.field.text{ value = _"Autoreject is on." } 66.36 + ui.link{ 66.37 + content = _"Remove autoreject", 66.38 + module = "membership", 66.39 + action = "update", 66.40 + params = { area_id = area.id, autoreject = false }, 66.41 + routing = { default = { mode = "redirect", module = "area", view = "show", id = area.id } } 66.42 + } 66.43 + else 66.44 + ui.field.text{ value = _"Autoreject is off." } 66.45 + ui.link{ 66.46 + content = _"Set autoreject", 66.47 + module = "membership", 66.48 + action = "update", 66.49 + params = { area_id = area.id, autoreject = true }, 66.50 + routing = { default = { mode = "redirect", module = "area", view = "show", id = area.id } } 66.51 + } 66.52 + end 66.53 + else 66.54 + ui.link{ 66.55 + content = _"Add my membership to this area", 66.56 + module = "membership", 66.57 + action = "update", 66.58 + params = { area_id = area.id }, 66.59 + routing = { default = { mode = "redirect", module = "area", view = "show", id = area.id } } 66.60 + } 66.61 + end 66.62 + ui.container{ 66.63 + attr = { 66.64 + class = "head", 66.65 + style = "cursor: pointer;", 66.66 + onclick = "document.getElementById('interest_content').style.display = 'none';" 66.67 + }, 66.68 + content = _"Click here to close." 66.69 + } 66.70 + end 66.71 + } 66.72 +end)
67.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 67.2 +++ b/app/main/opinion/_action/update.lua Wed Nov 18 12:00:00 2009 +0100 67.3 @@ -0,0 +1,33 @@ 67.4 +local member_id = app.session.member.id 67.5 + 67.6 +local suggestion_id = param.get("suggestion_id", atom.integer) 67.7 + 67.8 +local opinion = Opinion:by_pk(member_id, suggestion_id) 67.9 + 67.10 +if opinion and param.get("delete") then 67.11 + opinion:destroy() 67.12 + slot.put_into("notice", _"Your opinion has been updated") 67.13 + return 67.14 +end 67.15 + 67.16 +if not opinion then 67.17 + opinion = Opinion:new() 67.18 + opinion.member_id = member_id 67.19 + opinion.suggestion_id = suggestion_id 67.20 + opinion.fulfilled = false 67.21 +end 67.22 + 67.23 +local degree = param.get("degree", atom.number) 67.24 +local fulfilled = param.get("fulfilled", atom.boolean) 67.25 + 67.26 +if degree ~= nil then 67.27 + opinion.degree = degree 67.28 +end 67.29 + 67.30 +if fulfilled ~= nil then 67.31 + opinion.fulfilled = fulfilled 67.32 +end 67.33 + 67.34 +opinion:save() 67.35 + 67.36 +slot.put_into("notice", _"Your opinion has been updated")
68.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 68.2 +++ b/app/main/opinion/_list.lua Wed Nov 18 12:00:00 2009 +0100 68.3 @@ -0,0 +1,23 @@ 68.4 +local opinions_selector = param.get("opinions_selector", "table") 68.5 + 68.6 +ui.list{ 68.7 + records = opinions_selector:exec(), 68.8 + columns = { 68.9 + { 68.10 + label = _"Member login", 68.11 + name = "member_login" 68.12 + }, 68.13 + { 68.14 + label = _"Member name", 68.15 + name = "member_name" 68.16 + }, 68.17 + { 68.18 + label = _"Degree", 68.19 + name = "degree" 68.20 + }, 68.21 + { 68.22 + label = _"Fulfilled", 68.23 + name = "fulfilled" 68.24 + }, 68.25 + } 68.26 +} 68.27 \ No newline at end of file
69.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 69.2 +++ b/app/main/suggestion/_action/add.lua Wed Nov 18 12:00:00 2009 +0100 69.3 @@ -0,0 +1,20 @@ 69.4 +db:query("BEGIN") 69.5 + 69.6 +local suggestion = Suggestion:new() 69.7 + 69.8 +suggestion.author_id = app.session.member.id 69.9 +param.update(suggestion, "name", "description", "initiative_id") 69.10 +suggestion:save() 69.11 + 69.12 +local opinion = Opinion:new() 69.13 + 69.14 +opinion.suggestion_id = suggestion.id 69.15 +opinion.member_id = app.session.member.id 69.16 +opinion.degree = param.get("degree", atom.integer) 69.17 +opinion.fulfilled = false 69.18 + 69.19 +opinion:save() 69.20 + 69.21 +db:query("COMMIT") 69.22 + 69.23 +slot.put_into("notice", _"Your suggestion has been added") 69.24 \ No newline at end of file
70.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 70.2 +++ b/app/main/suggestion/_list.lua Wed Nov 18 12:00:00 2009 +0100 70.3 @@ -0,0 +1,185 @@ 70.4 +local suggestions_selector = param.get("suggestions_selector", "table") 70.5 + 70.6 +ui.paginate{ 70.7 + selector = suggestions_selector, 70.8 + content = function() 70.9 + ui.list{ 70.10 + records = suggestions_selector:exec(), 70.11 + columns = { 70.12 + { 70.13 + label = _"Name", 70.14 + content = function(record) 70.15 + ui.link{ 70.16 + text = record.name, 70.17 + module = "suggestion", 70.18 + view = "show", 70.19 + id = record.id 70.20 + } 70.21 + end 70.22 + }, 70.23 + { 70.24 + label = _"Support", 70.25 + content = function(record) 70.26 + if record.minus2_unfulfilled_count then 70.27 + local max_value = record.initiative.supporter_count 70.28 + ui.bargraph{ 70.29 + max_value = max_value, 70.30 + width = 50, 70.31 + bars = { 70.32 + { color = "#ddd", value = max_value - record.minus2_unfulfilled_count - record.minus1_unfulfilled_count - record.minus2_fulfilled_count - record.minus1_fulfilled_count }, 70.33 + { color = "#f88", value = record.minus1_unfulfilled_count + record.minus1_fulfilled_count }, 70.34 + { color = "#a00", value = record.minus2_unfulfilled_count + record.minus2_fulfilled_count }, 70.35 + { color = "#0a0", value = record.plus2_unfulfilled_count + record.plus2_fulfilled_count }, 70.36 + { color = "#8f8", value = record.plus1_unfulfilled_count + record.plus1_fulfilled_count }, 70.37 + { color = "#ddd", value = max_value - record.plus1_unfulfilled_count - record.plus2_unfulfilled_count - record.plus1_fulfilled_count - record.plus2_fulfilled_count }, 70.38 + } 70.39 + } 70.40 + end 70.41 + end 70.42 + }, 70.43 + { 70.44 + content = function(record) 70.45 + local degree 70.46 + local opinion = Opinion:by_pk(app.session.member.id, record.id) 70.47 + if opinion then 70.48 + degree = opinion.degree 70.49 + end 70.50 + ui.link{ 70.51 + attr = { class = "action" .. (degree == -2 and " active_red2" or "") }, 70.52 + text = _"must not", 70.53 + module = "opinion", 70.54 + action = "update", 70.55 + routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } }, 70.56 + params = { 70.57 + suggestion_id = record.id, 70.58 + degree = -2 70.59 + } 70.60 + } 70.61 + ui.link{ 70.62 + attr = { class = "action" .. (degree == -1 and " active_red1" or "") }, 70.63 + text = _"should not", 70.64 + module = "opinion", 70.65 + action = "update", 70.66 + routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } }, 70.67 + params = { 70.68 + suggestion_id = record.id, 70.69 + degree = -1 70.70 + } 70.71 + } 70.72 + ui.link{ 70.73 + attr = { class = "action" .. (degree == nil and " active" or "") }, 70.74 + text = _"neutral", 70.75 + module = "opinion", 70.76 + action = "update", 70.77 + routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } }, 70.78 + params = { 70.79 + suggestion_id = record.id, 70.80 + delete = true 70.81 + } 70.82 + } 70.83 + ui.link{ 70.84 + attr = { class = "action" .. (degree == 1 and " active_green1" or "") }, 70.85 + text = _"should", 70.86 + module = "opinion", 70.87 + action = "update", 70.88 + routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } }, 70.89 + params = { 70.90 + suggestion_id = record.id, 70.91 + degree = 1 70.92 + } 70.93 + } 70.94 + ui.link{ 70.95 + attr = { class = "action" .. (degree == 2 and " active_green2" or "") }, 70.96 + text = _"must", 70.97 + module = "opinion", 70.98 + action = "update", 70.99 + routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } }, 70.100 + params = { 70.101 + suggestion_id = record.id, 70.102 + degree = 2 70.103 + } 70.104 + } 70.105 + end 70.106 + }, 70.107 + { 70.108 + label = _"Not fullfilled", 70.109 + content = function(record) 70.110 + if record.minus2_unfulfilled_count then 70.111 + local max_value = record.initiative.supporter_count 70.112 + ui.bargraph{ 70.113 + max_value = max_value, 70.114 + width = 50, 70.115 + bars = { 70.116 + { color = "#ddd", value = max_value - record.minus2_unfulfilled_count - record.minus1_unfulfilled_count }, 70.117 + { color = "#f88", value = record.minus1_unfulfilled_count }, 70.118 + { color = "#a00", value = record.minus2_unfulfilled_count }, 70.119 + { color = "#0a0", value = record.plus2_unfulfilled_count }, 70.120 + { color = "#8f8", value = record.plus1_unfulfilled_count }, 70.121 + { color = "#ddd", value = max_value - record.plus1_unfulfilled_count - record.plus2_unfulfilled_count }, 70.122 + } 70.123 + } 70.124 + end 70.125 + end 70.126 + }, 70.127 + { 70.128 + label = _"Fullfilled", 70.129 + content = function(record) 70.130 + if record.minus2_fulfilled_count then 70.131 + local max_value = record.initiative.supporter_count 70.132 + ui.bargraph{ 70.133 + max_value = max_value, 70.134 + width = 50, 70.135 + bars = { 70.136 + { color = "#ddd", value = max_value - record.minus2_fulfilled_count - record.minus1_fulfilled_count }, 70.137 + { color = "#f88", value = record.minus1_fulfilled_count }, 70.138 + { color = "#a00", value = record.minus2_fulfilled_count }, 70.139 + { color = "#0a0", value = record.plus2_fulfilled_count }, 70.140 + { color = "#8f8", value = record.plus1_fulfilled_count }, 70.141 + { color = "#ddd", value = max_value - record.plus1_fulfilled_count - record.plus2_fulfilled_count }, 70.142 + } 70.143 + } 70.144 + end 70.145 + end 70.146 + }, 70.147 + { 70.148 + content = function(record) 70.149 + local degree 70.150 + local opinion = Opinion:by_pk(app.session.member.id, record.id) 70.151 + if opinion then 70.152 + degree = opinion.degree 70.153 + end 70.154 + if opinion then 70.155 + if not opinion.fulfilled then 70.156 + ui.image{ static = "icons/16/cross.png" } 70.157 + ui.link{ 70.158 + attr = { class = "action" }, 70.159 + text = _"set fulfilled", 70.160 + module = "opinion", 70.161 + action = "update", 70.162 + routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } }, 70.163 + params = { 70.164 + suggestion_id = record.id, 70.165 + fulfilled = true 70.166 + } 70.167 + } 70.168 + else 70.169 + ui.image{ static = "icons/16/tick.png" } 70.170 + ui.link{ 70.171 + attr = { class = "action" }, 70.172 + text = _"remove fulfilled", 70.173 + module = "opinion", 70.174 + action = "update", 70.175 + routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } }, 70.176 + params = { 70.177 + suggestion_id = record.id, 70.178 + fulfilled = false 70.179 + } 70.180 + } 70.181 + end 70.182 + end 70.183 + end 70.184 + }, 70.185 + } 70.186 + } 70.187 + end 70.188 +}
71.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 71.2 +++ b/app/main/suggestion/show.lua Wed Nov 18 12:00:00 2009 +0100 71.3 @@ -0,0 +1,32 @@ 71.4 +local suggestion = Suggestion:by_id(param.get_id()) 71.5 + 71.6 +slot.put_into("title", encode.html(_"Suggestion for initiative: '#{name}'":gsub("#{name}", suggestion.initiative.name) )) 71.7 + 71.8 +ui.form{ 71.9 + attr = { class = "vertical" }, 71.10 + record = suggestion, 71.11 + readonly = true, 71.12 + content = function() 71.13 + ui.field.text{ label = _"Name", name = "name" } 71.14 + ui.field.text{ label = _"Description", name = "description" } 71.15 + end 71.16 +} 71.17 + 71.18 +execute.view{ 71.19 + module = "suggestion", 71.20 + view = "_list", 71.21 + params = { suggestions_selector = Suggestion:new_selector():add_where{ "id = ?", suggestion.id } } 71.22 +} 71.23 + 71.24 +execute.view{ 71.25 + module = "opinion", 71.26 + view = "_list", 71.27 + params = { 71.28 + opinions_selector = Opinion:new_selector() 71.29 + :add_field("member.login", "member_login") 71.30 + :add_field("member.name", "member_name") 71.31 + :add_where{ "suggestion_id = ?", suggestion.id } 71.32 + :join("member", nil, "member.id = opinion.member_id") 71.33 + :add_order_by("member.id DESC") 71.34 + } 71.35 +} 71.36 \ No newline at end of file
72.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 72.2 +++ b/app/main/supporter/_show_box.lua Wed Nov 18 12:00:00 2009 +0100 72.3 @@ -0,0 +1,55 @@ 72.4 + 72.5 + 72.6 +slot.select("support", function() 72.7 + 72.8 + local initiative = param.get("initiative", "table") 72.9 + 72.10 + if not initiative.issue.frozen and not initiative.issue.closed then 72.11 + 72.12 + local supported = Supporter:by_pk(initiative.id, app.session.member.id) and true or false 72.13 + 72.14 + local text 72.15 + if supported then 72.16 + text = _"Direct supporter [change]" 72.17 + else 72.18 + text = _"No supporter [change]" 72.19 + end 72.20 + ui.container{ 72.21 + attr = { 72.22 + class = "head", 72.23 + style = "cursor: pointer;", 72.24 + onclick = "document.getElementById('support_content').style.display = 'block';" 72.25 + }, 72.26 + content = text 72.27 + } 72.28 + 72.29 + 72.30 + ui.container{ 72.31 + attr = { class = "content", id = "support_content" }, 72.32 + content = function() 72.33 + if supported then 72.34 + ui.link{ 72.35 + content = function() 72.36 + ui.image{ static = "icons/16/thumb_down_red.png" } 72.37 + slot.put(_"Remove my support from this initiative") 72.38 + end, 72.39 + module = "initiative", 72.40 + action = "remove_support", 72.41 + id = initiative.id 72.42 + } 72.43 + else 72.44 + ui.link{ 72.45 + content = function() 72.46 + ui.image{ static = "icons/16/thumb_up_green.png" } 72.47 + slot.put(_"Support this initiative") 72.48 + end, 72.49 + module = "initiative", 72.50 + action = "add_support", 72.51 + id = initiative.id 72.52 + } 72.53 + end 72.54 + end 72.55 + } 72.56 + end 72.57 + 72.58 +end)
73.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 73.2 +++ b/config/default.lua Wed Nov 18 12:00:00 2009 +0100 73.3 @@ -0,0 +1,48 @@ 73.4 +config.app_name = "LiquidFeedback" 73.5 +config.app_version = "alpha1" 73.6 + 73.7 +config.app_title = config.app_name .. " (" .. request.get_config_name() .. " environment)" 73.8 + 73.9 +config.app_service_provider = "Snake Oil<br/>10000 Berlin<br/>Germany" 73.10 + 73.11 +-- uncomment the following two lines to use C implementations of chosen 73.12 +-- functions and to disable garbage collection during the request, to 73.13 +-- increase speed: 73.14 +-- 73.15 +-- require 'webmcp_accelerator' 73.16 +-- collectgarbage("stop") 73.17 + 73.18 +-- open and set default database handle 73.19 +db = assert(mondelefant.connect{ 73.20 + engine='postgresql', 73.21 + dbname='liquid_feedback' 73.22 +}) 73.23 +at_exit(function() 73.24 + db:close() 73.25 +end) 73.26 +function mondelefant.class_prototype:get_db_conn() return db end 73.27 + 73.28 +-- enable output of SQL commands in trace system 73.29 +function db:sql_tracer(command) 73.30 + return function(error_info) 73.31 + local error_info = error_info or {} 73.32 + trace.sql{ command = command, error_position = error_info.position } 73.33 + end 73.34 +end 73.35 + 73.36 +-- 'request.get_relative_baseurl()' should be replaced by the absolute 73.37 +-- base URL of the application, as otherwise HTTP redirects will not be 73.38 +-- standard compliant 73.39 +request.set_absolute_baseurl(request.get_relative_baseurl()) 73.40 + 73.41 + 73.42 + 73.43 + 73.44 +-- get record by id 73.45 +function mondelefant.class_prototype:by_id(id) 73.46 + local selector = self:new_selector() 73.47 + selector:add_where{ 'id = ?', id } 73.48 + selector:optional_object_mode() 73.49 + return selector:exec() 73.50 +end 73.51 +
74.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 74.2 +++ b/config/development.lua Wed Nov 18 12:00:00 2009 +0100 74.3 @@ -0,0 +1,2 @@ 74.4 +execute.config("default") 74.5 +
75.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 75.2 +++ b/config/testing.lua Wed Nov 18 12:00:00 2009 +0100 75.3 @@ -0,0 +1,6 @@ 75.4 +execute.config("default") 75.5 + 75.6 + 75.7 + 75.8 + 75.9 +
76.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 76.2 +++ b/db/demodata.lua Wed Nov 18 12:00:00 2009 +0100 76.3 @@ -0,0 +1,102 @@ 76.4 +#!/usr/bin/env lua 76.5 + 76.6 +member_count = 10000 76.7 +area_count = 24 76.8 +issue_count = 1000 76.9 +policy_count = 3 -- do not change 76.10 + 76.11 +function write(...) 76.12 + io.stdout:write(...) 76.13 +end 76.14 +function writeln(...) 76.15 + write(...) 76.16 + write("\n") 76.17 +end 76.18 + 76.19 +math.randomseed(os.time()) 76.20 + 76.21 +writeln('BEGIN;') 76.22 + 76.23 +for i = 2, member_count do 76.24 + writeln('INSERT INTO "member" ("login", "name", "ident_number") VALUES (', "'testuser", i, "', 'Benutzer #", i, "', 'TEST", i, "');") 76.25 +end 76.26 + 76.27 +for i = 1, member_count do 76.28 + local is_linked = {} 76.29 + while math.random(4) > 1 do 76.30 + local k = math.random(member_count) 76.31 + if not is_linked[k] then 76.32 + local public = math.random(2) == 1 and "TRUE" or "FALSE" 76.33 + writeln('INSERT INTO "contact" ("member_id", "other_member_id", "public") VALUES (', i, ", ", k, ", ", public, ");") 76.34 + is_linked[k] = true 76.35 + end 76.36 + end 76.37 +end 76.38 + 76.39 +for i = 2, area_count do 76.40 + writeln('INSERT INTO "area" ("name") VALUES (', "'Area #", i, "');") 76.41 +end 76.42 + 76.43 +local memberships = {} 76.44 + 76.45 +for i = 1, area_count do 76.46 + memberships[i] = {} 76.47 + for j = 1, member_count do 76.48 + if math.random(4) == 1 then 76.49 + memberships[i][j] = true 76.50 + local autoreject = math.random(2) == 1 and "TRUE" or "FALSE" 76.51 + writeln('INSERT INTO "membership" ("member_id", "area_id", "autoreject") VALUES (', j, ", ", i, ", ", autoreject, ");") 76.52 + end 76.53 + end 76.54 +end 76.55 + 76.56 +do 76.57 + local issue_initiative_count = {} 76.58 + local initiative_draft_count = {} 76.59 + local initiative_idx = 1 76.60 + local draft_count = 0 76.61 + for i = 1, issue_count do 76.62 + local area = math.random(area_count) 76.63 + writeln('INSERT INTO "issue" ("area_id", "policy_id") VALUES (', area, ", ", math.random(policy_count), ");") 76.64 + issue_initiative_count[i] = 1 76.65 + while math.random(3) > 1 do 76.66 + issue_initiative_count[i] = issue_initiative_count[i] + 1 76.67 + end 76.68 + for j = 1, issue_initiative_count[i] do 76.69 + writeln('INSERT INTO "initiative" ("issue_id", "name") VALUES (', i, ", 'Initiative #", initiative_idx, "');") 76.70 + initiative_draft_count[i] = 1 76.71 + while math.random(4) > 1 do 76.72 + initiative_draft_count[i] = initiative_draft_count[i] + 1 76.73 + end 76.74 + local initiators = {} 76.75 + local is_used = {} 76.76 + repeat 76.77 + local member = math.random(member_count) 76.78 + if not is_used[member] then 76.79 + initiators[#initiators+1] = member 76.80 + is_used[member] = true 76.81 + end 76.82 + until math.random(2) == 1 76.83 + for k = 1, initiative_draft_count[i] do 76.84 + draft_count = draft_count + 1 76.85 + writeln('INSERT INTO "draft" ("initiative_id", "author_id", "content") VALUES (', initiative_idx, ", ", initiators[math.random(#initiators)], ", 'Lorem ipsum... (#", draft_count, ")');") 76.86 + end 76.87 + for k = 1, #initiators do 76.88 + local member = math.random(member_count) 76.89 + writeln('INSERT INTO "initiator" ("member_id", "initiative_id") VALUES (', initiators[k], ", ", initiative_idx, ");") 76.90 + if math.random(50) > 1 then 76.91 + writeln('INSERT INTO "supporter" ("member_id", "initiative_id", "draft_id") VALUES (', initiators[k], ", ", initiative_idx, ", ", draft_count - math.random(initiative_draft_count[i]) + 1, ");") 76.92 + end 76.93 + end 76.94 + local probability = math.random(99) + 1 76.95 + for k = 1, member_count do 76.96 + if not is_used[k] and (memberships[area][k] and math.random(probability) <= 4 or math.random(probability) == 1) then 76.97 + writeln('INSERT INTO "supporter" ("member_id", "initiative_id", "draft_id") VALUES (', k, ", ", initiative_idx, ", ", draft_count - math.random(initiative_draft_count[i]) + 1, ");") 76.98 + end 76.99 + end 76.100 + initiative_idx = initiative_idx + 1 76.101 + end 76.102 + end 76.103 +end 76.104 + 76.105 +writeln('END;')
77.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 77.2 +++ b/db/vote-test.sql Wed Nov 18 12:00:00 2009 +0100 77.3 @@ -0,0 +1,134 @@ 77.4 +BEGIN; 77.5 + 77.6 +INSERT INTO "member" ("login", "name", "ident_number") VALUES 77.7 + ('bernd', 'Bernd', '002'), 77.8 + ('cesar', 'Cesar', '003'), 77.9 + ('doris', 'Doris', '004'), 77.10 + ('emil', 'Emil', '005'), 77.11 + ('frank', 'Frank', '006'), 77.12 + ('gerhard', 'Gerhard', '007'), 77.13 + ('hugo', 'Hugo', '008'), 77.14 + ('ines', 'Ines', '009'), 77.15 + ('johann', 'Johann', '010'), 77.16 + ('klaus', 'Klaus', '011'), 77.17 + ('lisa', 'Lisa', '012'), 77.18 + ('monika', 'Monika', '013'), 77.19 + ('norbert', 'Norbert', '014'), 77.20 + ('olaf', 'Olaf', '015'), 77.21 + ('peter', 'Peter', '016'), 77.22 + ('quinn', 'Quinn', '017'), 77.23 + ('ralf', 'Ralf', '018'), 77.24 + ('sabine', 'Sabine', '019'), 77.25 + ('tobias', 'Tobias', '020'), 77.26 + ('ulla', 'Ulla', '021'), 77.27 + ('vincent', 'Vincent', '022'), 77.28 + ('wolfgang', 'Wolfgang', '023'), 77.29 + ('xavier', 'Xavier', '024'), 77.30 + ('yoko', 'Yoko', '025'), 77.31 + ('zareb', 'Zareb', '026'); 77.32 + 77.33 +INSERT INTO "issue" ("area_id", "policy_id") VALUES (1, 3); 77.34 +INSERT INTO "initiative" ("issue_id", "name") VALUES (1, 'Initiative #1'); 77.35 +INSERT INTO "initiative" ("issue_id", "name") VALUES (1, 'Initiative #2'); 77.36 +INSERT INTO "initiative" ("issue_id", "name") VALUES (1, 'Initiative #3'); 77.37 +INSERT INTO "initiative" ("issue_id", "name") VALUES (1, 'Initiative #4'); 77.38 +INSERT INTO "initiative" ("issue_id", "name") VALUES (1, 'Initiative #5'); 77.39 +INSERT INTO "initiative" ("issue_id", "name") VALUES (1, 'Initiative #6'); 77.40 +INSERT INTO "initiative" ("issue_id", "name") VALUES (1, 'Initiative #7'); 77.41 +INSERT INTO "initiative" ("issue_id", "name") VALUES (1, 'Initiative #8'); 77.42 +INSERT INTO "initiative" ("issue_id", "name") VALUES (1, 'Initiative #9'); 77.43 +INSERT INTO "initiative" ("issue_id", "name") VALUES (1, 'Initiative #10'); 77.44 +INSERT INTO "initiative" ("issue_id", "name") VALUES (1, 'Initiative #11'); 77.45 +INSERT INTO "initiative" ("issue_id", "name") VALUES (1, 'Initiative #12'); 77.46 +INSERT INTO "initiative" ("issue_id", "name") VALUES (1, 'Initiative #13'); 77.47 +INSERT INTO "initiative" ("issue_id", "name") VALUES (1, 'Initiative #14'); 77.48 +INSERT INTO "initiative" ("issue_id", "name") VALUES (1, 'Initiative #15'); 77.49 +INSERT INTO "initiative" ("issue_id", "name") VALUES (1, 'Initiative #16'); 77.50 +INSERT INTO "initiative" ("issue_id", "name") VALUES (1, 'Initiative #17'); 77.51 +INSERT INTO "initiative" ("issue_id", "name") VALUES (1, 'Initiative #18'); 77.52 +INSERT INTO "initiative" ("issue_id", "name") VALUES (1, 'Initiative #19'); 77.53 +INSERT INTO "initiative" ("issue_id", "name") VALUES (1, 'Initiative #20'); 77.54 +INSERT INTO "initiative" ("issue_id", "name") VALUES (1, 'Initiative #21'); 77.55 +INSERT INTO "initiative" ("issue_id", "name") VALUES (1, 'Initiative #22'); 77.56 +INSERT INTO "initiative" ("issue_id", "name") VALUES (1, 'Initiative #23'); 77.57 +INSERT INTO "initiative" ("issue_id", "name") VALUES (1, 'Initiative #24'); 77.58 +INSERT INTO "initiative" ("issue_id", "name") VALUES (1, 'Initiative #25'); 77.59 +INSERT INTO "initiative" ("issue_id", "name") VALUES (1, 'Initiative #26'); 77.60 +INSERT INTO "initiative" ("issue_id", "name") VALUES (1, 'Initiative #27'); 77.61 +INSERT INTO "initiative" ("issue_id", "name") VALUES (1, 'Initiative #28'); 77.62 +INSERT INTO "initiative" ("issue_id", "name") VALUES (1, 'Initiative #29'); 77.63 +INSERT INTO "initiative" ("issue_id", "name") VALUES (1, 'Initiative #30'); 77.64 + 77.65 +INSERT INTO "draft" ("initiative_id", "content") SELECT "id", 'Lorem ipsum ...' FROM "initiative"; 77.66 +INSERT INTO "initiator" ("member_id", "initiative_id") SELECT 1, "id" FROM "initiative"; 77.67 +INSERT INTO "supporter" ("member_id", "initiative_id", "draft_id") SELECT "member"."id", "initiative"."id", "initiative"."id" FROM "member", "initiative"; 77.68 + 77.69 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (1, 1, 1, 1); 77.70 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (1, 1, 2, 2); 77.71 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (1, 1, 3, 3); 77.72 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (1, 1, 4, 4); 77.73 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (1, 1, 5, 5); 77.74 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (1, 1, 6, 6); 77.75 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (1, 1, 7, 7); 77.76 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (1, 1, 8, 8); 77.77 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (1, 1, 9, 9); 77.78 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (1, 1, 10, 10); 77.79 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (1, 1, 11, 11); 77.80 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (1, 1, 12, 12); 77.81 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (1, 1, 13, 13); 77.82 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (1, 1, 14, 14); 77.83 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (1, 1, 15, 15); 77.84 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (1, 1, 16, 16); 77.85 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (1, 1, 17, 17); 77.86 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (1, 1, 18, 18); 77.87 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (1, 1, 19, 19); 77.88 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (1, 1, 20, 20); 77.89 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (1, 1, 21, 21); 77.90 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (1, 1, 22, 22); 77.91 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (1, 1, 23, 23); 77.92 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (1, 1, 24, 24); 77.93 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (1, 1, 25, 25); 77.94 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (1, 1, 26, 26); 77.95 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (1, 1, 27, 27); 77.96 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (1, 1, 28, 28); 77.97 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (1, 1, 29, 29); 77.98 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (1, 1, 30, 30); 77.99 + 77.100 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (2, 1, 1, 2); 77.101 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (2, 1, 2, 1); 77.102 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (2, 1, 3, 3); 77.103 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (2, 1, 4, 4); 77.104 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (2, 1, 5, 5); 77.105 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (2, 1, 6, 6); 77.106 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (2, 1, 7, 7); 77.107 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (2, 1, 8, 8); 77.108 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (2, 1, 9, 9); 77.109 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (2, 1, 10, 10); 77.110 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (2, 1, 11, 11); 77.111 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (2, 1, 12, 12); 77.112 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (2, 1, 13, 13); 77.113 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (2, 1, 14, 14); 77.114 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (2, 1, 15, 15); 77.115 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (2, 1, 16, 16); 77.116 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (2, 1, 17, 17); 77.117 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (2, 1, 18, 18); 77.118 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (2, 1, 19, 19); 77.119 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (2, 1, 20, 20); 77.120 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (2, 1, 21, 21); 77.121 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (2, 1, 22, 22); 77.122 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (2, 1, 23, 23); 77.123 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (2, 1, 24, 24); 77.124 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (2, 1, 25, 25); 77.125 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (2, 1, 26, 26); 77.126 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (2, 1, 27, 27); 77.127 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (2, 1, 28, 28); 77.128 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (2, 1, 29, 29); 77.129 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES (2, 1, 30, 30); 77.130 + 77.131 + 77.132 +SELECT check_issues(); 77.133 +UPDATE issue SET frozen = now(); 77.134 + 77.135 +END; 77.136 + 77.137 +-- UPDATE issue SET closed = now();
78.1 Binary file doc/delegation.dia has changed
79.1 Binary file doc/delegation.png has changed
80.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 80.2 +++ b/env/ui/bargraph.lua Wed Nov 18 12:00:00 2009 +0100 80.3 @@ -0,0 +1,19 @@ 80.4 +function ui.bargraph(args) 80.5 + ui.container{ 80.6 + attr = { 80.7 + class = "bargraph", 80.8 + }, 80.9 + content = function() 80.10 + for i, bar in ipairs(args.bars) do 80.11 + local value = bar.value * args.width / args.max_value / 2 80.12 + ui.container{ 80.13 + attr = { 80.14 + style = "width: " .. tostring(value) .. "px; background-color: " .. bar.color .. ";", 80.15 + title = tostring(bar.value) 80.16 + }, 80.17 + content = function() slot.put(" ") end 80.18 + } 80.19 + end 80.20 + end 80.21 + } 80.22 +end
81.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 81.2 +++ b/env/ui/field/image.lua Wed Nov 18 12:00:00 2009 +0100 81.3 @@ -0,0 +1,16 @@ 81.4 +function ui.field.image(args) 81.5 + ui.form_element(args, {}, function(args) 81.6 + local value_string = atom.dump(args.value) 81.7 + local attr = table.new(args.attr) 81.8 + attr.name = args.field_name 81.9 + attr.type = "file" 81.10 + attr.value = value_string 81.11 + ui.tag{ tag = "input", attr = attr } 81.12 + local attr = table.new(args.attr) 81.13 + attr.name = args.field_name .. '_' .. 'delete' 81.14 + attr.type = "checkbox" 81.15 + attr.value = '1' 81.16 + ui.tag{ tag = "input", attr = attr } 81.17 + slot.put(_'delete<br /><br />') 81.18 + end) 81.19 +end
82.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 82.2 +++ b/env/ui/field/issue_state.lua Wed Nov 18 12:00:00 2009 +0100 82.3 @@ -0,0 +1,15 @@ 82.4 +function ui.field.issue_state(args) 82.5 + ui.form_element(args, {fetch_value = true}, function(args) 82.6 + local value = args.value 82.7 + local state_name = Issue:get_state_name_for_state(value) 82.8 + ui.tag{ 82.9 + attr = { class = "vote_now" }, 82.10 + content = function() 82.11 + ui.tag{ 82.12 + attr = { class = "value" }, 82.13 + content = tostring(state_name) 82.14 + } 82.15 + end 82.16 + } 82.17 + end) 82.18 +end
83.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 83.2 +++ b/env/ui/field/negative_votes.lua Wed Nov 18 12:00:00 2009 +0100 83.3 @@ -0,0 +1,19 @@ 83.4 +function ui.field.negative_votes(args) 83.5 + ui.form_element(args, {fetch_value = true}, function(args) 83.6 + local value = args.value 83.7 + ui.container{ 83.8 + attr = { class = "negative_votes" }, 83.9 + content = function() 83.10 + ui.tag{ 83.11 + attr = { class = "value" }, 83.12 + content = function() 83.13 + slot.put(tostring(value) .. ' ') 83.14 + ui.image{ 83.15 + static = "icons/16/delete.png" 83.16 + } 83.17 + end 83.18 + } 83.19 + end 83.20 + } 83.21 + end) 83.22 +end
84.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 84.2 +++ b/env/ui/field/positive_votes.lua Wed Nov 18 12:00:00 2009 +0100 84.3 @@ -0,0 +1,19 @@ 84.4 +function ui.field.positive_votes(args) 84.5 + ui.form_element(args, {fetch_value = true}, function(args) 84.6 + local value = args.value 84.7 + ui.container{ 84.8 + attr = { class = "positive_votes" }, 84.9 + content = function() 84.10 + ui.tag{ 84.11 + attr = { class = "value" }, 84.12 + content = function() 84.13 + slot.put(tostring(value) .. ' ') 84.14 + ui.image{ 84.15 + static = "icons/16/add.png" 84.16 + } 84.17 + end 84.18 + } 84.19 + end 84.20 + } 84.21 + end) 84.22 +end
85.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 85.2 +++ b/env/ui/field/potential_initiative_weight.lua Wed Nov 18 12:00:00 2009 +0100 85.3 @@ -0,0 +1,14 @@ 85.4 +function ui.field.potential_initiative_weight(args) 85.5 + ui.form_element(args, {fetch_value = true}, function(args) 85.6 + local value = args.value 85.7 + ui.tag{ 85.8 + attr = { class = "potential_weight" }, 85.9 + content = function() 85.10 + ui.tag{ 85.11 + attr = { class = "value" }, 85.12 + content = "(" .. tostring(value) .. ")" 85.13 + } 85.14 + end 85.15 + } 85.16 + end) 85.17 +end 85.18 \ No newline at end of file
86.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 86.2 +++ b/env/ui/field/potential_issue_weight.lua Wed Nov 18 12:00:00 2009 +0100 86.3 @@ -0,0 +1,14 @@ 86.4 +function ui.field.potential_issue_weight(args) 86.5 + ui.form_element(args, {fetch_value = true}, function(args) 86.6 + local value = args.value 86.7 + ui.tag{ 86.8 + attr = { class = "potential_weight" }, 86.9 + content = function() 86.10 + ui.tag{ 86.11 + attr = { class = "value" }, 86.12 + content = tostring(value) 86.13 + } 86.14 + end 86.15 + } 86.16 + end) 86.17 +end 86.18 \ No newline at end of file
87.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 87.2 +++ b/env/ui/field/rank.lua Wed Nov 18 12:00:00 2009 +0100 87.3 @@ -0,0 +1,23 @@ 87.4 +function ui.field.rank(args) 87.5 + ui.form_element(args, {fetch_value = true}, function(args) 87.6 + local value = args.value 87.7 + ui.tag{ 87.8 + attr = { class = "rank" }, 87.9 + content = function() 87.10 + if value == 1 then 87.11 + ui.image{ static = "icons/16/award_star_gold_2.png" } 87.12 + elseif value then 87.13 + ui.image{ static = "icons/16/award_star_silver_2.png" } 87.14 + else 87.15 + ui.image{ static = "icons/16/cross.png" } 87.16 + end 87.17 + if value then 87.18 + ui.tag{ 87.19 + attr = { class = "value" }, 87.20 + content = tostring(value) 87.21 + } 87.22 + end 87.23 + end 87.24 + } 87.25 + end) 87.26 +end
88.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 88.2 +++ b/env/ui/field/satisfaction_informed.lua Wed Nov 18 12:00:00 2009 +0100 88.3 @@ -0,0 +1,20 @@ 88.4 +function ui.field.satisfaction_informed(args) 88.5 + ui.form_element(args, {fetch_value = true}, function(args) 88.6 + local value = args.value 88.7 + ui.tag{ 88.8 + attr = { class = "satisfaction_informed" }, 88.9 + content = function() 88.10 + ui.tag{ 88.11 + attr = { class = "value" }, 88.12 + content = function() 88.13 + slot.put(tostring(value) .. ' ') 88.14 + ui.image{ 88.15 + static = "icons/16/thumb_up_green.png" 88.16 + } 88.17 + end 88.18 + } 88.19 + end 88.20 + } 88.21 + end) 88.22 +end 88.23 +
89.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 89.2 +++ b/env/ui/field/satisfaction_total.lua Wed Nov 18 12:00:00 2009 +0100 89.3 @@ -0,0 +1,22 @@ 89.4 +function ui.field.satisfaction_total(args) 89.5 + ui.form_element(args, {fetch_value = true}, function(args) 89.6 + local value = args.value 89.7 + ui.tag{ 89.8 + attr = { class = "satisfaction_total" }, 89.9 + content = function() 89.10 + ui.tag{ 89.11 + attr = { class = "value" }, 89.12 + content = function() 89.13 + slot.put("(") 89.14 + slot.put(tostring(value) .. ' ') 89.15 + ui.image{ 89.16 + static = "icons/16/thumb_up_green.png" 89.17 + } 89.18 + slot.put(")") 89.19 + end 89.20 + } 89.21 + end 89.22 + } 89.23 + end) 89.24 +end 89.25 +
90.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 90.2 +++ b/env/ui/field/timestamp.lua Wed Nov 18 12:00:00 2009 +0100 90.3 @@ -0,0 +1,14 @@ 90.4 +function ui.field.timestamp(args) 90.5 + ui.form_element(args, {fetch_value = true}, function(args) 90.6 + local value = args.value 90.7 + ui.tag{ 90.8 + attr = { class = "ui_field_timestamp" }, 90.9 + content = function() 90.10 + ui.tag{ 90.11 + attr = { class = "value" }, 90.12 + content = tostring(value) 90.13 + } 90.14 + end 90.15 + } 90.16 + end) 90.17 +end
91.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 91.2 +++ b/env/ui/field/vote_later.lua Wed Nov 18 12:00:00 2009 +0100 91.3 @@ -0,0 +1,14 @@ 91.4 +function ui.field.vote_later(args) 91.5 + ui.form_element(args, {fetch_value = true}, function(args) 91.6 + local value = args.value 91.7 + ui.tag{ 91.8 + attr = { class = "vote_later" }, 91.9 + content = function() 91.10 + ui.tag{ 91.11 + attr = { class = "value" }, 91.12 + content = tostring(value) 91.13 + } 91.14 + end 91.15 + } 91.16 + end) 91.17 +end
92.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 92.2 +++ b/env/ui/field/vote_now.lua Wed Nov 18 12:00:00 2009 +0100 92.3 @@ -0,0 +1,14 @@ 92.4 +function ui.field.vote_now(args) 92.5 + ui.form_element(args, {fetch_value = true}, function(args) 92.6 + local value = args.value 92.7 + ui.tag{ 92.8 + attr = { class = "vote_now" }, 92.9 + content = function() 92.10 + ui.tag{ 92.11 + attr = { class = "value" }, 92.12 + content = tostring(value) 92.13 + } 92.14 + end 92.15 + } 92.16 + end) 92.17 +end
93.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 93.2 +++ b/env/ui/order.lua Wed Nov 18 12:00:00 2009 +0100 93.3 @@ -0,0 +1,40 @@ 93.4 +function ui.order(args) 93.5 + local name = args.name or "order" 93.6 + local current_order = atom.string:load(cgi.params[name]) or args.options[1].name 93.7 + local id = param.get_id_cgi() 93.8 + local params = param.get_all_cgi() 93.9 + ui.container{ 93.10 + attr = { class = "ui_order" }, 93.11 + content = function() 93.12 + ui.container{ 93.13 + attr = { class = "ui_order_head" }, 93.14 + content = function() 93.15 + slot.put(_"Order by") 93.16 + slot.put(": ") 93.17 + for i, option in ipairs(args.options) do 93.18 + params[name] = option.name 93.19 + local attr = {} 93.20 + if current_order == option.name then 93.21 + attr.class = "active" 93.22 + args.selector:add_order_by(option.order_by) 93.23 + end 93.24 + ui.link{ 93.25 + attr = attr, 93.26 + module = request.get_module(), 93.27 + view = request.get_view(), 93.28 + id = id, 93.29 + params = params, 93.30 + content = option.label 93.31 + } 93.32 + end 93.33 + end 93.34 + } 93.35 + ui.container{ 93.36 + attr = { class = "ui_order_content" }, 93.37 + content = function() 93.38 + args.content() 93.39 + end 93.40 + } 93.41 + end 93.42 + } 93.43 +end
94.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 94.2 +++ b/env/ui/tabs.lua Wed Nov 18 12:00:00 2009 +0100 94.3 @@ -0,0 +1,40 @@ 94.4 +function ui.tabs(tabs) 94.5 + ui.container{ 94.6 + attr = { class = "ui_tabs" }, 94.7 + content = function() 94.8 + local params = param.get_all_cgi() 94.9 + local current_tab = params["tab"] 94.10 + ui.container{ 94.11 + attr = { class = "ui_tabs_links" }, 94.12 + content = function() 94.13 + for i, tab in ipairs(tabs) do 94.14 + params["tab"] = i > 1 and tab.name or nil 94.15 + ui.link{ 94.16 + attr = { 94.17 + class = ( 94.18 + tab.name == current_tab and "selected" or 94.19 + not current_tab and i == 1 and "selected" or 94.20 + "" 94.21 + ) 94.22 + }, 94.23 + module = request.get_module(), 94.24 + view = request.get_view(), 94.25 + id = param.get_id_cgi(), 94.26 + text = tab.label, 94.27 + params = params 94.28 + } 94.29 + end 94.30 + end 94.31 + } 94.32 + for i, tab in ipairs(tabs) do 94.33 + if tab.name == current_tab or not current_tab and i == 1 then 94.34 + ui.container{ 94.35 + attr = { class = "ui_tabs_content" }, 94.36 + content = tab.content 94.37 + } 94.38 + end 94.39 + end 94.40 + end 94.41 + } 94.42 +end 94.43 +
95.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 95.2 +++ b/env/ui/twitter.lua Wed Nov 18 12:00:00 2009 +0100 95.3 @@ -0,0 +1,10 @@ 95.4 +function ui.twitter(message) 95.5 + ui.link{ 95.6 + attr = { target = "_blank" }, 95.7 + content = function() 95.8 + ui.image{ static = "icons/16/user_comment.png" } 95.9 + slot.put(encode.html("tweet it")) 95.10 + end, 95.11 + external = "http://twitter.com/?status=" .. encode.url_part(message) 95.12 + } 95.13 +end 95.14 \ No newline at end of file
96.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 96.2 +++ b/env/util/put_highlighted_string.lua Wed Nov 18 12:00:00 2009 +0100 96.3 @@ -0,0 +1,14 @@ 96.4 +function util.put_highlighted_string(string) 96.5 + local highlight_string = param.get("highlight_string") 96.6 + if highlight_string then 96.7 + local highlighted_string = slot.use_temporary(function() 96.8 + ui.tag{ 96.9 + tag = "span", 96.10 + attr = { class = "highlighted" }, 96.11 + content = highlight_string 96.12 + } 96.13 + end) 96.14 + string = string:gsub(highlight_string, highlighted_string) 96.15 + end 96.16 + slot.put(string) 96.17 +end 96.18 \ No newline at end of file
97.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 97.2 +++ b/locale/translations.de.lua Wed Nov 18 12:00:00 2009 +0100 97.3 @@ -0,0 +1,193 @@ 97.4 +#!/usr/bin/env lua 97.5 +return { 97.6 +["A-Z"] = false; 97.7 +["About"] = false; 97.8 +["About LiquidFeedback"] = "Über LiquidFeedback"; 97.9 +["Accepted"] = "Akzeptiert"; 97.10 +["Active?"] = "Aktiv?"; 97.11 +["Add my interest to this issue"] = "Mein Interesse am Thema anmelden"; 97.12 +["Add my membership to this area"] = "Mitglied im Themenbereich werden"; 97.13 +["Add new draft"] = "Neuen Entwurf hinzufügen"; 97.14 +["Add new initiative to issue"] = "Neue Initiative zum Thema hinzufügen"; 97.15 +["Add new suggestion"] = "Neue Anregung hinzufügen"; 97.16 +["Add to my contacts"] = "Zu meinen Kontakten hinzufügen"; 97.17 +["Admin"] = "Admin"; 97.18 +["Admin menu"] = "Admin Menü"; 97.19 +["Admin?"] = "Admin?"; 97.20 +["Admitted"] = "zugelassen"; 97.21 +["Area"] = "Themenbereich"; 97.22 +["Area '#{name}'"] = "Themenbereich '#{name}'"; 97.23 +["Area list"] = "Liste der Themenbereiche"; 97.24 +["Area successfully updated"] = "Themenbereich erfolgreich aktualisiert"; 97.25 +["Areas"] = "Themenbereiche"; 97.26 +["Author"] = "Autor"; 97.27 +["Autoreject is off."] = "Auto-Ablehnen ist aus"; 97.28 +["Autoreject is on."] = "Auto-Ablehnen ist an"; 97.29 +["Cancel"] = false; 97.30 +["Cancelled"] = "Abgebrochen"; 97.31 +["Change password"] = "Kennwort ändern"; 97.32 +["Click here to close."] = "Zum Schließen hier klicken"; 97.33 +["Close"] = "Schließen"; 97.34 +["Closed"] = "geschlossen"; 97.35 +["Commit suggestion"] = "Anregung speichern"; 97.36 +["Contacts"] = "Kontakte"; 97.37 +["Content"] = "Inhalt"; 97.38 +["Create new area"] = "Neuen Themenbereich anlegen"; 97.39 +["Create new issue"] = "Neues Thema anlegen"; 97.40 +["Created at"] = "Erzeugt am/um"; 97.41 +["Current draft"] = "Aktueller Entwurf"; 97.42 +["Degree"] = "Grad"; 97.43 +["Delegate"] = "Delegieren"; 97.44 +["Description"] = "Beschreibung"; 97.45 +["Details"] = "Details"; 97.46 +["Direct member count"] = "Anzahl Direktmitglieder"; 97.47 +["Direct supporter [change]"] = "Direkte Unterstützung [ändern]"; 97.48 +["Draft"] = "Entwurf"; 97.49 +["Edit"] = "Bearbeiten"; 97.50 +["Edit my page"] = "Meine Seite bearbeiten"; 97.51 +["Error while updating member, database reported:<br /><br /> (#{errormessage})"] = "Fehler beim aktualisieren des Mitglieds, die Datenbank berichtet folgenden Fehler:<br /><br /> (#{errormessage})"; 97.52 +["Finished"] = "Abgeschlossen"; 97.53 +["Frozen"] = "Eingefroren"; 97.54 +["Fulfilled"] = "Erfüllt"; 97.55 +["Fullfilled"] = "Erfüllt"; 97.56 +["Fully frozen"] = false; 97.57 +["Global delegation"] = "Globale Delegation"; 97.58 +["Half frozen"] = false; 97.59 +["Hide"] = "Verstecken"; 97.60 +["Home"] = "Startseite"; 97.61 +["Id"] = "Id"; 97.62 +["Ident number"] = "Ident-Nummer"; 97.63 +["In discussion"] = "In Diskussion"; 97.64 +["Incoming delegations"] = "Eingehende Delegationen"; 97.65 +["Initiative"] = "Initiative"; 97.66 +["Initiative successfully created"] = "Initiative erfolgreich erzeugt"; 97.67 +["Initiative: '#{name}'"] = "Initiative: '#{name}'"; 97.68 +["Initiatives"] = "Initiativen"; 97.69 +["Initiators"] = "Initiatoren"; 97.70 +["Interest not existant"] = false; 97.71 +["Interest removed"] = "Interesse entfernt"; 97.72 +["Interest updated"] = "Interesse aktualisiert"; 97.73 +["Invalid username or password!"] = "Ungültiger Benutzername oder Kennwort"; 97.74 +["Issue"] = "Thema"; 97.75 +["Issue ##{id}"] = "Issue ##{id}"; 97.76 +["Issue ##{id} (#{policy_name})"] = "Thema ##{id} (#{policy_name})"; 97.77 +["Issue policy"] = "Regelwerk für Thema"; 97.78 +["Issues"] = "Themen"; 97.79 +["License"] = "Lizenz"; 97.80 +["Locked?"] = "Gesperrt?"; 97.81 +["Logged in as:"] = "Angemeldet als:"; 97.82 +["Login"] = "Anmeldung"; 97.83 +["Login successful!"] = "Anmeldung erfolgreich"; 97.84 +["Logout"] = "Abmelden"; 97.85 +["Logout successful"] = "Abmeldung erfolgreich"; 97.86 +["Me"] = "Ich"; 97.87 +["Member '#{member}'"] = "Mitglied '#{member}'"; 97.88 +["Member has been removed from your contacts"] = "Mitglied wurde aus Deinen Kontakten entfernt"; 97.89 +["Member has been saved as private contact"] = "Mitglied wurde als privater Kontakt gespeichert"; 97.90 +["Member has been saved as public contact"] = "Mitglied wurde als öffentlicher Kontakt gespeichert"; 97.91 +["Member is already saved in your contacts!"] = "Mitglied ist schon in Deinen Kontakten!"; 97.92 +["Member list"] = "Mitgliederliste"; 97.93 +["Member login"] = "Mitglied Login"; 97.94 +["Member name"] = "Mitglied Name"; 97.95 +["Member successfully registered"] = "Mitglied erfolgreich registriert"; 97.96 +["Member successfully updated"] = "Mitglied erfolgreich aktualisert"; 97.97 +["Member: '#{login}' (#{name})"] = "Mitlied: '#{login}' (#{name})"; 97.98 +["Members"] = "Mitglieder"; 97.99 +["Membership not existant"] = false; 97.100 +["Membership removed"] = "Mitgliedschaft entfernt"; 97.101 +["Membership updated"] = "Mitgliedschaft aktualisiert"; 97.102 +["Name"] = "Name"; 97.103 +["New"] = "Neu"; 97.104 +["New draft has been added to initiative"] = "Neuer Entwurf wurde der Initiative hinzugefügt"; 97.105 +["New password"] = "Neues Kennwort"; 97.106 +["New passwords does not match."] = "Du hast nicht zweimal das gleiche Kennwort eingegeben"; 97.107 +["New passwords is too short."] = "Das neue Kennwort ist zu kurz"; 97.108 +["Newest"] = "Neueste"; 97.109 +["No supporter [change]"] = "Keine Unterstützung (ändern)"; 97.110 +["Not fullfilled"] = "Nicht erfüllt"; 97.111 +["OK"] = "OK"; 97.112 +["Old drafts"] = "Alte Entwürfe"; 97.113 +["Old password"] = "Altes Kennwort"; 97.114 +["Old password is wrong"] = "Das alte Kennwort ist falsch"; 97.115 +["Oldest"] = "Älteste"; 97.116 +["Order by"] = "Sortieren nach"; 97.117 +["Outgoing delegations"] = "Ausgehende Delegationen"; 97.118 +["Password"] = "Kennwort"; 97.119 +["Policy"] = "Regelwerk"; 97.120 +["Population"] = "Grundgesamtheit"; 97.121 +["Potential weight"] = "Potentielles Gewicht"; 97.122 +["Publish"] = "Veröffentlichen"; 97.123 +["Published"] = "veröffentlicht"; 97.124 +["Published contacts"] = "Veröffentlichte Kontakte"; 97.125 +["Rank"] = "Rang"; 97.126 +["Register new member"] = "Neues Mitglied registrieren"; 97.127 +["Remove"] = "Entfernen"; 97.128 +["Remove autoreject"] = "Auto-Ablehnen abschalten"; 97.129 +["Remove my interest"] = "Interesse abmelden"; 97.130 +["Remove my membership"] = "Mitgliedschaft aufgeben"; 97.131 +["Remove my support from this initiative"] = "Meine Unterstützung der Initiative entziehen"; 97.132 +["Repeat new password"] = "Neues Kennwort wiederholen"; 97.133 +["Revoke"] = "Widerrufen"; 97.134 +["Revoked at"] = "Zurückgezogen am/um"; 97.135 +["Save"] = "Speichern"; 97.136 +["Search"] = "Suchen"; 97.137 +["Search initiatives"] = "Suche Initiativen"; 97.138 +["Search issues"] = "Suche Themen"; 97.139 +["Search members"] = "Suche Mitglieder"; 97.140 +["Search results for: '#{search}'"] = "Suchergebnisse für: '#{search}'"; 97.141 +["Set autoreject"] = "Auto-Ablehnen anschalten"; 97.142 +["Set delegation for Area '#{name}'"] = "Delegation für Themengebiet '#{name}' festlegen"; 97.143 +["Set delegation for Issue ##{number} in Area '#{area_name}'"] = "Delegation für Thema ##{number} im Themenbereich '#{area_name}' festlegen"; 97.144 +["Show"] = "Zeige"; 97.145 +["Show active members"] = "Zeige aktive Mitglieder"; 97.146 +["Show areas in use"] = "Zeige verwendete Themenbereiche"; 97.147 +["Show areas not in use"] = "Zeige nicht verwendente Themenbereiche"; 97.148 +["Show locked members"] = "Zeige gesperrte Mitglieder"; 97.149 +["Software"] = false; 97.150 +["State"] = "Zustand"; 97.151 +["Suggestion for initiative: '#{name}'"] = "Anregung für Initiative '#{name}'"; 97.152 +["Suggestions"] = "Anregungen"; 97.153 +["Support"] = "Unterstützung"; 97.154 +["Support S+I"] = "Unterstütung S+I"; 97.155 +["Support this initiative"] = "Diese Initiative unterstützen"; 97.156 +["Supporter"] = "Unterstützer"; 97.157 +["That's me!"] = "Das bin ich"; 97.158 +["Trustee"] = "Bevollmächtigter"; 97.159 +["Truster"] = "Delegierender"; 97.160 +["Unknown author"] = "Unbekannter Autor"; 97.161 +["Upload avatar"] = "Avatar hochladen"; 97.162 +["Username"] = "Benutzername"; 97.163 +["Version"] = false; 97.164 +["Vote later"] = "Später abstimmen"; 97.165 +["Vote now"] = "Jetzt abstimmen"; 97.166 +["Voting"] = "Abstimmung"; 97.167 +["Voting requests"] = "Abstimmanträge"; 97.168 +["You are already not supporting this initiative"] = "Diese Initiative hat bereits keine Unterstützung von Dir"; 97.169 +["You are already supporting the latest draft"] = "Du unterstützt bereits den neuesten Entwurf"; 97.170 +["You are interested. [more]"] = "Du bist interessiert. [mehr]"; 97.171 +["You are member. [more]"] = "Du bist Mitglied. [mehr]"; 97.172 +["You are not a member. [more]"] = "Du bist kein Mitglied. [mehr]"; 97.173 +["You are not interested. [more]"] = "Du bist nicht interessiert. [mehr]"; 97.174 +["You didn't saved any member as contact yet."] = "Du hast noch kein Mitglied als Kontakt gespeichert!"; 97.175 +["Your delegation for this area has been deleted."] = "Deine Delegation für dieses Themengebiet wurde gelöscht"; 97.176 +["Your delegation for this area has been updated."] = "Deine Delegation für dieses Themengebiet wurde geändert"; 97.177 +["Your delegation for this issue has been deleted."] = "Deine Delegation für dieses Thema wurde gelöscht"; 97.178 +["Your delegation for this issue has been updated."] = "Deine Delegation für dieses Thema wurde geändert"; 97.179 +["Your global delegation has been deleted."] = "Deine globale Delegation wurde gelöscht"; 97.180 +["Your global delegation has been updated."] = "Deine globale Delegation würde geändert"; 97.181 +["Your opinion has been updated"] = "Deine Meinung wurde aktualisiert"; 97.182 +["Your password has been updated successfully"] = "Das Kennwort wurde erfolgreich geändert"; 97.183 +["Your suggestion has been added"] = "Deine Anregung wurde hinzufügt"; 97.184 +["Your support has been added to this initiative"] = "Deine Unterstützung wurde der Initiative hinzugefügt"; 97.185 +["Your support has been removed from this initiative"] = "Deine Unterstützung wurde der Initiave entzogen"; 97.186 +["Your support has been updated to the latest draft"] = "Deine Unterstützung wurde auf den neuesten Entwurf aktualisiert"; 97.187 +["Your vote is delegated. [more]"] = "Deine Stimme ist delegiert. [mehr]"; 97.188 +["Z-A"] = false; 97.189 +["must"] = "muss"; 97.190 +["must not"] = "darf nicht"; 97.191 +["neutral"] = "neutral"; 97.192 +["remove fulfilled"] = "erfüllt entfernen"; 97.193 +["set fulfilled"] = "erfüllt setzten"; 97.194 +["should"] = "soll"; 97.195 +["should not"] = "soll nicht"; 97.196 +}
98.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 98.2 +++ b/locale/translations.en.lua Wed Nov 18 12:00:00 2009 +0100 98.3 @@ -0,0 +1,15 @@ 98.4 +#!/usr/bin/env lua 98.5 +return { 98.6 +["Error compile"] = false; 98.7 +["Error no file"] = false; 98.8 +["Error runtime"] = false; 98.9 +["Home"] = false; 98.10 +["Invalid username or password!"] = false; 98.11 +["Login"] = false; 98.12 +["Login successful!"] = false; 98.13 +["Logout"] = false; 98.14 +["Logout successful"] = false; 98.15 +["Password"] = false; 98.16 +["Password login"] = false; 98.17 +["Username"] = false; 98.18 +}
99.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 99.2 +++ b/model/area.lua Wed Nov 18 12:00:00 2009 +0100 99.3 @@ -0,0 +1,31 @@ 99.4 +Area = mondelefant.new_class() 99.5 +Area.table = 'area' 99.6 + 99.7 +Area:add_reference{ 99.8 + mode = '1m', 99.9 + to = "Issue", 99.10 + this_key = 'id', 99.11 + that_key = 'area_id', 99.12 + ref = 'issues', 99.13 + back_ref = 'area' 99.14 +} 99.15 + 99.16 +Area:add_reference{ 99.17 + mode = '1m', 99.18 + to = "Membership", 99.19 + this_key = 'id', 99.20 + that_key = 'area_id', 99.21 + ref = 'memberships', 99.22 + back_ref = 'area' 99.23 +} 99.24 + 99.25 +Area:add_reference{ 99.26 + mode = 'mm', 99.27 + to = "Member", 99.28 + this_key = 'id', 99.29 + that_key = 'id', 99.30 + connected_by_table = 'membership', 99.31 + connected_by_this_key = 'area_id', 99.32 + connected_by_that_key = 'member_id', 99.33 + ref = 'members' 99.34 +}
100.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 100.2 +++ b/model/contact.lua Wed Nov 18 12:00:00 2009 +0100 100.3 @@ -0,0 +1,28 @@ 100.4 +Contact = mondelefant.new_class() 100.5 +Contact.table = 'contact' 100.6 +Contact.primary_key = { "member_id", "other_member_id" } 100.7 + 100.8 +Contact:add_reference{ 100.9 + mode = 'm1', 100.10 + to = "Member", 100.11 + this_key = 'member_id', 100.12 + that_key = 'id', 100.13 + ref = 'member', 100.14 +} 100.15 + 100.16 +Contact:add_reference{ 100.17 + mode = 'm1', 100.18 + to = "Member", 100.19 + this_key = 'other_member_id', 100.20 + that_key = 'id', 100.21 + ref = 'other_member', 100.22 +} 100.23 + 100.24 + 100.25 +function Contact:by_pk(member_id, other_member_id) 100.26 + return self:new_selector() 100.27 + :add_where{ "member_id = ?", member_id } 100.28 + :add_where{ "other_member_id = ?", other_member_id } 100.29 + :optional_object_mode() 100.30 + :exec() 100.31 +end
101.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 101.2 +++ b/model/delegation.lua Wed Nov 18 12:00:00 2009 +0100 101.3 @@ -0,0 +1,50 @@ 101.4 +Delegation = mondelefant.new_class() 101.5 +Delegation.table = 'delegation' 101.6 + 101.7 +Delegation:add_reference{ 101.8 + mode = 'm1', 101.9 + to = "Member", 101.10 + this_key = 'truster_id', 101.11 + that_key = 'id', 101.12 + ref = 'truster', 101.13 +} 101.14 + 101.15 +Delegation:add_reference{ 101.16 + mode = 'm1', 101.17 + to = "Member", 101.18 + this_key = 'trustee_id', 101.19 + that_key = 'id', 101.20 + ref = 'trustee', 101.21 +} 101.22 + 101.23 +Delegation:add_reference{ 101.24 + mode = 'm1', 101.25 + to = "Area", 101.26 + this_key = 'area_id', 101.27 + that_key = 'id', 101.28 + ref = 'area', 101.29 +} 101.30 + 101.31 +Delegation:add_reference{ 101.32 + mode = 'm1', 101.33 + to = "Issue", 101.34 + this_key = 'issue_id', 101.35 + that_key = 'id', 101.36 + ref = 'issue', 101.37 +} 101.38 + 101.39 +function Delegation:by_pk(truster_id, area_id, issue_id) 101.40 + local selector = self:new_selector():optional_object_mode() 101.41 + selector:add_where{ "truster_id = ?", truster_id } 101.42 + if area_id then 101.43 + selector:add_where{ "area_id = ?", area_id } 101.44 + else 101.45 + selector:add_where("area_id ISNULL") 101.46 + end 101.47 + if issue_id then 101.48 + selector:add_where{ "issue_id = ? ", issue_id } 101.49 + else 101.50 + selector:add_where("issue_id ISNULL ") 101.51 + end 101.52 + return selector:exec() 101.53 +end 101.54 \ No newline at end of file
102.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 102.2 +++ b/model/direct_voter.lua Wed Nov 18 12:00:00 2009 +0100 102.3 @@ -0,0 +1,18 @@ 102.4 +DirectVoter = mondelefant.new_class() 102.5 +DirectVoter.table = 'member' 102.6 + 102.7 +DirectVoter:add_reference{ 102.8 + mode = 'm1', 102.9 + to = "Issue", 102.10 + this_key = 'issue_id', 102.11 + that_key = 'id', 102.12 + ref = 'issue', 102.13 +} 102.14 + 102.15 +DirectVoter:add_reference{ 102.16 + mode = 'm1', 102.17 + to = "Member", 102.18 + this_key = 'member_id', 102.19 + that_key = 'id', 102.20 + ref = 'member', 102.21 +}
103.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 103.2 +++ b/model/draft.lua Wed Nov 18 12:00:00 2009 +0100 103.3 @@ -0,0 +1,24 @@ 103.4 +Draft = mondelefant.new_class() 103.5 +Draft.table = 'draft' 103.6 + 103.7 +Draft:add_reference{ 103.8 + mode = 'm1', 103.9 + to = "Initiative", 103.10 + this_key = 'initiative_id', 103.11 + that_key = 'id', 103.12 + ref = 'initiative', 103.13 +} 103.14 + 103.15 +Draft:add_reference{ 103.16 + mode = 'm1', 103.17 + to = "Member", 103.18 + this_key = 'author_id', 103.19 + that_key = 'id', 103.20 + ref = 'author', 103.21 +} 103.22 + 103.23 +-- reference to supporter probably not needed 103.24 + 103.25 +function Draft.object_get:author_name() 103.26 + return self.author and self.author.name or _"Unknown author" 103.27 +end
104.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 104.2 +++ b/model/initiative.lua Wed Nov 18 12:00:00 2009 +0100 104.3 @@ -0,0 +1,114 @@ 104.4 +Initiative = mondelefant.new_class() 104.5 +Initiative.table = 'initiative' 104.6 + 104.7 +Initiative:add_reference{ 104.8 + mode = 'm1', 104.9 + to = "Issue", 104.10 + this_key = 'issue_id', 104.11 + that_key = 'id', 104.12 + ref = 'issue', 104.13 +} 104.14 + 104.15 +Initiative:add_reference{ 104.16 + mode = '1m', 104.17 + to = "Draft", 104.18 + this_key = 'id', 104.19 + that_key = 'initiative_id', 104.20 + ref = 'drafts', 104.21 + back_ref = 'initiative', 104.22 + default_order = '"id"' 104.23 +} 104.24 + 104.25 +Initiative:add_reference{ 104.26 + mode = '1m', 104.27 + to = "Suggestion", 104.28 + this_key = 'id', 104.29 + that_key = 'initiative_id', 104.30 + ref = 'suggestions', 104.31 + back_ref = 'initiative', 104.32 + default_order = '"id"' 104.33 +} 104.34 + 104.35 +Initiative:add_reference{ 104.36 + mode = '1m', 104.37 + to = "Initiator", 104.38 + this_key = 'id', 104.39 + that_key = 'initiative_id', 104.40 + ref = 'initiators', 104.41 + back_ref = 'initiative', 104.42 + default_order = '"id"' 104.43 +} 104.44 + 104.45 +Initiative:add_reference{ 104.46 + mode = '1m', 104.47 + to = "Supporter", 104.48 + this_key = 'id', 104.49 + that_key = 'initiative_id', 104.50 + ref = 'supporters', 104.51 + back_ref = 'initiative', 104.52 + default_order = '"id"' 104.53 +} 104.54 + 104.55 +Initiative:add_reference{ 104.56 + mode = '1m', 104.57 + to = "Opinion", 104.58 + this_key = 'id', 104.59 + that_key = 'initiative_id', 104.60 + ref = 'opinions', 104.61 + back_ref = 'initiative', 104.62 + default_order = '"id"' 104.63 +} 104.64 + 104.65 +Initiative:add_reference{ 104.66 + mode = '1m', 104.67 + to = "Vote", 104.68 + this_key = 'id', 104.69 + that_key = 'initiative_id', 104.70 + ref = 'votes', 104.71 + back_ref = 'initiative', 104.72 + default_order = '"member_id"' 104.73 +} 104.74 + 104.75 +Initiative:add_reference{ 104.76 + mode = 'mm', 104.77 + to = "Member", 104.78 + this_key = 'id', 104.79 + that_key = 'id', 104.80 + connected_by_table = '"initiator"', 104.81 + connected_by_this_key = 'initiative_id', 104.82 + connected_by_that_key = 'member_id', 104.83 + ref = 'initiating_members' 104.84 +} 104.85 + 104.86 +Initiative:add_reference{ 104.87 + mode = 'mm', 104.88 + to = "Member", 104.89 + this_key = 'id', 104.90 + that_key = 'id', 104.91 + connected_by_table = '"supporter"', 104.92 + connected_by_this_key = 'initiative_id', 104.93 + connected_by_that_key = 'member_id', 104.94 + ref = 'supporting_members' 104.95 +} 104.96 + 104.97 +function Initiative:search(search_string) 104.98 + return self:new_selector() 104.99 + :add_where{ '"initiative"."name" ILIKE ?', "%" .. search_string:gsub("%%", "") .. "%" } 104.100 + :exec() 104.101 +end 104.102 + 104.103 +function Initiative.object_get:current_draft() 104.104 + return Draft:new_selector() 104.105 + :add_where{ '"initiative_id" = ?', self.id } 104.106 + :add_order_by('"id" DESC') 104.107 + :single_object_mode() 104.108 + :exec() 104.109 +end 104.110 + 104.111 +function Initiative.object_get:shortened_name() 104.112 + local name = self.name 104.113 + if #name > 100 then 104.114 + name = name:sub(1,100) .. "..." 104.115 + end 104.116 + return name 104.117 +end
105.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 105.2 +++ b/model/initiator.lua Wed Nov 18 12:00:00 2009 +0100 105.3 @@ -0,0 +1,27 @@ 105.4 +Initiator = mondelefant.new_class() 105.5 +Initiator.table = 'initiator' 105.6 +Initiator.primary_key = { "initiative_id", "member_id" } 105.7 + 105.8 +Initiator:add_reference{ 105.9 + mode = 'm1', 105.10 + to = "Initiative", 105.11 + this_key = 'initiative_id', 105.12 + that_key = 'id', 105.13 + ref = 'initiative', 105.14 +} 105.15 + 105.16 +Initiator:add_reference{ 105.17 + mode = 'm1', 105.18 + to = "Member", 105.19 + this_key = 'member_id', 105.20 + that_key = 'id', 105.21 + ref = 'member', 105.22 +} 105.23 + 105.24 +function Initiator:by_pk(initiative_id, member_id) 105.25 + return self:new_selector() 105.26 + :add_where{ "initiative_id = ?", initiative_id } 105.27 + :add_where{ "member_id = ?", member_id } 105.28 + :optional_object_mode() 105.29 + :exec() 105.30 +end
106.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 106.2 +++ b/model/interest.lua Wed Nov 18 12:00:00 2009 +0100 106.3 @@ -0,0 +1,25 @@ 106.4 +Interest = mondelefant.new_class() 106.5 +Interest.table = 'interest' 106.6 +Interest.primary_key = { "issue_id", "member_id" } 106.7 +Interest:add_reference{ 106.8 + mode = 'm1', 106.9 + to = "Member", 106.10 + this_key = 'member_id', 106.11 + that_key = 'id', 106.12 + ref = 'member', 106.13 +} 106.14 + 106.15 +Interest:add_reference{ 106.16 + mode = 'm1', 106.17 + to = "Issue", 106.18 + this_key = 'issue_id', 106.19 + that_key = 'id', 106.20 + ref = 'issue', 106.21 +} 106.22 + 106.23 +function Interest:by_pk(issue_id, member_id) 106.24 + return self:new_selector() 106.25 + :add_where{ "issue_id = ? AND member_id = ?", issue_id, member_id } 106.26 + :optional_object_mode() 106.27 + :exec() 106.28 +end 106.29 \ No newline at end of file
107.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 107.2 +++ b/model/issue.lua Wed Nov 18 12:00:00 2009 +0100 107.3 @@ -0,0 +1,109 @@ 107.4 +Issue = mondelefant.new_class() 107.5 +Issue.table = 'issue' 107.6 + 107.7 +Issue:add_reference{ 107.8 + mode = 'm1', 107.9 + to = "Area", 107.10 + this_key = 'area_id', 107.11 + that_key = 'id', 107.12 + ref = 'area', 107.13 +} 107.14 + 107.15 +Issue:add_reference{ 107.16 + mode = 'm1', 107.17 + to = "Policy", 107.18 + this_key = 'policy_id', 107.19 + that_key = 'id', 107.20 + ref = 'policy', 107.21 +} 107.22 + 107.23 +Issue:add_reference{ 107.24 + mode = '1m', 107.25 + to = "Initiative", 107.26 + this_key = 'id', 107.27 + that_key = 'issue_id', 107.28 + ref = 'initiatives', 107.29 + back_ref = 'issue' 107.30 +} 107.31 + 107.32 +Issue:add_reference{ 107.33 + mode = '1m', 107.34 + to = "Interest", 107.35 + this_key = 'id', 107.36 + that_key = 'issue_id', 107.37 + ref = 'interests', 107.38 + back_ref = 'issue', 107.39 + default_order = '"id"' 107.40 +} 107.41 + 107.42 +Issue:add_reference{ 107.43 + mode = '1m', 107.44 + to = "Supporter", 107.45 + this_key = 'id', 107.46 + that_key = 'issue_id', 107.47 + ref = 'supporters', 107.48 + back_ref = 'issue', 107.49 + default_order = '"id"' 107.50 +} 107.51 + 107.52 +Issue:add_reference{ 107.53 + mode = '1m', 107.54 + to = "DirectVoter", 107.55 + this_key = 'id', 107.56 + that_key = 'issue_id', 107.57 + ref = 'direct_voters', 107.58 + back_ref = 'issue', 107.59 + default_order = '"member_id"' 107.60 +} 107.61 + 107.62 +Issue:add_reference{ 107.63 + mode = '1m', 107.64 + to = "Vote", 107.65 + this_key = 'id', 107.66 + that_key = 'issue_id', 107.67 + ref = 'votes', 107.68 + back_ref = 'issue', 107.69 + default_order = '"member_id", "initiative_id"' 107.70 +} 107.71 + 107.72 +Issue:add_reference{ 107.73 + mode = 'mm', 107.74 + to = "Member", 107.75 + this_key = 'id', 107.76 + that_key = 'id', 107.77 + connected_by_table = 'interest', 107.78 + connected_by_this_key = 'issue_id', 107.79 + connected_by_that_key = 'member_id', 107.80 + ref = 'members' 107.81 +} 107.82 + 107.83 +function Issue:get_state_name_for_state(value) 107.84 + local state_name_table = {} 107.85 + return state_name_table[value] or value 107.86 +end 107.87 + 107.88 +function Issue:search(search_string) 107.89 + return self:new_selector() 107.90 + :join('"initiative"', nil, '"initiative"."issue_id" = "issue"."id"') 107.91 + :add_where{ '"initiative"."name" ILIKE ?', "%" .. search_string:gsub("%%", "") .. "%" } 107.92 + :set_distinct() 107.93 + :exec() 107.94 +end 107.95 + 107.96 +function Issue.object_get:state() 107.97 + if self.accepted then 107.98 + if self.frozen then 107.99 + return "frozen" 107.100 + elseif self.closed then 107.101 + return "closed" 107.102 + else 107.103 + return "accepted" 107.104 + end 107.105 + else 107.106 + if self.closed then 107.107 + return "closed" 107.108 + else 107.109 + return "new" 107.110 + end 107.111 + end 107.112 +end 107.113 \ No newline at end of file
108.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 108.2 +++ b/model/member.lua Wed Nov 18 12:00:00 2009 +0100 108.3 @@ -0,0 +1,256 @@ 108.4 +Member = mondelefant.new_class() 108.5 +Member.table = 'member' 108.6 + 108.7 +Member:add_reference{ 108.8 + mode = '1m', 108.9 + to = "Contact", 108.10 + this_key = 'id', 108.11 + that_key = 'member_id', 108.12 + ref = 'contacts', 108.13 + back_ref = 'member', 108.14 + default_order = '"other_member_id"' 108.15 +} 108.16 + 108.17 +Member:add_reference{ 108.18 + mode = '1m', 108.19 + to = "Contact", 108.20 + this_key = 'id', 108.21 + that_key = 'member_id', 108.22 + ref = 'foreign_contacts', 108.23 + back_ref = 'other_member', 108.24 + default_order = '"member_id"' 108.25 +} 108.26 + 108.27 +Member:add_reference{ 108.28 + mode = '1m', 108.29 + to = "Session", 108.30 + this_key = 'id', 108.31 + that_key = 'member_id', 108.32 + ref = 'sessions', 108.33 + back_ref = 'member', 108.34 + default_order = '"ident"' 108.35 +} 108.36 + 108.37 +Member:add_reference{ 108.38 + mode = '1m', 108.39 + to = "Draft", 108.40 + this_key = 'id', 108.41 + that_key = 'author_id', 108.42 + ref = 'drafts', 108.43 + back_ref = 'author', 108.44 + default_order = '"id"' 108.45 +} 108.46 + 108.47 +Member:add_reference{ 108.48 + mode = '1m', 108.49 + to = "Suggestion", 108.50 + this_key = 'id', 108.51 + that_key = 'author_id', 108.52 + ref = 'suggestions', 108.53 + back_ref = 'author', 108.54 + default_order = '"id"' 108.55 +} 108.56 + 108.57 +Member:add_reference{ 108.58 + mode = '1m', 108.59 + to = "Membership", 108.60 + this_key = 'id', 108.61 + that_key = 'member_id', 108.62 + ref = 'memberships', 108.63 + back_ref = 'member', 108.64 + default_order = '"area_id"' 108.65 +} 108.66 + 108.67 +Member:add_reference{ 108.68 + mode = '1m', 108.69 + to = "Interest", 108.70 + this_key = 'id', 108.71 + that_key = 'member_id', 108.72 + ref = 'interests', 108.73 + back_ref = 'member', 108.74 + default_order = '"id"' 108.75 +} 108.76 + 108.77 +Member:add_reference{ 108.78 + mode = '1m', 108.79 + to = "Initiator", 108.80 + this_key = 'id', 108.81 + that_key = 'member_id', 108.82 + ref = 'initiators', 108.83 + back_ref = 'member', 108.84 + default_order = '"id"' 108.85 +} 108.86 + 108.87 +Member:add_reference{ 108.88 + mode = '1m', 108.89 + to = "Supporter", 108.90 + this_key = 'id', 108.91 + that_key = 'member_id', 108.92 + ref = 'supporters', 108.93 + back_ref = 'member', 108.94 + default_order = '"id"' 108.95 +} 108.96 + 108.97 +Member:add_reference{ 108.98 + mode = '1m', 108.99 + to = "Opinion", 108.100 + this_key = 'id', 108.101 + that_key = 'member_id', 108.102 + ref = 'opinions', 108.103 + back_ref = 'member', 108.104 + default_order = '"id"' 108.105 +} 108.106 + 108.107 +Member:add_reference{ 108.108 + mode = '1m', 108.109 + to = "Delegation", 108.110 + this_key = 'id', 108.111 + that_key = 'truster_id', 108.112 + ref = 'outgoing_delegations', 108.113 + back_ref = 'truster', 108.114 + default_order = '"id"' 108.115 +} 108.116 + 108.117 +Member:add_reference{ 108.118 + mode = '1m', 108.119 + to = "Delegation", 108.120 + this_key = 'id', 108.121 + that_key = 'trustee_id', 108.122 + ref = 'incoming_delegations', 108.123 + back_ref = 'trustee', 108.124 + default_order = '"id"' 108.125 +} 108.126 + 108.127 +Member:add_reference{ 108.128 + mode = '1m', 108.129 + to = "DirectVoter", 108.130 + this_key = 'id', 108.131 + that_key = 'member_id', 108.132 + ref = 'direct_voter', 108.133 + back_ref = 'member', 108.134 + default_order = '"issue_id"' 108.135 +} 108.136 + 108.137 +Member:add_reference{ 108.138 + mode = '1m', 108.139 + to = "Vote", 108.140 + this_key = 'id', 108.141 + that_key = 'member_id', 108.142 + ref = 'vote', 108.143 + back_ref = 'member', 108.144 + default_order = '"issue_id", "initiative_id"' 108.145 +} 108.146 + 108.147 +Member:add_reference{ 108.148 + mode = 'mm', 108.149 + to = "Member", 108.150 + this_key = 'id', 108.151 + that_key = 'id', 108.152 + connected_by_table = 'contact', 108.153 + connected_by_this_key = 'member_id', 108.154 + connected_by_that_key = 'other_member_id', 108.155 + ref = 'saved_members', 108.156 +} 108.157 + 108.158 +Member:add_reference{ 108.159 + mode = 'mm', 108.160 + to = "Member", 108.161 + this_key = 'id', 108.162 + that_key = 'id', 108.163 + connected_by_table = 'contact', 108.164 + connected_by_this_key = 'other_member_id', 108.165 + connected_by_that_key = 'member_id', 108.166 + ref = 'saved_by_members', 108.167 +} 108.168 + 108.169 +Member:add_reference{ 108.170 + mode = 'mm', 108.171 + to = "Area", 108.172 + this_key = 'id', 108.173 + that_key = 'id', 108.174 + connected_by_table = 'membership', 108.175 + connected_by_this_key = 'member_id', 108.176 + connected_by_that_key = 'area_id', 108.177 + ref = 'areas' 108.178 +} 108.179 + 108.180 +Member:add_reference{ 108.181 + mode = 'mm', 108.182 + to = "Issue", 108.183 + this_key = 'id', 108.184 + that_key = 'id', 108.185 + connected_by_table = 'interest', 108.186 + connected_by_this_key = 'member_id', 108.187 + connected_by_that_key = 'issue_id', 108.188 + ref = 'issues' 108.189 +} 108.190 + 108.191 +Member:add_reference{ 108.192 + mode = 'mm', 108.193 + to = "Initiative", 108.194 + this_key = 'id', 108.195 + that_key = 'id', 108.196 + connected_by_table = 'initiator', 108.197 + connected_by_this_key = 'member_id', 108.198 + connected_by_that_key = 'initiative_id', 108.199 + ref = 'initiated_initiatives' 108.200 +} 108.201 + 108.202 +Member:add_reference{ 108.203 + mode = 'mm', 108.204 + to = "Initiative", 108.205 + this_key = 'id', 108.206 + that_key = 'id', 108.207 + connected_by_table = 'supporter', 108.208 + connected_by_this_key = 'member_id', 108.209 + connected_by_that_key = 'initiative_id', 108.210 + ref = 'supported_initiatives' 108.211 +} 108.212 + 108.213 +function Member.object:set_password(password) 108.214 + local hash = os.crypt( 108.215 + password, 108.216 + "$1$" .. multirand.string( 108.217 + 8, 108.218 + "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./" 108.219 + ) 108.220 + ) 108.221 + assert(hash, "os.crypt failed") 108.222 + self.password = hash 108.223 +end 108.224 + 108.225 +function Member.object:check_password(password) 108.226 + if type(password) == "string" and type(self.password) == "string" then 108.227 + return os.crypt(password, self.password) == self.password 108.228 + else 108.229 + return false 108.230 + end 108.231 +end 108.232 + 108.233 +function Member.object_get:published_contacts() 108.234 + return Member:new_selector() 108.235 + :join('"contact"', nil, '"contact"."other_member_id" = "member"."id"') 108.236 + :add_where{ '"contact"."member_id" = ?', self.id } 108.237 + :add_where("public") 108.238 + :exec() 108.239 +end 108.240 + 108.241 +function Member:by_login_and_password(login, password) 108.242 + local selector = self:new_selector() 108.243 + selector:add_where{'"login" = ?', login, password } 108.244 + selector:add_where('"active"') 108.245 + selector:optional_object_mode() 108.246 + local member = selector:exec() 108.247 + if member and member:check_password(password) then 108.248 + return member 108.249 + else 108.250 + return nil 108.251 + end 108.252 +end 108.253 + 108.254 +function Member:search(search_string) 108.255 + return self:new_selector() 108.256 + :add_where{ '"member"."name" ILIKE ?', "%" .. search_string:gsub("%%", "") .. "%" } 108.257 + :add_where("active") 108.258 + :exec() 108.259 +end
109.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 109.2 +++ b/model/member_count.lua Wed Nov 18 12:00:00 2009 +0100 109.3 @@ -0,0 +1,6 @@ 109.4 +MemberCount = mondelefant.new_class() 109.5 +MemberCount.table = 'member_count' 109.6 + 109.7 +function MemberCount:get() 109.8 + return self:new_selector():single_object_mode():exec().total_count 109.9 +end 109.10 \ No newline at end of file
110.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 110.2 +++ b/model/membership.lua Wed Nov 18 12:00:00 2009 +0100 110.3 @@ -0,0 +1,26 @@ 110.4 +Membership = mondelefant.new_class() 110.5 +Membership.table = 'membership' 110.6 +Membership.primary_key = { "area_id", "member_id" } 110.7 + 110.8 +Membership:add_reference{ 110.9 + mode = 'm1', 110.10 + to = "Member", 110.11 + this_key = 'member_id', 110.12 + that_key = 'id', 110.13 + ref = 'member', 110.14 +} 110.15 + 110.16 +Membership:add_reference{ 110.17 + mode = 'm1', 110.18 + to = "Area", 110.19 + this_key = 'area_id', 110.20 + that_key = 'id', 110.21 + ref = 'area', 110.22 +} 110.23 + 110.24 +function Membership:by_pk(area_id, member_id) 110.25 + return self:new_selector() 110.26 + :add_where{ "area_id = ? AND member_id = ?", area_id, member_id } 110.27 + :optional_object_mode() 110.28 + :exec() 110.29 +end 110.30 \ No newline at end of file
111.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 111.2 +++ b/model/opinion.lua Wed Nov 18 12:00:00 2009 +0100 111.3 @@ -0,0 +1,35 @@ 111.4 +Opinion = mondelefant.new_class() 111.5 +Opinion.table = 'opinion' 111.6 +Opinion.primary_key = { "member_id", "suggestion_id" } 111.7 + 111.8 +Opinion:add_reference{ 111.9 + mode = 'm1', 111.10 + to = "Initiative", 111.11 + this_key = 'initiative_id', 111.12 + that_key = 'id', 111.13 + ref = 'initiative', 111.14 +} 111.15 + 111.16 +Opinion:add_reference{ 111.17 + mode = 'm1', 111.18 + to = "Suggestion", 111.19 + this_key = 'suggestion_id', 111.20 + that_key = 'id', 111.21 + ref = 'suggestion', 111.22 +} 111.23 + 111.24 +Opinion:add_reference{ 111.25 + mode = 'm1', 111.26 + to = "Member", 111.27 + this_key = 'member_id', 111.28 + that_key = 'id', 111.29 + ref = 'member', 111.30 +} 111.31 + 111.32 +function Opinion:by_pk(member_id, suggestion_id) 111.33 + return self:new_selector() 111.34 + :add_where{ "member_id = ?", member_id } 111.35 + :add_where{ "suggestion_id = ?", suggestion_id } 111.36 + :optional_object_mode() 111.37 + :exec() 111.38 +end
112.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 112.2 +++ b/model/policy.lua Wed Nov 18 12:00:00 2009 +0100 112.3 @@ -0,0 +1,12 @@ 112.4 +Policy = mondelefant.new_class() 112.5 +Policy.table = 'policy' 112.6 + 112.7 +Policy:add_reference{ 112.8 + mode = '1m', 112.9 + to = "Issue", 112.10 + this_key = 'id', 112.11 + that_key = 'policy_id', 112.12 + ref = 'issues', 112.13 + back_ref = 'policy', 112.14 + default_order = '"created", "id"' 112.15 +}
113.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 113.2 +++ b/model/session.lua Wed Nov 18 12:00:00 2009 +0100 113.3 @@ -0,0 +1,33 @@ 113.4 +Session = mondelefant.new_class() 113.5 +Session.table = 'session' 113.6 +Session.primary_key = { 'ident' } 113.7 + 113.8 +Session:add_reference{ 113.9 + mode = 'm1', 113.10 + to = "Member", 113.11 + this_key = 'member_id', 113.12 + that_key = 'id', 113.13 + ref = 'member', 113.14 +} 113.15 + 113.16 +local function random_string() 113.17 + return multirand.string( 113.18 + 32, 113.19 + '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' 113.20 + ) 113.21 +end 113.22 + 113.23 +function Session:new() 113.24 + local session = self.prototype.new(self) -- super call 113.25 + session.ident = random_string() 113.26 + session.additional_secret = random_string() 113.27 + session:save() 113.28 + return session 113.29 +end 113.30 + 113.31 +function Session:by_ident(ident) 113.32 + local selector = self:new_selector() 113.33 + selector:add_where{ 'ident = ?', ident } 113.34 + selector:optional_object_mode() 113.35 + return selector:exec() 113.36 +end
114.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 114.2 +++ b/model/suggestion.lua Wed Nov 18 12:00:00 2009 +0100 114.3 @@ -0,0 +1,28 @@ 114.4 +Suggestion = mondelefant.new_class() 114.5 +Suggestion.table = 'suggestion' 114.6 + 114.7 +Suggestion:add_reference{ 114.8 + mode = 'm1', 114.9 + to = "Initiative", 114.10 + this_key = 'initiative_id', 114.11 + that_key = 'id', 114.12 + ref = 'initiative', 114.13 +} 114.14 + 114.15 +Suggestion:add_reference{ 114.16 + mode = 'm1', 114.17 + to = "Member", 114.18 + this_key = 'author_id', 114.19 + that_key = 'id', 114.20 + ref = 'author', 114.21 +} 114.22 + 114.23 +Suggestion:add_reference{ 114.24 + mode = '1m', 114.25 + to = "Opinion", 114.26 + this_key = 'id', 114.27 + that_key = 'issue_id', 114.28 + ref = 'opinions', 114.29 + back_ref = 'issue', 114.30 + default_order = '"id"' 114.31 +}
115.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 115.2 +++ b/model/supporter.lua Wed Nov 18 12:00:00 2009 +0100 115.3 @@ -0,0 +1,27 @@ 115.4 +Supporter = mondelefant.new_class() 115.5 +Supporter.table = 'supporter' 115.6 +Supporter.primary_key = { "initiative_id", "member_id" } 115.7 + 115.8 +Supporter:add_reference{ 115.9 + mode = 'm1', 115.10 + to = "Initiative", 115.11 + this_key = 'initiative_id', 115.12 + that_key = 'id', 115.13 + ref = 'initiative', 115.14 +} 115.15 + 115.16 +Supporter:add_reference{ 115.17 + mode = 'm1', 115.18 + to = "Member", 115.19 + this_key = 'member_id', 115.20 + that_key = 'id', 115.21 + ref = 'member', 115.22 +} 115.23 + 115.24 +function Supporter:by_pk(initiative_id, member_id) 115.25 + return self:new_selector() 115.26 + :add_where{ "initiative_id = ?", initiative_id } 115.27 + :add_where{ "member_id = ?", member_id } 115.28 + :optional_object_mode() 115.29 + :exec() 115.30 +end
116.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 116.2 +++ b/model/vote.lua Wed Nov 18 12:00:00 2009 +0100 116.3 @@ -0,0 +1,26 @@ 116.4 +Vote = mondelefant.new_class() 116.5 +Vote.table = 'vote' 116.6 + 116.7 +Vote:add_reference{ 116.8 + mode = 'm1', 116.9 + to = "Issue", 116.10 + this_key = 'issue_id', 116.11 + that_key = 'id', 116.12 + ref = 'issue', 116.13 +} 116.14 + 116.15 +Vote:add_reference{ 116.16 + mode = 'm1', 116.17 + to = "Initiative", 116.18 + this_key = 'initiative_id', 116.19 + that_key = 'id', 116.20 + ref = 'initiative', 116.21 +} 116.22 + 116.23 +Vote:add_reference{ 116.24 + mode = 'm1', 116.25 + to = "Member", 116.26 + this_key = 'author_id', 116.27 + that_key = 'id', 116.28 + ref = 'author', 116.29 +}
117.1 Binary file static/icons/16/add.png has changed
118.1 Binary file static/icons/16/application_form.png has changed
119.1 Binary file static/icons/16/award_star_gold_2.png has changed
120.1 Binary file static/icons/16/award_star_silver_2.png has changed
121.1 Binary file static/icons/16/book_add.png has changed
122.1 Binary file static/icons/16/book_edit.png has changed
123.1 Binary file static/icons/16/cancel.png has changed
124.1 Binary file static/icons/16/cog.png has changed
125.1 Binary file static/icons/16/comment_add.png has changed
126.1 Binary file static/icons/16/cross.png has changed
127.1 Binary file static/icons/16/delete.png has changed
128.1 Binary file static/icons/16/folder.png has changed
129.1 Binary file static/icons/16/folder_add.png has changed
130.1 Binary file static/icons/16/group.png has changed
131.1 Binary file static/icons/16/house.png has changed
132.1 Binary file static/icons/16/information.png has changed
133.1 Binary file static/icons/16/key.png has changed
134.1 Binary file static/icons/16/package.png has changed
135.1 Binary file static/icons/16/page.png has changed
136.1 Binary file static/icons/16/page_add.png has changed
137.1 Binary file static/icons/16/script.png has changed
138.1 Binary file static/icons/16/script_add.png has changed
139.1 Binary file static/icons/16/stop.png has changed
140.1 Binary file static/icons/16/table_go.png has changed
141.1 Binary file static/icons/16/thumb_down_red.png has changed
142.1 Binary file static/icons/16/thumb_up_green.png has changed
143.1 Binary file static/icons/16/tick.png has changed
144.1 Binary file static/icons/16/user_comment.png has changed
145.1 Binary file static/icons/16/user_gray.png has changed
146.1 Binary file static/lang/de.png has changed
147.1 Binary file static/lang/en.png has changed
148.1 Binary file static/lang/es.png has changed
149.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 149.2 +++ b/static/style.css Wed Nov 18 12:00:00 2009 +0100 149.3 @@ -0,0 +1,559 @@ 149.4 +/************************************************************************* 149.5 + * Some global definitions 149.6 + */ 149.7 + 149.8 +body, th, td { 149.9 + font-family: sans-serif; 149.10 + font-size: 14px; 149.11 + padding: 0; 149.12 + margin: 0; 149.13 +} 149.14 + 149.15 +body, a { 149.16 + color: #000; 149.17 +} 149.18 + 149.19 +img { 149.20 + border: none; 149.21 +} 149.22 + 149.23 +table { 149.24 + border-collapse: collapse; 149.25 + border: none; 149.26 +} 149.27 + 149.28 +td, th { 149.29 + vertical-align: top; 149.30 + padding: 0.5ex 0.5em 0.5ex 0.5em; 149.31 +} 149.32 + 149.33 +a.active { 149.34 + color: #fff; 149.35 +} 149.36 + 149.37 +.highlighted { 149.38 + background-color: #fa7; 149.39 + color: #000; 149.40 +} 149.41 + 149.42 +.admin_only { 149.43 + font-style: italic; 149.44 +} 149.45 + 149.46 +/************************************************************************* 149.47 + * Notices, warnings and errors 149.48 + */ 149.49 + 149.50 +.layout_notice, .layout_error, .layout_warning { 149.51 + background: #fff; 149.52 + font-weight: bold; 149.53 + right: 2ex; 149.54 + line-height: 1.7em; 149.55 + position: absolute; 149.56 + top: 6ex; 149.57 + width: 60ex; 149.58 + -moz-opacity:0.7; 149.59 +} 149.60 + 149.61 +.slot_notice, .slot_warning, .slot_error { 149.62 + padding: 2ex; 149.63 +} 149.64 + 149.65 +.slot_notice { 149.66 + color: green; 149.67 + border: 2px solid green; 149.68 +} 149.69 + 149.70 +.slot_warning { 149.71 + color: orange; 149.72 + border: 2px solid orange; 149.73 +} 149.74 + 149.75 +.slot_error { 149.76 + color: red; 149.77 + border: 2px solid red; 149.78 +} 149.79 + 149.80 +/************************************************************************* 149.81 + * Navigation, search and language chooser bar 149.82 + */ 149.83 + 149.84 +.topbar { 149.85 + margin-bottom: 1em; 149.86 + background-color: #444; 149.87 + color: #fff; 149.88 + font-size: 75%; 149.89 +} 149.90 + 149.91 +.topbar a { 149.92 + color: #fff; 149.93 +} 149.94 + 149.95 +.topbar a:hover { 149.96 + background-color: #fff; 149.97 + color: #000; 149.98 +} 149.99 + 149.100 +.navigation, 149.101 +.logout_button { 149.102 + line-height: 250%; 149.103 +} 149.104 + 149.105 +.navigation img, 149.106 +.logout_button img { 149.107 + margin-right: 0.5em; 149.108 + vertical-align: middle; 149.109 +} 149.110 + 149.111 +.navigation a, 149.112 +.logout_button a { 149.113 + padding: 1ex; 149.114 +} 149.115 + 149.116 +.logout_button { 149.117 + float: right; 149.118 +} 149.119 + 149.120 +.searchbox { 149.121 + padding: 0.5ex 1em 0ex 1em; 149.122 + float: right; 149.123 + line-height: 250%; 149.124 +} 149.125 + 149.126 +.searchbox div { 149.127 + display: inline; 149.128 +} 149.129 + 149.130 +.searchbox select { 149.131 + margin-left: 0.3em; 149.132 + margin-right: 0.4em; 149.133 + font-size: 100%; 149.134 + width: 8em; 149.135 +} 149.136 + 149.137 +.searchbox input[type=text] { 149.138 + width: 8em; 149.139 + padding: 0.25ex 0.25em 0.25ex 0.25em; 149.140 + margin-right: 0.5em; 149.141 + font-size: 100%; 149.142 +} 149.143 + 149.144 +.searchbox input[type=submit] { 149.145 + font-size: 100%; 149.146 + width: 2.5em; 149.147 +} 149.148 + 149.149 +/************************************************************************* 149.150 + * Title of current page including path and actions 149.151 + */ 149.152 + 149.153 +.title_bar { 149.154 + border-bottom: 1px solid #000; 149.155 + margin-bottom: 2ex; 149.156 +} 149.157 + 149.158 +.path { 149.159 + color: #444; 149.160 + xbackground-color: #ddd; 149.161 +} 149.162 + 149.163 +.path div { 149.164 + margin-left: 1em; 149.165 + font-size: 100%; 149.166 + line-height: 180%; 149.167 +} 149.168 + 149.169 +.path a { 149.170 + color: #444; 149.171 +} 149.172 + 149.173 +.slot_path div { 149.174 + display: inline; 149.175 + margin-left: 1em; 149.176 + margin-right: 1em; 149.177 +} 149.178 + 149.179 +.title { 149.180 + color: #000; 149.181 + margin-bottom: 0.5ex; 149.182 +} 149.183 + 149.184 +.slot_title { 149.185 +} 149.186 + 149.187 +.title div { 149.188 + margin-left: 0.66em; 149.189 + font-weight: bold; 149.190 + font-size: 135%; 149.191 + line-height: 110%; 149.192 +} 149.193 + 149.194 +.title a { 149.195 + color: #fff; 149.196 +} 149.197 + 149.198 +.avatar { 149.199 + float: left; 149.200 + margin-right: 0.5em; 149.201 +} 149.202 + 149.203 +.actions { 149.204 + display: inline; 149.205 + font-size: 75%; 149.206 + line-height: 200%; 149.207 +} 149.208 + 149.209 +.slot_actions { 149.210 + margin-left: 1em; 149.211 + display: inline; 149.212 +} 149.213 + 149.214 +.actions a { 149.215 + padding: 0.5ex 0.5em 0.5ex 0.0em; 149.216 + margin-right: 1em; 149.217 + vertical-align: middle; 149.218 +} 149.219 + 149.220 +.actions a:hover { 149.221 + background-color: #d7d7d7; 149.222 +} 149.223 + 149.224 +.actions img { 149.225 + padding-left: 0.2em; 149.226 + padding-right: 0.2em; 149.227 +} 149.228 + 149.229 +/************************************************************************* 149.230 + * Main content 149.231 + */ 149.232 + 149.233 +.main { 149.234 + margin-left: 1em; 149.235 + margin-right: 1em; 149.236 +} 149.237 + 149.238 + 149.239 +/************************************************************************* 149.240 + * ui.tab 149.241 + */ 149.242 + 149.243 +.ui_tabs_links { 149.244 + margin-top: 4ex; 149.245 + font-size: 75%; 149.246 +} 149.247 + 149.248 +.ui_tabs_links a { 149.249 + padding: 1ex; 149.250 + margin-left: 0.5em; 149.251 + background-color: #e7e7e7; 149.252 +} 149.253 + 149.254 +.ui_tabs_links a:hover { 149.255 + background-color: #d7d7d7; 149.256 +} 149.257 + 149.258 +.ui_tabs_links a.selected { 149.259 + background-color: #444; 149.260 + color: #fff; 149.261 + text-decoration: none; 149.262 + padding: 1ex; 149.263 +} 149.264 + 149.265 +.ui_tabs_content { 149.266 + border: 1px solid #444; 149.267 + padding: 1ex 1ex 1ex 1ex; 149.268 +} 149.269 + 149.270 +/************************************************************************* 149.271 + * ui.order 149.272 + */ 149.273 + 149.274 +.ui_order_head { 149.275 + color: #777; 149.276 + text-align: right; 149.277 + margin-bottom: 1ex; 149.278 + font-size: 75%; 149.279 +} 149.280 + 149.281 +.ui_order_head a { 149.282 + color: #777; 149.283 + padding: 0.5ex; 149.284 +} 149.285 + 149.286 +.ui_order_head a.active{ 149.287 + color: #fff; 149.288 + background-color: #777; 149.289 + padding: 0.5ex; 149.290 +} 149.291 + 149.292 +/************************************************************************* 149.293 + * ui.paginate 149.294 + */ 149.295 + 149.296 +.ui_paginate_select a { 149.297 + padding: 0.5ex; 149.298 +} 149.299 + 149.300 +/************************************************************************* 149.301 + * ui.bargraph 149.302 + */ 149.303 + 149.304 +.bargraph { 149.305 + width: 50px; 149.306 +} 149.307 + 149.308 +.bargraph div { 149.309 + float: left; 149.310 + margin-top: 0.5ex; 149.311 + height: 1ex; 149.312 +} 149.313 + 149.314 +/************************************************************************* 149.315 + * vertical ui.form 149.316 + */ 149.317 + 149.318 +.login input[type=text], 149.319 +.vertical input[type=text], 149.320 +.login input[type=password], 149.321 +.vertical input[type=password], 149.322 +.vertical textarea, 149.323 +.vertical select { 149.324 + font-family: sans-serif; 149.325 + font-size: 100%; 149.326 + border: 1px solid #444; 149.327 + width: 40em; 149.328 + padding: 0.2ex 0.2em 0.2ex 0.2em; 149.329 + margin-bottom: 1ex; 149.330 +} 149.331 + 149.332 +.login input[type=password], 149.333 +.vertical input[type=password] { 149.334 + width: 16em; 149.335 +} 149.336 + 149.337 +.vertical select { 149.338 + padding-right: 0; 149.339 +} 149.340 + 149.341 +.login .ui_field_label, 149.342 +.vertical .ui_field_label { 149.343 + text-transform: uppercase; 149.344 + font-size: 70%; 149.345 + line-height: 190%; 149.346 + font-weight: bold; 149.347 + color: #777; 149.348 + width: 15em; 149.349 + display: block; 149.350 + float: left; 149.351 + clear: left; 149.352 + text-align: right; 149.353 + padding-right: 0.5em; 149.354 +} 149.355 + 149.356 +.login input[type=text], 149.357 +.login input[type=password] { 149.358 + width: 10em; 149.359 +} 149.360 + 149.361 +.login div, 149.362 +.vertical div { 149.363 + clear: left; 149.364 +} 149.365 + 149.366 +.vertical span { 149.367 + display: block; 149.368 + margin-bottom: 0.5ex; 149.369 +} 149.370 + 149.371 +.vertical span:after { 149.372 + content: " "; 149.373 +} 149.374 + 149.375 +.vertical span span { 149.376 + display: inline; 149.377 + margin-bottom: 0; 149.378 +} 149.379 + 149.380 +.login input[type=submit], 149.381 +.vertical input[type=submit] { 149.382 + font-size: 100%; 149.383 + margin-left: 11em; 149.384 + background-color: #444444; 149.385 + color: #fff; 149.386 + border: none; 149.387 + padding: 0.75ex; 149.388 +} 149.389 + 149.390 +.login input[type=submit]:hover, 149.391 +.vertical input[type=submit]:hover { 149.392 + background-color: #444444; 149.393 +} 149.394 + 149.395 +/************************************************************************* 149.396 + * Tables 149.397 + */ 149.398 + 149.399 + 149.400 +table a.action { 149.401 + font-size: 70%; 149.402 + line-height: 190%; 149.403 + padding: 0.5ex; 149.404 + color: #777; 149.405 +} 149.406 + 149.407 +table a.active { 149.408 + color: #fff; 149.409 +} 149.410 + 149.411 +th { 149.412 + text-align: left; 149.413 + border-bottom: 1px solid #000; 149.414 +} 149.415 + 149.416 +tr:hover td { 149.417 + background-color: #ddd; 149.418 +} 149.419 + 149.420 + 149.421 +tr table tr:hover td { 149.422 + background-color: #fff; 149.423 +} 149.424 + 149.425 + 149.426 +/************************************************************************* 149.427 + * Hidden inline form 149.428 + */ 149.429 + 149.430 +.hidden_inline_form { 149.431 + display: none; 149.432 + border: 1px solid #444; 149.433 + width: 42em; 149.434 + position: absolute; 149.435 + background-color: #fff; 149.436 + left: 5em; 149.437 + top: 20ex; 149.438 +} 149.439 + 149.440 +.hidden_inline_form a { 149.441 + padding: 0.5ex; 149.442 + color: #fff; 149.443 +} 149.444 + 149.445 + 149.446 +.hidden_inline_form .head { 149.447 + background-color: #444; 149.448 + color: #fff; 149.449 + display: block; 149.450 + padding: 0.5ex; 149.451 +} 149.452 + 149.453 +.hidden_inline_form input[type=text], 149.454 +.hidden_inline_form textarea, 149.455 +.hidden_inline_form select { 149.456 + width: 30em; 149.457 +} 149.458 + 149.459 +/************************************************************************* 149.460 + * Positive / Negtive votes 149.461 + */ 149.462 + 149.463 + 149.464 +.positive_votes span { 149.465 + display: inline; 149.466 +} 149.467 + 149.468 +.positive_votes { 149.469 + display: inline; 149.470 + background-color: #cfc; 149.471 + padding: 0.3ex 0.5em 0.3ex 0.5em; 149.472 +} 149.473 + 149.474 +.negative_votes span { 149.475 + display: inline; 149.476 +} 149.477 + 149.478 +.negative_votes { 149.479 + display: inline; 149.480 + background-color: #fcc; 149.481 + padding: 0.3ex 0.5em 0.3ex 0.5em; 149.482 +} 149.483 + 149.484 + 149.485 + 149.486 +.active { 149.487 + background-color: #444; 149.488 + color: #fff; 149.489 +} 149.490 + 149.491 +.active_red2 { background-color: #a00; color: #fff !important; } 149.492 +.active_red1 { background-color: #f88; color: #000 !important; } 149.493 +.active_green1 { background-color: #8f8; color: #000 !important; } 149.494 +.active_green2 { background-color: #0a0; color: #000 !important; } 149.495 + 149.496 + 149.497 + 149.498 + 149.499 +/************************************************************************* 149.500 + * Issues 149.501 + */ 149.502 + 149.503 +.issues tr { 149.504 + border-bottom: 1px solid #444; 149.505 +} 149.506 + 149.507 +.issues tr tr { 149.508 + border-bottom: none; 149.509 +} 149.510 + 149.511 +/************************************************************************* 149.512 + * delegation 149.513 + */ 149.514 + 149.515 +.infobox { 149.516 + float: right; 149.517 + margin-right: 1em; 149.518 +} 149.519 + 149.520 +.slot_interest, 149.521 +.slot_support, 149.522 +.slot_delegation { 149.523 + border: 2px solid #444; 149.524 + width: 20em; 149.525 + font-size: 75%; 149.526 + padding: 0; 149.527 + margin-bottom: 0.5ex; 149.528 +} 149.529 + 149.530 +.infobox .head { 149.531 + margin: 0.5ex; 149.532 +} 149.533 + 149.534 +.infobox .content { 149.535 + display: none; 149.536 + position: absolute; 149.537 + z-index: 10; 149.538 + width: 20em; 149.539 + background-color: #fff; 149.540 + border: 2px solid #444; 149.541 +} 149.542 + 149.543 +.infobox .text { 149.544 + margin: 0.5ex; 149.545 + margin-bottom: 1ex; 149.546 +} 149.547 + 149.548 +.infobox .member { 149.549 + margin: 0.5ex; 149.550 + display: block; 149.551 + font-weight: bold; 149.552 + margin-bottom: 1ex; 149.553 +} 149.554 + 149.555 +.delegation .revoke { 149.556 + margin: 0.5ex; 149.557 +} 149.558 + 149.559 +.lang_chooser { 149.560 + float: right; 149.561 + margin-right: 0.5em; 149.562 +}
150.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 150.2 +++ b/static/trace.css Wed Nov 18 12:00:00 2009 +0100 150.3 @@ -0,0 +1,154 @@ 150.4 +.layout_trace { 150.5 + position: absolute; 150.6 + right: 0; 150.7 + margin-top: 20px; 150.8 + border: 1px solid #404040; 150.9 + font-size: 70%; 150.10 + padding: 5px; 150.11 + background: #ffe0c0; 150.12 +} 150.13 + 150.14 +#trace_show { 150.15 + cursor: pointer; 150.16 +} 150.17 + 150.18 +.trace_list { 150.19 + margin: 0px; 150.20 + margin-bottom: 10px; 150.21 + padding: 0px; 150.22 + list-style-type: none; 150.23 +} 150.24 + 150.25 +.trace_list .trace_list { 150.26 + border-top: 1px solid; 150.27 + margin-bottom: 0px; 150.28 +} 150.29 + 150.30 +.trace_list li { 150.31 + margin: 3px; 150.32 + padding: 0px; 150.33 +} 150.34 + 150.35 +.trace_head { 150.36 + font-weight: bold; 150.37 + margin: 1px; 150.38 +} 150.39 + 150.40 +.trace_error { 150.41 + border: 3px solid red; 150.42 + background-color: black; 150.43 + color: #c00000; 150.44 + text-align: center; 150.45 + text-decoration: blink; 150.46 +} 150.47 + 150.48 +.trace_error_position { 150.49 + color: red; 150.50 + text-decoration: blink; 150.51 + font-weight: bold; 150.52 +} 150.53 + 150.54 +.trace_config { 150.55 + border: 1px solid #608000; 150.56 + background-color: #ffffff; 150.57 + color: #608000; 150.58 +} 150.59 + 150.60 +.trace_config .trace_list { 150.61 + border-color: #608000; 150.62 +} 150.63 + 150.64 +.trace_request { 150.65 + border: 1px solid #6000ff; 150.66 + background-color: #c080ff; 150.67 + color: #6000ff; 150.68 +} 150.69 + 150.70 +.trace_request .trace_list { 150.71 + border-color: #6000ff; 150.72 +} 150.73 + 150.74 +.trace_filter { 150.75 + border: 1px solid #606060; 150.76 + background-color: #c0c0c0; 150.77 + color: #606060; 150.78 +} 150.79 + 150.80 +.trace_filter .trace_list { 150.81 + border-color: #606060; 150.82 +} 150.83 + 150.84 +.trace_view { 150.85 + border: 1px solid #0000ff; 150.86 + background-color: #40c0ff; 150.87 + color: #0000ff; 150.88 +} 150.89 + 150.90 +.trace_view .trace_list { 150.91 + border-color: #0000ff; 150.92 +} 150.93 + 150.94 +.trace_action_success { 150.95 + border: 1px solid #006000; 150.96 + background-color: #80ff80; 150.97 + color: #006000; 150.98 +} 150.99 + 150.100 +.trace_action_success .trace_list { 150.101 + border-color: #006000; 150.102 +} 150.103 + 150.104 +.trace_action_softfail { 150.105 + border: 1px solid #600000; 150.106 + background-color: #ff6020; 150.107 + color: #600000; 150.108 +} 150.109 + 150.110 +.trace_action_softfail .trace_list { 150.111 + border-color: #600000; 150.112 +} 150.113 + 150.114 +.trace_action_status { 150.115 + font-weight: bold; 150.116 +} 150.117 + 150.118 +.trace_action_neutral { 150.119 + border: 1px solid #600000; 150.120 + background-color: #ffc040; 150.121 + color: #600000; 150.122 +} 150.123 + 150.124 +.trace_action_neutral .trace_list { 150.125 + border-color: #600000; 150.126 +} 150.127 + 150.128 +.trace_redirect, .trace_forward { 150.129 + border: 1px solid #404000; 150.130 + background-color: #c08040; 150.131 + color: #404000; 150.132 +} 150.133 + 150.134 +.trace_redirect .trace_list, .trace_forward .trace_list { 150.135 + border-color: #404000; 150.136 +} 150.137 + 150.138 +.trace_exectime { 150.139 + border: 1px solid black; 150.140 + background-color: #404040; 150.141 + color: white; 150.142 +} 150.143 + 150.144 +.trace_exectime .trace_list { 150.145 + border-color: white; 150.146 +} 150.147 + 150.148 +.trace_close { 150.149 + border: 1px solid black; 150.150 + background-color: #605040; 150.151 + margin: 3px; 150.152 + padding: 3px; 150.153 + color: white; 150.154 + text-align: center; 150.155 + cursor: pointer; 150.156 +} 150.157 +