Acme-CPANModulesBundle-Import-MojoliciousAdvent-2017

 view release on metacpan or  search on metacpan

LICENSE  view on Meta::CPAN

you have.  You must make sure that they, too, receive or can get the
source code.  And you must tell them their rights.

  We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.

  Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software.  If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.

  The precise terms and conditions for copying, distribution and
modification follow.

                    GNU GENERAL PUBLIC LICENSE
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

  0. This License Agreement applies to any program or other work which
contains a notice placed by the copyright holder saying it may be

LICENSE  view on Meta::CPAN

the Program under this License.  However, parties who have received
copies, or rights to use copies, from you under this General Public
License will not have their licenses terminated so long as such parties
remain in full compliance.

  5. By copying, distributing or modifying the Program (or any work based
on the Program) you indicate your acceptance of this license to do so,
and all its terms and conditions.

  6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the original
licensor to copy, distribute or modify the Program subject to these
terms and conditions.  You may not impose any further restrictions on the
recipients' exercise of the rights granted herein.

  7. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time.  Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

Each version is given a distinguishing version number.  If the Program

LICENSE  view on Meta::CPAN

    cost, duplication charges, time of people involved, and so on. (You will
    not be required to justify it to the Copyright Holder, but only to the
    computing community at large as a market that must bear the fee.) 
  - "Freely Available" means that no fee is charged for the item itself, though
    there may be fees involved in handling the item. It also means that
    recipients of the item may redistribute it under the same conditions they
    received it. 

1. You may make and give away verbatim copies of the source form of the
Standard Version of this Package without restriction, provided that you
duplicate all of the original copyright notices and associated disclaimers.

2. You may apply bug fixes, portability fixes and other modifications derived
from the Public Domain or from the Copyright Holder. A Package modified in such
a way shall still be considered the Standard Version.

3. You may otherwise modify your copy of this Package in any way, provided that
you insert a prominent notice in each changed file stating how and when you
changed that file, and provided that you do at least ONE of the following:

  a) place your modifications in the Public Domain or otherwise make them

devdata/https_mojolicious.io_blog_2017_12_02_day-2-the-stash  view on Meta::CPAN

<p>In Mojolicious, when establishing a route, we can also specify some default values to add to the stash on each request (unless they are changed).
These defaults are passed as a hash reference to the route constructor <code>get</code>.</p>

<pre><code>use Mojolicious::Lite;
get &#39;/&#39; =&gt; {text =&gt; &#39;Hello 🌍 World!&#39;} =&gt; sub {
  my $c = shift;
};
app-&gt;start;
</code></pre>

<p>However now our action doesn&#39;t do anything, so we don&#39;t actually need it at all, and we are back to our original example.</p>

<pre><code>use Mojolicious::Lite;
get &#39;/&#39; =&gt; {text =&gt; &#39;hello 🌍 world!&#39;};
app-&gt;start;
</code></pre>

<h2>Using Placeholders</h2>

<p>We can take that example further and show how to make a more interesting greeting application, this time taking a name.</p>

devdata/https_mojolicious.io_blog_2017_12_05_day-5-your-apps-built-in-commands  view on Meta::CPAN


<pre><code>perl myapp.pl eval -V &#39;app-&gt;pg-&gt;db-&gt;query(&quot;SELECT NOW()&quot;)-&gt;hash&#39;
</code></pre>

<p>These last two database examples assumed that your app was using <a href="http://mojolicious.org/perldoc/Mojo/Pg">Mojo::Pg</a> but similar one-liners could work for any database that your app knows about.</p>

<p>There really is nothing like debugging or administering your application without having to copy and paste a bunch of your logic from your app to some script.
Although if you really find yourself using the <code>eval</code> command for the same tasks often ... well that should wait until tomorrow.</p>

              </section>
              <small><p><a href="https://commons.wikimedia.org/w/index.php?curid=44576486">Image</a> by <a href="//commons.wikimedia.org/w/index.php?title=User:Gsaisudha75&amp;action=edit&amp;redlink=1" title="User:Gsaisudha75 (page does not exist)">...
</small>

              <p class="tags">
                <span>Tagged in </span>:
                  <a href="/blog/tag/advent/">advent</a>,
                  <a href="/blog/tag/command/">command</a>,
                  <a href="/blog/tag/debugging/">debugging</a>,
                  <a href="/blog/tag/administration/">administration</a>
              </p>

