Skip to content

Instantly share code, notes, and snippets.


Michael Herrmann mherrmann

View GitHub Profile
View It doesn't


I directed you here because you sent me a question that I'd like to help answer, but am unable to because I'm missing some context. Very often, this is because you wrote "it doesn't work" without providing much additional detail. It's probably clear to you what you mean, but I am confused. Maybe I'm just not smart enough. But in any case, please help me help you by sending me further information. For example:

  1. How does it not work? What did you try? What did you expect to happen? What happened instead?
  2. Did you get any error messages? If yes, exactly what did they say?
  3. Maybe you can send me a screenshot to clarify?
  4. Where did you try this? On your phone, or on a laptop / standalone PC? What's your operating system?
  5. If the problem occurs on a web site, which browser are you using?
  6. ... does it also happen with a different browser?
View gist:efc2e376471ef3e18a5b697f0636268e
As of May 29, 2021, the available Linode types are:
View Good PRs are minimal
Hi! Thank you for offering a PR for one of my open source libraries. I really
appreciate it, because in most cases, I have very little time to maintain them.
I often get PRs that lead to a back-and-forth between me and the contributor,
where I ask them to undo many of the changes they have made. To avoid this in
your case, or to at least give you an idea why I'm asking you to adapt your PR,
here are my criteria for accepting PRs.
Every PR should have one, and only one, unique goal. Your PR should make the
absolute minimum number of changes that are required to achieve this goal.
mherrmann /
Created March 25, 2020 08:55
digistore python validate thank you page
from hashlib import sha512
from urllib.parse import parse_qs, unquote
def is_digistore_query_valid(qs, thankyou_page_key):
qs_dict = {key: unquote(value[0]) for key, value in parse_qs(qs).items()}
expected_sha = qs_dict.pop('sha_sign')
sha_string = ''
for key, value in sorted(qs_dict.items()):
sha_string += f'{key}={value}{thankyou_page_key}'
m = sha512()

Contributor License Agreement

In order to clarify the intellectual property license granted with Contributions from any person or entity, Michael Herrmann ("Michael") requires a Contributor License Agreement ("CLA") to be signed by each Contributor, indicating agreement to the license terms below. This license is for your protection as a Contributor as well as Michael's protection; it does not change your rights to use your own Contributions for any other purpose.

You accept and agree to the following terms and conditions for Your present and future Contributions submitted to Michael. Except for the license granted herein to Michael and recipients of software distributed by Michael, You reserve all right, title, and interest in and to Your Contributions.

  1. Definitions.
    "You" (or "Your") shall mean the copyright owner or legal entity authorized by the copyright owner that is making this Agreement with Michael. For legal entities, the entity making a Contribution and all other entities that control, are
mherrmann /
Created October 5, 2016 08:57
Determine if a file is hidden on OS X
from ctypes import CFUNCTYPE, POINTER, c_uint8, c_void_p, c_long, addressof, \
byref, CDLL, cdll, c_char_p
from ctypes.util import find_library
def is_hidden(path):
if not isinstance(path, bytes):
path = path.encode('utf-8')
with AutoRelease() as autorelease:
url = autorelease(CFURLCreateFromFileSystemRepresentation(
None, path, len(path), False
mherrmann /
Last active December 15, 2015 16:22
Measure the time taken by some Python code
from collections import OrderedDict
from time import time
class Timer(object):
Measure the time taken by some Python code, incl. its subtasks:
>>> with Timer('parent') as timer:
... sleep(0.5)
... with timer.child('child') as child: