Fixing bad library paths (using Fabian's local paths).

Fixed response building for /upload/
Added /upload/{filename} .
Added CMS_FILE_UPLOAD_API.

The storage/database part is untouched (and thus not implemented).
This commit is contained in:
2016-01-20 13:43:49 +01:00
parent 4b04e5f471
commit 53181f901d
12 changed files with 570 additions and 376 deletions

View File

@@ -26,6 +26,7 @@
<library name="cms_demo_module" location="modules\demo\cms_demo_module-safe.ecf" readonly="false"/> <library name="cms_demo_module" location="modules\demo\cms_demo_module-safe.ecf" readonly="false"/>
<library name="cms_email_service" location="..\..\library\email\email-safe.ecf" readonly="false"/> <library name="cms_email_service" location="..\..\library\email\email-safe.ecf" readonly="false"/>
<library name="cms_feed_aggregator_module" location="..\..\modules\feed_aggregator\feed_aggregator-safe.ecf" readonly="false"/> <library name="cms_feed_aggregator_module" location="..\..\modules\feed_aggregator\feed_aggregator-safe.ecf" readonly="false"/>
<library name="cms_file_uploader" location="..\..\modules\file_upload\file_uploader.ecf" readonly="false"/>
<library name="cms_google_search_module" location="..\..\modules\google_search\google_search-safe.ecf" readonly="false" use_application_options="true"/> <library name="cms_google_search_module" location="..\..\modules\google_search\google_search-safe.ecf" readonly="false" use_application_options="true"/>
<library name="cms_model" location="..\..\library\model\cms_model-safe.ecf" readonly="false"/> <library name="cms_model" location="..\..\library\model\cms_model-safe.ecf" readonly="false"/>
<library name="cms_node_module" location="..\..\modules\node\node-safe.ecf" readonly="false"/> <library name="cms_node_module" location="..\..\modules\node\node-safe.ecf" readonly="false"/>
@@ -54,7 +55,6 @@
</option> </option>
<setting name="concurrency" value="scoop"/> <setting name="concurrency" value="scoop"/>
<variable name="httpd_ssl_disabled" value="true"/> <variable name="httpd_ssl_disabled" value="true"/>
<library name="file_uploader" location="\home\fmurer\Documents\EWF_ROC\ROC\modules\file_upload\file_uploader.ecf"/>
<library name="standalone_launcher" location="..\..\launcher\standalone-safe.ecf" readonly="false"/> <library name="standalone_launcher" location="..\..\launcher\standalone-safe.ecf" readonly="false"/>
<cluster name="src" location=".\src\" recursive="true"/> <cluster name="src" location=".\src\" recursive="true"/>
</target> </target>

View File

@@ -1,82 +0,0 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-15-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-15-0 http://www.eiffel.com/developers/xml/configuration-1-15-0.xsd" name="demo" uuid="3643E657-BCBE-46AA-931B-71EAEA877A18" library_target="demo">
<description>Example/demo for Eiffel ROC CMS library</description>
<target name="common" abstract="true">
<root class="DEMO_CMS_SERVER" feature="make_and_launch"/>
<file_rule>
<exclude>/.svn$</exclude>
<exclude>/CVS$</exclude>
<exclude>/EIFGENs$</exclude>
</file_rule>
<option debug="true" warning="true" full_class_checking="false" is_attached_by_default="true" is_obsolete_routine_type="true" void_safety="all" syntax="transitional">
<debug name="dbglog" enabled="true"/>
</option>
<setting name="concurrency" value="thread"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="cms" location="..\..\cms-safe.ecf" readonly="false">
<option>
<assertions precondition="true" postcondition="true" supplier_precondition="true"/>
</option>
</library>
<library name="cms_admin_module" location="..\..\modules\admin\admin-safe.ecf" readonly="false"/>
<library name="cms_app_env" location="..\..\library\app_env\app_env-safe.ecf" readonly="false"/>
<library name="cms_auth_module" location="..\..\modules\auth\auth-safe.ecf" readonly="false"/>
<library name="cms_basic_auth_module" location="..\..\modules\basic_auth\basic_auth-safe.ecf" readonly="false"/>
<library name="cms_blog_module" location="..\..\modules\blog\cms_blog_module-safe.ecf" readonly="false"/>
<library name="cms_demo_module" location="modules\demo\cms_demo_module-safe.ecf" readonly="false"/>
<library name="cms_email_service" location="..\..\library\email\email-safe.ecf" readonly="false"/>
<library name="cms_feed_aggregator_module" location="..\..\modules\feed_aggregator\feed_aggregator-safe.ecf" readonly="false"/>
<library name="cms_google_search_module" location="..\..\modules\google_search\google_search-safe.ecf" readonly="false" use_application_options="true"/>
<library name="cms_model" location="..\..\library\model\cms_model-safe.ecf" readonly="false"/>
<library name="cms_node_module" location="..\..\modules\node\node-safe.ecf" readonly="false"/>
<library name="cms_oauth_20_module" location="..\..\modules\oauth20\oauth20-safe.ecf" readonly="false"/>
<library name="cms_openid_module" location="..\..\modules\openid\openid-safe.ecf" readonly="false"/>
<library name="cms_recent_changes_module" location="..\..\modules\recent_changes\recent_changes-safe.ecf" readonly="false"/>
<library name="cms_session_auth_module" location="..\..\modules\session_auth\cms_session_auth-safe.ecf" readonly="false"/>
<library name="cms_taxnomy_module" location="..\..\modules\taxonomy\taxonomy-safe.ecf" readonly="false"/>
<library name="persistence_sqlite3" location="..\..\library\persistence\sqlite3\sqlite3-safe.ecf" readonly="false">
<option>
<assertions/>
</option>
</library>
<library name="persistence_store_odbc" location="..\..\library\persistence\store_odbc\store_odbc-safe.ecf"/>
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
<library name="wsf_extension" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf_extension-safe.ecf" readonly="false"/>
</target>
<target name="demo_any" extends="common">
<setting name="concurrency" value="thread"/>
<library name="any_launcher" location="..\..\launcher\any-safe.ecf" readonly="false"/>
<cluster name="src" location=".\src\" recursive="true"/>
</target>
<target name="demo_standalone" extends="common">
<option debug="true">
<debug name="dbglog" enabled="true"/>
</option>
<setting name="concurrency" value="scoop"/>
<variable name="httpd_ssl_disabled" value="true"/>
<library name="file_uploader" location="\home\fmurer\Documents\EWF_ROC\ROC\modules\file_upload\file_uploader.ecf"/>
<library name="standalone_launcher" location="..\..\launcher\standalone-safe.ecf" readonly="false"/>
<cluster name="src" location=".\src\" recursive="true"/>
</target>
<target name="demo_standalone_none" extends="demo_standalone">
<setting name="concurrency" value="none"/>
</target>
<target name="demo_standalone_mt" extends="demo_standalone">
<setting name="concurrency" value="thread"/>
</target>
<target name="demo_standalone_scoop" extends="demo_standalone">
<setting name="concurrency" value="scoop"/>
</target>
<target name="demo_cgi" extends="common">
<setting name="concurrency" value="none"/>
<library name="cgi_launcher" location="..\..\launcher\cgi-safe.ecf" readonly="false"/>
<cluster name="src" location=".\src\" recursive="true"/>
</target>
<target name="demo_libfcgi" extends="common">
<setting name="concurrency" value="none"/>
<library name="libfcgi_launcher" location="..\..\launcher\libfcgi-safe.ecf" readonly="false"/>
<cluster name="src" location=".\src\" recursive="true"/>
</target>
<target name="demo" extends="demo_standalone">
</target>
</system>

View File

@@ -1,3 +0,0 @@
port=9090
#port=12345
#verbose=true

View File

@@ -1,15 +0,0 @@
setlocal
set ROC_CMD=call %~dp0..\..\tools\roc.bat
set ROC_CMS_DIR=%~dp0
%ROC_CMD% install --module ..\..\modules\admin --dir %ROC_CMS_DIR%
%ROC_CMD% install --module ..\..\modules\auth --dir %ROC_CMS_DIR%
%ROC_CMD% install --module ..\..\modules\basic_auth --dir %ROC_CMS_DIR%
%ROC_CMD% install --module ..\..\modules\blog --dir %ROC_CMS_DIR%
%ROC_CMD% install --module ..\..\modules\node --dir %ROC_CMS_DIR%
%ROC_CMD% install --module ..\..\modules\oauth20 --dir %ROC_CMS_DIR%
%ROC_CMD% install --module ..\..\modules\openid --dir %ROC_CMS_DIR%
%ROC_CMD% install --module ..\..\modules\recent_changes --dir %ROC_CMS_DIR%
%ROC_CMD% install --module ..\..\modules\feed_aggregator --dir %ROC_CMS_DIR%
%ROC_CMD% install --module ..\..\modules\google_search --dir %ROC_CMS_DIR%
%ROC_CMD% install --module ..\..\modules\taxonomy --dir %ROC_CMS_DIR%

View File

@@ -94,7 +94,7 @@ feature -- CMS modules
a_setup.register_module (m) a_setup.register_module (m)
-- uploader -- uploader
create {CMS_FILE_UPLOAD} m.make create {CMS_FILE_UPLOADER_MODULE} m.make
a_setup.register_module (m) a_setup.register_module (m)
end end

View File

@@ -0,0 +1,69 @@
note
description: "Interface representing any files under `{CMS_API}.files_location' ."
date: "$Date$"
revision: "$Revision$"
class
CMS_FILE
create
make
feature {NONE} -- Initializaion
make (a_relative_path: PATH; a_api: CMS_API)
do
cms_api := a_api
location := a_relative_path
end
cms_api: CMS_API
feature -- Access
filename: STRING_32
-- File name of Current file.
local
p: PATH
do
p := location
if attached p.entry as e then
Result := e.name
else
Result := p.name
end
end
location: PATH
-- Path relative the `CMS_API.files_location'.
owner: detachable CMS_USER
-- Optional owner.
feature -- Status report
is_directory: BOOLEAN
local
d: DIRECTORY
do
create d.make_with_path (cms_api.files_location.extended_path (location))
Result := d.exists
end
is_file: BOOLEAN
local
f: RAW_FILE
do
create f.make_with_path (cms_api.files_location.extended_path (location))
Result := f.exists
end
feature -- Element change
set_owner (u: detachable CMS_USER)
-- Set `owner' to `u'.
do
owner := u
end
end

View File

@@ -1,248 +0,0 @@
note
description: "file_upload application root class"
date: "$Date$"
revision: "$Revision$"
class
CMS_FILE_UPLOAD
inherit
CMS_MODULE
redefine
install,
initialize,
setup_hooks,
permissions
end
CMS_HOOK_BLOCK
CMS_HOOK_MENU_SYSTEM_ALTER
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
permissions: LIST [READABLE_STRING_8]
-- List of permission ids, used by this module, and declared.
do
Result := Precursor
Result.force ("manage admin")
Result.force ("admin users")
Result.force ("admin roles")
Result.force ("admin modules")
Result.force ("install modules")
Result.force ("admin core caches")
Result.force ("clear blocks cache")
Result.force ("admin export")
Result.force ("export core")
Result.force ("upload files")
end
feature {CMS_API} -- Module Initialization
initialize (api: CMS_API)
-- <Precursor>
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)
-- <Precursor>
local
www: WSF_FILE_SYSTEM_HANDLER
do
map_uri_template_agent (a_router, "/upload/", agent execute_upload, 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">>
end
get_block_view (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE)
local
menu: CMS_MENU
menu_block: CMS_MENU_BLOCK
menu_entries_count: INTEGER
do
if a_block_id.same_string ("uploader") then
-- create menu_block.make ({CMS_MENU_SYSTEM}.primary_menu)
-- a_response.add_block (menu_block, "page_top")
end
end
menu_system_alter (a_menu_system: CMS_MENU_SYSTEM; a_response: CMS_RESPONSE)
local
link: CMS_LOCAL_LINK
second_link: CMS_LOCAL_LINK
do
-- login in demo did somehow not work
-- if a_response.has_permission ("upload files") then
create link.make ("Upload", "upload/")
a_menu_system.primary_menu.extend (link)
-- end
end
feature -- Configuration
document_root: PATH
-- Document root to look for files or directories
once
Result := execution_environment.current_working_path.extended ("site")
end
files_root: PATH
-- Uploaded files will be stored in `files_root' folder
local
tmp: PATH
once
tmp := document_root.extended ("files")
Result := tmp.extended ("uploaded_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 (req: WSF_REQUEST; res: WSF_RESPONSE)
local
body: STRING_8
do
-- create body
create body.make_empty
body.append ("<h1> EWF: Upload files </h1>%N")
body.append ("<p>Please choose some file(s) to upload.</p>")
-- create form to choose files and upload them
body.append ("<form action=%"" + req.script_url ("/upload/") + "%" enctype=%"multipart/form-data%" method=%"POST%"> %N")
body.append ("<input name=%"file-name[]%" type=%"file%" multiple> %N")
body.append ("<button type=submit>Upload</button>%N")
body.append ("</form>%N")
-- put the body to the response
res.put_string (body)
show_and_store_files (req, res)
end
show_and_store_files (req: WSF_REQUEST; res: WSF_RESPONSE)
-- show all uploaded files
local
file_path: PATH
file_name: STRING_8
stored: BOOLEAN
file_system_handler: WSF_FILE_SYSTEM_HANDLER
file_system_upload_handler: CMS_FILE_UPLOAD_FILE_SYSTEM_HANDLER
uploaded_file: CMS_FILE_UPLOAD_FILE
do
-- if has uploaded files, then store them
if req.has_uploaded_file then
across
req.uploaded_files as uf
loop
file_name := uf.item.safe_filename
-- check if file is already in folder
if not files_root.has_extension (file_name) then
file_path := files_root.extended (file_name)
-- move file to path
stored := uf.item.move_to(file_path.name)
end
end
end
-- create file_system_handler and show the uploaded files
create file_system_handler.make_with_path (document_root)
file_system_handler.enable_index
file_system_handler.process_index ("/uploaded_files", files_root, req, res)
end
feature -- Mapping helper: uri template agent (analogue to the demo-module)
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

View File

@@ -9,26 +9,35 @@ class
inherit inherit
WSF_UPLOADED_FILE WSF_UPLOADED_FILE
redefine rename
name make as make_uploaded_file,
name as uploaded_file_name,
change_name as change_uploaded_file_name,
is_empty as is_empty_uploaded_file,
exists as uploaded_file_exists
end end
RAW_FILE RAW_FILE
undefine rename
make, change_name, is_empty, exists make as make_file
end end
-- undefine
-- make, change_name, is_empty, exists
-- end
create create
make_new, make
make_with_path
feature -- Initialization feature -- Initialization
make_new (a_name: READABLE_STRING_GENERAL; a_filename: READABLE_STRING_GENERAL; a_content_type: like content_type; a_size: like size; a_user: CMS_USER) make (a_name: READABLE_STRING_GENERAL; a_filename: READABLE_STRING_GENERAL; a_content_type: like content_type; a_size: like size; a_user: CMS_USER)
local local
time: DATE_TIME time: DATE_TIME
do do
new_name := a_name.as_string_32 make_uploaded_file (a_name, a_filename, a_content_type, a_size)
make_with_name (a_filename)
uploaded_file_name := a_name.as_string_32
url_encoded_name := url_encoded_string (a_name) url_encoded_name := url_encoded_string (a_name)
filename := a_filename.as_string_32 filename := a_filename.as_string_32
content_type := a_content_type content_type := a_content_type

View File

@@ -0,0 +1,78 @@
note
description: "API to manage files."
date: "$Date$"
revision: "$Revision$"
class
CMS_FILE_UPLOADER_API
inherit
CMS_MODULE_API
REFACTORING_HELPER
create
make
feature -- Access
uploads_directory_name: STRING = "uploaded_files"
uploads_location: PATH
do
Result := cms_api.files_location.extended (uploads_directory_name)
end
file_link (f: CMS_FILE): CMS_LOCAL_LINK
local
s: STRING
do
s := "files"
across
f.location.components as ic
loop
s.append_character ('/')
s.append (percent_encoded (ic.item.name))
end
create Result.make (f.filename, s)
end
feature -- Factory
new_file (p: PATH): CMS_FILE
do
create Result.make (p, cms_api)
end
new_uploads_file (p: PATH): CMS_FILE
-- New uploaded path from `p' related to `uploads_location'.
do
create Result.make ((create {PATH}.make_from_string (uploads_directory_name)).extended_path (p), cms_api)
end
feature -- Storage
save_uploaded_file (f: CMS_UPLOADED_FILE)
local
p: PATH
ut: FILE_UTILITIES
stored: BOOLEAN
do
p := f.location
if p.is_absolute then
else
p := uploads_location.extended_path (p)
end
if ut.file_path_exists (p) then
-- FIXME: find an alternative name for it, by appending "-" + i.out , with i: INTEGER;
error_handler.add_custom_error (-1, "uploaded file storage failed", "A file with same name already exists!")
else
-- move file to path
stored := f.move_to (p)
if not stored then
error_handler.add_custom_error (-1, "uploaded file storage failed", "Issue occurred when saving uploaded file!")
end
end
end
end

View File

@@ -0,0 +1,332 @@
note
description: "file_upload application root class"
date: "$Date$"
revision: "$Revision$"
class
CMS_FILE_UPLOADER_MODULE
inherit
CMS_MODULE
rename
module_api as file_upload_api
redefine
install,
initialize,
setup_hooks,
permissions,
file_upload_api
end
CMS_HOOK_MENU_SYSTEM_ALTER
SHARED_EXECUTION_ENVIRONMENT
create
make
feature {NONE} -- Initialization
make
do
name := "file_uploader"
version := "1.0"
description := "Service to upload files, and manage them."
package := "file"
end
feature -- Access
name: STRING
permissions: LIST [READABLE_STRING_8]
-- List of permission ids, used by this module, and declared.
do
Result := Precursor
Result.force ("admin uploaded files")
Result.force ("upload files")
end
feature {CMS_API} -- Module Initialization
initialize (api: CMS_API)
-- <Precursor>
do
Precursor (api)
if file_upload_api = Void then
create file_upload_api.make (api)
end
end
feature {CMS_API}-- Module management
install (api: CMS_API)
-- install the module
local
sql: STRING
l_file_upload_api: like file_upload_api
d: DIRECTORY
do
-- create a database table
if attached {CMS_STORAGE_SQL_I} api.storage as l_sql_storage then
-- FIXME: This is not used, is it planned in the future?
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
end
create l_file_upload_api.make (api)
create d.make_with_path (l_file_upload_api.uploads_location)
if not d.exists then
d.recursive_create_dir
end
file_upload_api := l_file_upload_api
Precursor (api)
end
feature {CMS_API} -- Access: API
file_upload_api: detachable CMS_FILE_UPLOADER_API
-- <Precursor>
feature -- Access: router
setup_router (a_router: WSF_ROUTER; a_api: CMS_API)
-- <Precursor>
local
-- www: WSF_FILE_SYSTEM_HANDLER
do
map_uri_template_agent (a_router, "/upload/", agent execute_upload (?, ?, a_api), Void) -- Accepts any method GET, HEAD, POST, PUT, DELETE, ...
map_uri_template_agent (a_router, "/upload/{filename}", agent display_uploaded_file_info (?, ?, a_api), a_router.methods_get)
-- 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)
end
menu_system_alter (a_menu_system: CMS_MENU_SYSTEM; a_response: CMS_RESPONSE)
local
link: CMS_LOCAL_LINK
do
-- login in demo did somehow not work
-- if a_response.has_permission ("upload files") then
create link.make ("Upload", "upload/")
a_menu_system.primary_menu.extend (link)
-- end
end
--feature -- Configuration
-- document_root: PATH
-- -- Document root to look for files or directories
-- once
-- Result := execution_environment.current_working_path.extended ("site")
-- end
-- files_root: PATH
-- -- Uploaded files will be stored in `files_root' folder
-- local
-- tmp: PATH
-- once
-- tmp := document_root.extended ("files")
-- Result := tmp.extended ("uploaded_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
display_uploaded_file_info (req: WSF_REQUEST; res: WSF_RESPONSE; api: CMS_API)
local
body: STRING_8
r: CMS_RESPONSE
f: CMS_FILE
fn: READABLE_STRING_32
do
check req.is_get_request_method end
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
create body.make_empty
if attached {WSF_STRING} req.path_parameter ("filename") as p_filename then
fn := p_filename.value
body.append ("<h1>File %"" + api.html_encoded (fn) + "%"</h1>%N")
body.append ("<div class=%"uploaded-file%">%N") -- To ease css customization.
if attached file_upload_api as l_file_upload_api then
f := l_file_upload_api.new_uploads_file (create {PATH}.make_from_string (fn))
-- FIXME: get CMS information related to this file ...
body.append ("<p>Open the media <a href=%"" + req.script_url ("/" + l_file_upload_api.file_link (f).location) + "%">")
body.append (api.html_encoded (f.filename))
body.append ("</a>.</p>%N")
if attached f.location.extension as ext then
if
ext.is_case_insensitive_equal_general ("png")
or ext.is_case_insensitive_equal_general ("jpg")
then
body.append ("<div><img src=%"" + req.script_url ("/" + l_file_upload_api.file_link (f).location) + "%" /></div>")
end
end
end
body.append ("%N</div>%N")
end
r.add_to_primary_tabs (create {CMS_LOCAL_LINK}.make ("Uploaded files", "upload/"))
r.set_main_content (body)
r.execute
end
execute_upload (req: WSF_REQUEST; res: WSF_RESPONSE; api: CMS_API)
local
body: STRING_8
r: CMS_RESPONSE
do
if req.is_get_head_request_method or req.is_post_request_method then
-- create body
create body.make_empty
body.append ("<h1> Upload files </h1>%N")
body.append ("<p>Please choose some file(s) to upload.</p>")
-- create form to choose files and upload them
body.append ("<form action=%"" + req.script_url ("/upload/") + "%" enctype=%"multipart/form-data%" method=%"POST%"> %N")
body.append ("<input name=%"file-name[]%" type=%"file%" multiple> %N")
body.append ("<button type=submit>Upload</button>%N")
body.append ("</form>%N")
if req.is_post_request_method then
process_uploaded_files (req, api, body)
end
-- Build the response.
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
append_uploaded_file_album_to (req, api, body)
r.set_main_content (body)
else
create {BAD_REQUEST_ERROR_CMS_RESPONSE} r.make (req, res, api)
end
r.execute
end
process_uploaded_files (req: WSF_REQUEST; api: CMS_API; a_output: STRING)
-- show all uploaded files
local
-- stored: BOOLEAN
-- file_system_handler: WSF_FILE_SYSTEM_HANDLER
-- file_system_upload_handler: CMS_FILE_UPLOAD_FILE_SYSTEM_HANDLER
l_uploaded_file: CMS_UPLOADED_FILE
uf: WSF_UPLOADED_FILE
-- ut: FILE_UTILITIES
-- files_root: PATH
do
if attached file_upload_api as l_file_upload_api then
-- if has uploaded files, then store them
if req.has_uploaded_file then
a_output.append ("<ul class=%"uploaded-files%"><strong>Uploaded file(s):</strong>%N")
across
req.uploaded_files as ic
loop
uf := ic.item
create l_uploaded_file.make_with_uploaded_file (l_file_upload_api.uploads_location, uf)
a_output.append ("<li>")
a_output.append (api.html_encoded (l_uploaded_file.filename))
l_file_upload_api.save_uploaded_file (l_uploaded_file)
-- FIXME: display for information, about the new disk filename.
if l_file_upload_api.error_handler.has_error then
a_output.append (" <span class=%"error%">failed!</span>")
end
a_output.append ("</li>")
end
a_output.append ("</ul>%N")
end
end
end
append_uploaded_file_album_to (req: WSF_REQUEST; api: CMS_API; a_output: STRING)
local
d: DIRECTORY
f: CMS_FILE
p: PATH
rel: PATH
do
if attached file_upload_api as l_file_upload_api then
create rel.make_from_string (l_file_upload_api.uploads_directory_name)
p := api.files_location.extended_path (rel)
a_output.append ("<ul class=%"directory-index%"><strong>Index of uploads:</strong>%N")
create d.make_with_path (p)
if d.exists then
across
d.entries as ic
loop
if ic.item.is_current_symbol then
-- Ignore
elseif ic.item.is_parent_symbol then
-- Ignore for now.
else
f := l_file_upload_api.new_file (rel.extended_path (ic.item))
if f.is_directory then
a_output.append ("<li class=%"directory%">")
else
a_output.append ("<li class=%"file%">")
end
a_output.append ("<a href=%"" + api.percent_encoded (f.filename) + "%">")
a_output.append (api.html_encoded (f.filename))
a_output.append ("</a>")
a_output.append ("( <a href=%"" + req.script_url ("/" + l_file_upload_api.file_link (f).location) + "%">")
a_output.append ("media</a>)")
a_output.append ("</li>%N")
end
end
end
a_output.append ("</ul>%N")
end
end
feature -- Mapping helper: uri template agent (analogue to the demo-module)
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

View File

@@ -0,0 +1,62 @@
note
description: "Summary description for {CMS_UPLOADED_FILE}."
date: "$Date$"
revision: "$Revision$"
class
CMS_UPLOADED_FILE
create
make_with_uploaded_file
feature {NONE} -- Initializaion
make_with_uploaded_file (a_uploads_location: PATH; uf: WSF_UPLOADED_FILE)
do
uploads_location := a_uploads_location
uploaded_file := uf
location := a_uploads_location.extended (uf.safe_filename)
end
feature -- Access
uploaded_file: WSF_UPLOADED_FILE
uploads_location: PATH
filename: STRING_32
-- File name of Current file.
local
p: PATH
do
p := location
if attached p.entry as e then
Result := e.name
else
Result := p.name
end
end
location: PATH
-- Absolute path, or relative path to the `CMS_API.files_location'.
owner: detachable CMS_USER
-- Optional owner.
feature -- Element change
set_owner (u: detachable CMS_USER)
-- Set `owner' to `u'.
do
owner := u
end
feature -- Basic operation
move_to (p: PATH): BOOLEAN
do
Result := uploaded_file.move_to (p.name)
end
end

