• tlinnet

    I made it with pythonista 3.

    Using the template for Xcode (found on github)
    deleted unnessary files, and finally updating objc_util.py in the template folder (look in site packages) with the copy from pythonista on phone.

    posted in Pythonista read more
  • tlinnet

    So, I was thinking of a chemistry app.

    With a similar interface as this:
    https://phet.colorado.edu/en/simulation/balancing-chemical-equations

    But, of course the student should be able to use his/her own chemistry equation to balance.

    That could be an input text field, OR, take a picture of the equation, and then text
    recognition.

    Anyone with experience in this? :)

    posted in Pythonista read more
  • tlinnet

    Hi!

    I just wan't to tell, that my very first app was just accepted in iTunes store.

    I could not have done it without you!

    1. Thanks for getting help to access the printning utility.

    2. Thanks for fixing the IPv6 issue ! That was a app killer. ;)

    So now I have tried the whole path from idea to App release. Now it is time to get better ideas :)

    Merry Christmas

    posted in Pythonista read more
  • tlinnet

    I ended up with this, which functions as expected.

    # Create a tableview, with data
    self.tv = ui.TableView()
    self.tv.row_height = 30
    self.tv.data_source = MyTableViewDataSource(self.tv.row_height)
    self.tv.delegate = MyTableViewDelegate()
    
    # Update tableview data
    self.tv.data_source.items = sorted(self.c.read_vouchers(), key=itemgetter(0), reverse=True)
    
    # Do not allow selection on the TableView
    #self.tv.allows_selection = False
    self.tv.allows_selection = True
    
    # Add the table
    self.add_subview(self.tv)
    
    
    # Define the class for the Table Data
    class MyTableViewDataSource(object):
        def __init__(self, row_height):
            self.row_height = row_height
            self.width = None
    
        def tableview_number_of_rows(self, tableview, section):
            return len(tableview.data_source.items)
    
        def tableview_cell_for_row(self, tableview, section, row):
            self.width, height = ui.get_screen_size()
            cell = ui.TableViewCell()
            cell.bounds = (0, 0, self.width, self.row_height)
            for i in range(3):
                self.make_labels(cell, tableview.data_source.items[row][i], i)
            return cell
    
        def make_labels(self, cell, text, pos):
            label = ui.Label()
            label.border_color = 'lightgrey'
            label.border_width = 0.5
            label.text = str(text)
            if pos == 0:
                label.frame = (self.width*0/5, 0, self.width/5, self.row_height)
            elif pos == 1:
                label.frame = (self.width*1/5, 0, self.width*2/5, self.row_height)
            elif pos == 2:
                label.frame = (self.width*3/5, 0, self.width*2/5, self.row_height)
            label.alignment = ui.ALIGN_CENTER
            cell.content_view.add_subview(label)
    
    class MyTableViewDelegate(object):
        @ui.in_background
        def tableview_did_select(self, tableview, section, row):
            select_voucher_index, select_voucher = tableview.data_source.items[row][:2]
            Common().write_config('select_voucher_index', select_voucher_index)
            Common().write_config('select_voucher', select_voucher)
            MyTableView().refresh_last_voucher()```

    posted in Pythonista read more
  • tlinnet

    Hi.

    I have a table. It contains 3 columns.
    I would like to make an interaction.

    When I click a row in the table, the 3 column information should be stored in a dict.

    # Create a tableview, with data
    self.tv = ui.TableView()
    self.tv.row_height = 30
    self.tv.data_source = MyTableViewDataSource(self.tv.row_height)
    #self.tv.delegate = MyTableViewDelegate()
    
    # Update tableview data
    self.tv.data_source.items = sorted(self.c.read_vouchers(), key=itemgetter(0), reverse=True)
    
    # Do not allow selection on the TableView
    self.tv.allows_selection = False
    #self.tv.allows_selection = True
    
    # Add the table
    self.add_subview(self.tv)
    

    And class

    class MyTableViewDataSource(object):
        def __init__(self, row_height):
            self.row_height = row_height
            self.width = None
    
        def tableview_number_of_rows(self, tableview, section):
            return len(tableview.data_source.items)
    
        def tableview_cell_for_row(self, tableview, section, row):
            self.width, height = ui.get_screen_size()
            cell = ui.TableViewCell()
            cell.bounds = (0,0,self.width,self.row_height)
            for i in range(3):
                self.make_labels(cell, tableview.data_source.items[row][i], i)
            return cell
    
        def make_labels(self, cell, text, pos):
            label = ui.Label()
            label.border_color = 'lightgrey'
            label.border_width = 0.5
            label.text = str(text)
            if pos == 0:
                label.frame = (self.width*0/5, 0, self.width/5, self.row_height)
    
            elif pos == 1:
                label.frame = (self.width*1/5, 0, self.width*2/5, self.row_height)
    
            elif pos == 2:
                label.frame = (self.width*3/5, 0, self.width*2/5, self.row_height)
    
    
            label.alignment = ui.ALIGN_CENTER
            cell.content_view.add_subview(label)
    
    #class MyTableViewDelegate(object):
    #    def tableview_did_select(self, tableview, section, row):
    #        print 'select'
    #    def tableview_did_deselect(self, tableview, section, row):
    #        print 'deselect'
    

    How would I do this?

    posted in Pythonista read more
  • tlinnet

    And now the last modification..

    Making exceptions work as well.

    https://gist.github.com/tlinnet/aff5decf31d07d0c0cccfad7961353f7

    posted in Pythonista read more
  • tlinnet

    I got it to work with, headers, ios basic authentication and parameters, and saving the response.

    Thanks!

    https://gist.github.com/tlinnet/31b35136e206ea2b4829a13799c89316

    posted in Pythonista read more
  • tlinnet

    Now getting a return.

    Don't know how to exactly to implement a "wait", but here is a try

    import objc_util
    from urlparse import urlparse
    from urllib import urlencode
    from ctypes import c_void_p
    import time
    
    class Web(object):
        def __init__(self, url=None, params=None):
            self.data = None
    
            if params:
                params_encoded = urlencode(params)
            else:
                params_encoded = ""
            url = objc_util.nsurl("{}?{}".format(url, params_encoded))
            request = objc_util.ObjCClass("NSURLRequest").request(URL=url)
            configuration = objc_util.ObjCClass("NSURLSessionConfiguration").defaultSessionConfiguration()
        
            session = objc_util.ObjCClass("NSURLSession").session(Configuration=configuration)
        
            completionHandler = objc_util.ObjCBlock(self.responseHandlerBlock, restype=None, argtypes=[c_void_p, c_void_p, c_void_p, c_void_p])
            objc_util.retain_global(completionHandler)
        
            dataTask = session.dataTask(Request=request, completionHandler=completionHandler)
            dataTask.resume()
    
        def responseHandlerBlock(self, _cmd, data, response, error):
            if error is not None:
                error = objc_util.ObjCInstance(error)
                print(error)
                return
            response = objc_util.ObjCInstance(response)
            data = objc_util.ObjCInstance(data)
            self.data = (str(objc_util.nsdata_to_bytes(data)))
    
        def return_data(self):
            return self.data
    
    
    url = "http://validate.jsontest.com"
    params = {"json" : {"first" : "lukas", "last" : "kollmer"}}
    
    #validate(url, None, responseHandlerBlock)
    #validate(url, params, responseHandlerBlock)
    call = Web(url, params)
    
    wait = True
    while wait:
        data = call.return_data()
        if data != None:
            print data
            wait = False
    print "Done"```

    posted in Pythonista read more
  • tlinnet

    WOW!!!!

    Thanks! :)
    This works as expected. :)

    I get a json back, I can work with.
    I will try to implement this, and see if it passes the Apple review.

    Thanks!

    import objc_util
    from urlparse import urlparse
    from urllib import urlencode
    from ctypes import c_void_p
    
    NSURLRequest = objc_util.ObjCClass("NSURLRequest")
    NSURLSession = objc_util.ObjCClass("NSURLSession")
    NSURLSessionConfiguration = objc_util.ObjCClass("NSURLSessionConfiguration")
    
    def validate(url, params, responseHandler):
        if params:
            params_encoded = urlencode(params)
        else:
            params_encoded = ""
        url = objc_util.nsurl("{}?{}".format(url, params_encoded))
        request = NSURLRequest.request(URL=url)
        configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
        
        session = NSURLSession.session(Configuration=configuration)
        
        completionHandler = objc_util.ObjCBlock(responseHandler, restype=None, argtypes=[c_void_p, c_void_p, c_void_p, c_void_p])
        objc_util.retain_global(completionHandler)
        
        dataTask = session.dataTask(Request=request, completionHandler=completionHandler)
        dataTask.resume()
    
    def responseHandlerBlock(_cmd, data, response, error):
        if error is not None:
            error = objc_util.ObjCInstance(error)
            print(error)
            return
        response = objc_util.ObjCInstance(response)
        data = objc_util.ObjCInstance(data)
        print(str(objc_util.nsdata_to_bytes(data)))
    
    url = "http://validate.jsontest.com"
    params = {"json" : {"first" : "lukas", "last" : "kollmer"}}
    
    #validate(url, None, responseHandlerBlock)
    validate(url, params, responseHandlerBlock)
    

    posted in Pythonista read more
  • tlinnet

    I am here at the moment

    from objc_util import *
    
    class Web(object):
        def __init__(self, root=None, method=None, headers=None):
            #NSMutableURLRequest* request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:url]];
            self.request = ObjCClass('NSMutableURLRequest').alloc().initWithURL_(nsurl(root))
            #[request setHTTPMethod:@"POST"];
            self.request.setHTTPMethod_(method)
    
            # Make headers
            for key in headers:
                #[request setValue:@"es" forHTTPHeaderField:@"Accept-Language"];
                self.request.setValue_forHTTPHeaderField_(key, headers[key])
    
            # Make request
            #NSURLConnection * theConnection = [[NSURLConnection alloc] initWithRequest:imageRequest delegate:self];
            #self.conn = ObjCClass('NSURLConnection').alloc().initWithRequest_delegate_(self.request, self)
            self.conn = ObjCClass('NSURLConnection').alloc().initWithRequest_delegate_startImmediately_(self.request, self, True)
    
            #[connection autorelease];
            self.conn.autorelease()
    

    But I dont know how to unpack or return the request?
    So I get the response from the server?

    posted in Pythonista read more
  • tlinnet

    Hi.

    Since pythonista does not handle ipv6, I would like to make a method for objc_util, that can be a replacement for python request.

    A objc_util replacement for a call like this:

    import requests
    
    root='http://validate.jsontest.com'
    url=root+''
    params = {'json':str({"key":"value"})}
    r = requests.get(url, params=params)
    print r.json()
    

    posted in Pythonista read more
  • tlinnet

    @JonB said:

    confdefs.h

    No luck in finding confdefs.h or any setting with IPV6.

    There is:
    PythonistaAppTemplate/PythonistaKit.framework/pylib/_sysconfigdata.py

     'ENABLE_IPV6': 1,```
    

    But the header says:

    # [omz] NOTE: This is required by site.py, but the values are not correct.
    #             It's a copy of the default OS X _sysconfigdata, but there shouldn't
    #             be much need for this on iOS anyway.
    
    # system configuration generated and used by the sysconfig module
    

    posted in Pythonista read more
  • tlinnet

    I will look into if Xcode can be manipulated to compile with ipv6 .

    The road by using objc util instead, could be a solution. But I am simply lost there, and don't know how to bug track.

    @omz can you confirm the ipv6 problem?
    Has any apps been released to the app store, which use request?

    posted in Pythonista read more
  • tlinnet

    The very first problem for this issue.

    To establish an ipv6-only environment, when my router WAN is only ipv4.

    So testing is difficult!

    But it seems pythonista is shipped without ipv6 support. At least in the iOS app.

    posted in Pythonista read more
  • tlinnet

    This is difficult!
    How to figure out how this is working in objc_util?

    I think I have prepared a request, but now I want to make the request.
    But I am lost....

    This is where I am at the moment.

    https://gist.github.com/tlinnet/92c0654081a6c49aa5b39a984018b253

    posted in Pythonista read more
  • tlinnet

    Could this be solved by using objc_util ?

    posted in Pythonista read more
  • tlinnet

    Hi.

    I am trying to submit an app for Apple app store.

    It uses the python request module.

    Apple request that such an app should support IPv6-only Networks.

    https://developer.apple.com/news/?id=05042016a

    The following snippet shows that ipv6 is not included.
    It shows:

    socket.has_ipv6 = False
    error message: "error: getsockaddrarg: bad family"

    import requests, socket
    
    # Test of python has ipvp
    print("Has ipv6?: %s\n"%socket.has_ipv6)
    
    root='http://ipv6.whatismyv6.com/'
    url=root
    params = {}
    
    try:
        r = requests.get(url, params=params)
        print("Request works\n")
    except requests.exceptions.RequestException as e:
        print("ERROR: Request does not work!")
        print(str(e.message))
    
    

    I have tested this on pythonista 3.0 and in the 2.7 and 3.5 interpreter.

    posted in Pythonista read more
  • tlinnet

    So I made an initial script "strip_pylib.py".

    This script should be runned in pythonista at the phone.
    It will make a "pylib_clean.sh" file, which should be copied to:

    "PATH/PythonistaAppTemplate/PythonistaKit.framework"
    at the Xcode project.

    And then issue:

    source pylib_clean.sh 
    rm pylib_clean.sh 
    

    (Note: pylib_clean.sh should be deleted in the PythonistaKit.framework folder afterwards,
    or there will be problems with signing and sending to App store.)

    pylib_clean.sh will delete a lot of files.

    After compilation in Xcode, the program did not work.
    I had to manually copy back the directory: "/pylib/encodings" from another copy of PythonistaAppTemplate, and then it worked.

    The compilation in Xcode is a lot faster. :)

    And the app size went from 60 MB to 30 MB.
    There are still some files left, but I am not sure why they survived.

    strip_pylib.py

    # Clear all
    # To get pythonista to work again, restart the app
    import sys
    sys.modules[__name__].__dict__.clear()
    
    # Now import
    import sys
    import inspect
    import importlib
    
    splitstr = "PythonistaKit.framework"
    
    pyt_mods = [
            "os",
            "datetime",
            "json",
            "requests",
            "operator",
            "time",
            ]
    
    pythonista_mods = [
            "ui",
            "console",
            "dialogs",
            "objc_util"
          ]  
    
    all_mods = pyt_mods + pythonista_mods
    
    keep_list = []
    for imods in all_mods:
        try:
            m  = importlib.import_module(imods)
            dirpath, filepath = inspect.getfile(m).split(splitstr)
            keep_list.append(filepath)
    
        except TypeError as e:
            #print(e)
            pass
    
    # Get the imported modules
    dict = sys.modules
    for key in dict:
        val = dict[key]
        if val == None:
            continue
        else:
            try:
                filepath = inspect.getfile(val)
                if splitstr in filepath:
                    filepath_append = filepath.split(splitstr)[1]
                    keep_list.append(filepath_append)
                else:
                    pass
    
            except TypeError as e:
                #print(e)
                pass
    
    # Make uniq and sort
    keep_list = sorted(set(keep_list))
    
    # Now find all files
    import os
    
    fp = dirpath+splitstr
    extensions = [".py", ".pyo"]
    all_files = []
    for path, dirs, files in os.walk(fp):
        for f in files:
            filename, file_extension = os.path.splitext(f)
            if "/pylib/" in path or "/pylib_ext/" in path:
                if file_extension in extensions:
                    stringfp = os.path.join(path, f)
                    dirpath, filepath = stringfp.split(splitstr)
                    all_files.append(filepath)
    
    # Make uniq and sort
    all_files = sorted(set(all_files))
    
    # Make a delete list
    dellist = [x for x in all_files if x not in keep_list]
    
    # Write delete file
    fname = 'pylib_clean.sh'
    f = open(fname,'w')
    f.write("#!/usr/bin/env bash\n")
    
    for idel in dellist:
        f.write("rm ."+idel+"\n")
    f.close()
    
    f = open(fname, "r")
    for line in f:
        print(line),
    f.close()
    

    posted in Pythonista read more
Internal error.

Oops! Looks like something went wrong!