| rev | 
   line source | 
| 
bsw@1496
 | 
     1 local initiative
 | 
| 
bsw@1496
 | 
     2 local new_initiative
 | 
| 
bsw@1496
 | 
     3 local draft_id
 | 
| 
bsw@1496
 | 
     4 local status
 | 
| 
bsw@1496
 | 
     5 
 | 
| 
bsw@1496
 | 
     6 if param.get("initiative_id", atom.integer) then
 | 
| 
bsw@1496
 | 
     7 
 | 
| 
bsw@1496
 | 
     8   local function donew()
 | 
| 
bsw@1496
 | 
     9     local draft_text = param.get("content")
 | 
| 
bsw@1496
 | 
    10 
 | 
| 
bsw@1496
 | 
    11     if not draft_text then
 | 
| 
bsw@1496
 | 
    12       return false
 | 
| 
bsw@1496
 | 
    13     end
 | 
| 
bsw@1496
 | 
    14 
 | 
| 
bsw@1496
 | 
    15     local draft_text = util.wysihtml_preproc(draft_text)
 | 
| 
bsw@1496
 | 
    16 
 | 
| 
bsw@1496
 | 
    17     local valid_html, error_message = util.html_is_safe(draft_text)
 | 
| 
bsw@1496
 | 
    18     if not valid_html then
 | 
| 
bsw@1496
 | 
    19       slot.put_into("error", _("Draft contains invalid formatting or character sequence: #{error_message}", { error_message = error_message }) )
 | 
| 
bsw@1496
 | 
    20       return false
 | 
| 
bsw@1496
 | 
    21     end
 | 
| 
bsw@1496
 | 
    22 
 | 
| 
bsw@1496
 | 
    23     if config.initiative_abstract then
 | 
| 
bsw@1496
 | 
    24       local abstract = param.get("abstract")
 | 
| 
bsw@1496
 | 
    25       if not abstract then
 | 
| 
bsw@1496
 | 
    26         return false
 | 
| 
bsw@1496
 | 
    27       end
 | 
| 
bsw@1496
 | 
    28       abstract = encode.html(abstract)
 | 
| 
bsw@1496
 | 
    29       draft_text = abstract .. "<!--END_OF_ABSTRACT-->" .. draft_text
 | 
| 
bsw@1496
 | 
    30     end
 | 
| 
bsw@1496
 | 
    31 
 | 
| 
bsw@1496
 | 
    32     draft_id = Draft:update_content(
 | 
| 
bsw@1496
 | 
    33       app.session.member.id, 
 | 
| 
bsw@1496
 | 
    34       param.get("initiative_id", atom.integer),
 | 
| 
bsw@1496
 | 
    35       param.get("formatting_engine"),
 | 
| 
bsw@1496
 | 
    36       draft_text,
 | 
| 
bsw@1496
 | 
    37       nil,
 | 
| 
bsw@1496
 | 
    38       param.get("preview") or param.get("edit")
 | 
| 
bsw@1496
 | 
    39     )
 | 
| 
bsw@1496
 | 
    40     return draft_id and true or false
 | 
| 
bsw@1496
 | 
    41   end
 | 
| 
bsw@1496
 | 
    42 
 | 
| 
bsw@1496
 | 
    43   status = donew()
 | 
| 
bsw@1496
 | 
    44 
 | 
| 
bsw@1496
 | 
    45 else
 | 
| 
bsw@1496
 | 
    46 
 | 
| 
bsw@1496
 | 
    47   local function donew()
 | 
| 
bsw@1496
 | 
    48     local issue
 | 
| 
bsw@1496
 | 
    49     local area
 | 
| 
bsw/jbe@1309
 | 
    50 
 | 
| 
bsw@1496
 | 
    51     local issue_id = param.get("issue_id", atom.integer)
 | 
| 
bsw@1496
 | 
    52     if issue_id then
 | 
| 
bsw@1496
 | 
    53       issue = Issue:new_selector():add_where{"id=?",issue_id}:for_share():single_object_mode():exec()
 | 
| 
bsw@1496
 | 
    54       if issue.closed then
 | 
