Jump to content

Is this feasible for a script?


Recommended Posts

Greetings.

Short version:

I'd like to know if I can create a script that runs through a lot of folders and sub-folders, checking the contents of a lot of XML files. These XML files have a "variable" that allows me to tell which camera recorded the AVI file.

The purpose of running the script is to copy all the AVI files recorded from a given camera to a different folder for archiving purposes.

Long version:

I have this closed source application that receives video from 8 to 10 IP cameras and then creates 2 randomly named files every 5 or 10 minutes.

One of the files is an AVI (*.avi) and the other is an XML (*.xml).

The AVI carries the movie while the XML carries some details about the video such as date/time and which camera recorded that video.

File naming can look as cryptic as 580001000057637.avi and 580001000057637.xml.

It is not only the file naming that looks complex, the folder structure is also complex, at least for someone like me who doesn't know much about coding or scripting.

For instance, the main folder is 580001. This folder has no files in it, just another folder.

Inside 580001 there's a folder named 000. Folder 000 doesn't have any files in it too, just other folders.

Inside folder 000 there are 6 folders named 00, 01, 02, 03, 04 and 05. All these don't have any files in them too.

Any of these 6 folders has 100 folders names ranging from 00 to 99. These 100's of folders are the ones who actually have files in them.

So, the aforementioned file named 580001000057637.avi/.xml is stored in c:\580001\000\05\76.

Whenever folder c:\580001\000\05\76 has 100 files in it, it will automatically create a new folder called c:\580001\000\05\77.

Now, every XML file has information regarding the actual location where the AVI was recorded.

Opening with MS Wordpad, the XML structure looks like this:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<recording>
<dataformat>video</dataformat>
<starttime>2011-09-09 15:11:54:000 +0100</starttime>
<endtime>2011-09-09 15:14:03:000 +0100</endtime>
<nostart>false</nostart>
<noend>false</noend>
<servicename>323</servicename>
<servicenumber></servicenumber>
<deliberatebreak>0</deliberatebreak>
<calldirection>Incoming</calldirection>
<filename>580001000050000.avi</filename>
<otherinum>0</otherinum>
<recordingowners>
</recordingowners>
<parties>
<party id="1">
<pstarttime>2011-09-09 15:13:54:043 +0100</pstarttime>
<pendtime>2011-09-09 15:13:54:043 +0100</pendtime>
</party>
<party id="2">
<pstarttime>2011-09-09 15:13:54:043 +0100</pstarttime>
<pendtime>2011-09-09 15:13:54:043 +0100</pendtime>
</party>
</parties>
<guids>
</guids>
</recording>

The two interesting fields are:

<servicename>323</servicename>

and

<filename>580001000050000.avi</filename>

If the XML shows servicename=323 then I need to copy the file named 580001000050000.avi to a different folder.

Can this be done in AutoIt?

If so, can someone point me in the right direction, please?

Many thanks in advance.

Cheers

Edited by rds_correia
Link to comment
Share on other sites

  • Moderators

rds_correia,

The RecFileListToArray UDF in my sig will collect the names of all the .xml files within your rather convoluted tree structure. :rip:

You can then use FileRead to get the content of these files and then StringRegExp to extract servicename and filename - comparing servicename to the required value is trivial.

You can then use FileMove to move the .avi file in filename to another location. If the .avi file in the same location as the .xml file then that is simple; if not then you might need to scan the tree structure a second time to locate all .avi files and then search the resultant array.

Does that give you enugh to go on? :D

Why not give it a try yourself - you know where we are if you run into difficulties. :oops:

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Greetings Melba23,

I've tested a RecFileListToArray and it took a lot of time browsing through all my directories/files and during that time my CPU was running at 100%.

I guess I've got too many files to browse through...

I would like to minimize the impact of the script in terms of CPU usage. After all, it needs to be ready to take more recordings.

Important: my script's purpose is to filter recordings from the _last_couple_of_days_only.

Which means that I can start ignoring 5800010000000 through 5800010000575 and start focusing only on 5800010000576 and further.

