Disabling images in Python Markdown
Posted by Sean Fujiwara in Python on May 5, 2011
Here’s a quick snippet that shows how to disable images (or any extension) in Python Markdown:
import markdown class MyMarkdownExtension(markdown.Extension): def extendMarkdown(self, md, md_globals): del md.inlinePatterns['image_link'] del md.inlinePatterns['image_reference'] my_markdown_extension = MyMarkdownExtension() raw_text = 'This is a test image: ' print markdown.markdown(raw_text, [my_markdown_extension], safe_mode = 'escape')
Edit:
Some processing is disabled through md.parser.blockprocessors instead.
Here are the options for each:
md.inlinePatterns:
'backtick' 'escape' 'reference' 'link' 'image_link' 'image_reference' 'short_reference' 'autolink' 'automail' 'linebreak2' 'linebreak' 'html' 'entity' 'not_strong' 'strong_em' 'strong' 'emphasis' 'emphasis2'
md.parser.blockprocessors:
'indent' 'code' 'hashheader' 'setextheader' 'hr' 'olist' 'ulist' 'quote' 'paragraph'
Running a reverse proxy for App Engine on Amazon EC2
Posted by Sean Fujiwara in App Engine, Sample Code on April 11, 2011
Updated Feburary 7th, 2012
1. Create a security group on EC2 that opens ports 22 (SSH) and 80 (HTTP).
2. Start an instance on EC2 using an Ubuntu AMI. Select the security group you just created when launching the instance. I used a micro instance running the “ami-ad7e2ee8″ (32-bit Ubuntu 10.10) image. The best place to find the AMI that you want is http://cloud-images.ubuntu.com/releases/. Everything there is nicely organized by version, release type, CPU architecture, and backing storage. (As opposed to the mess of text in the EC2 classic wizard).
3. Assign an elastic ip to the instance.
4. Go to your domain registrar, and edit your DNS zonefile. Add a CNAME that points www to your “Public DNS” on EC2 (ec2-elasticip.zone.compute.amazonaws.com.). It’s important to use a CNAME record rather than an A record, because your instance will not be accessible to other EC2 instances by public IP address.
5. SSH into your server and install nginx.
If you want the latest version of nginx, you need to add these repositories to apt-get to download from nginx.org. If not, skip this block, and you will get the latest version available from Ubuntu.
cd ~ sudo echo "deb http://nginx.org/packages/ubuntu/ quantal nginx" >> /etc/apt/sources.list sudo echo "deb-src http://nginx.org/packages/ubuntu/ quantal nginx" >> /etc/apt/sources.list sudo wget http://nginx.org/keys/nginx_signing.key sudo apt-key add nginx_signing.key
Now, download and install nginx.
sudo apt-get update sudo apt-get upgrade sudo apt-get install nginx sudo vi /etc/nginx/nginx.conf
6. Now, remove any existing server blocks, and add your own to /etc/nginx/nginx.conf.
server {
listen 80;
location / {
}
}
server {
listen 80;
server_name www.mysite.com;
location / {
proxy_pass http://mysite.appspot.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Real-HOST $host;
}
}
The first server block is the default, so this blocks requests that are not for the domain you’re trying to proxy.
7. Run nginx:
sudo service nginx start
8. You should be able to access your App Engine site using your own domain. However, in your app engine request handlers, self.request.host will be set to your appspot domain, and self.request.remote_addr will be set to your ec2 ip address. We can fix this by adding some middle ware to app engine, assuming you’re using webapp or webapp2.
class ReverseProxyMiddleware(object):
def __init__(self, application, debug=False):
self.application = application
def __call__(self, environ, start_response):
real_host = environ.get('HTTP_X_REAL_HOST')
if real_host:
environ['HTTP_HOST'] = real_host
environ['SERVER_NAME'] = real_host
real_ip = environ.get('HTTP_X_REAL_IP')
if real_ip:
environ['REMOTE_ADDR'] = real_ip
return self.application(environ, start_response)
To use it, wrap your WSGIApplication right after initialization.
application = WSGIApplication([ ... ]) application = ReverseProxyMiddleware(application)
9. That’s it! One thing to note is that app engine cron jobs and task queues don’t know anything about your reverse proxy, so in those handlers, self.request.host will still be your appspot domain.
Using a webcam in Molehill
Posted by Sean Fujiwara in ActionScript 3 on March 22, 2011
I’ve created a sample project on github that demonstrates how to use a webcam in Molehill. It’s not really any different than using a static texture, except for these lines:
snapshot.draw(video, snapshotTransform);
texture.uploadFromBitmapData(snapshot);
The performance is very impressive, and you can see from the code, it was simple to do. Hooray for Molehill.
Edit: Updated to work in Flash Player 11 beta 2.
ByteArray compress vs. deflate
Posted by Sean Fujiwara in ActionScript 3 on March 6, 2011
I couldn’t find any information on the difference between ByteArray.compress() and ByteArary.deflate(), so I decided to do a quick test.
package
{
import flash.display.Sprite;
import flash.utils.ByteArray;
import flash.utils.getTimer;
public class CompressionTest extends Sprite
{
public function CompressionTest()
{
var start:uint;
var bytes:ByteArray = new ByteArray();
for(var i:uint = 0; i < 100000; i++)
{
bytes.writeShort(0);
bytes.writeFloat(Math.random());
bytes.writeFloat(Math.random() * Number.MAX_VALUE);
}
trace('Uncompressed: '+bytes.length);
start = getTimer();
bytes.compress();
trace('Time spent on compress: '+(getTimer() - start)+'ms');
trace('Compressed size with compress(): '+bytes.length);
start = getTimer();
bytes.uncompress();
trace('Time spent on uncompress: '+(getTimer() - start)+'ms');
start = getTimer();
bytes.deflate();
trace('Time spent on deflate: '+(getTimer() - start)+'ms');
trace('Compressed size with deflate(): '+bytes.length);
start = getTimer();
bytes.inflate();
trace('Time spent on inflate: '+(getTimer() - start)+'ms');
}
}
}
My results are:
Uncompressed: 1000000 Time spent on compress: 1294ms Compressed size with compress(): 416142 Time spent on uncompress: 5ms Time spent on deflate: 1302ms Compressed size with deflate(): 416136 Time spent on inflate: 5ms
So, it looks like there is absolutely no difference.
According to this StackOverflow post, the only difference is a header and checksum in the compress version.
Flash Player molehill is available on Adobe Labs!
Posted by Sean Fujiwara in ActionScript 3 on February 27, 2011
Finally, we get a low-level 3D API for flash. The documentation on labs is really bad, the few examples there are don’t work at all. So, I made a simple source code example on github:
https://github.com/magicalhobo/MolehillSimpleExample
typeof in python
Posted by Sean Fujiwara in Python, Sample Code on February 18, 2011
I could not find a good way to get the name of a class from an instance with Python on google. It’s simple (but not obvious):
str(type(var))
Google App Engine “ImportError: DLL load failed with error code 193″
Posted by Sean Fujiwara in Time Wasted on February 18, 2011
Today I installed PIL, tried to use the images API on the local dev server, then got this message. The problem was I was running a 64-bit version of python, which won’t load PIL correctly. The solution is to install a 32-bit version of python, and make sure you re-install PIL into that copy of python.