| 
bsw@1496
 | 
    55         slot.put_into("error", _"This issue is already closed.")
 | 
| 
bsw@1496
 | 
    56         return false
 | 
| 
bsw@1496
 | 
    57       elseif issue.fully_frozen then 
 | 
| 
bsw@1496
 | 
    58         slot.put_into("error", _"Voting for this issue has already begun.")
 | 
| 
bsw@1496
 | 
    59         return false
 | 
| 
bsw@1496
 | 
    60       elseif issue.phase_finished then
 | 
| 
bsw@1496
 | 
    61         slot.put_into("error", _"Current phase is already closed.")
 | 
| 
bsw@1496
 | 
    62         return false
 | 
| 
bsw@1496
 | 
    63       end
 | 
| 
bsw@1496
 | 
    64       area = issue.area
 | 
| 
bsw@1496
 | 
    65     else
 | 
| 
bsw@1496
 | 
    66       local area_id = param.get("area_id", atom.integer)
 | 
| 
bsw@1496
 | 
    67       area = Area:new_selector():add_where{"id=?",area_id}:single_object_mode():exec()
 | 
| 
bsw@1496
 | 
    68       if not area.active then
 | 
| 
bsw@1496
 | 
    69         slot.put_into("error", "Invalid area.")
 | 
| 
bsw@1496
 | 
    70         return false
 | 
| 
bsw@1496
 | 
    71       end
 | 
| 
bsw@1496
 | 
    72     end
 | 
| 
bsw@1496
 | 
    73 
 | 
| 
bsw@1496
 | 
    74     if not app.session.member:has_voting_right_for_unit_id(area.unit_id) then
 | 
| 
bsw@1496
 | 
    75       return execute.view { module = "index", view = "403" }
 | 
| 
bsw@1496
 | 
    76     end
 | 
| 
bsw@1496
 | 
    77 
 | 
| 
bsw@1496
 | 
    78     local policy_id = param.get("policy_id", atom.integer)
 | 
| 
bsw@1496
 | 
    79     local policy
 | 
| 
bsw@1496
 | 
    80     if policy_id then
 | 
| 
bsw@1496
 | 
    81       policy = Policy:by_id(policy_id)
 | 
| 
bsw@1496
 | 
    82     end
 | 
| 
bsw/jbe@1309
 | 
    83 
 | 
| 
bsw@1496
 | 
    84     if not issue then
 | 
| 
bsw@1496
 | 
    85       if policy_id == -1 then
 | 
| 
bsw@1496
 | 
    86         slot.put_into("error", _"Please choose a policy")
 | 
| 
bsw@1496
 | 
    87         return false
 | 
| 
bsw@1496
 | 
    88       end
 | 
| 
bsw@1496
 | 
    89       if not policy.active then
 | 
| 
bsw@1496
 | 
    90         slot.put_into("error", "Invalid policy.")
 | 
| 
bsw@1496
 | 
    91         return false
 | 
| 
bsw@1496
 | 
    92       end
 | 
| 
bsw@1496
 | 
    93       if policy.polling and not app.session.member:has_polling_right_for_unit_id(area.unit_id) then
 | 
| 
bsw@1496
 | 
    94         return execute.view { module = "index", view = "403" }
 | 
| 
bsw@1496
 | 
    95       end
 | 
| 
bsw@1496
 | 
    96       if not area:get_reference_selector("allowed_policies")
 | 
| 
bsw@1496
 | 
    97         :add_where{ "policy.id = ?", policy_id }
 | 
| 
bsw@1496
 | 
    98         :optional_object_mode()
 | 
| 
bsw@1496
 | 
    99         :exec()
 | 
| 
bsw@1496
 | 
   100       then
 | 
| 
bsw@1496
 | 
   101         slot.put_into("error", "policy not allowed")
 | 
| 
bsw@1496
 | 
   102         return false
 | 
| 
bsw@1496
 | 
   103       end
 | 
| 
bsw@1496
 | 
   104     end
 | 
| 
bsw@1496
 | 
   105 
 | 
