• pudquick51


    <u><b>Commands and features:</b></u><ul>
    <li>cd - change directory</li>
    <li>pwd - print current working directory</li>
    <li>ls - list directory contents (and file sizes)</li>
    <li>cat - print the contents of a file</li>
    <li>q/quit/exit/logoff/logout - exit the shell</li>
    <li>mkdir - make a directory</li>
    <li>mv - move or rename files / directories</li>
    <li>cp - copy files / directories (recursively)</li>
    <li>rm - delete files / directories (recursively)</li>
    <li><b>unzip</b> - unzip zip archives</li>
    <li><b>untar</b> - untar tar archives</li>
    <li><b>ungzip / gunzip</b> - ungzip gzipped files</li>
    <li>Supports <b>wildcard matches</b> (matching any number of characters)</li>
    <li>Supports <b>? / question mark matches</b> (matching exactly one of any character)</li>
    <li>Supports <b>[ranges]</b> (like [a-z], [0-9], [a-f0-9], etc.)</li>
    <li>Supports <b>~ / tilde replacement</b> (defaults to Documents folder)</li>
    <li>Supports <b>environment variables</b> ($HOME, but you can expand it)</li>
    <li>Supports <b>single quote escaping</b> (special characters are disabled)</li>
    <li>Supports <b>backslash escaping</b> (for individual special characters)</li>
    <li>Supports <b>double quotes</b> (for preserving spaces, but allowing special sequences)</li></ul>

    <u>Examples of advanced usage:</u>
    <b>ls .py /.py</b> (lists all .py files in current directory and at the top level of any folders in current directory)
    <b>cp ~/
    .py backup</b> (copies all python scripts in the root scripts directory to a folder named 'backup')
    <b>rm test[1-3]?.txt</b> (removes files test1a.txt, test2a.txt, test2b.txt, test2c.txt, test3-.txt, etc.)

    This is an intial (rough) port of a script I put together for another python interpreter on the app store. I'll be porting the rest of the commands soon: unzip, ungzip, untar, wget/curl (basic download functionality)

    Enjoy :)

    <b>For the interested programmer:</b>

    This script uses a pure python re-implementation of some of the more basic globbing of "bash" which I wrote up myself. It's a little different than shlex, glob, or shlex+glob in that matching happens in a single parsing run through. It depends on glob for wildcard handling, but only after my code has already handled all character escapes and word parsing.

    <u>An example where shlex/glob fails:</u>

    In the current working directory are three files: 'test apple', 'peach', 'test a*' (with an asterisk as part of the name)

    The command to parse is the string: rm 'test a*' peach

    shlex interprets it as ['rm', 'test a*', 'peach'], which glob then interprets the file portion as a match of three files: ['test apple', 'test a*', 'peach']. shlex unfortunately clobbers quotes that in a bash environment specify that the special character should be treated as a literal. This would result in deletion of <b>all 3 files</b>.

    With my parser, the single quotes around 'test a*' are interpreted bash-style to mean escaping of the special character '' - disabling it as a wildcard match and turning it into a literal match, resulting in the deletion of only two files: 'test a' and 'peach'.

    posted in Pythonista read more
  • pudquick51


    This is a quick-n-dirty port of code I had running in another python interpreter on the App Store.

    Example usage from the console is as follows:

    <pre>>>> import pipista

    [{'_pypi_ordering': 156, 'version': '2.6.0', 'name': 'boto', 'summary': 'Amazon Web Services Library'}, {'_pypi_ordering': 19, 'version': '0.3', 'name': 'boto_utils', 'summary': 'Command-line tools based on Boto'}, {'_pypi_ordering': 18, 'version': '0.2', 'name': 'boto_utils', 'summary': 'Command-line tools based on Boto'}, {'_pypi_ordering': 17, 'version': '0.8.1', 'name': 'boto_rsync', 'summary': "An rsync-like wrapper for boto's S3 and Google Storage interfaces."}, {'_pypi_ordering': 17, 'version': '0.1.7', 'name': 'boto_utils', 'summary': 'Command-line tools based on Boto'}]

    ['2.6.0', '2.5.2', '2.5.1', '2.5.0', '2.4.1', '2.4.0', '2.3.0', '2.2.2', '2.2.1', '2.2.0']


    • Downloading: http://pypi.python.org/packages/source/b/boto/boto-2.6.0.tar.gz
      Downloaded 32768 of 640220 bytes (5.12%)
      Downloaded 65536 of 640220 bytes (10.24%)
      Downloaded 98304 of 640220 bytes (15.35%)
      Downloaded 131072 of 640220 bytes (20.47%)
      Downloaded 163840 of 640220 bytes (25.59%)
      Downloaded 196608 of 640220 bytes (30.71%)
      Downloaded 229376 of 640220 bytes (35.83%)
      Downloaded 262144 of 640220 bytes (40.95%)
      Downloaded 294912 of 640220 bytes (46.06%)
      Downloaded 327680 of 640220 bytes (51.18%)
      Downloaded 360448 of 640220 bytes (56.30%)
      Downloaded 393216 of 640220 bytes (61.42%)
      Downloaded 425984 of 640220 bytes (66.54%)
      Downloaded 458752 of 640220 bytes (71.66%)
      Downloaded 491520 of 640220 bytes (76.77%)
      Downloaded 524288 of 640220 bytes (81.89%)
      Downloaded 557056 of 640220 bytes (87.01%)
      Downloaded 589824 of 640220 bytes (92.13%)
      Downloaded 622592 of 640220 bytes (97.25%)
      Downloaded 640220 of 640220 bytes (100.00%)

    • Saved to: boto-2.6.0.tar.gz

    <u>What works:</u>
    <li>Searching for modules</li>
    <li>Finding module versions</li>
    <li>Limiting search results</li>
    <li>Downloading modules (that have source versions available, not just eggs)</li>
    <li>Can also download a specific module version (if public)</li>
    <li>Can also suppress download print(..) messages (on by default)</li>
    <li>Creation of a new sub-directory 'pypi-modules' for storage, added to import paths</li>

    <u>What doesn't yet work:</u>
    <li>Unzip / ungzip / untar of the modules</li>
    <li>Moving them into the correct place</li>

    The first bit (decompression) is easy - it's just late and I need some sleep.

    I'm using the simple Shell gist that was pasted in here elsewhere for the time being, but I'm also in the process of porting over my personal bash-alike module which includes things like: unzip, untar, wget, environment variables, tilde/home directory, single vs. double-quote escaping, glob patterns using *[]? characters, etc.

    .. The second bit is the hard bit - there's no rhyme or reason to how a particular package unpacks and installs itself. You just have to hope for the sane ones. We can't really run the included "setup.py install" scripts because they'll fall on their face in iOS. The best I'll be able to do is attempt some basic smarts - and otherwise warn the user they'll have to work with the downloaded results manually.

    Maybe I can include a list of cheats for unpacking popular modules to assist with it.

    Anyways, enjoy :)

    (If you want to find me during a weekday, I'm usually on IRC as frogor@Freenode on #macosx and ##osx-server)

    posted in Pythonista read more
  • pudquick51

    <b>Disclaimer:</b> This works in combination with a (free) third-party App Store app.

    The code is here:


    Using the gist downloader or manually saving it into Pythonista, it should be named 'YoutubeDL' when looking at your list of scripts in the Pythonista interface.

    In the comments, you'll notice a bookmarklet:


    In Mobile Safari, create a Bookmark for any page and name it something meaningful to you (mine is named: "--- m.Youtube DL"). Then go into Bookmark Edit mode and change the URL to the javascript listed above.

    The app that this script works in combination with is called 'iDownloads PLUS - Download Manager!', free, from Amad Marwat, in the iOS app store.

    <b>How to use the script:</b>

    Browse to http://m.youtube.com in Mobile Safari, view a video that you like (press Stop if it starts playing, you need to be looking at the page - not the video actually playing), then click on "Bookmarks" and select the bookmarklet that you created.

    This will launch my script, which will pull the URL of the page you were looking at as an argument, parse it, figure out the direct download URL for the .mp4 video file, then open iDownloads directly to that URL to start downloading it.

    I picked iDownloads because it's free, can download in the background (up to 10 minutes, with notifications when complete), can download multiple files, can play the .mp4 files directly, has HTTP sharing and iTunes documents capabilities (for getting the video to a computer), can save .mp4 files to your Photo roll, and also has 'Open In...' capabilities to move them to another app.

    When the download opens in iDownloads, it'll prompt with a few options - I usually choose 'Download As' and then give it a whatever.mp4 video file name.

    There's some tweaks, if you look at the source code of the script, where you can change what your preferred default download type / quality is (flv, mp4, webm, 720p, 480p, etc.).

    <b>Why I wrote this:</b>

    Apple has continued to crack down on App Store authors that make video download utilities and disallow submission / updates for apps that provide the ability to download content from YouTube and save it to your device. Every app that ever offered this feature (free or paid for) has always eventually removed it claiming 'compliance with YouTube Terms of Service', but it's always been Apple twisting the wrist.

    With this bit of code, in theory you could use any app in the App Store as long as it provided a custom URL opener (in this case 'iDownloads://') and took web URLs and offered to download them if they were not web pages. This script should be 'future proof' against Apple :)

    I use it in combination with a few other tools that I have so that, without accessing a computer, in my house I can download a YouTube video and then save it to a Samba / SMB file share on the network - making it instantly available to my TVs (WiiMC and XBMC on an AppleTV). Makes it a breeze to download stuff for my 3 year old without having to find the laptop.

    posted in Pythonista read more
  • pudquick51

    (earlier discussion about / source version for pipista can be found <a href="http://omz-software.com/pythonista/forums/discussion/59/pip-alike-039pipista039-download-python-modules-from-pypi">here</a>)

    I've run into some bugs in Pythonista that I'm currently working on workarounds.

    Here's the current (very alpha) version of pipista - with module installation support:


    You can install it and use it fine, as is, for the things that 1.0 did.

    However, here's a list of a few bugs I've run into that it <b>successfully</b> patches:<ul>
    <li><b>xmlrpclib is missing</b> from Pythonista (known issue)</li>
    <li><b>ConfigParser is missing</b> from Pythonista (new issue, to the best of my knowledge)</li>
    <li><b>distutils.util.get_platform( ) is broken</b> in Pythonista. This is a new issue. My code temporarily patches it to sys.platform (the default value) to avoid it attempting to look up Makefiles and other build configuration headers which Pythonista doesn't have in place (lib/config/Makefile) even though it claims to be a 'posix' build. I can't permanently patch this one since it's baked into Pythonista.app itself.</li></ul>

    <b>Side bug:</b> Running 'locals()' in the interpreter in Console view results in errors trying to generate repr strings for some of Pythonista's custom objects. You can still do locals().keys() and get to the objects in there, it might just break some things ... (see below)

    <b>New features:</b>
    Added the ability when using the pypi_install( ... ) method to automatically handle zip, .tgz, .tar.gz, and .tar files, decompress them in a temporary location, and locate the setup.py file necessary to configure the module installation.

    <b>In progress:</b>
    The current really big bug I'm trying to squash is that the exec statement, when used by distutils.core, seems to be doing something odd:

    <pre>exec open(script_name, 'r').read() in g, l</pre>

    This is supposed to execute the 'setup.py' python script in a separate global and local environment from the existing parent one - storing newly created global variables in 'g' and newly created local variables in 'l'.

    However, any 'setup.py' script that gets run through there by disutils.core.run_setup( ) invariably breaks the first time it imports something and tries to reference it. Two good examples are the setup.py from 'versiontools' and from 'greenlet' (both are just test modules, not expecting them to function correctly when installed in Pythonista - well, not greenlet anyways).

    'versiontools' throws:
    <pre>>>> import pipista


    • Downloading: http://pypi.python.org/packages/source/v/versiontools/versiontools-1.9.1.tar.gz
      Downloaded 19089 of 19089 bytes (100.00%)

    • Saved to: versiontools-1.9.1.tar.gz

    • setup.py found here: /private/var/mobile/Applications/25CC0752-0E40-4CD9-8C41-B059EC92A3C5/Documents/pypi-modules/.tmp/unpack/versiontools-1.9.1

    • Compiling pure python modules ...
      Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/var/mobile/Applications/25CC0752-0E40-4CD9-8C41-B059EC92A3C5/Documents/pipista.py", line 492, in pypi_install
      result = _py_build(setup_dir)
      File "/var/mobile/Applications/25CC0752-0E40-4CD9-8C41-B059EC92A3C5/Documents/pipista.py", line 445, in _py_build
      result = distutils.core.run_setup('setup.py', ['build_py', '--force'])
      File "/var/mobile/Applications/25CC0752-0E40-4CD9-8C41-B059EC92A3C5/Pythonista.app/pylib/distutils/core.py", line 219, in run_setup
      exec open(script_name, 'r').read() in g, l
      File "<string>", line 22, in <module>
      ImportError: No module named versiontools.versiontools_support</pre>

    'greenlet' throws a similar complaint about 'no module named glob'

    If you download and look at the source of each of these modules, the setup.py files in these instances are just running simple imports (and in the case of greenlet, it's attempting to import glob - a module that's standard in python) and then attempting to access the imported modules. Something <b>weird</b> is happening to exec where it's shoving these modules somewhere unexpected, but I'll keep working on it.

    ... And it's not just a simple bug, either, mind you - running this in console manually works as expected:
    <pre>g, l = {}, {}
    exec 'import glob\ntest_var = glob.name' in g, l</pre>

    Something about the interaction between Pythonista and the distutils it comes with is causing this issue.

    (<b>Note</b>: The pipista script works great on other versions of python and will happily download and install the pure python portion of PyPI modules. It's just these Pythonista idiosyncrasies I've got to iron out and then we'll be all set.)

    Just thought I'd fill everyone in on the details in the meantime.

    posted in Pythonista read more
  • pudquick51

    Yup, decided to do another one - mostly because it was interesting and this one <b>definitely</b> wasn't going to be available in app form.

    As before with my other downloader, this particular script relies on the free 'iDownloads PLUS - Download Manager!' app in the app store (though it can be retooled to use other downloaders, provided they have a custom URL for launching the download URL in the app). I just happen to like this one because it's free and offers background downloads and 'Open In' functionality to move files afterwards.


    Usage is with the bookmark listed at the bottom of the gist.

    Visit a page in Safari on Soundcloud (m.soundcloud.com) on your iOS device, find one with a song you like, then click on the bookmark to trigger a download of the .mp3 (even if the page does not offer a direct download link itself).

    Unfortunately the limitations of iOS make it so that .mp3 files you download can't be added to your device's music library programmatically. You'll have to save the .mp3 file from your device to iTunes and then sync it back to your device (or have a separate music player app, of which there are many, that you can 'Open In' the .mp3 file). In the meantime, iDownloads also offers a built-in media player so you can get to the listening :)

    <strike>There's an issue at the moment where the script takes a long delay in attempting to get a client id for the download. I'm not quite sure why it's doing that. When I was testing the script on my MBP, I didn't experience delays even remotely similar. I'll work on that more later when I get a chance and hopefully eliminate the delay.</strike>

    posted in Pythonista read more
  • pudquick51

    <b>Disclaimer:</b> This works in combination with a (free) third-party App Store app.

    The app that this script works in combination with is called 'iDownloads PLUS - Download Manager!', free, from Amad Marwat, in the iOS app store. I am not affiliated with him, it's just free and very useful (can download in the background with notifications when complete, can download multiple files, can play .mp3 files directly, has HTTP sharing and iTunes documents capabilities for transfer to a computer, and also has 'Open in ...' capabilities to move them to another app). Unfortunately for this script, Mobile Safari cannot directly be used as it lacks an 'Open in ...' capability to move .mp3 files to other apps.

    <b>This script is a Grooveshark search + download tool.</b> It allows you to enter what you're looking for, gives you the top 8 results, then helps you download the .mp3.


    Unlike other attempts at third-party Grooveshark libraries, I've attempted to do several things to help keep this client from being banned:
    <ul><li>Download files likely to be downloaded by a real browser.</li>
    <li>Mask the User-Agent of the browser.</li>
    <li>Retain cookies handed out by the site.</li>
    <li>Use the HTML5 version of the site so I can avoid needing to parse the Flash player.</li>
    <li>Dynamically pull special values instead of hardcoding them.</li>
    <li>Enforce the 30 second timer that fires when you've listened to an entire song.</li></ul>
    All of these things should help to make sure that you don't get banned. Note: If you do get banned (downloading too many songs too quickly), the ban should lift in 10 minutes or so - try again later. <b>I have no clue if this script will work outside of the US.</b> They're very geographically picky about who can use their site.

    <b>How it works when you run it:</b>
    <ol><li>The script will attempt to import requests module version 1.2. If it's not found, it will automatically download it and install it as requests_1_2.</li>
    <li>Once loaded, it will present a menu. Right now there is just a single choice '1) Search and download' (I'll add some more later). Enter 1, then enter your search term (like the name of a song).
    <img src="http://i.imgur.com/I534tz2.png"></li>
    <li>It will lookup your entry and provide the top hits (up to 8) for a match. Enter the number of the match you want to download.
    <img src="http://i.imgur.com/prS8pXk.png"></li>
    <li>The download will then start, with progress indicators. As noted, the download will take a minimum of 30 seconds to help ensure you're not banned.
    <img src="http://i.imgur.com/G1xFbf0.png"></li>
    <li>When complete, iDownloads+ will automatically launch (make sure you have it installed). <b>You can just hit the 'Download'</b> button as I've configured the script to attempt to offer a decent name for the .mp3. When the transfer is complete (it will be quick), you can go back to the script. It will automatically clean up and offer to run again.
    <img src="http://i.imgur.com/nIzgs3F.png"></li>
    <li>Entering 0 or nothing for an entry will cause it to quit.</li></ol>
    (<a href="http://imgur.com/a/7nJwL">album with images here</a>)

    As noted before in my Soundcloud downloader, the limitations of iOS make it so that .mp3 files you download can't be added to your device's music library programmatically. You'll have to save the .mp3 file from your device to iTunes and then sync it back to your device (or have a separate music player app, of which there are many, that you can 'Open in ...' the .mp3 file). In the meantime, iDownloads+ also offers a built-in media player so you can get to the listening :)

    As always, hope you guys enjoy! ☺

    I've already got the mechanics figured out for downloading playlists, just wanted to get the initial version published and out there for others to try.

    posted in Pythonista read more
  • pudquick51

    @gdcs - Unfortunately, the python Oracle client cx_Oracle includes libraries as it's closed source. Python modules that load external libraries aren't allowed in iOS - they'd have to be compiled into Pythonista as a static whole (which isn't possible for Oracle's client as they don't provide the source). There's no pure python client for Oracle and likely never will be. Even wonderful third-party toolsets like SQLalchemy still rely on cx_Oracle underneath to do the actual communication to the Oracle database servers.

    TL;DR: Nope.

    posted in Pythonista read more
  • pudquick51

    @omz - I've used the http server + app method for a couple of my scripts in here (Mega client, for one). This script contains a variant of SimpleHTTPServer I've been developing that has sane timeouts, limited number of responses, etc. (instead of .serve_forever). Side request: please include a newer requests module in the next release - it's gone through some major changes that are useful.

    @eliskan - Well, I've done Youtube, Soundcloud, Mega, and Grooveshark. They've all been fun. Got another suggestion?

    posted in Pythonista read more
  • pudquick51

    Side note: .mp3 files are stored temporarily in the gs_dl folder that it creates.

    If something goes wrong with the script, you can delete the folder in the Pythonista interface and it'll clear out everything that's in there (whether it's shown or not).

    posted in Pythonista read more
  • pudquick51

    My pipista script makes use of the built-in xmlrpclib to query PyPi for packages:


    If you're working with WSDL/SOAP specifically, though, suds is definitely the way to go.

    posted in Pythonista read more

Internal error.

Oops! Looks like something went wrong!