Forum Archive

Black Mamba - open quickly and other shortcuts

zrzka

Hi all,

I mainly work with Pythonista on the biggest iPad with external keyboard. And I miss some features like Open quickly, registering shortcuts for my scripts, ... so I decided to add them by myself. Hope it will be natively supported in the future.

Here's screen recording of what I can do with external keyboard only. If you would like to try it, feel free to clone all files from pythonista-site-packages-3 repository to your local site-packages-3 folder. Just download them or use git via StaSH.

Then you can hit ...

  • Cmd / - to toggle comments
  • Cmd N - to open new tab and to show new file dialog
  • Cmd Shift N - to open just new tab
  • Cmd 0 (zero) - to toggle library view (I call it navigator)
  • Cmd W - to close current tab
  • Cmd Shift W - to close all tabs except current one
  • Cmd O (letter o) - to quickly open files

If you need more shortcuts for more actions, just let me know and I'll try to add them.

WARNING It works, but it's experimental, dangerous. There's some swizzling, some direct calls to ObjC instances, passing guessed parameter values, etc. It can crash your Pythonista, you can lost data, ... I warned you :) If you will modify this code and Pythonista will crash during startup, just open pythonista3:// in your browser and fix your changes.

Will write more issues, so, Pythonista modules can be enhanced (like editor module functions to close tab, open file, etc.). Then I can remove some of these crazy calls.

Back to open quickly ... It just supports Python (.py) and Markdown (.md) files. That's because I have no clue yet what should I pass as editor type, when force reload should be used, ... Also some directories are excluded, so, you know why if some files are missing in open quickly dialog. Also the open quickly dialog has hidden title bar -> no close button -> you need to hit Esc (or Ctrl [ on smart keyboard) to close it.

Anyway, it's pretty scary, fascinating, ... that we can do all these things directly on iPad. Many thanks to Ole for this wonderful tool. This tool let me play with Python on iPad and I can drive our AWS services directly from iPad as well. I'm not forced to bring MBP everywhere, iPad is enough :) Thanks again.

Enjoy!

zrzka

Ouch, did forget to commit key_events.py. Fixed, everything's in place. Sorry.

zrzka

I did move these hacks into the blackmamba (Pythonista on steroids) package, so, it will not interfere with another packages you already have in the site-packages-3 folder.

zrzka

I'm dumb :) Did spend lot of time in the runtime searching for correct function to call that I completely missed that editor.open_file already exists. Open Quickly is no longer limited to Python & Markdown files only.

Also I just added Cmd-Shift-0 (zero) to open Dash with a) selected text as a query, b) if there's no selection, cursor position is used to find identifier around it.

omz

@zrzka said:

Also I just added Cmd-Shift-0 (zero) to open Dash with a) selected text as a query, b) if there's no selection, cursor position is used to find identifier around it.

Very nice idea!

Phuket2

@zrzka, thanks. This is looking pretty cool. Is there a strategy that i can clone the repo into the site-package-3 dir. i cloned it then moved it, i was a little unsure of what i was doing. Maybe this cant be done because of site-packages-3 being a special folder. Not sure. But maybe I should just clone the blackmamba dir and deal with the startup seperately. I just want to be able to update as you update by doing a git pull, rather than moving etc...

I have one suggestion, is to do print statements in your startup file. Just a few to say what's going on. I do that for my simple startup for changing the screen brightness, font size, turning off animations etc...Anyway, just a suggestion. I inserted a print line just saying 'doing some blackmamba stuff'.

zrzka

You can clone it directly into the site-packages-3 folder in this way ...

[site-packages-3]$ pwd
~/Documents/site-packages-3
[site-packages-3]$ ls -la
.git (352.0B) 2017-08-12 10:15:40
LICENSE (1.2K) 2017-08-12 10:15:40
Readme.md (2.2K) 2017-08-12 10:15:40
blackmamba (384.0B) 2017-08-12 10:15:40
external_screen.py (5.6K) 2017-08-12 10:15:40
pythonista_startup.py (1.3K) 2017-08-12 10:15:40
[site-packages-3]$ rm -rf .git LICENSE Readme.md blackmamba external_screen.py pythonista_startup.py 
[site-packages-3]$ ls -la

