Marty McGuire

Posts Tagged python

2024
Thu Dec 19
RaspberryPi 500 keyboard with small eInk screen attached. A cat is displayed on the screen.

Raspberry Pi 500 + Adafruit Cyberdeck Hat + Pimoroni Inky wHat = eInk display for important Caturday photos

2019
Fri Mar 29

Loving the Adafruit PyPortal as an IndieWeb-powered photo device.

Code to come!

2018
Fri Jan 12
🔖 Bookmarked Object models / fuzzy notepad https://eev.ee/blog/2017/11/28/object-models/

“We could do with more experimentation around how objects work, but that’s impossible in the languages most commonly thought of as object-oriented.

Here, then, is a (very) brief run through the inner workings of objects in four very dynamic languages. I don’t think I really appreciated objects until I’d spent some time with Python, and I hope this can help someone else whet their own appetite.”

2017
Thu Jan 26

Spano - a minimum-viable Micropub Media Endpoint

Micropub is an open API standard to create posts on one's own domain using third-party clients  and currently a W3C Candidate Recommendation. One of the (semi-) recent additions is the idea of a Micropub Media Endpoint. The Media Endpoint provides a way for Micropub clients to upload media files to a Micropub service, receiving a URL that is sent along in place of the file contents when the post is published.

Some of the things I like about Micropub media endpoints include:

  • The spec allows the media endpoint to be on a completely separate domain from the "full" micropub endpoint.
  • The spec doesn't specify anything about how the files are stored or their final URLs or filenames.
  • They make it easy to separate the handling of (large) media files from the (presumably much smaller) content and metadata of a post.
  • They enable Micropub clients to upload multiple files without creating multiple posts. This makes it simpler to create posts that contain multiple images, like a gallery.

Personally, I wanted a Micropub media endpoint server with a few extra properties:

  • It should be able to run completely separately from, and therefore work in conjunction with, any other micropub server implementation.
  • It should not store duplicate files. If the same file is uploaded twice, the same URL should be returned both times.
  • It should not allow overwriting files. If two images of the same name are uploaded, both are kept and receive different URLs.

Enter HashFS

My extra features above essentially describe a content-addressable storage storage system. CAS is a way of storing and accessing data based on some property of the actual content, rather than (potentially arbitrary) files and folders.

HashFS is a Python implementation of a content-addressable file management system. You give it files, it will put them in a directory structure based on a cryptographic hash function of the contents of that file. In other words - HashFS can take any file and give back a unique path to that file which will never change (if you later upload a new version of the file, it gets a different path).

To add the the fun of HashFS, there is a Flask extension called Flask-HashFS which makes it easy to expose a HashFS file store on the web via the Python Flask framework.

Introducing Spano

Spano is a Micropub Media Endpoint server written in Python via the Flask framework which combines Flask-HashFS for file storage with Flask-IndieAuth (introduced earlier) to handle authentication and authorization.

Spano is a server-side web app that basically does one thing: it accepts HTTP POST requests with a valid IndieAuth token and a file named "file", stores that file, and returns a URL to that file. The task of serving uploaded files is left to a dedicated web server like nginx or Apache.

Using Spano

Once Spano has been set up and configured for your domain, uploading is a matter of getting a valid IndieAuth token. IndieAuth-enabled Micropub clients will do this automatically. For testing by hand I like to log in to Quill and copy the access token from the Quill settings page. With token in hand, uploads are as easy as:

curl -D - -F "file=@myfile.jpg" \
  -H"Authorization: Bearer xxxx..." \
  https://media.example.com/micropub/

Which should output a response like:

HTTP/1.1 100 Continue

HTTP/1.0 201 CREATED
Content-Type: text/html; charset=utf-8
Content-Length: 108
Location: https://media.example.com/cc/a5/97/7c/2004..2cb.jpg
Server: Werkzeug/0.11.4 Python/2.7.11
Date: Thu, 26 Jan 2017 02:40:05 GMT

File created: https://media.example.com/cc/a5/97/7c/2004..2cb.jpg

Integrating Spano with your Micropub Endpoint

If you want Micropub clients to use Spano as your Media Endpoint, you need to advertise it. This is handled by your "main" Micropub server using discovery. Essentially, a client will make a configuration request to your server like so:

https://example.com/micropub?q=config

And your server's response should be a JSON-formatted object specifying the "media-endpoint". A bare minimum example:

{
  "media-endpoint": "https://media.example.com/micropub/"
}

