Synchroniseur de fichier

Partagez votre expérience de PureBasic avec les autres utilisateurs.
kwandjeen
Messages : 204
Inscription : dim. 16/juil./2006 21:44

Synchroniseur de fichier

Message par kwandjeen »

Je travaille pas tout le temps sur le même ordinateur et donc sur clef USB.
Pour m'y retrouver et synchroniser mon travail avec mon ordinateur personnel je me suis fait un petit synchroniseur.
Comme c'est un outils perso ce n'est pas très peaufiné et je vais à l'essentiel.
Le code est très certainement perfectible mais cela peut toujours aider.

Il prend les drag&drop pour la sélection des dossiers
F1 pour tout sélectionner ou déselectionner sur la liste du dossier 1
F2 pour la même chose sur le dossier 2
Dans les listes, couleur rouge pour fichier absent et couleur verte pour fichier présent mais à mettre à jour.
Pour le reste ça coule de source je pense.
N'hésitez pas à modifier/améliorer ;)

Code : Tout sélectionner

Enumeration #PB_Compiler_EnumerationValue
  #Window_0
  #Window_copy
EndEnumeration

Enumeration #PB_Compiler_EnumerationValue
  #Entry_chemin1
  #Entry_chemin2
  #bouton_analyse
  #bouton_parcourir_dossier1
  #bouton_parcourir_dossier2
  #option_mode_0
  #option_mode_1
  #Option_mode_2
  #Option_mode_3
  #Option_mode_4
  #Option_mode_5
  #list_1
  #list_2
  #bouton_synchroniser
  #Check_affichage_liste
  #ProgressBar_copy
  #Text_window_copy
  #Text_window_copy_2
  
  #all_select_gauche
  #all_select_droite
EndEnumeration

Structure item_fichier
  nom.s
  parent.s
  destination.s
  maj.b
EndStructure

Global NewList fichier.item_fichier()

Global chemin_dossier1$
Global chemin_dossier2$
Global memo_mode

Declare scan_dossier(chemin1$,chemin2$,dossier_base$,mode=0)
Declare scan_dossier2(chemin1$,chemin2$,dossier_base$,mode=0)
Declare verif_mode()
Declare _copy_file(liste.i,chemin$)

