Category: desenvolvimento

Backup File Utility in Python [Tkinter application]

Hi readers,

This is a graphic software (tkinter) in Python to back up a file on your computer. A backup folder is created in the current directory of the selected file and then every x minutes a backup of the file is done, respecting the maximum number of files in the backup directory.





import xxhash, time, shutil, os, threading
from datetime import datetime
from Tkinter import Label, Spinbox, Listbox, Scrollbar, Tk, E, W, S, N, Button, Frame
import tkFileDialog
from os.path import expanduser

class App(Frame):
    def __init__(self, parent):

        Frame.__init__(self, parent)
        self.parent = parent

        # Class Variables
        self.directory_selected = ''
        self.filename_selected = ''
        self.backup_folder_name = 'backup'
        self.num_max_files = None
        self.time_for_backup = None
        self.full_file_path = ''
        self.backup_running = False
        self.hash = None


    def initUI(self):
        self.parent.title("Application to Backup a File")

        self.label_minutes = Label(text='Time for Backup (Minutes): ', height=2)
        self.spinbox_minutes = Spinbox(from_=1, to=100, width=5)
        self.spinbox_minutes.delete(0, 'end')
        self.spinbox_minutes.insert(0, 5)

        self.label_numfiles = Label(text='Maximum number files in backup directory: ')
        self.spinbox_numfiles = Spinbox(from_=1, to=100, width=5)
        self.spinbox_numfiles.delete(0, 'end')
        self.spinbox_numfiles.insert(0, 10)

        self.scrollbar_loglist = Scrollbar()
        self.listbox_loglist = Listbox(yscrollcommand=self.scrollbar_loglist.set, width=70)

        self.button_file_choose = Button(text='Choose a file for backup ...', command=self.click_button_start_backup)
        self.button_stop_backup = Button(text='Stop Backup', command=self.click_button_stop_backup)
        self.button_stop_backup['state'] = 'disabled'
        self.button_exit = Button(text='Exit', command=self.click_button_exit)

        # Here the UI components are designed using grid layout
        self.label_minutes.grid(row=0, sticky=E)
        self.spinbox_minutes.grid(row=0, column=1, sticky=W)
        self.label_numfiles.grid(row=1, sticky=E)
        self.spinbox_numfiles.grid(row=1, column=1, sticky=W)
        self.listbox_loglist.grid(row=2, column=0, sticky=W + E + N + S, columnspan=3)
        self.scrollbar_loglist.grid(row=2, column=3, sticky=N + S)
        self.button_file_choose.grid(row=3, column=0)
        self.button_stop_backup.grid(row=3, column=1)
        self.button_exit.grid(row=3, column=2)

        # define options for opening or saving a file
        self.file_opt = options = {}
        options['initialdir'] = expanduser("~")
        options['parent'] = self
        options['title'] = 'Select a file for backup ...'

    def get_ask_open_file(self):
        return tkFileDialog.askopenfilename(**self.file_opt)

    def get_current_datetime(self):
        return datetime.strftime(, "%d%m%Y_%H%M%S")

    def get_current_datetime_formatted(self):
        return datetime.strftime(, "[%d/%m/%Y %H:%M:%S] - ")

    def log_action(self, msg):
        self.listbox_loglist.insert(0, self.get_current_datetime_formatted() + msg)

    def do_file_backup(self):
        curr_datetime = self.get_current_datetime()
        nom_arquivo = self.filename_selected.split('.')[0] + '_' + curr_datetime + '.' + \
                        self.directory_selected + os.sep + self.backup_folder_name + os.sep + nom_arquivo)
        self.log_action('Backup Done - ' + nom_arquivo)

    def get_file_hash_md5(self, file):
        BLOCKSIZE = 65536
        hasher = xxhash.xxh32()
        with open(file, 'rb') as afile:
            buf =
            while len(buf) > 0:
                buf =
        return hasher.hexdigest()

    def listdir_fullpath(self, d):
        return [os.path.join(d, f) for f in os.listdir(d)]

    def delete_oldest_files(self):
        num_total_files_in_directory = len(
            self.listdir_fullpath(self.directory_selected + os.sep + self.backup_folder_name))
        num_files_to_be_removed = num_total_files_in_directory - self.num_max_files
        if num_files_to_be_removed > 0:
            self.log_action('Removing ' + str(num_files_to_be_removed) + ' old files')
        for i in range(num_files_to_be_removed):
            file_to_remove = self.get_oldest_file_from_directory(
                self.directory_selected + os.sep + self.backup_folder_name)
            self.log_action('An old file was removed - ' + file_to_remove.split(os.sep)[-1])

    def get_oldest_file_from_directory(self, dir):
        return min(self.listdir_fullpath(dir), key=os.path.getctime)

    def start_loop_backup_job(self):
        if not self.backup_running:
        if self.hash != self.get_file_hash_md5(self.full_file_path):
            self.log_action('The file was not changed since last check')
        self.hash = self.get_file_hash_md5(self.full_file_path)
        self.parent.after(self.time_for_backup * 1000 * 60, self.start_loop_backup_job)

    def click_button_start_backup(self):
        file_choosed = self.get_ask_open_file()
        if not os.path.isfile(file_choosed):
        self.log_action('Backup has been started')
        self.backup_running = True
        self.button_file_choose['state'] = 'disabled'
        self.button_stop_backup['state'] = 'normal'
        self.directory_selected = os.path.split(os.path.abspath(file_choosed))[0]
        self.filename_selected = os.path.split(os.path.abspath(file_choosed))[1]
        self.full_file_path = self.directory_selected + os.sep + self.filename_selected

        if not os.path.exists(self.directory_selected + os.sep + self.backup_folder_name):
            os.mkdir(self.directory_selected + os.sep + self.backup_folder_name)

        self.time_for_backup = int(self.spinbox_minutes.get())
        self.num_max_files = int(self.spinbox_numfiles.get())

        self.backup_running = True

    def click_button_stop_backup(self):
        self.button_file_choose['state'] = 'normal'
        self.button_stop_backup['state'] = 'disabled'
        self.log_action('Backup has been stopped')
        self.backup_running = False

    def click_button_exit(self):

def main():
    root = Tk()
    root.eval('tk::PlaceWindow %s center' % root.winfo_pathname(root.winfo_id()))
    app = App(root)

if __name__ == '__main__':



Python – Unique Collection Class – HashCode and Equals – (Like Java Set)

Hi readers,

I will demonstrate in this post as we do in Python to have a collection of single objects (Set), implementing the standard methods key, hashcode and equals, so that the objects are not repeated.

class MyCustomClass:
    def __init__(self, at1, at2, at3):
        self.at1 = at1
        self.at2 = at2
        self.at3 = at3
    def __key(self):
        return (self.at2)
    def __eq__(x, y):
        return x.__key() == y.__key()
    def __hash__(self):
        return hash(self.__key())

my_object_1 = MyCustomClass('1', '2', '3')
my_object_2 = MyCustomClass('4', '5', '6')
my_object_3 = MyCustomClass('7', '8', '9')
my_object_2_dup = MyCustomClass('4', '5', '6')

set_collection = set()


for object in set_collection:
    print object.at2

The output of this script is:

Note that i added 4 objects, but only three is added because the second attribute is the Key.

See You,
Victor Jabur

TDC Florianópolis – 2014

Boa Noite Galera:

Desejo a todos um excelente evento e boas palestras.

Obrigado ao Vinicius Senger e a Yara por promover eventos de tão elevada qualidade para os devs brasileros.

Parabéns !!!

Evento TDC2014

Victor Jabur