Posts about python (old posts, page 45)

2013-04-10 10:23

Forget about "incognito mode", use a throwaway browser!

It's not because I wrote it (ok, yes, it's because I wrote it) but if you ever need a "clean" browser, without cookies etc for tests, you can do worse than using my Devicenzo like this:

rm -f ~/.config/ralsina/devicenzo.conf
curl https://devicenzo.googlecode.com/svn/trunk/devicenzo.py | python

The first line removes all configuration, cookies, etc, you may have and the second one downloads the latest version (don't worry, it takes about 2 seconds) and launches it.

And voilá, a completely fresh out-of-the-box, webkit-based browser, with no previous history, cookies, or configuration, fairly feature-complete.

Note

this requires you having python and PyQt already installed (which is why devicenzo itself is so tiny)

2013-04-08 10:14

Serbo-Croatian version of PyQt By Example!

A while ago I got an email from Anja Skrba asking me for permission to translate PyQt by Example into Serbo-Croatian.

And here it is all nice and translated. Lots of thanks to Anja for the hard work!

2013-04-05 21:54

Using rst2pdf in Different Ways

This was an idea by Dinu Gherman: you can use rst2pdf as a flowable generator for reportlab. Suppose you want to create, in a reportlab "story", a bunch of paragraphs, with emphasis, links, etc, and perhaps a table.

Using restructured text, it's something like this:

This is a paragraph. It has a link: http://rst2pdf.ralsina.me and then some random text.

+-------------+---------------------------+
| A table     | With cells                |
|             |                           |
|             |                           |
|             |                           |
|             |                           |
+-------------+---------------------------+
| And inside                              |
| it some                                 |
| more text                               |
|                                         |
|                                         |
+-----------------------------------------+

* And a list
* Just to make it harder

  + with a nested item here

It is, of course, perfectly possible to generate a bunch of reportlab (or rather platypus) flowables to represent all this. It will just mean some 75 lines of code. And if you change anything, then you have to edit code!

Or you can take advantage of rst2pdf and do this:

from docutils.core import publish_doctree
from rst2pdf.createpdf import RstToPdf
from reportlab.lib.units import cm
from reportlab.pdfgen.canvas import Canvas
from reportlab.platypus import Frame

rest_text = """
This is a paragraph. It has a link: http://rst2pdf.ralsina.me and then some random text.

+-------------+---------------------------+
| A table     | With cells                |
|             |                           |
|             |                           |
|             |                           |
|             |                           |
+-------------+---------------------------+
| And inside                              |
| it some                                 |
| more text                               |
|                                         |
|                                         |
+-----------------------------------------+

* And a list
* Just to make it harder

    + with a nested item here
"""
r2p = RstToPdf()
doctree = publish_doctree(rest_text)
story = r2p.gen_elements(doctree)
canv = Canvas("platypus-rest.pdf")
f = Frame(2 * cm, 2 * cm, 16 * cm, 18 * cm, showBoundary=True)
f.addFromList(story, canv)
canv.save()

This produces this pdf. And of course editing it is rather easier than editing code. Since you are not using rst2pdf to do the final PDF generation, you can use these flowables in your own documents.

The bad news

Some things will not work, like headings, since rst2pdf creates flowables that do a ton of things like adding themselves on indexes and such. If you want a heading-like thing you can use classes:

.. class:: heading1

This will look like a heading

This is a regular paragraph.

Other random restructured text features may or may not work, like footnotes or citations.

2013-03-26 12:34

The Password Is Password (follow the link to see what I mean)

I think this is a first in the world of static site generators :-)

Now Nikola supports password-protected pages. How does it work?

If you add a password metadata field, then it will "Just Work". Like this:

I think this is a first in the world of static site generators :-) And the result is what you are seeing now.

How is it implemented? Nikola will encrypt the content using RC4, then wrap it in a <div>, and tack a form at the end that triggers Javascript code to decrypt it, and show it.

Is it secure? Well, I am not a cryptographer, so assume no. Specifically, while RC4 is considered secure, I am not discarding the beginning of they keystream, and the implementations I am using are not audited.

So, don't use this for anything that could get you in trouble. Have fun!

UPDATE Remember when I asked "Is it secure?" well, really, no it's not. It's not stupid in the sense that decoding what's written in the post will require at least a modicum of effort by whoever is so interested in reading what you are posting in your site, but people with crypto chops will crack it like a WEP-secured AP, mmmmkay? It's also stupidly easy to bruteforce this, so be smart about passwords.

OTOH, it's more secure than HTTP simple auth, since you can't sniff it (not that simple auth is secure) and it can hide a piece of the page, which using server-based auth can't.

I may do a more secure version eventually, but this is not it. Therefore, use for fun stuff, not to hide important/illegal stuff.