Procedure OpenWindow_0()
  OpenWindow(#Window_0, 0, 0, 800, 660, "SynchronX", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_SizeGadget | #PB_Window_ScreenCentered)
  StringGadget(#Entry_chemin1, 10, 190, 290, 20, "")
  StringGadget(#Entry_chemin2, 500, 190, 290, 20, "")
  ButtonGadget(#bouton_analyse, 540, 80, 140, 30, "Analyse")
  GadgetToolTip(#bouton_analyse, "Analyse aucun fichier ne sera copiés avant la synchronisation")
  ButtonGadget(#bouton_parcourir_dossier1, 310, 185, 80, 30, "Parcourir")
  ButtonGadget(#bouton_parcourir_dossier2, 410, 185, 80, 30, "Parcourir")
  OptionGadget(#option_mode_0, 20, 0, 310, 30, "Copie les fichiers inexistants sur les 2 dossiers")
  SetGadgetState(#option_mode_0, 1)
  OptionGadget(#option_mode_1, 20, 30, 330, 30, "Copie les fichiers récents et inexistants sur les 2 dossiers")
  OptionGadget(#Option_mode_2, 20, 60, 310, 30, "Copie les fichiers inexistants sur le dossier 2 seulement")
  OptionGadget(#Option_mode_3, 20, 90, 370, 30, "Copie les fichiers récents et inexistants sur le dossier 2 seulement")
  OptionGadget(#Option_mode_4, 20, 120, 400, 30, "Copie les fichiers inexistants sur le dossier 1 seulement")
  OptionGadget(#Option_mode_5, 20, 150, 390, 30, "Copie les fichiers récents et inexistant sur le dossier 1 seulement")
  ListIconGadget(#list_1,10,220,380,430,"Dossier 1",500,#PB_ListIcon_CheckBoxes)  
  ListIconGadget(#list_2,410,220,380,430,"Dossier 2",500,#PB_ListIcon_CheckBoxes)
  ButtonGadget(#bouton_synchroniser, 540, 130, 140, 30, "Synchroniser")
  GadgetToolTip(#bouton_synchroniser, "Lance la synchronisation des fichiers")
  CheckBoxGadget(#Check_affichage_liste, 540, 30, 120, 30, "Affichage liste")
  SetGadgetState(#Check_affichage_liste, #PB_Checkbox_Checked)
  EnableGadgetDrop(#Entry_chemin1,#PB_Drop_Files,#PB_Drag_Link)
  EnableGadgetDrop(#Entry_chemin2,#PB_Drop_Files,#PB_Drag_Link)
  EnableGadgetDrop(#list_1,#PB_Drop_Files,#PB_Drag_Link)
  EnableGadgetDrop(#list_2,#PB_Drop_Files,#PB_Drag_Link)
  AddKeyboardShortcut(#Window_0,#PB_Shortcut_F1,#all_select_gauche)
  AddKeyboardShortcut(#Window_0,#PB_Shortcut_F2,#all_select_droite)
EndProcedure

Procedure.s get_nom_du_dernier_dossier(chemin_complet$)
  Protected nb_chaine
  nb_chaine=CountString(chemin_complet$,"\")
  If Right(chemin_complet$,1)="\"
    nb_chaine-1
  EndIf
  ProcedureReturn StringField(chemin_complet$,nb_chaine+1,"\")
EndProcedure

Procedure verif_presence_dossier()
  If PathIsDirectory_(chemin_dossier1$)=0
    MessageRequester("Attention","Il semble que le dossier 1 : "+chemin_dossier1$+" n'existe pas"+Chr(10)+Chr(13)+"Veuillez vérifier les chemins des dossiers")
    memo_mode = -1
    ProcedureReturn 0
  EndIf
  If PathIsDirectory_(chemin_dossier2$)=0
    MessageRequester("Attention","Il semble que le dossier 2 : "+chemin_dossier2$+" n'existe pas"+Chr(10)+Chr(13)+"Veuillez vérifier les chemins des dossiers")
    memo_mode = -1
    ProcedureReturn 0
  EndIf
  ProcedureReturn 1
EndProcedure

Procedure scan_dossier(chemin1$,chemin2$,dossier_base$,mode=0)
  If Right(chemin1$,1)<>"\"
    chemin1$ = chemin1$+"\"
  EndIf
  If Right(chemin2$,1)<>"\"
    chemin2$ = chemin2$+"\"
  EndIf
  exam = ExamineDirectory(#PB_Any,chemin1$,"*.*")
  While NextDirectoryEntry(exam)
    Select DirectoryEntryType(exam)
      Case #PB_DirectoryEntry_File
        file_dir2$ = chemin2$+RemoveString(chemin1$,dossier_base$,0,1,1)+DirectoryEntryName(exam)
        If PathFileExists_(file_dir2$)=0
          AddElement(fichier())
          fichier()\nom = DirectoryEntryName(exam)
          fichier()\parent = chemin1$
          fichier()\destination = chemin2$+RemoveString(chemin1$,dossier_base$,0,1,1)
        ElseIf mode=1
          If DirectoryEntryDate(exam,#PB_Date_Modified)>GetFileDate(file_dir2$,#PB_Date_Modified)
            If DirectoryEntryDate(exam,#PB_Date_Modified)-GetFileDate(file_dir2$,#PB_Date_Modified)>2
              AddElement(fichier())
              fichier()\nom = DirectoryEntryName(exam)
              fichier()\parent = chemin1$
              fichier()\destination = chemin2$+RemoveString(chemin1$,dossier_base$,0,1,1)
              fichier()\maj = 1
            EndIf
          EndIf
        EndIf
      Case #PB_DirectoryEntry_Directory
        If DirectoryEntryName(exam)<>"." And DirectoryEntryName(exam)<>".."
          dir2$ = chemin2$+RemoveString(chemin1$,dossier_base$,0,1,1)+DirectoryEntryName(exam)
          scan_dossier(chemin1$+DirectoryEntryName(exam),chemin2$,dossier_base$,mode)
        EndIf
    EndSelect
  Wend
  FinishDirectory(exam)
EndProcedure

Procedure _copy_file(liste.i,chemin$)
  Protected fin_de_chemin$,nb_occurence,memo_chemin$
  If PathIsDirectory_(chemin$)=0
    MessageRequester("Attention","Le dossier "+chemin$+" n'existe pas la mise à jour va être arrêtée")
    ProcedureReturn 0
  EndIf
  For i=0 To CountGadgetItems(liste)-1
    If  GetGadgetItemState(liste,i) = #PB_ListIcon_Checked
      ChangeCurrentElement(fichier(),GetGadgetItemData(liste,i))
      SetGadgetText(#Text_window_copy,"Copie de "+fichier()\parent+fichier()\nom)
      SetGadgetText(#Text_window_copy_2,"Vers "+fichier()\destination+fichier()\nom)
      fin_de_chemin$ = Mid(fichier()\destination,Len(chemin$))
      nb_occurence = CountString(Mid(fichier()\destination,Len(chemin$)),"\")
      If nb_occurence>1
        memo_chemin$ = ""
        For gg=2 To nb_occurence
          memo_chemin$ + StringField(fin_de_chemin$,gg,"\")+"\"
          If PathIsDirectory_(chemin$+memo_chemin$)=0
            CreateDirectory(chemin$+memo_chemin$)
          EndIf
        Next gg
      EndIf
      If PathIsDirectory_(fichier()\destination)=0
        CreateDirectory(fichier()\destination)
      EndIf
      CopyFile(fichier()\parent+fichier()\nom,fichier()\destination+fichier()\nom)
      If fichier()\maj=0
        SetFileDate(fichier()\destination+fichier()\nom,#PB_Date_Modified,GetFileDate(fichier()\parent+fichier()\nom,#PB_Date_Modified))
      EndIf
      SetGadgetState(#ProgressBar_copy,ListIndex(fichier()))
    EndIf
  Next
EndProcedure

Procedure copy_file()
  If verif_mode()<>memo_mode
    MessageRequester("Attention","Les options ont changées, vous devez relancer l'analyse.")
  Else
    If verif_presence_dossier() = 0
      ProcedureReturn 0
    EndIf
    If ListSize(fichier())>0
      OpenWindow(#Window_copy, 0, 0, 500, 150, "Synchronisation en cours", #PB_Window_ScreenCentered)
      ProgressBarGadget(#ProgressBar_copy, 10, 100, 480, 40, 0, ListSize(fichier()), #PB_ProgressBar_Smooth)
      TextGadget(#Text_window_copy, 20, 10, 460, 40, "")
      TextGadget(#Text_window_copy_2,20,60,460,40,"")
      _copy_file(#list_1,chemin_dossier1$)
      _copy_file(#list_2,chemin_dossier2$) 
      CloseWindow(#Window_copy)
      MessageRequester("Synchronisation terminée","La synchronisation est terminée")
    EndIf
  EndIf
EndProcedure

Procedure verif_mode()
  Protected mode.b
  mode = GetGadgetState(#option_mode_0)
  mode+(GetGadgetState(#option_mode_1)*2)
  mode+(GetGadgetState(#option_mode_2)*3)
  mode+(GetGadgetState(#option_mode_3)*4)
  mode+(GetGadgetState(#option_mode_4)*5)
  mode+(GetGadgetState(#option_mode_5)*6)
  ProcedureReturn mode
EndProcedure

Procedure analyse(chemin1$,chemin2$)
  Protected mode.b,nb_maj.l,nb_ajout.l
  If verif_presence_dossier() = 0
    ProcedureReturn 0
  EndIf
  mode = verif_mode()
  memo_mode = mode
  OpenWindow(#Window_copy, 0, 0, 200, 60, "Analyse en cours", #PB_Window_ScreenCentered)    
  ClearList(fichier())
  Select mode
    Case 1 ;on copie les fichiers inexistant sur les 2 dossiers
      TextGadget(#Text_window_copy, 30, 15, 460, 30, "Scan du dossier 1")
      scan_dossier(chemin1$,chemin2$,chemin_dossier1$,0)
      TextGadget(#Text_window_copy, 30, 15, 460, 30, "Scan du dossier 2")
      scan_dossier(chemin2$,chemin1$,chemin_dossier2$,0)
    Case 2 ;on copie les fichiers récent et inexsitant sur les 2 dossiers
      TextGadget(#Text_window_copy, 30, 15, 460, 30, "Scan du dossier 1")
      scan_dossier(chemin1$,chemin2$,chemin_dossier1$,1)
      TextGadget(#Text_window_copy, 30, 15, 460, 30, "Scan du dossier 2")
      scan_dossier(chemin2$,chemin1$,chemin_dossier2$,1)
    Case 3;on copie les fichiers inexistant sur le dossier 2
      TextGadget(#Text_window_copy, 30, 15, 460, 30, "Scan du dossier 1")
      scan_dossier(chemin1$,chemin2$,chemin_dossier1$,0)
    Case 4 ;on copie les fichiers récent et inexistant sur le dossier 2
      TextGadget(#Text_window_copy, 30, 15, 460, 30, "Scan du dossier 1")
      scan_dossier(chemin1$,chemin2$,chemin_dossier1$,1)
    Case 5 ;on copie les fichiers inexistant sur le dossier 1
      TextGadget(#Text_window_copy, 30, 15, 460, 30, "Scan du dossier 2")
      scan_dossier(chemin2$,chemin1$,chemin_dossier2$,0)
    Case 6 ;on copie les fichiers récents sur le dossier 1
      TextGadget(#Text_window_copy, 30, 15, 460, 30, "Scan du dossier 2")
      scan_dossier(chemin2$,chemin1$,chemin_dossier2$,1)
  EndSelect
  ClearGadgetItems(#list_1)
  ClearGadgetItems(#list_2)
  TextGadget(#Text_window_copy, 20, 15, 460, 30, "Remplissage des listes. Patientez")
  If GetGadgetState(#Check_affichage_liste)
    ForEach fichier()
      If fichier()\maj
        texte$ = "Mise à jour "+fichier()\parent+fichier()\nom
        couleur_font = RGB(0, 161, 77)
        nb_maj+1
      Else
        texte$ = "Ajout "+fichier()\parent+fichier()\nom
        couleur_font = RGB(238, 125, 48)
        nb_ajout+1
      EndIf
      If FindString(fichier()\destination,chemin_dossier2$)
        AddGadgetItem(#list_2,-1,texte$)
        SetGadgetItemColor(#list_2,CountGadgetItems(#list_2)-1,#PB_Gadget_FrontColor, couleur_font)
        SetGadgetItemData(#list_2,CountGadgetItems(#list_2)-1,@fichier())
      Else
        AddGadgetItem(#list_1,-1,texte$)
        SetGadgetItemColor(#list_1,CountGadgetItems(#list_1)-1,#PB_Gadget_FrontColor, couleur_font)
        SetGadgetItemData(#list_1,CountGadgetItems(#list_1)-1,@fichier())
      EndIf
    Next
  EndIf
  CloseWindow(#Window_copy)
  If ListSize(fichier())=0
    MessageRequester("Analyse terminée","Les dossiers sont à jour en regard des options choisies")
  Else    
    If ListSize(fichier())>1
      texte$ = Str(ListSize(fichier()))+" fichiers impactés"+#CRLF$
    Else
      texte$ = Str(ListSize(fichier()))+" fichier impacté"+#CRLF$ 
    EndIf
    If nb_ajout>1
      texte$+Str(nb_ajout)+" fichiers seront ajoutés"+#CRLF$
    Else
      texte$+Str(nb_ajout)+" fichier sera ajouté"+#CRLF$
    EndIf
    If nb_maj>1
      texte$+Str(nb_maj)+" fichiers seront mis à jour"+#CRLF$
    Else                
      texte$+Str(nb_maj)+" fichier sera mis à jour"+#CRLF$
    EndIf
    MessageRequester("Analyse terminée",texte$)
  EndIf
EndProcedure

Procedure all_select_liste(gadget.i)
  Static mode1,mode2
  Protected mselect
  Select gadget
    Case #list_1
      If mode1 = #PB_ListIcon_Checked
        mode1 = 0
      Else
        mode1 = #PB_ListIcon_Checked
      EndIf
      mselect = mode1
    Case #list_2
      If mode2 = #PB_ListIcon_Checked
        mode2 = 0
      Else
        mode2 = #PB_ListIcon_Checked
      EndIf
      mselect = mode2
  EndSelect
  For i=0 To CountGadgetItems(gadget)-1
    SetGadgetItemState(gadget,i,mselect)
  Next
EndProcedure

;-BOUCLE PRINCIPALE
OpenWindow_0()
Repeat
  event = WaitWindowEvent()
  gevent = EventGadget()
  Select event
    Case #PB_Event_CloseWindow
      End
    Case #PB_Event_Menu
      Select EventMenu()
        Case #all_select_gauche
          all_select_liste(#list_1)
        Case #all_select_droite
          all_select_liste(#list_2)
      EndSelect
    Case #PB_Event_GadgetDrop
      If gevent = #Entry_chemin1 Or gevent = #list_1
        chemin_dossier1$ = EventDropFiles()
        SetGadgetText(#Entry_chemin1,chemin_dossier1$)
      EndIf
      If gevent = #Entry_chemin2 Or gevent = #list_2  
        chemin_dossier2$ = EventDropFiles()
        SetGadgetText(#Entry_chemin2,chemin_dossier2$)
      EndIf
    Case #PB_Event_Gadget
      Select gevent
        Case #bouton_parcourir_dossier1
          chemin_dossier1$ = PathRequester("Choisissez un dossier","")
          SetGadgetText(#Entry_chemin1,chemin_dossier1$)
        Case #bouton_parcourir_dossier2
          chemin_dossier2$ = PathRequester("Choisissez un dossier","")
          SetGadgetText(#Entry_chemin2,chemin_dossier2$)
        Case #bouton_analyse
          If chemin_dossier1$<>"" And chemin_dossier2$<>""
            analyse(chemin_dossier1$,chemin_dossier2$)
          Else
            MessageRequester("Attention","Vous devez sélectionner deux dossiers.")
          EndIf
        Case #bouton_synchroniser
          copy_file()
      EndSelect
  EndSelect
ForEver