Community

    • Login
    • Search
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search

    Hierarchical backup wanted.

    General Discussion
    backup
    5
    12
    166
    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.
    • teleslon2
      teleslon2 last edited by

      Ok, NPP has great backup feature that saves all your edits to a special dir. But it would be a bit difficult to browse there though same-named copies originated from various sources (many days later). For example I could edit different websites and style.css files on each of them.

      It would be extremely nice to have hierarchical backup system, when if I edit (it’s WinScp) C:\Users\User\AppData\Local\Temp\scp18702\var\www\lala\data\www\example.com\actions\channel.php
      and backup copy to be saved to
      %Backup-dir%/Drive-c/Users\User\AppData\Local\Temp\scp18702\var\www\lala\data\www\example.com\actions\channel.php

      Seems there’s no such a plugin?

      Alan Kilborn 1 Reply Last reply Reply Quote 0
      • Alan Kilborn
        Alan Kilborn @teleslon2 last edited by

        @teleslon2

        To my knowledge, there’s no plugin to do such a thing.

        But, with the PythonScript plugin (or another scripting plugin) you can do pretty much anything you want. You would set up a “notification” on the save event and then fire off some script code to make a copy of your file.

        If you’d be willing to use the PythonScript plugin, I’ll volunteer to put together a demo for you (it’s really not difficult).

        1 Reply Last reply Reply Quote 2
        • Alan Kilborn
          Alan Kilborn last edited by

          So it could be as simple as a script like what follows.

          Note that this script only considers files that are mapped to a local C: through Z: drive.
          Other (network) paths are possible, but for the point of illustration, that’s just an unnecessary complication.

          Also note that much more error checking and results reporting (presumably upon failure) could be done.

          Typically the lines of the script would be added to the user’s startup.py file, so that it is transparently activated and sitting there waiting for user saves to happen, after Notepad++ initializes.

          Anyway, the script:

          # -*- coding: utf-8 -*-
          
          from Npp import notepad, NOTIFICATION
          import os
          import shutil
          import re
          
          def callback_notepad_FILESAVED(args):
              curr_buffer_id = notepad.getCurrentBufferID()
              notepad.activateBufferID(args['bufferID'])
              p = notepad.getCurrentFilename()
              m = re.match('([C-Z]):', p, re.I)
              if m:
                  top_level_backup_dir = r'c:\temp\mybackups'
                  backup_path = top_level_backup_dir + os.sep + 'Drive-{}'.format(m.group(1)) + p[2:]
                  backup_dir = backup_path.rsplit(os.sep, 1)[0]
                  if not os.path.isdir(backup_dir): os.makedirs(backup_dir)
                  if os.path.isdir(backup_dir): shutil.copy2(p, backup_path)
          
          notepad.callback(callback_notepad_FILESAVED, [NOTIFICATION.FILESAVED])
          
          1 Reply Last reply Reply Quote 3
          • teleslon2
            teleslon2 last edited by

            Sadly, it doesn’t work for me. Folder c:\temp\mybackups exists. I’ve tried files on Z (mapped c:\xampp…), on С - nothing appeared in mybackups folder.
            NPP 7.8 Windows 8.1
            Is it possible to print debug info there? My primary language is PHP, so I’m not so smart here…

            Alan Kilborn 2 Replies Last reply Reply Quote 0
            • Ekopalypse
              Ekopalypse last edited by

              @teleslon2

              Did you restart npp after creating your user startup.py?
              A print(m) before the if m will print to the python script console.
              Can be opened via the menu.
              Just make sure you use the same indentation (tabs or spaces but not mixed) as the lines before and after.

              1 Reply Last reply Reply Quote 1
              • Alan Kilborn
                Alan Kilborn @teleslon2 last edited by

                @teleslon2

                Did you notice this line in the demo script?:

                top_level_backup_dir = r'c:\temp\mybackups'

                Obviously you’d want to replace the path I used with the path you desire.

                Otherwise I suggest the “print” route that @Ekopalypse recommended.

                Saying “it doesn’t work” is fine but it doesn’t leave much room for help from someone not sitting right at your computer.

                1 Reply Last reply Reply Quote 1
                • Alan Kilborn
                  Alan Kilborn @teleslon2 last edited by

                  @teleslon2 said in Hierarchical backup wanted.:

                  Folder c:\temp\mybackups exists.

                  Oh, you did say this, so my comment about that doesn’t apply. Sorry.

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

                    That’s strange. I surely restarted it and not once. Ok, now it’s working (after inserting “print”, hmm…).
                    Next, I’d like to shorten some paths but my regex didn’t match, could you please help?

                    print (backup_path)
                    backup_path = re.sub(r"<c\:\\temp\\mybackups\\Drive\-C\\Users\\User\\AppData\\Local\\Temp\\scp\d+>", 'WinScp', backup_path)
                    

                    Prints
                    c:\temp\mybackups\Drive-C\Users\User\AppData\Local\Temp\scp26772\home\admin\web
                    before replacing.

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

                      Opps, there should by “c:\temp\mybackups\WinScp” as replacement string. But anyway, it prints the same after replacement.

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

                        Thanks, Alan!
                        And a guy helped me out there, so below is my final variant. I add time to file names and shorten paths derived from WinScp editing of remote files.

                        from Npp import notepad, NOTIFICATION
                        import os
                        import shutil
                        import re
                        from datetime import datetime
                        
                        def callback_notepad_FILESAVED(args):
                            curr_buffer_id = notepad.getCurrentBufferID()
                            notepad.activateBufferID(args['bufferID'])
                            p = notepad.getCurrentFilename()
                            m = re.match('([C-Z]):', p, re.I)
                            time_now = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
                            if m:
                                top_level_backup_dir = r'c:\temp\mybackups'
                                backup_path = top_level_backup_dir + os.sep + 'Drive-{}'.format(m.group(1)) + p[2:] + '.' + time_now
                                backup_path = re.sub(r"c\:\\temp\\mybackups\\Drive\-C\\Users\\User\\AppData\\Local\\Temp\\scp\d+", r'c:\\temp\\mybackups\\WinScp', backup_path)
                                backup_dir = backup_path.rsplit(os.sep, 1)[0]
                                if not os.path.isdir(backup_dir): os.makedirs(backup_dir)
                                if os.path.isdir(backup_dir): shutil.copy2(p, backup_path)
                        
                        notepad.callback(callback_notepad_FILESAVED, [NOTIFICATION.FILESAVED])
                        
                        1 Reply Last reply Reply Quote 2
                        • Moisey Oysgelt
                          Moisey Oysgelt last edited by

                          I made for my environment

                          def callback_notepad_FILESAVED(args):
                          curr_buffer_id = notepad.getCurrentBufferID()
                          notepad.activateBufferID(args[‘bufferID’])
                          p = notepad.getCurrentFilename()
                          time_now = datetime.now().strftime(“%Y-%m-%d_%H-%M-%S”)
                          # print§
                          # m = re.match(‘([C-Z]):’, p, re.I)
                          if True:
                          # p1=p.replace(‘:’,‘/’).replace(os.sep,‘/’).replace(‘//’,‘/’)
                          # backup_path = top_level_backup_dir + os.sep + ‘Drive-{}’.format(m.group(1)) + p[2:]
                          # backup_path = top_level_backup_dir + os.sep + p1
                          # backup_dir = backup_path.rsplit(os.sep, 1)[0]
                          # if not os.path.isdir(backup_dir): os.makedirs(backup_dir)
                          # if os.path.isdir(backup_dir): shutil.copy2(p, backup_path)
                          top_level_backup_dir = ‘C:/temp/backup/’
                          p=p.replace(os.sep,‘/’)
                          pathLisr=p.split(‘/’)
                          pat=‘/’.join(pathLisr[:-1])
                          OriginalName=pathLisr[-1]
                          ext=os.path.splitext(OriginalName)[1]
                          new_name=os.path.splitext(OriginalName)[0]+time_now+ext
                          backup_dir=top_level_backup_dir + pat.replace(‘:’,‘/’).replace(os.sep,‘/’).replace(‘//’,‘/’)
                          new_name= backup_dir+‘/’+new_name
                          if not os.path.isdir(backup_dir): os.makedirs(backup_dir)
                          shutil.copyfile(p,new_name)
                          #################################

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

                            Here is another version that backup file before it’s being overwritten with new data and appends date/time of the last modification date of the original file (not current date of the backup)
                            i.e. file C:\blah\mycode.js will be backed up as D:\Backup\Notepad++\C\blah\mycode.js_20210928_221824.js
                            It also works with network shares

                            from os import makedirs
                            from os.path import split, splitext, exists, getmtime
                            from shutil import copyfile
                            from time import strftime, localtime
                            from re import sub
                            from Npp import *
                            
                            def callback_FILEBEFORESAVE(args):
                            
                                backup_dir = "D:\\Backup\\Notepad++\\";             # backup directory, must have trailing slash
                            
                                _file = notepad.getBufferFilename(args['bufferID']) # get full path
                                if not exists(_file):                               # new file?
                                    return
                            
                                with open(_file, "r") as f:                         # read data from file
                                  if f.read() == editor.getText():                  # only save if file was modified
                                    console.write(msg + "file unchanged, no backup created\n")
                                    return
                            
                                file = sub("^\\\\+", "",                            # remove \ at beginning of the path
                                       sub('[<>"|?*:]', "_",                        # just a precation, replace invalid characters with _
                                       sub("^([a-zA-Z]):", r"\1",                   # remove : after drive letter
                                       _file)))
                            
                                dir, file = split(file)                             # get directory and file
                                filename, ext = splitext(file)                      # get filename and extension
                            
                                new_dir = backup_dir + dir + "\\";
                                new_filename = filename + ext                       # original filename
                                new_filename = new_filename + str(strftime("_%Y%m%d_%H%M%S", localtime(getmtime(_file)))) + ext; # append date/time and original extension
                            
                                if not exists(new_dir):
                                  try:
                                    makedirs(new_dir)
                                  except Exception as err:
                                    console.write(msg + str(err).replace("\\\\", "\\") + "\n")
                                    return
                            
                                try:
                                  copyfile(_file, new_dir + new_filename)
                                  console.write(msg + "saved as " + new_dir + new_filename + "\n")
                                except Exception as err:
                                  console.write(msg + str(err).replace("\\\\", "\\") + "\n")
                            
                            
                            notepad.clearCallbacks([NOTIFICATION.FILEBEFORESAVE])
                            notepad.callback(callback_FILEBEFORESAVE, [NOTIFICATION.FILEBEFORESAVE])
                            
                            msg = "[Auto backup] " # console message prefix
                            console.write(msg + "initialized\n")
                            

                            For easy managing it’s better to save this script as a separate file i.e autobackup.py in the same directory where startup.py is
                            and at the end of startup.py add this line:

                            import autobackup # script's filename without extension
                            
                            1 Reply Last reply Reply Quote 0
                            • First post
                              Last post
                            Copyright © 2014 NodeBB Forums | Contributors