2013-03-22 11:01

Nikola Internals Doc

Since Nikola, my static blog/website generator is getting a substantial amount of code from others, I thought it may be a good idea to roughly document how it works internally. So, here is Nikola internals which is very much a work in progress.

2013-03-15 00:39

Migrating from Wordpress to Nikola

Several people have migrated from Wordpress into Nikola, and here are some of their descriptions of the process:

In general, it seems to be working, but there's some work still to be done. Wordpress supports many different plugins and extensions which react to markup in their pages, and supporting that's almost an infinite task. Currently Nikola's importer handles a few of the more common. But if you try to import your blog and get less than ideal results, please file a bug and I'll do my best to fix it.

Usually the fixes are rather simple, it's just that I have never seen that specific thing ;-)

Have fun!

2013-03-12 20:09

Standalone Search in Nikola

This has been in the master branch of Nikola for a while but only now have I tried to fully integrate it, and polish all (most) of the rough edges.

By default, Nikola comes with support for search forms using Google and Duckduckgo. Some people disapprove of them for different reasons [1] so there was a request about supporting a standalone search engine.

The best of breed of those things seems to be Tipue so that's what I supported.

To use this, you need to enable a plugin, and do some configuration changes.

The plugin is called task_localsearch and you can find it in the Nikola source tree

Suppose your site is in a folder called mysite then to enable this plugin you need to create mysite/plugins and then copy task_localsearch.plugin and task_localsearch in there.

Then, in your site's conf.py find these options and change them accordingly:

SEARCH_FORM = """
<span class="navbar-form pull-left">
<input type="text" id="tipue_search_input">
</span>"""

ANALYTICS = """
<script type="text/javascript" src="/assets/js/tipuesearch_set.js"></script>
<script type="text/javascript" src="/assets/js/tipuesearch.js"></script>
<script type="text/javascript">
$(document).ready(function() {
    $('#tipue_search_input').tipuesearch({
        'mode': 'json',
        'contentLocation': '/assets/js/tipuesearch_content.json',
        'showUrl': false
    });
});
</script>
"""

EXTRA_HEAD_DATA = """
<link rel="stylesheet" type="text/css" href="/assets/css/tipuesearch.css">
<div id="tipue_search_content" style="margin-left: auto; margin-right: auto; padding: 20px;"></div>
"""

How does it work? Here's a demo site for you to try!

I would not recommend doing this for a big site, since it may load a multi-megabyte javascript file when you search, but for small to medium sites, it may be ok.

[1] My own reason for disapproving of duckduckgo site search? It finds nothing.

2013-03-10 20:23

Doing Your Homework, With Style

As usual in all programming lists, every once in a while someone will post a question in the Python Argentina list which is obviously his homework. To handle that there are two schools of thought.

  1. Telling the student how to do it is helping them cheat.
  2. Telling the student how to do it is teaching him.

I tend more towards 1) but I think I have discovered a middle road:

1.5) Tell the student a solution that's more complicated than the problem.

That way, if he figures out the solution, he has done the work, and if he doesn't figure it out, it's going to be so obviously beyond his skill the teacher will never accept it as an answer.

As an example, here's the problem for which help was requested:

Given an unsorted list of two-letter elements (une lowercase, one uppercase), for example:

['eD', 'fC', 'hC', 'iC', 'jD', 'bD', 'fH', 'mS', 'aS', 'mD']

Sort it by these criteria:

  1. Create subsets according to the uppercase letter, and sort them by the number of members in ascending order, like this:

    ['fH', 'mS', 'aS', 'fC', 'hC', 'iC', 'jD', 'bD', 'eD', 'mD']
    
  2. Then sort each subset in ascending order of the lowercase letter, like this:

    ['fH', 'aS', 'mS', 'fC', 'hC', 'iC', 'bD', 'eD', 'jD', 'mD']
    

Ignoring that the problem is not correctly written (there are at least two ways to read it, probably more), I proposed this solution, which requires python 3:

from collections import defaultdict
d1 = defaultdict(list)
[d1[i[1]].append(i) for i in  ['eD', 'fC', 'hC', 'iC', 'jD', 'bD', 'fH', 'mS', 'aS', 'mD']]
{i: d1[i].sort() for i in d1}
d2 = {len(d1[i]): d1[i] for i in d1}
print([item for sublist in [d2[i] for i in sorted(d2.keys())] for item in sublist])

This produces the desired result: ['fH', 'aS', 'mS', 'fC', 'hC', 'iC', 'bD', 'eD', 'jD', 'mD'] but it's done in such a way that to understand it, the student will need to understand roughly three or four things he has probably not been taught yet.

Contents © 2000-2019 Roberto Alsina