Категория: In English @en

pyoperalink: certificate verify failed

If you’re trying to use pyoperalink and you’re getting certificate verification errors:

httplib2.SSLHandshakeError: [Errno 1] _ssl.c:507: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

That might be because libhttpd2’s root certificate list is too short (I don’t know why).

Quick solution: Download this cacert.pem and save as Python\Lib\libhttpd2\cacerts.txt or Python\Lib\site-packages\libhttp2\cacerts.txt. You’ll need administrator privileges and make a backup of cacerts.txt beforehand.

Ostensible explanation: Certificates are chained: there’s a handful of root certificates which are used to sign site certificates or second-layer certificates and so on. Open auth.opera.com and study the certificate (in Opera you have to click the green placard in the address bar). At the time of writing the topmost certificate in its chain is "DigiCert High Assurance EV CA-1".

Open cacerts.txt. This is the root certificates libhttpd2 understands. Search for "DigiCert" or "Digi": no matches. Thus, libhttpd2 does not trust the "DigiCert High Assurance". It has to be added to this list. "Quick solution" does this by replacing the file with a longer list of trusted certificates extracted from the list at mozilla.org. You can use any other list in compatible format which contains root certificates you need. (You should study the source before copying it because I may be malevolent or mistaken myself).

Restore deleted notes in Anki

Sometimes you accidentally delete notes/cards in Anki. Ctrl-Z can revert one deletion, but several notes cannot be restored. If you use Anki Sync and haven’t done any important edits locally, you should simply delete the collection and redownload it. But what if you don’t want to lose local edits/reviews?

Note: If you have Sync enabled, do not sync at any point throughout this instruction. Pull out the network cable, disable Wi-Fi etc, to stop Anki from accidentally uploading your collection midway.

  1. Close Anki.
  2. Go to My Documents and zip the whole Anki folder. Put the archive in the safe place.
  3. Revert the collection to an older date:
    • Go to My Documents\Anki\YourProfile\Backups and choose a backup from when you have not yet deleted the cards.
    • Start Anki, wait until it loads, then double-click the chosen .apkg file.
    • Anki will say this will replace your collection, confirm it.
    • You have now reverted the collection to the older date.
  4. Export the broken deck:
    • Go to File->Export.
    • Choose "Export format: Anki deck package".
    • "Include": the deck where the deleted cards were.
    • Include sheduling information and media.
    • Press "Export" and save the file somewhere outside of Anki folder.
  5. Restore the current deck state
    • Close Anki.
    • Delete the My Documents\Anki folder
    • Unpack the zip file you have prepared before
    • Make sure the contents of My Documents\Anki folder is as before (no double Anki\Anki folders etc)
  6. Start Anki
  7. Double-click the saved deck .apkg file and let Anki import it
  8. Missing cards are imported with all their history.

Apache cannot serve files with unicode filenames

I’ve had a problem with my Apache setup where it couldn’t serve images with unicode characters in file names:

 <a href="http://www.boku.ru/img/проверка.jpg">http://www.boku.ru/img/проверка.jpg</a> (really missing right now; just an example)

SCP client (WinSCP) clearly showed files were present, other files from the same folder could be accessed but those with cyrillic characters were returning 404.

Using Wireshark, I determined my browser sends urlencoded text (B0%D0…) instead of bare unicode, but that was, apparently, like it should be.

Studying Apache logs, I’ve found it complain about missing files, re-encoded in \x notation (\xb0\xd0…). For a while I thought this suggested a problem, but in the end it was unrelated and probably correct behavior.

Turns out, WinSCP does not use UTF-8 by default. Instead it sends file names to server in the local PC encoding, Win-1251 in my case. Looking through WinSCP everything seemed alright because it reads filenames back in the same encoding. But from the server point of view (as seen through SSH for example) those were not Russian characters but some Krakozyabry.

In other words, there really was no проверка.jpg.

To recongifure WinSCP, open Site manager, press Edit, Advanced, "UTF-8 encoding for file names: On", then reconnect. You’ll have to rename all affected files.

A lost game

A move many debaters try to pull off is setting up a lost game. It works like this:

“Punishing those who download books is unfair. They just take what was lying in the open. That’s a basic human right.”
“Yes they can reshare. You can’t punish for that either. They haven’t signed a contract promising not to do so. They are free to do as they wish.”
“Eh, okay. But surely, as a writer, I’ll just pen a contract by which anyone who buys and then shares is to be held responsible for all the millions of dollars of damages?”
“No, we cannot do this because that’s immoral. That’s basically enslaving him.”
“But then how do we protect the writers?”
“I don’t know? You want copyright, you think of something.”

Or like this:

“The government has no right to ban Freedom Hosting! They didn’t host CP, they hosted everything, that was just their business model: no restrictions.”
“Providers cannot be ordered to ban sites. That’s censorship!”
“People must be allowed to remain anonymous on the internet.”
“So you want to fight CP? We cannot ban the site, cannot ban the hoster and cannot find out who the owner is. I guess you have to sit and wait until the owner reveals itself, FBI! Know that I rooted for you.”

Negotiations don’t work like this. Either you don’t support the idea at all, or you see a point in it and then by the rules of discussion you must protect its interests to the extent you see it as important. In other words, if you agree you agree. No one is ever convinced by “I’d love to clean the room mom, but there’s a reason I can’t”.

That’s not how you should do it. There are several sides to the story and it’s okay to take one as long as you’re honest.
“I want there be a certain amount of uncontrollable freedom in the internet because total control is unhealthy for any society”. Absolutely.

