Compare commits
19 Commits
es17.05
...
jfiat_2016
| Author | SHA1 | Date | |
|---|---|---|---|
| 9060025e1c | |||
| d18c7c9ad5 | |||
| e1d6e79f09 | |||
| 53181f901d | |||
|
|
4b04e5f471 | ||
|
|
e1a657a880 | ||
|
|
40fd1df648 | ||
|
|
ddb3f9474a | ||
|
|
7896036165 | ||
|
|
7e9c29f277 | ||
|
|
e1ae9f9eec | ||
|
|
52b9ed277c | ||
|
|
5e55a6f1f1 | ||
|
|
f439a791a9 | ||
|
|
85dfc45f8b | ||
|
|
e573d9da41 | ||
|
|
53cb73ca5a | ||
|
|
7f26b9feb3 | ||
|
|
948b4b3456 |
1
ROC
Submodule
1
ROC
Submodule
Submodule ROC added at ec53a2682b
@@ -1,14 +1,14 @@
|
|||||||
<?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-14-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-14-0 http://www.eiffel.com/developers/xml/configuration-1-14-0.xsd" name="demo" uuid="3643E657-BCBE-46AA-931B-71EAEA877A18" library_target="demo">
|
<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>
|
<description>Example/demo for Eiffel ROC CMS library</description>
|
||||||
<target name="common" abstract="true">
|
<target name="common" abstract="true">
|
||||||
<root class="DEMO_CMS_SERVER" feature="make_and_launch"/>
|
<root class="DEMO_CMS_SERVER" feature="make_and_launch"/>
|
||||||
<file_rule>
|
<file_rule>
|
||||||
<exclude>/EIFGENs$</exclude>
|
|
||||||
<exclude>/CVS$</exclude>
|
|
||||||
<exclude>/.svn$</exclude>
|
<exclude>/.svn$</exclude>
|
||||||
|
<exclude>/CVS$</exclude>
|
||||||
|
<exclude>/EIFGENs$</exclude>
|
||||||
</file_rule>
|
</file_rule>
|
||||||
<option debug="true" warning="true" full_class_checking="false" is_attached_by_default="true" void_safety="all" syntax="transitional">
|
<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"/>
|
<debug name="dbglog" enabled="true"/>
|
||||||
</option>
|
</option>
|
||||||
<setting name="concurrency" value="thread"/>
|
<setting name="concurrency" value="thread"/>
|
||||||
@@ -26,23 +26,21 @@
|
|||||||
<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"/>
|
||||||
<library name="cms_taxnomy_module" location="..\..\modules\taxonomy\taxonomy-safe.ecf" readonly="false"/>
|
|
||||||
<library name="cms_oauth_20_module" location="..\..\modules\oauth20\oauth20-safe.ecf" readonly="false"/>
|
<library name="cms_oauth_20_module" location="..\..\modules\oauth20\oauth20-safe.ecf" readonly="false"/>
|
||||||
<library name="cms_session_auth_module" location="..\..\modules\session_auth\cms_session_auth-safe.ecf" readonly="false"/>
|
|
||||||
<library name="cms_openid_module" location="..\..\modules\openid\openid-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_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">
|
<library name="persistence_sqlite3" location="..\..\library\persistence\sqlite3\sqlite3-safe.ecf" readonly="false">
|
||||||
<option>
|
<option>
|
||||||
<assertions/>
|
<assertions/>
|
||||||
</option>
|
</option>
|
||||||
</library>
|
</library>
|
||||||
<library name="persistence_store_odbc" location="..\..\library\persistence\store_odbc\store_odbc-safe.ecf"/>
|
<library name="persistence_store_odbc" location="..\..\library\persistence\store_odbc\store_odbc-safe.ecf"/>
|
||||||
<!--
|
|
||||||
<library name="persistence_store_mysql" location="..\..\library\persistence\store_mysql\store_mysql-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_extension" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf_extension-safe.ecf" readonly="false"/>
|
<library name="wsf_extension" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf_extension-safe.ecf" readonly="false"/>
|
||||||
</target>
|
</target>
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
port=9090
|
port=9090
|
||||||
|
#port=12345
|
||||||
#verbose=true
|
#verbose=true
|
||||||
|
|||||||
BIN
examples/demo/site/database.sqlite3
Normal file
BIN
examples/demo/site/database.sqlite3
Normal file
Binary file not shown.
@@ -0,0 +1,79 @@
|
|||||||
|
<!-- Updated: 12/04/2015 12:30:04.000 AM --><div class="feed">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<div class="date"> Dec 08</div>
|
||||||
|
<a href="https://groups.google.com/d/topic/eiffel-users/-jtyp4iengE">Re: [eiffel-users] Precompile on Linux</a>
|
||||||
|
<div class="description">Hi, I just check if the .ecf files are in /usr/share/eiffelstudio-MM.mm/precomp/spec/unix and they are. When I look in the "Locations of configuration files" dialog in EiffelStudio, I see this: # Search paths for precompiled libraries are specified in the configuration file: # /usr/share/ei</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="date"> Dec 08</div>
|
||||||
|
<a href="https://groups.google.com/d/topic/eiffel-users/-jtyp4iengE">RE: [eiffel-users] Precompile on Linux</a>
|
||||||
|
<div class="description">This is a bug in the Unix layout then. Do you mind submitting a problem report? Thanks, Manu *From:* eiffel...@googlegroups.com [mailto:eiffel...@googlegroups.com] *On Behalf Of *Louis *Sent:* Tuesday, December 08, 2015 23:02 *To:* eiffel...@googlegroups.com *Subject:* Re: [eiffel-users]</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="date"> Dec 08</div>
|
||||||
|
<a href="https://groups.google.com/d/topic/eiffel-users/ddSxnBrvhUg">Re: [eiffel-users] Re: Version of EiffelBase2 shipped with different EiffelStudio versions</a>
|
||||||
|
<div class="description">Not really. What I need to know is when I run tests on the performance and suitability for use of EiffelBase2, do I have to repeat them with all of ES versions 15.01, 15.08 and 15.11? On 8 December 2015 at 13:52, Jocelyn Fiat <jf...@eiffelsolution.com> wrote: > As the author of EiffelBase2 does</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="date"> Dec 08</div>
|
||||||
|
<a href="https://groups.google.com/d/topic/eiffel-users/ddSxnBrvhUg">RE: [eiffel-users] Re: Version of EiffelBase2 shipped with different EiffelStudio versions</a>
|
||||||
|
<div class="description">In this particular case, it is sufficient to take any version of EiffelStudio and the EiffelBase2 version that comes with it to evaluate EiffelBase2 as the library has not really changed much in the past few years. In the general case, you should stick to one version of EiffelStudio and</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="date"> Dec 08</div>
|
||||||
|
<a href="https://groups.google.com/d/topic/eiffel-users/ddSxnBrvhUg">Re: [eiffel-users] Re: Version of EiffelBase2 shipped with different EiffelStudio versions</a>
|
||||||
|
<div class="description">But this doesn't answer my question. Which version of EiffelBase2 ships with which version of EiffelStudio? On 8 December 2015 at 13:05, Jocelyn Fiat <jf...@eiffel.com> wrote: > Hi all, > > Usually the version uploaded to iron server comes from the associated > branch > for instance > > - 15.01</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="date"> Dec 08</div>
|
||||||
|
<a href="https://groups.google.com/d/topic/eiffel-users/ddSxnBrvhUg">Re: [eiffel-users] Re: Version of EiffelBase2 shipped with different EiffelStudio versions</a>
|
||||||
|
<div class="description">Hi all, Usually the version uploaded to iron server comes from the associated branch for instance - 15.01 has almost same content as https://svn.eiffel.com/eiffelstudio/branches/Eiffel_15.01/ - ... I said "almost" because, the ecf are modified to use iron references rather than $ISE_LIBRARY/...</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="date"> Dec 08</div>
|
||||||
|
<a href="https://groups.google.com/d/topic/eiffel-users/ddSxnBrvhUg">Re: [eiffel-users] Re: Version of EiffelBase2 shipped with different EiffelStudio versions</a>
|
||||||
|
<div class="description">As the author of EiffelBase2 does not define any specific versions, I would say - EiffelStudio 14.05 ships EiffelBase2 version 14.05, and associated source code can be found at https://svn.eiffel.com/eiffelstudio/branches/Eiffel_14.05/Src/unstable/library/base2/ (last changed revision: 94979)</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="date"> Dec 08</div>
|
||||||
|
<a href="https://groups.google.com/d/topic/eiffel-users/-jtyp4iengE">RE: [eiffel-users] Precompile on Linux</a>
|
||||||
|
<div class="description">We currently only ship precompiled libraries for EiffelBase, WEL on Windows and EiffelVision2. The configuration files for those precompiled library are in a read-only folder of the EiffelStudio installation. The first time EiffelStudio tries to access $ISE_PRECOMP (which if not set resolves to</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="date"> Dec 08</div>
|
||||||
|
<a href="https://groups.google.com/d/topic/eiffel-users/ddSxnBrvhUg">Re: [eiffel-users] Re: Version of EiffelBase2 shipped with different EiffelStudio versions</a>
|
||||||
|
<div class="description">Come on - someone must know - the person who loaded it to iron, e.g. On 7 December 2015 at 12:03, Colin Adams <colinpa...@gmail.com> wrote: > I know what EiffelBase2 is. I was asking about the version in the iron > repository for each version of EiffelStudio. > > On 7 December 2015 at 11:59,</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="date"> Dec 08</div>
|
||||||
|
<a href="https://groups.google.com/d/topic/eiffel-users/Vwsw67vq6ss">Re: Explaining high-level programming</a>
|
||||||
|
<div class="description">A very interesting article Ian. I learned more by reading it. However, the title leads me to ask: Who (precisely) is the target audience to whom the plea is being made? From my point of view, I cannot see this audience, so I am asking for your view to help me identify the audience. Thanks,</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="date"> Dec 08</div>
|
||||||
|
<a href="https://groups.google.com/d/topic/eiffel-users/Vwsw67vq6ss">Explaining high-level programming</a>
|
||||||
|
<div class="description">On 4 Dec 2015, at 00:24, Bertrand Meyer <Bertran...@inf.ethz.ch> wrote: 3. The community should help spread Eiffel. The last point is particularly important. The user community needs to grow; if it moves up to the next level then we at Eiffel Software will be able to perform many more</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="date"> Dec 08</div>
|
||||||
|
<a href="https://groups.google.com/d/topic/eiffel-users/-jtyp4iengE">Precompile on Linux</a>
|
||||||
|
<div class="description">Recently I installed EiffelStudio 15.08 on my Xubuntu laptop, with an assist from Louis M who showed me how to install it using apt-get. In the past, after extracting everything in the .tar.bz archive, I would run the supplied precompile script to produce the precompiled libraries I needed. The</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="date"> Dec 07</div>
|
||||||
|
<a href="https://groups.google.com/d/topic/eiffel-users/4BS09rbY6UY">RE: [eiffel-users] Maximum capacity of a TUPLE</a>
|
||||||
|
<div class="description">If you are looking at TUPLE with more than 20 entries, I think I would consider using LIST or ARRAY for storing data. The issue is not so much on the TUPLE capacity (which has the same limit as a SPECIAL object) but on the number of class types any type declaration. This is a limit for all</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="date"> Dec 07</div>
|
||||||
|
<a href="https://groups.google.com/d/topic/eiffel-users/YgyWglEEN3A">Re: [eiffel-users] Does {MEMORY}.collection_off reset the progress of the garbage collector?</a>
|
||||||
|
<div class="description">Thanks, that was what I was looking for.</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="date"> Dec 07</div>
|
||||||
|
<a href="https://groups.google.com/d/topic/eiffel-users/4BS09rbY6UY">Maximum capacity of a TUPLE</a>
|
||||||
|
<div class="description">The header comment to {TUPLE}.plus says the result can be Void if the result exceeds the capacity of a TUPLE. What is this maximum capacity? (without knowing it is is impossible to prove the result of such a concatenation will be attached).</div>
|
||||||
|
</li>
|
||||||
|
<liv class="nav"><a href="/feed_aggregation/forum">See more ...</a></li>
|
||||||
|
</ul>
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
<!-- Updated: 01/10/2016 12:50:45.000 PM --><div class="feed">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<div class="date"> Jan 11</div>
|
||||||
|
<a href="https://groups.google.com/d/topic/eiffel-users/mCVwJQ21QBA">SCOOP & Contracts</a>
|
||||||
|
<div class="description">Recently, I was reading a research paper from a Canadian university talking about applying something like SCOOP to Java. Because Java does not have Design-by-Contract, they wanted to build in a new keyword (like "require") called "await". From the writers point of view, the require contract was</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="date"> Jan 11</div>
|
||||||
|
<a href="https://groups.google.com/d/topic/eiffel-users/7HR-z0DVklU">General Question: Object Persistence Mechanism</a>
|
||||||
|
<div class="description">NEED: An innate, compiler-known, object persistence mechanism, whereby objects are tracked for version (at design-time), version-updating (at run-time comparative between memory object and persisted object), and attribute change auto-persist. What would be nice is something akin to the Design-by</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="date"> Jan 11</div>
|
||||||
|
<a href="https://groups.google.com/d/topic/eiffel-users/BouQ6JU-fQ4">RE: [eiffel-users] Solving OOSC 2/E E7.3</a>
|
||||||
|
<div class="description">In addition to Colin's reply, "is" is no longer used, as it is unnecessary. The functions sqrt and atan are in classes SINGLE_MATH or DOUBLE_MATH which are interfaces to the C library functions defined in math.h. Peter Horan -----Original Message----- From: eiffel...@googlegroups.com</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="date"> Jan 11</div>
|
||||||
|
<a href="https://groups.google.com/d/topic/eiffel-users/BouQ6JU-fQ4">Re: [eiffel-users] Solving OOSC 2/E E7.3</a>
|
||||||
|
<div class="description">The indexing clause has been replaced by the note clause (just a change of keyword). You might try changing the configuration to use transitional syntax instead of standard syntax. On 11 January 2016 at 09:46, <sagyo1...@gmail.com> wrote: > Hi, everyone. > > I'm reading the japanese version of</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="date"> Jan 11</div>
|
||||||
|
<a href="https://groups.google.com/d/topic/eiffel-users/BouQ6JU-fQ4">Solving OOSC 2/E E7.3</a>
|
||||||
|
<div class="description">Hi, everyone. I'm reading the japanese version of Object-Oriented Software Construction 2/E. I tried to build the code of "7.5.4 class" in EiffelStudio 15.11 and it raises some build errors. My question is: 1) Is the "indexing description:" description disposed? 2) Is the "function: syntax</div>
|
||||||
|
</li>
|
||||||
|
<liv class="nav"><a href="/feed_aggregation/forum">See more ...</a></li>
|
||||||
|
</ul>
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
<!-- Updated: 01/10/2016 12:50:45.000 PM --><div class="feed">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<div class="date">2015, Nov 17</div>
|
||||||
|
<a href="https://room.eiffel.com/blog/colinadams/some_lazy_data_structures_implemented_in_eiffel_part_i_iterating_the_calkinwilf_tree">Some lazy data structures implemented in Eiffel - Part I - Iterating the Calkin-Wilf tree</a>
|
||||||
|
<div class="description"><p>This is the first part of a series in which I intend to make some explorations of lazy, infinite data structures in Eiffel. If you want to compile the code in these articles, you will need EiffelStudio 15.11 or later.
|
||||||
|
</p><p>In this first article, I am going to iterate an infinite data structure - the strictly-positive rational numbers, represented by an infinite tree - <a href="https://en.wikipedia.org/wiki/Calkin%E2%80%93Wilf_tree" class="external text" title="https://en.wikipedia.org/wiki/Calkin%E2%80%93Wilf_tree">The Calkin-Wilf tree</a>. The easiest way to follow the code is to view it directly on <a href="https://github.com/colin-adams/lazy_eiffel" class="external text" title="https://github.com/colin-adams/lazy_eiffel">GitHub</a>. An alternative is to checkout the repository and compile it in EiffelStudio. To do the latter (instructions are for Linux from a bash terminal, but should be similar for other O/S I think):
|
||||||
|
</p>
|
||||||
|
<ol><li> git clone git@github.com:colin-adams/lazy_eiffel.git
|
||||||
|
</li><li> git checkout V1
|
||||||
|
</li><li> cd lazy_eiffel/examples/calkin_wilf/src
|
||||||
|
</li><li> estudio calkin_wilf.ecf &
|
||||||
|
</li><li> Press OK
|
||||||
|
</li></ol>
|
||||||
|
<p>The first class worth looking at briefly is <span class="geshifilter"><code class="eiffel geshifilter-eiffel">LAZY_BINARY_TREE</code></span>. This represents a single node in an infinite binary tree, together with a link to it's parent, and two <span class="geshifilter"><code class="eiffel geshifilter-eiffel"><a href="http://www.google.com/search?q=site%3Ahttp%3A%2F%2Fdocs.eiffel.com%2Feiffelstudio%2Flibraries+function&btnI=I%27m+Feeling+Lucky"><span style="color: #800000">FUNCTION</span></a></code></span>s to find the left and right children. Incidentally, you may be surprised at the syntax used for declaring these <span class="geshifilter"><code class="eiffel geshifilter-eiffel"><a href="http://www.google.com/search?q=site%3Ahttp%3A%2F%2Fdocs.eiffel.com%2Feiffelstudio%2Flibraries+function&btnI=I%27m+Feeling+Lucky"><span style="color: #800000">FUNCTION</span></a></code></span>s unless you have already read <a href="https://groups.google.com/forum/#!topic/eiffel-users/poTM7aUIa4I" class="external text" title="https://groups.google.com/forum/#!topic/eiffel-users/poTM7aUIa4I">this thread</a>. This is why 15.11 or later is needed to compile the code. I think it's worth showing one of those agents here:
|
||||||
|
</p><p><div class="geshifilter"><div class="eiffel geshifilter-eiffel" style="font-family:monospace;"> left_child_function<span style="color: #600000;">:</span> <a href="http://www.google.com/search?q=site%3Ahttp%3A%2F%2Fdocs.eiffel.com%2Feiffelstudio%2Flibraries+function&btnI=I%27m+Feeling+Lucky"><span style="color: #800000">FUNCTION</span></a> <span style="color: #FF0000;">[</span>LAZY_BINARY_TREE <span style="color: #FF0000;">[</span>G<span style="color: #FF0000;">]</span>, LAZY_BINARY_TREE <span style="color: #FF0000;">[</span>G<span style="color: #FF0000;">]</span><span style="color: #FF0000;">]</span></div></div>
|
||||||
|
</p><p>This syntax is starting to look lightweight. Looking quite comparable to Haskell, for example (<span class="geshifilter"><code class="text geshifilter-text">leftChildFunction :: LazyBinaryTree a -> LazyBinaryTree a</code></span>), and none of that horrible camelCase.
|
||||||
|
</p><p>Then let's look at the <span class="geshifilter"><code class="eiffel geshifilter-eiffel">CALKIN_WILF</code></span> tree itself. The core of the class is a root node, two functions to navigate from any node in the tree to the left and right children (or to lazily build the tree structure, depending on how you want to look at it), and a creation procedure to initialize root to 1/1.
|
||||||
|
</p><p><div class="geshifilter"><div class="eiffel geshifilter-eiffel" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">feature</span> <span style="color: #FF0000;">{</span><a href="http://www.google.com/search?q=site%3Ahttp%3A%2F%2Fdocs.eiffel.com%2Feiffelstudio%2Flibraries+none&btnI=I%27m+Feeling+Lucky"><span style="color: #800000">NONE</span></a><span style="color: #FF0000;">}</span> <span style="color: #008000; font-style: italic;">-- Initialization</span><br />
|
||||||
|
<br />
|
||||||
|
make<br />
|
||||||
|
<span style="color: #008000; font-style: italic;">-- Create `root'.</span><br />
|
||||||
|
<span style="color: #0600FF; font-weight: bold;">do</span><br />
|
||||||
|
left_child_agent<6E><span style="color: #600000;">:=</span> <span style="color: #0600FF; font-weight: bold;">agent</span> left_child<br />
|
||||||
|
right_child_agent<6E><span style="color: #600000;">:=</span> <span style="color: #0600FF; font-weight: bold;">agent</span> right_child<br />
|
||||||
|
<span style="color: #0600FF; font-weight: bold;">create</span> <span style="color: #603000;">root</span>.<span style="color: #000060;">make</span> <span style="color: #FF0000;">(</span><span style="color: #FF0000;">(</span><span style="color: #0600FF; font-weight: bold;">create</span> <span style="color: #FF0000;">{</span>RATIONAL_NUMBER<span style="color: #FF0000;">}</span>.<span style="color: #000060;">make</span> <span style="color: #FF0000;">(</span><span style="color: #FF0000;">1</span>, <span style="color: #FF0000;">1</span><span style="color: #FF0000;">)</span><span style="color: #FF0000;">)</span>, <span style="color: #800080;">Void</span>, left_child_agent, right_child_agent<span style="color: #FF0000;">)</span><br />
|
||||||
|
start<br />
|
||||||
|
<span style="color: #0600FF; font-weight: bold;">end</span><br />
|
||||||
|
<br />
|
||||||
|
<span style="color: #0600FF; font-weight: bold;">feature</span> <span style="color: #008000; font-style: italic;">-- Access</span><br />
|
||||||
|
<br />
|
||||||
|
<span style="color: #603000;">root</span><span style="color: #600000;">:</span> LAZY_BINARY_TREE <span style="color: #FF0000;">[</span>RATIONAL_NUMBER<span style="color: #FF0000;">]</span><br />
|
||||||
|
<span style="color: #008000; font-style: italic;">-- 1/1</span><br />
|
||||||
|
<br />
|
||||||
|
left_child_agent<span style="color: #600000;">:</span> <a href="http://www.google.com/search?q=site%3Ahttp%3A%2F%2Fdocs.eiffel.com%2Feiffelstudio%2Flibraries+function&btnI=I%27m+Feeling+Lucky"><span style="color: #800000">FUNCTION</span></a> <span style="color: #FF0000;">[</span>LAZY_BINARY_TREE <span style="color: #FF0000;">[</span>RATIONAL_NUMBER<span style="color: #FF0000;">]</span>, LAZY_BINARY_TREE <span style="color: #FF0000;">[</span>RATIONAL_NUMBER<span style="color: #FF0000;">]</span><span style="color: #FF0000;">]</span><br />
|
||||||
|
<span style="color: #008000; font-style: italic;">-- Function from a node to its left child</span><br />
|
||||||
|
<br />
|
||||||
|
right_child_agent<span style="color: #600000;">:</span> <a href="http://www.google.com/search?q=site%3Ahttp%3A%2F%2Fdocs.eiffel.com%2Feiffelstudio%2Flibraries+function&btnI=I%27m+Feeling+Lucky"><span style="color: #800000">FUNCTION</span></a> <span style="color: #FF0000;">[</span>LAZY_BINARY_TREE <span style="color: #FF0000;">[</span>RATIONAL_NUMBER<span style="color: #FF0000;">]</span>, LAZY_BINARY_TREE <span style="color: #FF0000;">[</span>RATIONAL_NUMBER<span style="color: #FF0000;">]</span><span style="color: #FF0000;">]</span><br />
|
||||||
|
<span style="color: #008000; font-style: italic;">-- Function from a node to its left child</span><br />
|
||||||
|
<br />
|
||||||
|
left_child <span style="color: #FF0000;">(</span>a_node<span style="color: #600000;">:</span> LAZY_BINARY_TREE <span style="color: #FF0000;">[</span>RATIONAL_NUMBER<span style="color: #FF0000;">]</span><span style="color: #FF0000;">)</span><span style="color: #600000;">:</span> LAZY_BINARY_TREE <span style="color: #FF0000;">[</span>RATIONAL_NUMBER<span style="color: #FF0000;">]</span><br />
|
||||||
|
<span style="color: #008000; font-style: italic;">-- Left child of `a_node'</span><br />
|
||||||
|
<span style="color: #0600FF; font-weight: bold;">do</span><br />
|
||||||
|
<span style="color: #0600FF; font-weight: bold;">create</span> <span style="color: #800080;">Result</span>.<span style="color: #000060;">make</span> <span style="color: #FF0000;">(</span><span style="color: #0600FF; font-weight: bold;">create</span> <span style="color: #FF0000;">{</span>RATIONAL_NUMBER<span style="color: #FF0000;">}</span>.<span style="color: #000060;">make</span> <span style="color: #FF0000;">(</span><br />
|
||||||
|
a_node.<span style="color: #000060;">item</span>.<span style="color: #000060;">numerator</span>, a_node.<span style="color: #000060;">item</span>.<span style="color: #000060;">numerator</span> <span style="color: #600000;">+</span> a_node.<span style="color: #000060;">item</span>.<span style="color: #000060;">denominator</span><span style="color: #FF0000;">)</span>,<br />
|
||||||
|
a_node, left_child_agent, right_child_agent<span style="color: #FF0000;">)</span><br />
|
||||||
|
<span style="color: #0600FF; font-weight: bold;">end</span><br />
|
||||||
|
<br />
|
||||||
|
right_child <span style="color: #FF0000;">(</span>a_node<span style="color: #600000;">:</span> LAZY_BINARY_TREE <span style="color: #FF0000;">[</span>RATIONAL_NUMBER<span style="color: #FF0000;">]</span><span style="color: #FF0000;">)</span><span style="color: #600000;">:</span> LAZY_BINARY_TREE <span style="color: #FF0000;">[</span>RATIONAL_NUMBER<span style="color: #FF0000;">]</span><br />
|
||||||
|
<span style="color: #008000; font-style: italic;">-- Right child of `a_node'</span><br />
|
||||||
|
<span style="color: #0600FF; font-weight: bold;">do</span><br />
|
||||||
|
<span style="color: #0600FF; font-weight: bold;">create</span> <span style="color: #800080;">Result</span>.<span style="color: #000060;">make</span> <span style="color: #FF0000;">(</span><span style="color: #0600FF; font-weight: bold;">create</span> <span style="color: #FF0000;">{</span>RATIONAL_NUMBER<span style="color: #FF0000;">}</span>.<span style="color: #000060;">make</span> <span style="color: #FF0000;">(</span><br />
|
||||||
|
a_node.<span style="color: #000060;">item</span>.<span style="color: #000060;">numerator</span> <span style="color: #600000;">+</span> a_node.<span style="color: #000060;">item</span>.<span style="color: #000060;">denominator</span>, a_node.<span style="color: #000060;">item</span>.<span style="color: #000060;">denominator</span><span style="color: #FF0000;">)</span>,<br />
|
||||||
|
a_node, left_child_agent, right_child_agent<span style="color: #FF0000;">)</span><br />
|
||||||
|
<span style="color: #0600FF; font-weight: bold;">end</span></div></div>
|
||||||
|
</p><p>However, I muddled this nice little picture by inheriting from <span class="geshifilter"><code class="eiffel geshifilter-eiffel"><a href="http://www.google.com/search?q=site%3Ahttp%3A%2F%2Fdocs.eiffel.com%2Feiffelstudio%2Flibraries+linear&btnI=I%27m+Feeling+Lucky"><span style="color: #800000">LINEAR</span></a> <span style="color: #FF0000;">[</span>LAZY_BINARY_TREE <span style="color: #FF0000;">[</span>RATIONAL_NUMBER<span style="color: #FF0000;">]</span><span style="color: #FF0000;">]</span></code></span>. So the class <span class="geshifilter"><code class="eiffel geshifilter-eiffel">CALKIN_WILF</code></span> <em>has</em> a lazy tree of rationals, and <em>is</em> a linear iteration of them. In the root class <span class="geshifilter"><code class="eiffel geshifilter-eiffel">CALKIN_WILF_DEMO_ROOT</code></span> we simply print the first 100 rational numbers (I could have made the program take an argument) using a <span class="geshifilter"><code class="eiffel geshifilter-eiffel"><a href="http://www.google.com/search?q=site%3Ahttp%3A%2F%2Fdocs.eiffel.com%2Feiffelstudio%2Flibraries+linear_iterator&btnI=I%27m+Feeling+Lucky"><span style="color: #800000">LINEAR_ITERATOR</span></a> <span style="color: #FF0000;">[</span>LAZY_BINARY_TREE <span style="color: #FF0000;">[</span>RATIONAL_NUMBER<span style="color: #FF0000;">]</span><span style="color: #FF0000;">]</span></code></span>. However, the iteration is <em>not</em> in numerical order. In a future post we'll see other ways of iterating the rationals.
|
||||||
|
</p><p>The really interesting thing (to me) about the Calkin-Wilf tree is the way I did a breadth-first traversal of this infinite tree. It turns out that the index in the linear structure, when translated into binary, can be considered as a set of instructions to move through the tree. You ignore all leading zeros. At the first one, move to the root. Then every time you see a zero, you take the left child, and every time you see a one, you take the right child. Lovely!
|
||||||
|
</p></div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="date">2015, Sep 15</div>
|
||||||
|
<a href="http://feedproxy.google.com/~r/BertrandMeyer/~3/vAyEwWESHTY/">Design by Contract: ACM Webinar this Thursday</a>
|
||||||
|
<div class="description"><p>A third ACM webinar this year (after two on agile methods): I will be providing a general introduction to Design by Contract. The date is this coming Thursday, September 17, and the time is noon New York (18 Paris/Zurich, 17 London, 9 Los Angeles, see here for hours elsewhere). Please tune in! The event is […]</p>
|
||||||
|
<p>The post <a rel="nofollow" href="https://bertrandmeyer.com/2015/09/15/design-by-contract-acm-webinar-this-thursday/">Design by Contract: ACM Webinar this Thursday</a> appeared first on <a rel="nofollow" href="https://bertrandmeyer.com">Bertrand Meyer's technology+ blog</a>.</p></div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="date">2015, Jan 21</div>
|
||||||
|
<a href="http://feedproxy.google.com/~r/BertrandMeyer/~3/zNoU82qSoBU/">Framing the frame problem (new paper)</a>
|
||||||
|
<div class="description"><p>Among the open problems of verification, particularly the verification of object-oriented programs, one of the most vexing is framing: how to specify and verify what programs element do not change. Continuing previous work, this article presents a “double frame inference” method, automatic on both sides the specification and verification sides. There is no need to […]</p>
|
||||||
|
<p>The post <a rel="nofollow" href="https://bertrandmeyer.com/2015/01/21/framing-the-frame-problem-new-paper/">Framing the frame problem (new paper)</a> appeared first on <a rel="nofollow" href="https://bertrandmeyer.com">Bertrand Meyer's technology+ blog</a>.</p></div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="date">2015, Jan 21</div>
|
||||||
|
<a href="http://feedproxy.google.com/~r/BertrandMeyer/~3/gYfn3TjKVzA/">Detecting deadlock automatically? (New paper)</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="date">2015, Jan 11</div>
|
||||||
|
<a href="https://room.eiffel.com/blog/conaclos/a_colored_year_on_the_web_for_eiffel">A colored year on the web for Eiffel</a>
|
||||||
|
<div class="description"><p>Happy new year!
|
||||||
|
</p><p>ACE, Prism, and Rouge now support the syntax highlighting of the Eiffel language.
|
||||||
|
</p>
|
||||||
|
<table id="toc" class="toc" summary="Contents"><tr><td><div id="toctitle"><strong>Contents</strong></div>
|
||||||
|
<div id="tocbody">
|
||||||
|
<ul>
|
||||||
|
<li class="toclevel-1"><a href="#Prism"><span class="tocnumber">1</span> <span class="toctext">Prism</span></a></li>
|
||||||
|
<li class="toclevel-1"><a href="#ACE_editor"><span class="tocnumber">2</span> <span class="toctext">ACE editor</span></a></li>
|
||||||
|
<li class="toclevel-1"><a href="#Rouge"><span class="tocnumber">3</span> <span class="toctext">Rouge</span></a></li>
|
||||||
|
<li class="toclevel-1"><a href="#Other_syntax_highlighters"><span class="tocnumber">4</span> <span class="toctext">Other syntax highlighters</span></a></li>
|
||||||
|
</ul></div>
|
||||||
|
</td></tr></table><a name="Prism"></a><h2> <span class="mw-headline"> Prism </span></h2>
|
||||||
|
<p><a href="http://prismjs.com/" class="external text" title="http://prismjs.com/">Prism</a> is by-design a lightweight syntax highlighter for the web.
|
||||||
|
It is very simple to use, and the <a href="http://prismjs.com/download.html" class="external text" title="http://prismjs.com/download.html">download page</a> enables to get only what you need. It proposes interesting add-ons (Line numbers, File Highlight, ...).
|
||||||
|
</p><p>The library is usable with a bench of tools, including <a href="https://wordpress.org/" class="external text" title="https://wordpress.org/">Wordpress</a> and <a href="http://jekyllrb.com/" class="external text" title="http://jekyllrb.com/">Jekyll</a>.
|
||||||
|
</p><p>You can test the highlighting <a href="http://prismjs.com/test.html" class="external text" title="http://prismjs.com/test.html">here</a>. The Eiffel support should be full, including the verbatim options.
|
||||||
|
</p><p>If you note any issues, you can report it on my <a href="https://github.com/Conaclos/prism" class="external text" title="https://github.com/Conaclos/prism">github fork</a>.
|
||||||
|
</p><p>I have commited a <a href="https://github.com/PrismJS/prism/pull/471" class="external text" title="https://github.com/PrismJS/prism/pull/471">Pull Request</a> to enable class name highlighting.
|
||||||
|
Please feel free to express your support in the discussion thread of the <a href="https://github.com/PrismJS/prism/pull/471" class="external text" title="https://github.com/PrismJS/prism/pull/471">Pull Request</a>.
|
||||||
|
The PR is waiitng for author agreement since January...
|
||||||
|
</p>
|
||||||
|
<a name="ACE_editor"></a><h2> <span class="mw-headline"> ACE editor </span></h2>
|
||||||
|
<p><a href="http://ace.c9.io/" class="external text" title="http://ace.c9.io/">ACE Editor</a> is certainly the most use web-based code editor.
|
||||||
|
A bench of web applications use ACE including:
|
||||||
|
</p>
|
||||||
|
<ul><li> the <a href="https://help.github.com/articles/editing-files-in-your-repository/" class="external text" title="https://help.github.com/articles/editing-files-in-your-repository/">Github web editor</a>
|
||||||
|
</li><li> the <a href="https://c9.io/" class="external text" title="https://c9.io/">Cloud9 web IDE</a>
|
||||||
|
</li><li> <a href="http://codecombat.com/" class="external text" title="http://codecombat.com/">Code Combat</a>, a game to learn programming basis
|
||||||
|
</li><li> and <a href="https://ace.c9.io/#nav=production" class="external text" title="https://ace.c9.io/#nav=production">more</a>
|
||||||
|
</li></ul>
|
||||||
|
<p>The support of Eiffel is not full. In particular, the verbatim options and multiple-line strings are not supported.
|
||||||
|
</p><p>If you note any issues, you can report it on my <a href="https://github.com/Conaclos/ace" class="external text" title="https://github.com/Conaclos/ace">github fork</a>.
|
||||||
|
</p>
|
||||||
|
<a name="Rouge"></a><h2> <span class="mw-headline"> Rouge </span></h2>
|
||||||
|
<p>Rouge is a recent syntax highlighter increasing in popularity.
|
||||||
|
It is compatible with the stylesheets of Pygments.
|
||||||
|
</p><p>It is used by:
|
||||||
|
</p>
|
||||||
|
<ul><li> <a href="https://about.gitlab.com/" class="external text" title="https://about.gitlab.com/">Gitlab</a>
|
||||||
|
</li><li> <a href="http://kramdown.gettalong.org/" class="external text" title="http://kramdown.gettalong.org/">krandown</a>, a markdown parser (anoption must be enabled)
|
||||||
|
</li><li> <a href="https://github.com/vmg/redcarpet" class="external text" title="https://github.com/vmg/redcarpet">RedCarpet</a>, another markdown parser
|
||||||
|
</li><li> the static site builder <a href="https://middlemanapp.com/" class="external text" title="https://middlemanapp.com/">Middleman</a>
|
||||||
|
</li></ul>
|
||||||
|
<p>The support of Eiffel is not full. In particular, the verbatim options are not supported.
|
||||||
|
</p><p>If you note any issues, you can report it on my <a href="https://github.com/Conaclos/rouge" class="external text" title="https://github.com/Conaclos/rouge">github fork</a>.
|
||||||
|
</p>
|
||||||
|
<a name="Other_syntax_highlighters"></a><h2> <span class="mw-headline"> Other syntax highlighters </span></h2>
|
||||||
|
<p>Some tools need updates in order to fully support the highlighting of Eiffel.
|
||||||
|
For instance:
|
||||||
|
</p>
|
||||||
|
<ul><li> <a href="https://codemirror.net/" class="external text" title="https://codemirror.net/">Code Mirror</a>, a web-based code editor
|
||||||
|
</li><li> <a href="http://pygments.org/" class="external text" title="http://pygments.org/">Pygments</a>
|
||||||
|
</li><li> <a href="https://github.com/textmate/eiffel.tmbundle" class="external text" title="https://github.com/textmate/eiffel.tmbundle">TexMate</a>, (used also by <a href="https://github.com/github/linguist" class="external text" title="https://github.com/github/linguist">Github Linguist</a>
|
||||||
|
</li><li> <a href="http://qbnz.com/highlighter/" class="external text" title="http://qbnz.com/highlighter/">GeSHi</a>
|
||||||
|
</li></ul>
|
||||||
|
<p>Enjoy ;)
|
||||||
|
</p></div>
|
||||||
|
</li>
|
||||||
|
<liv class="nav"><a href="/feed_aggregation/news">See more ...</a></li>
|
||||||
|
</ul>
|
||||||
0
examples/demo/site/files/uploaded_files/Readme.md
Normal file
0
examples/demo/site/files/uploaded_files/Readme.md
Normal file
@@ -91,6 +91,10 @@ feature -- CMS modules
|
|||||||
a_setup.register_module (m)
|
a_setup.register_module (m)
|
||||||
|
|
||||||
create {CMS_SESSION_AUTH_MODULE} m.make
|
create {CMS_SESSION_AUTH_MODULE} m.make
|
||||||
|
a_setup.register_module (m)
|
||||||
|
|
||||||
|
-- uploader
|
||||||
|
create {CMS_FILE_UPLOADER_MODULE} m.make
|
||||||
a_setup.register_module (m)
|
a_setup.register_module (m)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
69
modules/file_upload/cms_file.e
Normal file
69
modules/file_upload/cms_file.e
Normal 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
|
||||||
70
modules/file_upload/cms_file_upload_file.e
Normal file
70
modules/file_upload/cms_file_upload_file.e
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {CMS_FILE_UPLOAD_FILE}."
|
||||||
|
author: ""
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
class
|
||||||
|
CMS_FILE_UPLOAD_FILE
|
||||||
|
|
||||||
|
inherit
|
||||||
|
WSF_UPLOADED_FILE
|
||||||
|
rename
|
||||||
|
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
|
||||||
|
|
||||||
|
RAW_FILE
|
||||||
|
rename
|
||||||
|
make as make_file
|
||||||
|
end
|
||||||
|
-- undefine
|
||||||
|
-- make, change_name, is_empty, exists
|
||||||
|
-- end
|
||||||
|
|
||||||
|
create
|
||||||
|
make
|
||||||
|
|
||||||
|
feature -- Initialization
|
||||||
|
|
||||||
|
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
|
||||||
|
time: DATE_TIME
|
||||||
|
do
|
||||||
|
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)
|
||||||
|
filename := a_filename.as_string_32
|
||||||
|
content_type := a_content_type
|
||||||
|
size := a_size
|
||||||
|
|
||||||
|
create time.make_now_utc
|
||||||
|
set_uploaded_time (time)
|
||||||
|
set_uploaded_by (a_user)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
uploaded_by: CMS_USER
|
||||||
|
-- user who has uploaded the file
|
||||||
|
|
||||||
|
uploaded_time: DATE_TIME
|
||||||
|
-- time and date when file was uploaded
|
||||||
|
|
||||||
|
feature -- Setter functions
|
||||||
|
|
||||||
|
set_uploaded_by (a_user: CMS_USER)
|
||||||
|
do
|
||||||
|
uploaded_by := a_user
|
||||||
|
end
|
||||||
|
|
||||||
|
set_uploaded_time (a_time: DATE_TIME)
|
||||||
|
do
|
||||||
|
uploaded_time := a_time
|
||||||
|
end
|
||||||
|
end
|
||||||
145
modules/file_upload/cms_file_upload_file_system_handler.e
Normal file
145
modules/file_upload/cms_file_upload_file_system_handler.e
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {CMS_FILE_UPLOAD_FILE_SYSTEM_HANDLER}."
|
||||||
|
author: ""
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
class
|
||||||
|
CMS_FILE_UPLOAD_FILE_SYSTEM_HANDLER
|
||||||
|
|
||||||
|
inherit
|
||||||
|
WSF_FILE_SYSTEM_HANDLER
|
||||||
|
redefine
|
||||||
|
process_index
|
||||||
|
end
|
||||||
|
|
||||||
|
create
|
||||||
|
make_with_p
|
||||||
|
|
||||||
|
feature -- Initialization
|
||||||
|
|
||||||
|
make_with_p (d: like document_root)
|
||||||
|
do
|
||||||
|
if d.is_empty then
|
||||||
|
document_root := execution_environment.current_working_path
|
||||||
|
else
|
||||||
|
document_root := d
|
||||||
|
end
|
||||||
|
ensure
|
||||||
|
not document_root.is_empty
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- process function
|
||||||
|
|
||||||
|
process_index (a_uri: READABLE_STRING_8; dn: PATH; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||||
|
local
|
||||||
|
h: HTTP_HEADER
|
||||||
|
uri, s: STRING_8
|
||||||
|
d: DIRECTORY
|
||||||
|
l_files: LIST [PATH]
|
||||||
|
p: PATH
|
||||||
|
n: READABLE_STRING_32
|
||||||
|
httpdate: HTTP_DATE
|
||||||
|
pf: RAW_FILE
|
||||||
|
l_is_dir: BOOLEAN
|
||||||
|
do
|
||||||
|
create d.make_with_path (dn)
|
||||||
|
d.open_read
|
||||||
|
if attached directory_index_file (d) as f then
|
||||||
|
process_file (f, req, res)
|
||||||
|
else
|
||||||
|
uri := a_uri
|
||||||
|
if not uri.is_empty and then uri [uri.count] /= '/' then
|
||||||
|
uri.append_character ('/')
|
||||||
|
end
|
||||||
|
s := "[
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Index of $URI</title>
|
||||||
|
<style>
|
||||||
|
td { padding-left: 10px;}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Index of $URI</h1>
|
||||||
|
<table>
|
||||||
|
<tr><th/><th>Name</th><th>Last modified</th><th>Size</th></tr>
|
||||||
|
<tr><th colspan="4"><hr></th></tr>
|
||||||
|
]"
|
||||||
|
s.replace_substring_all ("$URI", uri)
|
||||||
|
|
||||||
|
from
|
||||||
|
l_files := d.entries
|
||||||
|
l_files.start
|
||||||
|
until
|
||||||
|
l_files.after
|
||||||
|
loop
|
||||||
|
p := l_files.item
|
||||||
|
if ignoring_index_entry (p) then
|
||||||
|
|
||||||
|
else
|
||||||
|
n := p.name
|
||||||
|
create pf.make_with_path (dn.extended_path (p))
|
||||||
|
if pf.exists and then pf.is_directory then
|
||||||
|
l_is_dir := True
|
||||||
|
else
|
||||||
|
l_is_dir := False
|
||||||
|
end
|
||||||
|
|
||||||
|
s.append ("<tr><td>")
|
||||||
|
if l_is_dir then
|
||||||
|
s.append ("[dir]")
|
||||||
|
else
|
||||||
|
s.append (" ")
|
||||||
|
end
|
||||||
|
s.append ("</td>")
|
||||||
|
s.append ("<td><a href=%"" + uri)
|
||||||
|
url_encoder.append_percent_encoded_string_to (n, s)
|
||||||
|
s.append ("%">")
|
||||||
|
if p.is_parent_symbol then
|
||||||
|
s.append ("[Parent Directory] ..")
|
||||||
|
else
|
||||||
|
s.append (html_encoder.encoded_string (n))
|
||||||
|
end
|
||||||
|
if l_is_dir then
|
||||||
|
s.append ("/")
|
||||||
|
end
|
||||||
|
|
||||||
|
s.append ("</td>")
|
||||||
|
s.append ("<td>")
|
||||||
|
if pf.exists then
|
||||||
|
create httpdate.make_from_date_time (file_date (pf))
|
||||||
|
httpdate.append_to_rfc1123_string (s)
|
||||||
|
end
|
||||||
|
s.append ("</td>")
|
||||||
|
s.append ("<td>")
|
||||||
|
if not l_is_dir and pf.exists then
|
||||||
|
s.append_integer (file_size (pf))
|
||||||
|
end
|
||||||
|
s.append ("</td>")
|
||||||
|
s.append ("</tr>")
|
||||||
|
end
|
||||||
|
l_files.forth
|
||||||
|
end
|
||||||
|
s.append ("[
|
||||||
|
<tr><th colspan="4"><hr></th></tr>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
]"
|
||||||
|
)
|
||||||
|
|
||||||
|
create h.make
|
||||||
|
h.put_content_type_text_html
|
||||||
|
res.set_status_code ({HTTP_STATUS_CODE}.ok)
|
||||||
|
h.put_content_length (s.count)
|
||||||
|
res.put_header_lines (h)
|
||||||
|
if not req.request_method.same_string ({HTTP_REQUEST_METHODS}.method_head) then
|
||||||
|
res.put_string (s)
|
||||||
|
end
|
||||||
|
res.flush
|
||||||
|
end
|
||||||
|
d.close
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
79
modules/file_upload/cms_file_uploader_api.e
Normal file
79
modules/file_upload/cms_file_uploader_api.e
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
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
|
||||||
|
reset_error
|
||||||
|
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
|
||||||
345
modules/file_upload/cms_file_uploader_module.e
Normal file
345
modules/file_upload/cms_file_uploader_module.e
Normal file
@@ -0,0 +1,345 @@
|
|||||||
|
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)
|
||||||
|
-- Display information related to a cms uploaded file.
|
||||||
|
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 ... owner, ...
|
||||||
|
|
||||||
|
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.make_empty
|
||||||
|
body.append ("<h1> Upload files </h1>%N")
|
||||||
|
|
||||||
|
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||||
|
if r.has_permission ("upload files") then
|
||||||
|
-- create body
|
||||||
|
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
|
||||||
|
else
|
||||||
|
create {FORBIDDEN_ERROR_CMS_RESPONSE} r.make (req, res, api)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Build the response.
|
||||||
|
|
||||||
|
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))
|
||||||
|
|
||||||
|
-- Record current user, ..
|
||||||
|
-- for now, only user, but it should also take care of uploaded time, ...
|
||||||
|
l_uploaded_file.set_owner (api.current_user (req))
|
||||||
|
|
||||||
|
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
|
||||||
62
modules/file_upload/cms_uploaded_file.e
Normal file
62
modules/file_upload/cms_uploaded_file.e
Normal 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
|
||||||
21
modules/file_upload/file_uploader.ecf
Normal file
21
modules/file_upload/file_uploader.ecf
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?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">
|
||||||
|
<target name="file_uploader">
|
||||||
|
<root all_classes="true" />
|
||||||
|
<file_rule>
|
||||||
|
<exclude>/.svn$</exclude>
|
||||||
|
<exclude>/CVS$</exclude>
|
||||||
|
<exclude>/EIFGENs$</exclude>
|
||||||
|
</file_rule>
|
||||||
|
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="standard"/>
|
||||||
|
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||||
|
<library name="cms" location="..\..\cms-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="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="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-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"/>
|
||||||
|
</target>
|
||||||
|
</system>
|
||||||
27
modules/file_upload/file_uploader.ecf~
Normal file
27
modules/file_upload/file_uploader.ecf~
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<?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">
|
||||||
|
<target name="file_uploader">
|
||||||
|
<!-- <root class="CMS_FILE_UPLOAD" feature="make"/> -->
|
||||||
|
<root all_classes="true" />
|
||||||
|
<option warning="true">
|
||||||
|
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||||
|
</option>
|
||||||
|
<setting name="console_application" value="true"/>
|
||||||
|
<!-- <precompile name="base_pre" location="$ISE_PRECOMP\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_model" location="\home\fmurer\Documents\EWF_ROC\ROC\library\model\cms_model-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="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_encoder" location="\home\fmurer\Documents\EWF_ROC\eiffelstudio-src\contrib\library\web\framework\ewf\text\encoder\encoder-safe.ecf"/>
|
||||||
|
<cluster name="file_uploader" location=".\" recursive="true">
|
||||||
|
<file_rule>
|
||||||
|
<exclude>/.svn$</exclude>
|
||||||
|
<exclude>/CVS$</exclude>
|
||||||
|
<exclude>/EIFGENs$</exclude>
|
||||||
|
</file_rule>
|
||||||
|
</cluster>
|
||||||
|
</target>
|
||||||
|
</system>
|
||||||
28
src/file/cms_file_uploader.e
Normal file
28
src/file/cms_file_uploader.e
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {CMS_FILE_UPLOADER}."
|
||||||
|
author: "Fabian Murer"
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
class
|
||||||
|
CMS_FILE_UPLOADER
|
||||||
|
|
||||||
|
inherit
|
||||||
|
ANY
|
||||||
|
|
||||||
|
create
|
||||||
|
make
|
||||||
|
|
||||||
|
feature {NONE} -- initialize
|
||||||
|
|
||||||
|
make (a_setup: CMS_SETUP)
|
||||||
|
-- creates the CMS_FILE_UPLOADER with a setup `a_setup'
|
||||||
|
do
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
note
|
||||||
|
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||||
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user