Find date and time of latest folder and compare with todays date.

Find date and time of latest folder and compare with todays date.

LDShaw
Collaborator Collaborator
907 Views
9 Replies
Message 1 of 10

Find date and time of latest folder and compare with todays date.

LDShaw
Collaborator
Collaborator

I have a lisp that creates sub folders under archive and saves files (DWG, TXT, CSV, RVT, PNG, JPG, XLSX) from our working folder into an dated archived folder. 

The folder is derrived from

(setq dwgDir (getvar "dwgprefix"))
(setq archiveRootDir (strcat dwgDir "archive\\"))
(setq foldername (strcat archiveDir "\\"))

I want to find the latest folder and if it's older than 10 days create another archive. If it's newer than 10 days ask if you'd like it created. 

Here is the lisp I created to list the files. 

defun c:ListFoldersInDir ()
  (setq dwgDir (getvar "dwgprefix"))
  (setq archiveRootDir (strcat dwgDir "archive\\"))
  
  ;; Define a function to list all subdirectories
  (defun list-folders (path / result folderList)
    (setq result nil)
    (setq folderList (vl-directory-files path nil -1))
    (foreach folder folderList
      (if (and
            (not (wcmatch folder "*~$*")) ; Exclude temp files
            (not (wcmatch folder ".*"))   ; Exclude hidden files and directories
            (vl-directory-files (strcat path folder) nil -1)
          )
        (setq result (cons folder result))
      )
    )
    result
  )
  
  ;; Get the list of folders
  (setq folders (list-folders archiveRootDir))
  
  ;; Print the list of folders to the command line
  (princ "\nList of folders:\n")
  (foreach folder folders
    (princ (strcat "\n" folder))
  )
  
  (princ) ; Exit quietly
)

(princ "\nType ListFoldersInDir to list folders in the archive directory.\n")

here is the lisp I am using to list the times

(setq dwgDir (getvar "dwgprefix"))
(setq archiveRootDir (strcat dwgDir "archive\\"))

(defun get-folder-creation-date (folderPath)
  (setq fso (vlax-create-object "Scripting.FileSystemObject"))
  (setq folder (vlax-get-property (vlax-invoke-method fso 'GetFolder folderPath) 'DateCreated))
  (setq folderDate (rtos folder 2 10))
  (vlax-release-object fso)
  folderDate
)

(setq archiveCreationDate (get-folder-creation-date archiveRootDir))

 

Am I going about this the right way?

Here is the lisp I wrote to create the archive.

 

;;; ==============================================================================
;;; Lisp Name: archive_and_save.lsp
;;; Author: Lonnie
;;; Date Created: 2024-06-06
;;; https://www.theswamp.org/index.php?topic=59596.msg621100#msg621100
;;; Last Edited: [Insert Last Edit Date]
;;;
;;; DESCRIPTION:
;;; A routine to archive and save files related to the current AutoCAD drawing.
;;;
;;; Usage:
;;; 1. Load the Lisp routine.
;;; 2. Run the command "DCARCH" in AutoCAD.
;;;
;;; Parameters:
;;; dwgDir currentDate year month day formattedDate archiveDir foldername dwgFiles txtFiles csvFiles rvtFiles allFiles pngFiles jpgFiles xlsxFiles
;;;
;;; Returns:
;;; None
;;;
;;; Notes:
;;; - This routine archives and saves files (DWG, TXT, CSV, RVT, PNG, JPG, XLSX) 
;;;   related to the current AutoCAD drawing in a dated subfolder within an 
;;;   "archive" directory.
;;;
;;; ---------------------------- Main program --------------------------------;

(defun C:dcarch (/ dwgDir currentDate year month day formattedDate archiveRootDir archiveDir foldername dwgFiles txtFiles csvFiles rvtFiles allFiles pngFiles jpgFiles xlsxFiles userResponse)

  ;; Get the directory of the current drawing
  (setq dwgDir (getvar "dwgprefix"))
  
  ;; Get and format the current date
  (setq currentDate (rtos (getvar "cdate") 2 5))
  (setq year (substr currentDate 1 4))
  (setq month (substr currentDate 5 2))
  (setq day (substr currentDate 7 2))
  (setq formattedDate (strcat year "-" month "-" day))
  
  ;; Define the archive root directory and the dated subdirectory
  (setq archiveRootDir (strcat dwgDir "Archive\\"))
  (setq archiveDir (strcat archiveRootDir formattedDate))
  (setq foldername (strcat archiveDir "\\"))


  ;; Check if the archive root directory exists
  (if (not (vl-file-directory-p archiveRootDir))
    (progn
      ;; Prompt the user to create the archive directory
      (setq userResponse (getstring (strcat "The archive directory does not exist. Do you want to create it? (Y/N): ")))
      ;; If the user wants to create it, do so
      (if (or (equal (strcase userResponse) "Y") (equal (strcase userResponse) "YES"))
        (vl-mkdir archiveRootDir)
        (progn
          (prompt "\nThe archive directory does not exist and was not created. Exiting command.")
          (exit)
        )
      )
    )
  )

  ;; Create the dated subdirectory
  (vl-mkdir archiveDir)

  ;; Function to list files in a directory matching a specific pattern (case-insensitive)
  (defun list-files (dir pattern)
    (vl-remove-if 'null
      (mapcar '(lambda (file)
                 (if (wcmatch (strcase file) (strcase pattern))
                   (strcat dir file)
                 )
               )
               (vl-directory-files dir)
      )
    )
  )

  ;; Function to copy a file from source to destination
  (defun copy-file (src dst)
    (vl-file-copy src dst)
  )

  ;; Get lists of files with specified extensions
  (setq dwgFiles (list-files dwgDir "*.DWG"))
  (setq txtFiles (list-files dwgDir "*.TXT"))
  (setq csvFiles (list-files dwgDir "*.CSV"))
  (setq rvtFiles (list-files dwgDir "*.RVT"))
  (setq pngFiles (list-files dwgDir "*.PNG"))
  (setq jpgFiles (list-files dwgDir "*.JPG"))
  (setq xlsxFiles (list-files dwgDir "*.XLSX"))

  ;; Combine all file lists
  (setq allFiles (append dwgFiles txtFiles csvFiles rvtFiles jpgFiles pngFiles xlsxFiles))

  ;; Copy each file to the archive directory
  (foreach file allFiles
    (copy-file file (strcat foldername (vl-filename-base file) (vl-filename-extension file)))
  )
)

 