[site-packages-3]$ git clone https://github.com/zrzka/pythonista-site-packages-3.git
[site-packages-3]$ ls -la
.git (352.0B) 2017-08-12 10:16:16
LICENSE (1.2K) 2017-08-12 10:16:15
Readme.md (2.2K) 2017-08-12 10:16:15
blackmamba (384.0B) 2017-08-12 10:16:15
external_screen.py (5.6K) 2017-08-12 10:16:15
pythonista_startup.py (1.3K) 2017-08-12 10:16:16
[site-packages-3]$ 

And then you can update it via git pull ...

[site-packages-3]$ pwd
~/Documents/site-packages-3
[site-packages-3]$ git pull
[site-packages-3]$ 
zrzka

Added some comments as requested and I also created blackmamba.startup file where all the startup things are done. Then I removed pythonista_startup.py from GitHub repo, so, it will not interfere with your pythonista_startup.py file and did add Installation section to the readme. Just copy & paste the lines from this section to your pythonista_startup.py file. This will be stable interface for BM initialization. Also pythonista_startup.py file is ignored by git (.gitignore), feel free to modify it, add your custom routines, git pull will be happy.

Yeah, I know it's akward installation process, but because I still consider it as hack, not going to provide better way to install / update it. And I hope that some of these features will be added to the Pythonista, thus lot of things will be removed, new ones added, ...

Phuket2

@zrzka, sorry. I cant see what I am doing wrong. I have done this a few times so all your cmds are not there. But I think you can see from the printout below, the site-packages-3 dir is empty before I do the clone. Bu you can see I only end up with a single folder in the site-packages-3 dir after the clone.
I cant see what I am doing wrong

[site-packages-3]$ pwd
~/Documents/site-packages-3
[site-packages-3]$ ls -la

[site-packages-3]$ git clone https://github.com/zrzka/pythonista-site-packages-3.git
[site-packages-3]$ ls -la
pythonista-site-packages-3 (256.0B) 2017-08-12 15:39:32
[site-packages-3]$

zrzka

I had probably older StaSH. Did update StaSH and you're right, now git clone behaves correctly. So the clone command is:

  • git clone https://github.com/zrzka/pythonista-site-packages-3.git . (<- space dot at the end)
Phuket2

@zrzka , perfect, works great. Thanks for your help. You might want to make a note in your installation instructions about the trailing period. I can see you changed it, but this would trip up newbies like me.

zrzka

Done :) More updates later, going to take week off :)

Phuket2

@zrzka , ok. Enjoy. Thanks again.

wolf71

cool,perfect,thanks.

and wish @omz next pythonista update can support it native.

Phuket2

@zrzka, hey. I know you are off right now, hope you are having a good break. But when you return could you consider having a (dedicated) key combo (cmd-something) that you can apply to invoke a given wrench menu item. Eg. Maybe the user could pass the name of the wrench item name as a param in the bm.start('StaSh'). I guess it could also be a .py filename. Although that seems a bit more on the wild side. Maybe you have some better ideas than that.
I also mention dedicated, because I think it would get infinitely more complicated to let users to map their own keys.
Anyway thanks again, still only a day or so with what you have done so far and its very useful for me with the Apple iPad Pro keyboard.

zrzka

@Phuket2 thanks for the suggestions.

Open Quickly

I would like to reuse Open Quickly dialog (when I refactor it) for:

  • Run Quickly (search for just .py and run it, basically emulation of open and tapping on play),
  • Wrench Quickly, same idea, but you can search for wrench items.

UI for mapping keys

I'm not going to provide UI for mapping keys, because it's a lot of work, which can be replaced with something more simpler. I can remove HW shortcuts registration from bm.start, can provide something like bm.register_default_key_commands. And if you don't call this function in your pythonista_startup.py file, feel free to map your own shortcuts via bm.register_key_command. Or call it and add your own after bm.start().

Shortcut for the wrench item

Just do this in your pythonista_startup.py file:

#!python3

import blackmamba.startup as bm
import blackmamba.key_commands as bkc
import blackmamba.uikit as bui


def launch_wrench_item(name):
    print('Wrench item: {}'.format(name))


def launch_stash():
    launch_wrench_item('StaSh')


bm.start()

bkc.register_key_command(
    bkc.PYTHONISTA_SCOPE_EDITOR,
    'S',
    bui.UIKeyModifierCommand | bui.UIKeyModifierShift,
    launch_stash,
    'Launch StaSh')

