[#262] Convert line endings to UNIX
This commit is contained in:
parent
05a4c4616f
commit
a85b6780d2
@ -1,6 +1,6 @@
|
|||||||
<h2><%=h @status %></h2>
|
<h2><%=h @status %></h2>
|
||||||
|
|
||||||
<p id="errorExplanation"><%=h @message %></p>
|
<p id="errorExplanation"><%=h @message %></p>
|
||||||
<p><a href="javascript:history.back()">Back</a></p>
|
<p><a href="javascript:history.back()">Back</a></p>
|
||||||
|
|
||||||
<% html_title @status %>
|
<% html_title @status %>
|
||||||
|
@ -1,112 +1,112 @@
|
|||||||
<% content_for :styles do %>
|
<% content_for :styles do %>
|
||||||
body { font:80% Verdana,Tahoma,Arial,sans-serif; }
|
body { font:80% Verdana,Tahoma,Arial,sans-serif; }
|
||||||
h1, h2, h3, h4 { font-family: Trebuchet MS,Georgia,"Times New Roman",serif; }
|
h1, h2, h3, h4 { font-family: Trebuchet MS,Georgia,"Times New Roman",serif; }
|
||||||
pre, code { font-size:120%; }
|
pre, code { font-size:120%; }
|
||||||
pre code { font-size:100%; }
|
pre code { font-size:100%; }
|
||||||
pre {
|
pre {
|
||||||
margin: 1em 1em 1em 1.6em;
|
margin: 1em 1em 1em 1.6em;
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
background-color: #fafafa;
|
background-color: #fafafa;
|
||||||
border: 1px solid #dadada;
|
border: 1px solid #dadada;
|
||||||
width:95%;
|
width:95%;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
}
|
}
|
||||||
a.new { color: #b73535; }
|
a.new { color: #b73535; }
|
||||||
|
|
||||||
.CodeRay .c { color:#666; }
|
.CodeRay .c { color:#666; }
|
||||||
|
|
||||||
.CodeRay .cl { color:#B06; font-weight:bold }
|
.CodeRay .cl { color:#B06; font-weight:bold }
|
||||||
.CodeRay .dl { color:black }
|
.CodeRay .dl { color:black }
|
||||||
.CodeRay .fu { color:#06B; font-weight:bold }
|
.CodeRay .fu { color:#06B; font-weight:bold }
|
||||||
|
|
||||||
.CodeRay .il { background: #eee }
|
.CodeRay .il { background: #eee }
|
||||||
.CodeRay .il .idl { font-weight: bold; color: #888 }
|
.CodeRay .il .idl { font-weight: bold; color: #888 }
|
||||||
|
|
||||||
.CodeRay .iv { color:#33B }
|
.CodeRay .iv { color:#33B }
|
||||||
.CodeRay .r { color:#080; font-weight:bold }
|
.CodeRay .r { color:#080; font-weight:bold }
|
||||||
|
|
||||||
.CodeRay .s { background-color:#fff0f0 }
|
.CodeRay .s { background-color:#fff0f0 }
|
||||||
.CodeRay .s .dl { color:#710 }
|
.CodeRay .s .dl { color:#710 }
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<% html_title "Wiki Formatting" %>
|
<% html_title "Wiki Formatting" %>
|
||||||
<h1><a name="1" class="wiki-page"></a>Wiki Formatting</h1>
|
<h1><a name="1" class="wiki-page"></a>Wiki Formatting</h1>
|
||||||
|
|
||||||
<h2><a name="2" class="wiki-page"></a>Links</h2>
|
<h2><a name="2" class="wiki-page"></a>Links</h2>
|
||||||
|
|
||||||
<h3><a name="3" class="wiki-page"></a>ChiliProject links</h3>
|
<h3><a name="3" class="wiki-page"></a>ChiliProject links</h3>
|
||||||
|
|
||||||
<p>ChiliProject allows hyperlinking between issues, changesets and wiki pages from anywhere wiki formatting is used.</p>
|
<p>ChiliProject allows hyperlinking between issues, changesets and wiki pages from anywhere wiki formatting is used.</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Link to an issue: <strong>#124</strong> (displays <del><a href="#" class="issue" title="bulk edit doesn't change the category or fixed version properties (Closed)">#124</a></del>, link is striked-through if the issue is closed)</li>
|
<li>Link to an issue: <strong>#124</strong> (displays <del><a href="#" class="issue" title="bulk edit doesn't change the category or fixed version properties (Closed)">#124</a></del>, link is striked-through if the issue is closed)</li>
|
||||||
<li>Link to a changeset: <strong>r758</strong> (displays <a href="#" class="changeset" title="Search engine now only searches objects the user is allowed to view.">r758</a>)</li>
|
<li>Link to a changeset: <strong>r758</strong> (displays <a href="#" class="changeset" title="Search engine now only searches objects the user is allowed to view.">r758</a>)</li>
|
||||||
<li>Link to a changeset with a non-numeric hash: <strong>commit:c6f4d0fd</strong> (displays <a href="#" class="changeset">c6f4d0fd</a>).</li>
|
<li>Link to a changeset with a non-numeric hash: <strong>commit:c6f4d0fd</strong> (displays <a href="#" class="changeset">c6f4d0fd</a>).</li>
|
||||||
<li>Link to a changeset of another project: <strong>sandbox:r758</strong> (displays <a href="#" class="changeset" title="Search engine now only searches objects the user is allowed to view.">sandbox:r758</a>)</li>
|
<li>Link to a changeset of another project: <strong>sandbox:r758</strong> (displays <a href="#" class="changeset" title="Search engine now only searches objects the user is allowed to view.">sandbox:r758</a>)</li>
|
||||||
<li>Link to a changeset with a non-numeric hash: <strong>sandbox:c6f4d0fd</strong> (displays <a href="#" class="changeset">sandbox:c6f4d0fd</a>).</li>
|
<li>Link to a changeset with a non-numeric hash: <strong>sandbox:c6f4d0fd</strong> (displays <a href="#" class="changeset">sandbox:c6f4d0fd</a>).</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p>Wiki links:</p>
|
<p>Wiki links:</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><strong>[[Guide]]</strong> displays a link to the page named 'Guide': <a href="#" class="wiki-page">Guide</a></li>
|
<li><strong>[[Guide]]</strong> displays a link to the page named 'Guide': <a href="#" class="wiki-page">Guide</a></li>
|
||||||
<li><strong>[[Guide#further-reading]]</strong> takes you to the anchor "further-reading". Headings get automatically assigned anchors so that you can refer to them: <a href="#" class="wiki-page">Guide</a></li>
|
<li><strong>[[Guide#further-reading]]</strong> takes you to the anchor "further-reading". Headings get automatically assigned anchors so that you can refer to them: <a href="#" class="wiki-page">Guide</a></li>
|
||||||
<li><strong>[[Guide|User manual]]</strong> displays a link to the same page but with a different text: <a href="#" class="wiki-page">User manual</a></li>
|
<li><strong>[[Guide|User manual]]</strong> displays a link to the same page but with a different text: <a href="#" class="wiki-page">User manual</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p>You can also link to pages of an other project wiki:</p>
|
<p>You can also link to pages of an other project wiki:</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><strong>[[sandbox:some page]]</strong> displays a link to the page named 'Some page' of the Sandbox wiki</li>
|
<li><strong>[[sandbox:some page]]</strong> displays a link to the page named 'Some page' of the Sandbox wiki</li>
|
||||||
<li><strong>[[sandbox:]]</strong> displays a link to the Sandbox wiki main page</li>
|
<li><strong>[[sandbox:]]</strong> displays a link to the Sandbox wiki main page</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p>Wiki links are displayed in red if the page doesn't exist yet, eg: <a href="#" class="wiki-page new">Nonexistent page</a>.</p>
|
<p>Wiki links are displayed in red if the page doesn't exist yet, eg: <a href="#" class="wiki-page new">Nonexistent page</a>.</p>
|
||||||
|
|
||||||
<p>Links to other resources:</p>
|
<p>Links to other resources:</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>Documents:
|
<li>Documents:
|
||||||
<ul>
|
<ul>
|
||||||
<li><strong>document#17</strong> (link to document with id 17)</li>
|
<li><strong>document#17</strong> (link to document with id 17)</li>
|
||||||
<li><strong>document:Greetings</strong> (link to the document with title "Greetings")</li>
|
<li><strong>document:Greetings</strong> (link to the document with title "Greetings")</li>
|
||||||
<li><strong>document:"Some document"</strong> (double quotes can be used when document title contains spaces)</li>
|
<li><strong>document:"Some document"</strong> (double quotes can be used when document title contains spaces)</li>
|
||||||
<li><strong>sandbox:document:"Some document"</strong> (link to a document with title "Some document" in other project "sandbox")</li>
|
<li><strong>sandbox:document:"Some document"</strong> (link to a document with title "Some document" in other project "sandbox")</li>
|
||||||
</ul></li>
|
</ul></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>Versions:
|
<li>Versions:
|
||||||
<ul>
|
<ul>
|
||||||
<li><strong>version#3</strong> (link to version with id 3)</li>
|
<li><strong>version#3</strong> (link to version with id 3)</li>
|
||||||
<li><strong>version:1.0.0</strong> (link to version named "1.0.0")</li>
|
<li><strong>version:1.0.0</strong> (link to version named "1.0.0")</li>
|
||||||
<li><strong>version:"1.0 beta 2"</strong></li>
|
<li><strong>version:"1.0 beta 2"</strong></li>
|
||||||
<li><strong>sandbox:version:1.0.0</strong> (link to version "1.0.0" in the project "sandbox")</li>
|
<li><strong>sandbox:version:1.0.0</strong> (link to version "1.0.0" in the project "sandbox")</li>
|
||||||
</ul></li>
|
</ul></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>Attachments:
|
<li>Attachments:
|
||||||
<ul>
|
<ul>
|
||||||
<li><strong>attachment:file.zip</strong> (link to the attachment of the current object named file.zip)</li>
|
<li><strong>attachment:file.zip</strong> (link to the attachment of the current object named file.zip)</li>
|
||||||
<li>For now, attachments of the current object can be referenced only (if you're on an issue, it's possible to reference attachments of this issue only)</li>
|
<li>For now, attachments of the current object can be referenced only (if you're on an issue, it's possible to reference attachments of this issue only)</li>
|
||||||
</ul></li>
|
</ul></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>Repository files:
|
<li>Repository files:
|
||||||
<ul>
|
<ul>
|
||||||
<li><strong>source:some/file</strong> (link to the file located at /some/file in the project's repository)</li>
|
<li><strong>source:some/file</strong> (link to the file located at /some/file in the project's repository)</li>
|
||||||
<li><strong>source:some/file@52</strong> (link to the file's revision 52)</li>
|
<li><strong>source:some/file@52</strong> (link to the file's revision 52)</li>
|
||||||
<li><strong>source:some/file#L120</strong> (link to line 120 of the file)</li>
|
<li><strong>source:some/file#L120</strong> (link to line 120 of the file)</li>
|
||||||
<li><strong>source:some/file@52#L120</strong> (link to line 120 of the file's revision 52)</li>
|
<li><strong>source:some/file@52#L120</strong> (link to line 120 of the file's revision 52)</li>
|
||||||
<li><strong>source:"some file@52#L120"</strong> (use double quotes when the URL contains spaces</li>
|
<li><strong>source:"some file@52#L120"</strong> (use double quotes when the URL contains spaces</li>
|
||||||
<li><strong>export:some/file</strong> (force the download of the file)</li>
|
<li><strong>export:some/file</strong> (force the download of the file)</li>
|
||||||
<li><strong>sandbox:source:some/file</strong> (link to the file located at /some/file in the repository of the project "sandbox")</li>
|
<li><strong>sandbox:source:some/file</strong> (link to the file located at /some/file in the repository of the project "sandbox")</li>
|
||||||
<li><strong>sandbox:export:some/file</strong> (force the download of the file)</li>
|
<li><strong>sandbox:export:some/file</strong> (force the download of the file)</li>
|
||||||
</ul></li>
|
</ul></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>Forum messages:
|
<li>Forum messages:
|
||||||
<ul>
|
<ul>
|
||||||
<li><strong>message#1218</strong> (link to message with id 1218)</li>
|
<li><strong>message#1218</strong> (link to message with id 1218)</li>
|
||||||
@ -124,139 +124,139 @@
|
|||||||
|
|
||||||
<p>Escaping:</p>
|
<p>Escaping:</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>You can prevent ChiliProject links from being parsed by preceding them with an exclamation mark: !</li>
|
<li>You can prevent ChiliProject links from being parsed by preceding them with an exclamation mark: !</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
<h3><a name="4" class="wiki-page"></a>External links</h3>
|
<h3><a name="4" class="wiki-page"></a>External links</h3>
|
||||||
|
|
||||||
<p>HTTP URLs and email addresses are automatically turned into clickable links:</p>
|
<p>HTTP URLs and email addresses are automatically turned into clickable links:</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
https://www.chiliproject.org, someone@foo.bar
|
https://www.chiliproject.org, someone@foo.bar
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>displays: <a class="external" href="https://www.chiliproject.org">https://www.chiliproject.org</a>, <a href="mailto:someone@foo.bar" class="email">someone@foo.bar</a></p>
|
<p>displays: <a class="external" href="https://www.chiliproject.org">https://www.chiliproject.org</a>, <a href="mailto:someone@foo.bar" class="email">someone@foo.bar</a></p>
|
||||||
|
|
||||||
<p>If you want to display a specific text instead of the URL, you can use the standard textile syntax:</p>
|
<p>If you want to display a specific text instead of the URL, you can use the standard textile syntax:</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
"ChiliProject web site":https://www.chiliproject.org
|
"ChiliProject web site":https://www.chiliproject.org
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>displays: <a href="https://www.chiliproject.org" class="external">ChiliProject web site</a></p>
|
<p>displays: <a href="https://www.chiliproject.org" class="external">ChiliProject web site</a></p>
|
||||||
|
|
||||||
|
|
||||||
<h2><a name="5" class="wiki-page"></a>Text formatting</h2>
|
<h2><a name="5" class="wiki-page"></a>Text formatting</h2>
|
||||||
|
|
||||||
|
|
||||||
<p>For things such as headlines, bold, tables, lists, ChiliProject supports Textile syntax. See <a class="external" href="http://www.textism.com/tools/textile/">http://www.textism.com/tools/textile/</a> for information on using any of these features. A few samples are included below, but the engine is capable of much more of that.</p>
|
<p>For things such as headlines, bold, tables, lists, ChiliProject supports Textile syntax. See <a class="external" href="http://www.textism.com/tools/textile/">http://www.textism.com/tools/textile/</a> for information on using any of these features. A few samples are included below, but the engine is capable of much more of that.</p>
|
||||||
|
|
||||||
<h3><a name="6" class="wiki-page"></a>Font style</h3>
|
<h3><a name="6" class="wiki-page"></a>Font style</h3>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
* *bold*
|
* *bold*
|
||||||
* _italic_
|
* _italic_
|
||||||
* _*bold italic*_
|
* _*bold italic*_
|
||||||
* +underline+
|
* +underline+
|
||||||
* -strike-through-
|
* -strike-through-
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>Display:</p>
|
<p>Display:</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><strong>bold</strong></li>
|
<li><strong>bold</strong></li>
|
||||||
<li><em>italic</em></li>
|
<li><em>italic</em></li>
|
||||||
<li><em>*bold italic*</em></li>
|
<li><em>*bold italic*</em></li>
|
||||||
<li><ins>underline</ins></li>
|
<li><ins>underline</ins></li>
|
||||||
<li><del>strike-through</del></li>
|
<li><del>strike-through</del></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h3><a name="7" class="wiki-page"></a>Inline images</h3>
|
<h3><a name="7" class="wiki-page"></a>Inline images</h3>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><strong>!image_url!</strong> displays an image located at image_url (textile syntax)</li>
|
<li><strong>!image_url!</strong> displays an image located at image_url (textile syntax)</li>
|
||||||
<li><strong>!>image_url!</strong> right floating image</li>
|
<li><strong>!>image_url!</strong> right floating image</li>
|
||||||
<li>If you have an image attached to your wiki page, it can be displayed inline using its filename: <strong>!attached_image.png!</strong></li>
|
<li>If you have an image attached to your wiki page, it can be displayed inline using its filename: <strong>!attached_image.png!</strong></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h3><a name="8" class="wiki-page"></a>Headings</h3>
|
<h3><a name="8" class="wiki-page"></a>Headings</h3>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
h1. Heading
|
h1. Heading
|
||||||
h2. Subheading
|
h2. Subheading
|
||||||
h3. Subsubheading
|
h3. Subsubheading
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>ChiliProject assigns an anchor to each of those headings thus you can link to them with "#Heading", "#Subheading" and so forth.</p>
|
<p>ChiliProject assigns an anchor to each of those headings thus you can link to them with "#Heading", "#Subheading" and so forth.</p>
|
||||||
|
|
||||||
|
|
||||||
<h3><a name="9" class="wiki-page"></a>Paragraphs</h3>
|
<h3><a name="9" class="wiki-page"></a>Paragraphs</h3>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
p>. right aligned
|
p>. right aligned
|
||||||
p=. centered
|
p=. centered
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p style="text-align:center;">This is a centered paragraph.</p>
|
<p style="text-align:center;">This is a centered paragraph.</p>
|
||||||
|
|
||||||
|
|
||||||
<h3><a name="10" class="wiki-page"></a>Blockquotes</h3>
|
<h3><a name="10" class="wiki-page"></a>Blockquotes</h3>
|
||||||
|
|
||||||
<p>Start the paragraph with <strong>bq.</strong></p>
|
<p>Start the paragraph with <strong>bq.</strong></p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
bq. Rails is a full-stack framework for developing database-backed web applications according to the Model-View-Control pattern.
|
bq. Rails is a full-stack framework for developing database-backed web applications according to the Model-View-Control pattern.
|
||||||
To go live, all you need to add is a database and a web server.
|
To go live, all you need to add is a database and a web server.
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>Display:</p>
|
<p>Display:</p>
|
||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<p>Rails is a full-stack framework for developing database-backed web applications according to the Model-View-Control pattern.<br />To go live, all you need to add is a database and a web server.</p>
|
<p>Rails is a full-stack framework for developing database-backed web applications according to the Model-View-Control pattern.<br />To go live, all you need to add is a database and a web server.</p>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
|
|
||||||
<h3><a name="11" class="wiki-page"></a>Table of content</h3>
|
<h3><a name="11" class="wiki-page"></a>Table of content</h3>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
{{toc}} => left aligned toc
|
{{toc}} => left aligned toc
|
||||||
{{>toc}} => right aligned toc
|
{{>toc}} => right aligned toc
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<h2><a name="12" class="wiki-page"></a>Macros</h2>
|
<h2><a name="12" class="wiki-page"></a>Macros</h2>
|
||||||
|
|
||||||
<p>ChiliProject has the following builtin macros:</p>
|
<p>ChiliProject has the following builtin macros:</p>
|
||||||
|
|
||||||
<p><dl><dt><code>hello_world</code></dt><dd><p>Sample macro.</p></dd><dt><code>include</code></dt><dd><p>Include a wiki page. Example:</p>
|
<p><dl><dt><code>hello_world</code></dt><dd><p>Sample macro.</p></dd><dt><code>include</code></dt><dd><p>Include a wiki page. Example:</p>
|
||||||
|
|
||||||
<pre><code>{{include(Foo)}}</code></pre></dd><dt><code>macro_list</code></dt><dd><p>Displays a list of all available macros, including description if available.</p></dd></dl></p>
|
<pre><code>{{include(Foo)}}</code></pre></dd><dt><code>macro_list</code></dt><dd><p>Displays a list of all available macros, including description if available.</p></dd></dl></p>
|
||||||
|
|
||||||
|
|
||||||
<h2><a name="13" class="wiki-page"></a>Code highlighting</h2>
|
<h2><a name="13" class="wiki-page"></a>Code highlighting</h2>
|
||||||
|
|
||||||
<p>Code highlightment relies on <a href="http://coderay.rubychan.de/" class="external">CodeRay</a>, a fast syntax highlighting library written completely in Ruby. It currently supports c, cpp, css, delphi, groovy, html, java, javascript, json, php, python, rhtml, ruby, scheme, sql, xml and yaml languages.</p>
|
<p>Code highlightment relies on <a href="http://coderay.rubychan.de/" class="external">CodeRay</a>, a fast syntax highlighting library written completely in Ruby. It currently supports c, cpp, css, delphi, groovy, html, java, javascript, json, php, python, rhtml, ruby, scheme, sql, xml and yaml languages.</p>
|
||||||
|
|
||||||
<p>You can highlight code in your wiki page using this syntax:</p>
|
<p>You can highlight code in your wiki page using this syntax:</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
<pre><code class="ruby">
|
<pre><code class="ruby">
|
||||||
Place you code here.
|
Place you code here.
|
||||||
</code></pre>
|
</code></pre>
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>Example:</p>
|
<p>Example:</p>
|
||||||
|
|
||||||
<pre><code class="ruby CodeRay"><span class="no"> 1</span> <span class="c"># The Greeter class</span>
|
<pre><code class="ruby CodeRay"><span class="no"> 1</span> <span class="c"># The Greeter class</span>
|
||||||
<span class="no"> 2</span> <span class="r">class</span> <span class="cl">Greeter</span>
|
<span class="no"> 2</span> <span class="r">class</span> <span class="cl">Greeter</span>
|
||||||
<span class="no"> 3</span> <span class="r">def</span> <span class="fu">initialize</span>(name)
|
<span class="no"> 3</span> <span class="r">def</span> <span class="fu">initialize</span>(name)
|
||||||
<span class="no"> 4</span> <span class="iv">@name</span> = name.capitalize
|
<span class="no"> 4</span> <span class="iv">@name</span> = name.capitalize
|
||||||
<span class="no"> 5</span> <span class="r">end</span>
|
<span class="no"> 5</span> <span class="r">end</span>
|
||||||
<span class="no"> 6</span>
|
<span class="no"> 6</span>
|
||||||
<span class="no"> 7</span> <span class="r">def</span> <span class="fu">salute</span>
|
<span class="no"> 7</span> <span class="r">def</span> <span class="fu">salute</span>
|
||||||
<span class="no"> 8</span> puts <span class="s"><span class="dl">"</span><span class="k">Hello </span><span class="il"><span class="idl">#{</span><span class="iv">@name</span><span class="idl">}</span></span><span class="k">!</span><span class="dl">"</span></span>
|
<span class="no"> 8</span> puts <span class="s"><span class="dl">"</span><span class="k">Hello </span><span class="il"><span class="idl">#{</span><span class="iv">@name</span><span class="idl">}</span></span><span class="k">!</span><span class="dl">"</span></span>
|
||||||
<span class="no"> 9</span> <span class="r">end</span>
|
<span class="no"> 9</span> <span class="r">end</span>
|
||||||
<span class="no"><strong>10</strong></span> <span class="r">end</span>
|
<span class="no"><strong>10</strong></span> <span class="r">end</span>
|
||||||
</code>
|
</code>
|
||||||
</pre>
|
</pre>
|
||||||
|
@ -1,42 +1,42 @@
|
|||||||
<% form_tag(project_project_enumerations_path(@project), :method => :put, :class => "tabular") do %>
|
<% form_tag(project_project_enumerations_path(@project), :method => :put, :class => "tabular") do %>
|
||||||
|
|
||||||
<table class="list">
|
<table class="list">
|
||||||
<thead><tr>
|
<thead><tr>
|
||||||
<th><%= l(:field_name) %></th>
|
<th><%= l(:field_name) %></th>
|
||||||
<th><%= l(:enumeration_system_activity) %></th>
|
<th><%= l(:enumeration_system_activity) %></th>
|
||||||
<% TimeEntryActivity.new.available_custom_fields.each do |value| %>
|
<% TimeEntryActivity.new.available_custom_fields.each do |value| %>
|
||||||
<th><%= h value.name %></th>
|
<th><%= h value.name %></th>
|
||||||
<% end %>
|
<% end %>
|
||||||
<th style="width:15%;"><%= l(:field_active) %></th>
|
<th style="width:15%;"><%= l(:field_active) %></th>
|
||||||
</tr></thead>
|
</tr></thead>
|
||||||
|
|
||||||
<% @project.activities(true).each do |enumeration| %>
|
<% @project.activities(true).each do |enumeration| %>
|
||||||
<% fields_for "enumerations[#{enumeration.id}]", enumeration do |ff| %>
|
<% fields_for "enumerations[#{enumeration.id}]", enumeration do |ff| %>
|
||||||
<tr class="<%= cycle('odd', 'even') %>">
|
<tr class="<%= cycle('odd', 'even') %>">
|
||||||
<td>
|
<td>
|
||||||
<%= ff.hidden_field :parent_id, :value => enumeration.id unless enumeration.project %>
|
<%= ff.hidden_field :parent_id, :value => enumeration.id unless enumeration.project %>
|
||||||
<%= h(enumeration) %>
|
<%= h(enumeration) %>
|
||||||
</td>
|
</td>
|
||||||
<td align="center" style="width:15%;"><%= checked_image !enumeration.project %></td>
|
<td align="center" style="width:15%;"><%= checked_image !enumeration.project %></td>
|
||||||
<% enumeration.custom_field_values.each do |value| %>
|
<% enumeration.custom_field_values.each do |value| %>
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<%= custom_field_tag "enumerations[#{enumeration.id}]", value %>
|
<%= custom_field_tag "enumerations[#{enumeration.id}]", value %>
|
||||||
</td>
|
</td>
|
||||||
<% end %>
|
<% end %>
|
||||||
<td align="center" style="width:15%;">
|
<td align="center" style="width:15%;">
|
||||||
<%= ff.check_box :active %>
|
<%= ff.check_box :active %>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<div class="contextual">
|
<div class="contextual">
|
||||||
<%= link_to(l(:button_reset), project_project_enumerations_path(@project),
|
<%= link_to(l(:button_reset), project_project_enumerations_path(@project),
|
||||||
:method => :delete,
|
:method => :delete,
|
||||||
:confirm => l(:text_are_you_sure),
|
:confirm => l(:text_are_you_sure),
|
||||||
:class => 'icon icon-del') %>
|
:class => 'icon icon-del') %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<%= submit_tag l(:button_save) %>
|
<%= submit_tag l(:button_save) %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -21,19 +21,19 @@ class Setup < ActiveRecord::Migration
|
|||||||
# model removed
|
# model removed
|
||||||
class Permission < ActiveRecord::Base; end
|
class Permission < ActiveRecord::Base; end
|
||||||
|
|
||||||
def self.up
|
def self.up
|
||||||
create_table "attachments", :force => true do |t|
|
create_table "attachments", :force => true do |t|
|
||||||
t.column "container_id", :integer, :default => 0, :null => false
|
t.column "container_id", :integer, :default => 0, :null => false
|
||||||
t.column "container_type", :string, :limit => 30, :default => "", :null => false
|
t.column "container_type", :string, :limit => 30, :default => "", :null => false
|
||||||
t.column "filename", :string, :default => "", :null => false
|
t.column "filename", :string, :default => "", :null => false
|
||||||
t.column "disk_filename", :string, :default => "", :null => false
|
t.column "disk_filename", :string, :default => "", :null => false
|
||||||
t.column "filesize", :integer, :default => 0, :null => false
|
t.column "filesize", :integer, :default => 0, :null => false
|
||||||
t.column "content_type", :string, :limit => 60, :default => ""
|
t.column "content_type", :string, :limit => 60, :default => ""
|
||||||
t.column "digest", :string, :limit => 40, :default => "", :null => false
|
t.column "digest", :string, :limit => 40, :default => "", :null => false
|
||||||
t.column "downloads", :integer, :default => 0, :null => false
|
t.column "downloads", :integer, :default => 0, :null => false
|
||||||
t.column "author_id", :integer, :default => 0, :null => false
|
t.column "author_id", :integer, :default => 0, :null => false
|
||||||
t.column "created_on", :timestamp
|
t.column "created_on", :timestamp
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "auth_sources", :force => true do |t|
|
create_table "auth_sources", :force => true do |t|
|
||||||
t.column "type", :string, :limit => 30, :default => "", :null => false
|
t.column "type", :string, :limit => 30, :default => "", :null => false
|
||||||
@ -49,143 +49,143 @@ class Setup < ActiveRecord::Migration
|
|||||||
t.column "attr_mail", :string, :limit => 30
|
t.column "attr_mail", :string, :limit => 30
|
||||||
t.column "onthefly_register", :boolean, :default => false, :null => false
|
t.column "onthefly_register", :boolean, :default => false, :null => false
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "custom_fields", :force => true do |t|
|
create_table "custom_fields", :force => true do |t|
|
||||||
t.column "type", :string, :limit => 30, :default => "", :null => false
|
t.column "type", :string, :limit => 30, :default => "", :null => false
|
||||||
t.column "name", :string, :limit => 30, :default => "", :null => false
|
t.column "name", :string, :limit => 30, :default => "", :null => false
|
||||||
t.column "field_format", :string, :limit => 30, :default => "", :null => false
|
t.column "field_format", :string, :limit => 30, :default => "", :null => false
|
||||||
t.column "possible_values", :text
|
t.column "possible_values", :text
|
||||||
t.column "regexp", :string, :default => ""
|
t.column "regexp", :string, :default => ""
|
||||||
t.column "min_length", :integer, :default => 0, :null => false
|
t.column "min_length", :integer, :default => 0, :null => false
|
||||||
t.column "max_length", :integer, :default => 0, :null => false
|
t.column "max_length", :integer, :default => 0, :null => false
|
||||||
t.column "is_required", :boolean, :default => false, :null => false
|
t.column "is_required", :boolean, :default => false, :null => false
|
||||||
t.column "is_for_all", :boolean, :default => false, :null => false
|
t.column "is_for_all", :boolean, :default => false, :null => false
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "custom_fields_projects", :id => false, :force => true do |t|
|
create_table "custom_fields_projects", :id => false, :force => true do |t|
|
||||||
t.column "custom_field_id", :integer, :default => 0, :null => false
|
t.column "custom_field_id", :integer, :default => 0, :null => false
|
||||||
t.column "project_id", :integer, :default => 0, :null => false
|
t.column "project_id", :integer, :default => 0, :null => false
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "custom_fields_trackers", :id => false, :force => true do |t|
|
create_table "custom_fields_trackers", :id => false, :force => true do |t|
|
||||||
t.column "custom_field_id", :integer, :default => 0, :null => false
|
t.column "custom_field_id", :integer, :default => 0, :null => false
|
||||||
t.column "tracker_id", :integer, :default => 0, :null => false
|
t.column "tracker_id", :integer, :default => 0, :null => false
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "custom_values", :force => true do |t|
|
create_table "custom_values", :force => true do |t|
|
||||||
t.column "customized_type", :string, :limit => 30, :default => "", :null => false
|
t.column "customized_type", :string, :limit => 30, :default => "", :null => false
|
||||||
t.column "customized_id", :integer, :default => 0, :null => false
|
t.column "customized_id", :integer, :default => 0, :null => false
|
||||||
t.column "custom_field_id", :integer, :default => 0, :null => false
|
t.column "custom_field_id", :integer, :default => 0, :null => false
|
||||||
t.column "value", :text
|
t.column "value", :text
|
||||||
end
|
|
||||||
|
|
||||||
create_table "documents", :force => true do |t|
|
|
||||||
t.column "project_id", :integer, :default => 0, :null => false
|
|
||||||
t.column "category_id", :integer, :default => 0, :null => false
|
|
||||||
t.column "title", :string, :limit => 60, :default => "", :null => false
|
|
||||||
t.column "description", :text
|
|
||||||
t.column "created_on", :timestamp
|
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "documents", ["project_id"], :name => "documents_project_id"
|
create_table "documents", :force => true do |t|
|
||||||
|
t.column "project_id", :integer, :default => 0, :null => false
|
||||||
create_table "enumerations", :force => true do |t|
|
t.column "category_id", :integer, :default => 0, :null => false
|
||||||
t.column "opt", :string, :limit => 4, :default => "", :null => false
|
t.column "title", :string, :limit => 60, :default => "", :null => false
|
||||||
t.column "name", :string, :limit => 30, :default => "", :null => false
|
|
||||||
end
|
|
||||||
|
|
||||||
create_table "issue_categories", :force => true do |t|
|
|
||||||
t.column "project_id", :integer, :default => 0, :null => false
|
|
||||||
t.column "name", :string, :limit => 30, :default => "", :null => false
|
|
||||||
end
|
|
||||||
|
|
||||||
add_index "issue_categories", ["project_id"], :name => "issue_categories_project_id"
|
|
||||||
|
|
||||||
create_table "issue_histories", :force => true do |t|
|
|
||||||
t.column "issue_id", :integer, :default => 0, :null => false
|
|
||||||
t.column "status_id", :integer, :default => 0, :null => false
|
|
||||||
t.column "author_id", :integer, :default => 0, :null => false
|
|
||||||
t.column "notes", :text
|
|
||||||
t.column "created_on", :timestamp
|
|
||||||
end
|
|
||||||
|
|
||||||
add_index "issue_histories", ["issue_id"], :name => "issue_histories_issue_id"
|
|
||||||
|
|
||||||
create_table "issue_statuses", :force => true do |t|
|
|
||||||
t.column "name", :string, :limit => 30, :default => "", :null => false
|
|
||||||
t.column "is_closed", :boolean, :default => false, :null => false
|
|
||||||
t.column "is_default", :boolean, :default => false, :null => false
|
|
||||||
t.column "html_color", :string, :limit => 6, :default => "FFFFFF", :null => false
|
|
||||||
end
|
|
||||||
|
|
||||||
create_table "issues", :force => true do |t|
|
|
||||||
t.column "tracker_id", :integer, :default => 0, :null => false
|
|
||||||
t.column "project_id", :integer, :default => 0, :null => false
|
|
||||||
t.column "subject", :string, :default => "", :null => false
|
|
||||||
t.column "description", :text
|
t.column "description", :text
|
||||||
t.column "due_date", :date
|
t.column "created_on", :timestamp
|
||||||
t.column "category_id", :integer
|
|
||||||
t.column "status_id", :integer, :default => 0, :null => false
|
|
||||||
t.column "assigned_to_id", :integer
|
|
||||||
t.column "priority_id", :integer, :default => 0, :null => false
|
|
||||||
t.column "fixed_version_id", :integer
|
|
||||||
t.column "author_id", :integer, :default => 0, :null => false
|
|
||||||
t.column "lock_version", :integer, :default => 0, :null => false
|
|
||||||
t.column "created_on", :timestamp
|
|
||||||
t.column "updated_on", :timestamp
|
|
||||||
end
|
|
||||||
|
|
||||||
add_index "issues", ["project_id"], :name => "issues_project_id"
|
|
||||||
|
|
||||||
create_table "members", :force => true do |t|
|
|
||||||
t.column "user_id", :integer, :default => 0, :null => false
|
|
||||||
t.column "project_id", :integer, :default => 0, :null => false
|
|
||||||
t.column "role_id", :integer, :default => 0, :null => false
|
|
||||||
t.column "created_on", :timestamp
|
|
||||||
end
|
|
||||||
|
|
||||||
create_table "news", :force => true do |t|
|
|
||||||
t.column "project_id", :integer
|
|
||||||
t.column "title", :string, :limit => 60, :default => "", :null => false
|
|
||||||
t.column "summary", :string, :limit => 255, :default => ""
|
|
||||||
t.column "description", :text
|
|
||||||
t.column "author_id", :integer, :default => 0, :null => false
|
|
||||||
t.column "created_on", :timestamp
|
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "news", ["project_id"], :name => "news_project_id"
|
add_index "documents", ["project_id"], :name => "documents_project_id"
|
||||||
|
|
||||||
create_table "permissions", :force => true do |t|
|
create_table "enumerations", :force => true do |t|
|
||||||
t.column "controller", :string, :limit => 30, :default => "", :null => false
|
t.column "opt", :string, :limit => 4, :default => "", :null => false
|
||||||
t.column "action", :string, :limit => 30, :default => "", :null => false
|
t.column "name", :string, :limit => 30, :default => "", :null => false
|
||||||
t.column "description", :string, :limit => 60, :default => "", :null => false
|
end
|
||||||
t.column "is_public", :boolean, :default => false, :null => false
|
|
||||||
t.column "sort", :integer, :default => 0, :null => false
|
create_table "issue_categories", :force => true do |t|
|
||||||
t.column "mail_option", :boolean, :default => false, :null => false
|
t.column "project_id", :integer, :default => 0, :null => false
|
||||||
t.column "mail_enabled", :boolean, :default => false, :null => false
|
t.column "name", :string, :limit => 30, :default => "", :null => false
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "permissions_roles", :id => false, :force => true do |t|
|
add_index "issue_categories", ["project_id"], :name => "issue_categories_project_id"
|
||||||
t.column "permission_id", :integer, :default => 0, :null => false
|
|
||||||
t.column "role_id", :integer, :default => 0, :null => false
|
create_table "issue_histories", :force => true do |t|
|
||||||
end
|
t.column "issue_id", :integer, :default => 0, :null => false
|
||||||
|
t.column "status_id", :integer, :default => 0, :null => false
|
||||||
add_index "permissions_roles", ["role_id"], :name => "permissions_roles_role_id"
|
t.column "author_id", :integer, :default => 0, :null => false
|
||||||
|
t.column "notes", :text
|
||||||
create_table "projects", :force => true do |t|
|
t.column "created_on", :timestamp
|
||||||
t.column "name", :string, :limit => 30, :default => "", :null => false
|
end
|
||||||
t.column "description", :string, :default => "", :null => false
|
|
||||||
t.column "homepage", :string, :limit => 60, :default => ""
|
add_index "issue_histories", ["issue_id"], :name => "issue_histories_issue_id"
|
||||||
|
|
||||||
|
create_table "issue_statuses", :force => true do |t|
|
||||||
|
t.column "name", :string, :limit => 30, :default => "", :null => false
|
||||||
|
t.column "is_closed", :boolean, :default => false, :null => false
|
||||||
|
t.column "is_default", :boolean, :default => false, :null => false
|
||||||
|
t.column "html_color", :string, :limit => 6, :default => "FFFFFF", :null => false
|
||||||
|
end
|
||||||
|
|
||||||
|
create_table "issues", :force => true do |t|
|
||||||
|
t.column "tracker_id", :integer, :default => 0, :null => false
|
||||||
|
t.column "project_id", :integer, :default => 0, :null => false
|
||||||
|
t.column "subject", :string, :default => "", :null => false
|
||||||
|
t.column "description", :text
|
||||||
|
t.column "due_date", :date
|
||||||
|
t.column "category_id", :integer
|
||||||
|
t.column "status_id", :integer, :default => 0, :null => false
|
||||||
|
t.column "assigned_to_id", :integer
|
||||||
|
t.column "priority_id", :integer, :default => 0, :null => false
|
||||||
|
t.column "fixed_version_id", :integer
|
||||||
|
t.column "author_id", :integer, :default => 0, :null => false
|
||||||
|
t.column "lock_version", :integer, :default => 0, :null => false
|
||||||
|
t.column "created_on", :timestamp
|
||||||
|
t.column "updated_on", :timestamp
|
||||||
|
end
|
||||||
|
|
||||||
|
add_index "issues", ["project_id"], :name => "issues_project_id"
|
||||||
|
|
||||||
|
create_table "members", :force => true do |t|
|
||||||
|
t.column "user_id", :integer, :default => 0, :null => false
|
||||||
|
t.column "project_id", :integer, :default => 0, :null => false
|
||||||
|
t.column "role_id", :integer, :default => 0, :null => false
|
||||||
|
t.column "created_on", :timestamp
|
||||||
|
end
|
||||||
|
|
||||||
|
create_table "news", :force => true do |t|
|
||||||
|
t.column "project_id", :integer
|
||||||
|
t.column "title", :string, :limit => 60, :default => "", :null => false
|
||||||
|
t.column "summary", :string, :limit => 255, :default => ""
|
||||||
|
t.column "description", :text
|
||||||
|
t.column "author_id", :integer, :default => 0, :null => false
|
||||||
|
t.column "created_on", :timestamp
|
||||||
|
end
|
||||||
|
|
||||||
|
add_index "news", ["project_id"], :name => "news_project_id"
|
||||||
|
|
||||||
|
create_table "permissions", :force => true do |t|
|
||||||
|
t.column "controller", :string, :limit => 30, :default => "", :null => false
|
||||||
|
t.column "action", :string, :limit => 30, :default => "", :null => false
|
||||||
|
t.column "description", :string, :limit => 60, :default => "", :null => false
|
||||||
|
t.column "is_public", :boolean, :default => false, :null => false
|
||||||
|
t.column "sort", :integer, :default => 0, :null => false
|
||||||
|
t.column "mail_option", :boolean, :default => false, :null => false
|
||||||
|
t.column "mail_enabled", :boolean, :default => false, :null => false
|
||||||
|
end
|
||||||
|
|
||||||
|
create_table "permissions_roles", :id => false, :force => true do |t|
|
||||||
|
t.column "permission_id", :integer, :default => 0, :null => false
|
||||||
|
t.column "role_id", :integer, :default => 0, :null => false
|
||||||
|
end
|
||||||
|
|
||||||
|
add_index "permissions_roles", ["role_id"], :name => "permissions_roles_role_id"
|
||||||
|
|
||||||
|
create_table "projects", :force => true do |t|
|
||||||
|
t.column "name", :string, :limit => 30, :default => "", :null => false
|
||||||
|
t.column "description", :string, :default => "", :null => false
|
||||||
|
t.column "homepage", :string, :limit => 60, :default => ""
|
||||||
t.column "is_public", :boolean, :default => true, :null => false
|
t.column "is_public", :boolean, :default => true, :null => false
|
||||||
t.column "parent_id", :integer
|
t.column "parent_id", :integer
|
||||||
t.column "projects_count", :integer, :default => 0
|
t.column "projects_count", :integer, :default => 0
|
||||||
t.column "created_on", :timestamp
|
t.column "created_on", :timestamp
|
||||||
t.column "updated_on", :timestamp
|
t.column "updated_on", :timestamp
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "roles", :force => true do |t|
|
create_table "roles", :force => true do |t|
|
||||||
t.column "name", :string, :limit => 30, :default => "", :null => false
|
t.column "name", :string, :limit => 30, :default => "", :null => false
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "tokens", :force => true do |t|
|
create_table "tokens", :force => true do |t|
|
||||||
t.column "user_id", :integer, :default => 0, :null => false
|
t.column "user_id", :integer, :default => 0, :null => false
|
||||||
@ -193,98 +193,98 @@ class Setup < ActiveRecord::Migration
|
|||||||
t.column "value", :string, :limit => 40, :default => "", :null => false
|
t.column "value", :string, :limit => 40, :default => "", :null => false
|
||||||
t.column "created_on", :datetime, :null => false
|
t.column "created_on", :datetime, :null => false
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "trackers", :force => true do |t|
|
create_table "trackers", :force => true do |t|
|
||||||
t.column "name", :string, :limit => 30, :default => "", :null => false
|
t.column "name", :string, :limit => 30, :default => "", :null => false
|
||||||
t.column "is_in_chlog", :boolean, :default => false, :null => false
|
t.column "is_in_chlog", :boolean, :default => false, :null => false
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "users", :force => true do |t|
|
create_table "users", :force => true do |t|
|
||||||
t.column "login", :string, :limit => 30, :default => "", :null => false
|
t.column "login", :string, :limit => 30, :default => "", :null => false
|
||||||
t.column "hashed_password", :string, :limit => 40, :default => "", :null => false
|
t.column "hashed_password", :string, :limit => 40, :default => "", :null => false
|
||||||
t.column "firstname", :string, :limit => 30, :default => "", :null => false
|
t.column "firstname", :string, :limit => 30, :default => "", :null => false
|
||||||
t.column "lastname", :string, :limit => 30, :default => "", :null => false
|
t.column "lastname", :string, :limit => 30, :default => "", :null => false
|
||||||
t.column "mail", :string, :limit => 60, :default => "", :null => false
|
t.column "mail", :string, :limit => 60, :default => "", :null => false
|
||||||
t.column "mail_notification", :boolean, :default => true, :null => false
|
t.column "mail_notification", :boolean, :default => true, :null => false
|
||||||
t.column "admin", :boolean, :default => false, :null => false
|
t.column "admin", :boolean, :default => false, :null => false
|
||||||
t.column "status", :integer, :default => 1, :null => false
|
t.column "status", :integer, :default => 1, :null => false
|
||||||
t.column "last_login_on", :datetime
|
t.column "last_login_on", :datetime
|
||||||
t.column "language", :string, :limit => 2, :default => ""
|
t.column "language", :string, :limit => 2, :default => ""
|
||||||
t.column "auth_source_id", :integer
|
t.column "auth_source_id", :integer
|
||||||
t.column "created_on", :timestamp
|
t.column "created_on", :timestamp
|
||||||
t.column "updated_on", :timestamp
|
t.column "updated_on", :timestamp
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "versions", :force => true do |t|
|
create_table "versions", :force => true do |t|
|
||||||
t.column "project_id", :integer, :default => 0, :null => false
|
t.column "project_id", :integer, :default => 0, :null => false
|
||||||
t.column "name", :string, :limit => 30, :default => "", :null => false
|
t.column "name", :string, :limit => 30, :default => "", :null => false
|
||||||
t.column "description", :string, :default => ""
|
t.column "description", :string, :default => ""
|
||||||
t.column "effective_date", :date
|
t.column "effective_date", :date
|
||||||
t.column "created_on", :timestamp
|
t.column "created_on", :timestamp
|
||||||
t.column "updated_on", :timestamp
|
t.column "updated_on", :timestamp
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "versions", ["project_id"], :name => "versions_project_id"
|
add_index "versions", ["project_id"], :name => "versions_project_id"
|
||||||
|
|
||||||
create_table "workflows", :force => true do |t|
|
create_table "workflows", :force => true do |t|
|
||||||
t.column "tracker_id", :integer, :default => 0, :null => false
|
t.column "tracker_id", :integer, :default => 0, :null => false
|
||||||
t.column "old_status_id", :integer, :default => 0, :null => false
|
t.column "old_status_id", :integer, :default => 0, :null => false
|
||||||
t.column "new_status_id", :integer, :default => 0, :null => false
|
t.column "new_status_id", :integer, :default => 0, :null => false
|
||||||
t.column "role_id", :integer, :default => 0, :null => false
|
t.column "role_id", :integer, :default => 0, :null => false
|
||||||
end
|
end
|
||||||
|
|
||||||
# project
|
# project
|
||||||
Permission.create :controller => "projects", :action => "show", :description => "label_overview", :sort => 100, :is_public => true
|
Permission.create :controller => "projects", :action => "show", :description => "label_overview", :sort => 100, :is_public => true
|
||||||
Permission.create :controller => "projects", :action => "changelog", :description => "label_change_log", :sort => 105, :is_public => true
|
Permission.create :controller => "projects", :action => "changelog", :description => "label_change_log", :sort => 105, :is_public => true
|
||||||
Permission.create :controller => "reports", :action => "issue_report", :description => "label_report_plural", :sort => 110, :is_public => true
|
Permission.create :controller => "reports", :action => "issue_report", :description => "label_report_plural", :sort => 110, :is_public => true
|
||||||
Permission.create :controller => "projects", :action => "settings", :description => "label_settings", :sort => 150
|
Permission.create :controller => "projects", :action => "settings", :description => "label_settings", :sort => 150
|
||||||
Permission.create :controller => "projects", :action => "edit", :description => "button_edit", :sort => 151
|
Permission.create :controller => "projects", :action => "edit", :description => "button_edit", :sort => 151
|
||||||
# members
|
# members
|
||||||
Permission.create :controller => "projects", :action => "list_members", :description => "button_list", :sort => 200, :is_public => true
|
Permission.create :controller => "projects", :action => "list_members", :description => "button_list", :sort => 200, :is_public => true
|
||||||
Permission.create :controller => "projects", :action => "add_member", :description => "button_add", :sort => 220
|
Permission.create :controller => "projects", :action => "add_member", :description => "button_add", :sort => 220
|
||||||
Permission.create :controller => "members", :action => "edit", :description => "button_edit", :sort => 221
|
Permission.create :controller => "members", :action => "edit", :description => "button_edit", :sort => 221
|
||||||
Permission.create :controller => "members", :action => "destroy", :description => "button_delete", :sort => 222
|
Permission.create :controller => "members", :action => "destroy", :description => "button_delete", :sort => 222
|
||||||
# versions
|
# versions
|
||||||
Permission.create :controller => "projects", :action => "add_version", :description => "button_add", :sort => 320
|
Permission.create :controller => "projects", :action => "add_version", :description => "button_add", :sort => 320
|
||||||
Permission.create :controller => "versions", :action => "edit", :description => "button_edit", :sort => 321
|
Permission.create :controller => "versions", :action => "edit", :description => "button_edit", :sort => 321
|
||||||
Permission.create :controller => "versions", :action => "destroy", :description => "button_delete", :sort => 322
|
Permission.create :controller => "versions", :action => "destroy", :description => "button_delete", :sort => 322
|
||||||
# issue categories
|
# issue categories
|
||||||
Permission.create :controller => "projects", :action => "add_issue_category", :description => "button_add", :sort => 420
|
Permission.create :controller => "projects", :action => "add_issue_category", :description => "button_add", :sort => 420
|
||||||
Permission.create :controller => "issue_categories", :action => "edit", :description => "button_edit", :sort => 421
|
Permission.create :controller => "issue_categories", :action => "edit", :description => "button_edit", :sort => 421
|
||||||
Permission.create :controller => "issue_categories", :action => "destroy", :description => "button_delete", :sort => 422
|
Permission.create :controller => "issue_categories", :action => "destroy", :description => "button_delete", :sort => 422
|
||||||
# issues
|
# issues
|
||||||
Permission.create :controller => "projects", :action => "list_issues", :description => "button_list", :sort => 1000, :is_public => true
|
Permission.create :controller => "projects", :action => "list_issues", :description => "button_list", :sort => 1000, :is_public => true
|
||||||
Permission.create :controller => "projects", :action => "export_issues_csv", :description => "label_export_csv", :sort => 1001, :is_public => true
|
Permission.create :controller => "projects", :action => "export_issues_csv", :description => "label_export_csv", :sort => 1001, :is_public => true
|
||||||
Permission.create :controller => "issues", :action => "show", :description => "button_view", :sort => 1005, :is_public => true
|
Permission.create :controller => "issues", :action => "show", :description => "button_view", :sort => 1005, :is_public => true
|
||||||
Permission.create :controller => "issues", :action => "download", :description => "button_download", :sort => 1010, :is_public => true
|
Permission.create :controller => "issues", :action => "download", :description => "button_download", :sort => 1010, :is_public => true
|
||||||
Permission.create :controller => "projects", :action => "add_issue", :description => "button_add", :sort => 1050, :mail_option => 1, :mail_enabled => 1
|
Permission.create :controller => "projects", :action => "add_issue", :description => "button_add", :sort => 1050, :mail_option => 1, :mail_enabled => 1
|
||||||
Permission.create :controller => "issues", :action => "edit", :description => "button_edit", :sort => 1055
|
Permission.create :controller => "issues", :action => "edit", :description => "button_edit", :sort => 1055
|
||||||
Permission.create :controller => "issues", :action => "change_status", :description => "label_change_status", :sort => 1060, :mail_option => 1, :mail_enabled => 1
|
Permission.create :controller => "issues", :action => "change_status", :description => "label_change_status", :sort => 1060, :mail_option => 1, :mail_enabled => 1
|
||||||
Permission.create :controller => "issues", :action => "destroy", :description => "button_delete", :sort => 1065
|
Permission.create :controller => "issues", :action => "destroy", :description => "button_delete", :sort => 1065
|
||||||
Permission.create :controller => "issues", :action => "add_attachment", :description => "label_attachment_new", :sort => 1070
|
Permission.create :controller => "issues", :action => "add_attachment", :description => "label_attachment_new", :sort => 1070
|
||||||
Permission.create :controller => "issues", :action => "destroy_attachment", :description => "label_attachment_delete", :sort => 1075
|
Permission.create :controller => "issues", :action => "destroy_attachment", :description => "label_attachment_delete", :sort => 1075
|
||||||
# news
|
# news
|
||||||
Permission.create :controller => "projects", :action => "list_news", :description => "button_list", :sort => 1100, :is_public => true
|
Permission.create :controller => "projects", :action => "list_news", :description => "button_list", :sort => 1100, :is_public => true
|
||||||
Permission.create :controller => "news", :action => "show", :description => "button_view", :sort => 1101, :is_public => true
|
Permission.create :controller => "news", :action => "show", :description => "button_view", :sort => 1101, :is_public => true
|
||||||
Permission.create :controller => "projects", :action => "add_news", :description => "button_add", :sort => 1120
|
Permission.create :controller => "projects", :action => "add_news", :description => "button_add", :sort => 1120
|
||||||
Permission.create :controller => "news", :action => "edit", :description => "button_edit", :sort => 1121
|
Permission.create :controller => "news", :action => "edit", :description => "button_edit", :sort => 1121
|
||||||
Permission.create :controller => "news", :action => "destroy", :description => "button_delete", :sort => 1122
|
Permission.create :controller => "news", :action => "destroy", :description => "button_delete", :sort => 1122
|
||||||
# documents
|
# documents
|
||||||
Permission.create :controller => "projects", :action => "list_documents", :description => "button_list", :sort => 1200, :is_public => true
|
Permission.create :controller => "projects", :action => "list_documents", :description => "button_list", :sort => 1200, :is_public => true
|
||||||
Permission.create :controller => "documents", :action => "show", :description => "button_view", :sort => 1201, :is_public => true
|
Permission.create :controller => "documents", :action => "show", :description => "button_view", :sort => 1201, :is_public => true
|
||||||
Permission.create :controller => "documents", :action => "download", :description => "button_download", :sort => 1202, :is_public => true
|
Permission.create :controller => "documents", :action => "download", :description => "button_download", :sort => 1202, :is_public => true
|
||||||
Permission.create :controller => "projects", :action => "add_document", :description => "button_add", :sort => 1220
|
Permission.create :controller => "projects", :action => "add_document", :description => "button_add", :sort => 1220
|
||||||
Permission.create :controller => "documents", :action => "edit", :description => "button_edit", :sort => 1221
|
Permission.create :controller => "documents", :action => "edit", :description => "button_edit", :sort => 1221
|
||||||
Permission.create :controller => "documents", :action => "destroy", :description => "button_delete", :sort => 1222
|
Permission.create :controller => "documents", :action => "destroy", :description => "button_delete", :sort => 1222
|
||||||
Permission.create :controller => "documents", :action => "add_attachment", :description => "label_attachment_new", :sort => 1223
|
Permission.create :controller => "documents", :action => "add_attachment", :description => "label_attachment_new", :sort => 1223
|
||||||
Permission.create :controller => "documents", :action => "destroy_attachment", :description => "label_attachment_delete", :sort => 1224
|
Permission.create :controller => "documents", :action => "destroy_attachment", :description => "label_attachment_delete", :sort => 1224
|
||||||
# files
|
# files
|
||||||
Permission.create :controller => "projects", :action => "list_files", :description => "button_list", :sort => 1300, :is_public => true
|
Permission.create :controller => "projects", :action => "list_files", :description => "button_list", :sort => 1300, :is_public => true
|
||||||
Permission.create :controller => "versions", :action => "download", :description => "button_download", :sort => 1301, :is_public => true
|
Permission.create :controller => "versions", :action => "download", :description => "button_download", :sort => 1301, :is_public => true
|
||||||
Permission.create :controller => "projects", :action => "add_file", :description => "button_add", :sort => 1320
|
Permission.create :controller => "projects", :action => "add_file", :description => "button_add", :sort => 1320
|
||||||
Permission.create :controller => "versions", :action => "destroy_file", :description => "button_delete", :sort => 1322
|
Permission.create :controller => "versions", :action => "destroy_file", :description => "button_delete", :sort => 1322
|
||||||
|
|
||||||
# create default administrator account
|
# create default administrator account
|
||||||
user = User.create :login => "admin",
|
user = User.create :login => "admin",
|
||||||
:hashed_password => "d033e22ae348aeb5660fc2140aec35850c4da997",
|
:hashed_password => "d033e22ae348aeb5660fc2140aec35850c4da997",
|
||||||
:admin => true,
|
:admin => true,
|
||||||
@ -296,29 +296,29 @@ class Setup < ActiveRecord::Migration
|
|||||||
:status => 1
|
:status => 1
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.down
|
def self.down
|
||||||
drop_table :attachments
|
drop_table :attachments
|
||||||
drop_table :auth_sources
|
drop_table :auth_sources
|
||||||
drop_table :custom_fields
|
drop_table :custom_fields
|
||||||
drop_table :custom_fields_projects
|
drop_table :custom_fields_projects
|
||||||
drop_table :custom_fields_trackers
|
drop_table :custom_fields_trackers
|
||||||
drop_table :custom_values
|
drop_table :custom_values
|
||||||
drop_table :documents
|
drop_table :documents
|
||||||
drop_table :enumerations
|
drop_table :enumerations
|
||||||
drop_table :issue_categories
|
drop_table :issue_categories
|
||||||
drop_table :issue_histories
|
drop_table :issue_histories
|
||||||
drop_table :issue_statuses
|
drop_table :issue_statuses
|
||||||
drop_table :issues
|
drop_table :issues
|
||||||
drop_table :members
|
drop_table :members
|
||||||
drop_table :news
|
drop_table :news
|
||||||
drop_table :permissions
|
drop_table :permissions
|
||||||
drop_table :permissions_roles
|
drop_table :permissions_roles
|
||||||
drop_table :projects
|
drop_table :projects
|
||||||
drop_table :roles
|
drop_table :roles
|
||||||
drop_table :trackers
|
drop_table :trackers
|
||||||
drop_table :tokens
|
drop_table :tokens
|
||||||
drop_table :users
|
drop_table :users
|
||||||
drop_table :versions
|
drop_table :versions
|
||||||
drop_table :workflows
|
drop_table :workflows
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,148 +1,148 @@
|
|||||||
require 'rexml/document'
|
require 'rexml/document'
|
||||||
require 'SVG/Graph/Graph'
|
require 'SVG/Graph/Graph'
|
||||||
require 'SVG/Graph/BarBase'
|
require 'SVG/Graph/BarBase'
|
||||||
|
|
||||||
module SVG
|
module SVG
|
||||||
module Graph
|
module Graph
|
||||||
# === Create presentation quality SVG bar graphs easily
|
# === Create presentation quality SVG bar graphs easily
|
||||||
#
|
#
|
||||||
# = Synopsis
|
# = Synopsis
|
||||||
#
|
#
|
||||||
# require 'SVG/Graph/Bar'
|
# require 'SVG/Graph/Bar'
|
||||||
#
|
#
|
||||||
# fields = %w(Jan Feb Mar);
|
# fields = %w(Jan Feb Mar);
|
||||||
# data_sales_02 = [12, 45, 21]
|
# data_sales_02 = [12, 45, 21]
|
||||||
#
|
#
|
||||||
# graph = SVG::Graph::Bar.new(
|
# graph = SVG::Graph::Bar.new(
|
||||||
# :height => 500,
|
# :height => 500,
|
||||||
# :width => 300,
|
# :width => 300,
|
||||||
# :fields => fields
|
# :fields => fields
|
||||||
# )
|
# )
|
||||||
#
|
#
|
||||||
# graph.add_data(
|
# graph.add_data(
|
||||||
# :data => data_sales_02,
|
# :data => data_sales_02,
|
||||||
# :title => 'Sales 2002'
|
# :title => 'Sales 2002'
|
||||||
# )
|
# )
|
||||||
#
|
#
|
||||||
# print "Content-type: image/svg+xml\r\n\r\n"
|
# print "Content-type: image/svg+xml\r\n\r\n"
|
||||||
# print graph.burn
|
# print graph.burn
|
||||||
#
|
#
|
||||||
# = Description
|
# = Description
|
||||||
#
|
#
|
||||||
# This object aims to allow you to easily create high quality
|
# This object aims to allow you to easily create high quality
|
||||||
# SVG[http://www.w3c.org/tr/svg bar graphs. You can either use the default
|
# SVG[http://www.w3c.org/tr/svg bar graphs. You can either use the default
|
||||||
# style sheet or supply your own. Either way there are many options which
|
# style sheet or supply your own. Either way there are many options which
|
||||||
# can be configured to give you control over how the graph is generated -
|
# can be configured to give you control over how the graph is generated -
|
||||||
# with or without a key, data elements at each point, title, subtitle etc.
|
# with or without a key, data elements at each point, title, subtitle etc.
|
||||||
#
|
#
|
||||||
# = Notes
|
# = Notes
|
||||||
#
|
#
|
||||||
# The default stylesheet handles upto 12 data sets, if you
|
# The default stylesheet handles upto 12 data sets, if you
|
||||||
# use more you must create your own stylesheet and add the
|
# use more you must create your own stylesheet and add the
|
||||||
# additional settings for the extra data sets. You will know
|
# additional settings for the extra data sets. You will know
|
||||||
# if you go over 12 data sets as they will have no style and
|
# if you go over 12 data sets as they will have no style and
|
||||||
# be in black.
|
# be in black.
|
||||||
#
|
#
|
||||||
# = Examples
|
# = Examples
|
||||||
#
|
#
|
||||||
# * http://germane-software.com/repositories/public/SVG/test/test.rb
|
# * http://germane-software.com/repositories/public/SVG/test/test.rb
|
||||||
#
|
#
|
||||||
# = See also
|
# = See also
|
||||||
#
|
#
|
||||||
# * SVG::Graph::Graph
|
# * SVG::Graph::Graph
|
||||||
# * SVG::Graph::BarHorizontal
|
# * SVG::Graph::BarHorizontal
|
||||||
# * SVG::Graph::Line
|
# * SVG::Graph::Line
|
||||||
# * SVG::Graph::Pie
|
# * SVG::Graph::Pie
|
||||||
# * SVG::Graph::Plot
|
# * SVG::Graph::Plot
|
||||||
# * SVG::Graph::TimeSeries
|
# * SVG::Graph::TimeSeries
|
||||||
class Bar < BarBase
|
class Bar < BarBase
|
||||||
include REXML
|
include REXML
|
||||||
|
|
||||||
# See Graph::initialize and BarBase::set_defaults
|
# See Graph::initialize and BarBase::set_defaults
|
||||||
def set_defaults
|
def set_defaults
|
||||||
super
|
super
|
||||||
self.top_align = self.top_font = 1
|
self.top_align = self.top_font = 1
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def get_x_labels
|
def get_x_labels
|
||||||
@config[:fields]
|
@config[:fields]
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_y_labels
|
def get_y_labels
|
||||||
maxvalue = max_value
|
maxvalue = max_value
|
||||||
minvalue = min_value
|
minvalue = min_value
|
||||||
range = maxvalue - minvalue
|
range = maxvalue - minvalue
|
||||||
|
|
||||||
top_pad = range == 0 ? 10 : range / 20.0
|
top_pad = range == 0 ? 10 : range / 20.0
|
||||||
scale_range = (maxvalue + top_pad) - minvalue
|
scale_range = (maxvalue + top_pad) - minvalue
|
||||||
|
|
||||||
scale_division = scale_divisions || (scale_range / 10.0)
|
scale_division = scale_divisions || (scale_range / 10.0)
|
||||||
|
|
||||||
if scale_integers
|
if scale_integers
|
||||||
scale_division = scale_division < 1 ? 1 : scale_division.round
|
scale_division = scale_division < 1 ? 1 : scale_division.round
|
||||||
end
|
end
|
||||||
|
|
||||||
rv = []
|
rv = []
|
||||||
maxvalue = maxvalue%scale_division == 0 ?
|
maxvalue = maxvalue%scale_division == 0 ?
|
||||||
maxvalue : maxvalue + scale_division
|
maxvalue : maxvalue + scale_division
|
||||||
minvalue.step( maxvalue, scale_division ) {|v| rv << v}
|
minvalue.step( maxvalue, scale_division ) {|v| rv << v}
|
||||||
return rv
|
return rv
|
||||||
end
|
end
|
||||||
|
|
||||||
def x_label_offset( width )
|
def x_label_offset( width )
|
||||||
width / 2.0
|
width / 2.0
|
||||||
end
|
end
|
||||||
|
|
||||||
def draw_data
|
def draw_data
|
||||||
minvalue = min_value
|
minvalue = min_value
|
||||||
fieldwidth = field_width
|
fieldwidth = field_width
|
||||||
|
|
||||||
unit_size = (@graph_height.to_f - font_size*2*top_font) /
|
unit_size = (@graph_height.to_f - font_size*2*top_font) /
|
||||||
(get_y_labels.max - get_y_labels.min)
|
(get_y_labels.max - get_y_labels.min)
|
||||||
bargap = bar_gap ? (fieldwidth < 10 ? fieldwidth / 2 : 10) : 0
|
bargap = bar_gap ? (fieldwidth < 10 ? fieldwidth / 2 : 10) : 0
|
||||||
|
|
||||||
bar_width = fieldwidth - bargap
|
bar_width = fieldwidth - bargap
|
||||||
bar_width /= @data.length if stack == :side
|
bar_width /= @data.length if stack == :side
|
||||||
x_mod = (@graph_width-bargap)/2 - (stack==:side ? bar_width/2 : 0)
|
x_mod = (@graph_width-bargap)/2 - (stack==:side ? bar_width/2 : 0)
|
||||||
|
|
||||||
bottom = @graph_height
|
bottom = @graph_height
|
||||||
|
|
||||||
field_count = 0
|
field_count = 0
|
||||||
@config[:fields].each_index { |i|
|
@config[:fields].each_index { |i|
|
||||||
dataset_count = 0
|
dataset_count = 0
|
||||||
for dataset in @data
|
for dataset in @data
|
||||||
|
|
||||||
# cases (assume 0 = +ve):
|
# cases (assume 0 = +ve):
|
||||||
# value min length
|
# value min length
|
||||||
# +ve +ve value - min
|
# +ve +ve value - min
|
||||||
# +ve -ve value - 0
|
# +ve -ve value - 0
|
||||||
# -ve -ve value.abs - 0
|
# -ve -ve value.abs - 0
|
||||||
|
|
||||||
value = dataset[:data][i]
|
value = dataset[:data][i]
|
||||||
|
|
||||||
left = (fieldwidth * field_count)
|
left = (fieldwidth * field_count)
|
||||||
|
|
||||||
length = (value.abs - (minvalue > 0 ? minvalue : 0)) * unit_size
|
length = (value.abs - (minvalue > 0 ? minvalue : 0)) * unit_size
|
||||||
# top is 0 if value is negative
|
# top is 0 if value is negative
|
||||||
top = bottom - (((value < 0 ? 0 : value) - minvalue) * unit_size)
|
top = bottom - (((value < 0 ? 0 : value) - minvalue) * unit_size)
|
||||||
left += bar_width * dataset_count if stack == :side
|
left += bar_width * dataset_count if stack == :side
|
||||||
|
|
||||||
@graph.add_element( "rect", {
|
@graph.add_element( "rect", {
|
||||||
"x" => left.to_s,
|
"x" => left.to_s,
|
||||||
"y" => top.to_s,
|
"y" => top.to_s,
|
||||||
"width" => bar_width.to_s,
|
"width" => bar_width.to_s,
|
||||||
"height" => length.to_s,
|
"height" => length.to_s,
|
||||||
"class" => "fill#{dataset_count+1}"
|
"class" => "fill#{dataset_count+1}"
|
||||||
})
|
})
|
||||||
|
|
||||||
make_datapoint_text(left + bar_width/2.0, top - 6, value.to_s)
|
make_datapoint_text(left + bar_width/2.0, top - 6, value.to_s)
|
||||||
dataset_count += 1
|
dataset_count += 1
|
||||||
end
|
end
|
||||||
field_count += 1
|
field_count += 1
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,139 +1,139 @@
|
|||||||
require 'rexml/document'
|
require 'rexml/document'
|
||||||
require 'SVG/Graph/Graph'
|
require 'SVG/Graph/Graph'
|
||||||
|
|
||||||
module SVG
|
module SVG
|
||||||
module Graph
|
module Graph
|
||||||
# = Synopsis
|
# = Synopsis
|
||||||
#
|
#
|
||||||
# A superclass for bar-style graphs. Do not attempt to instantiate
|
# A superclass for bar-style graphs. Do not attempt to instantiate
|
||||||
# directly; use one of the subclasses instead.
|
# directly; use one of the subclasses instead.
|
||||||
#
|
#
|
||||||
# = Author
|
# = Author
|
||||||
#
|
#
|
||||||
# Sean E. Russell <serATgermaneHYPHENsoftwareDOTcom>
|
# Sean E. Russell <serATgermaneHYPHENsoftwareDOTcom>
|
||||||
#
|
#
|
||||||
# Copyright 2004 Sean E. Russell
|
# Copyright 2004 Sean E. Russell
|
||||||
# This software is available under the Ruby license[LICENSE.txt]
|
# This software is available under the Ruby license[LICENSE.txt]
|
||||||
#
|
#
|
||||||
class BarBase < SVG::Graph::Graph
|
class BarBase < SVG::Graph::Graph
|
||||||
# Ensures that :fields are provided in the configuration.
|
# Ensures that :fields are provided in the configuration.
|
||||||
def initialize config
|
def initialize config
|
||||||
raise "fields was not supplied or is empty" unless config[:fields] &&
|
raise "fields was not supplied or is empty" unless config[:fields] &&
|
||||||
config[:fields].kind_of?(Array) &&
|
config[:fields].kind_of?(Array) &&
|
||||||
config[:fields].length > 0
|
config[:fields].length > 0
|
||||||
super
|
super
|
||||||
end
|
end
|
||||||
|
|
||||||
# In addition to the defaults set in Graph::initialize, sets
|
# In addition to the defaults set in Graph::initialize, sets
|
||||||
# [bar_gap] true
|
# [bar_gap] true
|
||||||
# [stack] :overlap
|
# [stack] :overlap
|
||||||
def set_defaults
|
def set_defaults
|
||||||
init_with( :bar_gap => true, :stack => :overlap )
|
init_with( :bar_gap => true, :stack => :overlap )
|
||||||
end
|
end
|
||||||
|
|
||||||
# Whether to have a gap between the bars or not, default
|
# Whether to have a gap between the bars or not, default
|
||||||
# is true, set to false if you don't want gaps.
|
# is true, set to false if you don't want gaps.
|
||||||
attr_accessor :bar_gap
|
attr_accessor :bar_gap
|
||||||
# How to stack data sets. :overlap overlaps bars with
|
# How to stack data sets. :overlap overlaps bars with
|
||||||
# transparent colors, :top stacks bars on top of one another,
|
# transparent colors, :top stacks bars on top of one another,
|
||||||
# :side stacks the bars side-by-side. Defaults to :overlap.
|
# :side stacks the bars side-by-side. Defaults to :overlap.
|
||||||
attr_accessor :stack
|
attr_accessor :stack
|
||||||
|
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def max_value
|
def max_value
|
||||||
@data.collect{|x| x[:data].max}.max
|
@data.collect{|x| x[:data].max}.max
|
||||||
end
|
end
|
||||||
|
|
||||||
def min_value
|
def min_value
|
||||||
min = 0
|
min = 0
|
||||||
if min_scale_value.nil?
|
if min_scale_value.nil?
|
||||||
min = @data.collect{|x| x[:data].min}.min
|
min = @data.collect{|x| x[:data].min}.min
|
||||||
min = min > 0 ? 0 : min
|
min = min > 0 ? 0 : min
|
||||||
else
|
else
|
||||||
min = min_scale_value
|
min = min_scale_value
|
||||||
end
|
end
|
||||||
return min
|
return min
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_css
|
def get_css
|
||||||
return <<EOL
|
return <<EOL
|
||||||
/* default fill styles for multiple datasets (probably only use a single dataset on this graph though) */
|
/* default fill styles for multiple datasets (probably only use a single dataset on this graph though) */
|
||||||
.key1,.fill1{
|
.key1,.fill1{
|
||||||
fill: #ff0000;
|
fill: #ff0000;
|
||||||
fill-opacity: 0.5;
|
fill-opacity: 0.5;
|
||||||
stroke: none;
|
stroke: none;
|
||||||
stroke-width: 0.5px;
|
stroke-width: 0.5px;
|
||||||
}
|
}
|
||||||
.key2,.fill2{
|
.key2,.fill2{
|
||||||
fill: #0000ff;
|
fill: #0000ff;
|
||||||
fill-opacity: 0.5;
|
fill-opacity: 0.5;
|
||||||
stroke: none;
|
stroke: none;
|
||||||
stroke-width: 1px;
|
stroke-width: 1px;
|
||||||
}
|
}
|
||||||
.key3,.fill3{
|
.key3,.fill3{
|
||||||
fill: #00ff00;
|
fill: #00ff00;
|
||||||
fill-opacity: 0.5;
|
fill-opacity: 0.5;
|
||||||
stroke: none;
|
stroke: none;
|
||||||
stroke-width: 1px;
|
stroke-width: 1px;
|
||||||
}
|
}
|
||||||
.key4,.fill4{
|
.key4,.fill4{
|
||||||
fill: #ffcc00;
|
fill: #ffcc00;
|
||||||
fill-opacity: 0.5;
|
fill-opacity: 0.5;
|
||||||
stroke: none;
|
stroke: none;
|
||||||
stroke-width: 1px;
|
stroke-width: 1px;
|
||||||
}
|
}
|
||||||
.key5,.fill5{
|
.key5,.fill5{
|
||||||
fill: #00ccff;
|
fill: #00ccff;
|
||||||
fill-opacity: 0.5;
|
fill-opacity: 0.5;
|
||||||
stroke: none;
|
stroke: none;
|
||||||
stroke-width: 1px;
|
stroke-width: 1px;
|
||||||
}
|
}
|
||||||
.key6,.fill6{
|
.key6,.fill6{
|
||||||
fill: #ff00ff;
|
fill: #ff00ff;
|
||||||
fill-opacity: 0.5;
|
fill-opacity: 0.5;
|
||||||
stroke: none;
|
stroke: none;
|
||||||
stroke-width: 1px;
|
stroke-width: 1px;
|
||||||
}
|
}
|
||||||
.key7,.fill7{
|
.key7,.fill7{
|
||||||
fill: #00ffff;
|
fill: #00ffff;
|
||||||
fill-opacity: 0.5;
|
fill-opacity: 0.5;
|
||||||
stroke: none;
|
stroke: none;
|
||||||
stroke-width: 1px;
|
stroke-width: 1px;
|
||||||
}
|
}
|
||||||
.key8,.fill8{
|
.key8,.fill8{
|
||||||
fill: #ffff00;
|
fill: #ffff00;
|
||||||
fill-opacity: 0.5;
|
fill-opacity: 0.5;
|
||||||
stroke: none;
|
stroke: none;
|
||||||
stroke-width: 1px;
|
stroke-width: 1px;
|
||||||
}
|
}
|
||||||
.key9,.fill9{
|
.key9,.fill9{
|
||||||
fill: #cc6666;
|
fill: #cc6666;
|
||||||
fill-opacity: 0.5;
|
fill-opacity: 0.5;
|
||||||
stroke: none;
|
stroke: none;
|
||||||
stroke-width: 1px;
|
stroke-width: 1px;
|
||||||
}
|
}
|
||||||
.key10,.fill10{
|
.key10,.fill10{
|
||||||
fill: #663399;
|
fill: #663399;
|
||||||
fill-opacity: 0.5;
|
fill-opacity: 0.5;
|
||||||
stroke: none;
|
stroke: none;
|
||||||
stroke-width: 1px;
|
stroke-width: 1px;
|
||||||
}
|
}
|
||||||
.key11,.fill11{
|
.key11,.fill11{
|
||||||
fill: #339900;
|
fill: #339900;
|
||||||
fill-opacity: 0.5;
|
fill-opacity: 0.5;
|
||||||
stroke: none;
|
stroke: none;
|
||||||
stroke-width: 1px;
|
stroke-width: 1px;
|
||||||
}
|
}
|
||||||
.key12,.fill12{
|
.key12,.fill12{
|
||||||
fill: #9966FF;
|
fill: #9966FF;
|
||||||
fill-opacity: 0.5;
|
fill-opacity: 0.5;
|
||||||
stroke: none;
|
stroke: none;
|
||||||
stroke-width: 1px;
|
stroke-width: 1px;
|
||||||
}
|
}
|
||||||
EOL
|
EOL
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,149 +1,149 @@
|
|||||||
require 'rexml/document'
|
require 'rexml/document'
|
||||||
require 'SVG/Graph/BarBase'
|
require 'SVG/Graph/BarBase'
|
||||||
|
|
||||||
module SVG
|
module SVG
|
||||||
module Graph
|
module Graph
|
||||||
# === Create presentation quality SVG horitonzal bar graphs easily
|
# === Create presentation quality SVG horitonzal bar graphs easily
|
||||||
#
|
#
|
||||||
# = Synopsis
|
# = Synopsis
|
||||||
#
|
#
|
||||||
# require 'SVG/Graph/BarHorizontal'
|
# require 'SVG/Graph/BarHorizontal'
|
||||||
#
|
#
|
||||||
# fields = %w(Jan Feb Mar)
|
# fields = %w(Jan Feb Mar)
|
||||||
# data_sales_02 = [12, 45, 21]
|
# data_sales_02 = [12, 45, 21]
|
||||||
#
|
#
|
||||||
# graph = SVG::Graph::BarHorizontal.new({
|
# graph = SVG::Graph::BarHorizontal.new({
|
||||||
# :height => 500,
|
# :height => 500,
|
||||||
# :width => 300,
|
# :width => 300,
|
||||||
# :fields => fields,
|
# :fields => fields,
|
||||||
# })
|
# })
|
||||||
#
|
#
|
||||||
# graph.add_data({
|
# graph.add_data({
|
||||||
# :data => data_sales_02,
|
# :data => data_sales_02,
|
||||||
# :title => 'Sales 2002',
|
# :title => 'Sales 2002',
|
||||||
# })
|
# })
|
||||||
#
|
#
|
||||||
# print "Content-type: image/svg+xml\r\n\r\n"
|
# print "Content-type: image/svg+xml\r\n\r\n"
|
||||||
# print graph.burn
|
# print graph.burn
|
||||||
#
|
#
|
||||||
# = Description
|
# = Description
|
||||||
#
|
#
|
||||||
# This object aims to allow you to easily create high quality
|
# This object aims to allow you to easily create high quality
|
||||||
# SVG horitonzal bar graphs. You can either use the default style sheet
|
# SVG horitonzal bar graphs. You can either use the default style sheet
|
||||||
# or supply your own. Either way there are many options which can
|
# or supply your own. Either way there are many options which can
|
||||||
# be configured to give you control over how the graph is
|
# be configured to give you control over how the graph is
|
||||||
# generated - with or without a key, data elements at each point,
|
# generated - with or without a key, data elements at each point,
|
||||||
# title, subtitle etc.
|
# title, subtitle etc.
|
||||||
#
|
#
|
||||||
# = Examples
|
# = Examples
|
||||||
#
|
#
|
||||||
# * http://germane-software.com/repositories/public/SVG/test/test.rb
|
# * http://germane-software.com/repositories/public/SVG/test/test.rb
|
||||||
#
|
#
|
||||||
# = See also
|
# = See also
|
||||||
#
|
#
|
||||||
# * SVG::Graph::Graph
|
# * SVG::Graph::Graph
|
||||||
# * SVG::Graph::Bar
|
# * SVG::Graph::Bar
|
||||||
# * SVG::Graph::Line
|
# * SVG::Graph::Line
|
||||||
# * SVG::Graph::Pie
|
# * SVG::Graph::Pie
|
||||||
# * SVG::Graph::Plot
|
# * SVG::Graph::Plot
|
||||||
# * SVG::Graph::TimeSeries
|
# * SVG::Graph::TimeSeries
|
||||||
#
|
#
|
||||||
# == Author
|
# == Author
|
||||||
#
|
#
|
||||||
# Sean E. Russell <serATgermaneHYPHENsoftwareDOTcom>
|
# Sean E. Russell <serATgermaneHYPHENsoftwareDOTcom>
|
||||||
#
|
#
|
||||||
# Copyright 2004 Sean E. Russell
|
# Copyright 2004 Sean E. Russell
|
||||||
# This software is available under the Ruby license[LICENSE.txt]
|
# This software is available under the Ruby license[LICENSE.txt]
|
||||||
#
|
#
|
||||||
class BarHorizontal < BarBase
|
class BarHorizontal < BarBase
|
||||||
# In addition to the defaults set in BarBase::set_defaults, sets
|
# In addition to the defaults set in BarBase::set_defaults, sets
|
||||||
# [rotate_y_labels] true
|
# [rotate_y_labels] true
|
||||||
# [show_x_guidelines] true
|
# [show_x_guidelines] true
|
||||||
# [show_y_guidelines] false
|
# [show_y_guidelines] false
|
||||||
def set_defaults
|
def set_defaults
|
||||||
super
|
super
|
||||||
init_with(
|
init_with(
|
||||||
:rotate_y_labels => true,
|
:rotate_y_labels => true,
|
||||||
:show_x_guidelines => true,
|
:show_x_guidelines => true,
|
||||||
:show_y_guidelines => false
|
:show_y_guidelines => false
|
||||||
)
|
)
|
||||||
self.right_align = self.right_font = 1
|
self.right_align = self.right_font = 1
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def get_x_labels
|
def get_x_labels
|
||||||
maxvalue = max_value
|
maxvalue = max_value
|
||||||
minvalue = min_value
|
minvalue = min_value
|
||||||
range = maxvalue - minvalue
|
range = maxvalue - minvalue
|
||||||
top_pad = range == 0 ? 10 : range / 20.0
|
top_pad = range == 0 ? 10 : range / 20.0
|
||||||
scale_range = (maxvalue + top_pad) - minvalue
|
scale_range = (maxvalue + top_pad) - minvalue
|
||||||
|
|
||||||
scale_division = scale_divisions || (scale_range / 10.0)
|
scale_division = scale_divisions || (scale_range / 10.0)
|
||||||
|
|
||||||
if scale_integers
|
if scale_integers
|
||||||
scale_division = scale_division < 1 ? 1 : scale_division.round
|
scale_division = scale_division < 1 ? 1 : scale_division.round
|
||||||
end
|
end
|
||||||
|
|
||||||
rv = []
|
rv = []
|
||||||
maxvalue = maxvalue%scale_division == 0 ?
|
maxvalue = maxvalue%scale_division == 0 ?
|
||||||
maxvalue : maxvalue + scale_division
|
maxvalue : maxvalue + scale_division
|
||||||
minvalue.step( maxvalue, scale_division ) {|v| rv << v}
|
minvalue.step( maxvalue, scale_division ) {|v| rv << v}
|
||||||
return rv
|
return rv
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_y_labels
|
def get_y_labels
|
||||||
@config[:fields]
|
@config[:fields]
|
||||||
end
|
end
|
||||||
|
|
||||||
def y_label_offset( height )
|
def y_label_offset( height )
|
||||||
height / -2.0
|
height / -2.0
|
||||||
end
|
end
|
||||||
|
|
||||||
def draw_data
|
def draw_data
|
||||||
minvalue = min_value
|
minvalue = min_value
|
||||||
fieldheight = field_height
|
fieldheight = field_height
|
||||||
|
|
||||||
unit_size = (@graph_width.to_f - font_size*2*right_font ) /
|
unit_size = (@graph_width.to_f - font_size*2*right_font ) /
|
||||||
(get_x_labels.max - get_x_labels.min )
|
(get_x_labels.max - get_x_labels.min )
|
||||||
bargap = bar_gap ? (fieldheight < 10 ? fieldheight / 2 : 10) : 0
|
bargap = bar_gap ? (fieldheight < 10 ? fieldheight / 2 : 10) : 0
|
||||||
|
|
||||||
bar_height = fieldheight - bargap
|
bar_height = fieldheight - bargap
|
||||||
bar_height /= @data.length if stack == :side
|
bar_height /= @data.length if stack == :side
|
||||||
y_mod = (bar_height / 2) + (font_size / 2)
|
y_mod = (bar_height / 2) + (font_size / 2)
|
||||||
|
|
||||||
field_count = 1
|
field_count = 1
|
||||||
@config[:fields].each_index { |i|
|
@config[:fields].each_index { |i|
|
||||||
dataset_count = 0
|
dataset_count = 0
|
||||||
for dataset in @data
|
for dataset in @data
|
||||||
value = dataset[:data][i]
|
value = dataset[:data][i]
|
||||||
|
|
||||||
top = @graph_height - (fieldheight * field_count)
|
top = @graph_height - (fieldheight * field_count)
|
||||||
top += (bar_height * dataset_count) if stack == :side
|
top += (bar_height * dataset_count) if stack == :side
|
||||||
# cases (assume 0 = +ve):
|
# cases (assume 0 = +ve):
|
||||||
# value min length left
|
# value min length left
|
||||||
# +ve +ve value.abs - min minvalue.abs
|
# +ve +ve value.abs - min minvalue.abs
|
||||||
# +ve -ve value.abs - 0 minvalue.abs
|
# +ve -ve value.abs - 0 minvalue.abs
|
||||||
# -ve -ve value.abs - 0 minvalue.abs + value
|
# -ve -ve value.abs - 0 minvalue.abs + value
|
||||||
length = (value.abs - (minvalue > 0 ? minvalue : 0)) * unit_size
|
length = (value.abs - (minvalue > 0 ? minvalue : 0)) * unit_size
|
||||||
left = (minvalue.abs + (value < 0 ? value : 0)) * unit_size
|
left = (minvalue.abs + (value < 0 ? value : 0)) * unit_size
|
||||||
|
|
||||||
@graph.add_element( "rect", {
|
@graph.add_element( "rect", {
|
||||||
"x" => left.to_s,
|
"x" => left.to_s,
|
||||||
"y" => top.to_s,
|
"y" => top.to_s,
|
||||||
"width" => length.to_s,
|
"width" => length.to_s,
|
||||||
"height" => bar_height.to_s,
|
"height" => bar_height.to_s,
|
||||||
"class" => "fill#{dataset_count+1}"
|
"class" => "fill#{dataset_count+1}"
|
||||||
})
|
})
|
||||||
|
|
||||||
make_datapoint_text(
|
make_datapoint_text(
|
||||||
left+length+5, top+y_mod, value, "text-anchor: start; "
|
left+length+5, top+y_mod, value, "text-anchor: start; "
|
||||||
)
|
)
|
||||||
dataset_count += 1
|
dataset_count += 1
|
||||||
end
|
end
|
||||||
field_count += 1
|
field_count += 1
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,395 +1,395 @@
|
|||||||
require 'SVG/Graph/Graph'
|
require 'SVG/Graph/Graph'
|
||||||
|
|
||||||
module SVG
|
module SVG
|
||||||
module Graph
|
module Graph
|
||||||
# === Create presentation quality SVG pie graphs easily
|
# === Create presentation quality SVG pie graphs easily
|
||||||
#
|
#
|
||||||
# == Synopsis
|
# == Synopsis
|
||||||
#
|
#
|
||||||
# require 'SVG/Graph/Pie'
|
# require 'SVG/Graph/Pie'
|
||||||
#
|
#
|
||||||
# fields = %w(Jan Feb Mar)
|
# fields = %w(Jan Feb Mar)
|
||||||
# data_sales_02 = [12, 45, 21]
|
# data_sales_02 = [12, 45, 21]
|
||||||
#
|
#
|
||||||
# graph = SVG::Graph::Pie.new({
|
# graph = SVG::Graph::Pie.new({
|
||||||
# :height => 500,
|
# :height => 500,
|
||||||
# :width => 300,
|
# :width => 300,
|
||||||
# :fields => fields,
|
# :fields => fields,
|
||||||
# })
|
# })
|
||||||
#
|
#
|
||||||
# graph.add_data({
|
# graph.add_data({
|
||||||
# :data => data_sales_02,
|
# :data => data_sales_02,
|
||||||
# :title => 'Sales 2002',
|
# :title => 'Sales 2002',
|
||||||
# })
|
# })
|
||||||
#
|
#
|
||||||
# print "Content-type: image/svg+xml\r\n\r\n"
|
# print "Content-type: image/svg+xml\r\n\r\n"
|
||||||
# print graph.burn();
|
# print graph.burn();
|
||||||
#
|
#
|
||||||
# == Description
|
# == Description
|
||||||
#
|
#
|
||||||
# This object aims to allow you to easily create high quality
|
# This object aims to allow you to easily create high quality
|
||||||
# SVG pie graphs. You can either use the default style sheet
|
# SVG pie graphs. You can either use the default style sheet
|
||||||
# or supply your own. Either way there are many options which can
|
# or supply your own. Either way there are many options which can
|
||||||
# be configured to give you control over how the graph is
|
# be configured to give you control over how the graph is
|
||||||
# generated - with or without a key, display percent on pie chart,
|
# generated - with or without a key, display percent on pie chart,
|
||||||
# title, subtitle etc.
|
# title, subtitle etc.
|
||||||
#
|
#
|
||||||
# = Examples
|
# = Examples
|
||||||
#
|
#
|
||||||
# http://www.germane-software/repositories/public/SVG/test/single.rb
|
# http://www.germane-software/repositories/public/SVG/test/single.rb
|
||||||
#
|
#
|
||||||
# == See also
|
# == See also
|
||||||
#
|
#
|
||||||
# * SVG::Graph::Graph
|
# * SVG::Graph::Graph
|
||||||
# * SVG::Graph::BarHorizontal
|
# * SVG::Graph::BarHorizontal
|
||||||
# * SVG::Graph::Bar
|
# * SVG::Graph::Bar
|
||||||
# * SVG::Graph::Line
|
# * SVG::Graph::Line
|
||||||
# * SVG::Graph::Plot
|
# * SVG::Graph::Plot
|
||||||
# * SVG::Graph::TimeSeries
|
# * SVG::Graph::TimeSeries
|
||||||
#
|
#
|
||||||
# == Author
|
# == Author
|
||||||
#
|
#
|
||||||
# Sean E. Russell <serATgermaneHYPHENsoftwareDOTcom>
|
# Sean E. Russell <serATgermaneHYPHENsoftwareDOTcom>
|
||||||
#
|
#
|
||||||
# Copyright 2004 Sean E. Russell
|
# Copyright 2004 Sean E. Russell
|
||||||
# This software is available under the Ruby license[LICENSE.txt]
|
# This software is available under the Ruby license[LICENSE.txt]
|
||||||
#
|
#
|
||||||
class Pie < Graph
|
class Pie < Graph
|
||||||
# Defaults are those set by Graph::initialize, and
|
# Defaults are those set by Graph::initialize, and
|
||||||
# [show_shadow] true
|
# [show_shadow] true
|
||||||
# [shadow_offset] 10
|
# [shadow_offset] 10
|
||||||
# [show_data_labels] false
|
# [show_data_labels] false
|
||||||
# [show_actual_values] false
|
# [show_actual_values] false
|
||||||
# [show_percent] true
|
# [show_percent] true
|
||||||
# [show_key_data_labels] true
|
# [show_key_data_labels] true
|
||||||
# [show_key_actual_values] true
|
# [show_key_actual_values] true
|
||||||
# [show_key_percent] false
|
# [show_key_percent] false
|
||||||
# [expanded] false
|
# [expanded] false
|
||||||
# [expand_greatest] false
|
# [expand_greatest] false
|
||||||
# [expand_gap] 10
|
# [expand_gap] 10
|
||||||
# [show_x_labels] false
|
# [show_x_labels] false
|
||||||
# [show_y_labels] false
|
# [show_y_labels] false
|
||||||
# [datapoint_font_size] 12
|
# [datapoint_font_size] 12
|
||||||
def set_defaults
|
def set_defaults
|
||||||
init_with(
|
init_with(
|
||||||
:show_shadow => true,
|
:show_shadow => true,
|
||||||
:shadow_offset => 10,
|
:shadow_offset => 10,
|
||||||
|
|
||||||
:show_data_labels => false,
|
:show_data_labels => false,
|
||||||
:show_actual_values => false,
|
:show_actual_values => false,
|
||||||
:show_percent => true,
|
:show_percent => true,
|
||||||
|
|
||||||
:show_key_data_labels => true,
|
:show_key_data_labels => true,
|
||||||
:show_key_actual_values => true,
|
:show_key_actual_values => true,
|
||||||
:show_key_percent => false,
|
:show_key_percent => false,
|
||||||
|
|
||||||
:expanded => false,
|
:expanded => false,
|
||||||
:expand_greatest => false,
|
:expand_greatest => false,
|
||||||
:expand_gap => 10,
|
:expand_gap => 10,
|
||||||
|
|
||||||
:show_x_labels => false,
|
:show_x_labels => false,
|
||||||
:show_y_labels => false,
|
:show_y_labels => false,
|
||||||
:datapoint_font_size => 12
|
:datapoint_font_size => 12
|
||||||
)
|
)
|
||||||
@data = []
|
@data = []
|
||||||
end
|
end
|
||||||
|
|
||||||
# Adds a data set to the graph.
|
# Adds a data set to the graph.
|
||||||
#
|
#
|
||||||
# graph.add_data( { :data => [1,2,3,4] } )
|
# graph.add_data( { :data => [1,2,3,4] } )
|
||||||
#
|
#
|
||||||
# Note that the :title is not necessary. If multiple
|
# Note that the :title is not necessary. If multiple
|
||||||
# data sets are added to the graph, the pie chart will
|
# data sets are added to the graph, the pie chart will
|
||||||
# display the +sums+ of the data. EG:
|
# display the +sums+ of the data. EG:
|
||||||
#
|
#
|
||||||
# graph.add_data( { :data => [1,2,3,4] } )
|
# graph.add_data( { :data => [1,2,3,4] } )
|
||||||
# graph.add_data( { :data => [2,3,5,9] } )
|
# graph.add_data( { :data => [2,3,5,9] } )
|
||||||
#
|
#
|
||||||
# is the same as:
|
# is the same as:
|
||||||
#
|
#
|
||||||
# graph.add_data( { :data => [3,5,8,13] } )
|
# graph.add_data( { :data => [3,5,8,13] } )
|
||||||
def add_data arg
|
def add_data arg
|
||||||
arg[:data].each_index {|idx|
|
arg[:data].each_index {|idx|
|
||||||
@data[idx] = 0 unless @data[idx]
|
@data[idx] = 0 unless @data[idx]
|
||||||
@data[idx] += arg[:data][idx]
|
@data[idx] += arg[:data][idx]
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
# If true, displays a drop shadow for the chart
|
# If true, displays a drop shadow for the chart
|
||||||
attr_accessor :show_shadow
|
attr_accessor :show_shadow
|
||||||
# Sets the offset of the shadow from the pie chart
|
# Sets the offset of the shadow from the pie chart
|
||||||
attr_accessor :shadow_offset
|
attr_accessor :shadow_offset
|
||||||
# If true, display the data labels on the chart
|
# If true, display the data labels on the chart
|
||||||
attr_accessor :show_data_labels
|
attr_accessor :show_data_labels
|
||||||
# If true, display the actual field values in the data labels
|
# If true, display the actual field values in the data labels
|
||||||
attr_accessor :show_actual_values
|
attr_accessor :show_actual_values
|
||||||
# If true, display the percentage value of each pie wedge in the data
|
# If true, display the percentage value of each pie wedge in the data
|
||||||
# labels
|
# labels
|
||||||
attr_accessor :show_percent
|
attr_accessor :show_percent
|
||||||
# If true, display the labels in the key
|
# If true, display the labels in the key
|
||||||
attr_accessor :show_key_data_labels
|
attr_accessor :show_key_data_labels
|
||||||
# If true, display the actual value of the field in the key
|
# If true, display the actual value of the field in the key
|
||||||
attr_accessor :show_key_actual_values
|
attr_accessor :show_key_actual_values
|
||||||
# If true, display the percentage value of the wedges in the key
|
# If true, display the percentage value of the wedges in the key
|
||||||
attr_accessor :show_key_percent
|
attr_accessor :show_key_percent
|
||||||
# If true, "explode" the pie (put space between the wedges)
|
# If true, "explode" the pie (put space between the wedges)
|
||||||
attr_accessor :expanded
|
attr_accessor :expanded
|
||||||
# If true, expand the largest pie wedge
|
# If true, expand the largest pie wedge
|
||||||
attr_accessor :expand_greatest
|
attr_accessor :expand_greatest
|
||||||
# The amount of space between expanded wedges
|
# The amount of space between expanded wedges
|
||||||
attr_accessor :expand_gap
|
attr_accessor :expand_gap
|
||||||
# The font size of the data point labels
|
# The font size of the data point labels
|
||||||
attr_accessor :datapoint_font_size
|
attr_accessor :datapoint_font_size
|
||||||
|
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def add_defs defs
|
def add_defs defs
|
||||||
gradient = defs.add_element( "filter", {
|
gradient = defs.add_element( "filter", {
|
||||||
"id"=>"dropshadow",
|
"id"=>"dropshadow",
|
||||||
"width" => "1.2",
|
"width" => "1.2",
|
||||||
"height" => "1.2",
|
"height" => "1.2",
|
||||||
} )
|
} )
|
||||||
gradient.add_element( "feGaussianBlur", {
|
gradient.add_element( "feGaussianBlur", {
|
||||||
"stdDeviation" => "4",
|
"stdDeviation" => "4",
|
||||||
"result" => "blur"
|
"result" => "blur"
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
# We don't need the graph
|
# We don't need the graph
|
||||||
def draw_graph
|
def draw_graph
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_y_labels
|
def get_y_labels
|
||||||
[""]
|
[""]
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_x_labels
|
def get_x_labels
|
||||||
[""]
|
[""]
|
||||||
end
|
end
|
||||||
|
|
||||||
def keys
|
def keys
|
||||||
total = 0
|
total = 0
|
||||||
max_value = 0
|
max_value = 0
|
||||||
@data.each {|x| total += x }
|
@data.each {|x| total += x }
|
||||||
percent_scale = 100.0 / total
|
percent_scale = 100.0 / total
|
||||||
count = -1
|
count = -1
|
||||||
a = @config[:fields].collect{ |x|
|
a = @config[:fields].collect{ |x|
|
||||||
count += 1
|
count += 1
|
||||||
v = @data[count]
|
v = @data[count]
|
||||||
perc = show_key_percent ? " "+(v * percent_scale).round.to_s+"%" : ""
|
perc = show_key_percent ? " "+(v * percent_scale).round.to_s+"%" : ""
|
||||||
x + " [" + v.to_s + "]" + perc
|
x + " [" + v.to_s + "]" + perc
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
RADIANS = Math::PI/180
|
RADIANS = Math::PI/180
|
||||||
|
|
||||||
def draw_data
|
def draw_data
|
||||||
@graph = @root.add_element( "g" )
|
@graph = @root.add_element( "g" )
|
||||||
background = @graph.add_element("g")
|
background = @graph.add_element("g")
|
||||||
midground = @graph.add_element("g")
|
midground = @graph.add_element("g")
|
||||||
|
|
||||||
diameter = @graph_height > @graph_width ? @graph_width : @graph_height
|
diameter = @graph_height > @graph_width ? @graph_width : @graph_height
|
||||||
diameter -= expand_gap if expanded or expand_greatest
|
diameter -= expand_gap if expanded or expand_greatest
|
||||||
diameter -= datapoint_font_size if show_data_labels
|
diameter -= datapoint_font_size if show_data_labels
|
||||||
diameter -= 10 if show_shadow
|
diameter -= 10 if show_shadow
|
||||||
radius = diameter / 2.0
|
radius = diameter / 2.0
|
||||||
|
|
||||||
xoff = (width - diameter) / 2
|
xoff = (width - diameter) / 2
|
||||||
yoff = (height - @border_bottom - diameter)
|
yoff = (height - @border_bottom - diameter)
|
||||||
yoff -= 10 if show_shadow
|
yoff -= 10 if show_shadow
|
||||||
@graph.attributes['transform'] = "translate( #{xoff} #{yoff} )"
|
@graph.attributes['transform'] = "translate( #{xoff} #{yoff} )"
|
||||||
|
|
||||||
wedge_text_pad = 5
|
wedge_text_pad = 5
|
||||||
wedge_text_pad = 20 if show_percent and show_data_labels
|
wedge_text_pad = 20 if show_percent and show_data_labels
|
||||||
|
|
||||||
total = 0
|
total = 0
|
||||||
max_value = 0
|
max_value = 0
|
||||||
@data.each {|x|
|
@data.each {|x|
|
||||||
max_value = max_value < x ? x : max_value
|
max_value = max_value < x ? x : max_value
|
||||||
total += x
|
total += x
|
||||||
}
|
}
|
||||||
percent_scale = 100.0 / total
|
percent_scale = 100.0 / total
|
||||||
|
|
||||||
prev_percent = 0
|
prev_percent = 0
|
||||||
rad_mult = 3.6 * RADIANS
|
rad_mult = 3.6 * RADIANS
|
||||||
@config[:fields].each_index { |count|
|
@config[:fields].each_index { |count|
|
||||||
value = @data[count]
|
value = @data[count]
|
||||||
percent = percent_scale * value
|
percent = percent_scale * value
|
||||||
|
|
||||||
radians = prev_percent * rad_mult
|
radians = prev_percent * rad_mult
|
||||||
x_start = radius+(Math.sin(radians) * radius)
|
x_start = radius+(Math.sin(radians) * radius)
|
||||||
y_start = radius-(Math.cos(radians) * radius)
|
y_start = radius-(Math.cos(radians) * radius)
|
||||||
radians = (prev_percent+percent) * rad_mult
|
radians = (prev_percent+percent) * rad_mult
|
||||||
x_end = radius+(Math.sin(radians) * radius)
|
x_end = radius+(Math.sin(radians) * radius)
|
||||||
x_end -= 0.00001 if @data.length == 1
|
x_end -= 0.00001 if @data.length == 1
|
||||||
y_end = radius-(Math.cos(radians) * radius)
|
y_end = radius-(Math.cos(radians) * radius)
|
||||||
path = "M#{radius},#{radius} L#{x_start},#{y_start} "+
|
path = "M#{radius},#{radius} L#{x_start},#{y_start} "+
|
||||||
"A#{radius},#{radius} "+
|
"A#{radius},#{radius} "+
|
||||||
"0, #{percent >= 50 ? '1' : '0'},1, "+
|
"0, #{percent >= 50 ? '1' : '0'},1, "+
|
||||||
"#{x_end} #{y_end} Z"
|
"#{x_end} #{y_end} Z"
|
||||||
|
|
||||||
|
|
||||||
wedge = @foreground.add_element( "path", {
|
wedge = @foreground.add_element( "path", {
|
||||||
"d" => path,
|
"d" => path,
|
||||||
"class" => "fill#{count+1}"
|
"class" => "fill#{count+1}"
|
||||||
})
|
})
|
||||||
|
|
||||||
translate = nil
|
translate = nil
|
||||||
tx = 0
|
tx = 0
|
||||||
ty = 0
|
ty = 0
|
||||||
half_percent = prev_percent + percent / 2
|
half_percent = prev_percent + percent / 2
|
||||||
radians = half_percent * rad_mult
|
radians = half_percent * rad_mult
|
||||||
|
|
||||||
if show_shadow
|
if show_shadow
|
||||||
shadow = background.add_element( "path", {
|
shadow = background.add_element( "path", {
|
||||||
"d" => path,
|
"d" => path,
|
||||||
"filter" => "url(#dropshadow)",
|
"filter" => "url(#dropshadow)",
|
||||||
"style" => "fill: #ccc; stroke: none;"
|
"style" => "fill: #ccc; stroke: none;"
|
||||||
})
|
})
|
||||||
clear = midground.add_element( "path", {
|
clear = midground.add_element( "path", {
|
||||||
"d" => path,
|
"d" => path,
|
||||||
"style" => "fill: #fff; stroke: none;"
|
"style" => "fill: #fff; stroke: none;"
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
if expanded or (expand_greatest && value == max_value)
|
if expanded or (expand_greatest && value == max_value)
|
||||||
tx = (Math.sin(radians) * expand_gap)
|
tx = (Math.sin(radians) * expand_gap)
|
||||||
ty = -(Math.cos(radians) * expand_gap)
|
ty = -(Math.cos(radians) * expand_gap)
|
||||||
translate = "translate( #{tx} #{ty} )"
|
translate = "translate( #{tx} #{ty} )"
|
||||||
wedge.attributes["transform"] = translate
|
wedge.attributes["transform"] = translate
|
||||||
clear.attributes["transform"] = translate if clear
|
clear.attributes["transform"] = translate if clear
|
||||||
end
|
end
|
||||||
|
|
||||||
if show_shadow
|
if show_shadow
|
||||||
shadow.attributes["transform"] =
|
shadow.attributes["transform"] =
|
||||||
"translate( #{tx+shadow_offset} #{ty+shadow_offset} )"
|
"translate( #{tx+shadow_offset} #{ty+shadow_offset} )"
|
||||||
end
|
end
|
||||||
|
|
||||||
if show_data_labels and value != 0
|
if show_data_labels and value != 0
|
||||||
label = ""
|
label = ""
|
||||||
label += @config[:fields][count] if show_key_data_labels
|
label += @config[:fields][count] if show_key_data_labels
|
||||||
label += " ["+value.to_s+"]" if show_actual_values
|
label += " ["+value.to_s+"]" if show_actual_values
|
||||||
label += " "+percent.round.to_s+"%" if show_percent
|
label += " "+percent.round.to_s+"%" if show_percent
|
||||||
|
|
||||||
msr = Math.sin(radians)
|
msr = Math.sin(radians)
|
||||||
mcr = Math.cos(radians)
|
mcr = Math.cos(radians)
|
||||||
tx = radius + (msr * radius)
|
tx = radius + (msr * radius)
|
||||||
ty = radius -(mcr * radius)
|
ty = radius -(mcr * radius)
|
||||||
|
|
||||||
if expanded or (expand_greatest && value == max_value)
|
if expanded or (expand_greatest && value == max_value)
|
||||||
tx += (msr * expand_gap)
|
tx += (msr * expand_gap)
|
||||||
ty -= (mcr * expand_gap)
|
ty -= (mcr * expand_gap)
|
||||||
end
|
end
|
||||||
@foreground.add_element( "text", {
|
@foreground.add_element( "text", {
|
||||||
"x" => tx.to_s,
|
"x" => tx.to_s,
|
||||||
"y" => ty.to_s,
|
"y" => ty.to_s,
|
||||||
"class" => "dataPointLabel",
|
"class" => "dataPointLabel",
|
||||||
"style" => "stroke: #fff; stroke-width: 2;"
|
"style" => "stroke: #fff; stroke-width: 2;"
|
||||||
}).text = label.to_s
|
}).text = label.to_s
|
||||||
@foreground.add_element( "text", {
|
@foreground.add_element( "text", {
|
||||||
"x" => tx.to_s,
|
"x" => tx.to_s,
|
||||||
"y" => ty.to_s,
|
"y" => ty.to_s,
|
||||||
"class" => "dataPointLabel",
|
"class" => "dataPointLabel",
|
||||||
}).text = label.to_s
|
}).text = label.to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
prev_percent += percent
|
prev_percent += percent
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def round val, to
|
def round val, to
|
||||||
up = 10**to.to_f
|
up = 10**to.to_f
|
||||||
(val * up).to_i / up
|
(val * up).to_i / up
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def get_css
|
def get_css
|
||||||
return <<EOL
|
return <<EOL
|
||||||
.dataPointLabel{
|
.dataPointLabel{
|
||||||
fill: #000000;
|
fill: #000000;
|
||||||
text-anchor:middle;
|
text-anchor:middle;
|
||||||
font-size: #{datapoint_font_size}px;
|
font-size: #{datapoint_font_size}px;
|
||||||
font-family: "Arial", sans-serif;
|
font-family: "Arial", sans-serif;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* key - MUST match fill styles */
|
/* key - MUST match fill styles */
|
||||||
.key1,.fill1{
|
.key1,.fill1{
|
||||||
fill: #ff0000;
|
fill: #ff0000;
|
||||||
fill-opacity: 0.7;
|
fill-opacity: 0.7;
|
||||||
stroke: none;
|
stroke: none;
|
||||||
stroke-width: 1px;
|
stroke-width: 1px;
|
||||||
}
|
}
|
||||||
.key2,.fill2{
|
.key2,.fill2{
|
||||||
fill: #0000ff;
|
fill: #0000ff;
|
||||||
fill-opacity: 0.7;
|
fill-opacity: 0.7;
|
||||||
stroke: none;
|
stroke: none;
|
||||||
stroke-width: 1px;
|
stroke-width: 1px;
|
||||||
}
|
}
|
||||||
.key3,.fill3{
|
.key3,.fill3{
|
||||||
fill-opacity: 0.7;
|
fill-opacity: 0.7;
|
||||||
fill: #00ff00;
|
fill: #00ff00;
|
||||||
stroke: none;
|
stroke: none;
|
||||||
stroke-width: 1px;
|
stroke-width: 1px;
|
||||||
}
|
}
|
||||||
.key4,.fill4{
|
.key4,.fill4{
|
||||||
fill-opacity: 0.7;
|
fill-opacity: 0.7;
|
||||||
fill: #ffcc00;
|
fill: #ffcc00;
|
||||||
stroke: none;
|
stroke: none;
|
||||||
stroke-width: 1px;
|
stroke-width: 1px;
|
||||||
}
|
}
|
||||||
.key5,.fill5{
|
.key5,.fill5{
|
||||||
fill-opacity: 0.7;
|
fill-opacity: 0.7;
|
||||||
fill: #00ccff;
|
fill: #00ccff;
|
||||||
stroke: none;
|
stroke: none;
|
||||||
stroke-width: 1px;
|
stroke-width: 1px;
|
||||||
}
|
}
|
||||||
.key6,.fill6{
|
.key6,.fill6{
|
||||||
fill-opacity: 0.7;
|
fill-opacity: 0.7;
|
||||||
fill: #ff00ff;
|
fill: #ff00ff;
|
||||||
stroke: none;
|
stroke: none;
|
||||||
stroke-width: 1px;
|
stroke-width: 1px;
|
||||||
}
|
}
|
||||||
.key7,.fill7{
|
.key7,.fill7{
|
||||||
fill-opacity: 0.7;
|
fill-opacity: 0.7;
|
||||||
fill: #00ff99;
|
fill: #00ff99;
|
||||||
stroke: none;
|
stroke: none;
|
||||||
stroke-width: 1px;
|
stroke-width: 1px;
|
||||||
}
|
}
|
||||||
.key8,.fill8{
|
.key8,.fill8{
|
||||||
fill-opacity: 0.7;
|
fill-opacity: 0.7;
|
||||||
fill: #ffff00;
|
fill: #ffff00;
|
||||||
stroke: none;
|
stroke: none;
|
||||||
stroke-width: 1px;
|
stroke-width: 1px;
|
||||||
}
|
}
|
||||||
.key9,.fill9{
|
.key9,.fill9{
|
||||||
fill-opacity: 0.7;
|
fill-opacity: 0.7;
|
||||||
fill: #cc6666;
|
fill: #cc6666;
|
||||||
stroke: none;
|
stroke: none;
|
||||||
stroke-width: 1px;
|
stroke-width: 1px;
|
||||||
}
|
}
|
||||||
.key10,.fill10{
|
.key10,.fill10{
|
||||||
fill-opacity: 0.7;
|
fill-opacity: 0.7;
|
||||||
fill: #663399;
|
fill: #663399;
|
||||||
stroke: none;
|
stroke: none;
|
||||||
stroke-width: 1px;
|
stroke-width: 1px;
|
||||||
}
|
}
|
||||||
.key11,.fill11{
|
.key11,.fill11{
|
||||||
fill-opacity: 0.7;
|
fill-opacity: 0.7;
|
||||||
fill: #339900;
|
fill: #339900;
|
||||||
stroke: none;
|
stroke: none;
|
||||||
stroke-width: 1px;
|
stroke-width: 1px;
|
||||||
}
|
}
|
||||||
.key12,.fill12{
|
.key12,.fill12{
|
||||||
fill-opacity: 0.7;
|
fill-opacity: 0.7;
|
||||||
fill: #9966FF;
|
fill: #9966FF;
|
||||||
stroke: none;
|
stroke: none;
|
||||||
stroke-width: 1px;
|
stroke-width: 1px;
|
||||||
}
|
}
|
||||||
EOL
|
EOL
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,241 +1,241 @@
|
|||||||
require 'SVG/Graph/Plot'
|
require 'SVG/Graph/Plot'
|
||||||
require 'parsedate'
|
require 'parsedate'
|
||||||
|
|
||||||
module SVG
|
module SVG
|
||||||
module Graph
|
module Graph
|
||||||
# === For creating SVG plots of scalar temporal data
|
# === For creating SVG plots of scalar temporal data
|
||||||
#
|
#
|
||||||
# = Synopsis
|
# = Synopsis
|
||||||
#
|
#
|
||||||
# require 'SVG/Graph/TimeSeriess'
|
# require 'SVG/Graph/TimeSeriess'
|
||||||
#
|
#
|
||||||
# # Data sets are x,y pairs
|
# # Data sets are x,y pairs
|
||||||
# data1 = ["6/17/72", 11, "1/11/72", 7, "4/13/04 17:31", 11,
|
# data1 = ["6/17/72", 11, "1/11/72", 7, "4/13/04 17:31", 11,
|
||||||
# "9/11/01", 9, "9/1/85", 2, "9/1/88", 1, "1/15/95", 13]
|
# "9/11/01", 9, "9/1/85", 2, "9/1/88", 1, "1/15/95", 13]
|
||||||
# data2 = ["8/1/73", 18, "3/1/77", 15, "10/1/98", 4,
|
# data2 = ["8/1/73", 18, "3/1/77", 15, "10/1/98", 4,
|
||||||
# "5/1/02", 14, "3/1/95", 6, "8/1/91", 12, "12/1/87", 6,
|
# "5/1/02", 14, "3/1/95", 6, "8/1/91", 12, "12/1/87", 6,
|
||||||
# "5/1/84", 17, "10/1/80", 12]
|
# "5/1/84", 17, "10/1/80", 12]
|
||||||
#
|
#
|
||||||
# graph = SVG::Graph::TimeSeries.new( {
|
# graph = SVG::Graph::TimeSeries.new( {
|
||||||
# :width => 640,
|
# :width => 640,
|
||||||
# :height => 480,
|
# :height => 480,
|
||||||
# :graph_title => title,
|
# :graph_title => title,
|
||||||
# :show_graph_title => true,
|
# :show_graph_title => true,
|
||||||
# :no_css => true,
|
# :no_css => true,
|
||||||
# :key => true,
|
# :key => true,
|
||||||
# :scale_x_integers => true,
|
# :scale_x_integers => true,
|
||||||
# :scale_y_integers => true,
|
# :scale_y_integers => true,
|
||||||
# :min_x_value => 0,
|
# :min_x_value => 0,
|
||||||
# :min_y_value => 0,
|
# :min_y_value => 0,
|
||||||
# :show_data_labels => true,
|
# :show_data_labels => true,
|
||||||
# :show_x_guidelines => true,
|
# :show_x_guidelines => true,
|
||||||
# :show_x_title => true,
|
# :show_x_title => true,
|
||||||
# :x_title => "Time",
|
# :x_title => "Time",
|
||||||
# :show_y_title => true,
|
# :show_y_title => true,
|
||||||
# :y_title => "Ice Cream Cones",
|
# :y_title => "Ice Cream Cones",
|
||||||
# :y_title_text_direction => :bt,
|
# :y_title_text_direction => :bt,
|
||||||
# :stagger_x_labels => true,
|
# :stagger_x_labels => true,
|
||||||
# :x_label_format => "%m/%d/%y",
|
# :x_label_format => "%m/%d/%y",
|
||||||
# })
|
# })
|
||||||
#
|
#
|
||||||
# graph.add_data({
|
# graph.add_data({
|
||||||
# :data => projection
|
# :data => projection
|
||||||
# :title => 'Projected',
|
# :title => 'Projected',
|
||||||
# })
|
# })
|
||||||
#
|
#
|
||||||
# graph.add_data({
|
# graph.add_data({
|
||||||
# :data => actual,
|
# :data => actual,
|
||||||
# :title => 'Actual',
|
# :title => 'Actual',
|
||||||
# })
|
# })
|
||||||
#
|
#
|
||||||
# print graph.burn()
|
# print graph.burn()
|
||||||
#
|
#
|
||||||
# = Description
|
# = Description
|
||||||
#
|
#
|
||||||
# Produces a graph of temporal scalar data.
|
# Produces a graph of temporal scalar data.
|
||||||
#
|
#
|
||||||
# = Examples
|
# = Examples
|
||||||
#
|
#
|
||||||
# http://www.germane-software/repositories/public/SVG/test/timeseries.rb
|
# http://www.germane-software/repositories/public/SVG/test/timeseries.rb
|
||||||
#
|
#
|
||||||
# = Notes
|
# = Notes
|
||||||
#
|
#
|
||||||
# The default stylesheet handles upto 10 data sets, if you
|
# The default stylesheet handles upto 10 data sets, if you
|
||||||
# use more you must create your own stylesheet and add the
|
# use more you must create your own stylesheet and add the
|
||||||
# additional settings for the extra data sets. You will know
|
# additional settings for the extra data sets. You will know
|
||||||
# if you go over 10 data sets as they will have no style and
|
# if you go over 10 data sets as they will have no style and
|
||||||
# be in black.
|
# be in black.
|
||||||
#
|
#
|
||||||
# Unlike the other types of charts, data sets must contain x,y pairs:
|
# Unlike the other types of charts, data sets must contain x,y pairs:
|
||||||
#
|
#
|
||||||
# [ "12:30", 2 ] # A data set with 1 point: ("12:30",2)
|
# [ "12:30", 2 ] # A data set with 1 point: ("12:30",2)
|
||||||
# [ "01:00",2, "14:20",6] # A data set with 2 points: ("01:00",2) and
|
# [ "01:00",2, "14:20",6] # A data set with 2 points: ("01:00",2) and
|
||||||
# # ("14:20",6)
|
# # ("14:20",6)
|
||||||
#
|
#
|
||||||
# Note that multiple data sets within the same chart can differ in length,
|
# Note that multiple data sets within the same chart can differ in length,
|
||||||
# and that the data in the datasets needn't be in order; they will be ordered
|
# and that the data in the datasets needn't be in order; they will be ordered
|
||||||
# by the plot along the X-axis.
|
# by the plot along the X-axis.
|
||||||
#
|
#
|
||||||
# The dates must be parseable by ParseDate, but otherwise can be
|
# The dates must be parseable by ParseDate, but otherwise can be
|
||||||
# any order of magnitude (seconds within the hour, or years)
|
# any order of magnitude (seconds within the hour, or years)
|
||||||
#
|
#
|
||||||
# = See also
|
# = See also
|
||||||
#
|
#
|
||||||
# * SVG::Graph::Graph
|
# * SVG::Graph::Graph
|
||||||
# * SVG::Graph::BarHorizontal
|
# * SVG::Graph::BarHorizontal
|
||||||
# * SVG::Graph::Bar
|
# * SVG::Graph::Bar
|
||||||
# * SVG::Graph::Line
|
# * SVG::Graph::Line
|
||||||
# * SVG::Graph::Pie
|
# * SVG::Graph::Pie
|
||||||
# * SVG::Graph::Plot
|
# * SVG::Graph::Plot
|
||||||
#
|
#
|
||||||
# == Author
|
# == Author
|
||||||
#
|
#
|
||||||
# Sean E. Russell <serATgermaneHYPHENsoftwareDOTcom>
|
# Sean E. Russell <serATgermaneHYPHENsoftwareDOTcom>
|
||||||
#
|
#
|
||||||
# Copyright 2004 Sean E. Russell
|
# Copyright 2004 Sean E. Russell
|
||||||
# This software is available under the Ruby license[LICENSE.txt]
|
# This software is available under the Ruby license[LICENSE.txt]
|
||||||
#
|
#
|
||||||
class TimeSeries < Plot
|
class TimeSeries < Plot
|
||||||
# In addition to the defaults set by Graph::initialize and
|
# In addition to the defaults set by Graph::initialize and
|
||||||
# Plot::set_defaults, sets:
|
# Plot::set_defaults, sets:
|
||||||
# [x_label_format] '%Y-%m-%d %H:%M:%S'
|
# [x_label_format] '%Y-%m-%d %H:%M:%S'
|
||||||
# [popup_format] '%Y-%m-%d %H:%M:%S'
|
# [popup_format] '%Y-%m-%d %H:%M:%S'
|
||||||
def set_defaults
|
def set_defaults
|
||||||
super
|
super
|
||||||
init_with(
|
init_with(
|
||||||
#:max_time_span => '',
|
#:max_time_span => '',
|
||||||
:x_label_format => '%Y-%m-%d %H:%M:%S',
|
:x_label_format => '%Y-%m-%d %H:%M:%S',
|
||||||
:popup_format => '%Y-%m-%d %H:%M:%S'
|
:popup_format => '%Y-%m-%d %H:%M:%S'
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
# The format string use do format the X axis labels.
|
# The format string use do format the X axis labels.
|
||||||
# See Time::strformat
|
# See Time::strformat
|
||||||
attr_accessor :x_label_format
|
attr_accessor :x_label_format
|
||||||
# Use this to set the spacing between dates on the axis. The value
|
# Use this to set the spacing between dates on the axis. The value
|
||||||
# must be of the form
|
# must be of the form
|
||||||
# "\d+ ?(days|weeks|months|years|hours|minutes|seconds)?"
|
# "\d+ ?(days|weeks|months|years|hours|minutes|seconds)?"
|
||||||
#
|
#
|
||||||
# EG:
|
# EG:
|
||||||
#
|
#
|
||||||
# graph.timescale_divisions = "2 weeks"
|
# graph.timescale_divisions = "2 weeks"
|
||||||
#
|
#
|
||||||
# will cause the chart to try to divide the X axis up into segments of
|
# will cause the chart to try to divide the X axis up into segments of
|
||||||
# two week periods.
|
# two week periods.
|
||||||
attr_accessor :timescale_divisions
|
attr_accessor :timescale_divisions
|
||||||
# The formatting used for the popups. See x_label_format
|
# The formatting used for the popups. See x_label_format
|
||||||
attr_accessor :popup_format
|
attr_accessor :popup_format
|
||||||
|
|
||||||
# Add data to the plot.
|
# Add data to the plot.
|
||||||
#
|
#
|
||||||
# d1 = [ "12:30", 2 ] # A data set with 1 point: ("12:30",2)
|
# d1 = [ "12:30", 2 ] # A data set with 1 point: ("12:30",2)
|
||||||
# d2 = [ "01:00",2, "14:20",6] # A data set with 2 points: ("01:00",2) and
|
# d2 = [ "01:00",2, "14:20",6] # A data set with 2 points: ("01:00",2) and
|
||||||
# # ("14:20",6)
|
# # ("14:20",6)
|
||||||
# graph.add_data(
|
# graph.add_data(
|
||||||
# :data => d1,
|
# :data => d1,
|
||||||
# :title => 'One'
|
# :title => 'One'
|
||||||
# )
|
# )
|
||||||
# graph.add_data(
|
# graph.add_data(
|
||||||
# :data => d2,
|
# :data => d2,
|
||||||
# :title => 'Two'
|
# :title => 'Two'
|
||||||
# )
|
# )
|
||||||
#
|
#
|
||||||
# Note that the data must be in time,value pairs, and that the date format
|
# Note that the data must be in time,value pairs, and that the date format
|
||||||
# may be any date that is parseable by ParseDate.
|
# may be any date that is parseable by ParseDate.
|
||||||
def add_data data
|
def add_data data
|
||||||
@data = [] unless @data
|
@data = [] unless @data
|
||||||
|
|
||||||
raise "No data provided by #{@data.inspect}" unless data[:data] and
|
raise "No data provided by #{@data.inspect}" unless data[:data] and
|
||||||
data[:data].kind_of? Array
|
data[:data].kind_of? Array
|
||||||
raise "Data supplied must be x,y pairs! "+
|
raise "Data supplied must be x,y pairs! "+
|
||||||
"The data provided contained an odd set of "+
|
"The data provided contained an odd set of "+
|
||||||
"data points" unless data[:data].length % 2 == 0
|
"data points" unless data[:data].length % 2 == 0
|
||||||
return if data[:data].length == 0
|
return if data[:data].length == 0
|
||||||
|
|
||||||
|
|
||||||
x = []
|
x = []
|
||||||
y = []
|
y = []
|
||||||
data[:data].each_index {|i|
|
data[:data].each_index {|i|
|
||||||
if i%2 == 0
|
if i%2 == 0
|
||||||
arr = ParseDate.parsedate( data[:data][i] )
|
arr = ParseDate.parsedate( data[:data][i] )
|
||||||
t = Time.local( *arr[0,6].compact )
|
t = Time.local( *arr[0,6].compact )
|
||||||
x << t.to_i
|
x << t.to_i
|
||||||
else
|
else
|
||||||
y << data[:data][i]
|
y << data[:data][i]
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
sort( x, y )
|
sort( x, y )
|
||||||
data[:data] = [x,y]
|
data[:data] = [x,y]
|
||||||
@data << data
|
@data << data
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def min_x_value=(value)
|
def min_x_value=(value)
|
||||||
arr = ParseDate.parsedate( value )
|
arr = ParseDate.parsedate( value )
|
||||||
@min_x_value = Time.local( *arr[0,6].compact ).to_i
|
@min_x_value = Time.local( *arr[0,6].compact ).to_i
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def format x, y
|
def format x, y
|
||||||
Time.at( x ).strftime( popup_format )
|
Time.at( x ).strftime( popup_format )
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_x_labels
|
def get_x_labels
|
||||||
get_x_values.collect { |v| Time.at(v).strftime( x_label_format ) }
|
get_x_values.collect { |v| Time.at(v).strftime( x_label_format ) }
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
def get_x_values
|
def get_x_values
|
||||||
rv = []
|
rv = []
|
||||||
min, max, scale_division = x_range
|
min, max, scale_division = x_range
|
||||||
if timescale_divisions
|
if timescale_divisions
|
||||||
timescale_divisions =~ /(\d+) ?(day|week|month|year|hour|minute|second)?/
|
timescale_divisions =~ /(\d+) ?(day|week|month|year|hour|minute|second)?/
|
||||||
division_units = $2 ? $2 : "day"
|
division_units = $2 ? $2 : "day"
|
||||||
amount = $1.to_i
|
amount = $1.to_i
|
||||||
if amount
|
if amount
|
||||||
step = nil
|
step = nil
|
||||||
case division_units
|
case division_units
|
||||||
when "month"
|
when "month"
|
||||||
cur = min
|
cur = min
|
||||||
while cur < max
|
while cur < max
|
||||||
rv << cur
|
rv << cur
|
||||||
arr = Time.at( cur ).to_a
|
arr = Time.at( cur ).to_a
|
||||||
arr[4] += amount
|
arr[4] += amount
|
||||||
if arr[4] > 12
|
if arr[4] > 12
|
||||||
arr[5] += (arr[4] / 12).to_i
|
arr[5] += (arr[4] / 12).to_i
|
||||||
arr[4] = (arr[4] % 12)
|
arr[4] = (arr[4] % 12)
|
||||||
end
|
end
|
||||||
cur = Time.local(*arr).to_i
|
cur = Time.local(*arr).to_i
|
||||||
end
|
end
|
||||||
when "year"
|
when "year"
|
||||||
cur = min
|
cur = min
|
||||||
while cur < max
|
while cur < max
|
||||||
rv << cur
|
rv << cur
|
||||||
arr = Time.at( cur ).to_a
|
arr = Time.at( cur ).to_a
|
||||||
arr[5] += amount
|
arr[5] += amount
|
||||||
cur = Time.local(*arr).to_i
|
cur = Time.local(*arr).to_i
|
||||||
end
|
end
|
||||||
when "week"
|
when "week"
|
||||||
step = 7 * 24 * 60 * 60 * amount
|
step = 7 * 24 * 60 * 60 * amount
|
||||||
when "day"
|
when "day"
|
||||||
step = 24 * 60 * 60 * amount
|
step = 24 * 60 * 60 * amount
|
||||||
when "hour"
|
when "hour"
|
||||||
step = 60 * 60 * amount
|
step = 60 * 60 * amount
|
||||||
when "minute"
|
when "minute"
|
||||||
step = 60 * amount
|
step = 60 * amount
|
||||||
when "second"
|
when "second"
|
||||||
step = amount
|
step = amount
|
||||||
end
|
end
|
||||||
min.step( max, step ) {|v| rv << v} if step
|
min.step( max, step ) {|v| rv << v} if step
|
||||||
|
|
||||||
return rv
|
return rv
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
min.step( max, scale_division ) {|v| rv << v}
|
min.step( max, scale_division ) {|v| rv << v}
|
||||||
return rv
|
return rv
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,282 +1,282 @@
|
|||||||
# Redmine - project management software
|
# Redmine - project management software
|
||||||
# Copyright (C) 2006-2010 Jean-Philippe Lang
|
# Copyright (C) 2006-2010 Jean-Philippe Lang
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or
|
# This program is free software; you can redistribute it and/or
|
||||||
# modify it under the terms of the GNU General Public License
|
# modify it under the terms of the GNU General Public License
|
||||||
# as published by the Free Software Foundation; either version 2
|
# as published by the Free Software Foundation; either version 2
|
||||||
# of the License, or (at your option) any later version.
|
# of the License, or (at your option) any later version.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# This program is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program; if not, write to the Free Software
|
# along with this program; if not, write to the Free Software
|
||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
require 'redmine/scm/adapters/abstract_adapter'
|
require 'redmine/scm/adapters/abstract_adapter'
|
||||||
require 'uri'
|
require 'uri'
|
||||||
|
|
||||||
module Redmine
|
module Redmine
|
||||||
module Scm
|
module Scm
|
||||||
module Adapters
|
module Adapters
|
||||||
class SubversionAdapter < AbstractAdapter
|
class SubversionAdapter < AbstractAdapter
|
||||||
|
|
||||||
# SVN executable name
|
# SVN executable name
|
||||||
SVN_BIN = Redmine::Configuration['scm_subversion_command'] || "svn"
|
SVN_BIN = Redmine::Configuration['scm_subversion_command'] || "svn"
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
def client_command
|
def client_command
|
||||||
@@bin ||= SVN_BIN
|
@@bin ||= SVN_BIN
|
||||||
end
|
end
|
||||||
|
|
||||||
def sq_bin
|
def sq_bin
|
||||||
@@sq_bin ||= shell_quote(SVN_BIN)
|
@@sq_bin ||= shell_quote(SVN_BIN)
|
||||||
end
|
end
|
||||||
|
|
||||||
def client_version
|
def client_version
|
||||||
@@client_version ||= (svn_binary_version || [])
|
@@client_version ||= (svn_binary_version || [])
|
||||||
end
|
end
|
||||||
|
|
||||||
def client_available
|
def client_available
|
||||||
!client_version.empty?
|
!client_version.empty?
|
||||||
end
|
end
|
||||||
|
|
||||||
def svn_binary_version
|
def svn_binary_version
|
||||||
scm_version = scm_version_from_command_line.dup
|
scm_version = scm_version_from_command_line.dup
|
||||||
if scm_version.respond_to?(:force_encoding)
|
if scm_version.respond_to?(:force_encoding)
|
||||||
scm_version.force_encoding('ASCII-8BIT')
|
scm_version.force_encoding('ASCII-8BIT')
|
||||||
end
|
end
|
||||||
if m = scm_version.match(%r{\A(.*?)((\d+\.)+\d+)})
|
if m = scm_version.match(%r{\A(.*?)((\d+\.)+\d+)})
|
||||||
m[2].scan(%r{\d+}).collect(&:to_i)
|
m[2].scan(%r{\d+}).collect(&:to_i)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def scm_version_from_command_line
|
def scm_version_from_command_line
|
||||||
shellout("#{sq_bin} --version") { |io| io.read }.to_s
|
shellout("#{sq_bin} --version") { |io| io.read }.to_s
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Get info about the svn repository
|
# Get info about the svn repository
|
||||||
def info
|
def info
|
||||||
cmd = "#{self.class.sq_bin} info --xml #{target}"
|
cmd = "#{self.class.sq_bin} info --xml #{target}"
|
||||||
cmd << credentials_string
|
cmd << credentials_string
|
||||||
info = nil
|
info = nil
|
||||||
shellout(cmd) do |io|
|
shellout(cmd) do |io|
|
||||||
output = io.read
|
output = io.read
|
||||||
if output.respond_to?(:force_encoding)
|
if output.respond_to?(:force_encoding)
|
||||||
output.force_encoding('UTF-8')
|
output.force_encoding('UTF-8')
|
||||||
end
|
end
|
||||||
begin
|
begin
|
||||||
doc = ActiveSupport::XmlMini.parse(output)
|
doc = ActiveSupport::XmlMini.parse(output)
|
||||||
#root_url = doc.elements["info/entry/repository/root"].text
|
#root_url = doc.elements["info/entry/repository/root"].text
|
||||||
info = Info.new({:root_url => doc['info']['entry']['repository']['root']['__content__'],
|
info = Info.new({:root_url => doc['info']['entry']['repository']['root']['__content__'],
|
||||||
:lastrev => Revision.new({
|
:lastrev => Revision.new({
|
||||||
:identifier => doc['info']['entry']['commit']['revision'],
|
:identifier => doc['info']['entry']['commit']['revision'],
|
||||||
:time => Time.parse(doc['info']['entry']['commit']['date']['__content__']).localtime,
|
:time => Time.parse(doc['info']['entry']['commit']['date']['__content__']).localtime,
|
||||||
:author => (doc['info']['entry']['commit']['author'] ? doc['info']['entry']['commit']['author']['__content__'] : "")
|
:author => (doc['info']['entry']['commit']['author'] ? doc['info']['entry']['commit']['author']['__content__'] : "")
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
rescue
|
rescue
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return nil if $? && $?.exitstatus != 0
|
return nil if $? && $?.exitstatus != 0
|
||||||
info
|
info
|
||||||
rescue CommandFailed
|
rescue CommandFailed
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns an Entries collection
|
# Returns an Entries collection
|
||||||
# or nil if the given path doesn't exist in the repository
|
# or nil if the given path doesn't exist in the repository
|
||||||
def entries(path=nil, identifier=nil)
|
def entries(path=nil, identifier=nil)
|
||||||
path ||= ''
|
path ||= ''
|
||||||
identifier = (identifier and identifier.to_i > 0) ? identifier.to_i : "HEAD"
|
identifier = (identifier and identifier.to_i > 0) ? identifier.to_i : "HEAD"
|
||||||
entries = Entries.new
|
entries = Entries.new
|
||||||
cmd = "#{self.class.sq_bin} list --xml #{target(path)}@#{identifier}"
|
cmd = "#{self.class.sq_bin} list --xml #{target(path)}@#{identifier}"
|
||||||
cmd << credentials_string
|
cmd << credentials_string
|
||||||
shellout(cmd) do |io|
|
shellout(cmd) do |io|
|
||||||
output = io.read
|
output = io.read
|
||||||
if output.respond_to?(:force_encoding)
|
if output.respond_to?(:force_encoding)
|
||||||
output.force_encoding('UTF-8')
|
output.force_encoding('UTF-8')
|
||||||
end
|
end
|
||||||
begin
|
begin
|
||||||
doc = ActiveSupport::XmlMini.parse(output)
|
doc = ActiveSupport::XmlMini.parse(output)
|
||||||
each_xml_element(doc['lists']['list'], 'entry') do |entry|
|
each_xml_element(doc['lists']['list'], 'entry') do |entry|
|
||||||
commit = entry['commit']
|
commit = entry['commit']
|
||||||
commit_date = commit['date']
|
commit_date = commit['date']
|
||||||
# Skip directory if there is no commit date (usually that
|
# Skip directory if there is no commit date (usually that
|
||||||
# means that we don't have read access to it)
|
# means that we don't have read access to it)
|
||||||
next if entry['kind'] == 'dir' && commit_date.nil?
|
next if entry['kind'] == 'dir' && commit_date.nil?
|
||||||
name = entry['name']['__content__']
|
name = entry['name']['__content__']
|
||||||
entries << Entry.new({:name => URI.unescape(name),
|
entries << Entry.new({:name => URI.unescape(name),
|
||||||
:path => ((path.empty? ? "" : "#{path}/") + name),
|
:path => ((path.empty? ? "" : "#{path}/") + name),
|
||||||
:kind => entry['kind'],
|
:kind => entry['kind'],
|
||||||
:size => ((s = entry['size']) ? s['__content__'].to_i : nil),
|
:size => ((s = entry['size']) ? s['__content__'].to_i : nil),
|
||||||
:lastrev => Revision.new({
|
:lastrev => Revision.new({
|
||||||
:identifier => commit['revision'],
|
:identifier => commit['revision'],
|
||||||
:time => Time.parse(commit_date['__content__'].to_s).localtime,
|
:time => Time.parse(commit_date['__content__'].to_s).localtime,
|
||||||
:author => ((a = commit['author']) ? a['__content__'] : nil)
|
:author => ((a = commit['author']) ? a['__content__'] : nil)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
rescue Exception => e
|
rescue Exception => e
|
||||||
logger.error("Error parsing svn output: #{e.message}")
|
logger.error("Error parsing svn output: #{e.message}")
|
||||||
logger.error("Output was:\n #{output}")
|
logger.error("Output was:\n #{output}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return nil if $? && $?.exitstatus != 0
|
return nil if $? && $?.exitstatus != 0
|
||||||
logger.debug("Found #{entries.size} entries in the repository for #{target(path)}") if logger && logger.debug?
|
logger.debug("Found #{entries.size} entries in the repository for #{target(path)}") if logger && logger.debug?
|
||||||
entries.sort_by_name
|
entries.sort_by_name
|
||||||
end
|
end
|
||||||
|
|
||||||
def properties(path, identifier=nil)
|
def properties(path, identifier=nil)
|
||||||
# proplist xml output supported in svn 1.5.0 and higher
|
# proplist xml output supported in svn 1.5.0 and higher
|
||||||
return nil unless self.class.client_version_above?([1, 5, 0])
|
return nil unless self.class.client_version_above?([1, 5, 0])
|
||||||
|
|
||||||
identifier = (identifier and identifier.to_i > 0) ? identifier.to_i : "HEAD"
|
identifier = (identifier and identifier.to_i > 0) ? identifier.to_i : "HEAD"
|
||||||
cmd = "#{self.class.sq_bin} proplist --verbose --xml #{target(path)}@#{identifier}"
|
cmd = "#{self.class.sq_bin} proplist --verbose --xml #{target(path)}@#{identifier}"
|
||||||
cmd << credentials_string
|
cmd << credentials_string
|
||||||
properties = {}
|
properties = {}
|
||||||
shellout(cmd) do |io|
|
shellout(cmd) do |io|
|
||||||
output = io.read
|
output = io.read
|
||||||
if output.respond_to?(:force_encoding)
|
if output.respond_to?(:force_encoding)
|
||||||
output.force_encoding('UTF-8')
|
output.force_encoding('UTF-8')
|
||||||
end
|
end
|
||||||
begin
|
begin
|
||||||
doc = ActiveSupport::XmlMini.parse(output)
|
doc = ActiveSupport::XmlMini.parse(output)
|
||||||
each_xml_element(doc['properties']['target'], 'property') do |property|
|
each_xml_element(doc['properties']['target'], 'property') do |property|
|
||||||
properties[ property['name'] ] = property['__content__'].to_s
|
properties[ property['name'] ] = property['__content__'].to_s
|
||||||
end
|
end
|
||||||
rescue
|
rescue
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return nil if $? && $?.exitstatus != 0
|
return nil if $? && $?.exitstatus != 0
|
||||||
properties
|
properties
|
||||||
end
|
end
|
||||||
|
|
||||||
def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={})
|
def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={})
|
||||||
path ||= ''
|
path ||= ''
|
||||||
identifier_from = (identifier_from && identifier_from.to_i > 0) ? identifier_from.to_i : "HEAD"
|
identifier_from = (identifier_from && identifier_from.to_i > 0) ? identifier_from.to_i : "HEAD"
|
||||||
identifier_to = (identifier_to && identifier_to.to_i > 0) ? identifier_to.to_i : 1
|
identifier_to = (identifier_to && identifier_to.to_i > 0) ? identifier_to.to_i : 1
|
||||||
revisions = Revisions.new
|
revisions = Revisions.new
|
||||||
cmd = "#{self.class.sq_bin} log --xml -r #{identifier_from}:#{identifier_to}"
|
cmd = "#{self.class.sq_bin} log --xml -r #{identifier_from}:#{identifier_to}"
|
||||||
cmd << credentials_string
|
cmd << credentials_string
|
||||||
cmd << " --verbose " if options[:with_paths]
|
cmd << " --verbose " if options[:with_paths]
|
||||||
cmd << " --limit #{options[:limit].to_i}" if options[:limit]
|
cmd << " --limit #{options[:limit].to_i}" if options[:limit]
|
||||||
cmd << ' ' + target(path)
|
cmd << ' ' + target(path)
|
||||||
shellout(cmd) do |io|
|
shellout(cmd) do |io|
|
||||||
output = io.read
|
output = io.read
|
||||||
if output.respond_to?(:force_encoding)
|
if output.respond_to?(:force_encoding)
|
||||||
output.force_encoding('UTF-8')
|
output.force_encoding('UTF-8')
|
||||||
end
|
end
|
||||||
begin
|
begin
|
||||||
doc = ActiveSupport::XmlMini.parse(output)
|
doc = ActiveSupport::XmlMini.parse(output)
|
||||||
each_xml_element(doc['log'], 'logentry') do |logentry|
|
each_xml_element(doc['log'], 'logentry') do |logentry|
|
||||||
paths = []
|
paths = []
|
||||||
each_xml_element(logentry['paths'], 'path') do |path|
|
each_xml_element(logentry['paths'], 'path') do |path|
|
||||||
paths << {:action => path['action'],
|
paths << {:action => path['action'],
|
||||||
:path => path['__content__'],
|
:path => path['__content__'],
|
||||||
:from_path => path['copyfrom-path'],
|
:from_path => path['copyfrom-path'],
|
||||||
:from_revision => path['copyfrom-rev']
|
:from_revision => path['copyfrom-rev']
|
||||||
}
|
}
|
||||||
end if logentry['paths'] && logentry['paths']['path']
|
end if logentry['paths'] && logentry['paths']['path']
|
||||||
paths.sort! { |x,y| x[:path] <=> y[:path] }
|
paths.sort! { |x,y| x[:path] <=> y[:path] }
|
||||||
|
|
||||||
revisions << Revision.new({:identifier => logentry['revision'],
|
revisions << Revision.new({:identifier => logentry['revision'],
|
||||||
:author => (logentry['author'] ? logentry['author']['__content__'] : ""),
|
:author => (logentry['author'] ? logentry['author']['__content__'] : ""),
|
||||||
:time => Time.parse(logentry['date']['__content__'].to_s).localtime,
|
:time => Time.parse(logentry['date']['__content__'].to_s).localtime,
|
||||||
:message => logentry['msg']['__content__'],
|
:message => logentry['msg']['__content__'],
|
||||||
:paths => paths
|
:paths => paths
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
rescue
|
rescue
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return nil if $? && $?.exitstatus != 0
|
return nil if $? && $?.exitstatus != 0
|
||||||
revisions
|
revisions
|
||||||
end
|
end
|
||||||
|
|
||||||
def diff(path, identifier_from, identifier_to=nil, type="inline")
|
def diff(path, identifier_from, identifier_to=nil, type="inline")
|
||||||
path ||= ''
|
path ||= ''
|
||||||
identifier_from = (identifier_from and identifier_from.to_i > 0) ? identifier_from.to_i : ''
|
identifier_from = (identifier_from and identifier_from.to_i > 0) ? identifier_from.to_i : ''
|
||||||
|
|
||||||
identifier_to = (identifier_to and identifier_to.to_i > 0) ? identifier_to.to_i : (identifier_from.to_i - 1)
|
identifier_to = (identifier_to and identifier_to.to_i > 0) ? identifier_to.to_i : (identifier_from.to_i - 1)
|
||||||
|
|
||||||
cmd = "#{self.class.sq_bin} diff -r "
|
cmd = "#{self.class.sq_bin} diff -r "
|
||||||
cmd << "#{identifier_to}:"
|
cmd << "#{identifier_to}:"
|
||||||
cmd << "#{identifier_from}"
|
cmd << "#{identifier_from}"
|
||||||
cmd << " #{target(path)}@#{identifier_from}"
|
cmd << " #{target(path)}@#{identifier_from}"
|
||||||
cmd << credentials_string
|
cmd << credentials_string
|
||||||
diff = []
|
diff = []
|
||||||
shellout(cmd) do |io|
|
shellout(cmd) do |io|
|
||||||
io.each_line do |line|
|
io.each_line do |line|
|
||||||
diff << line
|
diff << line
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return nil if $? && $?.exitstatus != 0
|
return nil if $? && $?.exitstatus != 0
|
||||||
diff
|
diff
|
||||||
end
|
end
|
||||||
|
|
||||||
def cat(path, identifier=nil)
|
def cat(path, identifier=nil)
|
||||||
identifier = (identifier and identifier.to_i > 0) ? identifier.to_i : "HEAD"
|
identifier = (identifier and identifier.to_i > 0) ? identifier.to_i : "HEAD"
|
||||||
cmd = "#{self.class.sq_bin} cat #{target(path)}@#{identifier}"
|
cmd = "#{self.class.sq_bin} cat #{target(path)}@#{identifier}"
|
||||||
cmd << credentials_string
|
cmd << credentials_string
|
||||||
cat = nil
|
cat = nil
|
||||||
shellout(cmd) do |io|
|
shellout(cmd) do |io|
|
||||||
io.binmode
|
io.binmode
|
||||||
cat = io.read
|
cat = io.read
|
||||||
end
|
end
|
||||||
return nil if $? && $?.exitstatus != 0
|
return nil if $? && $?.exitstatus != 0
|
||||||
cat
|
cat
|
||||||
end
|
end
|
||||||
|
|
||||||
def annotate(path, identifier=nil)
|
def annotate(path, identifier=nil)
|
||||||
identifier = (identifier and identifier.to_i > 0) ? identifier.to_i : "HEAD"
|
identifier = (identifier and identifier.to_i > 0) ? identifier.to_i : "HEAD"
|
||||||
cmd = "#{self.class.sq_bin} blame #{target(path)}@#{identifier}"
|
cmd = "#{self.class.sq_bin} blame #{target(path)}@#{identifier}"
|
||||||
cmd << credentials_string
|
cmd << credentials_string
|
||||||
blame = Annotate.new
|
blame = Annotate.new
|
||||||
shellout(cmd) do |io|
|
shellout(cmd) do |io|
|
||||||
io.each_line do |line|
|
io.each_line do |line|
|
||||||
next unless line =~ %r{^\s*(\d+)\s*(\S+)\s(.*)$}
|
next unless line =~ %r{^\s*(\d+)\s*(\S+)\s(.*)$}
|
||||||
blame.add_line($3.rstrip, Revision.new(:identifier => $1.to_i, :author => $2.strip))
|
blame.add_line($3.rstrip, Revision.new(:identifier => $1.to_i, :author => $2.strip))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return nil if $? && $?.exitstatus != 0
|
return nil if $? && $?.exitstatus != 0
|
||||||
blame
|
blame
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def credentials_string
|
def credentials_string
|
||||||
str = ''
|
str = ''
|
||||||
str << " --username #{shell_quote(@login)}" unless @login.blank?
|
str << " --username #{shell_quote(@login)}" unless @login.blank?
|
||||||
str << " --password #{shell_quote(@password)}" unless @login.blank? || @password.blank?
|
str << " --password #{shell_quote(@password)}" unless @login.blank? || @password.blank?
|
||||||
str << " --no-auth-cache --non-interactive"
|
str << " --no-auth-cache --non-interactive"
|
||||||
str
|
str
|
||||||
end
|
end
|
||||||
|
|
||||||
# Helper that iterates over the child elements of a xml node
|
# Helper that iterates over the child elements of a xml node
|
||||||
# MiniXml returns a hash when a single child is found or an array of hashes for multiple children
|
# MiniXml returns a hash when a single child is found or an array of hashes for multiple children
|
||||||
def each_xml_element(node, name)
|
def each_xml_element(node, name)
|
||||||
if node && node[name]
|
if node && node[name]
|
||||||
if node[name].is_a?(Hash)
|
if node[name].is_a?(Hash)
|
||||||
yield node[name]
|
yield node[name]
|
||||||
else
|
else
|
||||||
node[name].each do |element|
|
node[name].each do |element|
|
||||||
yield element
|
yield element
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def target(path = '')
|
def target(path = '')
|
||||||
base = path.match(/^\//) ? root_url : url
|
base = path.match(/^\//) ? root_url : url
|
||||||
uri = "#{base}/#{path}"
|
uri = "#{base}/#{path}"
|
||||||
uri = URI.escape(URI.escape(uri), '[]')
|
uri = URI.escape(URI.escape(uri), '[]')
|
||||||
shell_quote(uri.gsub(/[?<>\*]/, ''))
|
shell_quote(uri.gsub(/[?<>\*]/, ''))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,186 +1,186 @@
|
|||||||
# Redmine - project management software
|
# Redmine - project management software
|
||||||
# Copyright (C) 2006-2008 Jean-Philippe Lang
|
# Copyright (C) 2006-2008 Jean-Philippe Lang
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or
|
# This program is free software; you can redistribute it and/or
|
||||||
# modify it under the terms of the GNU General Public License
|
# modify it under the terms of the GNU General Public License
|
||||||
# as published by the Free Software Foundation; either version 2
|
# as published by the Free Software Foundation; either version 2
|
||||||
# of the License, or (at your option) any later version.
|
# of the License, or (at your option) any later version.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# This program is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program; if not, write to the Free Software
|
# along with this program; if not, write to the Free Software
|
||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
namespace :redmine do
|
namespace :redmine do
|
||||||
namespace :email do
|
namespace :email do
|
||||||
|
|
||||||
desc <<-END_DESC
|
desc <<-END_DESC
|
||||||
Read an email from standard input.
|
Read an email from standard input.
|
||||||
|
|
||||||
General options:
|
General options:
|
||||||
unknown_user=ACTION how to handle emails from an unknown user
|
unknown_user=ACTION how to handle emails from an unknown user
|
||||||
ACTION can be one of the following values:
|
ACTION can be one of the following values:
|
||||||
ignore: email is ignored (default)
|
ignore: email is ignored (default)
|
||||||
accept: accept as anonymous user
|
accept: accept as anonymous user
|
||||||
create: create a user account
|
create: create a user account
|
||||||
no_permission_check=1 disable permission checking when receiving
|
no_permission_check=1 disable permission checking when receiving
|
||||||
the email
|
the email
|
||||||
|
|
||||||
Issue attributes control options:
|
Issue attributes control options:
|
||||||
project=PROJECT identifier of the target project
|
project=PROJECT identifier of the target project
|
||||||
status=STATUS name of the target status
|
status=STATUS name of the target status
|
||||||
tracker=TRACKER name of the target tracker
|
tracker=TRACKER name of the target tracker
|
||||||
category=CATEGORY name of the target category
|
category=CATEGORY name of the target category
|
||||||
priority=PRIORITY name of the target priority
|
priority=PRIORITY name of the target priority
|
||||||
allow_override=ATTRS allow email content to override attributes
|
allow_override=ATTRS allow email content to override attributes
|
||||||
specified by previous options
|
specified by previous options
|
||||||
ATTRS is a comma separated list of attributes
|
ATTRS is a comma separated list of attributes
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
# No project specified. Emails MUST contain the 'Project' keyword:
|
# No project specified. Emails MUST contain the 'Project' keyword:
|
||||||
rake redmine:email:read RAILS_ENV="production" < raw_email
|
rake redmine:email:read RAILS_ENV="production" < raw_email
|
||||||
|
|
||||||
# Fixed project and default tracker specified, but emails can override
|
# Fixed project and default tracker specified, but emails can override
|
||||||
# both tracker and priority attributes:
|
# both tracker and priority attributes:
|
||||||
rake redmine:email:read RAILS_ENV="production" \\
|
rake redmine:email:read RAILS_ENV="production" \\
|
||||||
project=foo \\
|
project=foo \\
|
||||||
tracker=bug \\
|
tracker=bug \\
|
||||||
allow_override=tracker,priority < raw_email
|
allow_override=tracker,priority < raw_email
|
||||||
END_DESC
|
END_DESC
|
||||||
|
|
||||||
task :read => :environment do
|
task :read => :environment do
|
||||||
options = { :issue => {} }
|
options = { :issue => {} }
|
||||||
%w(project status tracker category priority).each { |a| options[:issue][a.to_sym] = ENV[a] if ENV[a] }
|
%w(project status tracker category priority).each { |a| options[:issue][a.to_sym] = ENV[a] if ENV[a] }
|
||||||
options[:allow_override] = ENV['allow_override'] if ENV['allow_override']
|
options[:allow_override] = ENV['allow_override'] if ENV['allow_override']
|
||||||
options[:unknown_user] = ENV['unknown_user'] if ENV['unknown_user']
|
options[:unknown_user] = ENV['unknown_user'] if ENV['unknown_user']
|
||||||
options[:no_permission_check] = ENV['no_permission_check'] if ENV['no_permission_check']
|
options[:no_permission_check] = ENV['no_permission_check'] if ENV['no_permission_check']
|
||||||
|
|
||||||
MailHandler.receive(STDIN.read, options)
|
MailHandler.receive(STDIN.read, options)
|
||||||
end
|
end
|
||||||
|
|
||||||
desc <<-END_DESC
|
desc <<-END_DESC
|
||||||
Read emails from an IMAP server.
|
Read emails from an IMAP server.
|
||||||
|
|
||||||
General options:
|
General options:
|
||||||
unknown_user=ACTION how to handle emails from an unknown user
|
unknown_user=ACTION how to handle emails from an unknown user
|
||||||
ACTION can be one of the following values:
|
ACTION can be one of the following values:
|
||||||
ignore: email is ignored (default)
|
ignore: email is ignored (default)
|
||||||
accept: accept as anonymous user
|
accept: accept as anonymous user
|
||||||
create: create a user account
|
create: create a user account
|
||||||
no_permission_check=1 disable permission checking when receiving
|
no_permission_check=1 disable permission checking when receiving
|
||||||
the email
|
the email
|
||||||
|
|
||||||
Available IMAP options:
|
Available IMAP options:
|
||||||
host=HOST IMAP server host (default: 127.0.0.1)
|
host=HOST IMAP server host (default: 127.0.0.1)
|
||||||
port=PORT IMAP server port (default: 143)
|
port=PORT IMAP server port (default: 143)
|
||||||
ssl=SSL Use SSL? (default: false)
|
ssl=SSL Use SSL? (default: false)
|
||||||
username=USERNAME IMAP account
|
username=USERNAME IMAP account
|
||||||
password=PASSWORD IMAP password
|
password=PASSWORD IMAP password
|
||||||
folder=FOLDER IMAP folder to read (default: INBOX)
|
folder=FOLDER IMAP folder to read (default: INBOX)
|
||||||
|
|
||||||
Issue attributes control options:
|
Issue attributes control options:
|
||||||
project=PROJECT identifier of the target project
|
project=PROJECT identifier of the target project
|
||||||
status=STATUS name of the target status
|
status=STATUS name of the target status
|
||||||
tracker=TRACKER name of the target tracker
|
tracker=TRACKER name of the target tracker
|
||||||
category=CATEGORY name of the target category
|
category=CATEGORY name of the target category
|
||||||
priority=PRIORITY name of the target priority
|
priority=PRIORITY name of the target priority
|
||||||
allow_override=ATTRS allow email content to override attributes
|
allow_override=ATTRS allow email content to override attributes
|
||||||
specified by previous options
|
specified by previous options
|
||||||
ATTRS is a comma separated list of attributes
|
ATTRS is a comma separated list of attributes
|
||||||
|
|
||||||
Processed emails control options:
|
Processed emails control options:
|
||||||
move_on_success=MAILBOX move emails that were successfully received
|
move_on_success=MAILBOX move emails that were successfully received
|
||||||
to MAILBOX instead of deleting them
|
to MAILBOX instead of deleting them
|
||||||
move_on_failure=MAILBOX move emails that were ignored to MAILBOX
|
move_on_failure=MAILBOX move emails that were ignored to MAILBOX
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
# No project specified. Emails MUST contain the 'Project' keyword:
|
# No project specified. Emails MUST contain the 'Project' keyword:
|
||||||
|
|
||||||
rake redmine:email:receive_iamp RAILS_ENV="production" \\
|
rake redmine:email:receive_iamp RAILS_ENV="production" \\
|
||||||
host=imap.foo.bar username=redmine@example.net password=xxx
|
host=imap.foo.bar username=redmine@example.net password=xxx
|
||||||
|
|
||||||
|
|
||||||
# Fixed project and default tracker specified, but emails can override
|
# Fixed project and default tracker specified, but emails can override
|
||||||
# both tracker and priority attributes:
|
# both tracker and priority attributes:
|
||||||
|
|
||||||
rake redmine:email:receive_iamp RAILS_ENV="production" \\
|
rake redmine:email:receive_iamp RAILS_ENV="production" \\
|
||||||
host=imap.foo.bar username=redmine@example.net password=xxx ssl=1 \\
|
host=imap.foo.bar username=redmine@example.net password=xxx ssl=1 \\
|
||||||
project=foo \\
|
project=foo \\
|
||||||
tracker=bug \\
|
tracker=bug \\
|
||||||
allow_override=tracker,priority
|
allow_override=tracker,priority
|
||||||
END_DESC
|
END_DESC
|
||||||
|
|
||||||
task :receive_imap => :environment do
|
task :receive_imap => :environment do
|
||||||
imap_options = {:host => ENV['host'],
|
imap_options = {:host => ENV['host'],
|
||||||
:port => ENV['port'],
|
:port => ENV['port'],
|
||||||
:ssl => ENV['ssl'],
|
:ssl => ENV['ssl'],
|
||||||
:username => ENV['username'],
|
:username => ENV['username'],
|
||||||
:password => ENV['password'],
|
:password => ENV['password'],
|
||||||
:folder => ENV['folder'],
|
:folder => ENV['folder'],
|
||||||
:move_on_success => ENV['move_on_success'],
|
:move_on_success => ENV['move_on_success'],
|
||||||
:move_on_failure => ENV['move_on_failure']}
|
:move_on_failure => ENV['move_on_failure']}
|
||||||
|
|
||||||
options = { :issue => {} }
|
options = { :issue => {} }
|
||||||
%w(project status tracker category priority).each { |a| options[:issue][a.to_sym] = ENV[a] if ENV[a] }
|
%w(project status tracker category priority).each { |a| options[:issue][a.to_sym] = ENV[a] if ENV[a] }
|
||||||
options[:allow_override] = ENV['allow_override'] if ENV['allow_override']
|
options[:allow_override] = ENV['allow_override'] if ENV['allow_override']
|
||||||
options[:unknown_user] = ENV['unknown_user'] if ENV['unknown_user']
|
options[:unknown_user] = ENV['unknown_user'] if ENV['unknown_user']
|
||||||
options[:no_permission_check] = ENV['no_permission_check'] if ENV['no_permission_check']
|
options[:no_permission_check] = ENV['no_permission_check'] if ENV['no_permission_check']
|
||||||
|
|
||||||
Redmine::IMAP.check(imap_options, options)
|
Redmine::IMAP.check(imap_options, options)
|
||||||
end
|
end
|
||||||
|
|
||||||
desc <<-END_DESC
|
desc <<-END_DESC
|
||||||
Read emails from an POP3 server.
|
Read emails from an POP3 server.
|
||||||
|
|
||||||
Available POP3 options:
|
Available POP3 options:
|
||||||
host=HOST POP3 server host (default: 127.0.0.1)
|
host=HOST POP3 server host (default: 127.0.0.1)
|
||||||
port=PORT POP3 server port (default: 110)
|
port=PORT POP3 server port (default: 110)
|
||||||
username=USERNAME POP3 account
|
username=USERNAME POP3 account
|
||||||
password=PASSWORD POP3 password
|
password=PASSWORD POP3 password
|
||||||
apop=1 use APOP authentication (default: false)
|
apop=1 use APOP authentication (default: false)
|
||||||
delete_unprocessed=1 delete messages that could not be processed
|
delete_unprocessed=1 delete messages that could not be processed
|
||||||
successfully from the server (default
|
successfully from the server (default
|
||||||
behaviour is to leave them on the server)
|
behaviour is to leave them on the server)
|
||||||
|
|
||||||
See redmine:email:receive_imap for more options and examples.
|
See redmine:email:receive_imap for more options and examples.
|
||||||
END_DESC
|
END_DESC
|
||||||
|
|
||||||
task :receive_pop3 => :environment do
|
task :receive_pop3 => :environment do
|
||||||
pop_options = {:host => ENV['host'],
|
pop_options = {:host => ENV['host'],
|
||||||
:port => ENV['port'],
|
:port => ENV['port'],
|
||||||
:apop => ENV['apop'],
|
:apop => ENV['apop'],
|
||||||
:username => ENV['username'],
|
:username => ENV['username'],
|
||||||
:password => ENV['password'],
|
:password => ENV['password'],
|
||||||
:delete_unprocessed => ENV['delete_unprocessed']}
|
:delete_unprocessed => ENV['delete_unprocessed']}
|
||||||
|
|
||||||
options = { :issue => {} }
|
options = { :issue => {} }
|
||||||
%w(project status tracker category priority).each { |a| options[:issue][a.to_sym] = ENV[a] if ENV[a] }
|
%w(project status tracker category priority).each { |a| options[:issue][a.to_sym] = ENV[a] if ENV[a] }
|
||||||
options[:allow_override] = ENV['allow_override'] if ENV['allow_override']
|
options[:allow_override] = ENV['allow_override'] if ENV['allow_override']
|
||||||
options[:unknown_user] = ENV['unknown_user'] if ENV['unknown_user']
|
options[:unknown_user] = ENV['unknown_user'] if ENV['unknown_user']
|
||||||
options[:no_permission_check] = ENV['no_permission_check'] if ENV['no_permission_check']
|
options[:no_permission_check] = ENV['no_permission_check'] if ENV['no_permission_check']
|
||||||
|
|
||||||
Redmine::POP3.check(pop_options, options)
|
Redmine::POP3.check(pop_options, options)
|
||||||
end
|
end
|
||||||
|
|
||||||
desc "Send a test email to the user with the provided login name"
|
desc "Send a test email to the user with the provided login name"
|
||||||
task :test, [:login] => :environment do |task, args|
|
task :test, [:login] => :environment do |task, args|
|
||||||
include Redmine::I18n
|
include Redmine::I18n
|
||||||
abort l(:notice_email_error, "Please include the user login to test with. Example: login=example-login") if args[:login].blank?
|
abort l(:notice_email_error, "Please include the user login to test with. Example: login=example-login") if args[:login].blank?
|
||||||
|
|
||||||
user = User.find_by_login(args[:login])
|
user = User.find_by_login(args[:login])
|
||||||
abort l(:notice_email_error, "User #{args[:login]} not found") unless user && user.logged?
|
abort l(:notice_email_error, "User #{args[:login]} not found") unless user && user.logged?
|
||||||
|
|
||||||
ActionMailer::Base.raise_delivery_errors = true
|
ActionMailer::Base.raise_delivery_errors = true
|
||||||
begin
|
begin
|
||||||
Mailer.deliver_test(User.current)
|
Mailer.deliver_test(User.current)
|
||||||
puts l(:notice_email_sent, user.mail)
|
puts l(:notice_email_sent, user.mail)
|
||||||
rescue Exception => e
|
rescue Exception => e
|
||||||
abort l(:notice_email_error, e.message)
|
abort l(:notice_email_error, e.message)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,24 +1,24 @@
|
|||||||
desc 'Create YAML test fixtures from data in an existing database.
|
desc 'Create YAML test fixtures from data in an existing database.
|
||||||
Defaults to development database. Set RAILS_ENV to override.'
|
Defaults to development database. Set RAILS_ENV to override.'
|
||||||
|
|
||||||
task :extract_fixtures => :environment do
|
task :extract_fixtures => :environment do
|
||||||
sql = "SELECT * FROM %s"
|
sql = "SELECT * FROM %s"
|
||||||
skip_tables = ["schema_info"]
|
skip_tables = ["schema_info"]
|
||||||
ActiveRecord::Base.establish_connection
|
ActiveRecord::Base.establish_connection
|
||||||
(ActiveRecord::Base.connection.tables - skip_tables).each do |table_name|
|
(ActiveRecord::Base.connection.tables - skip_tables).each do |table_name|
|
||||||
i = "000"
|
i = "000"
|
||||||
File.open("#{RAILS_ROOT}/#{table_name}.yml", 'w' ) do |file|
|
File.open("#{RAILS_ROOT}/#{table_name}.yml", 'w' ) do |file|
|
||||||
data = ActiveRecord::Base.connection.select_all(sql % table_name)
|
data = ActiveRecord::Base.connection.select_all(sql % table_name)
|
||||||
file.write data.inject({}) { |hash, record|
|
file.write data.inject({}) { |hash, record|
|
||||||
|
|
||||||
# cast extracted values
|
# cast extracted values
|
||||||
ActiveRecord::Base.connection.columns(table_name).each { |col|
|
ActiveRecord::Base.connection.columns(table_name).each { |col|
|
||||||
record[col.name] = col.type_cast(record[col.name]) if record[col.name]
|
record[col.name] = col.type_cast(record[col.name]) if record[col.name]
|
||||||
}
|
}
|
||||||
|
|
||||||
hash["#{table_name}_#{i.succ!}"] = record
|
hash["#{table_name}_#{i.succ!}"] = record
|
||||||
hash
|
hash
|
||||||
}.to_yaml
|
}.to_yaml
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
@ -1,24 +1,24 @@
|
|||||||
# redMine - project management software
|
# redMine - project management software
|
||||||
# Copyright (C) 2006-2008 Jean-Philippe Lang
|
# Copyright (C) 2006-2008 Jean-Philippe Lang
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or
|
# This program is free software; you can redistribute it and/or
|
||||||
# modify it under the terms of the GNU General Public License
|
# modify it under the terms of the GNU General Public License
|
||||||
# as published by the Free Software Foundation; either version 2
|
# as published by the Free Software Foundation; either version 2
|
||||||
# of the License, or (at your option) any later version.
|
# of the License, or (at your option) any later version.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# This program is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program; if not, write to the Free Software
|
# along with this program; if not, write to the Free Software
|
||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
desc 'Fetch changesets from the repositories'
|
desc 'Fetch changesets from the repositories'
|
||||||
|
|
||||||
namespace :redmine do
|
namespace :redmine do
|
||||||
task :fetch_changesets => :environment do
|
task :fetch_changesets => :environment do
|
||||||
Repository.fetch_changesets
|
Repository.fetch_changesets
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,35 +1,35 @@
|
|||||||
desc 'Load Redmine default configuration data. Language is chosen interactively or by setting REDMINE_LANG environment variable.'
|
desc 'Load Redmine default configuration data. Language is chosen interactively or by setting REDMINE_LANG environment variable.'
|
||||||
|
|
||||||
namespace :redmine do
|
namespace :redmine do
|
||||||
task :load_default_data => :environment do
|
task :load_default_data => :environment do
|
||||||
include Redmine::I18n
|
include Redmine::I18n
|
||||||
set_language_if_valid('en')
|
set_language_if_valid('en')
|
||||||
|
|
||||||
envlang = ENV['REDMINE_LANG']
|
envlang = ENV['REDMINE_LANG']
|
||||||
if !envlang || !set_language_if_valid(envlang)
|
if !envlang || !set_language_if_valid(envlang)
|
||||||
puts
|
puts
|
||||||
while true
|
while true
|
||||||
print "Select language: "
|
print "Select language: "
|
||||||
print valid_languages.collect(&:to_s).sort.join(", ")
|
print valid_languages.collect(&:to_s).sort.join(", ")
|
||||||
print " [#{current_language}] "
|
print " [#{current_language}] "
|
||||||
STDOUT.flush
|
STDOUT.flush
|
||||||
lang = STDIN.gets.chomp!
|
lang = STDIN.gets.chomp!
|
||||||
break if lang.empty?
|
break if lang.empty?
|
||||||
break if set_language_if_valid(lang)
|
break if set_language_if_valid(lang)
|
||||||
puts "Unknown language!"
|
puts "Unknown language!"
|
||||||
end
|
end
|
||||||
STDOUT.flush
|
STDOUT.flush
|
||||||
puts "===================================="
|
puts "===================================="
|
||||||
end
|
end
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Redmine::DefaultData::Loader.load(current_language)
|
Redmine::DefaultData::Loader.load(current_language)
|
||||||
puts "Default configuration data loaded."
|
puts "Default configuration data loaded."
|
||||||
rescue Redmine::DefaultData::DataAlreadyLoaded => error
|
rescue Redmine::DefaultData::DataAlreadyLoaded => error
|
||||||
puts error
|
puts error
|
||||||
rescue => error
|
rescue => error
|
||||||
puts "Error: " + error
|
puts "Error: " + error
|
||||||
puts "Default configuration data was not loaded."
|
puts "Default configuration data was not loaded."
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,15 +1,15 @@
|
|||||||
namespace :db do
|
namespace :db do
|
||||||
desc 'Migrates installed plugins.'
|
desc 'Migrates installed plugins.'
|
||||||
task :migrate_plugins => :environment do
|
task :migrate_plugins => :environment do
|
||||||
if Rails.respond_to?('plugins')
|
if Rails.respond_to?('plugins')
|
||||||
Rails.plugins.each do |plugin|
|
Rails.plugins.each do |plugin|
|
||||||
next unless plugin.respond_to?('migrate')
|
next unless plugin.respond_to?('migrate')
|
||||||
puts "Migrating #{plugin.name}..."
|
puts "Migrating #{plugin.name}..."
|
||||||
plugin.migrate
|
plugin.migrate
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
puts "Undefined method plugins for Rails!"
|
puts "Undefined method plugins for Rails!"
|
||||||
puts "Make sure engines plugin is installed."
|
puts "Make sure engines plugin is installed."
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,91 +1,91 @@
|
|||||||
### From http://svn.geekdaily.org/public/rails/plugins/generally_useful/tasks/coverage_via_rcov.rake
|
### From http://svn.geekdaily.org/public/rails/plugins/generally_useful/tasks/coverage_via_rcov.rake
|
||||||
|
|
||||||
namespace :test do
|
namespace :test do
|
||||||
desc 'Measures test coverage'
|
desc 'Measures test coverage'
|
||||||
task :coverage do
|
task :coverage do
|
||||||
rm_f "coverage"
|
rm_f "coverage"
|
||||||
rm_f "coverage.data"
|
rm_f "coverage.data"
|
||||||
rcov = "rcov --rails --aggregate coverage.data --text-summary -Ilib --html"
|
rcov = "rcov --rails --aggregate coverage.data --text-summary -Ilib --html"
|
||||||
files = Dir.glob("test/**/*_test.rb").join(" ")
|
files = Dir.glob("test/**/*_test.rb").join(" ")
|
||||||
system("#{rcov} #{files}")
|
system("#{rcov} #{files}")
|
||||||
system("open coverage/index.html") if PLATFORM['darwin']
|
system("open coverage/index.html") if PLATFORM['darwin']
|
||||||
end
|
end
|
||||||
|
|
||||||
desc 'Run unit and functional scm tests'
|
desc 'Run unit and functional scm tests'
|
||||||
task :scm do
|
task :scm do
|
||||||
errors = %w(test:scm:units test:scm:functionals).collect do |task|
|
errors = %w(test:scm:units test:scm:functionals).collect do |task|
|
||||||
begin
|
begin
|
||||||
Rake::Task[task].invoke
|
Rake::Task[task].invoke
|
||||||
nil
|
nil
|
||||||
rescue => e
|
rescue => e
|
||||||
task
|
task
|
||||||
end
|
end
|
||||||
end.compact
|
end.compact
|
||||||
abort "Errors running #{errors.to_sentence(:locale => :en)}!" if errors.any?
|
abort "Errors running #{errors.to_sentence(:locale => :en)}!" if errors.any?
|
||||||
end
|
end
|
||||||
|
|
||||||
namespace :scm do
|
namespace :scm do
|
||||||
namespace :setup do
|
namespace :setup do
|
||||||
desc "Creates directory for test repositories"
|
desc "Creates directory for test repositories"
|
||||||
task :create_dir do
|
task :create_dir do
|
||||||
FileUtils.mkdir_p Rails.root + '/tmp/test'
|
FileUtils.mkdir_p Rails.root + '/tmp/test'
|
||||||
end
|
end
|
||||||
|
|
||||||
supported_scms = [:subversion, :cvs, :bazaar, :mercurial, :git, :darcs, :filesystem]
|
supported_scms = [:subversion, :cvs, :bazaar, :mercurial, :git, :darcs, :filesystem]
|
||||||
|
|
||||||
desc "Creates a test subversion repository"
|
desc "Creates a test subversion repository"
|
||||||
task :subversion => :create_dir do
|
task :subversion => :create_dir do
|
||||||
repo_path = "tmp/test/subversion_repository"
|
repo_path = "tmp/test/subversion_repository"
|
||||||
system "svnadmin create #{repo_path}"
|
system "svnadmin create #{repo_path}"
|
||||||
system "gunzip < test/fixtures/repositories/subversion_repository.dump.gz | svnadmin load #{repo_path}"
|
system "gunzip < test/fixtures/repositories/subversion_repository.dump.gz | svnadmin load #{repo_path}"
|
||||||
end
|
end
|
||||||
|
|
||||||
desc "Creates a test mercurial repository"
|
desc "Creates a test mercurial repository"
|
||||||
task :mercurial => :create_dir do
|
task :mercurial => :create_dir do
|
||||||
repo_path = "tmp/test/mercurial_repository"
|
repo_path = "tmp/test/mercurial_repository"
|
||||||
bundle_path = "test/fixtures/repositories/mercurial_repository.hg"
|
bundle_path = "test/fixtures/repositories/mercurial_repository.hg"
|
||||||
system "hg init #{repo_path}"
|
system "hg init #{repo_path}"
|
||||||
system "hg -R #{repo_path} pull #{bundle_path}"
|
system "hg -R #{repo_path} pull #{bundle_path}"
|
||||||
end
|
end
|
||||||
|
|
||||||
(supported_scms - [:subversion, :mercurial]).each do |scm|
|
(supported_scms - [:subversion, :mercurial]).each do |scm|
|
||||||
desc "Creates a test #{scm} repository"
|
desc "Creates a test #{scm} repository"
|
||||||
task scm => :create_dir do
|
task scm => :create_dir do
|
||||||
# system "gunzip < test/fixtures/repositories/#{scm}_repository.tar.gz | tar -xv -C tmp/test"
|
# system "gunzip < test/fixtures/repositories/#{scm}_repository.tar.gz | tar -xv -C tmp/test"
|
||||||
system "tar -xvz -C tmp/test -f test/fixtures/repositories/#{scm}_repository.tar.gz"
|
system "tar -xvz -C tmp/test -f test/fixtures/repositories/#{scm}_repository.tar.gz"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
desc "Creates all test repositories"
|
desc "Creates all test repositories"
|
||||||
task :all => supported_scms
|
task :all => supported_scms
|
||||||
end
|
end
|
||||||
|
|
||||||
desc "Updates installed test repositories"
|
desc "Updates installed test repositories"
|
||||||
task :update do
|
task :update do
|
||||||
require 'fileutils'
|
require 'fileutils'
|
||||||
Dir.glob("tmp/test/*_repository").each do |dir|
|
Dir.glob("tmp/test/*_repository").each do |dir|
|
||||||
next unless File.basename(dir) =~ %r{^(.+)_repository$} && File.directory?(dir)
|
next unless File.basename(dir) =~ %r{^(.+)_repository$} && File.directory?(dir)
|
||||||
scm = $1
|
scm = $1
|
||||||
next unless fixture = Dir.glob("test/fixtures/repositories/#{scm}_repository.*").first
|
next unless fixture = Dir.glob("test/fixtures/repositories/#{scm}_repository.*").first
|
||||||
next if File.stat(dir).ctime > File.stat(fixture).mtime
|
next if File.stat(dir).ctime > File.stat(fixture).mtime
|
||||||
|
|
||||||
FileUtils.rm_rf dir
|
FileUtils.rm_rf dir
|
||||||
Rake::Task["test:scm:setup:#{scm}"].execute
|
Rake::Task["test:scm:setup:#{scm}"].execute
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
Rake::TestTask.new(:units => "db:test:prepare") do |t|
|
Rake::TestTask.new(:units => "db:test:prepare") do |t|
|
||||||
t.libs << "test"
|
t.libs << "test"
|
||||||
t.verbose = true
|
t.verbose = true
|
||||||
t.test_files = FileList['test/unit/repository*_test.rb'] + FileList['test/unit/lib/redmine/scm/**/*_test.rb']
|
t.test_files = FileList['test/unit/repository*_test.rb'] + FileList['test/unit/lib/redmine/scm/**/*_test.rb']
|
||||||
end
|
end
|
||||||
Rake::Task['test:scm:units'].comment = "Run the scm unit tests"
|
Rake::Task['test:scm:units'].comment = "Run the scm unit tests"
|
||||||
|
|
||||||
Rake::TestTask.new(:functionals => "db:test:prepare") do |t|
|
Rake::TestTask.new(:functionals => "db:test:prepare") do |t|
|
||||||
t.libs << "test"
|
t.libs << "test"
|
||||||
t.verbose = true
|
t.verbose = true
|
||||||
t.test_files = FileList['test/functional/repositories*_test.rb']
|
t.test_files = FileList['test/functional/repositories*_test.rb']
|
||||||
end
|
end
|
||||||
Rake::Task['test:scm:functionals'].comment = "Run the scm functional tests"
|
Rake::Task['test:scm:functionals'].comment = "Run the scm functional tests"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
class Version < ActiveRecord::Base
|
class Version < ActiveRecord::Base
|
||||||
generator_for :name, :method => :next_name
|
generator_for :name, :method => :next_name
|
||||||
generator_for :status => 'open'
|
generator_for :status => 'open'
|
||||||
|
|
||||||
def self.next_name
|
def self.next_name
|
||||||
@last_name ||= 'Version 1.0.0'
|
@last_name ||= 'Version 1.0.0'
|
||||||
@last_name.succ!
|
@last_name.succ!
|
||||||
@last_name
|
@last_name
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -1,48 +1,48 @@
|
|||||||
Return-Path: <JSmith@somenet.foo>
|
Return-Path: <JSmith@somenet.foo>
|
||||||
Received: from osiris ([127.0.0.1])
|
Received: from osiris ([127.0.0.1])
|
||||||
by OSIRIS
|
by OSIRIS
|
||||||
with hMailServer ; Sun, 22 Jun 2008 12:28:07 +0200
|
with hMailServer ; Sun, 22 Jun 2008 12:28:07 +0200
|
||||||
Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris>
|
Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris>
|
||||||
In-Reply-To: <chiliproject.issue-2.20060719210421@osiris>
|
In-Reply-To: <chiliproject.issue-2.20060719210421@osiris>
|
||||||
From: "John Smith" <JSmith@somenet.foo>
|
From: "John Smith" <JSmith@somenet.foo>
|
||||||
To: <redmine@somenet.foo>
|
To: <redmine@somenet.foo>
|
||||||
Subject: Re: update to issue 2
|
Subject: Re: update to issue 2
|
||||||
Date: Sun, 22 Jun 2008 12:28:07 +0200
|
Date: Sun, 22 Jun 2008 12:28:07 +0200
|
||||||
MIME-Version: 1.0
|
MIME-Version: 1.0
|
||||||
Content-Type: text/plain;
|
Content-Type: text/plain;
|
||||||
format=flowed;
|
format=flowed;
|
||||||
charset="iso-8859-1";
|
charset="iso-8859-1";
|
||||||
reply-type=original
|
reply-type=original
|
||||||
Content-Transfer-Encoding: 7bit
|
Content-Transfer-Encoding: 7bit
|
||||||
X-Priority: 3
|
X-Priority: 3
|
||||||
X-MSMail-Priority: Normal
|
X-MSMail-Priority: Normal
|
||||||
X-Mailer: Microsoft Outlook Express 6.00.2900.2869
|
X-Mailer: Microsoft Outlook Express 6.00.2900.2869
|
||||||
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869
|
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869
|
||||||
|
|
||||||
An update to the issue by the sender.
|
An update to the issue by the sender.
|
||||||
|
|
||||||
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas imperdiet
|
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas imperdiet
|
||||||
turpis et odio. Integer eget pede vel dolor euismod varius. Phasellus
|
turpis et odio. Integer eget pede vel dolor euismod varius. Phasellus
|
||||||
blandit eleifend augue. Nulla facilisi. Duis id diam. Class aptent taciti
|
blandit eleifend augue. Nulla facilisi. Duis id diam. Class aptent taciti
|
||||||
sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In
|
sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In
|
||||||
in urna sed tellus aliquet lobortis. Morbi scelerisque tortor in dolor. Cras
|
in urna sed tellus aliquet lobortis. Morbi scelerisque tortor in dolor. Cras
|
||||||
sagittis odio eu lacus. Aliquam sem tortor, consequat sit amet, vestibulum
|
sagittis odio eu lacus. Aliquam sem tortor, consequat sit amet, vestibulum
|
||||||
id, iaculis at, lectus. Fusce tortor libero, congue ut, euismod nec, luctus
|
id, iaculis at, lectus. Fusce tortor libero, congue ut, euismod nec, luctus
|
||||||
eget, eros. Pellentesque tortor enim, feugiat in, dignissim eget, tristique
|
eget, eros. Pellentesque tortor enim, feugiat in, dignissim eget, tristique
|
||||||
sed, mauris --- Pellentesque habitant morbi tristique senectus et netus et
|
sed, mauris --- Pellentesque habitant morbi tristique senectus et netus et
|
||||||
malesuada fames ac turpis egestas. Quisque sit amet libero. In hac habitasse
|
malesuada fames ac turpis egestas. Quisque sit amet libero. In hac habitasse
|
||||||
platea dictumst.
|
platea dictumst.
|
||||||
|
|
||||||
>> > --- Reply above. Do not remove this line. ---
|
>> > --- Reply above. Do not remove this line. ---
|
||||||
>> >
|
>> >
|
||||||
>> > Issue #6779 has been updated by Eric Davis.
|
>> > Issue #6779 has been updated by Eric Davis.
|
||||||
>> >
|
>> >
|
||||||
>> > Subject changed from Projects with JSON to Project JSON API
|
>> > Subject changed from Projects with JSON to Project JSON API
|
||||||
>> > Status changed from New to Assigned
|
>> > Status changed from New to Assigned
|
||||||
>> > Assignee set to Eric Davis
|
>> > Assignee set to Eric Davis
|
||||||
>> > Priority changed from Low to Normal
|
>> > Priority changed from Low to Normal
|
||||||
>> > Estimated time deleted (1.00)
|
>> > Estimated time deleted (1.00)
|
||||||
>> >
|
>> >
|
||||||
>> > Looks like the JSON api for projects was missed. I'm going to be
|
>> > Looks like the JSON api for projects was missed. I'm going to be
|
||||||
>> > reviewing the existing APIs and trying to clean them up over the next
|
>> > reviewing the existing APIs and trying to clean them up over the next
|
||||||
>> > few weeks.
|
>> > few weeks.
|
||||||
|
@ -1,48 +1,48 @@
|
|||||||
Return-Path: <JSmith@somenet.foo>
|
Return-Path: <JSmith@somenet.foo>
|
||||||
Received: from osiris ([127.0.0.1])
|
Received: from osiris ([127.0.0.1])
|
||||||
by OSIRIS
|
by OSIRIS
|
||||||
with hMailServer ; Sun, 22 Jun 2008 12:28:07 +0200
|
with hMailServer ; Sun, 22 Jun 2008 12:28:07 +0200
|
||||||
Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris>
|
Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris>
|
||||||
In-Reply-To: <chiliproject.issue-2.20060719210421@osiris>
|
In-Reply-To: <chiliproject.issue-2.20060719210421@osiris>
|
||||||
From: "John Smith" <JSmith@somenet.foo>
|
From: "John Smith" <JSmith@somenet.foo>
|
||||||
To: <redmine@somenet.foo>
|
To: <redmine@somenet.foo>
|
||||||
Subject: Re: update to issue 2
|
Subject: Re: update to issue 2
|
||||||
Date: Sun, 22 Jun 2008 12:28:07 +0200
|
Date: Sun, 22 Jun 2008 12:28:07 +0200
|
||||||
MIME-Version: 1.0
|
MIME-Version: 1.0
|
||||||
Content-Type: text/plain;
|
Content-Type: text/plain;
|
||||||
format=flowed;
|
format=flowed;
|
||||||
charset="iso-8859-1";
|
charset="iso-8859-1";
|
||||||
reply-type=original
|
reply-type=original
|
||||||
Content-Transfer-Encoding: 7bit
|
Content-Transfer-Encoding: 7bit
|
||||||
X-Priority: 3
|
X-Priority: 3
|
||||||
X-MSMail-Priority: Normal
|
X-MSMail-Priority: Normal
|
||||||
X-Mailer: Microsoft Outlook Express 6.00.2900.2869
|
X-Mailer: Microsoft Outlook Express 6.00.2900.2869
|
||||||
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869
|
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869
|
||||||
|
|
||||||
An update to the issue by the sender.
|
An update to the issue by the sender.
|
||||||
|
|
||||||
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas imperdiet
|
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas imperdiet
|
||||||
turpis et odio. Integer eget pede vel dolor euismod varius. Phasellus
|
turpis et odio. Integer eget pede vel dolor euismod varius. Phasellus
|
||||||
blandit eleifend augue. Nulla facilisi. Duis id diam. Class aptent taciti
|
blandit eleifend augue. Nulla facilisi. Duis id diam. Class aptent taciti
|
||||||
sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In
|
sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In
|
||||||
in urna sed tellus aliquet lobortis. Morbi scelerisque tortor in dolor. Cras
|
in urna sed tellus aliquet lobortis. Morbi scelerisque tortor in dolor. Cras
|
||||||
sagittis odio eu lacus. Aliquam sem tortor, consequat sit amet, vestibulum
|
sagittis odio eu lacus. Aliquam sem tortor, consequat sit amet, vestibulum
|
||||||
id, iaculis at, lectus. Fusce tortor libero, congue ut, euismod nec, luctus
|
id, iaculis at, lectus. Fusce tortor libero, congue ut, euismod nec, luctus
|
||||||
eget, eros. Pellentesque tortor enim, feugiat in, dignissim eget, tristique
|
eget, eros. Pellentesque tortor enim, feugiat in, dignissim eget, tristique
|
||||||
sed, mauris --- Pellentesque habitant morbi tristique senectus et netus et
|
sed, mauris --- Pellentesque habitant morbi tristique senectus et netus et
|
||||||
malesuada fames ac turpis egestas. Quisque sit amet libero. In hac habitasse
|
malesuada fames ac turpis egestas. Quisque sit amet libero. In hac habitasse
|
||||||
platea dictumst.
|
platea dictumst.
|
||||||
|
|
||||||
> --- Reply above. Do not remove this line. ---
|
> --- Reply above. Do not remove this line. ---
|
||||||
>
|
>
|
||||||
> Issue #6779 has been updated by Eric Davis.
|
> Issue #6779 has been updated by Eric Davis.
|
||||||
>
|
>
|
||||||
> Subject changed from Projects with JSON to Project JSON API
|
> Subject changed from Projects with JSON to Project JSON API
|
||||||
> Status changed from New to Assigned
|
> Status changed from New to Assigned
|
||||||
> Assignee set to Eric Davis
|
> Assignee set to Eric Davis
|
||||||
> Priority changed from Low to Normal
|
> Priority changed from Low to Normal
|
||||||
> Estimated time deleted (1.00)
|
> Estimated time deleted (1.00)
|
||||||
>
|
>
|
||||||
> Looks like the JSON api for projects was missed. I'm going to be
|
> Looks like the JSON api for projects was missed. I'm going to be
|
||||||
> reviewing the existing APIs and trying to clean them up over the next
|
> reviewing the existing APIs and trying to clean them up over the next
|
||||||
> few weeks.
|
> few weeks.
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
Return-Path: <john.doe@somenet.foo>
|
Return-Path: <john.doe@somenet.foo>
|
||||||
Received: from osiris ([127.0.0.1])
|
Received: from osiris ([127.0.0.1])
|
||||||
by OSIRIS
|
by OSIRIS
|
||||||
with hMailServer ; Sun, 22 Jun 2008 12:28:07 +0200
|
with hMailServer ; Sun, 22 Jun 2008 12:28:07 +0200
|
||||||
Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris>
|
Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris>
|
||||||
To: <redmine@somenet.foo>
|
To: <redmine@somenet.foo>
|
||||||
Subject: Ticket by unknown user
|
Subject: Ticket by unknown user
|
||||||
Date: Sun, 22 Jun 2008 12:28:07 +0200
|
Date: Sun, 22 Jun 2008 12:28:07 +0200
|
||||||
MIME-Version: 1.0
|
MIME-Version: 1.0
|
||||||
Content-Type: text/plain;
|
Content-Type: text/plain;
|
||||||
format=flowed;
|
format=flowed;
|
||||||
charset="iso-8859-1";
|
charset="iso-8859-1";
|
||||||
reply-type=original
|
reply-type=original
|
||||||
Content-Transfer-Encoding: 7bit
|
Content-Transfer-Encoding: 7bit
|
||||||
|
|
||||||
This is a ticket submitted by an unknown user.
|
This is a ticket submitted by an unknown user.
|
||||||
|
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
Return-Path: <john.doe@somenet.foo>
|
Return-Path: <john.doe@somenet.foo>
|
||||||
Received: from osiris ([127.0.0.1])
|
Received: from osiris ([127.0.0.1])
|
||||||
by OSIRIS
|
by OSIRIS
|
||||||
with hMailServer ; Sun, 22 Jun 2008 12:28:07 +0200
|
with hMailServer ; Sun, 22 Jun 2008 12:28:07 +0200
|
||||||
Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris>
|
Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris>
|
||||||
From: "John Doe" <john.doe@somenet.foo>
|
From: "John Doe" <john.doe@somenet.foo>
|
||||||
To: <redmine@somenet.foo>
|
To: <redmine@somenet.foo>
|
||||||
Subject: Ticket by unknown user
|
Subject: Ticket by unknown user
|
||||||
Date: Sun, 22 Jun 2008 12:28:07 +0200
|
Date: Sun, 22 Jun 2008 12:28:07 +0200
|
||||||
MIME-Version: 1.0
|
MIME-Version: 1.0
|
||||||
Content-Type: text/plain;
|
Content-Type: text/plain;
|
||||||
format=flowed;
|
format=flowed;
|
||||||
charset="iso-8859-1";
|
charset="iso-8859-1";
|
||||||
reply-type=original
|
reply-type=original
|
||||||
Content-Transfer-Encoding: 7bit
|
Content-Transfer-Encoding: 7bit
|
||||||
|
|
||||||
This is a ticket submitted by an unknown user.
|
This is a ticket submitted by an unknown user.
|
||||||
|
|
||||||
|
@ -1,60 +1,60 @@
|
|||||||
Return-Path: <JSmith@somenet.foo>
|
Return-Path: <JSmith@somenet.foo>
|
||||||
Received: from osiris ([127.0.0.1])
|
Received: from osiris ([127.0.0.1])
|
||||||
by OSIRIS
|
by OSIRIS
|
||||||
with hMailServer ; Sun, 22 Jun 2008 12:28:07 +0200
|
with hMailServer ; Sun, 22 Jun 2008 12:28:07 +0200
|
||||||
Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris>
|
Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris>
|
||||||
From: "John Smith" <JSmith@somenet.foo>
|
From: "John Smith" <JSmith@somenet.foo>
|
||||||
To: <redmine@somenet.foo>
|
To: <redmine@somenet.foo>
|
||||||
Subject: New ticket on a given project
|
Subject: New ticket on a given project
|
||||||
Date: Sun, 22 Jun 2008 12:28:07 +0200
|
Date: Sun, 22 Jun 2008 12:28:07 +0200
|
||||||
MIME-Version: 1.0
|
MIME-Version: 1.0
|
||||||
Content-Type: text/plain;
|
Content-Type: text/plain;
|
||||||
format=flowed;
|
format=flowed;
|
||||||
charset="iso-8859-1";
|
charset="iso-8859-1";
|
||||||
reply-type=original
|
reply-type=original
|
||||||
Content-Transfer-Encoding: 7bit
|
Content-Transfer-Encoding: 7bit
|
||||||
X-Priority: 3
|
X-Priority: 3
|
||||||
X-MSMail-Priority: Normal
|
X-MSMail-Priority: Normal
|
||||||
X-Mailer: Microsoft Outlook Express 6.00.2900.2869
|
X-Mailer: Microsoft Outlook Express 6.00.2900.2869
|
||||||
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869
|
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869
|
||||||
|
|
||||||
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas imperdiet
|
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas imperdiet
|
||||||
turpis et odio. Integer eget pede vel dolor euismod varius. Phasellus
|
turpis et odio. Integer eget pede vel dolor euismod varius. Phasellus
|
||||||
blandit eleifend augue. Nulla facilisi. Duis id diam. Class aptent taciti
|
blandit eleifend augue. Nulla facilisi. Duis id diam. Class aptent taciti
|
||||||
sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In
|
sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In
|
||||||
in urna sed tellus aliquet lobortis. Morbi scelerisque tortor in dolor. Cras
|
in urna sed tellus aliquet lobortis. Morbi scelerisque tortor in dolor. Cras
|
||||||
sagittis odio eu lacus. Aliquam sem tortor, consequat sit amet, vestibulum
|
sagittis odio eu lacus. Aliquam sem tortor, consequat sit amet, vestibulum
|
||||||
id, iaculis at, lectus. Fusce tortor libero, congue ut, euismod nec, luctus
|
id, iaculis at, lectus. Fusce tortor libero, congue ut, euismod nec, luctus
|
||||||
eget, eros. Pellentesque tortor enim, feugiat in, dignissim eget, tristique
|
eget, eros. Pellentesque tortor enim, feugiat in, dignissim eget, tristique
|
||||||
sed, mauris --- Pellentesque habitant morbi tristique senectus et netus et
|
sed, mauris --- Pellentesque habitant morbi tristique senectus et netus et
|
||||||
malesuada fames ac turpis egestas. Quisque sit amet libero. In hac habitasse
|
malesuada fames ac turpis egestas. Quisque sit amet libero. In hac habitasse
|
||||||
platea dictumst.
|
platea dictumst.
|
||||||
|
|
||||||
--- This line starts with a delimiter and should not be stripped
|
--- This line starts with a delimiter and should not be stripped
|
||||||
|
|
||||||
This paragraph is before delimiters.
|
This paragraph is before delimiters.
|
||||||
|
|
||||||
BREAK
|
BREAK
|
||||||
|
|
||||||
This paragraph is between delimiters.
|
This paragraph is between delimiters.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
This paragraph is after the delimiter so it shouldn't appear.
|
This paragraph is after the delimiter so it shouldn't appear.
|
||||||
|
|
||||||
Nulla et nunc. Duis pede. Donec et ipsum. Nam ut dui tincidunt neque
|
Nulla et nunc. Duis pede. Donec et ipsum. Nam ut dui tincidunt neque
|
||||||
sollicitudin iaculis. Duis vitae dolor. Vestibulum eget massa. Sed lorem.
|
sollicitudin iaculis. Duis vitae dolor. Vestibulum eget massa. Sed lorem.
|
||||||
Nullam volutpat cursus erat. Cras felis dolor, lacinia quis, rutrum et,
|
Nullam volutpat cursus erat. Cras felis dolor, lacinia quis, rutrum et,
|
||||||
dictum et, ligula. Sed erat nibh, gravida in, accumsan non, placerat sed,
|
dictum et, ligula. Sed erat nibh, gravida in, accumsan non, placerat sed,
|
||||||
massa. Sed sodales, ante fermentum ultricies sollicitudin, massa leo
|
massa. Sed sodales, ante fermentum ultricies sollicitudin, massa leo
|
||||||
pulvinar dui, a gravida orci mi eget odio. Nunc a lacus.
|
pulvinar dui, a gravida orci mi eget odio. Nunc a lacus.
|
||||||
|
|
||||||
Project: onlinestore
|
Project: onlinestore
|
||||||
Status: Resolved
|
Status: Resolved
|
||||||
due date: 2010-12-31
|
due date: 2010-12-31
|
||||||
Start Date:2010-01-01
|
Start Date:2010-01-01
|
||||||
Assigned to: John Smith
|
Assigned to: John Smith
|
||||||
fixed version: alpha
|
fixed version: alpha
|
||||||
estimated hours: 2.5
|
estimated hours: 2.5
|
||||||
done ratio: 30
|
done ratio: 30
|
||||||
|
|
||||||
|
148
test/fixtures/mail_handler/ticket_reply.eml
vendored
148
test/fixtures/mail_handler/ticket_reply.eml
vendored
@ -1,74 +1,74 @@
|
|||||||
Return-Path: <jsmith@somenet.foo>
|
Return-Path: <jsmith@somenet.foo>
|
||||||
Received: from osiris ([127.0.0.1])
|
Received: from osiris ([127.0.0.1])
|
||||||
by OSIRIS
|
by OSIRIS
|
||||||
with hMailServer ; Sat, 21 Jun 2008 18:41:39 +0200
|
with hMailServer ; Sat, 21 Jun 2008 18:41:39 +0200
|
||||||
Message-ID: <006a01c8d3bd$ad9baec0$0a00a8c0@osiris>
|
Message-ID: <006a01c8d3bd$ad9baec0$0a00a8c0@osiris>
|
||||||
In-Reply-To: <chiliproject.issue-2.20060719210421@osiris>
|
In-Reply-To: <chiliproject.issue-2.20060719210421@osiris>
|
||||||
From: "John Smith" <jsmith@somenet.foo>
|
From: "John Smith" <jsmith@somenet.foo>
|
||||||
To: <redmine@somenet.foo>
|
To: <redmine@somenet.foo>
|
||||||
References: <485d0ad366c88_d7014663a025f@osiris.tmail>
|
References: <485d0ad366c88_d7014663a025f@osiris.tmail>
|
||||||
Subject: Re: Add ingredients categories
|
Subject: Re: Add ingredients categories
|
||||||
Date: Sat, 21 Jun 2008 18:41:39 +0200
|
Date: Sat, 21 Jun 2008 18:41:39 +0200
|
||||||
MIME-Version: 1.0
|
MIME-Version: 1.0
|
||||||
Content-Type: multipart/alternative;
|
Content-Type: multipart/alternative;
|
||||||
boundary="----=_NextPart_000_0067_01C8D3CE.711F9CC0"
|
boundary="----=_NextPart_000_0067_01C8D3CE.711F9CC0"
|
||||||
X-Priority: 3
|
X-Priority: 3
|
||||||
X-MSMail-Priority: Normal
|
X-MSMail-Priority: Normal
|
||||||
X-Mailer: Microsoft Outlook Express 6.00.2900.2869
|
X-Mailer: Microsoft Outlook Express 6.00.2900.2869
|
||||||
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869
|
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869
|
||||||
|
|
||||||
This is a multi-part message in MIME format.
|
This is a multi-part message in MIME format.
|
||||||
|
|
||||||
------=_NextPart_000_0067_01C8D3CE.711F9CC0
|
------=_NextPart_000_0067_01C8D3CE.711F9CC0
|
||||||
Content-Type: text/plain;
|
Content-Type: text/plain;
|
||||||
charset="utf-8"
|
charset="utf-8"
|
||||||
Content-Transfer-Encoding: quoted-printable
|
Content-Transfer-Encoding: quoted-printable
|
||||||
|
|
||||||
This is reply
|
This is reply
|
||||||
------=_NextPart_000_0067_01C8D3CE.711F9CC0
|
------=_NextPart_000_0067_01C8D3CE.711F9CC0
|
||||||
Content-Type: text/html;
|
Content-Type: text/html;
|
||||||
charset="utf-8"
|
charset="utf-8"
|
||||||
Content-Transfer-Encoding: quoted-printable
|
Content-Transfer-Encoding: quoted-printable
|
||||||
|
|
||||||
=EF=BB=BF<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
=EF=BB=BF<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||||
<HTML><HEAD>
|
<HTML><HEAD>
|
||||||
<META http-equiv=3DContent-Type content=3D"text/html; charset=3Dutf-8">
|
<META http-equiv=3DContent-Type content=3D"text/html; charset=3Dutf-8">
|
||||||
<STYLE>BODY {
|
<STYLE>BODY {
|
||||||
FONT-SIZE: 0.8em; COLOR: #484848; FONT-FAMILY: Verdana, sans-serif
|
FONT-SIZE: 0.8em; COLOR: #484848; FONT-FAMILY: Verdana, sans-serif
|
||||||
}
|
}
|
||||||
BODY H1 {
|
BODY H1 {
|
||||||
FONT-SIZE: 1.2em; MARGIN: 0px; FONT-FAMILY: "Trebuchet MS", Verdana, =
|
FONT-SIZE: 1.2em; MARGIN: 0px; FONT-FAMILY: "Trebuchet MS", Verdana, =
|
||||||
sans-serif
|
sans-serif
|
||||||
}
|
}
|
||||||
A {
|
A {
|
||||||
COLOR: #2a5685
|
COLOR: #2a5685
|
||||||
}
|
}
|
||||||
A:link {
|
A:link {
|
||||||
COLOR: #2a5685
|
COLOR: #2a5685
|
||||||
}
|
}
|
||||||
A:visited {
|
A:visited {
|
||||||
COLOR: #2a5685
|
COLOR: #2a5685
|
||||||
}
|
}
|
||||||
A:hover {
|
A:hover {
|
||||||
COLOR: #c61a1a
|
COLOR: #c61a1a
|
||||||
}
|
}
|
||||||
A:active {
|
A:active {
|
||||||
COLOR: #c61a1a
|
COLOR: #c61a1a
|
||||||
}
|
}
|
||||||
HR {
|
HR {
|
||||||
BORDER-RIGHT: 0px; BORDER-TOP: 0px; BACKGROUND: #ccc; BORDER-LEFT: 0px; =
|
BORDER-RIGHT: 0px; BORDER-TOP: 0px; BACKGROUND: #ccc; BORDER-LEFT: 0px; =
|
||||||
WIDTH: 100%; BORDER-BOTTOM: 0px; HEIGHT: 1px
|
WIDTH: 100%; BORDER-BOTTOM: 0px; HEIGHT: 1px
|
||||||
}
|
}
|
||||||
.footer {
|
.footer {
|
||||||
FONT-SIZE: 0.8em; FONT-STYLE: italic
|
FONT-SIZE: 0.8em; FONT-STYLE: italic
|
||||||
}
|
}
|
||||||
</STYLE>
|
</STYLE>
|
||||||
|
|
||||||
<META content=3D"MSHTML 6.00.2900.2883" name=3DGENERATOR></HEAD>
|
<META content=3D"MSHTML 6.00.2900.2883" name=3DGENERATOR></HEAD>
|
||||||
<BODY bgColor=3D#ffffff>
|
<BODY bgColor=3D#ffffff>
|
||||||
<DIV><SPAN class=3Dfooter><FONT face=3DArial color=3D#000000 =
|
<DIV><SPAN class=3Dfooter><FONT face=3DArial color=3D#000000 =
|
||||||
size=3D2>This is=20
|
size=3D2>This is=20
|
||||||
reply</FONT></DIV></SPAN></BODY></HTML>
|
reply</FONT></DIV></SPAN></BODY></HTML>
|
||||||
|
|
||||||
------=_NextPart_000_0067_01C8D3CE.711F9CC0--
|
------=_NextPart_000_0067_01C8D3CE.711F9CC0--
|
||||||
|
|
||||||
|
@ -1,248 +1,248 @@
|
|||||||
Return-Path: <jsmith@somenet.foo>
|
Return-Path: <jsmith@somenet.foo>
|
||||||
Received: from osiris ([127.0.0.1])
|
Received: from osiris ([127.0.0.1])
|
||||||
by OSIRIS
|
by OSIRIS
|
||||||
with hMailServer ; Sat, 21 Jun 2008 15:53:25 +0200
|
with hMailServer ; Sat, 21 Jun 2008 15:53:25 +0200
|
||||||
Message-ID: <002301c8d3a6$2cdf6950$0a00a8c0@osiris>
|
Message-ID: <002301c8d3a6$2cdf6950$0a00a8c0@osiris>
|
||||||
From: "John Smith" <jsmith@somenet.foo>
|
From: "John Smith" <jsmith@somenet.foo>
|
||||||
To: <redmine@somenet.foo>
|
To: <redmine@somenet.foo>
|
||||||
Subject: Ticket created by email with attachment
|
Subject: Ticket created by email with attachment
|
||||||
Date: Sat, 21 Jun 2008 15:53:25 +0200
|
Date: Sat, 21 Jun 2008 15:53:25 +0200
|
||||||
MIME-Version: 1.0
|
MIME-Version: 1.0
|
||||||
Content-Type: multipart/mixed;
|
Content-Type: multipart/mixed;
|
||||||
boundary="----=_NextPart_000_001F_01C8D3B6.F05C5270"
|
boundary="----=_NextPart_000_001F_01C8D3B6.F05C5270"
|
||||||
X-Priority: 3
|
X-Priority: 3
|
||||||
X-MSMail-Priority: Normal
|
X-MSMail-Priority: Normal
|
||||||
X-Mailer: Microsoft Outlook Express 6.00.2900.2869
|
X-Mailer: Microsoft Outlook Express 6.00.2900.2869
|
||||||
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869
|
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869
|
||||||
|
|
||||||
This is a multi-part message in MIME format.
|
This is a multi-part message in MIME format.
|
||||||
|
|
||||||
------=_NextPart_000_001F_01C8D3B6.F05C5270
|
------=_NextPart_000_001F_01C8D3B6.F05C5270
|
||||||
Content-Type: multipart/alternative;
|
Content-Type: multipart/alternative;
|
||||||
boundary="----=_NextPart_001_0020_01C8D3B6.F05C5270"
|
boundary="----=_NextPart_001_0020_01C8D3B6.F05C5270"
|
||||||
|
|
||||||
|
|
||||||
------=_NextPart_001_0020_01C8D3B6.F05C5270
|
------=_NextPart_001_0020_01C8D3B6.F05C5270
|
||||||
Content-Type: text/plain;
|
Content-Type: text/plain;
|
||||||
charset="iso-8859-1"
|
charset="iso-8859-1"
|
||||||
Content-Transfer-Encoding: quoted-printable
|
Content-Transfer-Encoding: quoted-printable
|
||||||
|
|
||||||
This is a new ticket with attachments
|
This is a new ticket with attachments
|
||||||
------=_NextPart_001_0020_01C8D3B6.F05C5270
|
------=_NextPart_001_0020_01C8D3B6.F05C5270
|
||||||
Content-Type: text/html;
|
Content-Type: text/html;
|
||||||
charset="iso-8859-1"
|
charset="iso-8859-1"
|
||||||
Content-Transfer-Encoding: quoted-printable
|
Content-Transfer-Encoding: quoted-printable
|
||||||
|
|
||||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||||
<HTML><HEAD>
|
<HTML><HEAD>
|
||||||
<META http-equiv=3DContent-Type content=3D"text/html; =
|
<META http-equiv=3DContent-Type content=3D"text/html; =
|
||||||
charset=3Diso-8859-1">
|
charset=3Diso-8859-1">
|
||||||
<META content=3D"MSHTML 6.00.2900.2883" name=3DGENERATOR>
|
<META content=3D"MSHTML 6.00.2900.2883" name=3DGENERATOR>
|
||||||
<STYLE></STYLE>
|
<STYLE></STYLE>
|
||||||
</HEAD>
|
</HEAD>
|
||||||
<BODY bgColor=3D#ffffff>
|
<BODY bgColor=3D#ffffff>
|
||||||
<DIV><FONT face=3DArial size=3D2>This is a new ticket with=20
|
<DIV><FONT face=3DArial size=3D2>This is a new ticket with=20
|
||||||
attachments</FONT></DIV></BODY></HTML>
|
attachments</FONT></DIV></BODY></HTML>
|
||||||
|
|
||||||
------=_NextPart_001_0020_01C8D3B6.F05C5270--
|
------=_NextPart_001_0020_01C8D3B6.F05C5270--
|
||||||
|
|
||||||
------=_NextPart_000_001F_01C8D3B6.F05C5270
|
------=_NextPart_000_001F_01C8D3B6.F05C5270
|
||||||
Content-Type: image/jpeg;
|
Content-Type: image/jpeg;
|
||||||
name="Paella.jpg"
|
name="Paella.jpg"
|
||||||
Content-Transfer-Encoding: base64
|
Content-Transfer-Encoding: base64
|
||||||
Content-Disposition: attachment;
|
Content-Disposition: attachment;
|
||||||
filename="Paella.jpg"
|
filename="Paella.jpg"
|
||||||
|
|
||||||
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
|
||||||
cbis+/WpUqUcMZKdF44n/9k=
|
cbis+/WpUqUcMZKdF44n/9k=
|
||||||
|
|
||||||
------=_NextPart_000_001F_01C8D3B6.F05C5270--
|
------=_NextPart_000_001F_01C8D3B6.F05C5270--
|
||||||
|
|
||||||
|
@ -1,47 +1,47 @@
|
|||||||
Return-Path: <jsmith@somenet.foo>
|
Return-Path: <jsmith@somenet.foo>
|
||||||
Received: from osiris ([127.0.0.1])
|
Received: from osiris ([127.0.0.1])
|
||||||
by OSIRIS
|
by OSIRIS
|
||||||
with hMailServer ; Sun, 22 Jun 2008 12:28:07 +0200
|
with hMailServer ; Sun, 22 Jun 2008 12:28:07 +0200
|
||||||
Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris>
|
Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris>
|
||||||
From: "John Smith" <jsmith@somenet.foo>
|
From: "John Smith" <jsmith@somenet.foo>
|
||||||
To: <redmine@somenet.foo>
|
To: <redmine@somenet.foo>
|
||||||
Subject: New ticket on a given project
|
Subject: New ticket on a given project
|
||||||
Date: Sun, 22 Jun 2008 12:28:07 +0200
|
Date: Sun, 22 Jun 2008 12:28:07 +0200
|
||||||
MIME-Version: 1.0
|
MIME-Version: 1.0
|
||||||
Content-Type: text/plain;
|
Content-Type: text/plain;
|
||||||
format=flowed;
|
format=flowed;
|
||||||
charset="iso-8859-1";
|
charset="iso-8859-1";
|
||||||
reply-type=original
|
reply-type=original
|
||||||
Content-Transfer-Encoding: 7bit
|
Content-Transfer-Encoding: 7bit
|
||||||
X-Priority: 3
|
X-Priority: 3
|
||||||
X-MSMail-Priority: Normal
|
X-MSMail-Priority: Normal
|
||||||
X-Mailer: Microsoft Outlook Express 6.00.2900.2869
|
X-Mailer: Microsoft Outlook Express 6.00.2900.2869
|
||||||
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869
|
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869
|
||||||
|
|
||||||
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas imperdiet
|
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas imperdiet
|
||||||
turpis et odio. Integer eget pede vel dolor euismod varius. Phasellus
|
turpis et odio. Integer eget pede vel dolor euismod varius. Phasellus
|
||||||
blandit eleifend augue. Nulla facilisi. Duis id diam. Class aptent taciti
|
blandit eleifend augue. Nulla facilisi. Duis id diam. Class aptent taciti
|
||||||
sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In
|
sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In
|
||||||
in urna sed tellus aliquet lobortis. Morbi scelerisque tortor in dolor. Cras
|
in urna sed tellus aliquet lobortis. Morbi scelerisque tortor in dolor. Cras
|
||||||
sagittis odio eu lacus. Aliquam sem tortor, consequat sit amet, vestibulum
|
sagittis odio eu lacus. Aliquam sem tortor, consequat sit amet, vestibulum
|
||||||
id, iaculis at, lectus. Fusce tortor libero, congue ut, euismod nec, luctus
|
id, iaculis at, lectus. Fusce tortor libero, congue ut, euismod nec, luctus
|
||||||
eget, eros. Pellentesque tortor enim, feugiat in, dignissim eget, tristique
|
eget, eros. Pellentesque tortor enim, feugiat in, dignissim eget, tristique
|
||||||
sed, mauris. Pellentesque habitant morbi tristique senectus et netus et
|
sed, mauris. Pellentesque habitant morbi tristique senectus et netus et
|
||||||
malesuada fames ac turpis egestas. Quisque sit amet libero. In hac habitasse
|
malesuada fames ac turpis egestas. Quisque sit amet libero. In hac habitasse
|
||||||
platea dictumst.
|
platea dictumst.
|
||||||
|
|
||||||
Nulla et nunc. Duis pede. Donec et ipsum. Nam ut dui tincidunt neque
|
Nulla et nunc. Duis pede. Donec et ipsum. Nam ut dui tincidunt neque
|
||||||
sollicitudin iaculis. Duis vitae dolor. Vestibulum eget massa. Sed lorem.
|
sollicitudin iaculis. Duis vitae dolor. Vestibulum eget massa. Sed lorem.
|
||||||
Nullam volutpat cursus erat. Cras felis dolor, lacinia quis, rutrum et,
|
Nullam volutpat cursus erat. Cras felis dolor, lacinia quis, rutrum et,
|
||||||
dictum et, ligula. Sed erat nibh, gravida in, accumsan non, placerat sed,
|
dictum et, ligula. Sed erat nibh, gravida in, accumsan non, placerat sed,
|
||||||
massa. Sed sodales, ante fermentum ultricies sollicitudin, massa leo
|
massa. Sed sodales, ante fermentum ultricies sollicitudin, massa leo
|
||||||
pulvinar dui, a gravida orci mi eget odio. Nunc a lacus.
|
pulvinar dui, a gravida orci mi eget odio. Nunc a lacus.
|
||||||
|
|
||||||
Project: onlinestore
|
Project: onlinestore
|
||||||
Tracker: Feature request
|
Tracker: Feature request
|
||||||
category: Stock management
|
category: Stock management
|
||||||
assigned to: miscuser9@foo.bar
|
assigned to: miscuser9@foo.bar
|
||||||
priority: foo
|
priority: foo
|
||||||
done ratio: x
|
done ratio: x
|
||||||
start date: some day
|
start date: some day
|
||||||
due date: never
|
due date: never
|
||||||
|
@ -1,43 +1,43 @@
|
|||||||
Return-Path: <jsmith@somenet.foo>
|
Return-Path: <jsmith@somenet.foo>
|
||||||
Received: from osiris ([127.0.0.1])
|
Received: from osiris ([127.0.0.1])
|
||||||
by OSIRIS
|
by OSIRIS
|
||||||
with hMailServer ; Sun, 22 Jun 2008 12:28:07 +0200
|
with hMailServer ; Sun, 22 Jun 2008 12:28:07 +0200
|
||||||
Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris>
|
Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris>
|
||||||
From: "John Smith" <jsmith@somenet.foo>
|
From: "John Smith" <jsmith@somenet.foo>
|
||||||
To: <redmine@somenet.foo>
|
To: <redmine@somenet.foo>
|
||||||
Subject: New ticket on a given project
|
Subject: New ticket on a given project
|
||||||
Date: Sun, 22 Jun 2008 12:28:07 +0200
|
Date: Sun, 22 Jun 2008 12:28:07 +0200
|
||||||
MIME-Version: 1.0
|
MIME-Version: 1.0
|
||||||
Content-Type: text/plain;
|
Content-Type: text/plain;
|
||||||
format=flowed;
|
format=flowed;
|
||||||
charset="iso-8859-1";
|
charset="iso-8859-1";
|
||||||
reply-type=original
|
reply-type=original
|
||||||
Content-Transfer-Encoding: 7bit
|
Content-Transfer-Encoding: 7bit
|
||||||
X-Priority: 3
|
X-Priority: 3
|
||||||
X-MSMail-Priority: Normal
|
X-MSMail-Priority: Normal
|
||||||
X-Mailer: Microsoft Outlook Express 6.00.2900.2869
|
X-Mailer: Microsoft Outlook Express 6.00.2900.2869
|
||||||
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869
|
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869
|
||||||
|
|
||||||
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas imperdiet
|
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas imperdiet
|
||||||
turpis et odio. Integer eget pede vel dolor euismod varius. Phasellus
|
turpis et odio. Integer eget pede vel dolor euismod varius. Phasellus
|
||||||
blandit eleifend augue. Nulla facilisi. Duis id diam. Class aptent taciti
|
blandit eleifend augue. Nulla facilisi. Duis id diam. Class aptent taciti
|
||||||
sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In
|
sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In
|
||||||
in urna sed tellus aliquet lobortis. Morbi scelerisque tortor in dolor. Cras
|
in urna sed tellus aliquet lobortis. Morbi scelerisque tortor in dolor. Cras
|
||||||
sagittis odio eu lacus. Aliquam sem tortor, consequat sit amet, vestibulum
|
sagittis odio eu lacus. Aliquam sem tortor, consequat sit amet, vestibulum
|
||||||
id, iaculis at, lectus. Fusce tortor libero, congue ut, euismod nec, luctus
|
id, iaculis at, lectus. Fusce tortor libero, congue ut, euismod nec, luctus
|
||||||
eget, eros. Pellentesque tortor enim, feugiat in, dignissim eget, tristique
|
eget, eros. Pellentesque tortor enim, feugiat in, dignissim eget, tristique
|
||||||
sed, mauris. Pellentesque habitant morbi tristique senectus et netus et
|
sed, mauris. Pellentesque habitant morbi tristique senectus et netus et
|
||||||
malesuada fames ac turpis egestas. Quisque sit amet libero. In hac habitasse
|
malesuada fames ac turpis egestas. Quisque sit amet libero. In hac habitasse
|
||||||
platea dictumst.
|
platea dictumst.
|
||||||
|
|
||||||
Nulla et nunc. Duis pede. Donec et ipsum. Nam ut dui tincidunt neque
|
Nulla et nunc. Duis pede. Donec et ipsum. Nam ut dui tincidunt neque
|
||||||
sollicitudin iaculis. Duis vitae dolor. Vestibulum eget massa. Sed lorem.
|
sollicitudin iaculis. Duis vitae dolor. Vestibulum eget massa. Sed lorem.
|
||||||
Nullam volutpat cursus erat. Cras felis dolor, lacinia quis, rutrum et,
|
Nullam volutpat cursus erat. Cras felis dolor, lacinia quis, rutrum et,
|
||||||
dictum et, ligula. Sed erat nibh, gravida in, accumsan non, placerat sed,
|
dictum et, ligula. Sed erat nibh, gravida in, accumsan non, placerat sed,
|
||||||
massa. Sed sodales, ante fermentum ultricies sollicitudin, massa leo
|
massa. Sed sodales, ante fermentum ultricies sollicitudin, massa leo
|
||||||
pulvinar dui, a gravida orci mi eget odio. Nunc a lacus.
|
pulvinar dui, a gravida orci mi eget odio. Nunc a lacus.
|
||||||
|
|
||||||
Projet: onlinestore
|
Projet: onlinestore
|
||||||
Tracker: Feature request
|
Tracker: Feature request
|
||||||
catégorie: Stock management
|
catégorie: Stock management
|
||||||
priorité: Urgent
|
priorité: Urgent
|
||||||
|
@ -1,57 +1,57 @@
|
|||||||
Return-Path: <JSmith@somenet.foo>
|
Return-Path: <JSmith@somenet.foo>
|
||||||
Received: from osiris ([127.0.0.1])
|
Received: from osiris ([127.0.0.1])
|
||||||
by OSIRIS
|
by OSIRIS
|
||||||
with hMailServer ; Sun, 22 Jun 2008 12:28:07 +0200
|
with hMailServer ; Sun, 22 Jun 2008 12:28:07 +0200
|
||||||
Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris>
|
Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris>
|
||||||
From: "John Smith" <JSmith@somenet.foo>
|
From: "John Smith" <JSmith@somenet.foo>
|
||||||
To: <redmine@somenet.foo>
|
To: <redmine@somenet.foo>
|
||||||
Subject: New ticket on a given project with a very long subject line which exceeds 255 chars and should not be ignored but chopped off. And if the subject line is still not long enough, we just add more text. And more text. Wow, this is really annoying. Especially, if you have nothing to say...
|
Subject: New ticket on a given project with a very long subject line which exceeds 255 chars and should not be ignored but chopped off. And if the subject line is still not long enough, we just add more text. And more text. Wow, this is really annoying. Especially, if you have nothing to say...
|
||||||
Date: Sun, 22 Jun 2008 12:28:07 +0200
|
Date: Sun, 22 Jun 2008 12:28:07 +0200
|
||||||
MIME-Version: 1.0
|
MIME-Version: 1.0
|
||||||
Content-Type: text/plain;
|
Content-Type: text/plain;
|
||||||
format=flowed;
|
format=flowed;
|
||||||
charset="iso-8859-1";
|
charset="iso-8859-1";
|
||||||
reply-type=original
|
reply-type=original
|
||||||
Content-Transfer-Encoding: 7bit
|
Content-Transfer-Encoding: 7bit
|
||||||
X-Priority: 3
|
X-Priority: 3
|
||||||
X-MSMail-Priority: Normal
|
X-MSMail-Priority: Normal
|
||||||
X-Mailer: Microsoft Outlook Express 6.00.2900.2869
|
X-Mailer: Microsoft Outlook Express 6.00.2900.2869
|
||||||
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869
|
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869
|
||||||
|
|
||||||
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas imperdiet
|
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas imperdiet
|
||||||
turpis et odio. Integer eget pede vel dolor euismod varius. Phasellus
|
turpis et odio. Integer eget pede vel dolor euismod varius. Phasellus
|
||||||
blandit eleifend augue. Nulla facilisi. Duis id diam. Class aptent taciti
|
blandit eleifend augue. Nulla facilisi. Duis id diam. Class aptent taciti
|
||||||
sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In
|
sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In
|
||||||
in urna sed tellus aliquet lobortis. Morbi scelerisque tortor in dolor. Cras
|
in urna sed tellus aliquet lobortis. Morbi scelerisque tortor in dolor. Cras
|
||||||
sagittis odio eu lacus. Aliquam sem tortor, consequat sit amet, vestibulum
|
sagittis odio eu lacus. Aliquam sem tortor, consequat sit amet, vestibulum
|
||||||
id, iaculis at, lectus. Fusce tortor libero, congue ut, euismod nec, luctus
|
id, iaculis at, lectus. Fusce tortor libero, congue ut, euismod nec, luctus
|
||||||
eget, eros. Pellentesque tortor enim, feugiat in, dignissim eget, tristique
|
eget, eros. Pellentesque tortor enim, feugiat in, dignissim eget, tristique
|
||||||
sed, mauris --- Pellentesque habitant morbi tristique senectus et netus et
|
sed, mauris --- Pellentesque habitant morbi tristique senectus et netus et
|
||||||
malesuada fames ac turpis egestas. Quisque sit amet libero. In hac habitasse
|
malesuada fames ac turpis egestas. Quisque sit amet libero. In hac habitasse
|
||||||
platea dictumst.
|
platea dictumst.
|
||||||
|
|
||||||
--- This line starts with a delimiter and should not be stripped
|
--- This line starts with a delimiter and should not be stripped
|
||||||
|
|
||||||
This paragraph is before delimiters.
|
This paragraph is before delimiters.
|
||||||
|
|
||||||
BREAK
|
BREAK
|
||||||
|
|
||||||
This paragraph is between delimiters.
|
This paragraph is between delimiters.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
This paragraph is after the delimiter so it shouldn't appear.
|
This paragraph is after the delimiter so it shouldn't appear.
|
||||||
|
|
||||||
Nulla et nunc. Duis pede. Donec et ipsum. Nam ut dui tincidunt neque
|
Nulla et nunc. Duis pede. Donec et ipsum. Nam ut dui tincidunt neque
|
||||||
sollicitudin iaculis. Duis vitae dolor. Vestibulum eget massa. Sed lorem.
|
sollicitudin iaculis. Duis vitae dolor. Vestibulum eget massa. Sed lorem.
|
||||||
Nullam volutpat cursus erat. Cras felis dolor, lacinia quis, rutrum et,
|
Nullam volutpat cursus erat. Cras felis dolor, lacinia quis, rutrum et,
|
||||||
dictum et, ligula. Sed erat nibh, gravida in, accumsan non, placerat sed,
|
dictum et, ligula. Sed erat nibh, gravida in, accumsan non, placerat sed,
|
||||||
massa. Sed sodales, ante fermentum ultricies sollicitudin, massa leo
|
massa. Sed sodales, ante fermentum ultricies sollicitudin, massa leo
|
||||||
pulvinar dui, a gravida orci mi eget odio. Nunc a lacus.
|
pulvinar dui, a gravida orci mi eget odio. Nunc a lacus.
|
||||||
|
|
||||||
Project: onlinestore
|
Project: onlinestore
|
||||||
Status: Resolved
|
Status: Resolved
|
||||||
due date: 2010-12-31
|
due date: 2010-12-31
|
||||||
Start Date:2010-01-01
|
Start Date:2010-01-01
|
||||||
Assigned to: John Smith
|
Assigned to: John Smith
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user