So, a few years ago I made a small flask-app, just to keep myself entertained. This was a few years after I did another minimal webapp in React. Since I just migrated to a new set of servers I thought, I fluff those apps a bit. Bring some color into them, upgrade to the latest versions, fix a few bugs and so on.

Now I’ve got a set of interesting applications, all managed in the same flask-container, delivering some features that you might find useful.

URIFunctionwarm-up needed?
flenn.netshows you a warm and fuzzy image from reddityes
geocheck.inshows you your current location (ip or device based with js)no
joker23.deshows you an excuse from the BOFH fortune moduleno
neoanarchie.netshows you a quote from the anarchism fortune moduleno
virtualhug.megives you a virtual hug with a GIF from Giphyyes

Some of these are a bit icky, you might be familiar with the new policies around API usage at reddit, which may or may not have lead to a few strange images shown on flenn.net displaying a well known late-night moderator from the US along with derogative comments towards the current chief executive of reddit.

This means I have to read reddit as a ’normal’ RSS client and then extract image-urls from it, that you will then embed directly via my website.

To my dismay this function (caching) of the 5 year old variant was implemented with a now retired function of werkzeug.contrib so I had to move to flask_caching. And this, really, is wonderful.

...
from flask_caching import Cache
...

# this is where the image-meta being stored
cache = Cache(config={
    "CACHE_TYPE": "SimpleCache",
    "CACHE_DEFAULT_TIMEOUT": 60 * 60
    })

cache.init_app(your_flask_app)

@cache.cached(key_prefix="aww-images")
def awwimagegen():
    """
    generate a current aww-set.
    KEEP THIS CACHED OR GET BLOCKED BY GREEDY REDDIT ADMINS
    """
    items = dict()
    for feed in AWWFEEDLIST:
        allitems = feedparser.parse(feed)
        for item in allitems['items']:
            addthing = redditrssstrip(item)
            if addthing:
                items.update(addthing)
    return items

I don’t have do fiddle around with checking if the cache is live or not, its just slapping on the decorator and that’s it, the return-value of the function will be cached as requested. Brilliant!

This obviously still means that the first couple of requests to that page and some request every time the cache dies will be aw(w)fully slow.

Another thing I’ve move was that old react-app for your location. This I wanted to replace with Vue, since I hate JS. As it turns out, I hate Vue more than I hate vanilla JS. Because of what I wanted was accomplished in less than three dozen lines of JS (see the source if you’re interested), the level of abstraction that vue offers did not help me and instead only got in my way. My way is to make the information on my websites as accessible as possible.

One of the things that I like to do is designing my site in a way that it still works if you browse to them with a text-only browser (like w3m) and for those sites I did go one step further.

With a little help of my friends flask.request and json …

...
import json
from flask import Flask, request
...
def special_render(render_args):
    """
    allow to just return the render arguments as json (very simple GET info for browsers)
    if the client wants json specifically.
    curl -H "Accept: application/json" http://localhost:3000/yourpath to test.
    """
    mimes = request.accept_mimetypes
    if mimes.accept_json and not mimes.accept_html:
        return json.dumps(render_args)
    else:
        render_args.update(evalsite())
        return TEMPLATE.render(**render_args)

… you can use any of my sites as a Service. Most likely geocheck.in will be the most useful, since besides the current ip-based location it also reflects the external ip address. I wonder if I should drop ipschwein.de from my toolbox now. It is still much more beautiful, but then again, it does not support IPv6.

curl -sS -L -H "Accept: application/json" https://geocheck.in | jq .

I hope you’ll find something you can use here.

If you have any questions, comments or remarks, be sure to give me a ping, I’ll happily update this post.