devdata/https_mojolicious.io_blog_2017_12_07_day-7-using-template-variants-for-a-beta-landing-page  view on Meta::CPAN

</code></pre>

<p>This gives me the <a href="http://beta.cpantesters.org">new landing page for beta.cpantesters.org</a>.</p>

<pre><code>$ perl myapp.pl get / -m beta
&lt;h1&gt;CPAN Testers Beta&lt;/h1&gt;
&lt;p&gt;This site shows off some new features currently being tested.&lt;/p&gt;
&lt;h2&gt;&lt;a href=&quot;/chart.html&quot;&gt;Release Dashboard&lt;/a&gt;&lt;/h2&gt;
</code></pre>

<p>But now I also need to replace the original landing page (index.html.ep)
so it can still be seen on the beta website. I do this with a simple
trick: I created a new template called <code>web.html+beta.ep</code> that imports
the original template and unsets the <code>variant</code> stash variable. Now
I can see the <a href="http://beta.cpantesters.org/web">main index page on the beta site at
http://beta.cpantesters.org/web</a>.</p>

<pre><code class="hljs">%= include &#39;index&#39;, variant =&gt; undef
</code></pre>

<pre><code>$ perl myapp.pl get /web -m beta
&lt;h1&gt;CPAN Testers&lt;/h1&gt;
&lt;p&gt;This is the main CPAN Testers application.&lt;/p&gt;
</code></pre>

devdata/https_mojolicious.io_blog_2017_12_08_day-8-mocking-a-rest-api  view on Meta::CPAN

@@ POST/servers.json.ep
{ &quot;status&quot;: &quot;success&quot;, &quot;id&quot;: 3, &quot;server&quot;: &lt;%== $c-&gt;req-&gt;body %&gt; }
</code></pre>

<p>Now all our template paths start with the HTTP request method (<code>GET</code>),
allowing us to add different routes for <code>POST</code> requests and other HTTP
methods.</p>

<p>We also added a <code>POST/servers.json.ep</code> template that shows us getting
a successful response from adding a new server via the API. It even
correctly gives us back the data we submitted, like our original API
might do.</p>

<p>We can test our added <code>POST /servers</code> method with the <code>get</code> command
again:</p>

<pre><code>$ perl test-api.pl get -M POST -c &#39;{ &quot;ip&quot;: &quot;10.0.0.3&quot; }&#39; /servers
{ &quot;status&quot;: &quot;success&quot;, &quot;id&quot;: 3, &quot;server&quot;: { &quot;ip&quot;: &quot;10.0.0.3&quot; } }
</code></pre>

<p>Now what if I want to test what happens when the API gives me an error?
Mojolicious has an easy way to layer on additional templates to use for
certain routes: <a href="http://mojolicious.org/perldoc/Mojolicious/Guides/Rendering#Template-variants">Template
variants</a>.
These variant templates will be used instead of the original template,
but only if they are available. Read more on <a href="/blog/2017/12/07/day-7-using-template-variants-for-a-beta-landing-page/">how to use template
variants yesterday on the advent
calendar</a>.</p>

<p>By setting the template variant to the application &quot;mode&quot;, we can easily
switch between multiple sets of templates by adding <code>-m &lt;mode&gt;</code> to the
command we run.</p>

<pre><code class="hljs"><span class="hljs-comment"># test-api.pl</span><span class="hljs-comment">
</span><span class="hljs-keyword">use</span> <span class="hljs-function">Mojolicious::Lite</span>;

devdata/https_mojolicious.io_blog_2017_12_08_day-8-mocking-a-rest-api  view on Meta::CPAN

{ &quot;status&quot;: &quot;error&quot;, &quot;error&quot;: &quot;Bad request&quot; }
</code></pre>

<pre><code>$ perl test-api.pl get -m error -M POST -c &#39;{}&#39; /servers
{ &quot;status&quot;: &quot;error&quot;, &quot;error&quot;: &quot;Bad request&quot; }
</code></pre>