But I will have to worry about 580001000 when 5800010009999 gets filled with 100 avi's.

Only then the system will create a 5800010010000.

And when 5800019999999 gets filled with 100 avi's then the system will create 5800020000000 and so on.

So I was thinking about this logic:

:start
$1st_folder=580001
$2nd_folder=000
$3rd_folder=05
$4th_folder=75

:check_1st_folder
if $1st_folder exists then
   if $1st_folder+1 exists then
      $1st_folder=$1st_folder+1
      goto :check_1st_folder
   else
   :check_2nd_folder
   if $2nd_folder exists then
      if $2nd_folder+1 exists then
         $2nd_folder=$2nd_folder+1
         goto :check_2nd_folder
      else
      :check_3rd_folder
      if $3rd_folder exists then
         if $3rd_folder+1 exists then
            $3rd_folder=$3rd_folder+1
            goto :check_3rd_folder
         else
         :check_4th_folder
         if $4th_folder exists then
            if $4th_folder+1 exists then
               $4th_folder=$4th_folder+1
               goto :check_4th_folder
            else
            START USING RECFILELISTTOARRAY USING THE LAST FOLDER FOUND BY THIS ROUTINE
         else
         display error "4th folder doesn't exist!"
      else
      display error "3rd folder doesn't exist!"
   else
   display error "2nd folder doesn't exist!"
else
display error "1st folder doesn't exist!"

What do you think?

I think this way I'd save some CPU cycles, right?

Being a total script-noob, could you help me with the code?

Thanks in advance.

Cheers

Link to comment
Share on other sites

  • Moderators

rds_correia,

I see your problem and I am working on it. Please be patient - I think I have a good handle on how to solve the problem but it needs a lot of testing to be sure it works. :D

Would you have a problem with saving a small file which holds details of the last file that was opened? That way we only open and examine files saved since then. :oops:

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

rds_correia,

Check this out http://msdn.microsoft.com/en-us/library/windows/desktop/aa365261(v=vs.85).aspx.

kylomas

Edit: Ther are also hits within the forums, in particular this link http://www.autoitscript.com/forum/index.php?showtopic=42511&st=0

Edit: Apologies, I forgot to include that this technique involves monitoring changes to a specific folder, or set of folders and if chaged, archive/copy the new/changed files. As opposed to spinning through files and programmatically moving/grouping them.

Edited by kylomas

Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Link to comment
Share on other sites

  • Moderators

rds_correia,

Have a try with this script and see how you get on. :D

First create a small file in the same folder as the script which looks like this:

580001
000
05
76
37

This is based on the example data you gave me - just adjust the values to match a suitable point in the tree structure. The final value is the index number of the final file you assume had been examined on teh last run - 580001000057637.xml. :)

The elements of this file determine the last file that was examined - the following script should examine all subsequent files created in the tree even if new folders have been created. Note we are only looking at the files in one folder at a time using _FileListToArray - this should speed things up a a lot: :oops:

#include <File.au3>
#include <Array.au3>

Global $aLast_Path

; Name of the file we save to hold the data of the last file examined
$sLast_Read = "Last Read.txt"

; Read the file into an array
_FileReadToArray(@ScriptDir & "" & $sLast_Read, $aLast_Path)

; Here we see the eleemnts of the last file examined on the last run
_ArrayDisplay($aLast_Path, "Current")

; As long as the last file examined did not end in 99 we need to examine the same folder for new files
If $aLast_Path[5] <> "99" Then
    ; So pass the path and file details to the function
    $iLast_File = List_Files($aLast_Path, $aLast_Path[5])
    ; And save the new file data
    $aLast_Path[5] = $iLast_File
EndIf

