diff -r 80c215dbf076 -r afd9f769c7ae app/main/admin/_action/area_update.lua
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/app/main/admin/_action/area_update.lua Fri Dec 25 12:00:00 2009 +0100
@@ -0,0 +1,19 @@
+if not app.session.member.admin then
+ error()
+end
+
+local id = param.get_id()
+
+local area
+if id then
+ area = Area:new_selector():add_where{ "id = ?", id }:single_object_mode():exec()
+else
+ area = Area:new()
+end
+
+
+param.update(area, "name", "description", "active")
+
+area:save()
+
+slot.put_into("notice", _"Area successfully updated")
diff -r 80c215dbf076 -r afd9f769c7ae app/main/admin/area_show.lua
--- a/app/main/admin/area_show.lua Thu Dec 10 12:00:00 2009 +0100
+++ b/app/main/admin/area_show.lua Fri Dec 25 12:00:00 2009 +0100
@@ -10,8 +10,8 @@
ui.form{
attr = { class = "vertical" },
record = area,
- module = "area",
- action = "update",
+ module = "admin",
+ action = "area_update",
routing = {
default = {
mode = "redirect",
diff -r 80c215dbf076 -r afd9f769c7ae app/main/area/_action/update.lua
--- a/app/main/area/_action/update.lua Thu Dec 10 12:00:00 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-if not app.session.member.admin then
- error()
-end
-
-local id = param.get_id()
-
-local area
-if id then
- area = Area:new_selector():add_where{ "id = ?", id }:single_object_mode():exec()
-else
- area = Area:new()
-end
-
-
-param.update(area, "name", "description", "active")
-
-area:save()
-
-slot.put_into("notice", _"Area successfully updated")
diff -r 80c215dbf076 -r afd9f769c7ae app/main/contact/_action/add_member.lua
--- a/app/main/contact/_action/add_member.lua Thu Dec 10 12:00:00 2009 +0100
+++ b/app/main/contact/_action/add_member.lua Fri Dec 25 12:00:00 2009 +0100
@@ -20,8 +20,3 @@
contact.public = public or false
contact:save()
-if public then
--- slot.put_into("notice", _"Member has been saved as public contact")
-else
--- slot.put_into("notice", _"Member has been saved as private contact")
-end
diff -r 80c215dbf076 -r afd9f769c7ae app/main/delegation/_action/update.lua
--- a/app/main/delegation/_action/update.lua Thu Dec 10 12:00:00 2009 +0100
+++ b/app/main/delegation/_action/update.lua Fri Dec 25 12:00:00 2009 +0100
@@ -15,9 +15,9 @@
if param.get("delete") or trustee_id == -1 then
if delegation then
-
+
delegation:destroy()
-
+
if issue_id then
slot.put_into("notice", _"Your delegation for this issue has been deleted.")
elseif area_id then
@@ -27,7 +27,7 @@
end
end
-
+
else
if not delegation then
@@ -35,6 +35,13 @@
delegation.truster_id = truster_id
delegation.area_id = area_id
delegation.issue_id = issue_id
+ if issue_id then
+ delegation.scope = "issue"
+ elseif area_id then
+ delegation.scope = "area"
+ else
+ delegation.scope = "global"
+ end
end
delegation.trustee_id = trustee_id
diff -r 80c215dbf076 -r afd9f769c7ae app/main/delegation/_show_box.lua
--- a/app/main/delegation/_show_box.lua Thu Dec 10 12:00:00 2009 +0100
+++ b/app/main/delegation/_show_box.lua Fri Dec 25 12:00:00 2009 +0100
@@ -1,48 +1,47 @@
slot.select("actions", function()
- ui.container{
- attr = { class = "delegation vote_info"},
- content = function()
-
- local delegation
- local area_id
- local issue_id
-
- local scope = "global"
-
- if param.get("initiative_id", atom.integer) then
- issue_id = Initiative:by_id(param.get("initiative_id", atom.integer)).issue_id
- scope = "issue"
- end
-
- if param.get("issue_id", atom.integer) then
- issue_id = param.get("issue_id", atom.integer)
- scope = "issue"
- end
-
- if param.get("area_id", atom.integer) then
- area_id = param.get("area_id", atom.integer)
- scope = "area"
- end
-
-
-
- local delegation
-
- if issue_id then
- delegation = Delegation:by_pk(app.session.member.id, nil, issue_id)
- if not delegation then
- local issue = Issue:by_id(issue_id)
- delegation = Delegation:by_pk(app.session.member.id, issue.area_id)
- end
- elseif area_id then
- delegation = Delegation:by_pk(app.session.member.id, area_id)
- end
-
- if not delegation then
- delegation = Delegation:by_pk(app.session.member.id)
- end
- if delegation then
+ local delegation
+ local area_id
+ local issue_id
+
+ local scope = "global"
+
+ if param.get("initiative_id", atom.integer) then
+ issue_id = Initiative:by_id(param.get("initiative_id", atom.integer)).issue_id
+ scope = "issue"
+ end
+
+ if param.get("issue_id", atom.integer) then
+ issue_id = param.get("issue_id", atom.integer)
+ scope = "issue"
+ end
+
+ if param.get("area_id", atom.integer) then
+ area_id = param.get("area_id", atom.integer)
+ scope = "area"
+ end
+
+
+
+ local delegation
+ local issue
+ if issue_id then
+ issue = Issue:by_id(issue_id)
+ delegation = Delegation:by_pk(app.session.member.id, nil, issue_id)
+ if not delegation then
+ delegation = Delegation:by_pk(app.session.member.id, issue.area_id)
+ end
+ elseif area_id then
+ delegation = Delegation:by_pk(app.session.member.id, area_id)
+ end
+
+ if not delegation then
+ delegation = Delegation:by_pk(app.session.member.id)
+ end
+ if delegation then
+ ui.container{
+ attr = { class = "delegation vote_info"},
+ content = function()
ui.container{
attr = {
title = _"Click for details",
@@ -117,25 +116,27 @@
end
}
if i == 2 then
- ui.link{
- attr = { class = "revoke" },
- content = function()
- ui.image{ static = "icons/16/delete.png" }
- slot.put(_"Revoke")
- end,
- module = "delegation",
- action = "update",
- params = { issue_id = delegation.issue_id, area_id = delegation.area_id, delete = true },
- routing = {
- default = {
- mode = "redirect",
- module = request.get_module(),
- view = request.get_view(),
- id = param.get_id_cgi(),
- params = param.get_all_cgi()
+ if not issue or (issue.state ~= "finished" and issue.state ~= "cancelled") then
+ ui.link{
+ attr = { class = "revoke" },
+ content = function()
+ ui.image{ static = "icons/16/delete.png" }
+ slot.put(_"Revoke")
+ end,
+ module = "delegation",
+ action = "update",
+ params = { issue_id = delegation.issue_id, area_id = delegation.area_id, delete = true },
+ routing = {
+ default = {
+ mode = "redirect",
+ module = request.get_module(),
+ view = request.get_view(),
+ id = param.get_id_cgi(),
+ params = param.get_all_cgi()
+ }
}
}
- }
+ end
end
end
}
@@ -163,30 +164,39 @@
end
}
end
- ui.link{
- content = function()
+ }
+
+
+ end
+ ui.link{
+ content = function()
+ if scope == "global" and delegation then
+ ui.image{ static = "icons/16/table_go.png" }
+ slot.put(_"Change global delegation")
+ elseif scope == "global" and not delegation then
+ ui.image{ static = "icons/16/table_go.png" }
+ slot.put(_"Set global delegation")
+ elseif scope == "area" and delegation and delegation.area_id then
+ ui.image{ static = "icons/16/table_go.png" }
+ slot.put(_"Change area delegation")
+ elseif scope == "area" and not (delegation and delegation.area_id) then
+ ui.image{ static = "icons/16/table_go.png" }
+ slot.put(_"Set area delegation")
+ elseif scope == "issue" then
+ if delegation and delegation.issue_id then
ui.image{ static = "icons/16/table_go.png" }
- if scope == "global" and delegation then
- slot.put(_"Change global delegation")
- elseif scope == "global" and not delegation then
- slot.put(_"Set global delegation")
- elseif scope == "area" and delegation and delegation.area_id then
- slot.put(_"Change area delegation")
- elseif scope == "area" and not (delegation and delegation.area_id) then
- slot.put(_"Set area delegation")
- elseif scope == "issue" and delegation and delegation.issue_id then
- slot.put(_"Change issue delegation")
- elseif scope == "issue" and not (delegation and delegation.issue_id) then
- slot.put(_"Set issue delegation")
- end
- end,
- module = "delegation",
- view = "new",
- params = {
- area_id = area_id,
- issue_id = issue_id
- }
- }
- end
+ slot.put(_"Change issue delegation")
+ elseif issue.state ~= "finished" and issue.state ~= "cancelled" then
+ ui.image{ static = "icons/16/table_go.png" }
+ slot.put(_"Set issue delegation")
+ end
+ end
+ end,
+ module = "delegation",
+ view = "new",
+ params = {
+ area_id = area_id,
+ issue_id = issue_id
+ }
}
end)
diff -r 80c215dbf076 -r afd9f769c7ae app/main/draft/_action/add.lua
--- a/app/main/draft/_action/add.lua Thu Dec 10 12:00:00 2009 +0100
+++ b/app/main/draft/_action/add.lua Fri Dec 25 12:00:00 2009 +0100
@@ -1,5 +1,22 @@
+local tmp = db:query({ "SELECT text_entries_left FROM member_contingent_left WHERE member_id = ?", app.session.member.id }, "opt_object")
+if tmp and tmp.text_entries_left and tmp.text_entries_left < 1 then
+ slot.put_into("error", _"Sorry, you have reached your personal flood limit. Please be slower...")
+ return false
+end
+
local initiative = Initiative:by_id(param.get("initiative_id", atom.integer))
+-- TODO important m1 selectors returning result _SET_!
+local issue = initiative:get_reference_selector("issue"):for_share():single_object_mode():exec()
+
+if issue.closed then
+ slot.put_into("error", _"This issue is already closed.")
+ return false
+elseif issue.half_frozen then
+ slot.put_into("error", _"This issue is already frozen.")
+ return false
+end
+
if Initiator:by_pk(initiative.id, app.session.member.id) then
local draft = Draft:new()
draft.author_id = app.session.member.id
diff -r 80c215dbf076 -r afd9f769c7ae app/main/index/_action/register.lua
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/app/main/index/_action/register.lua Fri Dec 25 12:00:00 2009 +0100
@@ -0,0 +1,132 @@
+local invite_code = InviteCode:by_code(param.get("code"))
+
+if not invite_code or invite_code.used then
+ slot.put_into("error", _"The code you've entered is invalid")
+ request.redirect{
+ mode = "forward",
+ module = "index",
+ view = "register"
+ }
+ return false
+end
+
+local name = param.get("name")
+
+if invite_code and not name then
+ slot.put_into("notice", _"Invite code valid!")
+ request.redirect{
+ mode = "redirect",
+ module = "index",
+ view = "register",
+ params = { code = invite_code.code }
+ }
+ return false
+end
+
+if Member:by_name(name) then
+ slot.put_into("error", _"This name is already taken, please choose another one!")
+ request.redirect{
+ mode = "redirect",
+ module = "index",
+ view = "register",
+ params = { code = invite_code.code }
+ }
+ return false
+end
+
+local login = param.get("login")
+
+if name and not login then
+ slot.put_into("notice", _"Name is available")
+ request.redirect{
+ mode = "redirect",
+ module = "index",
+ view = "register",
+ params = {
+ code = invite_code.code,
+ name = name
+ }
+ }
+ return false
+end
+
+if Member:by_login(login) then
+ slot.put_into("error", _"This login is already taken, please choose another one!")
+ request.redirect{
+ mode = "redirect",
+ module = "index",
+ view = "register",
+ params = {
+ code = invite_code.code,
+ name = name
+ }
+ }
+ return false
+end
+
+local password1 = param.get("password1")
+local password2 = param.get("password2")
+
+if login and not password1 then
+ slot.put_into("notice", _"Login is available")
+ request.redirect{
+ mode = "redirect",
+ module = "index",
+ view = "register",
+ params = {
+ code = invite_code.code,
+ name = name,
+ login = login
+ }
+ }
+ return false
+end
+
+if password1 ~= password2 then
+ slot.put_into("error", _"Passwords don't match!")
+ request.redirect{
+ mode = "redirect",
+ module = "index",
+ view = "register",
+ params = {
+ code = invite_code.code,
+ name = name,
+ login = login
+ }
+ }
+ return false
+end
+
+if #password1 < 8 then
+ slot.put_into("error", _"Passwords must consist of at least 8 characters!")
+ request.redirect{
+ mode = "redirect",
+ module = "index",
+ view = "register",
+ params = {
+ code = invite_code.code,
+ name = name,
+ login = login
+ }
+ }
+ return false
+end
+
+local member = Member:new()
+
+member.login = login
+member.name = name
+member:set_password(password1)
+member:save()
+
+invite_code.member_id = member.id
+invite_code.used = "now"
+invite_code:save()
+
+slot.put_into("notice", _"You've successfully registered and you can login now with your login and password!")
+
+ request.redirect{
+ mode = "redirect",
+ module = "index",
+ view = "login",
+ }
diff -r 80c215dbf076 -r afd9f769c7ae app/main/index/index.lua
--- a/app/main/index/index.lua Thu Dec 10 12:00:00 2009 +0100
+++ b/app/main/index/index.lua Fri Dec 25 12:00:00 2009 +0100
@@ -96,6 +96,90 @@
util.help("index.index", _"Home")
+
+local selector = Area:new_selector()
+ :reset_fields()
+ :add_field("area.id", nil, { "grouped" })
+ :add_field("area.name", nil, { "grouped" })
+ :add_field("membership.member_id NOTNULL", "is_member", { "grouped" })
+ :add_field("count(issue.id)", "issues_to_vote_count")
+ :add_field("count(interest.member_id)", "interested_issues_to_vote_count")
+ :join("issue", nil, "issue.area_id = area.id AND issue.fully_frozen NOTNULL AND issue.closed ISNULL")
+ :left_join("direct_voter", nil, { "direct_voter.issue_id = issue.id AND direct_voter.member_id = ?", app.session.member.id })
+ :add_where{ "direct_voter.member_id ISNULL" }
+ :left_join("interest", nil, { "interest.issue_id = issue.id AND interest.member_id = ?", app.session.member.id })
+ :left_join("membership", nil, { "membership.area_id = area.id AND membership.member_id = ? ", app.session.member.id })
+
+local areas = {}
+for i, area in ipairs(selector:exec()) do
+ if area.is_member or area.interested_issues_to_vote_count > 0 then
+ areas[#areas+1] = area
+ end
+end
+
+if #areas > 0 then
+ ui.container{
+ attr = { style = "font-weight: bold;" },
+ content = _"Current votings in areas you are member of and issues you are interested in:"
+ }
+
+ ui.list{
+ records = areas,
+ columns = {
+ {
+ name = "name"
+ },
+ {
+ content = function(record)
+ if record.is_member and record.issues_to_vote_count > 0 then
+ ui.link{
+ content = function()
+ if record.issues_to_vote_count > 1 then
+ slot.put(_("#{issues_to_vote_count} issue(s)", { issues_to_vote_count = record.issues_to_vote_count }))
+ else
+ slot.put(_("One issue"))
+ end
+ end,
+ module = "area",
+ view = "show",
+ id = record.id,
+ params = {
+ filter = "frozen",
+ filter_voting = "not_voted"
+ }
+ }
+ else
+ slot.put(_"Not a member")
+ end
+ end
+ },
+ {
+ content = function(record)
+ if record.interested_issues_to_vote_count > 0 then
+ ui.link{
+ content = function()
+ if record.interested_issues_to_vote_count > 1 then
+ slot.put(_("#{interested_issues_to_vote_count} issue(s) you are interested in", { interested_issues_to_vote_count = record.interested_issues_to_vote_count }))
+ else
+ slot.put(_"One issue you are interested in")
+ end
+ end,
+ module = "area",
+ view = "show",
+ id = record.id,
+ params = {
+ filter = "frozen",
+ filter_interest = "my",
+ filter_voting = "not_voted"
+ }
+ }
+ end
+ end
+ },
+ }
+ }
+end
+
execute.view{
module = "member",
view = "_show",
diff -r 80c215dbf076 -r afd9f769c7ae app/main/index/login.lua
--- a/app/main/index/login.lua Thu Dec 10 12:00:00 2009 +0100
+++ b/app/main/index/login.lua Fri Dec 25 12:00:00 2009 +0100
@@ -1,3 +1,15 @@
+local warning_text = _"Some JavaScript based functions (voting in particular) will not work.\nFor this beta, please use a current version of Firefox, Safari, Opera(?), Konqueror or another (more) standard compliant browser.\nAlternative access without JavaScript will be available soon."
+
+ui.script{ static = "js/browser_warning.js" }
+ui.script{ script = "checkBrowser(" .. encode.json(_"Your web browser is not fully supported yet." .. " " .. warning_text:gsub("\n", "\n\n")) .. ");" }
+
+ui.tag{
+ tag = "noscript",
+ content = function()
+ slot.put(_"JavaScript is disabled or not available." .. " " .. encode.html_newlines(warning_text))
+ end
+}
+
slot.put_into("title", encode.html(config.app_title))
ui.tag{
@@ -24,7 +36,7 @@
content = function()
ui.field.text{
attr = { id = "username_field" },
- label = _'Username',
+ label = _'login name',
html_name = 'login',
value = ''
}
diff -r 80c215dbf076 -r afd9f769c7ae app/main/index/register.lua
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/app/main/index/register.lua Fri Dec 25 12:00:00 2009 +0100
@@ -0,0 +1,96 @@
+slot.put_into("title", _"Registration")
+
+slot.select("actions", function()
+ ui.link{
+ content = function()
+ ui.image{ static = "icons/16/cancel.png" }
+ slot.put(_"Cancel")
+ end,
+ module = "index",
+ view = "index"
+ }
+end)
+
+local code = param.get("code")
+local name = param.get("name")
+local login = param.get("login")
+
+ui.form{
+ attr = { class = "login" },
+ module = 'index',
+ action = 'register',
+ params = {
+ code = code,
+ name = name,
+ login = login
+ },
+ content = function()
+
+ if not code then
+ ui.tag{
+ tag = "p",
+ content = _"Please enter the invite code you've received."
+ }
+ ui.field.text{
+ label = _'Invite code',
+ name = 'code',
+ }
+
+ elseif not name then
+ ui.tag{
+ tag = "p",
+ content = _"Please choose a name, i.e. your real name or your nick name. This name will be shown to others to identify you. You CAN'T change this name later, so please choose it wisely!"
+ }
+ ui.field.text{
+ label = _'Name',
+ name = 'name',
+ value = param.get("name")
+ }
+
+ elseif not login then
+ ui.tag{
+ tag = "p",
+ content = _"Please choose a login name. This name will not be shown to others and is used only by you to login into the system. The login name is case sensitive."
+ }
+ ui.field.text{
+ label = _'Login name',
+ name = 'login',
+ value = param.get("login")
+ }
+
+ else
+ ui.field.text{
+ label = _'Name',
+ name = 'name',
+ value = param.get("name"),
+ readonly = true
+ }
+ ui.field.text{
+ label = _'Login name',
+ name = 'login',
+ value = param.get("login"),
+ readonly = true
+ }
+ ui.tag{
+ tag = "p",
+ content = _"Please choose a password and enter it twice. The password is case sensitive."
+ }
+ ui.field.password{
+ label = _'Password',
+ name = 'password1',
+ }
+ ui.field.password{
+ label = _'Password (repeat)',
+ name = 'password2',
+ }
+
+ end
+
+ ui.submit{
+ text = _'Register'
+ }
+
+ end
+}
+
+
diff -r 80c215dbf076 -r afd9f769c7ae app/main/initiative/_action/add_support.lua
--- a/app/main/initiative/_action/add_support.lua Thu Dec 10 12:00:00 2009 +0100
+++ b/app/main/initiative/_action/add_support.lua Fri Dec 25 12:00:00 2009 +0100
@@ -1,5 +1,16 @@
local initiative = Initiative:new_selector():add_where{ "id = ?", param.get_id()}:single_object_mode():exec()
+-- TODO important m1 selectors returning result _SET_!
+local issue = initiative:get_reference_selector("issue"):for_share():single_object_mode():exec()
+
+if issue.closed then
+ slot.put_into("error", _"This issue is already closed.")
+ return false
+elseif issue.fully_frozen then
+ slot.put_into("error", _"Voting for this issue has already begun.")
+ return false
+end
+
local member = app.session.member
local supporter = Supporter:by_pk(initiative.id, member.id)
diff -r 80c215dbf076 -r afd9f769c7ae app/main/initiative/_action/create.lua
--- a/app/main/initiative/_action/create.lua Thu Dec 10 12:00:00 2009 +0100
+++ b/app/main/initiative/_action/create.lua Fri Dec 25 12:00:00 2009 +0100
@@ -1,13 +1,29 @@
+local tmp = db:query({ "SELECT text_entries_left, initiatives_left FROM member_contingent_left WHERE member_id = ?", app.session.member.id }, "opt_object")
+if tmp then
+ if tmp.initiatives_left and tmp.initiatives_left < 1 then
+ slot.put_into("error", _"Sorry, your contingent for creating initiatives has been used up. Please try again later.")
+ return false
+ end
+ if tmp.text_entries_left and tmp.text_entries_left < 1 then
+ slot.put_into("error", _"Sorry, you have reached your personal flood limit. Please be slower...")
+ return false
+ end
+end
+
local issue
local area
-db:query("BEGIN")
-
local issue_id = param.get("issue_id", atom.integer)
if issue_id then
issue = Issue:new_selector():add_where{"id=?",issue_id}:single_object_mode():exec()
+ if issue.closed then
+ slot.put_into("error", _"This issue is already closed.")
+ return false
+ elseif issue.fully_frozen then
+ slot.put_into("error", _"Voting for this issue has already begun.")
+ return false
+ end
area = issue.area
-
else
local area_id = param.get("area_id", atom.integer)
area = Area:new_selector():add_where{"id=?",area_id}:single_object_mode():exec()
@@ -22,6 +38,8 @@
issue:save()
end
+
+
initiative.issue_id = issue.id
param.update(initiative, "name", "discussion_url")
@@ -55,8 +73,6 @@
supporter.draft_id = draft.id
supporter:save()
-db:query("COMMIT")
-
slot.put_into("notice", _"Initiative successfully created")
request.redirect{
diff -r 80c215dbf076 -r afd9f769c7ae app/main/initiative/_action/remove_support.lua
--- a/app/main/initiative/_action/remove_support.lua Thu Dec 10 12:00:00 2009 +0100
+++ b/app/main/initiative/_action/remove_support.lua Fri Dec 25 12:00:00 2009 +0100
@@ -1,5 +1,16 @@
local initiative = Initiative:new_selector():add_where{ "id = ?", param.get_id()}:single_object_mode():exec()
+-- TODO important m1 selectors returning result _SET_!
+local issue = initiative:get_reference_selector("issue"):for_share():single_object_mode():exec()
+
+if issue.closed then
+ slot.put_into("error", _"This issue is already closed.")
+ return false
+elseif issue.fully_frozen then
+ slot.put_into("error", _"Voting for this issue has already begun.")
+ return false
+end
+
local member = app.session.member
local supporter = Supporter:by_pk(initiative.id, member.id)
diff -r 80c215dbf076 -r afd9f769c7ae app/main/initiative/_list.lua
--- a/app/main/initiative/_list.lua Thu Dec 10 12:00:00 2009 +0100
+++ b/app/main/initiative/_list.lua Fri Dec 25 12:00:00 2009 +0100
@@ -9,32 +9,32 @@
order_options[#order_options+1] = {
name = "rank",
label = _"Rank",
- order_by = "initiative.rank"
+ order_by = "initiative.rank, initiative.admitted DESC, vote_ratio(initiative.positive_votes, initiative.negative_votes) DESC, initiative.id"
}
end
order_options[#order_options+1] = {
+ name = "potential_support",
+ label = _"Potential support",
+ order_by = "initiative.supporter_count::float / issue.population::float DESC, initiative.id"
+}
+
+order_options[#order_options+1] = {
name = "support",
label = _"Support",
- order_by = "initiative.supporter_count::float / issue.population::float DESC"
-}
-
-order_options[#order_options+1] = {
- name = "support_si",
- label = _"Support S+I",
- order_by = "initiative.satisfied_informed_supporter_count::float / issue.population::float DESC"
+ order_by = "initiative.satisfied_supporter_count::float / issue.population::float DESC, initiative.id"
}
order_options[#order_options+1] = {
name = "newest",
label = _"Newest",
- order_by = "initiative.created DESC"
+ order_by = "initiative.created DESC, initiative.id"
}
order_options[#order_options+1] = {
name = "oldest",
label = _"Oldest",
- order_by = "initiative.created"
+ order_by = "initiative.created, initiative.id"
}
local name = "initiative_list"
@@ -61,18 +61,22 @@
}
columns[#columns+1] = {
content = function(record)
- if record.issue.accepted and record.issue.closed and record.issue.ranks_available then
- if record.negative_votes and record.positive_votes then
- local max_value = record.issue.voter_count
- ui.bargraph{
- max_value = max_value,
- width = 100,
- bars = {
- { color = "#0a0", value = record.positive_votes },
- { color = "#aaa", value = max_value - record.negative_votes - record.positive_votes },
- { color = "#a00", value = record.negative_votes },
+ if record.issue.accepted and record.issue.closed then
+ if record.issue.ranks_available then
+ if record.negative_votes and record.positive_votes then
+ local max_value = record.issue.voter_count
+ ui.bargraph{
+ max_value = max_value,
+ width = 100,
+ bars = {
+ { color = "#0a0", value = record.positive_votes },
+ { color = "#aaa", value = max_value - record.negative_votes - record.positive_votes },
+ { color = "#a00", value = record.negative_votes },
+ }
}
- }
+ end
+ else
+ slot.put(_"Counting of votes")
end
else
local max_value = (record.issue.population or 0)
@@ -81,7 +85,7 @@
width = 100,
bars = {
{ color = "#0a0", value = (record.satisfied_supporter_count or 0) },
- { color = "#8f8", value = (record.supporter_count or 0) - (record.satisfied_supporter_count or 0) },
+ { color = "#777", value = (record.supporter_count or 0) - (record.satisfied_supporter_count or 0) },
{ color = "#ddd", value = max_value - (record.supporter_count or 0) },
}
}
diff -r 80c215dbf076 -r afd9f769c7ae app/main/initiative/new.lua
--- a/app/main/initiative/new.lua Thu Dec 10 12:00:00 2009 +0100
+++ b/app/main/initiative/new.lua Fri Dec 25 12:00:00 2009 +0100
@@ -33,7 +33,7 @@
ui.field.select{
label = _"Policy",
name = "policy_id",
- foreign_records = Policy:new_selector():exec(),
+ foreign_records = Policy:new_selector():add_order_by("index"):exec(),
foreign_id = "id",
foreign_name = "name"
}
diff -r 80c215dbf076 -r afd9f769c7ae app/main/initiative/show.lua
--- a/app/main/initiative/show.lua Thu Dec 10 12:00:00 2009 +0100
+++ b/app/main/initiative/show.lua Fri Dec 25 12:00:00 2009 +0100
@@ -1,6 +1,16 @@
local initiative = Initiative:new_selector():add_where{ "id = ?", param.get_id()}:single_object_mode():exec()
-
+slot.select("actions", function()
+ ui.link{
+ content = function()
+ ui.image{ static = "icons/16/script.png" }
+ slot.put(_"Show all initiatives")
+ end,
+ module = "issue",
+ view = "show",
+ id = initiative.issue.id
+ }
+end)
execute.view{
module = "issue",
@@ -18,55 +28,11 @@
params = { initiative = initiative }
}
---[[
-
-execute.view{
- module = "delegation",
- view = "_show_box",
- params = { issue_id = initiative.issue_id }
-}
-
-execute.view{
- module = "issue",
- view = "_show_box",
- params = { issue = initiative.issue }
-}
-
-
-slot.select("path", function()
- ui.link{
- content = _"Area '#{name}'":gsub("#{name}", initiative.issue.area.name),
- module = "area",
- view = "show",
- id = initiative.issue.area.id
- }
- ui.container{ content = "::" }
- ui.link{
- content = _"Issue ##{id}":gsub("#{id}", initiative.issue.id),
- module = "issue",
- view = "show",
- id = initiative.issue.id
- }
-end)
-
-slot.put_into("title", encode.html(_"Initiative: '#{name}'":gsub("#{name}", initiative.shortened_name) ))
---]]
-
slot.put_into("sub_title", encode.html(_"Initiative: '#{name}'":gsub("#{name}", initiative.shortened_name) ))
slot.select("actions", function()
-
if not initiative.issue.fully_frozen and not initiative.issue.closed then
ui.link{
- content = function()
- ui.image{ static = "icons/16/script.png" }
- slot.put(_"Show other initiatives")
- end,
- module = "issue",
- view = "show",
- id = initiative.issue.id
- }
- ui.link{
attr = { class = "action" },
content = function()
ui.image{ static = "icons/16/script_add.png" }
@@ -77,8 +43,6 @@
params = { issue_id = initiative.issue.id }
}
end
--- ui.twitter("http://example.com/i" .. tostring(initiative.id) .. " " .. initiative.name)
-
end)
@@ -99,7 +63,7 @@
ui.link{
attr = {
class = "actions",
- target = _"blank",
+ target = "_blank",
title = initiative.discussion_url
},
content = function()
@@ -256,7 +220,7 @@
}
}
slot.put(" ")
- if not initiative.issue.frozen and not initiative.issue.closed then
+ if not initiative.issue.fully_frozen and not initiative.issue.closed then
ui.link{
content = function()
ui.image{ static = "icons/16/comment_add.png" }
@@ -269,7 +233,7 @@
end
},
{
- name = "supporter",
+ name = "satisfied_supporter",
label = _"Supporter",
content = function()
execute.view{
@@ -282,6 +246,26 @@
:join("direct_interest_snapshot", nil, "direct_interest_snapshot.event = issue.latest_snapshot_event AND direct_interest_snapshot.issue_id = issue.id AND direct_interest_snapshot.member_id = member.id")
:add_field("direct_interest_snapshot.weight")
:add_where("direct_supporter_snapshot.event = issue.latest_snapshot_event")
+ :add_where("direct_supporter_snapshot.satisfied")
+ }
+ }
+ end
+ },
+ {
+ name = "supporter",
+ label = _"Potential supporter",
+ content = function()
+ execute.view{
+ module = "member",
+ view = "_list",
+ params = {
+ initiative = initiative,
+ members_selector = initiative:get_reference_selector("supporting_members_snapshot")
+ :join("issue", nil, "issue.id = direct_supporter_snapshot.issue_id")
+ :join("direct_interest_snapshot", nil, "direct_interest_snapshot.event = issue.latest_snapshot_event AND direct_interest_snapshot.issue_id = issue.id AND direct_interest_snapshot.member_id = member.id")
+ :add_field("direct_interest_snapshot.weight")
+ :add_where("direct_supporter_snapshot.event = issue.latest_snapshot_event")
+ :add_where("NOT direct_supporter_snapshot.satisfied")
}
}
end
diff -r 80c215dbf076 -r afd9f769c7ae app/main/interest/_action/update.lua
--- a/app/main/interest/_action/update.lua Thu Dec 10 12:00:00 2009 +0100
+++ b/app/main/interest/_action/update.lua Fri Dec 25 12:00:00 2009 +0100
@@ -1,6 +1,18 @@
local issue_id = assert(param.get("issue_id", atom.integer), "no issue id given")
+
local interest = Interest:by_pk(issue_id, app.session.member.id)
+-- TODO important m1 selectors returning result _SET_!
+local issue = interest:get_reference_selector("issue"):for_share():single_object_mode():exec()
+
+if issue.closed then
+ slot.put_into("error", _"This issue is already closed.")
+ return false
+elseif issue.fully_frozen then
+ slot.put_into("error", _"Voting for this issue has already begun.")
+ return false
+end
+
if param.get("delete", atom.boolean) then
if interest then
interest:destroy()
diff -r 80c215dbf076 -r afd9f769c7ae app/main/interest/_show_box.lua
--- a/app/main/interest/_show_box.lua Thu Dec 10 12:00:00 2009 +0100
+++ b/app/main/interest/_show_box.lua Fri Dec 25 12:00:00 2009 +0100
@@ -15,6 +15,9 @@
onclick = "document.getElementById('interest_content').style.display = 'block';"
},
content = function()
+ ui.image{
+ static = "icons/16/eye.png"
+ }
slot.put(_"Your are interested")
ui.image{
static = "icons/16/dropdown.png"
@@ -35,33 +38,39 @@
ui.image{ static = "icons/16/cross.png" }
end
}
- ui.link{
- content = _"Remove my interest",
- module = "interest",
- action = "update",
- params = { issue_id = issue.id, delete = true },
- routing = { default = { mode = "redirect", module = "issue", view = "show", id = issue.id } }
- }
- slot.put(" ")
- slot.put(" ")
+ if issue.state ~= "finished" and issue.state ~= "cancelled" and issue.state ~= "voting" then
+ ui.link{
+ content = _"Remove my interest",
+ module = "interest",
+ action = "update",
+ params = { issue_id = issue.id, delete = true },
+ routing = { default = { mode = "redirect", module = "issue", view = "show", id = issue.id } }
+ }
+ slot.put(" ")
+ slot.put(" ")
+ end
if interest.autoreject then
ui.field.text{ value = _"Autoreject is on." }
- ui.link{
- content = _"Remove autoreject",
- module = "interest",
- action = "update",
- params = { issue_id = issue.id, autoreject = false },
- routing = { default = { mode = "redirect", module = "issue", view = "show", id = issue.id } }
- }
+ if issue.state ~= "finished" and issue.state ~= "cancelled" then
+ ui.link{
+ content = _"Remove autoreject",
+ module = "interest",
+ action = "update",
+ params = { issue_id = issue.id, autoreject = false },
+ routing = { default = { mode = "redirect", module = "issue", view = "show", id = issue.id } }
+ }
+ end
else
ui.field.text{ value = _"Autoreject is off." }
- ui.link{
- content = _"Set autoreject",
- module = "interest",
- action = "update",
- params = { issue_id = issue.id, autoreject = true },
- routing = { default = { mode = "redirect", module = "issue", view = "show", id = issue.id } }
- }
+ if issue.state ~= "finished" and issue.state ~= "cancelled" then
+ ui.link{
+ content = _"Set autoreject",
+ module = "interest",
+ action = "update",
+ params = { issue_id = issue.id, autoreject = true },
+ routing = { default = { mode = "redirect", module = "issue", view = "show", id = issue.id } }
+ }
+ end
end
end
}
diff -r 80c215dbf076 -r afd9f769c7ae app/main/issue/_list.lua
--- a/app/main/issue/_list.lua Thu Dec 10 12:00:00 2009 +0100
+++ b/app/main/issue/_list.lua Fri Dec 25 12:00:00 2009 +0100
@@ -1,7 +1,12 @@
local issues_selector = param.get("issues_selector", "table")
+local ui_filter = ui.filter
+if param.get("filter", atom.boolean) == false then
+ ui_filter = function(args) args.content() end
+end
-ui.filter{
+local filter_voting = false
+ui_filter{
selector = issues_selector,
filters = {
{
@@ -36,7 +41,7 @@
label = _"Frozen",
selector_modifier = function(selector, value)
if value then
- selector:add_where("issue.half_frozen NOTNULL AND issue.closed ISNULL")
+ selector:add_where("issue.half_frozen NOTNULL AND issue.fully_frozen ISNULL")
end
end
},
@@ -47,6 +52,7 @@
selector_modifier = function(selector, value)
if value then
selector:add_where("issue.fully_frozen NOTNULL AND issue.closed ISNULL")
+ filter_voting = true
end
end
},
@@ -56,7 +62,7 @@
label = _"Finished",
selector_modifier = function(selector, value)
if value then
- selector:add_where("issue.closed NOTNULL AND ranks_available")
+ selector:add_where("issue.closed NOTNULL AND issue.fully_frozen NOTNULL")
end
end
},
@@ -66,98 +72,203 @@
label = _"Cancelled",
selector_modifier = function(selector, value)
if value then
- selector:add_where("issue.closed NOTNULL AND NOT ranks_available")
+ selector:add_where("issue.closed NOTNULL AND issue.accepted ISNULL")
end
end
},
},
content = function()
- ui.order{
- name = "issue_list",
+ local ui_filter = ui.filter
+ if not filter_voting then
+ ui_filter = function(args) args.content() end
+ end
+ ui_filter{
selector = issues_selector,
- options = {
+ name = "filter_voting",
+ filters = {
{
- name = "population",
- label = _"Population",
- order_by = "issue.population DESC"
+ type = "boolean",
+ name = "any",
+ label = _"Any",
+ selector_modifier = function() end
},
{
- name = "newest",
- label = _"Newest",
- order_by = "issue.created DESC"
+ type = "boolean",
+ name = "not_voted",
+ label = _"Not voted",
+ selector_modifier = function(selector, value)
+ if value then
+ selector:left_join("direct_voter", nil, { "direct_voter.issue_id = issue.id AND direct_voter.member_id = ?", app.session.member.id })
+ selector:add_where("direct_voter.member_id ISNULL")
+ end
+ end
},
{
- name = "oldest",
- label = _"Oldest",
- order_by = "issue.created"
- }
+ type = "boolean",
+ name = "voted",
+ label = _"Voted",
+ selector_modifier = function(selector, value)
+ if value then
+ selector:join("direct_voter", nil, { "direct_voter.issue_id = issue.id AND direct_voter.member_id = ?", app.session.member.id })
+ end
+ end
+ },
},
content = function()
- ui.paginate{
+ local ui_filter = ui.filter
+ if param.get("filter", atom.boolean) == false then
+ ui_filter = function(args) args.content() end
+ end
+ ui_filter{
selector = issues_selector,
+ name = "filter_interest",
+ filters = {
+ {
+ type = "boolean",
+ name = "any",
+ label = _"Any",
+ selector_modifier = function() end
+ },
+ {
+ type = "boolean",
+ name = "my",
+ label = _"Interested",
+ selector_modifier = function(selector, value)
+ if value then
+ selector:join("interest", "filter_interest", { "filter_interest.issue_id = issue.id AND filter_interest.member_id = ? ", app.session.member.id })
+ end
+ end
+ },
+ },
content = function()
- local highlight_string = param.get("highlight_string", "string")
- local issues = issues or issues_selector:exec()
--- issues:load(initiatives)
- ui.list{
- attr = { class = "issues" },
- records = issues,
- columns = {
+
+ ui.order{
+ name = "issue_list",
+ selector = issues_selector,
+ options = {
{
- label = _"Issue",
- content = function(record)
- if not param.get("for_area_list", atom.boolean) then
- ui.field.text{
- value = record.area.name
- }
- slot.put(" ")
- end
- ui.link{
- text = _"Issue ##{id}":gsub("#{id}", tostring(record.id)),
- module = "issue",
- view = "show",
- id = record.id
- }
- if record.state == "new" then
- ui.image{
- static = "icons/16/new.png"
- }
- end
- slot.put(" ")
- slot.put(" ")
+ name = "max_potential_support",
+ label = _"Max potential support",
+ selector_modifier = function(selector)
+ selector:add_order_by("(SELECT max(supporter_count) FROM initiative WHERE initiative.issue_id = issue.id)")
end
},
{
- label = _"State",
- content = function(record)
- ui.field.issue_state{ value = record.state }
+ name = "max_support",
+ label = _"Max support",
+ selector_modifier = function(selector)
+ selector:add_order_by("(SELECT max(satisfied_supporter_count) FROM initiative WHERE initiative.issue_id = issue.id)")
end
},
{
- label = _"Initiatives",
- content = function(record)
- local initiatives_selector = record:get_reference_selector("initiatives")
- local highlight_string = param.get("highlight_string")
- if highlight_string then
- initiatives_selector:add_field( {'"highlight"("initiative"."name", ?)', highlight_string }, "name_highlighted")
- end
- execute.view{
- module = "initiative",
- view = "_list",
- params = {
- issue = record,
- initiatives_selector = initiatives_selector,
- highlight_string = highlight_string,
- limit = 3
+ name = "population",
+ label = _"Population",
+ order_by = "issue.population DESC"
+ },
+ {
+ name = "newest",
+ label = _"Newest",
+ order_by = "issue.created DESC"
+ },
+ {
+ name = "oldest",
+ label = _"Oldest",
+ order_by = "issue.created"
+ }
+ },
+ content = function()
+ ui.paginate{
+ selector = issues_selector,
+ content = function()
+ local highlight_string = param.get("highlight_string", "string")
+ local issues = issues or issues_selector:exec()
+ -- issues:load(initiatives)
+ ui.list{
+ attr = { class = "issues" },
+ records = issues,
+ columns = {
+ {
+ label = _"Issue",
+ content = function(record)
+ if not param.get("for_area_list", atom.boolean) then
+ ui.field.text{
+ value = record.area.name
+ }
+ slot.put(" ")
+ end
+ ui.link{
+ text = _"Issue ##{id}":gsub("#{id}", tostring(record.id)),
+ module = "issue",
+ view = "show",
+ id = record.id
+ }
+ if record.state == "new" then
+ ui.image{
+ static = "icons/16/new.png"
+ }
+ end
+ slot.put(" ")
+ slot.put(" ")
+ end
+ },
+ {
+ label = _"State",
+ content = function(record)
+ ui.field.issue_state{ value = record.state }
+ end
+ },
+ {
+ label = _"Initiatives",
+ content = function(record)
+ local initiatives_selector = record:get_reference_selector("initiatives")
+ local highlight_string = param.get("highlight_string")
+ if highlight_string then
+ initiatives_selector:add_field( {'"highlight"("initiative"."name", ?)', highlight_string }, "name_highlighted")
+ end
+ execute.view{
+ module = "initiative",
+ view = "_list",
+ params = {
+ issue = record,
+ initiatives_selector = initiatives_selector,
+ highlight_string = highlight_string,
+ limit = 3
+ }
+ }
+ end
+ },
}
}
end
- },
- }
+ }
+ end
}
end
}
end
}
+ if param.get("legend", atom.boolean) ~= false then
+ local filter = param.get_all_cgi().filter
+ if not filter or filter == "any" or filter ~= "finished" then
+ ui.bargraph_legend{
+ width = 25,
+ bars = {
+ { color = "#0a0", label = _"Supporter" },
+ { color = "#777", label = _"Potential supporter" },
+ { color = "#ddd", label = _"No support at all" },
+ }
+ }
+ end
+ if not filter or filter == "any" or filter == "finished" then
+ ui.bargraph_legend{
+ width = 25,
+ bars = {
+ { color = "#0a0", label = _"Yes" },
+ { color = "#aaa", label = _"Abstention" },
+ { color = "#a00", label = _"No" },
+ }
+ }
+ end
+ end
end
}
diff -r 80c215dbf076 -r afd9f769c7ae app/main/issue/_show_head.lua
--- a/app/main/issue/_show_head.lua Thu Dec 10 12:00:00 2009 +0100
+++ b/app/main/issue/_show_head.lua Fri Dec 25 12:00:00 2009 +0100
@@ -11,21 +11,35 @@
}
end)
-slot.put_into("title", encode.html(_"Issue ##{id} (#{policy_name})":gsub("#{id}", issue.id):gsub("#{policy_name}", issue.policy.name)))
+slot.select("title", function()
+ ui.link{
+ content = _"Issue ##{id} (#{policy_name})":gsub("#{id}", issue.id):gsub("#{policy_name}", issue.policy.name),
+ module = "issue",
+ view = "show",
+ id = issue.id
+ }
+end)
+
slot.select("actions", function()
+
+ if issue.state == 'voting' then
+ ui.link{
+ content = function()
+ ui.image{ static = "icons/16/email_open.png" }
+ slot.put(_"Vote now")
+ end,
+ module = "vote",
+ view = "list",
+ params = { issue_id = issue.id }
+ }
+ end
+
execute.view{
module = "interest",
view = "_show_box",
params = { issue = issue }
}
-
- execute.view{
- module = "delegation",
- view = "_show_box",
- params = { issue_id = issue.id }
- }
-
-- TODO performance
local interest = Interest:by_pk(issue.id, app.session.member.id)
if not issue.closed and not issue.fully_frozen then
@@ -43,6 +57,23 @@
end
end
+ if not issue.closed then
+ execute.view{
+ module = "delegation",
+ view = "_show_box",
+ params = { issue_id = issue.id }
+ }
+ end
+
+ if issue.state == "accepted" then
+ -- TODO
+ ui.link{
+ content = function()
+ ui.image{ static = "icons/16/time.png" }
+ slot.put(_"Vote now/later")
+ end,
+ }
+ end
end)
diff -r 80c215dbf076 -r afd9f769c7ae app/main/issue/show.lua
--- a/app/main/issue/show.lua Thu Dec 10 12:00:00 2009 +0100
+++ b/app/main/issue/show.lua Fri Dec 25 12:00:00 2009 +0100
@@ -12,7 +12,8 @@
{
name = "initiatives",
label = _"Initiatives",
- content = function() execute.view{
+ content = function()
+ execute.view{
module = "initiative",
view = "_list",
params = {
diff -r 80c215dbf076 -r afd9f769c7ae app/main/member/_action/update.lua
--- a/app/main/member/_action/update.lua Thu Dec 10 12:00:00 2009 +0100
+++ b/app/main/member/_action/update.lua Fri Dec 25 12:00:00 2009 +0100
@@ -1,5 +1,4 @@
param.update(app.session.member,
- "name",
"organizational_unit",
"internal_posts",
"realname",
diff -r 80c215dbf076 -r afd9f769c7ae app/main/member/edit.lua
--- a/app/main/member/edit.lua Thu Dec 10 12:00:00 2009 +0100
+++ b/app/main/member/edit.lua Fri Dec 25 12:00:00 2009 +0100
@@ -26,7 +26,6 @@
}
},
content = function()
- ui.field.text{ label = _"Name", name = "name" }
ui.field.text{ label = _"Organizational unit", name = "organizational_unit" }
ui.field.text{ label = _"Internal posts", name = "internal_posts" }
ui.field.text{ label = _"Real name", name = "realname" }
diff -r 80c215dbf076 -r afd9f769c7ae app/main/opinion/_action/update.lua
--- a/app/main/opinion/_action/update.lua Thu Dec 10 12:00:00 2009 +0100
+++ b/app/main/opinion/_action/update.lua Fri Dec 25 12:00:00 2009 +0100
@@ -4,6 +4,19 @@
local opinion = Opinion:by_pk(member_id, suggestion_id)
+-- TODO important m1 selectors returning result _SET_!
+local issue = opinion.initiative:get_reference_selector("issue"):for_share():single_object_mode():exec()
+
+if issue.closed then
+ slot.put_into("error", _"This issue is already closed.")
+ return false
+elseif issue.fully_frozen then
+ slot.put_into("error", _"Voting for this issue has already begun.")
+ return false
+end
+
+
+
if param.get("delete") then
if opinion then
opinion:destroy()
diff -r 80c215dbf076 -r afd9f769c7ae app/main/suggestion/_action/add.lua
--- a/app/main/suggestion/_action/add.lua Thu Dec 10 12:00:00 2009 +0100
+++ b/app/main/suggestion/_action/add.lua Fri Dec 25 12:00:00 2009 +0100
@@ -1,4 +1,8 @@
-db:query("BEGIN")
+local tmp = db:query({ "SELECT text_entries_left FROM member_contingent_left WHERE member_id = ?", app.session.member.id }, "opt_object")
+if tmp and tmp.text_entries_left and tmp.text_entries_left < 1 then
+ slot.put_into("error", _"Sorry, you have reached your personal flood limit. Please be slower...")
+ return false
+end
local suggestion = Suggestion:new()
@@ -6,6 +10,17 @@
param.update(suggestion, "name", "description", "initiative_id")
suggestion:save()
+-- TODO important m1 selectors returning result _SET_!
+local issue = suggestion.initiative:get_reference_selector("issue"):for_share():single_object_mode():exec()
+
+if issue.closed then
+ slot.put_into("error", _"This issue is already closed.")
+ return false
+elseif issue.fully_frozen then
+ slot.put_into("error", _"Voting for this issue has already begun.")
+ return false
+end
+
local opinion = Opinion:new()
opinion.suggestion_id = suggestion.id
@@ -15,6 +30,4 @@
opinion:save()
-db:query("COMMIT")
-
slot.put_into("notice", _"Your suggestion has been added")
\ No newline at end of file
diff -r 80c215dbf076 -r afd9f769c7ae app/main/suggestion/_list.lua
--- a/app/main/suggestion/_list.lua Thu Dec 10 12:00:00 2009 +0100
+++ b/app/main/suggestion/_list.lua Fri Dec 25 12:00:00 2009 +0100
@@ -105,60 +105,69 @@
if opinion then
degree = opinion.degree
end
- ui.link{
- attr = { class = "action" .. (degree == -2 and " active_red2" or "") },
- text = _"must not",
- module = "opinion",
- action = "update",
- routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } },
- params = {
- suggestion_id = record.id,
- degree = -2
- }
- }
- ui.link{
- attr = { class = "action" .. (degree == -1 and " active_red1" or "") },
- text = _"should not",
- module = "opinion",
- action = "update",
- routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } },
- params = {
- suggestion_id = record.id,
- degree = -1
- }
- }
- ui.link{
- attr = { class = "action" .. (degree == nil and " active" or "") },
- text = _"neutral",
- module = "opinion",
- action = "update",
- routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } },
- params = {
- suggestion_id = record.id,
- delete = true
- }
- }
- ui.link{
- attr = { class = "action" .. (degree == 1 and " active_green1" or "") },
- text = _"should",
- module = "opinion",
- action = "update",
- routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } },
- params = {
- suggestion_id = record.id,
- degree = 1
- }
- }
- ui.link{
- attr = { class = "action" .. (degree == 2 and " active_green2" or "") },
- text = _"must",
- module = "opinion",
- action = "update",
- routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } },
- params = {
- suggestion_id = record.id,
- degree = 2
- }
+ ui.container{
+ attr = { class = "suggestion_my_opinion" },
+ content = function()
+ ui.link{
+ attr = { class = "action" .. (degree == -2 and " active_red2" or "") },
+ text = _"must not",
+ module = "opinion",
+ action = "update",
+ routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } },
+ params = {
+ suggestion_id = record.id,
+ degree = -2
+ }
+ }
+ slot.put(" ")
+ ui.link{
+ attr = { class = "action" .. (degree == -1 and " active_red1" or "") },
+ text = _"should not",
+ module = "opinion",
+ action = "update",
+ routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } },
+ params = {
+ suggestion_id = record.id,
+ degree = -1
+ }
+ }
+ slot.put(" ")
+ ui.link{
+ attr = { class = "action" .. (degree == nil and " active" or "") },
+ text = _"neutral",
+ module = "opinion",
+ action = "update",
+ routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } },
+ params = {
+ suggestion_id = record.id,
+ delete = true
+ }
+ }
+ slot.put(" ")
+ ui.link{
+ attr = { class = "action" .. (degree == 1 and " active_green1" or "") },
+ text = _"should",
+ module = "opinion",
+ action = "update",
+ routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } },
+ params = {
+ suggestion_id = record.id,
+ degree = 1
+ }
+ }
+ slot.put(" ")
+ ui.link{
+ attr = { class = "action" .. (degree == 2 and " active_green2" or "") },
+ text = _"must",
+ module = "opinion",
+ action = "update",
+ routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } },
+ params = {
+ suggestion_id = record.id,
+ degree = 2
+ }
+ }
+ end
}
end
},
diff -r 80c215dbf076 -r afd9f769c7ae app/main/supporter/_show_box.lua
--- a/app/main/supporter/_show_box.lua Thu Dec 10 12:00:00 2009 +0100
+++ b/app/main/supporter/_show_box.lua Fri Dec 25 12:00:00 2009 +0100
@@ -1,29 +1,48 @@
slot.select("support", function()
local initiative = param.get("initiative", "table")
- local supported = Supporter:by_pk(initiative.id, app.session.member.id) and true or false
+ local supporter = Supporter:by_pk(initiative.id, app.session.member.id)
ui.container{
attr = { class = "actions" },
content = function()
- if not initiative.issue.frozen and not initiative.issue.closed then
- if supported then
- ui.container{
- attr = {
- class = "head head_active",
- style = "cursor: pointer;",
- onclick = "document.getElementById('support_content').style.display = 'block';"
- },
- content = function()
- ui.image{
- static = "icons/16/thumb_up_green.png"
- }
- slot.put(_"Your are supporter")
- ui.image{
- static = "icons/16/dropdown.png"
- }
- end
- }
+ if not initiative.issue.fully_frozen and not initiative.issue.closed then
+ if supporter then
+ if not supporter:has_critical_opinion() then
+ ui.container{
+ attr = {
+ class = "head head_supporter",
+ style = "cursor: pointer;",
+ onclick = "document.getElementById('support_content').style.display = 'block';"
+ },
+ content = function()
+ ui.image{
+ static = "icons/16/thumb_up_green.png"
+ }
+ slot.put(_"Your are supporter")
+ ui.image{
+ static = "icons/16/dropdown.png"
+ }
+ end
+ }
+ else
+ ui.container{
+ attr = {
+ class = "head head_potential_supporter",
+ style = "cursor: pointer;",
+ onclick = "document.getElementById('support_content').style.display = 'block';"
+ },
+ content = function()
+ ui.image{
+ static = "icons/16/thumb_up.png"
+ }
+ slot.put(_"Your are potential supporter")
+ ui.image{
+ static = "icons/16/dropdown.png"
+ }
+ end
+ }
+ end
ui.container{
attr = { class = "content", id = "support_content" },
content = function()
@@ -37,7 +56,7 @@
ui.image{ static = "icons/16/cross.png" }
end
}
- if supported then
+ if supporter then
ui.link{
content = function()
ui.image{ static = "icons/16/thumb_down_red.png" }
diff -r 80c215dbf076 -r afd9f769c7ae app/main/vote/_action/update.lua
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/app/main/vote/_action/update.lua Fri Dec 25 12:00:00 2009 +0100
@@ -0,0 +1,47 @@
+local issue = Issue:new_selector():add_where{ "id = ?", param.get("issue_id", atom.integer) }:for_share():single_object_mode():exec()
+
+if issue.closed then
+ slot.put_into("error", _"This issue is already closed.")
+ return false
+end
+
+if issue.state ~= "voting" then
+ slot.put_into("error", _"Voting has not started yet.")
+ return false
+end
+
+local direct_voter = DirectVoter:by_pk(issue.id, app.session.member_id)
+
+if not direct_voter then
+ direct_voter = DirectVoter:new()
+ direct_voter.issue_id = issue.id
+ direct_voter.member_id = app.session.member_id
+end
+
+direct_voter.autoreject = false
+
+direct_voter:save()
+
+
+local scoring = param.get("scoring")
+
+for initiative_id, grade in scoring:gmatch("([^:;]+):([^:;]+)") do
+ local initiative_id = tonumber(initiative_id)
+ local grade = tonumber(grade)
+ local initiative = Initiative:by_id(initiative_id)
+ if initiative.issue.id ~= issue.id then
+ error("initiative from wrong issue")
+ end
+ local vote = Vote:by_pk(initiative_id, app.session.member.id)
+ if not vote then
+ vote = Vote:new()
+ vote.issue_id = issue.id
+ vote.initiative_id = initiative.id
+ vote.member_id = app.session.member.id
+ end
+ vote.grade = grade
+ vote:save()
+end
+
+trace.debug(scoring)
+
diff -r 80c215dbf076 -r afd9f769c7ae app/main/vote/list.lua
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/app/main/vote/list.lua Fri Dec 25 12:00:00 2009 +0100
@@ -0,0 +1,138 @@
+local warning_text = _"Some JavaScript based functions (voting in particular) will not work.\nFor this beta, please use a current version of Firefox, Safari, Opera(?), Konqueror or another (more) standard compliant browser.\nAlternative access without JavaScript will be available soon."
+
+ui.script{ static = "js/browser_warning.js" }
+ui.script{ script = "checkBrowser(" .. encode.json(_"Your web browser is not fully supported yet." .. " " .. warning_text:gsub("\n", "\n\n")) .. ");" }
+
+ui.tag{
+ tag = "noscript",
+ content = function()
+ slot.put(_"JavaScript is disabled or not available." .. " " .. encode.html_newlines(warning_text))
+ end
+}
+
+
+local issue = Issue:by_id(param.get("issue_id"), atom.integer)
+
+local initiatives = issue.initiatives
+
+local min_grade = -1;
+local max_grade = 1;
+
+for i, initiative in ipairs(initiatives) do
+ -- TODO performance
+ initiative.vote = Vote:by_pk(initiative.id, app.session.member.id)
+ if initiative.vote then
+ if initiative.vote.grade > max_grade then
+ max_grade = initiative.vote.grade
+ end
+ if initiative.vote.grade < min_grade then
+ min_grade = initiative.vote.grade
+ end
+ end
+end
+
+local sections = {}
+for i = min_grade, max_grade do
+ sections[i] = {}
+ for j, initiative in ipairs(initiatives) do
+ if (initiative.vote and initiative.vote.grade == i) or (not initiative.vote and i == 0) then
+ sections[i][#(sections[i])+1] = initiative
+ end
+ end
+end
+
+slot.put_into("title", _"Voting")
+
+slot.select("actions", function()
+ ui.link{
+ content = function()
+ ui.image{ static = "icons/16/cancel.png" }
+ slot.put(_"Cancel")
+ end,
+ module = "issue",
+ view = "show",
+ id = issue.id
+ }
+end)
+
+util.help("vote.list", _"Voting")
+
+
+slot.put('')
+slot.put('')
+
+ui.form{
+ attr = { id = "voting_form" },
+ module = "vote",
+ action = "update",
+ params = { issue_id = issue.id },
+ routing = {
+ default = {
+ mode = "redirect",
+ module = "issue",
+ view = "show",
+ id = issue.id
+ }
+ },
+ content = function()
+ slot.put('')
+ -- TODO abstrahieren
+ ui.tag{
+ tag = "input",
+ attr = {
+ type = "button",
+ class = "voting_done",
+ value = _"Finish voting"
+ }
+ }
+ ui.container{
+ attr = { id = "voting" },
+ content = function()
+ for grade = max_grade, min_grade, -1 do
+ local section = sections[grade]
+ local class
+ if grade > 0 then
+ class = "approval"
+ elseif grade < 0 then
+ class = "disapproval"
+ else
+ class = "abstention"
+ end
+ ui.container{
+ attr = { class = class },
+ content = function()
+ slot.put('')
+ for i, initiative in ipairs(section) do
+ ui.container{
+ attr = {
+ class = "movable",
+ id = "entry_" .. tostring(initiative.id)
+ },
+ content = function()
+ ui.link{
+ attr = { class = "clickable" },
+ content = initiative.name,
+ module = "initiative",
+ view = "show",
+ id = initiative.id
+ }
+ end
+ }
+ end
+ end
+ }
+ end
+ end
+ }
+ ui.tag{
+ tag = "input",
+ attr = {
+ type = "button",
+ class = "voting_done",
+ value = _"Finish voting"
+ }
+ }
+ end
+}
+
+
diff -r 80c215dbf076 -r afd9f769c7ae config/default.lua
--- a/config/default.lua Thu Dec 10 12:00:00 2009 +0100
+++ b/config/default.lua Fri Dec 25 12:00:00 2009 +0100
@@ -1,5 +1,5 @@
config.app_name = "LiquidFeedback"
-config.app_version = "alpha5"
+config.app_version = "beta1"
config.app_title = config.app_name .. " (" .. request.get_config_name() .. " environment)"
diff -r 80c215dbf076 -r afd9f769c7ae env/ui/order.lua
--- a/env/ui/order.lua Thu Dec 10 12:00:00 2009 +0100
+++ b/env/ui/order.lua Fri Dec 25 12:00:00 2009 +0100
@@ -16,7 +16,11 @@
local attr = {}
if current_order == option.name then
attr.class = "active"
- args.selector:add_order_by(option.order_by)
+ if option.selector_modifier then
+ option.selector_modifier(args.selector)
+ else
+ args.selector:add_order_by(option.order_by)
+ end
end
ui.link{
attr = attr,
diff -r 80c215dbf076 -r afd9f769c7ae fastpath/Makefile
--- a/fastpath/Makefile Thu Dec 10 12:00:00 2009 +0100
+++ b/fastpath/Makefile Fri Dec 25 12:00:00 2009 +0100
@@ -1,5 +1,5 @@
getpic: getpic.c
- cc -g -Wall -o getpic getpic.c -I /usr/pkg/include/ -I /usr/include/postgresql -L /usr/pkg/lib -L /usr/lib/postgresql -lpq -Wl,-rpath,/usr/pkg/lib -Wl,-rpath,/usr/lib/postgresql
+ cc -g -Wall -o getpic getpic.c -I `pg_config --includedir` -L `pg_config --libdir` -lpq -Wl,-rpath,`pg_config --libdir`
clean::
rm -f getpic
diff -r 80c215dbf076 -r afd9f769c7ae fastpath/getpic.c
--- a/fastpath/getpic.c Thu Dec 10 12:00:00 2009 +0100
+++ b/fastpath/getpic.c Fri Dec 25 12:00:00 2009 +0100
@@ -16,67 +16,50 @@
#endif
int main(int argc, const char * const *argv) {
- PGconn *conn;
- PGresult *dbr;
-
- char *cookies = getenv("HTTP_COOKIE");
char *args_string;
char *member_id;
char *image_type;
-
- char *sql_session_params[1];
char *sql_member_image_params[2];
+ char *cookies;
+ regex_t session_ident_regex;
ssize_t start, length;
-
+ regmatch_t session_ident_regmatch[3];
char *session_ident;
+ char *sql_session_params[1];
- regex_t session_ident_regex;
- regmatch_t session_ident_regmatch[2];
-
- cookies = getenv("HTTP_COOKIE");
+ PGconn *conn;
+ PGresult *dbr;
args_string = getenv("QUERY_STRING");
-
- if (!cookies || !args_string) {
+ cookies = getenv("HTTP_COOKIE");
+ if (!args_string || !cookies) {
fputs("Status: 403 Access Denied\n\n", stdout);
return 0;
}
member_id = strtok(args_string, "+");
image_type = strtok(NULL, "+");
-
sql_member_image_params[0] = member_id;
sql_member_image_params[1] = image_type;
- // get session from cookie
-
- // TODO improve regex to fit better
- if (regcomp(&session_ident_regex, "liquid_feedback_session=([a-zA-Z0-9]+)", REG_EXTENDED) != 0) {
+ if (regcomp(&session_ident_regex, "(^|[; \t])liquid_feedback_session=([0-9A-Za-z]+)", REG_EXTENDED) != 0) {
// shouldn't happen
abort();
}
-
if (regexec(&session_ident_regex, cookies, 2, session_ident_regmatch, 0) != 0) {
fputs("Status: 403 Access Denied\n\n", stdout);
return 0;
}
-
- start = session_ident_regmatch[1].rm_so;
- length = session_ident_regmatch[1].rm_eo - session_ident_regmatch[1].rm_so;
-
+ start = session_ident_regmatch[2].rm_so;
+ length = session_ident_regmatch[2].rm_eo - session_ident_regmatch[2].rm_so;
session_ident = malloc(length + 1);
-
+ if (!session_ident) abort(); // shouldn't happen
strncpy(session_ident, cookies + start, length);
-
session_ident[length] = 0;
-
sql_session_params[0] = session_ident;
-
- // connect to database
-
conn = PQconnectdb(GETPIC_CONNINFO);
if (!conn) {
fputs("Could not create PGconn structure.\n", stderr);
@@ -84,27 +67,25 @@
}
if (PQstatus(conn) != CONNECTION_OK) {
fputs(PQerrorMessage(conn), stderr);
+ PQfinish(conn);
return 1;
}
- // check session
dbr = PQexecParams(conn,
"SELECT NULL FROM session JOIN member ON member.id = session.member_id WHERE session.ident = $1 AND member.active",
1, NULL, sql_session_params, NULL, NULL, 0
);
-
if (PQresultStatus(dbr) != PGRES_TUPLES_OK) {
fputs(PQresultErrorMessage(dbr), stderr);
+ PQfinish(conn);
return 1;
}
-
if (PQntuples(dbr) != 1) {
fputs("Status: 403 Access Denied\n\n", stdout);
+ PQfinish(conn);
return 0;
}
-
- // get picture
dbr = PQexecParams(conn,
"SELECT content_type, data "
"FROM member_image "
@@ -114,35 +95,34 @@
"LIMIT 1;",
2, NULL, sql_member_image_params, NULL, NULL, 1
);
-
if (PQresultStatus(dbr) != PGRES_TUPLES_OK) {
fputs(PQresultErrorMessage(dbr), stderr);
- return 1;
- }
- if (PQntuples(dbr) > 1) {
+ PQfinish(conn);
return 1;
}
- fputs("Cache-Control: private; max-age=86400\n", stdout);
if (PQntuples(dbr) == 0) {
struct stat sb;
PQclear(dbr);
PQfinish(conn);
fputs("Content-Type: image/jpeg\n\n", stdout);
if (stat(GETPIC_DEFAULT_AVATAR, &sb)) return 1;
- fprintf(stdout, "Content-Length: %i\n", sb.st_size);
+ fprintf(stdout, "Content-Length: %i\n", (int)sb.st_size);
execl("/bin/cat", "cat", GETPIC_DEFAULT_AVATAR, NULL);
return 1;
} else {
if (PQnfields(dbr) < 0) {
fputs("Too few columns returned by database.\n", stderr);
+ PQfinish(conn);
return 1;
}
if (PQfformat(dbr, 0) != 1 || PQfformat(dbr, 1) != 1) {
fputs("Database did not return data in binary format.\n", stderr);
+ PQfinish(conn);
return 1;
}
if (PQgetisnull(dbr, 0, 0) || PQgetisnull(dbr, 0, 1)) {
fputs("Unexpected NULL in database result.\n", stderr);
+ PQfinish(conn);
return 1;
}
fputs("Content-Type: ", stdout);
@@ -151,7 +131,7 @@
fputs("\n\n", stdout);
fwrite(PQgetvalue(dbr, 0, 1), PQgetlength(dbr, 0, 1), 1, stdout);
}
- PQclear(dbr);
PQfinish(conn);
return 0;
+
}
diff -r 80c215dbf076 -r afd9f769c7ae locale/help/area.show.de.txt
--- a/locale/help/area.show.de.txt Thu Dec 10 12:00:00 2009 +0100
+++ b/locale/help/area.show.de.txt Fri Dec 25 12:00:00 2009 +0100
@@ -1,6 +1,8 @@
-=Themenbereich, Mitgliedschaft=
-Für die Teilnahme an der Diskussion und Endabstimmung einzelner Themen ist die Mitgliedschaft im Themenbereich **keine** Voraussetzung. Mit der Mitgliedschaft erklärst du vielmehr ein generelles Interesse an diesem Themenbereich.
-=Delegation, Auto-Ablehnen=
-Du kannst deine Stimme für diesen Themenbereich (unabhängig von deiner Mitgliedschaft im Themenbereich) an eine Person in deiner Kontaktliste delegieren. Als Themenbereichsmitglied kannst du ,,Auto-Ablehnen'' als Standardabstimmverhalten festlegen. Diese Weisung gilt nur für den Fall, dass du nicht selbst an der Endabstimmung teilnimmst, es keine tatsächlich genutzte Delegation und keine Weisung für das jeweilige konkrete Thema gibt.
-=Neues Thema=
-Hier kannst du mit einer eigenen Initiative ein neues Thema eröffnen. **Bevor** du ein neues Thema eröffnest, solltest du prüfen, ob es dieses Thema vieleicht schon gibt. Eine Initiative zu einem bestehenden Thema (Alternativantrag) kannst du von der jeweilige Themenseite aus starten.
+=Thema, Interesse=
+Auf dieser Seite werden alle Initiativen zu diesem Thema aufgelistet. Wenn du ,,Interesse am Thema'' anmeldest, wirst du für dieses Thema den Mitgliedern des übergeordneten Themenbereichs gleichgestellt und erhöhst die Bemessungsgrundlage der von Initiativen zu erreichenden Unterstützerquoren. Sobald du eine Initiative dieses Themas unterstützt, wird dein Interesse auch automatisch angemeldet. Sofern du allen Initiativen die Unterstützung entziehst, bleibt dein Interesse dennoch bestehen bis du es abmeldest.
+=Delegation, Auto-Ablehnung=
+Eine Delegation zu diesem Thema geht einer eventuell vorhandenen globalen Delegation und/oder Delegation für den übergeordneten Themenbereich vor. Eine eventuelle Weisung zur Auto-Ablehung gilt nur für den Fall, dass du nicht selbst an der Endabstimmung teilnimmst und es keine tatsächlich genutzte Delegation gibt. Bei angemeldetem Interesse werden ausgehende Delegationen während der Diskussionsphase ausgesetzt, gelten aber in der Endabstimmung.
+=Diskussionsphase=
+Während der Diskussionsphase (Zustände ,,Neu'' und ,,Diskussion'') solltest du **alle** Initiativen, die du grundsätzlich (oder unter bestimmten Bedingungen) für zustimmungsfähig hältst, unterstützen und Anregungen zur Verbesserung geben (Näheres dazu findest du auf der Initiativenseite). Hierdurch gibst du den Initiatoren die Chance, den Entwurf zu verbessern. Während dieser Phase hast du auch die Möglichkeit, eine eigene (konkurrierende) Initiative zu diesem Thema zu starten und um Unterstützung zu ringen.
+=Endabstimmung=
+Initiativen, die ein bestimmtes Quorum erreichen, werden in die Endabstimmung übernommen. Du kannst dann alle Initiativen, denen du zustimmen möchtest, in eine Präferenzreihenfolge bringen. Bei den anderen Initiativen kannst Du dich enthalten oder auch dagegen stimmen (letzteres ebenfalls mit Präferenz). Beschlossen werden können nur Initiativen die insgesamt mehr Ja- als Nein-Stimmen erhalten.
diff -r 80c215dbf076 -r afd9f769c7ae locale/help/vote.list.de.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/locale/help/vote.list.de.txt Fri Dec 25 12:00:00 2009 +0100
@@ -0,0 +1,8 @@
+=Abstimmmung=
+Je nachdem, welche Standardeinstellungen du gewählt hast, befinden sich zu Beginn der Abstimmung alle Initiativen im Feld Enthaltung oder im Feld Ablehnung. Beginne am besten mit deinem Favoriten und ziehe ihn mit der Maus in das Feld Zustimmung. Danach wählst du die nächste Initiative, der du zustimmen möchtest und ziehst sie
+- in die gleiche grüne Box, falls du dieser Initiative gleichberechtigt zustimmen möchtest oder
+- zwischen die Zustimmungs- und Enthaltungsbox, falls diese Initiative dein Ersatzwunsch sein soll.
+
+Auf diese Weise fährst du fort und legst die Präferenzreihenfolge der Initiativen, denen du zustimmen möchtest fest, wobei du gleichwertige Initiativen jeweils in die gleiche Box hineinziehst. Dann legst du deine Enthaltungen und Ablehnungen fest, wobei du auch die Ablehnungen in eine Rangreihenfolge bringen kannst, falls eine der Initiativen so etwas wie das ,,kleinere Übel'' darstellen sollte.
+
+**Wichtig:** Verlasse diese Seite über die Schaltfläche ,,Stimmabgabe abschließen''. Bis zum Ende der Abstimmung kannst du deine Angaben jederzeit ändern. Es werden keine Zwischenergebnisse der Abstimmung veröffentlicht. Die Unterstützerangaben auf der Themenübersichtsseite beziehen sich auf die abgeschlossene Diskussion, beziehen sich jeweils auf die einzelne Initiative und sind nur sehr bedingt geeignet, zwischen den Initiativen zu vergleichen. Insbesondere enthalten sie keinerlei Informationen über Präferenzen. Darüber hinaus kann sich der Teilnehmerkreis von Diskussion und Abstimmung erheblich unterscheiden.
diff -r 80c215dbf076 -r afd9f769c7ae locale/translations.de.lua
--- a/locale/translations.de.lua Thu Dec 10 12:00:00 2009 +0100
+++ b/locale/translations.de.lua Fri Dec 25 12:00:00 2009 +0100
@@ -1,12 +1,15 @@
#!/usr/bin/env lua
return {
+["#{interested_issues_to_vote_count} issue(s) you are interested in"] = "#{interested_issues_to_vote_count} Themen, die Dich interessieren";
+["#{issues_to_vote_count} issue(s)"] = "#{issues_to_vote_count} Themen";
["#{number} Image(s) has been deleted"] = "Es wurde(n) #{number} Bild(er) gelöscht";
["#{number} Image(s) has been updated"] = "Es wurde(n) #{number} Bild(er) aktualisiert";
["(change URL)"] = "(URL ändern)";
-["+ #{weight}"] = false;
-["A-Z"] = false;
-["About"] = false;
+["+ #{weight}"] = "+ #{weight}";
+["A-Z"] = "A-Z";
+["About"] = "About";
["About LiquidFeedback"] = "Über LiquidFeedback";
+["Abstention"] = "Enthaltung";
["Accepted at"] = "Angenommen am/um";
["Active?"] = "Aktiv?";
["Add my interest"] = "Mein Interesse anmelden";
@@ -17,7 +20,7 @@
["Admin"] = "Admin";
["Admin menu"] = "Admin Menü";
["Admin?"] = "Admin?";
-["Administrator"] = false;
+["Administrator"] = "Administrator";
["Admission time"] = "Zeit für die Zulassung";
["Admitted"] = "zugelassen";
["Any"] = "Alle";
@@ -31,7 +34,7 @@
["Author"] = "Autor";
["Autoreject is off."] = "Auto-Ablehnen ist aus";
["Autoreject is on."] = "Auto-Ablehnen ist an";
-["Avatar"] = false;
+["Avatar"] = "Avatar";
["Become a member"] = "Mitglied werden";
["Birthday"] = "Geburtstag";
["Bug report"] = "Fehlerbericht";
@@ -49,16 +52,18 @@
["Compare"] = "Vergleichen";
["Contacts"] = "Kontakte";
["Content"] = "Inhalt";
+["Counting of votes"] = "Auszählung";
["Create alternative initiative"] = "Alternative Initiative hinzufügen";
["Create new area"] = "Neuen Themenbereich anlegen";
["Create new issue"] = "Neues Thema anlegen";
["Created at"] = "Erzeugt am/um";
["Current draft"] = "Aktueller Entwurf";
+["Current votings in areas you are member of and issues you are interested in:"] = "Jetzt laufende Abstimmungen zu Themen aus Deinen Themenbereichen oder solchen an denen Du interessiert bist:";
["Degree"] = "Grad";
["Delegations"] = "Delegationen";
["Description"] = "Beschreibung";
["Details"] = "Details";
-["Diff"] = false;
+["Diff"] = "Differenz";
["Direct member count"] = "Anzahl Direktmitglieder";
["Direct membership"] = "Direkte Mitgliedschaft";
["Discussion"] = "Diskussion";
@@ -70,11 +75,12 @@
["Edit initiative"] = "Initiative bearbeiten";
["Edit my page"] = "Meine Seite bearbeiten";
["Edit my profile"] = "Mein Profil bearbeiten";
-["Empty help text: #{id}.#{lang}.txt"] = false;
+["Empty help text: #{id}.#{lang}.txt"] = "Leerer Hilfe-Text: #{id}.#{lang}.txt";
["Error while updating member, database reported:
(#{errormessage})"] = "Fehler beim aktualisieren des Mitglieds, die Datenbank berichtet folgenden Fehler:
(#{errormessage})";
["External memberships"] = "Externe Mitgliedschaften";
["External posts"] = "Externe Ämter";
-["Filter"] = false;
+["Filter"] = "Filter";
+["Finish voting"] = "Stimmabgabe abschließen";
["Finished"] = "Abgeschlossen";
["Frozen"] = "Eingefroren";
["Fulfilled"] = "Erfüllt";
@@ -101,9 +107,12 @@
["Interest not existant"] = "Interesse existiert nicht";
["Interest removed"] = "Interesse entfernt";
["Interest updated"] = "Interesse aktualisiert";
+["Interested"] = "Interessiert";
["Interested members"] = "Interessierte Mitglieder";
["Internal posts"] = "Interne Ämter";
["Invalid username or password!"] = "Ungültiger Benutzername oder Kennwort";
+["Invite code"] = "Invite-Code";
+["Invite code valid!"] = "Invite-Code gültig!";
["Issue"] = "Thema";
["Issue ##{id}"] = "Issue ##{id}";
["Issue ##{id} (#{policy_name})"] = "Thema ##{id} (#{policy_name})";
@@ -112,11 +121,14 @@
["Issue policy"] = "Regelwerk für Thema";
["Issue quorum"] = "Quorum Thema";
["Issues"] = "Themen";
+["JavaScript is disabled or not available."] = "JavaScript ist abgeschaltet oder nicht verfügbar.";
["Last snapshot:"] = "Letzte Auszählung:";
["Legend:"] = "Legende:";
["License"] = "Lizenz";
["Locked?"] = "Gesperrt?";
["Login"] = "Anmeldung";
+["Login is available"] = "Anmeldename ist verfügbar";
+["Login name"] = "Anmeldename";
["Login successful!"] = "Anmeldung erfolgreich";
["Logout"] = "Abmelden";
["Logout successful"] = "Abmeldung erfolgreich";
@@ -124,16 +136,16 @@
["Mark suggestion as implemented and express satisfaction"] = "Anregung als umgesetzt markieren und Zufriedenheit ausdrücken";
["Mark suggestion as not implemented and express dissatisfaction"] = "Anregung als nicht umgesetzt markieren und Unzufriedenheit ausdrücken";
["Mark suggestion as not implemented and express satisfaction"] = "Anregung als nicht umgesetzt markieren und Zufriedenheit ausdrücken";
+["Max potential support"] = "Max. potentielle Unterstützer";
+["Max support"] = "Max. Unterstützer";
["Member '#{member}'"] = "Mitglied '#{member}'";
["Member has been removed from your contacts"] = "Mitglied wurde aus Deinen Kontakten entfernt";
-["Member has been saved as private contact"] = "Mitglied wurde als privater Kontakt gespeichert";
-["Member has been saved as public contact"] = "Mitglied wurde als öffentlicher Kontakt gespeichert";
["Member is administrator"] = "Mitglied ist Administrator";
["Member is already saved in your contacts!"] = "Mitglied ist schon in Deinen Kontakten!";
["Member list"] = "Mitgliederliste";
["Member login"] = "Mitglied Login";
["Member name"] = "Mitglied Name";
-["Member page"] = false;
+["Member page"] = "Mitgliederseite";
["Member successfully registered"] = "Mitglied erfolgreich registriert";
["Member successfully updated"] = "Mitglied erfolgreich aktualisert";
["Member: '#{login}' (#{name})"] = "Mitlied: '#{login}' (#{name})";
@@ -143,10 +155,11 @@
["Membership removed"] = "Mitgliedschaft entfernt";
["Membership updated"] = "Mitgliedschaft aktualisiert";
["Memberships"] = "Mitgliedschaften";
-["Missing help text: #{id}.#{lang}.txt"] = false;
+["Missing help text: #{id}.#{lang}.txt"] = "Fehlender Hilfe-Text: #{id}.#{lang}.txt";
["Mobile phone"] = "Mobiltelefon";
["My opinion"] = "Meine Meinung";
["Name"] = "Name";
+["Name is available"] = "Name ist verfügbar";
["New"] = "Neu";
["New draft has been added to initiative"] = "Neuer Entwurf wurde der Initiative hinzugefügt";
["New draft revision"] = "Neue Revision des Entwurfs";
@@ -155,9 +168,13 @@
["New passwords is too short."] = "Das neue Kennwort ist zu kurz";
["Newest"] = "Neueste";
["Next state"] = "Nächster Zustand";
+["No"] = "Nein";
["No changes to your images were made"] = "An Deinen Bildern wurde nichts geändert";
["No delegation"] = "Keine Delegation";
["No membership at all"] = "Gar keine Mitgliedschaft";
+["No support at all"] = "Gar keine Unterstützung";
+["Not a member"] = "Kein Mitglied";
+["Not voted"] = "Nicht abgestimmt";
["Number of incoming delegations, follow link to see more details"] = "Anzahl eingehender Delegationen, Link folgen für mehr Details";
["OK"] = "OK";
["Old draft revision"] = "Alte Revision des Entwurfs";
@@ -165,15 +182,26 @@
["Old password"] = "Altes Kennwort";
["Old password is wrong"] = "Das alte Kennwort ist falsch";
["Oldest"] = "Älteste";
+["One issue"] = "Ein Thema";
+["One issue you are interested in"] = "Ein Thema, das Dich interessiert";
["Order by"] = "Sortieren nach";
["Organizational unit"] = "Organisationseinheit";
["Outgoing delegations"] = "Ausgehende Delegationen";
["Password"] = "Kennwort";
+["Password (repeat)"] = "Kennwort (wiederholen)";
+["Passwords don't match!"] = "Kennwörter stimmen nicht überein!";
+["Passwords must consist of at least 8 characters!"] = "Das Kennwort muß zumindest 8 Zeichen lang sein!";
["Phone"] = "Telefon";
["Photo"] = "Foto";
+["Please choose a login name. This name will not be shown to others and is used only by you to login into the system. The login name is case sensitive."] = "Bitte wähle einen Anmeldenamen. Dieser wird anderen nicht gezeigt und nur von Dir zum Anmelden verwendet. Groß- und Kleinschreibung wird berücksichtigt.";
+["Please choose a name, i.e. your real name or your nick name. This name will be shown to others to identify you. You CAN'T change this name later, so please choose it wisely!"] = "Bitte wähle einen Namen, z. B. Deinen Real- oder Nicknamen. Dieser wird anderen angezeigt um Dich zu identifizieren. Du kannst Deinen Namen später NICHT ändern, wähle ihn also weise!";
+["Please choose a password and enter it twice. The password is case sensitive."] = "Bitte wähle ein Kennwort und gebe es zweimal ein. Groß- und Kleinschreibung wird berücksichtigt.";
+["Please enter the invite code you've received."] = "Bitte gib den Invite-Code ein, den Du erhalten hast.";
["Policy"] = "Regelwerk";
["Population"] = "Grundgesamtheit";
["Posts"] = "Ämter";
+["Potential support"] = "Potentielle Unterstützung";
+["Potential supporter"] = "Potentielle Unterstützer";
["Profession"] = "Beruf";
["Profile"] = "Profil";
["Publish"] = "Veröffentlichen";
@@ -182,7 +210,9 @@
["Rank"] = "Rang";
["Real name"] = "Realname";
["Refresh support to current draft"] = "Unterstützung auf aktuellen Entwurf aktualisieren";
+["Register"] = "Registrieren";
["Register new member"] = "Neues Mitglied registrieren";
+["Registration"] = "Registrierung";
["Remove"] = "Entfernen";
["Remove autoreject"] = "Auto-Ablehnen abschalten";
["Remove from contacts"] = "Aus den Kontakten entfernen";
@@ -207,57 +237,72 @@
["Set issue delegation"] = "Delegation für Thema festlegen";
["Show"] = "Zeige";
["Show active members"] = "Zeige aktive Mitglieder";
+["Show all initiatives"] = "Zeige alle Initiativen";
["Show areas in use"] = "Zeige verwendete Themenbereiche";
["Show areas not in use"] = "Zeige nicht verwendente Themenbereiche";
["Show diff"] = "Änderungen anzeigen";
["Show locked members"] = "Zeige gesperrte Mitglieder";
["Show member"] = "Mitglied anzeigen";
-["Show other initiatives"] = "Zeige alternative Initiativen";
-["Software"] = false;
+["Software"] = "Software";
+["Some JavaScript based functions (voting in particular) will not work.\nFor this beta, please use a current version of Firefox, Safari, Opera(?), Konqueror or another (more) standard compliant browser.\nAlternative access without JavaScript will be available soon."] = "Einige auf JavaScript basierende Funktionen (insbesondere der Abstimmung) sind nicht benutzbar.\nFür diese Beta verwende bitte eine aktuelle Version von Firefox, Safari, Opera(?), Konqueror oder einen anderen (mehr) den Standards entsprechenden Browser.\nEin alternativer Zugriff ohne JavaScript wird bald zur Verfügung stehen.";
+["Sorry, you have reached your personal flood limit. Please be slower..."] = "Sorry, Du hast Dein persönliches Flood-Limit erreicht. Bitte sei langsamer...";
+["Sorry, your contingent for creating initiatives has been used up. Please try again later."] = "Sorry, Dein Antragskontingent ist zur Zeit ausgeschöpft. Bitte versuche es später erneut!";
["State"] = "Zustand";
-["Statement"] = false;
+["Statement"] = "Statement";
["Suggestion"] = "Anregung";
["Suggestion currently implemented"] = "Anregung zur Zeit umgesetzt";
["Suggestion currently not implemented"] = "Anregung zur Zeit nicht umgesetzt";
["Suggestion for initiative: '#{name}'"] = "Anregung für Initiative '#{name}'";
["Suggestions"] = "Anregungen";
["Support"] = "Unterstützung";
-["Support S+I"] = "Unterstütung S+I";
["Support this initiative"] = "Diese Initiative unterstützen";
["Supported initiatives"] = "Unterstützte Initiativen";
["Supporter"] = "Unterstützer";
["That's me!"] = "Das bin ich";
+["The code you've entered is invalid"] = "Den Code den Du eingeben hast ist nicht gültig!";
["The drafts do not differ"] = "Die Entwürfe unterscheiden sich nicht";
+["This issue is already closed."] = "Das Thema ist schon geschlossen.";
+["This issue is already frozen."] = "Das Thema ist schon eingefroren";
+["This login is already taken, please choose another one!"] = "Dieser Anmeldename ist bereits vergeben, bitte wähle einen anderen!";
+["This name is already taken, please choose another one!"] = "Dieser Name ist bereits vergeben, bitte wähle einen anderen!";
["Time left"] = "Restzeit";
-["Title (80 chars max)"] = "Titel (max. 80 Zeichen)";
+["Title (80 chars max)"] = "Title (max. 80 Zeichen)";
+["Traditional wiki syntax"] = "Traditionaller Wiki-Syntax";
["Trustee"] = "Bevollmächtigter";
["Unknown author"] = "Unbekannter Autor";
["Upload images"] = "Bilder hochladen";
-["Username"] = "Benutzername";
["Verification time"] = "Zeit für die Überprüfung";
-["Version"] = false;
+["Version"] = "Version";
["Vote later"] = "Später abstimmen";
["Vote now"] = "Jetzt abstimmen";
+["Vote now/later"] = "Jetzt/später abstimmen";
+["Voted"] = "Abgestimmt";
["Voting"] = "Abstimmung";
+["Voting for this issue has already begun."] = "Die Abstimmung für dieses Thema hat schon begonnen.";
+["Voting has not started yet."] = "Die Abstimmung hat noch nicht begonnen.";
["Voting requests"] = "Abstimmanträge";
["Voting time"] = "Zeit für die Abstimmung";
["Website"] = "Webseite";
+["Wiki engine"] = "Wiki engine";
+["Yes"] = "Ja";
["You are already not supporting this initiative"] = "Diese Initiative hat bereits keine Unterstützung von Dir";
["You are already supporting the latest draft"] = "Du unterstützt bereits den neuesten Entwurf";
-["You are currently not supporting this initiative. By adding suggestions to this initiative you will automatically become a potential supporter."] = false;
+["You are currently not supporting this initiative. By adding suggestions to this initiative you will automatically become a potential supporter."] = "Du bist zur Zeit kein Unterstützer dieser Initiative. Wenn Du eine Anregung hinzufügst wirst Du automatisch potentieller Unterstützer!";
["You are member"] = "Du bist Mitglied";
["You didn't saved any member as contact yet."] = "Du hast noch kein Mitglied als Kontakt gespeichert!";
["You have saved this member as contact"] = "Du hast das Mitglied als Kontakt gespeichert";
["You have saved this member as contact."] = "Du hast das Mitglied als Kontakt gespeichert.";
["You need to be logged in, to use this system."] = "Du musst eingeloggt sein, um das System zu benutzen";
+["You've successfully registered and you can login now with your login and password!"] = "Du hast Dich erfolgreich registriert und kannst Dich jetzt mit Deinen Benutzernamen und Kennwort anmelden!";
["Your are interested"] = "Du bist interessiert";
+["Your are potential supporter"] = "Du bist potentieller Unterstützer";
["Your are supporter"] = "Du bist Unterstützer";
["Your delegation for this area has been deleted."] = "Deine Delegation für dieses Themengebiet wurde gelöscht";
["Your delegation for this area has been updated."] = "Deine Delegation für dieses Themengebiet wurde geändert";
["Your delegation for this issue has been deleted."] = "Deine Delegation für dieses Thema wurde gelöscht";
["Your delegation for this issue has been updated."] = "Deine Delegation für dieses Thema wurde geändert";
["Your global delegation has been deleted."] = "Deine globale Delegation wurde gelöscht";
-["Your global delegation has been updated."] = "Deine globale Delegation würde geändert";
+["Your global delegation has been updated."] = "Deine globale Delegation wurde geändert";
["Your opinion has been deleted"] = "Deine Meinung wurde gelöscht";
["Your opinion has been updated"] = "Deine Meinung wurde aktualisiert";
["Your page has been updated"] = "Deine Seite wurde aktualisiert";
@@ -266,11 +311,12 @@
["Your support has been added to this initiative"] = "Deine Unterstützung wurde der Initiative hinzugefügt";
["Your support has been removed from this initiative"] = "Deine Unterstützung wurde der Initiave entzogen";
["Your support has been updated to the latest draft"] = "Deine Unterstützung wurde auf den neuesten Entwurf aktualisiert";
-["Z-A"] = false;
+["Your web browser is not fully supported yet."] = "Dein Web-Browser wird noch nicht vollständig unterstützt.";
+["Z-A"] = "Z-A";
["all"] = "Alle";
-["blank"] = false;
["delete