omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    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.


    [solved] duplicate a directory or multiple files.

    Pythonista
    6
    14
    11555
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • abcabc
      abcabc last edited by

      You can use stash cp command ("cp f1 f2 f3 destination_directory") to copy multiple files and directory. The stash command "cd ~/../Documents" would take you to top level Pythonista 2 directory. For example "ls ~/../Documents" lists the top level files in pythonista 2 directory and "ls ~/Documents" lists the top level files in pythonista 3 directory. May be you can look at the cp.py in site-packages/stash/bin to see how copy is implemented and it may help you to write your own copy command. Note that cp.py uses shutil.copytree.

      1 Reply Last reply Reply Quote 0
      • jmv38
        jmv38 last edited by jmv38

        thank you all. i did this, for anyone who needs it:

        import os
        import shutil
        cwd = os.getcwd()
        src = '/private/var/mobile/Containers/Shared/AppGroup/blablabla/Documents/FFT' # change for the good adress
        dst = cwd+'/myProg1/FFT'
        print(src)
        print(dst)
        shutil.copytree(src,dst)
        

        however this could be a built-in command of the editor.

        1 Reply Last reply Reply Quote 0
        • jmv38
          jmv38 last edited by

          here are two pieces of code to copy, then paste a directory:

          import editor, clipboard, re, console, os
          
          '''Utilities to be added to the editor
          '''
          def copyDirPathToClipboard():
          	'''Copy current file directory to the clipboard
          	'''
          	# get current location
          	file = editor.get_path()
          	dir = os.path.dirname(file)
          	
          	# inform user and get confirmation
          	msg = re.match('.*Pythonista3/Documents/(.+)',dir).group(1)
          	ans = console.alert('Copy','Copy this directory?\n'+msg+'\nNB: select a file to get its directory!','yes')
          	
          	# if yes, copy to clipboard
          	if ans == 1 :
          	  clipboard.set(dir)
          	  console.hud_alert('Done!','success',0.5)
          	
          copyDirPathToClipboard()
          
          import editor, clipboard, console, re, shutil, os
          
          '''Utility to be added to the editor
          '''
          def pasteDir():
          	'''Copy the directory in clipboard to the same directory as the current file
          	'''
          	# get current directory location
          	file = editor.get_path()
          	dir = os.path.dirname(file)
          	
          	# get source directory from clipboard
          	src = clipboard.get()
          	
          	# get name of directory
          	name = src.split('/')
          	name = name[-1]
          	
          	# build destination name
          	dst = dir + '/' + name
          	
          	# short version of destination
          	msg = re.match('.*Pythonista3/Documents/(.+)',dst).group(1)
          	
          	# if already exists then cancel
          	if os.path.exists(dst):
          		console.alert('Paste Error','Directory:\n'+ msg + '\nalready exists! Paste not possible.')
          
          	# inform user and get confirmation
          	ans = console.alert('Paste','Create this new directory?\n'+msg,'yes')
          	
          	# if yes, paste
          	if ans == 1:
          		shutil.copytree(src,dst)
          		console.hud_alert('Done!','success',0.5)
          	
          	
          pasteDir()
          

          is it possible to add these in the editor wrench menu other than manually?
          Thanks

          1 Reply Last reply Reply Quote 0
          • JonB
            JonB last edited by

            here is a set of tools that can be used for adding /removing items to the wrench menu. I have not tested this in recent versions, let me know if it does not work. You need to save the user defaults after editing.

            1 Reply Last reply Reply Quote 0
            • jmv38
              jmv38 last edited by jmv38

              thank you @JonB
              your code seems ok, however i have type problems.

              I want to check if the action button is not already there before adding it. So i list the action.
              The list of actions is, when i print it

              [<b'__NSCFDictionary': {
                  arguments = paste;
                  iconName = "Primaries_Paste";
                  scriptName = "/myProg1/pasteDir.py";
                  title = "paste_dir";
              }>, <b'__NSCFDictionary': {
                  arguments = copy;
                  iconName = "ios7-copy-outline";
                  scriptName = "/myProg1/pasteDir.py";
                  title = "copy_dir";
              }
              

              so i create a disctionnary with title keys

              	lst = get_actions()
              	titles = {}
              	for dct in lst:
              		titles[dct['title']] = True
              

              but when i try to access title['copy_dir'] i get a key error.
              i get when i print my dictionnary:

              {<b'NSTaggedPointerString': copy_dir>: True, <b'NSTaggedPointerString': paste_dir>: True}
              

              the maybe the keys are not simple strings?
              so i think i should convert my dct['title'] to strings before using them as key for the dictionnary? But i dont know how to do that, there is no tostring(). Any idea?

              1 Reply Last reply Reply Quote 0
              • JonB
                JonB last edited by JonB

                use str() to convert an NSString to a python string. e.g. str(dct['title'])

                1 Reply Last reply Reply Quote 0
                • jmv38
                  jmv38 last edited by jmv38

                  @JonB thanks! it does work.
                  Here is my final code. Nothing great here, this is just for me to get familiar with python and pythonista.
                  paste it where you want, run it, you should have 2 more icons in the wrench menu: copy_dir and paste_dir. There is some limited error management in these 2 function. Only problem: you must select a file in the directory (src or dst) to get the good adress, displaying the good directory is not enough.

                  '''This script installs two utilities in the editor:
                  	copy directory
                  	paste directory
                  	Author: Jmv38 - 2016 - Pythonista3
                  '''
                  import editor, clipboard, console, re, shutil, os
                  
                  from sys import argv
                  
                  # this code is from JonB - Thank you!
                  # source: https://github.com/jsbain/objc_hacks/blob/master/add_action.py
                  
                  from objc_util import *
                  NSUserDefaults = ObjCClass('NSUserDefaults')
                  
                  def add_action(scriptName,iconName='python',iconColor='',title='',arguments=''):
                     '''adds an editor action.  scriptName should start with / 
                     (e.g /stash/stash.py)
                     iconName should be an icon without leading prefix, or trailing size.  i.e alert instead of iob:alert_256
                     iconColor should be a web style hex string, eg aa00ff
                     title is the alternative title
                     Call save_defaults() to store defaults
                     ')'''
                     defaults=NSUserDefaults.standardUserDefaults()
                     kwargs=locals()
                     entry={ key:kwargs[key] 
                              for key in
                              ('scriptName','iconName','iconColor','title','arguments') 
                              if key in kwargs and kwargs[key] }
                     editoractions=get_actions()
                     editoractions.append(ns(entry))
                     defaults.setObject_forKey_(editoractions,'EditorActionInfos')
                  
                  def remove_action(scriptName):
                     ''' remove all instances of a given scriptname.  
                     Call save_defaults() to store for next session
                     '''
                     defaults=NSUserDefaults.standardUserDefaults()
                     editoractions=get_actions()
                     [editoractions.remove(x) for x in editoractions if str(x['scriptName'])==scriptName]
                     defaults.setObject_forKey_(editoractions,'EditorActionInfos')
                     
                  def remove_action_at_index(index):
                     ''' remove action at index.  Call save_defaults() to save result.
                     '''
                     defaults=NSUserDefaults.standardUserDefaults()
                     editoractions = get_actions()
                     del editoractions[index]
                     defaults.setObject_forKey_(editoractions,'EditorActionInfos')
                     
                  def get_defaults_dict():
                     '''return NSdictionary of defaults'''
                     defaults=NSUserDefaults.standardUserDefaults()
                     return defaults.dictionaryRepresentation()
                     
                  def get_actions():
                     '''return action list'''
                     defaults=NSUserDefaults.standardUserDefaults()
                     return list(defaults.arrayForKey_('EditorActionInfos'))
                     
                  def save_defaults():
                     '''save current set of defaults'''
                     defaults=NSUserDefaults.standardUserDefaults()
                     NSUserDefaults.setStandardUserDefaults_(defaults)
                     
                  # end of JonB code
                  
                  def install_actions():
                  	''' Installs shortcuts in the wrench menu
                  	'''
                  	# get current location
                  	file = editor.get_path()
                  	file = re.match('.+Pythonista3/Documents(/.+)',file).group(1)
                  	
                  	lst = get_actions()
                  	titles = {}
                  	for dct in lst:
                  		titles[str(dct['title'])] = True
                  	
                  	cmd = 'paste_dir'
                  	if cmd not in titles:
                  		add_action(arguments = 'paste', 
                  		iconName = "Primaries_Paste", 
                  		scriptName = file,
                  		title = cmd )
                  		
                  	cmd = 'copy_dir'
                  	if cmd not in titles:
                  		add_action(arguments = 'copy', 
                  		iconName = "ios7-copy-outline", 
                  		scriptName = file,
                  		title = cmd )
                  		
                  	save_defaults()
                  
                  def copyDir():
                  	'''Copy current file directory to the clipboard
                  	'''
                  	# get current location
                  	file = editor.get_path()
                  	dir = os.path.dirname(file)
                  	
                  	# inform user and get confirmation
                  	msg = re.match('.*Pythonista3/Documents/(.+)',dir).group(1)
                  	ans = console.alert('Copy',
                  				'\nNB: YOU MUST SELECT A FILE IN THE DIRECTORY TO COPY!'
                  				+ '\n\nIs this the directory you want to copy?\n\n' + msg
                  				,'yes')
                  	
                  	# if yes, copy to clipboard
                  	if ans == 1 :
                  	  clipboard.set(dir)
                  	  console.hud_alert('Done!','success',0.5)
                  	
                  
                  def pasteDir():
                  	'''Copy the directory in clipboard to the same directory as the current file
                  	'''
                  	# get current directory location
                  	file = editor.get_path()
                  	dir = os.path.dirname(file)
                  	
                  	# get source directory from clipboard
                  	src = clipboard.get()
                  	
                  	# is it a valid source?
                  	if not os.path.exists(src):
                  		console.alert('Paste Error',
                  			'Directory described in clipboard does not exist! Paste not possible.'
                  			+ '\nClipboard content:\n\n' + src)
                  		return 
                  	msg = re.match('.+(Pythonista3/Documents/)(.+)',src)
                  	if (msg == None) or (msg.group(2) == None):
                  		msg = 'clipboard content is not a valid pythonista3 sub-directory:\n'+src+'\npaste not possible.'
                  		console.alert('Paste Error', msg)
                  		return
                  		
                  	# get name of directory
                  	name = msg.group(2)
                  	name = name.split('/')[-1]
                  	
                  	# build destination name
                  	dst = dir + '/' + name
                  	# and a short version
                  	msg = re.match('.+(Pythonista3/Documents/)(.+)',dst).group(2)
                  	
                  	# if already exists then cancel
                  	if os.path.exists(dst):
                  		console.alert('Paste Error','Directory:\n'+ msg + '\nalready exists! Paste not possible.')
                  		return 
                  
                  	# inform user and get confirmation
                  	ans = console.alert('Paste',
                  				'\nNB: YOU MUST SELECT A FILE IN THE DIRECTORY WHERE TO PASTE!'
                  				+ '\n\nIs this the directory you want to create?\n\n' + msg
                  				,'yes')
                  	
                  	# if yes, paste
                  	if ans == 1:
                  		shutil.copytree(src,dst)
                  		console.hud_alert('Done!','success',0.5)
                  
                  # get script argument
                  cmd = argv[-1]
                  if cmd == 'paste':
                  	pasteDir()
                  elif cmd == 'copy':
                  	copyDir()
                  else:
                  	install_actions()
                  	
                  	
                  
                  1 Reply Last reply Reply Quote 0
                  • jmv38
                    jmv38 last edited by

                    hello @JonB.
                    using you code for remove_action i found a bug: not all actions were removed. This is due to the dynamic remove of the list elements. I modified your code by adding a reverse scan of the list, and now it is fixed. Thanks.

                    def remove_action(scriptName):
                       ''' remove all instances of a given scriptname.  
                       Call save_defaults() to store for next session
                       '''
                       defaults=NSUserDefaults.standardUserDefaults()
                       editoractions=get_actions()
                       [editoractions.remove(x) for x in reversed(editoractions) if str(x['scriptName'])==scriptName]
                       defaults.setObject_forKey_(editoractions,'EditorActionInfos')
                    
                    1 Reply Last reply Reply Quote 0
                    • jmv38
                      jmv38 last edited by

                      here is the last version of code https://gist.github.com/23407f680c9744ad2beb6d1fafcca9a4
                      it adds 4 shortcuts: copy, paste, dir, file
                      remove the old shortcuts manually.

                      1 Reply Last reply Reply Quote 0
                      • jmv38
                        jmv38 last edited by

                        any one who knows how to get the currently displayed editor directory without selecting a file in this directory?
                        Thanks!

                        1 Reply Last reply Reply Quote 0
                        • dgelessus
                          dgelessus last edited by

                          @jmv38 There is no way to find out what folder is currently shown in Pythonista's file list - there is no function in the editor or console module for that. It might be possible to find this out using objc_util, but I don't know Pythonista's internal structure well enough to help you with that.

                          1 Reply Last reply Reply Quote 0
                          • First post
                            Last post
                          Powered by NodeBB Forums | Contributors