; If the final file ends in less than 99 there is still space in this folder so no point in looking further
; But if it does end in 99 we need to look further
If $aLast_Path[5] = "99" Then

    ; Create a new array to hold the path data
    $aNew_Path = $aLast_Path

    ; And now we look for any new folders in the series until we find one that does not exist
    While 1

        ; Add 1 to the folder and reset to 00 if needed
        $aNew_Path[4] = StringFormat("%02i", Mod($aNew_Path[4] + 1, 100))
        ; If we did reset to 00 then we need to check the level above
        If $aNew_Path[4] = "00" Then
            ; Again we add 1 and reset to 00 if required
            $aNew_Path[3] = StringFormat("%02i", Mod($aNew_Path[3] + 1, 100))
            ; And if we reset to 00 we need to check the level above
            If $aNew_Path[3] = "00" Then
                ; Add 1 but this time we reset to 000 if required
                $aNew_Path[2] = StringFormat("%03i", Mod($aNew_Path[2] + 1, 1000))
                ; And again we move up a level if the lower folder was reset
                If $aNew_Path[2] = "000" Then
                    ; If this one gets to 589999 then you need to restart - or add another level to this tree!
                    $aNew_Path[1] = $aNew_Path[1] + 1
                EndIf
            EndIf
        EndIf

        ; Now see if this path exists
        $sNew_Path = "C:" & _ArrayToString($aNew_Path, "", 1, 4) & ""
        If FileExists($sNew_Path) Then
            ; If it does we save it to write to disk as the new start point
            ;ConsoleWrite("Looking at " & $sNew_Path    & @CRLF)
            $aLast_Path = $aNew_Path
            ; We pass the path to the function - note no file data passed as we are going to start at 00
            $iLast_File = List_Files($aNew_Path)
            ; And save the numbe rof the last file examined
            $aLast_Path[5] = $iLast_File
        Else
            ; If the path does not exist then we exit the loop
            ExitLoop
        EndIf

    WEnd

EndIf

; Here we see the elements of the final file that was examined
_ArrayDisplay($aLast_Path)

; This can be saved to disk to act as the start point for the next search

; This is the function that searches within the files - note the start is at 00 if no parameter passed
Func List_Files($aPath, $sStart = "00")

    ; Create the path and filename from the passed parameters
    $sPath = "C:" & _ArrayToString($aPath, "", 1, 4) & ""
    $sFile = $sPath & _ArrayToString($aPath, "", 1, 4) & $sStart & ".xml"
    ; Get a list of all the files matching our search in the folder
    $aFile_List = _FileListToArray($sPath & "", "*.xml", 1)

    ;_ArrayDisplay($aFile_List, $sStart)

    ; Now we see if we start at 00 or further in
    If $sStart = "00" Then
        ; If we start at 00 we examine all the files found
        For $j = 1 To $aFile_List[0]
            ; Pass the filename to the function
            Examine_File($sPath & $aFile_List[$j])
            $sFile_Treated = $aFile_List[$j]
        Next
    Else
        ; If we have already examined some of the files in this folder we find how far we have already been
        For $i = 1 To $aFile_List[0]
            If $sPath & $aFile_List[$i] = $sFile Then
                ExitLoop
            EndIf
        Next
        ; And then examine the files from then on
        For $j = $i + 1 To $aFile_List[0]
            ; Pass the filename to the function
            Examine_File($sPath & $aFile_List[$j])
            $sFile_Treated = $aFile_List[$j]
        Next

    EndIf

    ; Finally we extract and return the last 2 digits of the filename so we know how far we have read in this folder
    Return StringRegExpReplace($sFile_Treated, ".*(d{2}).xml", "$1")

EndFunc

Func Examine_File($sFile)

    ; Read the content of the file
    $sFile_Content = FileRead($sFile)
    ; Extract the data we require
    $aData = StringRegExp($sFile_Content, "(?i)(?U)name>(.*)<", 3)
    ; And display it
    MsgBox(0, "Data", "Extracting from file: " & $sFile & @CRLF & @CRLF & _
                      @TAB & "Servicename: " & @TAB & $aData[0] & @CRLF & _
                      @TAB & "Filename:    " & @TAB & $aData[1])

EndFunc

SRE explanation:

