omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular
    1. Home
    2. bosco
    3. Best

    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 0
    • Topics 0
    • Posts 26
    • Best 6
    • Controversial 0
    • Groups 0

    Best posts made by bosco

    • RE: How to refresh Dropbox access token with the (older) Dropbox library included with Pythonista?

      I have created a modified version of dropboxlogin.py that generates short-lived access tokens. So far, it seems to work with dropbox version 6.4.0 that is provided with Pythonista.

      First run will authorize your application and store a long-lived refresh token in your device keychain.

      # simple test app
      import dropboxlogin
      dropbox_client = dropboxlogin.get_client()
      print('Getting account info...')
      account_info = dropbox_client.users_get_current_account()
      print('linked account:', account_info)
      

      Useful links:
      Migrating App access tokens
      Dropbox OAuth Guide

      I was able to update dropbox to the latest version with this work around script which downloads the dropbox wheel and unzips the contents in site-packages. I had to use Stash pip to install the requests, six and stone. I'm still testing to see if it is better to stick with the original Pythonista dropbox version or to use the upgraded versions of dropbox, requests and six.

      # workaround to install latest dropbox in pythonista
      # install requirements using stash pip
      # pip install requests
      # pip install six
      # pip install stone
      
      import sys, os
      import requests
      from zipfile import ZipFile
      
      sitepath = os.path.expanduser('~/Documents/site-packages-3')
      os.chdir(sitepath)
      from zipfile import ZipFile
      url = 'https://files.pythonhosted.org/packages/ef/64'
      url += '/2ef3c03ac039f9e5f29c0f557dc3f276241ef3c1627903a5f6a8c289cf24/'
      url += 'dropbox-11.7.0-py3-none-any.whl'
      dest_path = './dropbox.zip'
      r = requests.get(url)
      
      with open(dest_path, 'wb') as f:
          f.write(r.content)
          print('download complete...')
      
      with ZipFile(dest_path, 'r') as zip:
          # extracting all the files
          print('Extracting all the files now...')
          zip.extractall()
          print('Done!')
      
      os.remove(dest_path)
      
      posted in Pythonista
      bosco
      bosco
    • RE: Does the dropbox 6.4.0 library support TLS 1.2?

      @dthomson You may want to look at this post.
      https://forum.omz-software.com/topic/7014/how-to-refresh-dropbox-access-token-with-the-older-dropbox-library-included-with-pythonista/2
      I installed dropbox version 11.7.0 a year ago and I appears to still be working today.

      posted in Pythonista
      bosco
      bosco
    • RE: Problems with ios15

      This code works on my iPhone 12.

      I added @ui.in_background to def select_author(sender)

      I will also test the Lock code.

      import ui
      #
      def show_list_dialog(items=None, *args, **kwargs):
          items = items or []
          tbl = ui.TableView(**kwargs)
          tbl.data_source = ui.ListDataSource(items)
          my_sel = {'value': None}
          class MyTableViewDelegate (object):
              def tableview_did_select(self, tableview, section, row):
                  print('items:', tableview.data_source.items)
                  print('section, row:', section, row)
                  my_sel['value'] = tableview.data_source.items[row]
                  tableview.close()
                  print('in delegate: my_sel',my_sel['value'])
          tbl.delegate = MyTableViewDelegate()
          tbl.present(style='sheet')
          tbl.wait_modal()
          print('after wait: ', my_sel['value'])
          return my_sel['value']
      #
      w, h = ui.get_screen_size()
      view = ui.View(name="Frank's Library", bg_color='lightblue', frame=(0, 0, w, h))
       
      @ui.in_background 
      def select_author(sender):
          author_unique = ['Baldacci,David', 'Barr,Nevada', 'Bartol,Amy', 'Bernt,Eric', 'Brandt,Kylie', 'Bruni,Riccardo', 'Bryndza,Robert', 'Burke,James Lee', 'Burton,Mary', 'Butcher,Jim', 'Carlson,Tucker', 'Carrol,Sean', 'Case,Andrew', 'Chernov,Ron', 'Clayton,MegWaite', 'Coben,Harlan', 'Cole,Bobby', 'Connelly,Michael', 'Cornwell,Bernard', 'Cornwell,Patricia', 'Cowie,Amber', 'Crombie,Deborah', 'Crosby,Ellen', 'Cross,Katie', 'Cussler,Clive', 'Delaney,Matthew B.J.', 'Dilts,Tyler', 'Dorsey,Tim']
          f = (0, 0, 400, 300)
          selected_author = show_list_dialog(author_unique, frame=f, name='Select an Author')
          print('list dialog returned:', selected_author)
          global author_result
          author_result.text = str(selected_author)
          return
       
      author_button = ui.Button(title='Author', frame=(10,5,350,100), border_color='black', border_width=2, background_color='#EAECEE', action=select_author, font=('Arial Rounded MT Bold',18))
      author_button.width=70
      author_button.height=40
      view.add_subview(author_button)
      #
      global author_result
      author_entry=''
      author_result = ui.TextView(name='author',frame=(100,5,250,40), border_color='black', border_width=3, text=author_entry, font=('Arial Rounded MT Bold',16))
      view.add_subview(author_result)
       
      view.present('sheet')
      #nav_view = ui.NavigationView(view)
      #nav_view.present('sheet')
      

      @

      posted in Pythonista
      bosco
      bosco
    • RE: How to refresh Dropbox access token with the (older) Dropbox library included with Pythonista?

      @felciano There appear to be 2 issues.

      • Dropbox version 11.7.0 crashes when using the appex module.
      • The keychain module does not work with the appex module.

      You will need to use Dropbox 6.4.0 and you will need to store your refresh_token somewhere else besides keychain.

      You can modify dropboxlogin like this:

      #refresh_token = keychain.get_password('dropbox', 'refresh_token')
      refresh_token = "your_refresh_token"
      

      You can then remove the dropbox folders from site-packages-3 or try this script which removes site-packages-3 from sys.path when running from a share sheet and temporarily reverts back to dropbox 6.4.0.

      import sys
      import appex
      import console
      
      print('file', appex.get_file_path())
      
      def test():
          print(sys.path[1])
          if appex.is_running_extension():  # if share sheet  
              sys.path.remove(sys.path[1])  # remove site-packages-3 from sys.path  
          import dropbox
          print('dropbox version', str(dropbox.__version__))
      
          import dropboxlogin
          dropbox_client = dropboxlogin.get_client()
          print('Getting account info...')
          account_info = dropbox_client.users_get_current_account()
          print('linked account:', account_info)
          
      test()
          
      

      If you are just trying to upload a file from a share sheet, this script does not use the dropbox module:

      import sys, os, json, shutil
      import appex
      import console
      import keychain
      import requests
      from requests.auth import HTTPBasicAuth
      
      app_key = "your_app_key"
      app_secret = "your_app_secret"
      refresh_token = "your_refresh_token"
      
      def dropbox_token(refresh_token):
          data = {'refresh_token': refresh_token, 'grant_type': 'refresh_token'}
          try:
              r = requests.post('https://api.dropbox.com/oauth2/token', data=data,
                  auth = HTTPBasicAuth(app_key, app_secret))
              result = r.json()
          except:
              print(str(sys.exc_info()))
              return { 'refresh_token': None, 'access_token': None, 'error': {'.tag': str(sys.exc_info())} }
      
          #print('dbx:', result)
          return result
          
      def upload_file(source_filename, path):
          with open(source_filename, 'rb') as f:
              data = f.read()
      
          parms = {}
          parms['path'] =  path
          parms['mode'] =  'overwrite'
          print (json.dumps(parms))
          headers = {'Authorization': 'Bearer %s' % (access_token,),'Dropbox-API-Arg': json.dumps(parms),'Content-Type': 'application/octet-stream' }
          url = 'https://content.dropboxapi.com/2/files/upload'
          try:
              r = requests.post(url, stream=True, headers=headers, data=data)
          except:
              print("Exception requests: %s" % str(sys.exc_info()))
          result = r.json()
          return result
          
      local_path = os.path.expanduser('~/Documents/tmp')
      access_token = dropbox_token(refresh_token)['access_token']
      
      files = appex.get_file_paths()
      if files != None and files != []:
          for i in range(len(files)):
              print('Input path: %s' % files[i])
              basename = os.path.basename(files[i])
              filename=os.path.join(local_path, basename)
              shutil.copy(files[i], filename)
              upload_file(basename, '/remote/dropbox/path/' + basename)
      
      
      posted in Pythonista
      bosco
      bosco
    • RE: Xcode Template for Pythonista

      @ccc This link is for Microsoft OneDrive. My Dropbox space is limited.

      The original link is a more permanent and reliable alias to this URL.

      https://onedrive.live.com/?authkey=!AC94lHutmY315L4&id=98B88F62EF7BB2B3!125&cid=98B88F62EF7BB2B3

      posted in Pythonista
      bosco
      bosco
    • RE: Dropbox file picker needs update

      Ok. Now I see how to include source.

      import requests
      import urllib
      import os
      import ui
      import json
      
      def list_folder(folder_path='/'):
          headers = {'Authorization': 'Bearer %s' % (TOKEN,),'Content-Type': 'application/json' }
          if folder_path == '/': folder_path = ''
          data = {'path':folder_path}
          r = requests.post('https://api.dropboxapi.com/2/files/list_folder', headers=headers, data=json.dumps(data))
          result = r.json()
          return result.get('entries', None)
      
      def download_file(path, dest_filename, progress=None):
          data = {'path':path}
          headers = {'Authorization': 'Bearer %s' % (TOKEN,),'Dropbox-API-Arg': json.dumps(data)}
          url = 'https://content.dropboxapi.com/2/files/download'
          r = requests.post(url, stream=True, headers=headers)
      
      
      

      You also need to replace 'path' with 'path_dislpay' in twice in def load_folder.

      @ui.in_background
          def load_folder(self):
              infos = list_folder(self.path)
              items = []
              if self.path != '/':
                  items.append({'title': '..', 'image': 'ionicons-arrow-up-c-32', 'up': True})
              if not infos:
                  import console
                  console.alert('Error', 'Could not load folder. Please check if you entered the access token correctly.', 'OK', hide_cancel_button=True)
                  self.status_label.hidden = True
                  return
              for info in infos:
                  path = info.get('path_display')
                  name = os.path.split(path)[1]
                  if name.startswith('.'):
                      continue
                  is_dir = info.get('is_dir', False)
                  item = {'title': name, 'image': 'ionicons-folder-32' if is_dir else 'ionicons-ios7-download-outline-32', 'accessory_type': 'disclosure_indicator' if is_dir else 'none', 'is_dir': is_dir, 'path': info['path_display']}
      
      posted in Pythonista
      bosco
      bosco