{"id":13680,"date":"2020-04-08T12:19:10","date_gmt":"2020-04-08T18:19:10","guid":{"rendered":"http:\/\/macblaze.ca\/?p=13680"},"modified":"2020-04-08T12:19:10","modified_gmt":"2020-04-08T18:19:10","slug":"flask-part-deux","status":"publish","type":"post","link":"https:\/\/macblaze.ca\/?p=13680","title":{"rendered":"Flask Part Deux"},"content":{"rendered":"<p>A continuation of <a href=\"http:\/\/macblaze.ca\/?p=13665\">The Great Flask Adventure.<\/a><\/p>\n<h3>The structure<\/h3>\n<p>When last we left our heroes we had posted a groovy python script: Mark III. This was saved as yacht_app.py in a folder. The rest of the files were built and&nbsp; also stored there. The structure of the folders is thus:<\/p>\n<p>[searchyachtworld]<br \/>\n\u2014yacht_app.py<br \/>\n\u2014[output]<br \/>\n\u2014\u2014boatlist.json (a file generated by the app)<br \/>\n\u2014[static]<br \/>\n\u2014\u2014<br \/>\n\u2014\u2014\u2014style.css<br \/>\n\u2014\u2014[images]<br \/>\n\u2014\u2014\u2014artboard.png<br \/>\n\u2014[templates]<br \/>\n\u2014\u2014index.html<br \/>\n\u2014\u2014results.html<br \/>\n\u2014\u2014template.html<\/p>\n<h3>Back to the app<\/h3>\n<p>The app\/python file consists of several parts which mostly consist of mini scripts to render results to a specific template. The simplest is:<\/p>\n<pre><code>@app.route(\"\/\")\ndef home():\n    return render_template(\"index.html\")<\/code><\/pre>\n<p>This simply displays the &#8220;index.html file which is a basic form. The next is:<\/p>\n<pre><code>@app.route('\/results')\ndef results():\n    data = []\n    with open(\"output\/boatlist.json\", \"r\") as jdata:\n        data = json.load(jdata)\n    return render_template(\"results.html\", boatlist=data['boats'],predata=data['fileinfo'])<\/code><\/pre>\n<p>&nbsp;<\/p>\n<p>This defines &#8220;results.html,&#8221; basically calling for it to open using the boatlist.json file as its data.<\/p>\n<p>The next one is &#8220;index.html&#8221; after the search button is clicked and it uses a form post request to gather the input data an executes the rest of the python script using that data. I am not going to get into that as it&#8217;s just a variation of the <a href=\"http:\/\/macblaze.ca\/?p=13488\">Book Page scraping<\/a>.<\/p>\n<p>I did add a bit at the end that reopens the output json file and uses the submitted search parameter to reorder it before moving on to the results page.<\/p>\n<pre><code>@app.route(\"\/\", methods=['POST'])\ndef echo():\n    #get index form data\n    if request.method == \"POST\":\n        inputcurr=request.form[\"inputcurr\"]\n        minprice=request.form[\"minprice\"]\n        maxprice=request.form[\"maxprice\"]\n        minlength=request.form[\"minlength\"]\n...\n    data = []\n    with open(\"output\/boatlist.json\", \"r\") as jdata:\n        data = json.load(jdata)\n        data['boats'].sort(key=keyparam)\n    return render_template('results.html', boatlist=data['boats'],predata=data['fileinfo'])<\/code><\/pre>\n<h3>&nbsp;Back to the HTML<\/h3>\n<p>Flask uses the template.html file to set all the default elements (header, navbar, styles sheets etc.)<\/p>\n<p>I won&#8217;t bother with the code for the index page, but here is the results which is pretty simple. Basically extracting the header information form the &#8220;predata&#8221; section of the json and then a loop though the &#8220;boatlist&#8221; to display each boat.<\/p>\n<pre><code>&lt;!DOCTYPE html&gt;\n&lt;html lang=\"en\"&gt;\n&lt;head&gt;\n    &lt;title&gt;Yachtworld Results&lt;\/title&gt;\n&lt;\/head&gt;\n\n&lt;body&gt;\n{% extends \"template.html\" %}\n{% set active_page = \"results\" %}\n{% block content %}\n&lt;div class=\"page-header\"&gt;\n    &lt;h2 class=\"orange\"&gt;YachtWorld Results&lt;\/h2&gt;\n    &lt;div id=\"preface\"&gt;\n        {% for pb in predata %}\n    &lt;div&gt;\n        &lt;p&gt;{{pb.Text}}&lt;br\/&gt;Updated: {{pb.Date}}\n        &lt;br\/&gt;&lt;a href=\"{{pb.Creator}}\"&gt;created by {{pb.Creator}}&lt;\/a&gt;&lt;\/p&gt;\n        &lt;p&gt;Price range : &lt;strong&gt;${{pb.Low}} &lt;\/strong&gt; and &lt;strong&gt;${{pb.High}}&lt;\/strong&gt; (${{pb.Currency}})&lt;br\/&gt;\n        Boat length: &lt;strong&gt;{{pb.Short}}'&lt;\/strong&gt; \u2013 &lt;strong&gt;{{pb.Long}}'&lt;\/strong&gt;&lt;\/p&gt;\n    &lt;\/div&gt;\n    {% endfor %}\n    &lt;\/div&gt;\n    {% for boat in boatlist %}\n    &lt;div class=\"col-xs-6\" style=\"min-height:170px;\"&gt;\n        &lt;div class=\"col-md-5 text-right \"&gt;\n            &lt;img src=\"{{boat.Thumb}}\" alt=\"\" width=\"150px\"&gt;\n        &lt;\/div&gt;\n        &lt;div class=\"col-md-7\"&gt;\n            &lt;h3&gt;&lt;a href=\"{{boat.URL}}\"&gt;{{boat.Name}}&lt;\/a&gt;&lt;\/h3&gt;\n            &lt;p&gt;&lt;strong&gt;${{boat.Price}} &lt;\/strong&gt; \/ {{boat.Size}}&lt;\/br&gt;\n            {{boat.Location}}&lt;\/p&gt;\n        &lt;\/div&gt;\n    &lt;\/div&gt;\n    {% endfor %}\n\n{% endblock %}\n&lt;\/body&gt;\n&lt;\/html&gt;\n<\/code><\/pre>\n<p>Pretty simple really&#8230;lol.<\/p>\n<h4>In conclusion<\/h4>\n<p>Anyway I don&#8217;t suspect anyone will actually understand\/get much out of all this and its here mostly for posterity. There are plenty of resources online to help dig into the code.&nbsp;<\/p>\n<p>I am still playing with it and it will continue to evolve. I did post it on <a href=\"https:\/\/github.com\/b-t-k\/searchboats.github.io\" target=\"_blank\" rel=\"noopener noreferrer\">github<\/a> if anyone is interested in the latest version (I have already added in some bits to handle price errors). I am still searching for host to make it publicly available but&nbsp; anyone can download it from Github if they want to run it on their own server.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A continuation of The Great Flask Adventure. The structure When last we left our heroes we had posted a groovy python script: Mark III. This was saved as yacht_app.py in a folder. The rest of the files were built and&nbsp; also stored there. The structure of the folders is thus: [searchyachtworld] \u2014yacht_app.py \u2014[output] \u2014\u2014boatlist.json (a [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false},"categories":[1],"tags":[],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/macblaze.ca\/index.php?rest_route=\/wp\/v2\/posts\/13680"}],"collection":[{"href":"https:\/\/macblaze.ca\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/macblaze.ca\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/macblaze.ca\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/macblaze.ca\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=13680"}],"version-history":[{"count":2,"href":"https:\/\/macblaze.ca\/index.php?rest_route=\/wp\/v2\/posts\/13680\/revisions"}],"predecessor-version":[{"id":13682,"href":"https:\/\/macblaze.ca\/index.php?rest_route=\/wp\/v2\/posts\/13680\/revisions\/13682"}],"wp:attachment":[{"href":"https:\/\/macblaze.ca\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=13680"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/macblaze.ca\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=13680"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/macblaze.ca\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=13680"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}