note description: "file_upload application root class" date: "$Date$" revision: "$Revision$" class CMS_FILE_UPLOAD inherit CMS_MODULE redefine install, initialize, setup_hooks end CMS_HOOK_BLOCK CMS_HOOK_MENU_SYSTEM_ALTER -- WSF_ROUTED_URI_TEMPLATE_HELPER SHARED_EXECUTION_ENVIRONMENT create make feature {NONE} -- Initialization make do name := "file_uploader" version := "1.0" description := "Service to upload some files" package := "file upload" end feature -- Access name: STRING feature {CMS_API} -- Module Initialization initialize (api: CMS_API) -- do Precursor (api) end feature {CMS_API }-- Module management install (api: CMS_API) -- install the module local sql: STRING do -- create a database table if attached {CMS_STORAGE_SQL_I} api.storage as l_sql_storage then if not l_sql_storage.sql_table_exists ("file_upload_table") then sql := "[ CREATE TABLE file_upload_table( `id` INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL CHECK("id">=0), `name` VARCHAR(100) NOT NULL, `uploaded_date` DATE, `size` INTEGER ); ]" l_sql_storage.sql_execute_script (sql, Void) if l_sql_storage.has_error then api.logger.put_error ("Could not initialize database for file uploader module", generating_type) end end Precursor {CMS_MODULE}(api) end end feature -- Access: router setup_router (a_router: WSF_ROUTER; a_api: CMS_API) -- local www: WSF_FILE_SYSTEM_HANDLER do map_uri_template_agent (a_router, "/upload{?nb}", agent execute_upload_handler, void) create www.make_with_path (document_root) www.set_directory_index (<<"index.html">>) www.set_not_found_handler (agent execute_not_found_handler) a_router.handle("", www, a_router.methods_get) end feature -- Hooks setup_hooks (a_hooks: CMS_HOOK_CORE_MANAGER) do a_hooks.subscribe_to_menu_system_alter_hook (Current) a_hooks.subscribe_to_block_hook (Current) end block_list: ITERABLE [like {CMS_BLOCK}.name] do Result := <<"Uploader info TODO">> end get_block_view (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE) do end menu_system_alter (a_menu_system: CMS_MENU_SYSTEM; a_response: CMS_RESPONSE) local link: CMS_LOCAL_LINK do create link.make ("Upload", "/upload") a_menu_system.primary_menu.extend (link) end feature -- Configuration document_root: PATH -- Document root to look for files or directories once Result := execution_environment.current_working_path.extended ("docs") end files_root: PATH -- Uploaded files will be stored in `files_root' folder once Result := document_root.extended ("files") end feature -- Handler execute_not_found_handler (uri: READABLE_STRING_8; req: WSF_REQUEST; res: WSF_RESPONSE) -- `uri' is not found, redirect to default page do res.redirect_now_with_content (req.script_url ("/"), uri + ": not found. %N Redirectioin to" + req.script_url ("/"), "text/html") end execute_upload_handler(req: WSF_REQUEST; res: WSF_RESPONSE; a_api: CMS_API) local body: STRING_8 safe_filename: STRING_8 path: PATH page: WSF_HTML_PAGE_RESPONSE n: INTEGER do if req.is_request_method ("GET") or else not req.has_uploaded_file then create page.make page.set_title ("EWF: Upload file") page.add_style (req.script_url ("style.css"), "all") create body.make_empty page.set_body (body) -- create the body body.append ("

EWF: Upload files

%N") body.append ("
%N") -- tetermine how many files to upload by a query parameter ?nb=number_of_files if attached {WSF_STRING} req.query_parameter ("nb") as p_nb and then p_nb.is_integer then n := p_nb.integer_value else n := 1 end -- llist for the number of wanted files a upload button from until n = 0 loop body.append ("
%N") n := n-1 end -- set the submit button body.append ("%N") res.send (page) else create body.make_empty body.append ("

EWF: Uploaded files

%N") body.append ("
    %N") n := 0 across req.uploaded_files as u_file loop body.append ("
  • %N") body.append ("
    " + u_file.item.name + "=" + html_encode (u_file.item.filename) + " size=" + u_file.item.size.out + " type" + u_file.item.content_type + "
    %N") safe_filename := u_file.item.safe_filename path := files_root.extended (safe_filename) -- TODO: list dhe uploaded items body.append ("
  • %N") end body.append ("
%N") -- create page create page.make page.add_style ("../style.css", "all") page.set_body (body) res.send (page) end end feature {NONE} -- Encoder url_encode (s: READABLE_STRING_32): STRING_8 -- URL Encode `s' as Result do Result := url_encoder.encoded_string (s) end url_encoder: URL_ENCODER once create Result end html_encode (s: READABLE_STRING_32): STRING_8 -- HTML Encode `s' as Result do Result := html_encoder.encoded_string (s) end html_encoder: HTML_ENCODER once create Result end feature -- Mapping helper: uri template agent map_uri_template (a_router: WSF_ROUTER; a_tpl: STRING; h: WSF_URI_TEMPLATE_HANDLER; rqst_methods: detachable WSF_REQUEST_METHODS) -- Map `h' as handler for `a_tpl', according to `rqst_methods'. require a_tpl_attached: a_tpl /= Void h_attached: h /= Void do a_router.map (create {WSF_URI_TEMPLATE_MAPPING}.make (a_tpl, h), rqst_methods) end map_uri_template_agent (a_router: WSF_ROUTER; a_tpl: READABLE_STRING_8; proc: PROCEDURE [TUPLE [req: WSF_REQUEST; res: WSF_RESPONSE]]; rqst_methods: detachable WSF_REQUEST_METHODS) -- Map `proc' as handler for `a_tpl', according to `rqst_methods'. require a_tpl_attached: a_tpl /= Void proc_attached: proc /= Void do map_uri_template (a_router, a_tpl, create {WSF_URI_TEMPLATE_AGENT_HANDLER}.make (proc), rqst_methods) end end