<p>And finally, since I&#39;m using this to test an AJAX web application,
I need to allow the preflight <code>OPTIONS</code> request to succeed and I need to
make sure that all of the correct <code>Access-Control-*</code> headers are set
to allow for cross-origin requests.</p>

<pre><code class="hljs"><span class="hljs-comment"># test-api.pl</span><span class="hljs-comment">
</span><span class="hljs-keyword">use</span> <span class="hljs-function">Mojolicious::Lite</span>;
hook after_build_tx =&gt; <span class="hljs-keyword">sub </span>{
    <span class="hljs-keyword">my</span> (<span class="hljs-type">$tx</span>, <span class="hljs-type">$app</span>) = <span class="hljs-type">@_</span>;
    <span class="hljs-type">$tx</span>-&gt;<span class="hljs-type">res</span>-&gt;<span class="hljs-type">headers</span>-&gt;<span class="hljs-type">header</span>( &#39;<span class="hljs-string">Access-Control-Allow-Origin</span>&#39; =&gt; &#39;<spa...
    <span class="hljs-type">$tx</span>-&gt;<span class="hljs-type">res</span>-&gt;<span class="hljs-type">headers</span>-&gt;<span class="hljs-type">header</span>( &#39;<span class="hljs-string">Access-Control-Allow-Methods</span>&#39; =&gt; &#39;<sp...
    <span class="hljs-type">$tx</span>-&gt;<span class="hljs-type">res</span>-&gt;<span class="hljs-type">headers</span>-&gt;<span class="hljs-type">header</span>( &#39;<span class="hljs-string">Access-Control-Max-Age</span>&#39; =&gt; <span class="h...
    <span class="hljs-type">$tx</span>-&gt;<span class="hljs-type">res</span>-&gt;<span class="hljs-type">headers</span>-&gt;<span class="hljs-type">header</span>( &#39;<span class="hljs-string">Access-Control-Allow-Headers</span>&#39; =&gt; &#39;<sp...
};

devdata/https_mojolicious.io_blog_2017_12_11_day-11-useragent-content-generators  view on Meta::CPAN

It then returns a result or fault (exception).
These responses also contain arguments, that is to say, the response data.</p>

<p>Personally I find it is much easier to learn something new by seeing how it works.
I pulled <a href="https://metacpan.org/pod/XMLRPC::Fast">XMLRPC::Fast</a> from CPAN and started inspecting the code.
It started to make sense to me, but I noticed that it used <a href="https://metacpan.org/pod/XML::Parser">XML::Parser</a> for its XML.
Since Mojolicious has tools for that, I decided to continue learning by porting the code to <a href="http://mojolicious.org/perldoc/Mojo/Template">Mojo::Template</a> and <a href="http://mojolicious.org/perldoc/Mojo/DOM">Mojo::DOM</a>.</p>

<p>By the time I finished I had completely rewritten the module and decided that perhaps others would benefit from it in environments already using the Mojo stack.
So with much thanks to XMLRPC::Fast and its author Sébastien Aperghis-Tramoni I released my own as <a href="https://metacpan.org/pod/Mojo::XMLRPC">Mojo::XMLRPC</a>.
My module (as did the original) only has functions that build the XML payloads.
Therefore, to make a simple request, pass the result of encoding as XML-RPC as the body of a request, like so</p>

<pre><code class="hljs"><span class="hljs-keyword">use</span> <span class="hljs-function">Mojo::Base</span> -strict;
<span class="hljs-keyword">use</span> <span class="hljs-function">Mojo::UserAgent</span>;
<span class="hljs-keyword">use</span> <span class="hljs-function">Mojo::XMLRPC</span> qw[encode_xmlrpc decode_xmlrpc];

<span class="hljs-keyword">my</span> <span class="hljs-type">$ua</span> = <span class="hljs-function">Mojo::UserAgent</span>-&gt;new;
<span class="hljs-keyword">my</span> <span class="hljs-type">$tx</span> = <span class="hljs-type">$ua</span>-&gt;<span class="hljs-type">post</span>(
  &#39;<span class="hljs-string">/rpc</span>&#39;,
  {&#39;<span class="hljs-string">Content-Type</span>&#39; =&gt; &#39;<span class="hljs-string">text/xml</span>&#39;},

devdata/https_mojolicious.io_blog_2017_12_18_day-18-the-wishlist-model  view on Meta::CPAN


<p>Here you can see how to move from the empty version 0 up to version 1.
You can also define how to move back down though it is ok to ignore those and not support downgrading.</p>

<p>The schema we define mimics the one we used yesterday.
Users have names.
Items have titles, urls, purchased state (SQLite doesn&#39;t have a boolean) and a reference to the user that requested it.</p>

<h2>The Model Class</h2>

<p>I extracted the business logic from the <a href="https://metacpan.org/pod/SQL::Abstract">original application&#39;s controller actions</a>, anything that handled persistence, and moved them to a dedicated class, <a href="https://github.com/jberger...

<pre><code class="hljs"><span class="hljs-keyword">package</span> <span class="hljs-function">Wishlist::Model</span>;
<span class="hljs-keyword">use</span> <span class="hljs-function">Mojo::Base</span> -base;

<span class="hljs-keyword">use</span> Carp ();

has sqlite =&gt; <span class="hljs-keyword">sub </span>{ <span class="hljs-function">Carp::croak</span> &#39;<span class="hljs-string">sqlite is required</span>&#39; };

<span class="hljs-keyword">sub </span><span class="hljs-function">add_user</span> {
  <span class="hljs-keyword">my</span> (<span class="hljs-type">$self</span>, <span class="hljs-type">$name</span>) = <span class="hljs-type">@_</span>;

devdata/https_mojolicious.io_blog_2017_12_19_day-19-make-your-app-installable  view on Meta::CPAN

<pre><code>[ShareDir]
</code></pre>

<p>whose default is <code>share</code>.
I&#39;m sure other installers have ways to handle it too.</p>

<h2>File::Share Saves the Day</h2>

<p>Since we earlier moved the location of templates and static files, we now need to tell the application where we put them.
The major innovation that makes this method possible and so painless is the module <a href="https://metacpan.org/pod/File::Share">File::Share</a>.
While it isn&#39;t <a href="https://metacpan.org/pod/File::ShareDir">the original module</a> used to locate share directories after installation, it is the best one since it also works before hand during development too.
To do so it uses the heuristic of looking to see if a directory exists named <code>share</code> in that particular location (and a few checks for sanity), thus the second reason we call the directory that.</p>

<p>When used we get the absolute path to the share directory of your distribution.
Usually the name of the distribution is the name of your main module with the <code>::</code> replaced by <code>-</code>.</p>

<h2>Use in Mojolicious Apps</h2>

<p>To use File::Share in a Mojolicious (Full) app I recommend wrapping it in a <a href="http://mojolicious.org/perldoc/Mojo/File">Mojo::File</a> object and storing it in an attirbute on the app.
The attribute can be named anything, perhaps even as simple as <code>files</code>, though for the <a href="https://github.com/jberger/Wishlist/blob/blog_post/installable/lib/Wishlist.pm#L10-L14">Wishlist app</a> I have used the name <code>dist_dir</c...

devdata/https_mojolicious.io_blog_2017_12_21_day-21-virtually-a-lumberjack  view on Meta::CPAN

HEIGHT=$(printf &quot;%08d&quot; $(echo $(wc -l &quot;$FILE&quot; | cut -f1 -d&#39; &#39;) - 4 | bc));

echo $WIDTH  | dd of=&quot;$FILE&quot; bs=1 seek=3  count=8 conv=notrunc
echo $HEIGHT | dd of=&quot;$FILE&quot; bs=1 seek=12 count=8 conv=notrunc
</code></pre>

<p>Now these are valid PGM images and we can open them to see the data stream!</p>

<p><img alt="Section of Yaw PGM" src="yaw.png"></p>

<p>(The above has been rotated and flipped, the original image is a thin
&quot;waterfall&quot;.)</p>

<p>Some parts are immediately obvious.
Very smooth gradients next to larger smooth blocks or gradients hints at a
high-precision timer, which tend to be 32 bits (4 bytes) wide.
This can be seen at the top of the example.</p>

<p>Other aspects are only noticeable when compared to the other movements.
The simple file format makes it very easy to graph the data with gnuplot.
In the worst/simple case scenario, you can simply graph at each offset and



( run in 1.392 second using v1.01-cache-2.11-cpan-f985c23238c )