0 Likes
908 Views
9 Replies
Replies (9)
Message 2 of 10

paullimapa
Mentor
Mentor

So do all the lisp functions you posted work as desired?

If they do, you have all the code you need to generate your lisp to check for the latest folder date and then compared to the current date. What's the problem?


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 3 of 10

LDShaw
Collaborator
Collaborator

The parts are there I believe.
I create a list of folders I need dated.
I can find the date of any folder.

What I could not do is get the list I created, find the newest folder then compare it with todays date to see if it's older than two weeks. If it's newer then two weeks ask them if they really want to create another archive. 

0 Likes
Message 4 of 10

paullimapa
Mentor
Mentor

As you stated your c:ListFoldersInDir.lsp function should give you a list of folder names:

  ;; Get the list of folders
  (setq folders (list-folders archiveRootDir))

Assuming these folders are properly named using the 4 digit year - 2 digit month - 2 digit date format, then you can use the vl-sort function as shown here:

AutoCAD 2023 Developer and ObjectARX Help | vl-sort (AutoLISP) | Autodesk:

(setq folders (vl-sort folders '>)) ; sorts with latest date as first element

Next get the first element of this list which should be the folder with the latest date using car function:

(setq folders (car folders)) ; retrieve first element in list

Then reverse engineer the name of the folder back to something like the date format by converting the characters representing the year, month & date dropping the dashes "-" back to an integer like by using the strcat & substr functions: 

; assume folders is named like this: "2024-06-01"
; first drop the dashes to get "20240601":
(setq folders14 (strcat (substr folders 1 4) (substr folders 6 2) (substr folders 9 2)))
; convert string to integer to get: 20240601
(setq folders14 (atoi folders14)) 
; now add 14 more days to this number:
(setq folders14 (+ 14 folders14))

Now your C:dcarch.lsp function includes this section of the code to get the current date using the above format to to name a folder:

;; Get and format the current date
  (setq currentDate (rtos (getvar "cdate") 2 5))

But what you want is currentDate as a number and not a string:

;; Get the current date 
 (setq currentDate (getvar "cdate"))
;; convert from real number to integer dropping decimals:
 (setq currentDate (fix currentDate))

Finally just compare folders14 & currentDate using < or > depending on what results you're looking for to determine if folders14 is still a smaller number compared to the current date

 

 


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 5 of 10

paullimapa
Mentor
Mentor

I just thought of a minor glitch.

When 14 days is added to a folder like: 2023-12-29 the year, month & day are all impacted.

This is when you'll have to do more calculations to derive the proper folder date.

 


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 6 of 10

Sea-Haven
Mentor
Mentor
Message 7 of 10

paullimapa
Mentor
Mentor

Yes, excellent suggestion @Sea-Haven 

That means for @LDShaw 

1. load Express Tools julian.lsp

2. use the ctoj function to convert folder named as date to julian date ie:

(ctoj 2024 6 9 0 0 0) ; where 2024 is year, 6 is month of June & 9 is the 9th

3. then add 14 days

4a. if desired convert that back to calendar date using the jtoc function:

(jtoc (+ (ctoj 2024 6 9 0 0 0) 14)) ; returns list (2024 6 23 0 0 0.0)

5a.  1st item (nth 0) = year, 2nd item (nth 1) = month & 3rd item (nth 2) = date

Using this method will need to check 2nd item & 3rd item if single digit to add a 0 in front

 


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 8 of 10

LDShaw
Collaborator
Collaborator

Thank you so much for this. When I get a little time I will try your suggestions. Right now these are the parts created 

archive_and_save.lsp creates
fformat.png
ListFoldersInDir and archiveCreationDate
create this
.lisp.png
archiveCreationDate only creates the file date I ask for 

(setq dwgDir (getvar "dwgprefix"))
(setq archiveRootDir (strcat dwgDir "archive\\24-06-04\\"))

It does not get the list from ListFoldersInDir and dates all the files. That was just one of the parts I was have trouble with. I am not strong in creating and using lists in lisp. 

0 Likes
Message 9 of 10

paullimapa
Mentor
Mentor

Work through my replies and see if you can come up with what you need…cheers!!!


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 10 of 10

ronjonp
Mentor
Mentor

@LDShaw HERE is a function Lee wrote to subtract dates.

 

Have you thought about using ROBOCOPY for backing up files? It's very powerful.