In addition to advertising the media-endpoint, your Micropub server must be able to handle lists of URLs in places where it would normally expect a file.

For example, when posting a photo from Quill without a media endpoint, your Micropub server will receive a multipart/form-data encoded file named "photo". When posting from Quill with a media endpoint, your Micropub server will instead receive a list of URLs represented as "photo[]=https://media.example.com/cc/...2cb.jpg". Presumably this pattern would hold for other media types such as video and audio, if you are using Micropub clients that support them.

This particular step has been an interesting challenge for my site, which is a static site generated by Jekyll. My previous Micropub file-handling implementation expected all uploaded assets to live on disk next to the post files, and updating my Jekyll theme and plugins to handle the change is a work in progress. I eventually plan to move all my uploads out of the source for my project in favor of storing them with Spano.

Feedback Welcome!

Spano is probably my second public Python project, so I'd love feedback! If you try it out and run into issues, please drop me a line on GitHub. Or you can find me in the #indieweb chat on freenode IRC.

I'd also like to thank Kyle Mahan for his Woodwind Flask server application, which inspired the structure of Spano.

2011
Sat Feb 5

gml2unicorn - Graffiti Markup Language to Unicorn G-Code

Files

gml2unicorn.py
2237 bytes. Updated
20226.gcode
4189 bytes. Updated
20226.gml
29892 bytes. Updated

This work is licensed BSD License.

Description

When I first heard of Graffiti Markup Language (GML)[1] I was like “An XML format for graffiti? Pfft!” Then yesterday I was like “Wait, I have a pen plotter.”

There are a ton of tags for you to play with at 000000book[2], so go get some files and start tagging … with post-it notes!

Updates

Watch for updates on GitHub:

https://github.com/martymcguire/gml2unicorn

[1] http://graffitimarkuplanguage.com/
[2] http://000000book.com/

Instructions

Installation

To use this script, you’ll need to have Python and the PyGML library installed:

https://bitbucket.org/keegan3d/pygml

Usage

  • Edit the configuration section of gml2unicorn.py to match your Unicorn plotting preferences.
  • Acquire a GML file. 000000book is great for this.
  • python gml2unicorn.py my_graffiti.gml > my_graffiti.gcode
  • Load my_graffiti.gcode in ReplicatorG
  • Build!
Tue Feb 1

Unicorn G-Code Extension for Inkscape

Files

martymcguire-inkscape-unicorn-43629f0.zip
10222 bytes. Updated
inkscape-unicorn.svg
37763 bytes. Updated
inkscape-unicorn.gcode
30111 bytes. Updated

This work is licensed GNU - GPL.

Description

One problem that has often plagued users of the MakerBot Unicorn[1] is the long and confusing chain of tools required to go from a nice vector drawing to a G-Code file that can be plotted from ReplicatorG.

mifga did an awesome tutorial[2] that made it possible to understand the steps needed to work all of these tools, but it was obvious that something better was needed.

So, I made a mashup of scribbles.py[3] and the Egg-Bot Driver for Inkscape[4] to bring you the inkscape-unicorn extension for Inkscape!

Once installed, this extension allows you to save files in “MakerBot Unicorn G-Code (*.gcode)” format!

Learn more, download, and contribute at the GitHub page for this project:

https://github.com/martymcguire/inkscape-unicorn

If you’re desperate, you can also download the zip file attached to this thing, but it is guaranteed to be out of date. Please get the latest version from GitHub. :)

Thanks to langfordw for the original Unicorn Logo[5] used as an example on this Thing.

UPDATES!

I’m updating and adding features to this script as my first days for the February Thing-A-Day. Updates below:

[1] Unicorn - http://store.makerbot.com/makerbot-unicorn-pen-plotter-kit.html
[2] mifga’s Unicorn Tutorial - http://wiki.makerbot.com/unicorn-tutorial-01
[3] scribbles.py - https://github.com/makerbot/Makerbot/tree/master/Unicorn/Scribbles%20Scripts
[4] Egg-Bot Driver for Inkscape - http://code.google.com/p/eggbotcode/
[5] Unicorn Logo by langfordw http://www.thingiverse.com/thing:4197

Instructions

From the README:

Install

Copy the contents of src/ to your Inkscape extensions/ folder.

Typical locations include:

  • OS X - /Applications/Inkscape.app/Contents/Resources/extensions
  • Linux - /usr/share/inkscape/extensions
  • Windows - C:\Program Files\Inkscape\share\extensions