This maps Cmd-Shift-S to launch_stash, where you can do whatever you want :)

zrzka

Some breaking changes pushed. Check Usage section in the readme. Summary:

  • external_screen.py moved to blackmamba/experimental
  • blackmamba/startup.py trashed
  • register_default_key_commands introduced in blackmamba/__init__.py
  • removed scope in blackmamba/key_commands.py
  • usage examples updated
  • repository renamed (pythonista-site-packages-3 -> blackmamba)

If you don't want to check all these changes, just update your pythonista_startup.py content:

#!python3

import blackmamba as bm
bm.register_default_key_commands()
Phuket2

@zrzka , hey thanks. The git pull worked perfectly. Thanks for your help to get it setup correctly. Makes a huge difference being able to do that. I haven't added my own keys yet, but will put some thought into it. I am always running 'Check Style' and 'Reformat Code' these days so I am guessing, i just need to find these scripts and run them from function stubs like you do with the hallo example. Anyway, will give it a go later.
Thanks again. This is really fantastic with an external keyboard. I am sure a lot of other apps would be envious of this ability.

Oppps, sorry, I missed the post above this...Looks like the wrench keys have been handled. That's great. I will try them now!!!!

zrzka

@Phuket2 wrench item(s) are not handled yet. It's just silly example how to print smth with keyboard shortcut. I'll try to add run script / wrench item today. Then you'll be able to use it.

Phuket2

@zrzka , ok. Cool. I had a lame attempt to get it working and started going down a rabbit hole. But for me it will be a big help. Esp the check styles/reformat code. @ccc has beaten me with a big stick so I don't dare to push anything anymore until I have done all the checks :) I find it super annoying and time consuming. But I am happy I am staring to take the time to do things properly. Just a matter of time it will become second nature.
Ok, will keep a look out for the next update :)

zrzka

@Phuket2 I did refactor my picker, thus I was able to add Run Quickly... (Cmd Shift R) and Wrench Quickly... (Cmd Option R). But it does work only and only if scripts are Python 3 compatible. Otherwise you can run them, but they will fail to execute. See another thread for more info. Sorry for this, will try to solve it somehow.

It's useless for StaSh (Python 2) and maybe for many more scripts.

zrzka

@Phuket2 works now, but it's kinda limited. See this commit.

zrzka

Another update ...

  • wrench_picker renamed to action_picker
  • Wrench Quickly... renamed to Action Quickly... with new shortcut Cmd-Shift-A
  • ide.run_action added (see example below)
  • slight Action Quickly... UI improvements
    • title is custom title or just script name without extension if title is not provided
    • subtitle is script path

... and here's an example how to register custom shortcut to launch StaSh for example ...

#!python3

import blackmamba as bm
from blackmamba.key_commands import register_key_command
from blackmamba.uikit import *  # UIKeyModifier*
import blackmamba.ide as ide

bm.register_default_key_commands()


def launch_stash():
    ide.run_action('StaSh')  # <- editor action custom title, case sensitive
    # or ide.run_script('launch_stash.py')


register_key_command('S', UIKeyModifierCommand | UIKeyModifierShift,
                     launch_stash, 'Launch StaSh...')

ide.run_action accepts editor action custom title and it's case sensitive. Another option is to ignore editor actions and use just ide.run_script with script name.

zrzka

Another installation method added (StaSh & Pip). Check readme. This is preferred way to install Black Mamba. The old git way still works and will work.

zrzka

Hmm, StaSh & pip & GitHub doesn't support update. Hmm.

zrzka

Okay, managed to create PyPI package. So, it's installable via:

cd ~/Documents
pip install blackmamba -d site-packages-3

But there's an issue with XML RPC and PyPI, see issue #264. So far, the workaround is to change line number 899 in the site-packages/stash/bin/pip.py file from ...

hits = self.pypi.package_releases(pkg_name, True)  # True to show all versions

... to ...

hits = self.pypi.package_releases(pkg_name, False)

This fixes the pip issue. Or at least, it looks like it does.

Phuket2

I give up smoking last night and changed to vamping instead. Maybe this was not a good week to do that :)

zrzka

For those who are using git, feel free to pull:

Basically did add more complex sample pythonista_startup.py (readme) and ability to set which folders are ignored in Run/Open Quickly... dialogs. Now going to figure out how to publish PyPI package on iPad, left MBP at home for two days :)