(?i)   - Case insensitive (you never know!)
(?U)   - Shortest match
name>  - Look for this text
(.*)   - Capture all text afterwards
<      - Until we find this

3      - Get an array of all matches

At the moment we make no changes to the small file which details the last file examined - we can do that when we know the script works. Similarly we do nothing with the data we extract from the file - other than display it to see if it is what we want. :D

Give this a try and see if it extracts the data correctly from the files following the one set in the small data file. If it does we can look to refining it to do exactly what you want. :rip:

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Hi Melba23,

Thank you very much for your help.

I have tried your script on my server.

First it displays a window named "Current" which shows a list of the items that I have copied to the "Last Read.txt" file.

And then it crashes with an error message saying:

Line 96 (File "c:\script\test.au3"):
For $i=1 To $aFile_List[0]
For $i=1 To $aFile_List^ Error
Error: subscript used with non-Array variable

Plus, yesterday I was thinking about the script and I noticed that I forgot to mention one thing important: in the future, when I run the script I want to see all the video recordings from the previous day.

But, the previous day video recordings can be archived across two or more folders...

They could be 580001\000\05\73\580001000057381.avi till 580001\000\05\75\580001000057523.avi

Which means that, when I run my script, I immediately want to find the last folder.

Then I want to check if that folder has recordings from the previous day.

If so, then I want to mark that folder for further usage.

Then I want to check if the previous folder has recordings from the previous day.

If so, then I want to mark that folder for further usage, and so on.

When I hit a folder that doesn't have recordings from the previous day, then I stop looking for more previous folders.

Then I take the folders previously marked for further usage and I check all the XML files on them.

I want to mark all the files with XML references from the previous day and with XML references of the camera that I want to inspect.

This can be done checking the <starttime></starttime> and the <servicename></servicename> fields in the XML files.

Now that I have the recordings from that particular day and from that particular camera, now I can copy the corresponding AVI files to a separate directory.

Thanks a lot for all the help your giving me.

Cheers

Link to comment
Share on other sites

  • Moderators

rds_correia,

That error means you have no files in a folder - which according to what you told me earlier should never happen. :oops:

And I see you are changing the goalposts in mid-match. :D

Ah well - let us see what we can do now. However, we shall proceed in small steps. :(

Based on your new request, try running this script and see if it works for you as well it works for me when I test it. It should work its way through the tree starting at "C:5800010000000" and find the last created folder in the sequence you described - these folders are then displayed in a dialog. Please check to see if the list is complete and the final folder displayed is indeed the final one in your tree. :rip:

The script then lists the .xml files within these folders - starting with the last created and working backwards. You will see either a dialog displaying the files or a MsgBox telling you there are no files is that folder. You can easily stop the script at this point so you do not have to wait for all the folder to be listed! :)

#include <Array.au3>
#include <File.au3>

Global $aPath[5] = [4, "580001", "000", "00", "00"]

; Find last folder
$aFolder_List = _Last_Folder($aPath)

_ArrayDisplay($aFolder_List)

; Work backwards through the folder list
For $i = $aFolder_List[0] To 1 Step -1
    ; Read the list of files in this folder
    $aFile_List = _FileListToArray($aFolder_List[$i] & "", "*.xml", 1)
    If IsArray($aFile_List) Then
        _ArrayDisplay($aFile_List, $aFolder_List[$i])
    Else
        MsgBox(0, "Error", "No files found in" & @CRLF & $aFolder_List[$i])
        Exit
    EndIf
Next

