Recent Updates Toggle Comment Threads | Keyboard Shortcuts

  • raj 7:23 pm on March 5, 2014 Permalink | Reply
    Tags: PyInstaller, PyQt,   

    Loading DLLs from a PyInstaller-packaged PyQt standalone application 

    I wanted to package a PyQt script as a standalone Windows .exe using PyInstaller, and I wanted the app to display a jpeg.

    It turned out that displaying a PNG was fine, but displaying a JPEG took a while to get working. PyQt uses a dll called `qjpeg4.dll` for decoding the jpeg, and PyInstaller doesn’t automatically bundle it into the package, so we have to tell PyInstaller to do so.

    There is still one problem though: when you run the .exe, where does PyQt try to load `qjpeg4.dll` from? It turns out that *it depends*..

    If you use the `–onedir` option for PyInstaller, the `imageformats/qjpeg4.dll` just needs to be in a directory called `imageformats`. No problem.

    If you use the `–onefile` option, PyInstaller unzips the binaries into a temp directory, and loads dlls from there. But for some reason, in the `–onefile` case, PyQt tries to load the dll from `qt4_plugins/imageformats/qjpeg4.dll`.

    I used SysInternals Process Monitor to figure this out…

    To make things easy, I just added an `imageformats` directory to my repo, and checked in the qjpeg4.dll.

    I also wanted to load a dll called `discid.dll`, required by python-discid. I checked into the root level of the repo, but couldn’t get the python package to load the dll properly, until I modified the PATH environment variable:

    #fix for loading discid.dll
    if getattr(sys, 'frozen', None):
         BASE_DIR = sys._MEIPASS
    else:
         BASE_DIR = os.path.dirname(__file__)
    os.environ['PATH'] = BASE_DIR + '\;' + os.environ.get('PATH', '')
    import discid

    My PyInstaller .spec file for the `–onefile` case looks like this:

    # -*- mode: python -*-
    a = Analysis(['wizard.py'],
                 pathex=['y:\\archivecd'],
                 hiddenimports=[],
                 hookspath=None,
                 runtime_hooks=None)
     
    onefile_binaries = a.binaries + [('discid.dll', 'discid.dll', 'BINARY'),
                             ('qt4_plugins/imageformats/qjpeg4.dll', 'imageformats/qjpeg4.dll', 'BINARY'),
                            ]
    pyz = PYZ(a.pure)
    exe = EXE(pyz,
              a.scripts,
              Tree('images', prefix='images'),
              onefile_binaries,
              a.zipfiles,
              a.datas,
              name='wizard.exe',
              debug=False,
              strip=None,
              upx=True,
              console=True )
     
  • raj 11:46 pm on February 12, 2014 Permalink | Reply
    Tags:   

    Thinking about the Wayback Machine 

    wayback boxes and arrows

     
  • raj 11:58 pm on February 7, 2014 Permalink | Reply
    Tags:   

    BookReader usage in 2013 

    We measured whenever someone opened the IA BookReader. Usage more than doubled in 2013, to more than 5 people opening up the BookReader every second!

    bookreader_graphite.us.archive.org

    For 2014, we won’t be able to produce the same data, since we now embed the BookReader on archive.org details pages, and a pageview now registers as a “bookreader open” event, even if the user doesn’t actually read the book.

     
  • raj 7:16 pm on October 31, 2013 Permalink | Reply
    Tags: , wordpress   

    BookReader embeds on wordpress.com 

    Blogs hosted at wordpress.com can now use BookReader embeds!

    http://en.support.wordpress.com/embedding-ebooks/

     
  • raj 6:46 pm on October 14, 2013 Permalink | Reply
    Tags: , iceland   

    Iceland: Where one in 10 people will publish a book – http://www.bbc.co.uk/news/magazine-24399599

     
  • raj 6:24 pm on September 5, 2013 Permalink | Reply
    Tags: dvd,   

    A robot for digitizing DVDs: http://www.britishideas.com/2013/09/03/jack-the-ripper-bot-i-introduction/

     
  • raj 7:51 pm on September 4, 2013 Permalink | Reply
    Tags: cnc,   

    MatrixShotâ„¢ 1.0 First Run

     
  • raj 11:32 pm on August 8, 2013 Permalink | Reply
    Tags:   

    A python interface to archive.org 

    Jake pointed out today that he wrote a cool python wrapper for archive.org that made it easy to upload files. I added downloading support and a few other features:

    #The Internet Archive stores data in "items". You can query the archive using an item identifier:
     
    >>> import archive
    >>> item = archive.Item('stairs')
    >>> print item.metadata
     
    #Items contains files, which can be downloaded:
     
    >>> f = item.file('glogo.png')
    >>> f.download() #writes to disk
    >>> f.download('/foo/bar/some_other_name.png')
     
    #You can iterate over files:
     
    >>> for f in item.files():
    ...     print f.name, f.sha1
     
    #You can use the IA's S3-like interface to upload files to an item.
    #You need to supply your IAS3 credentials in environment variables in order to upload.
    #You can retrieve S3 keys from https://archive.org/account/s3.php
     
    >>> import os;
    >>> os.environ['AWS_ACCESS_KEY_ID']='x'; os.environ['AWS_SECRET_ACCESS_KEY']='y'
    >>> item.upload('myfile')
    True
     
  • raj 6:01 pm on July 17, 2013 Permalink | Reply
    Tags: canon, chdk, magic lantern   

    Magic Lantern is third-party firmware (like CHDK) that works on Canon DSLRs: http://www.magiclantern.fm

     
  • raj 11:44 pm on June 26, 2013 Permalink | Reply
    Tags: , uploader   

    Plotting uploads/day 

    We are beta testing a HTML5 Uploader, and I wanted to see how much use it was getting. Here is how I plotted the usage. First, install ipython html notebook, then install matplotlib 1.3rc2 to use the xkcd style, then start iPython notebook:

    $ source ~/pyenvs/notebook/bin/activate
    $ ipython notebook --profile=nbserver

    Then, in iPython notebook, use the archive.org advanced search engine to see how many uploads per day we were getting:

    import json
    import urllib
    import datetime as dt
    x=[]
    y=[]
    urlbase = 'http://archive.org/advancedsearch.php?%s'
    date = dt.datetime.utcnow()
    for i in range(90):
        date -= dt.timedelta(days=1)
        x.append(date)
        params = {'q':'scanner:"Internet Archive HTML5 Uploader" AND publicdate:'+date.strftime('%Y-%m-%d'),
                  'fl[]':'identifier',
                  'rows':1,
                  'output':'json'
                 }
        url = urlbase % urllib.urlencode(params)
        f = urllib.urlopen(url)
        o = json.load(f)
        y.append(o['response']['numFound'])

    Now that I have the data, I can plot it, using xkcd-style:

    #Turn on XKCD style
    plt.xkcd()
     
    plot(x, y)
    plt.title("HTML Uploader Items/Day")
    plt.xticks(rotation=75)
     
    #Save PNG
    fig = plt.gcf()
    subplots_adjust(bottom=0.3)
    plt.savefig('out.png',dpi=100)

    It looks like this:
    out

     
c
compose new post
j
next post/next comment
k
previous post/previous comment
r
reply
e
edit
o
show/hide comments
t
go to top
l
go to login
h
show/hide help
shift + esc
cancel