zrzka

0.0.11 released (git & pip):

  • two shortcuts modified
  • Ctrl-Shift-B added for clear annotations & pyflakes (Analyze)

Changelog

P.S. Did want to use Cmd-Shift-B (Xcode sync), but it's already used in Pythonista for toggle breakpoint.

WARNING I did release the package via PyPI as well, but StaSh pip doesn't see it. Thinking what should I do with this :)

Phuket2

@zrzka , i am still using git pull. Working great. Ctrl-shift-b working perfectly!
I am going to add an issue to the Pythonista github issues about the hud display delay for 'check style' and 'Analyse'. I feel its twice the time it should be. Depends what @omz thinks. It does not deserve its own param setting in my view (more important things). Can live with what it is now, but seems to me that the hud should be shown for half the time.

zrzka

@Phuket2 This HUD delay you're talking about, do you mean HUD delay when you do use Ctrl Shift B or when you do use Wrench - Analyze / Check Style action item? If you're talking about the first case (via Ctrl Shift B), then the delay is 1.0s. Check analyzer.py, lines 72 & 99. I do not emulate tapping on these items, nor using these action items from my script. I have custom analyzer.py module which uses pyflakes directly. So, it's a completely independent implementation.

Phuket2

@zrzka , yes i agree. It's different. I was talking about when you select from the wrench menu. But i did think it affected your code also, but I can see now it does not. I guess you felt the same, the time was to long.

JonB

re pythonista version check in latest version... I wonder if it would make more sense to check for conflicting shortcuts. Then just enable the ones that are free.

zrzka

@JonB basically I see two issues here:

Pythonista version

This check is here, because:

  • Pythonista UI can be changed (-> associated function will not work in case that the function emulates UI touching)
  • What if dependent module will be removed?
  • What if behaviour of some modules will be modified?
  • Can imagine many more worse scenarios than these two.

It's just safety measure, nothing more. Will not happen probably, but who knows. I can change it in this way:

  • Write red warning to the console
  • Continue, but warn user that it's a risk and can lead to data loss (Pythonista crash, ...)

Keyboard shortcuts

I see this as another issue. What I can do in the keyCommands:

  • If there's Pythonista key command with the same shortcut, disable Black Mamba key command and write a warning to the console.
  • Or add a settings to change this behavior (which one has higher priority).
  • Or add a way how to modify default Black Mamba keyboard shortcuts.

Low hanging fruit is the first one for now.

zrzka

@JonB first issue (Pythonista version) fixed in the master (not released yet). Second one (shortcuts) is in the category no need to do anything. I just tested it ...

keyCommands method is called zillion times and it must be blazingly fast. So, I'm just concatenating two lists. Just tried to filter BM key commands there and experienced significant slow down of Pythonista. Almost unusable even on the latest and biggest iPad available. No way to do it here. Slow down wasn't here just because of filtering only, but some print statements, ... -> no way.

Issue is that I have no idea what key commands Pythonista provides, because original keyCommands does return different set of shortcuts. Depends on where I am (what's open in Pythonista). I can't filter out key commands in advance -> no way.

Anyway, I just tried to assign same shortcut for one of my commands to test what will happen. Found that the first command in the array is used by the iOS - HUD, functionality, ... In other words, when Black Mamba registers command with some shortcut which is already provided by the Pythonista, Pythonista one will be used automatically, because I'm concatenating Black Mamba key commands at the end of the key commands list.

JonB

@zrzka Seems like it should be possible to call keyCommands in advance (at startup), for a few of the main viewControllers, to see what is provided. IIRCthe little keycommand swizzle technique we have been using swizzles the root view controller, so it is last in line. It would technically be possible to swizzle down at a particular view controller, say, to have commands in the editor, and different commands in the console.
But, point taken, that if ole changes the structure of the app, then things break if you are trying to be too clever.

zrzka

@JonB that's what I initially did want to achieve with scope (removed) - to have different set of shortcuts for the editor, console, ... I will eventually put it back, because we have lot of commands now and I'm accidentally closing editor files when I hit Cmd W in the console for example :)

Phuket2

@zrzka, I am not sure if you use the ui Designer or not. But a great addition would be if you were able to inc/decrement the x,y position fields and the width, height fields with the arrow keys or shifted combo of these keys. (I guess the trick, maybe doing that without changing the focus).
This could give keyboard positioning and sizing of objects in the ui Designer. Another nice addition would be a object cycling selection key like tab for example.
Sometimes i can be quite hard to select an object without resizing or moving it.