Func _Last_Folder($aPath)

    ; Create an array to hold the list of folders found
    Local $aFolders[100] = [1, "C:" & _ArrayToString($aPath, "", 1, 4) & ""]

    While 1

        ; Add 1 to the folder and reset to 00 if needed
        $aPath[4] = StringFormat("%02i", Mod($aPath[4] + 1, 100))
        ; If we did reset to 00 then we need to check the level above
        If $aPath[4] = "00" Then
            ; Again we add 1 and reset to 00 if required
            $aPath[3] = StringFormat("%02i", Mod($aPath[3] + 1, 100))
            ; And if we reset to 00 we need to check the level above
            If $aPath[3] = "00" Then
                ; Add 1 but this time we reset to 000 if required
                $aPath[2] = StringFormat("%03i", Mod($aPath[2] + 1, 1000))
                ; And again we move up a level if the lower folder was reset
                If $aPath[2] = "000" Then
                    ; If this one gets to 589999 then you need to restart - or add another level to this tree!
                    $aPath[1] = $aPath[1] + 1
                EndIf
            EndIf
        EndIf

        ; Now see if this path exists
        $sNext_Path = "N:" & _ArrayToString($aPath, "", 1, 4) & ""
        If Not FileExists($sNext_Path) Then
            ; If the path does not exist then we return the list of folders found
            ReDim $aFolders[$aFolders[0] + 1]
            Return $aFolders
        Else
            ; The folder exists so add it to the array - resizing if necessary
            $aFolders[0] += 1
            If UBound($aFolders) <= $aFolders[0] Then
                ReDim $aFolders[$aFolders[0] * 2]
            EndIf
            $aFolders[$aFolders[0]] = $sNext_Path
        EndIf

    WEnd

EndFunc