View File

@@ -1,29 +1,21 @@
<?xml version="1.0" encoding="ISO-8859-1"?> <?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-15-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-15-0 http://www.eiffel.com/developers/xml/configuration-1-15-0.xsd" name="file_uploader" uuid="795C88E5-9218-4F35-A985-5501340E2D9D" library_target="file_uploader"> <system xmlns="http://www.eiffel.com/developers/xml/configuration-1-15-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-15-0 http://www.eiffel.com/developers/xml/configuration-1-15-0.xsd" name="file_uploader" uuid="795C88E5-9218-4F35-A985-5501340E2D9D" library_target="file_uploader">
<target name="file_uploader"> <target name="file_uploader">
<!-- <root class="CMS_FILE_UPLOAD" feature="make"/> -->
<root all_classes="true" /> <root all_classes="true" />
<!-- <option warning="true"> <file_rule>
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/> <exclude>/.svn$</exclude>
</option> --> <exclude>/CVS$</exclude>
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="standard"> <exclude>/EIFGENs$</exclude>
</option> </file_rule>
<setting name="console_application" value="true"/> <option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="standard"/>
<!-- <precompile name="base_pre" location="$ISE_PRECOMP\base-safe.ecf"/> -->
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="cms" location="\home\fmurer\Documents\EWF_ROC\ROC\cms-safe.ecf"/> <library name="cms" location="..\..\cms-safe.ecf"/>
<library name="cms_model" location="\home\fmurer\Documents\EWF_ROC\ROC\library\model\cms_model-safe.ecf"/> <library name="cms_model" location="..\..\library\model\cms_model-safe.ecf"/>
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/> <library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/>
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json-safe.ecf"/> <library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json-safe.ecf"/>
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/> <library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/> <library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
<library name="wsf_encoder" location="\home\fmurer\Documents\EWF_ROC\eiffelstudio-src\contrib\library\web\framework\ewf\text\encoder\encoder-safe.ecf"/> <library name="wsf_encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder-safe.ecf"/>
<cluster name="file_uploader" location=".\" recursive="true"> <cluster name="file_uploader" location=".\" recursive="true"/>
<file_rule>
<exclude>/.svn$</exclude>
<exclude>/CVS$</exclude>
<exclude>/EIFGENs$</exclude>
</file_rule>
</cluster>
</target> </target>
</system> </system>