Look I understand this may be way outside the scope of what you want to do. And it may not even be possible. But thought it was worth a mention. Never know unless you ask

zrzka

@Phuket2 thanks for the suggestion. I was thinking about this as well and decided not to do it. Not that it's not possible, but it will use lot of Pythonista internals and even a minimal change from Ole can break it. Thus it will lead to maintenance hell.

Yes, I do use it and to be honest, it's a tough job sometimes. I'm talking about complicated UI. If it's simple, designer works perfectly. Agree it would be super useful to use [Shift] Tab for cycling and arrow keys for x, y and shift arrow keys for width, height. Also backspace to delete selected item.

Anyway, you should fill issues for all these ideas, so, that @omz will not miss them and they'll be eventually implemented.

Phuket2

@zrzka , thanks for the answer. I have posted these as issues on github recently. But i understand, for sure this better implemented by @omz. Not that i could do it myself, but I can imagine it could be quite brittle. I think @omz will address it. I am sure It's just about priorities.
Again thanks for getting back to me

Phuket2

@zrzka, this maybe a crap suggestion but i am going to suggest it anyway :) What about a dedicated key combo for BM version check with an option to run the requests update script. It seems to make sense to me at least for now giving you are updating regularly. At first I was thinking about something in the startup script. I would not have a problem with that, but I think maybe others would. Anyway, food for thought.

Btw, i changed to using the requests install script. It did fix some problems i was having using the git pull. Same version. So seems to me that the git pull idea is dead.

zrzka

@Phuket2 I decided to fix pip (here's the pull request) instead of reinventing wheel with installer, updater, ... So, when the PR will be merged and it will be available in the next StaSh version, I'll switch the installation method back to pip and will trash the current installer.

Then I'll update check for updates method to check against PyPI. If there will be new version available, I'll copy pip update blackmamba to the clipboard and will inform you about this in an alert. So, decided to fix the root cause (pip), not the workarounds :)

Phuket2

@zrzka , sounds good. I didn't really know about the pip update problem until recently. It's great its getting fixed. Being a novice, I thought I was doing something wrong. Appears to do the remove ok, just not the new install :)
I often run selfupdate in StaSh, so should see when it comes through

zrzka

@Phuket2 pip was broken in several ways ...

  • Uses XML-RPC which is legacy API and it causes issue that newly released versions are not returned, you have to wait more than 24h and sometimes even longer.
  • pip update internally calls install, but ...
    • invalid version specifier arguments passed -> exception
    • pip install command is wrapped with fake setuptools modules, ... but update isn't and because update calls install, it doesn't work

... fixed these things, tested and it works for me. Hope someone will find time to review, merge and release it.

zrzka

@Phuket2 pip fixes were merged to dev. If you'd like to test it, you can use StaSh dev branch ...

selfupdate -f dev

... then restart Pythonista (to reload StaSh), then ...

rm -rf ~/Documents/site-packages-3/blackmamba
pip install blackmamba -d ~/Documents/site-packages-3

... restart Pythonista (to reload Black Mamba).

And now, whenever you see new new post in Black Mamba - releases topic, you can update Black Mamba via ...

pip update blackmamba

... that's it. If pip will be stable enough, will work as expected, will be merged to master, I'll switch Black Mamba to pip only. Now I'm releasing it to PyPI as well to test pip changes.

Phuket2

@zrzka, I had some ideas about BlackMamba today. I cant keep up with all the thread items so this may have been discussed or somewhere in your vision.

I noted the other day you mentioned about your vision for BM being more than just a KeyMapper, or words to that effect. You can see that by the helpers you also include I.e ''open quickly".

I was thinking today, what If I wrote a calendar app (for example). Let's say I also wanted to support a set of keyboard shortcuts, like 'go to today, 'go to next/previous month' etc. You get my drift. Seems like it would be great if somewhere in my app startup code I could import bm, start it. Then when loading a view to be able to make the calls I need to do the keymapping (preferably some container that could be passed as a set of mappings). Then when view is closed make the required calls to unregister the mapping set. Possiblly a global set could be created/registered on the app startup, and the contextual views done as said above.
Of course all the key mappings need to be backed up with ui Equivalents. You could leave this to the developer to figure out, or have a few helper Libs to create for example a popover view , that links into the registering of the keymappings.