Usage

  • Size and locate your image appropriately:
    • The CupCake CNC build platform size is 100mm x 100mm.
    • Setting units to mm in Inkscape makes it easy to size your drawing.
    • The extension will automatically attempt to center everything.
  • Convert all text to paths:
    • Select all text objects.
    • Choose Path | Object to Path.
  • Save as G-Code:
    • File | Save a Copy.
    • Select MakerBot Unicorn G-Code (*.gcode).
    • Save your file.
  • Preview
    • For OS X, Pleasant3D is great for this.
    • For other operating systems… I don’t know!
  • Print!
    • Open your .gcode file in ReplicatorG
    • Set up your Unicorn and pen.
    • Center your build platform.
    • Click the Build button!
Sun Jan 9

Sticky Notes - Unicorn Banner Plotting

Files

sticky_notes.py
4225 bytes. Updated
sticky_notes.gcode
134830 bytes. Updated

This work is licensed Creative Commons - Attribution.

Description

Decorations in a pinch!

Note: This script is designed to work with the MakerBot Unicorn Pen Plotter: http://store.makerbot.com/makerbot-unicorn-pen-plotter-kit.html

This Python script takes your message and turns it into G-Code which prints one character on each page of a pad of sticky notes. It makes use of mifga’s tricks for pen registration and page-changing.

There are configuration options at the top of the file, so tweak them to make things work best for your bot and your needs.

This is a work in progress. Fork it and make improvements on GitHub! https://gist.github.com/771967

Ideas for improvements:

  • Fills and/or cross-hatching
  • Deploy this as a web service
  • Clean up the code :)

Instructions

Generating a Banner

You’ll need Python and Pycairo and its dependencies: http://cairographics.org/pycairo/

On Ubuntu, this is as easy as:

sudo apt-get install python-cairo-dev

You can then run the script with:

python sticky_notes.py 'Your Message Here' > out.gcode

Printing Your Banner

  1. Attach a pad of sticky notes to your build platform. Scotch tape is good.
  2. Center the build platform at 0,0, so the pen is over the center of the pad.
  3. Open your G-Code file in ReplicatorG and click “Build”.
  4. Watch the pen as it does its registration test and make sure it touches the center of the pad.
  5. If the pen is too low or too high, or the pad is not centered, now is the time to fix it by hand. Feel free to click “No” and restart the build to redo the registration test.
  6. If the pen is in place, click “Yes” and watch your first letter appear!
  7. When the letter is finished, you will be prompted about retrieving the print.
  8. Remove the build platform and take off the top sticky note.
  9. Replace the build platform and click “Yes”
  10. Repeat steps 4-8 until your message is complete!
2009
Fri Feb 20

Face Detection in Static Images with Python

One of the things I’ve been longing to do with my mobile photo-sharing site Camura is to offer image annotations, like objects and faces.  Over the last couple of years I have been increasingly frustrated by the appearance of face tagging on services like Facebook, and the recent addition of face recognition to iPhoto has brought this frustration to the surface once again.  I don’t even want to do something as complex as face recognition - I just want to find faces in an image.

Googling for things like “open source face detector” doesn’t come up with much.  The landscape seems to be comprised of mostly expensive for-pay libraries written for Windows, abandoned research projects, and lots of research papers full of equations – but no code that I could get to run.

To make a long post short, it turns out that Intel’s OpenCV computer vision library comes with a face detector example that should work out of the box.  Better yet, there are now some decent Python bindings for OpenCV that come pre-packaged with OpenCV for Ubuntu and Debian.  You can install them with: $ sudo apt-get install python-opencv

Now, it seems that most OpenCV face detector examples are meant to be run “live”, usually taking the image from a webcam and highlighting faces with a red box in real-time.  However, I have a large database of static images that I want to consider individually, and I simply want to save the face coordinates for later use, rather than altering the picture.

So, with a bit more Googling, I found a Python script that I could chop up and use for this purpose, and here is what I came up with:

An example run of the script looks something like this:

$ python face_detect.py marty_mcguire.jpg
[(50,36) -> (115,101)]

You can overlay that rectangle on an output image with ImageMagick’s “convert”:

$ convert marty_mcguire.jpg -stroke red -fill none -draw "rectangle 50,36 115,101" output.jpg

And the output might look something like this:

My face, it has been detected.

Pretty fun stuff!