| 
bsw@1496
 | 
   106     local is_polling = (issue and param.get("polling", atom.boolean)) or (policy and policy.polling) or false
 | 
| 
bsw@1496
 | 
   107 
 | 
| 
bsw@1496
 | 
   108     local tmp = db:query({ "SELECT text_entries_left, initiatives_left FROM member_contingent_left WHERE member_id = ? AND polling = ?", app.session.member.id, is_polling }, "opt_object")
 | 
| 
bsw@1496
 | 
   109     if not tmp or tmp.initiatives_left < 1 then
 | 
| 
bsw@1496
 | 
   110       slot.put_into("error", _"Sorry, your contingent for creating initiatives has been used up. Please try again later.")
 | 
| 
bsw@1496
 | 
   111       return false
 | 
| 
bsw@1496
 | 
   112     end
 | 
| 
bsw@1496
 | 
   113     if tmp and tmp.text_entries_left < 1 then
 | 
| 
bsw@1496
 | 
   114       slot.put_into("error", _"Sorry, you have reached your personal flood limit. Please be slower...")
 | 
| 
bsw@1496
 | 
   115       return false
 | 
| 
bsw@1496
 | 
   116     end
 | 
| 
bsw@1496
 | 
   117 
 | 
| 
bsw@1496
 | 
   118     local name = param.get("name")
 | 
| 
bsw@1496
 | 
   119 
 | 
| 
bsw@1496
 | 
   120     local name = util.trim(name)
 | 
| 
bsw@1496
 | 
   121 
 | 
| 
bsw@1496
 | 
   122     if #name < 3 then
 | 
| 
bsw@1496
 | 
   123       slot.put_into("error", _"Please enter a meaningful title for your initiative!")
 | 
| 
bsw@1496
 | 
   124       return false
 | 
| 
bsw@1496
 | 
   125     end
 | 
| 
bsw@1496
 | 
   126 
 | 
| 
bsw@1496
 | 
   127     if #name > 140 then
 | 
| 
bsw@1496
 | 
   128       slot.put_into("error", _"This title is too long!")
 | 
| 
bsw@1496
 | 
   129       return false
 | 
| 
bsw@1496
 | 
   130     end
 | 
| 
bsw/jbe@1309
 | 
   131 
 | 
| 
bsw@1496
 | 
   132     local timing
 | 
| 
bsw@1496
 | 
   133     if not issue and policy.free_timeable then
 | 
| 
bsw@1496
 | 
   134       local free_timing_string = util.trim(param.get("free_timing"))
 | 
| 
bsw@1496
 | 
   135       if not free_timing_string or #free_timing_string < 1 then
 | 
| 
bsw@1496
 | 
   136         slot.put_into("error", _"Choose timing")
 | 
| 
bsw@1496
 | 
   137         return false
 | 
| 
bsw@1496
 | 
   138       end
 | 
| 
bsw@1496
 | 
   139       local available_timings
 | 
| 
bsw@1496
 | 
   140       if config.free_timing and config.free_timing.available_func then
 | 
| 
bsw@1496
 | 
   141         available_timings = config.free_timing.available_func(policy)
 | 
| 
bsw@1496
 | 
   142         if available_timings == false then
 | 
| 
bsw@1496
 | 
   143           slot.put_into("error", "error in free timing config")
 | 
| 
bsw@1496
 | 
   144           return false
 | 
| 
bsw@1496
 | 
   145         end
 | 
| 
bsw@1496
 | 
   146       end
 | 
| 
bsw@1496
 | 
   147       if available_timings then
 | 
| 
bsw@1496
 | 
   148         local timing_available = false
 | 
| 
bsw@1496
 | 
   149         for i, available_timing in ipairs(available_timings) do
 | 
| 
bsw@1496
 | 
   150           if available_timing.id == free_timing_string then
 | 
| 
bsw@1496
 | 
   151       	    timing_available = true
 | 
| 
bsw@1496
 | 
   152           end
 | 
| 
bsw@1496
 | 
   153         end
 | 
| 
bsw@1496
 | 
   154         if not timing_available then
 | 
| 
bsw@1496
 | 
   155           slot.put_into("error", _"Invalid timing")
 | 
