Pythonista 1.6 Beta
So, with Apple's new TestFlight, I can finally have a lot more beta testers, and won't have to worry about device limits so much.
If you'd like to play with the next version of Pythonista before it hits the App Store, please send me an email with your Apple ID, and I'll see what I can do. I don't plan to use up all the slots yet (I might need some later), but if you've been posting here, there's a very good chance that I can give you access to the beta.
As for what to expect, here's a list of the new features in the current beta:
- Improved support for the iPhone 6 and 6 Plus screen sizes
- Removing files from the library moves them to a trash folder instead of deleting them immediately.
- URLs in console output are 'linkified' automatically
remindersmodule for accessing the iOS Reminders database (read/write)
cbmodule for connecting to Bluetooth LE peripherals (experimental)
- New dialogs module as an easy-to-use alternative to the ui module when you just need simple data entry. This also contains functions to import files from the iCloud Drive document picker (iOS 8 only). – note: this is broken in the current beta, but will be fixed in the next few days
just reading the release notes is awesome. I immediately tried some of the stuff and just have to say WOW. Just one question about the beta testing: Open comments about the the beta here or where to sent my remarks?
As long as you make it clear that a thread is beta-related, it's totally fine with me to discuss it here.
I've just submitted a new build with a few fixes – most importantly, the
dialogsmodule should actually work now. It'll be available in a few hours (it takes a while for iTunes Connect to process new uploads).
There's also a new
urllib), if you want more control.
Bug: passing variables into
console.login_alertdoesn't work and causes the command to hang (was working in stable).
@hyshai Thanks, I'll look into that. So far, I can't reproduce the hanging, but it definitely doesn't work correctly (it always behaves as if it was cancelled).
Just started playing with it, truly great. Also noticed that sheet view doesn't have a fixed width and height now, and it responds to the views set size. Wasn't in the release notes so I'm not sure if this was meant to be there.
@omz I narrowed it down. It has nothing to do with a variable. Multiple prompts are the issue e.g.
import console, keychain keychain.get_password('test', 'test') #requires keychain.master_password which has a prompt console.login_alert('hello') # this will never be called and the script hangs
import console console.login_alert('hello') console.login_alert('goodbye') # this will never be called but the script exits silently
Is this possibly related to the bug of not showing the keyboard automatically when there's an input prompt (specifically the
This sounds interesting, looking forward to the update. Sent you an e-mail.
Does TestFlight require iOS 8? I have an oldish iPhone that can only run iOS 7 that I might be able to test with as well.
I think TestFlight requires iOS 8.
@omz TestFlight does require iOS 8. How do you get the text entered into a text dialog?
How do you get the text entered into a text dialog?
It's the return value of the
Just mailed you my apple id. Would love to test out BTLE.
I assume the appex module you teased on Twitter is not integrated/activated in this Beta? Anyway, it's pretty cool you're doing this and I am happy to test the Twitter integration :)
Feedback on the in-app "What's new in Pythonista?" docs... Change
dialogsand activate the hyperlink.
@ccc, I believe omz uses the same doc generator that is used for the standard library, in which case it will automatically link once the module name is recognized.
@omz searching in the docs is very wonky. sometimes it works and sometimes it doesn't - just says "Searching......". (using an iPhone 5)
Just looking at the docs has me wowed! One tip would be to include an example script for BLE, as the protocol my be a little foreign to some.
A few things I've noticed so far:
- The Pythonista.app bundle is now fully moved out of the "Data" folder and no longer easily accessible (sad face)
- The Trash is invisible when empty (not really a bug, but somewhat counter-intuitive)
- The Trash didn't appear for me the first time I deleted a file until I opened the settings (thus reloading the file list I suppose)
- No way to selectively delete files from the Trash or restore multiple files at once
- The Move menu still takes ages to open
- Not specifically a beta bug, but in thumbnail view the default syntax highlight style is always used, no matter which one is selected in the settings
reminders.get_reminders(completed=TRUE)is there currently, or could there be in a future version, a way to filter completed reminders with completion date. Perhaps something like reminders completed today, or the past week, or since a given date? That could be nice for keeping track of certain projects or self-quantification, et al. Also would like to see this module in Editorial eventually. Better than using url schemes in all these reminder workflows.
I was able to use the Bluetooth LE module to talk to a LightBlue Bean and enumerate all of its services and characteristics.
I also tried reading all the values for each characteristic and ran into one problem. The values returned may or may not be text strings and if you simply assume they are and print them to the console you can get the module to throw an exception
TypeError: must be string without null bytes, not str
Trace back says it happened at line 73 in cb.py
After that you can recover but you can also crash completely or leave the module in a bad state and unable to talk to the peripheral.
Here is my code:
import cb import sound import time import struct class LightBlueBean (object): def __init__(self): self.peripheral = None def did_discover_peripheral(self, p): print 'Discovered:', p.name if p.name and 'Bean' in p.name and not self.peripheral: self.peripheral = p print 'Connecting to Bean...' cb.connect_peripheral(p) def did_connect_peripheral(self, p): print 'Connected:', p.name print 'Discovering services...' p.discover_services() def did_fail_to_connect_peripheral(self, p, error): print 'Failed to connect: %s' % (error,) def did_disconnect_peripheral(self, p, error): print 'Disconnected, error: %s' % (error,) self.peripheral = None def did_discover_services(self, p, error): print 'Did discover services...' for s in p.services: print 'Service:', s.uuid if True: # s.uuid == '180D' print 'Discovering characteristics...' p.discover_characteristics(s) def did_discover_characteristics(self, s, error): print 'Did discover characteristics...' for c in s.characteristics: print 'Characteristic:', c.uuid, ' Value:', c.value #if c.uuid == '2A37': # self.peripheral.set_notify_value(c, True) self.peripheral.read_characteristic_value(c) def did_update_value(self, c, error): #somevalue = struct.unpack('<B', c.value) #self.values.append(somevalue) #print 'Value: %i' % somevalue print 'Update to a value...' print 'Characteristic:', c.uuid, ' Value:', c.value mngr = LightBlueBean() cb.set_central_delegate(mngr) print 'Scanning for peripherals...' cb.scan_for_peripherals() try: while True: pass except KeyboardInterrupt: print 'keyboard interrupt - resetting' cb.reset()
Here is the console output:
Scanning for peripherals... Discovered: Bean Connecting to Bean... Connected: Bean Discovering services... Disconnected, error: (10, u'The connection has failed unexpectedly.') keyboard interrupt - resetting Scanning for peripherals... Discovered: Bean Connecting to Bean... Connected: Bean Discovering services... Did discover services... Service: F000FFC0-0451-4000-B000-000000000000 Discovering characteristics... Service: 180A Discovering characteristics... Service: A495FF10-C5B1-4B44-B512-1370F02D74DE Discovering characteristics... Service: A495FF20-C5B1-4B44-B512-1370F02D74DE Discovering characteristics... Service: 180F Discovering characteristics... Did discover characteristics... Characteristic: F000FFC1-0451-4000-B000-000000000000 Value: None Characteristic: F000FFC2-0451-4000-B000-000000000000 Value: None Did discover characteristics... Characteristic: 2A23 Value: None Characteristic: 2A24 Value: None Characteristic: 2A25 Value: None Characteristic: 2A26 Value: None Characteristic: 2A27 Value: None Characteristic: 2A28 Value: None Characteristic: 2A29 Value: None Characteristic: 2A2A Value: None Characteristic: 2A50 Value: None Did discover characteristics... Characteristic: A495FF11-C5B1-4B44-B512-1370F02D74DE Value: None Did discover characteristics... Characteristic: A495FF21-C5B1-4B44-B512-1370F02D74DE Value: None Characteristic: A495FF22-C5B1-4B44-B512-1370F02D74DE Value: None Characteristic: A495FF23-C5B1-4B44-B512-1370F02D74DE Value: None Characteristic: A495FF24-C5B1-4B44-B512-1370F02D74DE Value: None Characteristic: A495FF25-C5B1-4B44-B512-1370F02D74DE Value: None Did discover characteristics... Characteristic: 2A19 Value: None Update to a value... Characteristic: F000FFC1-0451-4000-B000-000000000000 Value: None Update to a value... Characteristic: F000FFC2-0451-4000-B000-000000000000 Value: None Update to a value... Characteristic: 2A23 Value: Update to a value... Characteristic: 2A24 Value: Bean Update to a value... Characteristic: 2A25 Value: Serial Number Update to a value... Characteristic: 2A26 Value: 201409080001 Img-B Update to a value... Characteristic: 2A27 Value: E Update to a value... Characteristic: 2A28 Value: Software Revision Update to a value... Characteristic: 2A29 Value: Punch Through Design Update to a value... Characteristic: 2A2A Value: Update to a value... Characteristic: 2A50 Value: Update to a value... Characteristic: A495FF11-C5B1-4B44-B512-1370F02D74DE Value: Update to a value... Characteristic: A495FF21-C5B1-4B44-B512-1370F02D74DE Value: Update to a value... Characteristic: A495FF22-C5B1-4B44-B512-1370F02D74DE Value: Update to a value... Characteristic: A495FF23-C5B1-4B44-B512-1370F02D74DE Value: Update to a value... Characteristic: A495FF24-C5B1-4B44-B512-1370F02D74DE Value: Update to a value... Characteristic: A495FF25-C5B1-4B44-B512-1370F02D74DE Value: Update to a value... Characteristic: 2A19 Value: 1 keyboard interrupt - resetting
Instead of a plain
print(data), try using
print(data.replace("\x00", "")), with
databeing the value received from the peripheral. This simply removes any null bytes from the string to stop print from complaining. For debugging purposes you might want to replace null bytes with something like
"NULL"so you can find them in the printed text.