omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular
    1. Home
    2. JonB

    Welcome!

    This is the community forum for my apps Pythonista and Editorial.

    For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.


    • Profile
    • Following 0
    • Followers 40
    • Topics 82
    • Posts 3926
    • Best 752
    • Controversial 0
    • Groups 0

    JonB

    @JonB

    1027
    Reputation
    26973
    Profile views
    3926
    Posts
    40
    Followers
    0
    Following
    Joined Last Online
    Website github.com/jsbain

    JonB Unfollow Follow

    Best posts made by JonB

    • interactive local notifications

      Someone posted the wishlist the ability to add interactive local notifications.... so this was this evening's distraction.


      The basic idea is that you have to override the app delegate with a custom version. (it should have been possible to add a method to the existing delegate, but this always caused a crash for me). Of course, this only works until ios decides to unload the app from memory, or you actively kill or crash the app, since the delegate is not permanent. As such, it is probably less useful than regular notifications.... omz would need to provide a way to hook delegate calls to python functions (specific file in site-packages, say).

      One note, I had to override the type encoding, because the @? type for a Block caused a TypeError when called... so I replaced this with a regular pointer @ and used ObjCInstance to convert to a Block to .invoke() the completionhandler.

      posted in Pythonista
      JonB
      JonB
    • Visual Debugger for pythonista [share]

      I have been toying with various ideas for a pythonista debugging system for a long time, to replace pdb in the console. With ObjC, we can finally integrate this into the editor itself.
      Here is a working, albeit not yet complete, visual debugger. right now it supports stepping in/over/continue/quit, as well as a Locals/Globals display (read only right now).

      I have separately working an overlay system for setting breakpoints by tapping the line number, though this is not yet fully baked and is not integrated into the main class yet (see inwork folder) I think I want to also go back to my older line highlight method (currently using editor annotations, but the "warning" is not overridable and interferes with the interface a bit)...

      Anyhoo, here's the Readme/install/screenies:

      Visual Debugger(vdb)

      interactive debugger inside pythonista editor

      ##features

      • single stepping, or step over
      • continue, or quit
      • watch window (view only right now)
      • During debugging, current line is highlighted, and editor opens new file if needed

      ##TODO:

      • breakpoint set/clear by tapping line s
      • launch script via menu
      • stack up/down
      • help menu
      • optimizations for small devices

      usage (where debugging is needed)

      	import vdb
      	vdb.VDB().set_trace()
      	
      

      ##install
      Thanks to @ywangd for this method.

      import requests as r; exec r.get('https://raw.githubusercontent.com/jsbain/vdb/master/get_vdb.py').text
      

      screenshots

      watch window
      ui overview

      posted in Pythonista
      JonB
      JonB
    • RE: For those that would like to write code on your iPad, look into Pythonista. It's Amazing!

      Thanks, but does it have a user forum where people can ask and answer questions?

      ...

      posted in Pythonista
      JonB
      JonB
    • ObjC View and Object Browser

      https://github.com/jsbain/viewbrowser.git

      Inspired by the UIDebuggingInformationOverlay, which I couldn't get to run on my 32 bit device, this is an overlay that allows exploration of the UIView heirarchy. Add to wrench menu for easy access. Mainly for exploring pythonista internals, but can also be used for views presented from the ui module.

      Tapping a view highlights the view in red, making it easy to find where you are. Currently hidden views are greyed out. Expanding a view shows its subviews. For buttons, or other views with gesture recognizers, tapping the link button shows the action and target(prints to console for now) -- useful for determining the objc methods to simulate button taps, etc. (@zrzka, you have probably figured out everything you want to simulate for blackmamba, but if not, this might be helpful)
      browser

      The info button opens an objc object browser, which shows all of the properties of the instance. Tapping on a property that is an ObjCInstance opens that object in the object browser, and so on.
      object browser
      The object browser is still somewhat experimental, and sometimes crashes for properties that return a different objc object for each call -- since i currently do not store the actual instance, but instead use the address, so if the object is gc'd, tapping on its rowresults in a segfault. I may change that (though it also seems like it could be a bad idea hanging onto strong references to a bunch of objects)

      posted in Pythonista
      JonB
      JonB
    • git / github workflow in stash

      With the addition (in latest master and dev brsnches) of the new gh command for interfacing with github (create, fork, or issue pull requests), I figure it is time to start writing down some simple git in stash tutorials. This is probably also a good way to expose and work on the remaining bugs in the stash git implementation.

      https://github.com/jsbain/stash_git_tutorial/blob/master/stash_git_tutorial.md

      posted in Pythonista
      JonB
      JonB
    • RE: Writing watermarks to PDF files

      see http://wa5pb.freeshell.org/motd/?p=769 for an example of creating a watermark with reportlab, then applying it using PyPDF ( or PyPDF2 in our case)

      both reportlab and pypdf2 are included with pythonista

      posted in Pythonista
      JonB
      JonB
    • RE: Show Lines Number

      I don't have an iphone to test this on, but you could try this:

      # coding: utf-8
      from objc_util import *
      app=UIApplication.sharedApplication()
      rootVC = app.keyWindow().rootViewController()
      tabVC = rootVC.detailViewController()
      tvc=tabVC.selectedTabViewController()
      ed=tvc.editorView()
      tv=ed.textView()
      tv.showLineNumbers=not tv.showLineNumbers()
      #not sure how to force a redraw.  changing frame size works
      oldframe=tv.frame()
      newframe=oldframe
      newframe.size.width-=1
      tv.frame=newframe
      import time
      time.sleep(0.1)
      tv.frame=oldframe
      

      maybe use in an action script, and it should toggle line numbers in the current tab. Not sure if the view heirarchy is the same on iphone, so maybe this won't work.

      posted in Pythonista
      JonB
      JonB
    • RE: Pythonista: Run Script with Command-Line Parameters?

      press and hold the play button, it will pop up a dialog asking for arguments.

      posted in Pythonista
      JonB
      JonB
    • RE: Access Pythonista Settings from Script
      from objc_util import *
      >>> defaults=ObjCClass('NSUserDefaults').standardUserDefaults()
      >>> defaultsDict=defaults.dictionaryRepresentation()
      >>> defaultsDict['UseSoftTabs']
      <b'__NSCFBoolean': 1>
      >>> defaultsDict['IndentationWidth']
      <b'__NSCFNumber': 3>
      

      type defaultsDict at the console to see all of the pythonista settings that you can check this way.

      posted in Pythonista
      JonB
      JonB
    • RE: How many days left until Python 2 end of life?

      @Ti-Leyon Actually, any devices still running python2.7 will instantly explode, into flames, possibly ending your life. The PSF does NOT mess around.

      posted in Pythonista
      JonB
      JonB

    Latest posts made by JonB

    • RE: ObjCClass('SUIViewController') does not work anymore in Pythonista beta but ...

      @cvp FWIW, I think the PY3 versions were available in the last version. So that code should also be backwards compatible.

      posted in Pythonista
      JonB
      JonB
    • RE: Recognize text from picture

      @Attirail that will be a little tricky because of the small and large numbers in each box. Detecting the outer box probably won't be too bad, then if you have known grid dimensions I'd think you could then find the grid without much trouble. But then you'd have to essentially only grab a specific region of each grid.

      posted in Pythonista
      JonB
      JonB
    • RE: Can’t write file to iPad

      @cvp IIRC, it needs to be in a folder inside iCloud, rather than in the "root" iCloud, otherwise you won't have write access?

      Also, text files can be viewed from within pythonista. Just swipe from left to see folders, and choose your file.

      posted in Pythonista
      JonB
      JonB
    • RE: Can’t write file to iPad

      @SpideryArticle what have you tried? And is your script in the main documents folder. Or under an on iCloud folder?

      You can write a file,but there are limits on which paths are writable. Generally

      with open('test.txt','wt') as f:
           f.write('it works')
      

      Should work. If you want to write to a specific location (not the script path) you need to specify a writable absolute path. You cannot write to the root folder for example.

      posted in Pythonista
      JonB
      JonB
    • RE: Cryptography support

      @kizik pythonista comes with pycrypto. But unless @omz de decides to include cryptography in next version (it is a commonly requested module), you might be out of luck.

      What specifically are you using in cryptography? Sometimes there are alternatives that you could have wrappers for.

      Edit: oh, I see, you are using robin_stocks. The only part of cryptography used is cryptography.fernet. you might be able to create a wrapper to
      https://github.com/heroku/fernet-py/blob/master/fernet/fernet.py
      That is based on pyCrypto, so should work.

      to make it look like the cryptography.fernet.Fernet class. Looks like there really are just one or two methods that you have to wrap, if it doesn't work as is.

      To install, you can use wget with the archive URL instead of pip, then unzip.

      posted in Pythonista
      JonB
      JonB
    • RE: Shortcut error: Could not run Run Pythonista Script

      @yaroslav_ya_ya right. Found this:
      https://developer.apple.com/forums/thread/655189
      And this
      https://developer.apple.com/videos/play/wwdc2020/10073/

      Looks like it might be both time (10sec) and memory (30MB).

      It seems like there is a method that @omz might be able to add to add a handler for in-app intents, and some sort of plug in system for handling them in python.

      posted in Pythonista
      JonB
      JonB
    • RE: 3D rotations in a UImage

      @cvp by the way, the crash was because I was using c_float instead of CGFloat. objc_util defines CGFloat, along with some other useful iOS c types. CGFloat is double on 64 bit (all modern version of iOS) and float on 32 bit machines (ipad 3 or maybe 4 and earlier). Also, as you guys found, I mistakenly forgot the last row of the transform.

      There are ways to animate the rotations.
      But I suspect SceneKit is ultimately easier to work with.

      posted in Pythonista
      JonB
      JonB
    • RE: 3D rotations in a UImage

      @cvp
      Looks like @cvp came to the rescue with my untested code. But here is the original, marked up with the intent. You can do google search for iOS headers CATransform3D, and get the c header files describing the various structure and functions, then just have to manually translate. The way CFUNCTION wrappers work, the doll contains the symbol, but you have to manually set return type (restype) and argument types argtypes.

      The low level stuff is slightly trickier to work it’s compared to actual ObjC. When converting objc code, you usually don’t need to mess with any of that, because the method encodings define everything, and are built into the runtime. But when passing structures instead of objects, you often have to override restypes. Rubicon handles this cleaner than the current objc_util…

      
      from objc_util import *
      from ctypes import *
      import ui
      import math, copy
      
      '''we need to wrap the CATransform structure
       struct CATransform3D
      {
        CGFloat m11, m12, m13, m14;
        CGFloat m21, m22, m23, m24;
        CGFloat m31, m32, m33, m34;
        CGFloat m41, m42, m43, m44;
      };
      this could also have been done with a pack
       '''
       
      class CATransform3D(Structure):
          _fields_ =   [('m11', CGFloat),('m12', CGFloat),('m13', CGFloat),('m14', CGFloat),
              ('m21', CGFloat),('m22', CGFloat),('m23', CGFloat),('m24', CGFloat),
              ('m31', CGFloat),('m32', CGFloat),('m33', CGFloat),('m34', CGFloat),
              ('m41', CGFloat),('m42', CGFloat),('m43', CGFloat),('m44', CGFloat),
              ]
      
      ''' 
      note, c is a variable imported in objc_util, which is the cDLL for the static library.
      '''
      
      '''
      /* Returns a transform that translates by '(tx, ty, tz)':
       * t' =  [1 0 0 0; 0 1 0 0; 0 0 1 0; tx ty tz 1]. */
      
      CA_EXTERN CATransform3D CATransform3DMakeTranslation (CGFloat tx,
          CGFloat ty, CGFloat tz)
          '''
      CATransform3DMakeTranslation = c.CATransform3DMakeTranslation 
      CATransform3DMakeTranslation.argtypes = [CGFloat, CGFloat, CGFloat]
      CATransform3DMakeTranslation.restype = CATransform3D
      
      '''
      /* Rotate 't' by 'angle' radians about the vector '(x, y, z)' and return
       * the result. If the vector has zero length the behavior is undefined:
       * t' = rotation(angle, x, y, z) * t. */
      
      CA_EXTERN CATransform3D CATransform3DRotate (CATransform3D t, CGFloat angle,
          CGFloat x, CGFloat y, CGFloat z)
          '''
      CATransform3DRotate = c.CATransform3DRotate
      CATransform3DRotate.restype = CATransform3D
      CATransform3DRotate.argtypes = [CATransform3D, CGFloat, CGFloat, CGFloat, CGFloat]
      
      ''' named const can often be retrieved using in_dll.  however, we need a mutable copy, so we dont wat to use this as identity'''
      CATransform3DIdentity=CATransform3D.in_dll(c,'CATransform3DIdentity')
      identity=copy.deepcopy(CATransform3DIdentity)
      
      
      '''other ways to get identity:
      
      identity = CATransform3D()
      identity.m11=1
      identity.m22=1
      identity.m33=1
      identity.m44=1
      
      or
      
      identity=CATransform3DMakeTranslation(0,0,0)
      
      note, we cant use CATransformMake because that is a c macro, not an exported function
      '''
      
      
      
      v=ui.View(frame=(0,0,500,500))
      v.bg_color='white'
      sv=ui.ImageView()
      
      sv.image=ui.Image.named('card:Clubs3')
      sv.size_to_fit()
      v.add_subview(sv)
      v.present('sheet')
      
      layer = sv.objc_instance.layer() 
      
      #another way to get current transrorm
      #identity=layer.transform(argtypes=[],restype=CATransform3D)
      
      identity.m34 = -1/500 #sets perspective
      #rotate 
      rot = CATransform3DRotate(identity,  math.radians(55), 0,1,0)
      layer.setTransform_(rot,argtypes=[CATransform3D],restype=None)
      
      posted in Pythonista
      JonB
      JonB
    • RE: 3D rotations in a UImage

      @madivad This should be doable.

      Something like this though I haven't tried yet

      from objc_util.import *
      from ctypes import *
      import math
      
      '''we need to wrap the CATransform structure '''
      def CATransform (ctypes.Structure):
          _fields_ = 
              [{'m11', c_float},{'m12', c_float},{'m13', c_float},{'m14', c_float},
              {'m21', c_float},{'m22', c_float},{'m23', c_float},{'m24', c_float},
              {'m31', c_float},{'m32', c_float},{'m33', c_float},{'m34', c_float}]
      
      
      CATransform3DMakeTranslation = c.CATransform3DMakeTranslation 
      CATransform3DMakeTranslation.argtypes = [c_float, c_float, c_float]
      CATransform3DMakeTranslation.restype = CATransform
      
      CATransform3DRotate = c.CATransform3DRotate
      CATransform3DRotate.restype = CATransform3D
      CATransform3DRotate.argtypes = [CATransform c_float, c_float, c_float, c_float]
      
      identity= CATransform3DMakeTranslation(0,0,0)
      identity.m34 = -1/500
      rot = CATransform3DRotate(identity,  math.radians(45), 0,1,0)
      
      v=ui.View(frame=(0,0,800,800))
      sv=ui.View(frame = (50,5,300,300))
      sv.bgcolor = 'blue'
      v.add_subview(sv)
      v.present()
      
      SV = ObjCInstance(sv)
      layer = SV.layer()
      layer.transform = rot
      

      Pythonista interface with ctypes structures returned from ObjC methods can be kind of screwed up, so we might have to modify the argtypes of the setLayer_ method manually to get things to work in the last statement.
      I can give it a try tonight

      posted in Pythonista
      JonB
      JonB
    • RE: Adding and Accessing my own assets (sounds, images, etc.)

      @quantumquark you can share files from Files, or Workflow app, etc. Then, you can use

      ui.Image.named('full_path_to_file')
      

      You can also use relative paths, but that often confuses people. The current working directory changes when you press "Play", so if you place pngs or jpegs in the same folder as the running script, you can just load the image name, without the full path.

      posted in Pythonista
      JonB
      JonB