| 
bsw@1496
 | 
   156           return false
 | 
| 
bsw@1496
 | 
   157         end
 | 
| 
bsw@1496
 | 
   158       end
 | 
| 
bsw@1496
 | 
   159       timing = config.free_timing.calculate_func(policy, free_timing_string)
 | 
| 
bsw@1496
 | 
   160       if not timing then
 | 
| 
bsw@1496
 | 
   161         slot.put_into("error", "error in free timing config")
 | 
| 
bsw@1496
 | 
   162         return false
 | 
| 
bsw@1496
 | 
   163       end
 | 
| 
bsw@1496
 | 
   164     end
 | 
| 
bsw@1496
 | 
   165 
 | 
| 
bsw@1496
 | 
   166     local draft_text = param.get("content")
 | 
| 
bsw@1496
 | 
   167 
 | 
| 
bsw@1496
 | 
   168     if not draft_text then
 | 
| 
bsw@1496
 | 
   169       slot.put_into("error", "no draft text")
 | 
| 
bsw@1496
 | 
   170       return false
 | 
| 
bsw@1496
 | 
   171     end
 | 
| 
bsw@1496
 | 
   172 
 | 
| 
bsw@1496
 | 
   173     local draft_text = util.wysihtml_preproc(draft_text)
 | 
| 
bsw@1496
 | 
   174 
 | 
| 
bsw@1496
 | 
   175     local valid_html, error_message = util.html_is_safe(draft_text)
 | 
| 
bsw@1496
 | 
   176     if not valid_html then
 | 
| 
bsw@1496
 | 
   177       slot.put_into("error", _("Draft contains invalid formatting or character sequence: #{error_message}", { error_message = error_message }) )
 | 
| 
bsw@1496
 | 
   178       return false
 | 
| 
bsw@1496
 | 
   179     end
 | 
| 
bsw@1496
 | 
   180 
 | 
| 
bsw@1496
 | 
   181     if config.initiative_abstract then
 | 
| 
bsw@1496
 | 
   182       local abstract = param.get("abstract")
 | 
| 
bsw@1496
 | 
   183       if not abstract then
 | 
| 
bsw@1496
 | 
   184         slot.put_into("error", "no abstract")
 | 
| 
bsw@1496
 | 
   185         return false
 | 
| 
bsw@1496
 | 
   186       end
 | 
| 
bsw@1496
 | 
   187       abstract = encode.html(abstract)
 | 
| 
bsw@1496
 | 
   188       draft_text = abstract .. "<!--END_OF_ABSTRACT-->" .. draft_text
 | 
| 
bsw@1496
 | 
   189     end
 | 
| 
bsw@1496
 | 
   190 
 | 
| 
bsw@1496
 | 
   191     local location = param.get("location")
 | 
| 
bsw@1496
 | 
   192     if location == "" then
 | 
| 
bsw@1496
 | 
   193       location = nil
 | 
| 
bsw@1496
 | 
   194     end
 | 
| 
bsw@1496
 | 
   195 
 | 
| 
bsw@1496
 | 
   196     if param.get("preview") or param.get("edit") then
 | 
| 
bsw@1496
 | 
   197       return false
 | 
| 
bsw@1496
 | 
   198     end
 | 
| 
bsw/jbe@1309
 | 
   199 
 | 
| 
bsw@1496
 | 
   200     initiative = Initiative:new()
 | 
| 
bsw@1496
 | 
   201 
 | 
| 
bsw@1496
 | 
   202     if not issue then
 | 
| 
bsw@1496
 | 
   203       issue = Issue:new()
 | 
| 
bsw@1496
 | 
   204       issue.area_id = area.id
 | 
| 
bsw@1496
 | 
   205       issue.policy_id = policy_id
 | 
| 
bsw@1496
 | 
   206       
 | 
| 
bsw@1496
 | 
   207       if policy.polling then
 | 
| 
bsw@1496
 | 
   208         issue.accepted = 'now'
 | 
| 
bsw@1496
 | 
   209         issue.state = 'discussion'
 | 
| 
bsw@1496
 | 
   210         initiative.polling = true
 | 