See how the reaction changed? That’s because that was the truth. That was the idea that moved you, not the layers of justifications built around to make it “consistent”. And what moved one person may move another. You wouldn’t want to be held responsible for simply providing a hosting? Neither would I. It just feels wrong that one can go to jail for typing on the keyboard? Does so to me. You don’t want to be made to buy books, you want to buy books you liked? I can relate to that.

WordPress not remembering name or email for anonymous commenters

Someone reported that WordPress at boku.ru hasn’t been remembering the name and email which you enter in comments. I vaguely remembered this working before. After some investigation, turns out it was W3 Total Cache plugin which uses comment_cookie_lifetime filter to drop standard WordPress cookie lifetime from half a year to 30 minutes. And since my site runs as GMT, this was eaten by the 4-hour time difference.

W3 Total Cache did that because for cookie-less visitors it serves fast static version of the page (which can not be tailored for each visitor and have their name pre-entered, the way names are handled now). As long as you have posted a comment, you receive a cookie and WordPress serves you slower, dynamic version of the page. So the longer the cookie lifetime is, the longer you’re going to be served dynamic pages (but the longer your settings are going to be preserved).

This setting can be changed at “Performance > Page Cache > Advanced > Comment cookie lifetime”.

If you’ve stumbled upon this post while solving a related problem, here’s some additional pointers:
1. WordPress stores commenter name/email/url in cookies:

An example of how querying for these values should look like is in /wp-includes/comment-template.php/comments_template()

2. Your comment form is generated either by this, or by customization hook in your theme’s comments.php.

3. To debug cookies, add print_r($_COOKIES); to your theme’s header.php, don’t forget to remove it later. Use Wireshark or your browser’s request sniffer to track what’s being sent.

Can you repeat that?

Reading personal experiences on trimming the sizes of Delphi executables, I often encounter stories like this one:

I’ve moved from Delphi 2007 to Delphi XE3 and my executable went from 3Mb to 18Mb! I did this thing and that thing and disabled RTTI and set these flags and got the executable down to 16Mb. Nice, but not enough.
Then I discovered UPX and it reduced the size to 3.5Mb! UPX is magic!!

This is obviously wrong, it should make anyone with half a pint of a sense cringe – but why is it wrong? They got their size down. That’s what they wanted.

And then I figured:
Well, you got it down to 3Mb. Can you repeat that?

If Delphi XE8 comes out and your executable is suddenly 17Mb again, what are you going to do to trim it back? If you had spent several hours more and actually understood what happened and how to unhappen that, then you’d still be on a fair footing with the circumstances. Your trump card of using UPX and being excited would still be with you. And now it isn’t.

Right-click to copy web path for the file

Everybody who uses Dropbox have probably seen that you can right-click the file and “Copy shared path”, under which it is accessible in the internet.

I thought it would be nice to have similar functionality for BTSync and wrote the following sсript.

Code on pastebin.

Usage: put the code into “Copy links.cmd”, drop the shorcut to it into “C:\Users\[your username]\AppData\Roaming\Microsoft\Windows\SendTo” or wherever Sent To folder is in your versions of Windows.

Now suppose you have a folder C:\Download\images which is BTSync-ed to your server as http://example.org/lib/img. Create a file C:\Download\images\path.txt and write the above web base path to it.

Now select some files, right-click them and press “Send To -> Copy Links”. Web links for all the selected images are copied into your clipboard:

C:\Download\images\test\file.png --> http://example.org/lib/img/test/file.png

The sсript can also be used if you have a web server running at home which presents some of the files on your PC to the outside world, or even if you share some files and want to copy those as “\\mypc\share\path”. Since the sсript looks for the first available path.txt in the parent directories, you can link different folders to different addresses, or even copy and modify the sсript so that the same folder is linked to several base paths (“Copy as web address”, “Copy as local \\share”).


Bias is when you’ve picked a desired outcome before examining the issue. By presenting an objectively wrong party as having an equally valid position, you are biased in their favor.

flutterfly28 at reddit

This is the difference between being neutral and being neutrally biased. It’s true that many choose a neutral position because “the truth is always somewhere in the middle”, which is a bias. It’s also true that there is still usually more than one side to the story.

Shingeki no Sasha

Giants are attacking my town
And here I am, eating my potato
Peope are being killed right now
But baked potatos are good when they’re warm.

For those monsters people are just food,
In the same way potato is food for me
Why wouldn’t titans stop eating people
And start eating potatoes?

My combat gear lies beside me
Ready to fly me wherever I want
Potato fields are vast and well guarded
You can’t navigate there without some technical advantage.

Scout corps are the best of the best
They are the humanity’s only hope
If not for them, titans would surely win
And take all of our potatos, as well as kill everyone of course.

— Sasha no Kartoshka OP translation (provisional).

Multiobject try..finally

Just a simple Delphi pattern. We all have encountered nested try..finally blocks like this:

CChar := TTextTableCursor.Create(TChar);
 CCharProp := TTextTableCursor.Create(TCharProp);
   Builder := TCharPropBuilder.Create(Result);
     //Do some work with all three objects
     //Since all three are needed, we can't destroy any before this point



end;But there’s a nicer way of doing the same while still being exception safe (and avoiding the overhead of three try..finally exception frames):

CChar := nil;
CCharProp := nil;
Builder := nil;
 CChar := TTextTableCursor.Create(TChar);
 CCharProp := TTextTableCursor.Create(TCharProp);
 Builder := TCharPropBuilder.Create(Result);
//Do some work with all three objects