-
blmacbeth
I was playing around with the
location
module the other day and was wondering about how it deals with scripts closing without manually turning off location tracking. So I made a context Manager for thelocation
moduleimport location class LocationManager (object): def __enter__(self): location.start_updates() def __exit__(self): location.stop_updates()
You can use it like so:
with LocationManager(): # Do stuff that requires `location` here... ...
Now, this may be completely unnecessary, but I have found it useful for applications where constant location updates are not needed (e.g. get my location every 15 minutes or set my initial location for some one off script).
@omz also think this may be a good feature for the built-in
location
module to adopt (if possible). So we can have bothlocation.start(stop)_updates()
orwith location: ...
.Let me know what y'all think (criticism is welcome).
B.
EDIT
A bit less verbose code with the help of @ccc on contexlibimport contexlib import location @contexlib.contexmanager def location_enabled(): location.start_updates() yield location.stop_updates()
the use case is still the same.
with location_enabled(): # Do location stuff here... ...
-
blmacbeth
@bistrot Add the
#! python2
she-bang at the top of the script to tell it to use the (possibly) nom-default python 2.7 interpreter. -
-
blmacbeth
I have a script where I'm trying to get the system attributes; eventually this will gather memory information. I have isolated the crash to this line of code:
from ctypes import POINTER from objc_util import ObjCClass, ObjCInstance, c, c_void_p NSHomeDirectory = c.NSHomeDirectory NSHomeDirectory.restype = c_void_p NSHomeDirectory.argtype = [] NSFileManager = ObjCClass('NSFileManager') LP_c_void_p = POINTER(c_void_p) def get_system_attributes(): file_manager = NSFileManager.defaultManager() error = LP_c_void_p() attributes = file_manager.attributesOfFileSystemForPath_error_( ObjCInstance( NSHomeDirectory() ).cString(), error ) return attributes get_system_attributes()
attributesOfFileSystemForPath_error_
takes a string and an error pointer. It crashes when it gets to the error inside that function. I think it crashes due to anNSError
object being created. Any ideas on how to stop the crash? -
blmacbeth
@Phuket2 quoted from the Apple developer forums:
Retina Flash
iPhone 6s and 6s Plus contain a custom display chip that allows the retina display to briefly flash 3 times brighter than its usual maximum illuminance. No new API was added to support this feature. Since iOS 4, AVCaptureDevice has supported the -hasFlash, -isFlashModeSupported: and -flashMode properties. The iPhone 6s and 6s Plus front-facing cameras are the first front-facing iOS cameras to respond YES to the -hasFlash property. By setting the front-facing camera's flashMode to AVCaptureFlashModeOn or AVCaptureFlashModeAuto, the retina flash fires when a still image is captured (see AVCaptureStillImageOutput’s captureStillImageAsynchronouslyFromConnection:completionHandler:), just as the True Tone flash fires for rear-facing camera stills.Hope this. Only works on 6s, 6s+, and SE.
B. -
blmacbeth
@Tizzy sorry for not explaining myself better. @dgelessus is correct about the
?
being the important part.I checked MySQL and it has its own syntax for variable arguments that just so happens to be
%s
. Shame on them… -
blmacbeth
@Tizzy it is good practice to not do
statement = 'SELECT * FROM ' + table_name'
or evenstatement = 'SELECT * FROM ' + %s' % table_name
as this can cause security issues with SQL injection. Most database packages (read: modules) will have something along the lines ofstatement = ''' SELECT * FROM ? ''' with db.connect as conn: result = conn.execute(statement, (table_name,))
This is a more secure way of accessing batabases. The other way is good enough for person projects, but keep that in mind or little Bobby Tables will make your life awful as a DBA.
B.
-
blmacbeth
@omz said:
Btw, you can just pass a prefix to
ObjCClass.get_names()
instead of doing the filtering yourself (in the current beta, it would have to be a byte string though).Did not know that…
-
blmacbeth
Hey @omz, I got back in to playing around with
objc_util
and found this:>>> dir(OMJavaScriptSyntaxHighlighter) Traceback (most recent call last): File "<string>", line 1, in <module> File "/var/mobile/Containers/Bundle/Application/61407674-7331-47C2-B308-BDB7BBE52166/Pythonista3.app/Frameworks/PythonistaKit3.framework/pylib/site-packages/objc_util.py", line 380, in __dir__ py_method_name = sel_name.replace(':', '_') TypeError: a bytes-like object is required, not 'str'
This error come from the way Python3.* encodes ASCII vs Unicode strings. When you run the following:
om_classes = [cls for cls in ObjCClass.get_names() if cls.startswith(b'OM')] for cls in om_classes: print(cls)
You get the following (truncated for brevity):
b'OMAutoresizingMaskView' b'OMBarButton' b'OMBarButtonItem' b'OMBaseSyntaxHighlighter' b'OMBasicPythonCompletionProvider' b'OMBasicPythonCompletionProviderTokenizedLine' b'OMButtonFieldSpecifier' b'OMCSSSyntaxHighlighter' b'OMCaretView' b'OMCheckCell' b'OMCheckFieldSpecifier' … b'OMUIWidgetViewScrollView' b'OMUIWidgetViewSegmentedControl' b'OMUIWidgetViewSlider' b'OMUIWidgetViewStickyNote' b'OMUIWidgetViewSwitch' b'OMUIWidgetViewTableView' b'OMUIWidgetViewTextField' b'OMUIWidgetViewTextView' b'OMUIWidgetViewWebView'
Notice the
b
before the string. So, when you want to run string operations, which are now encoded asUTF-8
, it throws aTypeError
becauseASCII
is (for whatever reason) a byte-like object, not a string.To fix this you can have
.get_names()
return strings, or add theb
prefix to the strings inreplace()
method inobjc_util
. -
blmacbeth
Noticed some bugs in the above code, so here are my fixes to make it work (in Pythonista3, at least).
# coding: utf-8 import ui from objc_util import * class BlurView (ui.View): def __init__(self, style=1, *args, **kwargs): ui.View.__init__(self, **kwargs) self._style = style self.effect_view = None self.setup_effect_view() @on_main_thread def setup_effect_view(self): if self.effect_view is not None: self.effect_view.removeFromSuperview() UIVisualEffectView = ObjCClass('UIVisualEffectView') UIVibrancyEffect = ObjCClass('UIVibrancyEffect') UIBlurEffect = ObjCClass('UIBlurEffect') UILabel = ObjCClass('UILabel') # Brooks patch for Rect not having a 'slice' bounds = self.bounds.as_tuple() frame = (bounds[:2], bounds[2:]) self.effect_view = UIVisualEffectView.alloc().initWithFrame_(frame).autorelease() effect = UIBlurEffect.effectWithStyle_(self._style) self.effect_view.effect = effect self.effect_view.setAutoresizingMask_(18) ObjCInstance(self).addSubview_(self.effect_view) vibrancy_effect = UIVibrancyEffect.effectForBlurEffect_(effect) self.vibrancy_view = UIVisualEffectView.alloc().initWithFrame_(frame).autorelease() self.vibrancy_view.effect = vibrancy_effect self.effect_view.contentView().addSubview_(self.vibrancy_view) @property def style(self): return self._style @style.setter def style(self, value): if value != self._style: self._style = value self.setup_effect_view() # Brooks fix @on_mains_thread to @on_main_thread @on_main_thread def add_vibrant_label(self, label): self.vibrancy_view.contentView().addSubview_(ObjCInstance(label)) def main(): image_view = ui.ImageView(frame=(0, 0, 320, 320)) image_view.image = ui.Image.named('test:Mandrill') blur_view = BlurView(style=2, frame=image_view.bounds.inset(40, 40)) image_view.add_subview(blur_view) label = ui.Label(frame=blur_view.bounds) label.text = 'Hello World' label.font = ('HelveticaNeue', 40) label.alignment = ui.ALIGN_CENTER blur_view.add_vibrant_label(label) image_view.present('sheet') main()
The biggest problem was that the
ui.Rect()
object does not have the ability to useslices
. This was fixed with theui.Rect().as_tuple()
function. The second problem was just a typo.B