| 
bsw@1496
 | 
   211         
 | 
| 
bsw@1496
 | 
   212         if policy.free_timeable then
 | 
| 
bsw@1496
 | 
   213           issue.discussion_time = timing.discussion
 | 
| 
bsw@1496
 | 
   214           issue.verification_time = timing.verification
 | 
| 
bsw@1496
 | 
   215           issue.voting_time = timing.voting
 | 
| 
bsw@1496
 | 
   216         end
 | 
| 
bsw@1496
 | 
   217         
 | 
| 
bsw@1496
 | 
   218       end
 | 
| 
bsw@1496
 | 
   219       
 | 
| 
bsw@1496
 | 
   220       issue:save()
 | 
| 
bsw@1496
 | 
   221 
 | 
| 
bsw@1496
 | 
   222       if config.etherpad then
 | 
| 
bsw@1496
 | 
   223         local result = net.curl(
 | 
| 
bsw@1496
 | 
   224           config.etherpad.api_base 
 | 
| 
bsw@1496
 | 
   225           .. "api/1/createGroupPad?apikey=" .. config.etherpad.api_key
 | 
| 
bsw@1496
 | 
   226           .. "&groupID=" .. config.etherpad.group_id
 | 
| 
bsw@1496
 | 
   227           .. "&padName=Issue" .. tostring(issue.id)
 | 
| 
bsw@1496
 | 
   228           .. "&text=" .. request.get_absolute_baseurl() .. "issue/show/" .. tostring(issue.id) .. ".html"
 | 
| 
bsw@1496
 | 
   229         )
 | 
| 
bsw@1496
 | 
   230       end
 | 
| 
bsw@1496
 | 
   231     end
 | 
| 
bsw@1496
 | 
   232 
 | 
| 
bsw@1496
 | 
   233     if param.get("polling", atom.boolean) and app.session.member:has_polling_right_for_unit_id(area.unit_id) then
 | 
| 
bsw@1496
 | 
   234       initiative.polling = true
 | 
| 
bsw@1496
 | 
   235     end
 | 
| 
bsw@1496
 | 
   236     initiative.issue_id = issue.id
 | 
| 
bsw@1496
 | 
   237     initiative.name = name
 | 
| 
bsw@1496
 | 
   238     initiative:save()
 | 
| 
bsw@1496
 | 
   239 
 | 
| 
bsw@1496
 | 
   240     new_initiative = initiative
 | 
| 
bsw@1496
 | 
   241 
 | 
| 
bsw@1496
 | 
   242     local draft = Draft:new()
 | 
| 
bsw@1496
 | 
   243     draft.initiative_id = initiative.id
 | 
| 
bsw@1496
 | 
   244     draft.formatting_engine = formatting_engine
 | 
| 
bsw@1496
 | 
   245     draft.content = draft_text
 | 
| 
bsw@1496
 | 
   246     draft.location = location
 | 
| 
bsw@1496
 | 
   247     draft.author_id = app.session.member.id
 | 
| 
bsw@1496
 | 
   248     draft:save()
 | 
| 
bsw@1496
 | 
   249 
 | 
| 
bsw@1496
 | 
   250     draft_id = draft.id
 | 
| 
bsw@1496
 | 
   251 
 | 
| 
bsw@1496
 | 
   252     local initiator = Initiator:new()
 | 
| 
bsw@1496
 | 
   253     initiator.initiative_id = initiative.id
 | 
| 
bsw@1496
 | 
   254     initiator.member_id = app.session.member.id
 | 
| 
bsw@1496
 | 
   255     initiator.accepted = true
 | 
| 
bsw@1496
 | 
   256     initiator:save()
 | 
| 
bsw@1496
 | 
   257 
 | 
| 
bsw@1496
 | 
   258     if not is_polling then
 | 
| 
bsw@1496
 | 
   259       local supporter = Supporter:new()
 | 
| 
bsw@1496
 | 
   260       supporter.initiative_id = initiative.id
 | 
| 
bsw@1496
 | 
   261       supporter.member_id = app.session.member.id
 | 