Another bonus would be that any keymappings that get registered during the apps lifecycle are automatically unregistered when the app terminates. Just to save ourselves from ourselves :)

It would be nice if the user didn't have to run BM as it stands today. Meaning they could opt to just to import it and use its keymappings and other tools that you could/would expose that may make sense in their app as you would use any other lib. The fact BlackMamba is on PyPI also fits in nicely with this idea.

It seems to me you have either most or all the working parts their now. Then again, maybe I am trivialising some of aspects of doing this on the fly and having potentially multiple contexts running at one time. I mean, if you where running your app presented as a 'popover' in the wrench menu, or as a panel for example.

Anyway, not sure what you think. Look BM is super useful already. To me this is way you could extend its use to benefit even people. Anyway food for thought. I had some other ideas also. I put in another post later.

zrzka

@Phuket2 thanks for your input.

What's the main goal of Black Mamba? Basically there're two:

  • make great IDE from Pythonista (it's "just script editor" from this point of view today),
  • make experiments Ole can't do, show Ole what we miss and hopefully some of these things will be added to Pythonista some day. If not, can still live in Black Mamba,
  • provide functionality for both external keyboard and tapping users.

What's the current status?

Still alpha, still lot of breaking changes inside, ... From this point of view it's not a good idea to allow others to use internals. It will mean that I have to maintain compatibility and that's not what I want to do now. I do maintain stable "API" in:

  • blackmamba.log.*
  • blackmamba.key_command.register_key_command.* & UI* constants
  • blackmamba.main

And that's it. Also some of the Black Mamba features were wrapped with scripts usable as actions (= wrench icon) if you don't have external keyboard. That's also the main reason why I put back title bar with X button instead of my custom title to allow non keyboard users to close these dialogs. These last two changes were not officially released yet (not fully tested).

How the 1.0 can look like?

Black Mamba in several packages. One for UI stuff, one for runtime stuff, ... and one which does use all these packages to provide IDE functionality. Then, we can start talking about exposing some of these features via stable API to others. Like key commands registration / deregistration, ...But it's too soon to do it now. Latest release is 0.0.24, still a long way to 1.0. I'm alone, have job, ... and I have to minimise amount of work. That's the main reason why I'm not willing to maintain wider stable API except mentioned ones. So yes, I was thinking about this as well, but my time is kinda limited.

Not recommended part

Anyway, what main does?

  • Updates config
  • Checks for updates (can be disabled via update.enabled)
  • Registers default keys (can be disabled via general.register_key_commands)

See default values. Basically, if you do not want to call main, you're not forced to do it if you're not interested in updates, default shortcuts and if you're happy with default config. Then feel free to use register_key_command. The only thing which is missing is unregister_key_command. If you want it, file an issue.

Or you can use register_key_event_handler / unregister_key_event_handler in your dialogs. See this as an example how to use them. BUT, as I said, it's not officially supported. Can break any time (not likely), but can. I warned you :)

Phuket2

@zrzka, thanks for the reply. I understand your rationale.

zrzka

Sneak peak of new features that are coming ...

... 1.4 will be focused on refactoring. Another feature will be import organization (sorting, ...).

Phuket2

@zrzka , if you ever get bored one day, a nice challenge for you might be a search view like the latest version of the working copy app does. I think its so well done. I thought of you and BM when I seen it in action.
Maybe another dev here might aklso be interested in doing something like that also.

zrzka

@Phuket2 thanks for the idea. It's already reported as #21, but I'm not still sure if I should do this. Basically I don't need it, I'm happy with jump to definition, find usages and other stuff. Full text search can be slow, because you have to check all files again and again, or you have to store some indexes, then you have to validate them, check if something were changed, ... I'm not going to do this probably. Sorry :) As I wrote, focusing on refactoring, that's what I miss now.

Phuket2

@zrzka , no problems. I understand. Can't blame a guy for pushing his own agenda :). But anyway, it is a cool search implementation. In 20 years or so when I get better, I might attempt it :).
LOl, you can see I was also able to slip in another plug for Tinydb. I am shamless :)

ccc

It would be cool if you could add the futurize process (at least steps 0 and 1) which is a much more modern, less distructive approach to the 2to3 conversion that is built into Pythonista.