I hope you do not see the MsgBox as that would mean that I have misunderstood everything you have told me about the way the folder structure is created. :(

Let me know how it works. :D

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Hi Melba23,

Once again, thanks a lot for your help.

I have tested your last script and I got a MsgBox.

But I have possibly found the issue.

I failed to tell you the FULL path where my cameras are recording.

It is not c:5800010000000580001000000000(..99).avi.

Instead it it c:surveillance5800010000580001000000000(..99).avi.

Maybe your scripts are assuming a full path, right?

My bad, I'm awfully sorry.

Cheers

Link to comment
Share on other sites

  • Moderators

rds_correia,

I failed to tell you the FULL path where my cameras are recording

:D

Try this version: :rip:

#include <Array.au3>
#include <File.au3>

Global $aPath[5] = [4, "580001", "000", "00", "00"]

; Find last folder
$aFolder_List = _Last_Folder($aPath)

_ArrayDisplay($aFolder_List)

; Work backwards through the folder list
For $i = $aFolder_List[0] To 1 Step -1
    ; Read the list of files in this folder
    $aFile_List = _FileListToArray($aFolder_List[$i] & "\", "*.xml", 1)
    If IsArray($aFile_List) Then
        _ArrayDisplay($aFile_List, $aFolder_List[$i])
    Else
        MsgBox(0, "Error", "No files found in" & @CRLF & $aFolder_List[$i])
        Exit
    EndIf
Next

Func _Last_Folder($aPath)

    ; Create an array to hold the list of folders found
    Local $aFolders[100] = [1, "C:\surveillance\" & _ArrayToString($aPath, "\", 1, 4) & "\"]

    While 1

        ; Add 1 to the folder and reset to 00 if needed
        $aPath[4] = StringFormat("%02i", Mod($aPath[4] + 1, 100))
        ; If we did reset to 00 then we need to check the level above
        If $aPath[4] = "00" Then
            ; Again we add 1 and reset to 00 if required
            $aPath[3] = StringFormat("%02i", Mod($aPath[3] + 1, 100))
            ; And if we reset to 00 we need to check the level above
            If $aPath[3] = "00" Then
                ; Add 1 but this time we reset to 000 if required
                $aPath[2] = StringFormat("%03i", Mod($aPath[2] + 1, 1000))
                ; And again we move up a level if the lower folder was reset
                If $aPath[2] = "000" Then
                    ; If this one gets to 589999 then you need to restart - or add another level to this tree!
                    $aPath[1] = $aPath[1] + 1
                EndIf
            EndIf
        EndIf

        ; Now see if this path exists
        $sNext_Path = "C:\surveillance\" & _ArrayToString($aPath, "\", 1, 4) & "\"
        If Not FileExists($sNext_Path) Then
            ; If the path does not exist then we return the list of folders found
            ReDim $aFolders[$aFolders[0] + 1]
            Return $aFolders
        Else
            ; The folder exists so add it to the array - resizing if necessary
            $aFolders[0] += 1
            If UBound($aFolders) <= $aFolders[0] Then
                ReDim $aFolders[$aFolders[0] * 2]
            EndIf
            $aFolders[$aFolders[0]] = $sNext_Path
        EndIf

    WEnd

EndFunc

Does it work now? :oops:

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

  • Moderators

rds_correia,

Good! :D

And now the next step. Now we read the camera and date values from within the .xml files to see if we need to deal with the associated .avi file. Try running this script - you should see the camera and YYYY-MM-DD date for each file appear in the MsgBox:

#include <Array.au3>
#include <File.au3>

Global $aPath[5] = [4, "580001", "000", "00", "00"]

; Find last folder
$aFolder_List = _Last_Folder($aPath)

;_ArrayDisplay($aFolder_List)

; Work backwards through the folder list
For $i = $aFolder_List[0] To 1 Step -1
    ; Read the list of files in this folder
    $aFile_List = _FileListToArray($aFolder_List[$i] & "", "*.xml", 1)

    _ArrayDisplay($aFile_List, $aFolder_List[$i])

    If IsArray($aFile_List) Then
        _Check_Files($aFile_List, $aFolder_List[$i] & "")
    Else
        MsgBox(0, "Error", "No files found in" & @CRLF & $aFolder_List[$i])
        Exit
    EndIf
Next


Func _Check_Files($aArray, $sPath)

    For $i = $aArray[0] To 1 Step -1

        ; Read the content of the file
        $sFile_Content = FileRead($sPath & $aArray[$i])
        ; Extract the data we require

        ; Is it the correct camera
        $aCamera = StringRegExp($sFile_Content, "(?i)(?U)servicename>(.*)<", 3)
        ; And date
        $aDate = StringRegExp($sFile_Content, "(?i)(?U)starttime>(.*)x20", 3)
        ; And display it
        MsgBox(0, "Data", "Extracting from file: " & $aArray[$i] & @CRLF & @CRLF & _
                          @TAB & "Camera: " & @TAB & $aCamera[0] & @CRLF & _
                          @TAB & "Date  : " & @TAB & $aDate[0])
    Next

EndFunc

Func _Last_Folder($aPath)

    ; Create an array to hold the list of folders found
    Local $aFolders[100] = [1, "C:surveillance" & _ArrayToString($aPath, "", 1, 4) & ""]

    While 1

        ; Add 1 to the folder and reset to 00 if needed
        $aPath[4] = StringFormat("%02i", Mod($aPath[4] + 1, 100))
        ; If we did reset to 00 then we need to check the level above
        If $aPath[4] = "00" Then
            ; Again we add 1 and reset to 00 if required
            $aPath[3] = StringFormat("%02i", Mod($aPath[3] + 1, 100))
            ; And if we reset to 00 we need to check the level above
            If $aPath[3] = "00" Then
                ; Add 1 but this time we reset to 000 if required
                $aPath[2] = StringFormat("%03i", Mod($aPath[2] + 1, 1000))
                ; And again we move up a level if the lower folder was reset
                If $aPath[2] = "000" Then
                    ; If this one gets to 589999 then you need to restart - or add another level to this tree!
                    $aPath[1] = $aPath[1] + 1
                EndIf
            EndIf
        EndIf

        ; Now see if this path exists
        $sNext_Path = "C:surveillance" & _ArrayToString($aPath, "", 1, 4) & ""
        If Not FileExists($sNext_Path) Then
            ; If the path does not exist then we return the list of folders found
            ReDim $aFolders[$aFolders[0] + 1]
            Return $aFolders
        Else
            ; The folder exists so add it to the array - resizing if necessary
            $aFolders[0] += 1
            If UBound($aFolders) <= $aFolders[0] Then
                ReDim $aFolders[$aFolders[0] * 2]
            EndIf
            $aFolders[$aFolders[0]] = $sNext_Path
        EndIf

    WEnd

EndFunc

If this works we can run a couple of tests against these values to confirm that they are yesterday's files from the correct camera and then extract the .avi name for further treatment. :oops:

I presume you are intending to create a GUI to wrap all this later on and that will include some way of defining the camera ID. I will hard code it for the moment - the date is trivial to obtain. :rip:

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

the date is trivial to obtain. :D

You're not thinking of reading the xml timestamp, are you?

Because the files timestamps and the actual recording date/time can actually differ by several hours.

The avi and the xml both come from remote servers that send these files to a centralized server that stores them using this cryptic file/folder scheme.

If a link between a remote server and the the centralized server goes offline, then xml+avi timestamps will be all wrong.

Let me try your last script and I'll report back in a couple of minutes.

Cheers

Link to comment
Share on other sites

  • Moderators

rds_correia,

You're not thinking of reading the xml timestamp, are you?

I was going to use the

<STARTTIME>2011-09-09 15:11:54:000 +0100</STARTTIME>

data from the file. If that is not the correct date, then which bit of the file data does hold the correct data? :D

M23

Edit: I am assuming that omnce I hit the first file with the day before yesterday's date we can abandon the search. Is that a valid assumption in your rather wacky world of files? :oops:

Edited by Melba23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

I was going to use the

<STARTTIME>2011-09-09 15:11:54:000 +0100</STARTTIME>

data from the file. If that is not the correct date, then which bit of the file data does hold the correct data? :D

That's perfect.

That's the only place where we can be sure about the video recording date/time.

On my last post I was talking about the avi/xml timestamp (the one you can see in Windows File Explorer) :oops:.

Edit: I am assuming that omnce I hit the first file with the day before yesterday's date we can abandon the search. Is that a valid assumption in your rather wacky world of files? :)

Well...you've brought up an interesting question...

I'm not sure.

I would guess that a day can be broken in two just because of the link-down issue that I just told you right above.

But for now, let's just ignore that possibility.

If that actually happens, it will only be a couple of times and it will be ok to search/copy the files manually instead of using the script :rip:.

I'm curious about your last script.

Apparently it ran fine.

I'm just wondering what you mean by "extracting file ...".

Was it really copying stuff? If so, where to?

Other than that, it seemed like it did exactly what we were hoping for.

Thanks a bunch.

Cheers

Link to comment
Share on other sites

I presume you are intending to create a GUI to wrap all this later on and that will include some way of defining the camera ID. I will hard code it for the moment - the date is trivial to obtain. :oops:

In fact I intend to write a small GUI to wrap it up.

Maybe with Koda? What do you advise?

A real bonus would be being able to choose multiple cameras at once.

A range like 320..329.

But I wasn't born to code so it will take time, lot's of time :D.

Cheers

Link to comment
Share on other sites

  • Moderators

rds_correia,

Looks like we might be in business! :D

Here is the next stage - extracting the .avi name ready for you copy it elsewhere: :rip:

#include <Array.au3>
#include <File.au3>
#include <Date.au3>

Global $aPath[5] = [4, "580001", "000", "00", "00"]
Global $sCamera_ID = "323"
Global $sYesterday = StringReplace(_DateAdd("D", -1, @YEAR & "/" & @MON & "/" & @MDAY), "/", "-")
Global $sBefore_Yesterday = StringReplace(_DateAdd("D", -2, @YEAR & "/" & @MON & "/" & @MDAY), "/", "-")

; Find last folder
$aFolder_List = _Last_Folder($aPath)

; Work backwards through the folder list
For $i = $aFolder_List[0] To 1 Step -1
    ; Read the list of files in this folder
    $aFile_List = _FileListToArray($aFolder_List[$i] & "", "*.xml", 1)

    ;_ArrayDisplay($aFile_List, $aFolder_List[$i])

    If IsArray($aFile_List) Then
        If _Check_Files($aFile_List, $aFolder_List[$i]) Then
            ; We have reached the files from 2 days ago
            ExitLoop
        EndIf
    Else
        ; There are no files to check - this should never happen
        ExitLoop
    EndIf
Next

MsgBox(0, "Done", "All files from " & $sYesterday & @CRLF & "taken by camera " & $sCamera_ID & @CRLF & "have been dealt with")

Func _Check_Files($aArray, $sPath)

    ; Clear the "day before yesterday" flag
    $fEnded = False

    For $i = $aArray[0] To 1 Step -1

        ; Read the content of the file
        $sFile_Content = FileRead($sPath & $aArray[$i])
        ; Is it the correct date
        $aDate = StringRegExp($sFile_Content, "(?i)(?U)starttime>(.*)x20", 3)
        Switch $aDate[0]
            Case $sYesterday
                ; Is it the correct camera
                $aCamera = StringRegExp($sFile_Content, "(?i)(?U)servicename>(.*)<", 3)
                If $aCamera[0] = $sCamera_ID Then
                    ; Extract the .avi name
                    $aAVI = StringRegExp($sFile_Content, "(?i)(?U)filename>(.*)<", 3)

                    ; And display the data
                    ConsoleWrite("File: " & $sPath & $aArray[$i] & @CRLF)
                    ConsoleWrite(@TAB & "Avi: " & $sPath & $aAVI[0] & @CRLF & @TAB & " could now be copied" & @CRLF)

                EndIf
            Case $sBefore_Yesterday
                ; Set the flag
                $fEnded = True
                ; No point in going back further
                ExitLoop
        EndSwitch
    Next

    Return $fEnded

EndFunc

Func _Last_Folder($aPath)

    ; Create an array to hold the list of folders found
    Local $aFolders[100] = [1, "C:surveillance" & _ArrayToString($aPath, "", 1, 4) & ""]

    While 1

        ; Add 1 to the folder and reset to 00 if needed
        $aPath[4] = StringFormat("%02i", Mod($aPath[4] + 1, 100))
        ; If we did reset to 00 then we need to check the level above
        If $aPath[4] = "00" Then
            ; Again we add 1 and reset to 00 if required
            $aPath[3] = StringFormat("%02i", Mod($aPath[3] + 1, 100))
            ; And if we reset to 00 we need to check the level above
            If $aPath[3] = "00" Then
                ; Add 1 but this time we reset to 000 if required
                $aPath[2] = StringFormat("%03i", Mod($aPath[2] + 1, 1000))
                ; And again we move up a level if the lower folder was reset
                If $aPath[2] = "000" Then
                    ; If this one gets to 589999 then you need to restart - or add another level to this tree!
                    $aPath[1] = $aPath[1] + 1
                EndIf
            EndIf
        EndIf

        ; Now see if this path exists
        $sNext_Path = "C:surveillance" & _ArrayToString($aPath, "", 1, 4) & ""
        If Not FileExists($sNext_Path) Then
            ; If the path does not exist then we return the list of folders found
            ReDim $aFolders[$aFolders[0] + 1]
            Return $aFolders
        Else
            ; The folder exists so add it to the array - resizing if necessary
            $aFolders[0] += 1
            If UBound($aFolders) <= $aFolders[0] Then
                ReDim $aFolders[$aFolders[0] * 2]
            EndIf
            $aFolders[$aFolders[0]] = $sNext_Path
        EndIf

    WEnd

EndFunc

Is that what you wanted? :oops:

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Looks like we might be in business! :D

Wooohoooo :D:)

Here is the next stage - extracting the .avi name ready for you copy it elsewhere: :rip:

...

Is that what you wanted? :oops:

What? Having a list of avi files that I can later copy to a folder? Sure! That's exactly what I'm looking for.

Let me try your last script and I'll report back.

Cheers

Link to comment
Share on other sites

  • Moderators

rds_correia,

Having a list of avi files that I can later copy to a folder?

I think it would be more elegant to copy them as you find them - why make a list and then rerun it? :oops:

As to the GUI - please do try and code something yourself. But you know where we are if you run into trouble. :D

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...