| 
bsw@1496
 | 
   262       supporter.draft_id = draft.id
 | 
| 
bsw@1496
 | 
   263       supporter:save()
 | 
| 
bsw@1496
 | 
   264     end
 | 
| 
bsw@1496
 | 
   265 
 | 
| 
bsw/jbe@1309
 | 
   266   end
 | 
| 
bsw@1496
 | 
   267   status = donew()
 | 
| 
bsw/jbe@1309
 | 
   268 end
 | 
| 
bsw/jbe@1309
 | 
   269 
 | 
| 
bsw@1495
 | 
   270 if config.attachments then
 | 
| 
bsw@1495
 | 
   271   local file_upload_session = param.get("file_upload_session")
 | 
| 
bsw@1495
 | 
   272   file_upload_session = string.gsub(file_upload_session, "[^A-Za-z0-9]", "")
 | 
| 
bsw@1495
 | 
   273   local file_uploads = json.array()
 | 
| 
bsw@1495
 | 
   274   local filename = encode.file_path(WEBMCP_BASE_PATH, 'tmp', "file_upload-" .. file_upload_session .. ".json")
 | 
| 
bsw@1495
 | 
   275   local fh = io.open(filename, "r")
 | 
| 
bsw@1495
 | 
   276   if fh then
 | 
| 
bsw@1495
 | 
   277     file_uploads = json.import(fh:read("*a"))
 | 
| 
bsw@1495
 | 
   278   end
 | 
| 
bsw@1495
 | 
   279   for i, file_upload in ipairs(file_uploads) do
 | 
| 
bsw@1495
 | 
   280     if param.get("file_upload_delete_" .. file_upload.id, atom.boolean) then
 | 
| 
bsw@1495
 | 
   281       for j = i, #file_uploads - 1 do
 | 
| 
bsw@1495
 | 
   282         file_uploads[j] = file_uploads[j+1]
 | 
| 
bsw@1495
 | 
   283       end
 | 
