Tagged: python Toggle Comment Threads | Keyboard Shortcuts

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

    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:32 pm on August 8, 2013 Permalink | Reply
    Tags: python   

    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 7:27 pm on December 10, 2012 Permalink | Reply
    Tags: python, virtualenv   

    A tiny virtualenv wrapper 

    Tymm shared his bash function for assisting with virtualenvs. I’ve been using it instead of virtualenvwrapper. Typing `pye` will list your virtualenvs, and typing `pye envname` will activate one of them:

    # Enable a python virtualenv
    function pye() { 
       if [[ -z "${1}" ]]; then
           echo -e "\x1b[01;34mAvailable virtualenvs:\x1b[00m"
           (cd ~/pyenvs && for i in *; do echo -e "\x1b[01;36m ${i} \x1b[00m"; done)
       else
           . ~/pyenvs/"${1}"/bin/activate; 
       fi
    }
     
  • raj 12:01 am on July 19, 2012 Permalink | Reply
    Tags: lxml, python, unicode   

    Parsing UTF-8 webpages with lxml 

    Here is how to use python and lxml to parse web pages with unicode characters, encoded as utf-8. It would be nice if lxml.html.parse(url) could correctly use the Content-Type HTTP header, but it doesn’t, so you have to tell lxml what encoding to use.

    >>> import lxml.etree
    >>> url = 'http://hi.wikipedia.org/wiki/मुखपृष्ठ' #utf-8 encoded bytes
    >>> url
    'http://hi.wikipedia.org/wiki/\xe0\xa4\xae\xe0\xa5\x81\xe0\xa4\x96\xe0\xa4\xaa\xe0\xa5\x83\xe0\xa4\xb7\xe0\xa5\x8d\xe0\xa4\xa0'
     
    >>> utf8_html_parser = lxml.etree.HTMLParser(encoding='utf-8')
    >>> page = lxml.etree.parse(url, parser=utf8_html_parser)
     
    >>> print page.find('head/title').text
    विकिपीडिया
    >>> page.find('head/title').text
    u'\u0935\u093f\u0915\u093f\u092a\u0940\u0921\u093f\u092f\u093e'
     
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