| 
bsw@1495
 | 
   284       file_uploads[#file_uploads] = nil
 | 
| 
bsw@1495
 | 
   285     end
 | 
| 
bsw@1495
 | 
   286   end
 | 
| 
bsw@1495
 | 
   287   local convert_func = config.attachments.convert_func
 | 
| 
bsw@1495
 | 
   288   local last_id = param.get("file_upload_last_id", atom.number)
 | 
| 
bsw@1495
 | 
   289   if last_id and last_id > 0 then
 | 
| 
bsw@1495
 | 
   290     if last_id > 1024 then
 | 
| 
bsw@1495
 | 
   291       last_id = 1024
 | 
| 
bsw@1495
 | 
   292     end
 | 
| 
bsw@1495
 | 
   293     for i = 1, last_id do
 | 
| 
bsw@1495
 | 
   294       local file = param.get("file_" .. i)
 | 
| 
bsw@1495
 | 
   295       if file and #file > 0 then
 | 
| 
bsw@1495
 | 
   296         local id = multirand.string(
 | 
| 
bsw@1495
 | 
   297           32,
 | 
| 
bsw@1495
 | 
   298           '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
 | 
| 
bsw@1495
 | 
   299         )
 | 
| 
bsw@1495
 | 
   300         local data, err, status = convert_func(file)
 | 
| 
bsw@1495
 | 
   301         if status ~= 0 or data == nil then
 | 
| 
bsw@1495
 | 
   302           slot.put_into("error", _"Error while converting image. Please note, that only JPG files are supported!")
 | 
| 
bsw@1495
 | 
   303           return false
 | 
| 
bsw@1495
 | 
   304         end
 | 
| 
bsw@1495
 | 
   305         local filename = encode.file_path(WEBMCP_BASE_PATH, 'tmp', "file_upload-" .. file_upload_session .. "-" .. id .. ".jpg")
 | 
| 
bsw@1495
 | 
   306         local fh = assert(io.open(filename, "w"))
 | 
| 
bsw@1495
 | 
   307         fh:write(file)
 | 
| 
bsw@1495
 | 
   308         fh:write("\n")
 | 
| 
bsw@1495
 | 
   309         fh:close()
 | 
| 
bsw@1495
 | 
   310         local filename = encode.file_path(WEBMCP_BASE_PATH, 'tmp', "file_upload-" .. file_upload_session .. "-" .. id .. ".preview.jpg")
 | 
| 
bsw@1495
 | 
   311         local fh = assert(io.open(filename, "w"))
 | 
| 
bsw@1495
 | 
   312         fh:write(data)
 | 
| 
bsw@1495
 | 
   313         fh:write("\n")
 | 
| 
bsw@1495
 | 
   314         fh:close()
 | 
| 
bsw@1495
 | 
   315         table.insert(file_uploads, json.object{
 | 
| 
bsw@1495
 | 
   316           id = id,
 | 
| 
bsw@1495
 | 
   317           filename = filename,
 | 
| 
bsw@1495
 | 
   318           title = param.get("title_" .. i),
 | 
| 
bsw@1495
 | 
   319           description = param.get("description_" .. i)
 | 
| 
bsw@1495
 | 
   320         })
 | 
| 
bsw@1495
 | 
   321       end
 | 
| 
bsw@1495
 | 
   322     end
 | 
| 
bsw@1495
 | 
   323   end
 | 
| 
bsw@1495
 | 
   324   local filename = encode.file_path(WEBMCP_BASE_PATH, 'tmp', "file_upload-" .. file_upload_session .. ".json")
 | 
| 
bsw@1495
 | 
   325   local fh = assert(io.open(filename, "w"))
 | 
| 
bsw@1495
 | 
   326   fh:write(json.export(file_uploads))
 | 
| 
bsw@1495
 | 
   327   fh:write("\n")
 | 
| 
bsw@1495
 | 
   328   fh:close()
 | 
| 
bsw@1496
 | 
   329 
 | 
| 
bsw@1496
 | 
   330   if draft_id then
 | 
| 
bsw@1496
 | 
   331     local file_upload_session = param.get("file_upload_session")
 | 
| 
bsw@1496
 | 
   332     file_upload_session = string.gsub(file_upload_session, "[^A-Za-z0-9]", "")
 | 
| 
bsw@1495
 | 
   333 
 | 
| 
bsw@1496
 | 
   334     local draft_attachments = DraftAttachment:new_selector()
 | 
| 
bsw@1496
 | 
   335       :add_where{ "draft_attachment.draft_id = ?", draft_id }
 | 
| 
bsw@1496
 | 
   336       :exec()
 | 
| 
bsw@1496
 | 
   337 
 | 
| 
bsw@1496
 | 
   338     for i, draft_attachment in ipairs(draft_attachments) do
 | 
| 
bsw@1496
 | 
   339       if param.get("file_delete_" .. draft_attachment.file_id, atom.boolean) then
 | 
| 
bsw@1496
 | 
   340         draft_attachment:destroy()
 | 
| 
bsw@1496
 | 
   341       end
 | 
| 
bsw@1496
 | 
   342     end
 | 
| 
bsw@1495
 | 
   343 
 | 
| 
bsw@1496
 | 
   344     local file_uploads = json.array()
 | 
| 
bsw@1496
 | 
   345     local filename = encode.file_path(WEBMCP_BASE_PATH, 'tmp', "file_upload-" .. file_upload_session .. ".json")
 | 
| 
bsw@1496
 | 
   346     local fh = io.open(filename, "r")
 | 
| 
bsw@1496
 | 
   347     if fh then
 | 
| 
bsw@1496
 | 
   348       file_uploads = json.import(fh:read("*a"))
 | 
| 
bsw@1496
 | 
   349     end
 | 
| 
bsw@1496
 | 
   350     for i, file_upload in ipairs(file_uploads) do
 | 
| 
bsw@1496
 | 
   351       local filename = encode.file_path(WEBMCP_BASE_PATH, 'tmp', "file_upload-" .. file_upload_session .. "-" .. file_upload.id .. ".jpg")
 | 
| 
bsw@1496
 | 
   352       local data
 | 
| 
bsw@1496
 | 
   353       local fh = io.open(filename, "r")
 | 
| 
bsw@1496
 | 
   354       if fh then
 | 
| 
bsw@1496
 | 
   355         data = fh:read("*a")
 | 
| 
bsw@1496
 | 
   356       end
 | 
| 
bsw@1496
 | 
   357       local filename = encode.file_path(WEBMCP_BASE_PATH, 'tmp', "file_upload-" .. file_upload_session .. "-" .. file_upload.id .. ".preview.jpg")
 | 
| 
bsw@1496
 | 
   358       local data_preview
 | 
| 
bsw@1496
 | 
   359       local fh = io.open(filename, "r")
 | 
| 
bsw@1496
 | 
   360       if fh then
 | 
| 
bsw@1496
 | 
   361         data_preview = fh:read("*a")
 | 
| 
bsw@1496
 | 
   362       end
 | 
| 
bsw@1496
 | 
   363 
 | 
| 
bsw@1496
 | 
   364       local hash = moonhash.sha3_512(data)
 | 
| 
bsw@1495
 | 
   365 
 | 
| 
bsw@1496
 | 
   366       local file = File:new_selector()
 | 
| 
bsw@1496
 | 
   367         :add_where{ "hash = ?", hash }
 | 
| 
bsw@1496
 | 
   368         :add_where{ "content_type = ?", "image/jpeg" }
 | 
| 
bsw@1496
 | 
   369         :optional_object_mode()
 | 
| 
bsw@1496
 | 
   370         :exec()
 | 
| 
bsw@1495
 | 
   371 
 | 
| 
bsw@1496
 | 
   372       if not file then
 | 
| 
bsw@1496
 | 
   373         file = File:new()
 | 
| 
bsw@1496
 | 
   374         file.content_type = "image/jpeg"
 | 
| 
bsw@1496
 | 
   375         file.hash = hash
 | 
| 
bsw@1496
 | 
   376         file.data = data
 | 
| 
bsw@1496
 | 
   377         file.preview_content_type = "image/jpeg"
 | 
| 
bsw@1496
 | 
   378         file.preview_data = data_preview
 | 
| 
bsw@1496
 | 
   379         file:save()
 | 
| 
bsw@1496
 | 
   380       end
 | 
| 
bsw@1496
 | 
   381 
 | 
| 
bsw@1496
 | 
   382       local draft_attachment = DraftAttachment:new()
 | 
| 
bsw@1496
 | 
   383       draft_attachment.draft_id = draft_id
 | 
| 
bsw@1496
 | 
   384       draft_attachment.file_id = file.id
 | 
| 
bsw@1496
 | 
   385       draft_attachment.title = file_upload.title
 | 
| 
bsw@1496
 | 
   386       draft_attachment.description = file_upload.description
 | 
| 
bsw@1496
 | 
   387       draft_attachment:save()
 | 
| 
bsw@1495
 | 
   388     end
 | 
| 
bsw@1495
 | 
   389   end
 | 
| 
bsw@1495
 | 
   390 
 | 
| 
bsw@1495
 | 
   391 end
 | 
| 
bsw@1495
 | 
   392 
 | 
| 
bsw@1496
 | 
   393 if new_initiative and status ~= false then
 | 
| 
bsw@1535
 | 
   394   local callback = param.get("callback")
 | 
| 
bsw@1535
 | 
   395   if config.allow_new_draft_callback and callback then
 | 
| 
bsw@1535
 | 
   396     request.redirect{ external = callback }
 | 
| 
bsw@1535
 | 
   397   else
 | 
| 
bsw@1535
 | 
   398     request.redirect{
 | 
| 
bsw@1535
 | 
   399       module = "initiative",
 | 
| 
bsw@1535
 | 
   400       view = "show",
 | 
| 
bsw@1535
 | 
   401       id = new_initiative.id
 | 
| 
bsw@1535
 | 
   402     }
 | 
| 
bsw@1535
 | 
   403   end
 | 
| 
bsw@1496
 | 
   404 end
 | 
| 
bsw@1496
 | 
   405 
 | 
| 
bsw@1496
 | 
   406 return status
 | 
| 
bsw@1496
 | 
   407 
 |