view release on metacpan or search on metacpan
Revision history for Perl application BackupAndRestore.
0.011 Sa 21. Jun 10:07:09 CEST 2008
- added some information and reorder and clean up of folders
- added a test
- added -run; so you can now write 'use Application:BackupAndRestore -run;'
- correcly handling exit code 512; The 512 exit status means tar thinks
it failed for some reason. This could be caused by files with no permission.
- added drag an drop support for for exclude file and exclude folder widget
- added remove backup for last backup
- backup dialog is now of type notifiction
- added a Restore Backup Notification
0.010 Jan CEST 2007
- original version; created
bin/BackupAndRestore.glade view on Meta::CPAN
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
<!--*- mode: xml -*-->
<glade-interface>
<widget class="GtkWindow" id="window">
<property name="border_width">6</property>
<property name="title">Backup & Restore</property>
<property name="default_width">530</property>
<property name="default_height">600</property>
<signal name="destroy" handler="gtk_main_quit"/>
<child>
<widget class="GtkVBox" id="backup_and_restore_widget">
<property name="visible">True</property>
<property name="spacing">6</property>
<child>
<widget class="GtkFrame" id="frame2">
<property name="visible">True</property>
<property name="label_xalign">0</property>
<child>
<widget class="GtkAlignment" id="alignment2">
<property name="visible">True</property>
<child>
<widget class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<child>
<widget class="GtkExpander" id="backup_expander">
<property name="visible">True</property>
<property name="expanded">True</property>
<signal name="activate" handler="expander_nop"/>
<child>
<widget class="GtkVBox" id="vbox2">
<property name="visible">True</property>
<property name="border_width">12</property>
<property name="spacing">6</property>
<child>
<widget class="GtkHBox" id="folder_box">
bin/BackupAndRestore.glade view on Meta::CPAN
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkFileChooserButton" id="folder">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="has_focus">True</property>
<property name="action">GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER</property>
<signal name="selection_changed" handler="on_backup_folder_changed"/>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
bin/BackupAndRestore.glade view on Meta::CPAN
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox5">
<property name="visible">True</property>
<property name="spacing">6</property>
<child>
<widget class="GtkButton" id="backup_button">
<property name="visible">True</property>
<property name="label" translatable="yes">Backup</property>
<property name="use_underline">True</property>
<property name="response_id">0</property>
<signal name="clicked" handler="on_backup_button_clicked"/>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="restore_button">
<property name="visible">True</property>
<property name="sensitive">False</property>
bin/BackupAndRestore.glade view on Meta::CPAN
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox3">
<property name="visible">True</property>
<property name="spacing">6</property>
<child>
<widget class="GtkButton" id="backup_remove_button">
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="label" translatable="yes">gtk-delete</property>
<property name="use_stock">True</property>
<property name="response_id">0</property>
<signal name="clicked" handler="on_backup_remove_button_clicked"/>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label7">
<property name="visible">True</property>
<property name="xalign">0</property>
bin/BackupAndRestore.glade view on Meta::CPAN
</widget>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label6">
<property name="visible">True</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Restore backup from:</property>
</widget>
<packing>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label23">
<property name="visible">True</property>
<property name="xalign">1</property>
bin/BackupAndRestore.glade view on Meta::CPAN
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="restore_backup_from_label">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">label</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
</packing>
</child>
bin/BackupAndRestore.glade view on Meta::CPAN
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
</widget>
</child>
</widget>
<widget class="GtkDialog" id="backup_notification">
<property name="border_width">5</property>
<property name="title" translatable="yes">Backup in progress</property>
<property name="modal">True</property>
<property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
<property name="default_width">500</property>
<property name="default_height">180</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_NOTIFICATION</property>
<property name="transient_for">window</property>
<property name="has_separator">False</property>
<signal name="delete_event" handler="on_cancel_backup"/>
<child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox3">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK</property>
<property name="spacing">2</property>
<child>
<widget class="GtkFrame" id="frame1">
<property name="visible">True</property>
<property name="label_xalign">0</property>
<child>
bin/BackupAndRestore.glade view on Meta::CPAN
<property name="selectable">True</property>
</widget>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="backup_elapsed_time_label">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="selectable">True</property>
<property name="ellipsize">PANGO_ELLIPSIZE_START</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="backup_estimated_time_label">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="selectable">True</property>
<property name="ellipsize">PANGO_ELLIPSIZE_START</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
bin/BackupAndRestore.glade view on Meta::CPAN
<property name="selectable">True</property>
</widget>
<packing>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="backup_file_label">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="selectable">True</property>
<property name="ellipsize">PANGO_ELLIPSIZE_START</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
bin/BackupAndRestore.glade view on Meta::CPAN
<property name="xalign">1</property>
<property name="label" translatable="yes">Changed files:</property>
<property name="selectable">True</property>
</widget>
<packing>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="backup_folders_label">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="selectable">True</property>
<property name="ellipsize">PANGO_ELLIPSIZE_START</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="backup_changed_files_label">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="selectable">True</property>
<property name="ellipsize">PANGO_ELLIPSIZE_START</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
</packing>
</child>
<child>
<widget class="GtkProgressBar" id="backup_progressbar">
<property name="visible">True</property>
<property name="pulse_step">0</property>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
</widget>
</child>
</widget>
bin/BackupAndRestore.glade view on Meta::CPAN
<property name="layout_style">GTK_BUTTONBOX_END</property>
<child>
<placeholder/>
</child>
<child>
<widget class="GtkButton" id="button5">
<property name="visible">True</property>
<property name="label" translatable="yes">gtk-cancel</property>
<property name="use_stock">True</property>
<property name="response_id">0</property>
<signal name="clicked" handler="on_cancel_backup"/>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
</widget>
</child>
</widget>
<widget class="GtkDialog" id="remove_dialog">
<property name="border_width">5</property>
<property name="title" translatable="yes">Remove backup</property>
<property name="modal">True</property>
<property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
<property name="default_width">390</property>
<property name="default_height">100</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<property name="transient_for">window</property>
<property name="has_separator">False</property>
<signal name="delete_event" handler="on_backup_remove_dialog_cancel"/>
<child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox4">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK</property>
<property name="spacing">2</property>
<child>
<widget class="GtkFrame" id="frame3">
<property name="visible">True</property>
<property name="label_xalign">0</property>
<child>
bin/BackupAndRestore.glade view on Meta::CPAN
<property name="visible">True</property>
<property name="border_width">12</property>
<child>
<widget class="GtkHBox" id="hbox4">
<property name="visible">True</property>
<child>
<widget class="GtkLabel" id="label27">
<property name="visible">True</property>
<property name="xalign">1</property>
<property name="xpad">6</property>
<property name="label" translatable="yes">Remove backup from:</property>
</widget>
</child>
<child>
<widget class="GtkLabel" id="backup_remove_from_label">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">label</property>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkLabel" id="label28">
<property name="visible">True</property>
<property name="label" translatable="yes"><b>Remove backup</b></property>
<property name="use_markup">True</property>
</widget>
<packing>
<property name="type">label_item</property>
</packing>
</child>
</widget>
<packing>
<property name="position">1</property>
</packing>
bin/BackupAndRestore.glade view on Meta::CPAN
<widget class="GtkHButtonBox" id="dialog-action_area4">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<child>
<widget class="GtkButton" id="button7">
<property name="visible">True</property>
<property name="label" translatable="yes">gtk-ok</property>
<property name="use_stock">True</property>
<property name="response_id">0</property>
<signal name="clicked" handler="on_backup_remove_dialog_ok"/>
</widget>
</child>
<child>
<widget class="GtkButton" id="button6">
<property name="visible">True</property>
<property name="label" translatable="yes">gtk-cancel</property>
<property name="use_stock">True</property>
<property name="response_id">0</property>
<signal name="clicked" handler="on_backup_remove_dialog_cancel"/>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
bin/BackupAndRestore.glade view on Meta::CPAN
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label33">
<property name="visible">True</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Process backup:</property>
<property name="selectable">True</property>
</widget>
<packing>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="restore_process_backup_label">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="selectable">True</property>
<property name="ellipsize">PANGO_ELLIPSIZE_START</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
</packing>
</child>
lib/Applications/BackupAndRestore.pm view on Meta::CPAN
our $VERSION = 0.021;
our $DEBUG = 1;
=head1 NAME
Applications::BackupAndRestore - a linux frontend for tar
=head1 DESCRIPTION
BackupAndRestore is a backup utility for making incremental backups by using GNU Tar.
Core features:
=over
=item *
Incremental backup with quick and easy restoration of files
=item *
Handels different backup locations
=item *
Full support for excluding files and folders and even file patterns (shell regex)
=item *
Handels different store locations
=item *
Log with all relevant information
lib/Applications/BackupAndRestore.pm view on Meta::CPAN
=begin html
<img src="BackupAndRestore/pod/BackupAndRestore.png"><br>
=end html
=head1
To start up Backup & Restore from a terminal window, type B<BackupAndRestore> and then press C<Enter>.
Backup & Restore has a List View where you see every single backup with time, date, changed files and the exact space required on your harddrive.
Above the list view there is a File Chooser Button where you can select a folder to backup. Position the cursor over File Chooser Button and press the right mouse button. A pop-up menu appears. Choose a folder from the pop-up menu. Drag a folder ico...
Right hand to the File Chooser Button there is a Recycle Button. The recycle button keeps a list of folders you have saved. For example, place the cursor over the recycle button on a Backup & Restore window; then press the left mouse button to see a ...
Below the list view there is a backup button.
=head2 Backup In Progress Notification
The Backup In Progress Notification is illustrated in Figure 1-2.
=head3 Figure 1-2. Backup In Progress Notification
=begin html
<img src="BackupAndRestore/pod/BackupInProgressNotification.png"><br>
lib/Applications/BackupAndRestore.pm view on Meta::CPAN
#configure;
$this->restore_extract_modifiction_time->set_active(
defined $this->gconf("restore-extract-modification-time")
? $this->gconf("restore-extract-modification-time")
: 1
);
$this->restore_folder->set_current_folder( $this->gconf("restore-folder") || $ENV{HOME} );
$this->store_folder->set_current_folder( $this->gconf("store-folder") || $ENV{HOME} );
$this->store_folder_name->set_text( $this->gconf("store-folder-name") || "Backup" );
$this->folder->set_current_folder( $this->gconf("current-backup-folder") || $ENV{HOME} );
$this->configure_expander;
$this->build_tree;
$this->log_init;
$this->log_add_text( "*** $ApplicationName\n", "Version: $VERSION\n", "\n", );
$this->log_add_text( "*** ", $this->get_tar_version );
$this->{init} = FALSE;
lib/Applications/BackupAndRestore.pm view on Meta::CPAN
$tree_column->pack_start( $renderer, FALSE );
$tree_column->add_attribute( $renderer, text => COL_PATH );
#$tree_column->set_sort_column_id(COL_PATH);
#add $tree_column to the treeviewGtk2::CellRenderer
$tree_view->append_column($tree_column);
}
#backup
#
sub on_backup_folder_changed {
my ($this) = @_;
return unless $this->folder->get_filename;
return if abs_path( $this->folder->get_filename ) eq $this->gconf("current-backup-folder");
printf "on_backup_folder_changed %s\n", abs_path $this->folder->get_filename if $DEBUG > 0;
$this->gconf( "current-backup-folder", abs_path $this->folder->get_filename );
$this->fill_tree;
return;
}
sub on_folder_recycle_button {
my ($this) = @_;
return unless $this->{folder_recycle_button}->get_filename;
return if $this->folder->get_filename eq abs_path( $this->{folder_recycle_button}->get_filename );
lib/Applications/BackupAndRestore.pm view on Meta::CPAN
my $folder = $this->get_store_folder;
printf "fill_tree %s\n", $folder if $DEBUG > 0;
my $tree_store = Gtk2::TreeStore->new(@ColumnTypes);
if ( -e $folder ) {
my ( $day_iter, $day, $day_folder_size, $day_folder_real_size, $day_folder_files ) = ( undef, "", 0, 0, 0 );
my $current_dat = "$folder/$CurrentDat";
my $date_of_last_backup = $this->fetch_restore_date($folder);
#printf "%s\n", $date_of_last_backup;
my @filenames = reverse grep { m/\.tar\.bz2$/ } get_files($folder);
foreach my $filename (@filenames) {
# get basename
my $basename = basename( $filename, ".tar.bz2" );
# calculate size
my $tardat = "$folder/$basename.dat.bz2";
my $size = ( -s $filename ) + ( -s $tardat );
$size += -s $current_dat unless $day;
################################################################
my $infofile = "$folder/$basename.info.txt";
my $info = $this->get_backup_info( $filename, $infofile );
################################################################
# append day folder
my ( $date, $time ) = split / /o, $basename;
if ( $date ne $day ) {
$tree_store->set(
$day_iter,
(
COL_SIZE, $day_folder_size, COL_REAL_SIZE, $day_folder_real_size, COL_HSIZE,
( sprintf "%sB (%sB)", format_bytes($day_folder_size), format_bytes($day_folder_real_size) ),
lib/Applications/BackupAndRestore.pm view on Meta::CPAN
format_date($date),
COL_TIME, $time, COL_NAME, $time, COL_SIZE, $size,
COL_HSIZE,
( sprintf "%sB (%sB)", format_bytes($size), format_bytes( $info->{size} ) ),
COL_FILES,
scalar @{ $info->{files} },
COL_LABEL,
__("$info->{label}")
. ( "$info->{label}" ? ", " : "" )
. (
$date_of_last_backup eq $basename
? __("Last backup.")
: ""
),
COL_PATH,
$filename,
COL_LAST_BACKUP,
$date_of_last_backup eq $basename,
COL_WEIGHT,
800,
)
);
}
# append last day folder
$tree_store->set(
$day_iter,
(
lib/Applications/BackupAndRestore.pm view on Meta::CPAN
$this->size_all->set_text( format_bytes( folder_size($folder) ) );
#this will create a treeview, specify $tree_store as its model
$this->tree_view->set_model($tree_store);
$this->exclude_configure;
#$this->window->set_sensitive(TRUE);
}
sub get_backup_info {
my ( $this, $filename, $infoname ) = @_;
tie my %info, 'Tie::DataDumper', $infoname
or warn "Problem tying %info: $!";
$info{folders} = 0 unless exists $info{folders};
$info{files} = [] unless exists $info{files};
$info{label} = '' unless exists $info{label};
$info{size} = 0 unless exists $info{size};
lib/Applications/BackupAndRestore.pm view on Meta::CPAN
if ( $this->{tree_view_2button_press} ) # double click
{
my $path = $this->tree_view->get_model->get( $selected, COL_PATH );
printf "*** %s\n", $path if $DEBUG > 3;
system $TarOpenCmd, $path;
}
else {
my $last_backup = $this->tree_view->get_model->get( $selected, COL_LAST_BACKUP );
printf "*** %s\n", $last_backup ? 1 : 0 if $DEBUG > 3;
if ($last_backup) {
$this->backup_remove_button->set_sensitive(TRUE);
}
else {
$this->backup_remove_button->set_sensitive(FALSE);
}
}
}
return;
}
#backup
#
sub on_backup_button_clicked {
my ($this) = @_;
print "on_backup_button_clicked $this\n" if $DEBUG > 3;
$this->window->set_sensitive(FALSE);
$this->backup_changed_files_label->set_text(0);
$this->backup_folders_label->set_text(0);
$this->backup_elapsed_time_label->set_text( sprintf "%s", strtime(0) );
$this->backup_estimated_time_label->set_text( sprintf "%s / %s", map { strtime(0) } ( 0, 0 ) );
$this->backup_file_label->set_text("");
$this->backup_progress(0);
$this->backup_notification->present;
$this->backup_folder;
$this->{folder_recycle_button}->set_uri( $this->folder->get_uri );
$this->fill_tree;
$this->backup_notification->hide;
$this->window->set_sensitive(TRUE);
return;
}
sub rmdir_p {
my ($folder) = @_;
while ( rmdir $folder ) {
$folder = dirname $folder;
}
return;
}
sub backup_folder {
my ($this) = @_;
#$this->{backup_folder} = TRUE;
my $date = strftime( "%F %X", localtime );
$this->log_add_text( sprintf "\n%s\n", "*" x 42 );
$this->log_add_text( sprintf __("%s Starting backup . . .\n"), $date );
$this->backup_progress(0);
$this->backup_notification->{startTime} = time;
my $folder = abs_path $this->folder->get_filename;
my $store = $this->get_store_folder;
my $mainstore = $this->get_main_store_folder;
my $current_dat = "$store/$CurrentDat";
my $process_dat = "$store/$ProcessDat";
my $archive = "$store/$date.tar.bz2";
my $tardat = "$store/$date.dat.bz2";
my $excludes = "$store/$ExcludesFile";
my $first = -e $excludes;
$this->{cleanup} = sub {
print "cleanup backup @_\n" if $DEBUG > 3;
unlink $tardat;
unlink $process_dat;
unlink $archive;
unless ( -s $current_dat ) {
unlink $current_dat;
unlink $excludes;
rmdir_p $store;
}
if (@_) {
$this->gtk_main_quit;
lib/Applications/BackupAndRestore.pm view on Meta::CPAN
my $size = 1;
my $files = {};
my $total_size = 1;
my $folders = 0;
my $utf8 = Unicode::UTF8simple->new;
while (<TAR>) {
print $_ if $DEBUG > 3;
#last unless $this->{backup_folder};
chomp;
$_ = $utf8->fromUTF8( "iso-8859-1", $_ );
if (s|^\./||o) {
my $path = "$folder/$_";
if ( -d $path ) {
$this->backup_folders_label->set_text( ++$folders );
Gtk2->main_iteration while Gtk2->events_pending;
}
else {
unless ( exists $files->{$path} ) {
$total_size += $files->{$path} = ( -s $path ) || 0;
$this->backup_changed_files_label->set_text( sprintf "%d [%sB]", scalar keys %$files,
format_bytes($total_size) );
}
$files->{$path} = 0
unless defined $files->{$path}; # wegen: -s link = 0
my @times =
map { strtime($_) } estimated_time( $this->backup_notification->{startTime}, $size, $total_size );
$this->backup_elapsed_time_label->set_text( sprintf "%s", $times[0] );
$this->backup_estimated_time_label->set_text( sprintf "%s / %s", @times[ 1, 2 ] );
$this->backup_file_label->set_text( sprintf "%s [%sB]", $path, format_bytes( $files->{$path} ) );
$this->backup_progress( $size / $total_size );
$size += $files->{$path};
}
}
elsif ( m|^tar: \./(.*?): Directory is new$|o
|| m|^tar: \./(.*?): Directory has been renamed from.*$|o )
{
#print "$1\n" if $DEBUG > 3;
$files->{$_} = -s $_ foreach get_files("$folder/$1");
$total_size += folder_size("$folder/$1");
$this->backup_changed_files_label->set_text( sprintf "%d [%sB]", scalar keys %$files, format_bytes($total_size) );
Gtk2->main_iteration while Gtk2->events_pending;
}
elsif (/^(tar: ).*?(Warning:)/o) {
print "$_\n" if $DEBUG > 3;
$this->log_add_text( $_, "\n" );
}
elsif (/^(tar: )?(Terminated|Killed|Hangup)$/o) {
print "$_\n" if $DEBUG > 3;
$this->log_add_text( $_, "\n" );
}
lib/Applications/BackupAndRestore.pm view on Meta::CPAN
my $retval = system qq{ nice --adjustment=17 \\
bzip2 -c9 "$process_dat" > "$tardat" \\
};
printf "bzip2 returned %s\n", $retval if $DEBUG > 3;
$SIG{$_} = 'IGNORE' foreach @SIGS;
system "cp", $process_dat, $current_dat;
unlink $process_dat;
#store date of current backup
$this->store_restore_date($archive);
#store size
my $infofile = "$store/$date.info.txt";
my $info = $this->get_backup_info( $archive, $infofile );
$info->{label} = "First Backup" unless $first;
$info->{folders} = $folders;
$info->{files} = [ keys %$files ];
$info->{size} = $total_size;
tied(%$info)->save;
}
#$this->{backup_folder} = FALSE;
$this->{tarpid} = 0;
if ( $this->backup_notification->{startTime} ) {
$this->log_add_text( sprintf __("Changed files: %d\n"), scalar keys %$files );
$this->log_add_text( sprintf __("Folders: %d\n"), $folders );
$this->log_add_text( sprintf __("Total size: %s\n"), format_bytes($total_size) );
$this->log_add_text( sprintf __("Total time: %s\n"),
strtime( localtime( time - $this->backup_notification->{startTime} ) ) );
}
$this->log_add_text( sprintf __("%s Backup done.\n"), strftime( "%F %X", localtime ) )
if $this->backup_notification->{startTime};
$SIG{$_} = sub { $this->gtk_main_quit }
foreach @SIGS;
}
sub backup_progress {
my ( $this, $fraction ) = @_;
$this->backup_progressbar->set_fraction($fraction);
$this->backup_progressbar->set_text( sprintf "%.2f %%", $fraction * 100 );
#$this->backup_notification->set_title( sprintf "Backup in progress %.2f %%", $fraction * 100 );
Gtk2->main_iteration while Gtk2->events_pending;
return;
}
sub on_cancel_backup {
my ($this) = @_;
printf "on_cancel_backup %s\n", $this->{tarpid} if $DEBUG > 3;
system "pkill", "-P", $this->{tarpid};
$this->backup_notification->{startTime} = 0;
$this->backup_progressbar->set_fraction(1);
$this->backup_progressbar->set_text( __ "Canceling Backup ..." );
#$this->{backup_folder} = FALSE;
$this->log_add_text( sprintf __("%s Backup canceled.\n"), strftime( "%F %X", localtime ) );
return 1;
}
#exclude
#
sub exclude_configure {
my ($this) = @_;
lib/Applications/BackupAndRestore.pm view on Meta::CPAN
return;
}
sub on_restore_button_clicked {
my ($this) = @_;
print "on_restore_button_clicked $this\n" if $DEBUG > 3;
my $selected = $this->tree_view->get_selection->get_selected;
my ( $hdate, $time ) = $this->tree_view->get_model->get( $selected, COL_HDATE, COL_TIME );
$this->restore_backup_from_label->set_text("$hdate $time");
$this->window->set_sensitive(FALSE);
$this->restore_dialog->show;
return;
}
sub on_restore_dialog_cancel {
my ( $this, $widget ) = @_;
print "on_restore_folder_dialog_cancel $this\n" if $DEBUG > 3;
$this->restore_dialog->hide;
$this->window->set_sensitive(TRUE);
return 1;
}
sub on_restore_dialog_ok {
my ( $this, $widget ) = @_;
$this->restore_dialog->hide;
$this->restore_notification->show;
$this->restore_backup;
$this->fill_tree;
$this->restore_notification->hide;
$this->window->set_sensitive(TRUE);
return;
}
sub restore_backup {
my ($this) = @_;
my $restore_to_folder = abs_path $this->restore_folder->get_filename;
my @files = $this->get_files_to_restore;
$this->log_add_text( sprintf "\n%s\n", "*" x 42 );
$this->log_add_text( sprintf __("%s Starting restore . . .\n"), strftime( "%F %X", localtime ) );
$this->restore_progress(0);
$this->restore_notification->{startTime} = time;
my $store = $this->get_store_folder;
my $utf8 = Unicode::UTF8simple->new;
my $backup = 0;
my $counter = 0;
my $numFiles = 0;
my $size = 0;
my $elapsedSize = 0;
my $totalSize = 0;
foreach my $filename (@files) {
my $infofile = "$store/" . basename( $filename, ".tar.bz2" ) . ".info.txt";
my $info = $this->get_backup_info( $filename, $infofile );
$numFiles += @{ $info->{files} };
$totalSize += $info->{size};
$this->log_add_text( sprintf "%s %d\n", $infofile, $info->{size} );
}
$this->log_add_text( sprintf "total size %d\n", $totalSize );
printf "***restore_backup to folder: %s %d\n", $restore_to_folder, $totalSize
if $DEBUG > 3;
foreach my $filename (@files) {
printf "file: %s\n", $filename if $DEBUG > 3;
##########################################################################
my $infofile = "$store/" . basename( $filename, ".tar.bz2" ) . ".info.txt";
my $info = $this->get_backup_info( $filename, $infofile );
##########################################################################
$this->log_add_text( sprintf __("restoring backup from %s\n"), basename( $filename, ".tar.bz2" ) );
$this->restore_process_backup_label->set_text( sprintf __("%d / %d"), ++$backup, scalar @files );
Gtk2->main_iteration while Gtk2->events_pending;
my $touch =
$this->restore_extract_modifiction_time->get_active
? ""
: "--touch";
my $cmd = qq{ env LANG=en_GB.utf8 nice --adjustment=17 \\
env LANG=en_GB.utf8 tar --extract \\
--verbose \\
lib/Applications/BackupAndRestore.pm view on Meta::CPAN
$this->log_add_text( sprintf __("%s Restore canceled.\n"), strftime( "%F %X", localtime ) );
return 1;
}
sub restore_progress {
my ( $this, $fraction ) = @_;
$this->restore_progressbar->set_fraction($fraction);
$this->restore_progressbar->set_text( sprintf "%.2f %%", $fraction * 100 );
#$this->backup_notification->set_title( sprintf "Backup in progress %.2f %%", $fraction * 100 );
return;
}
# remove backup
#
sub on_backup_remove_button_clicked {
my ($this) = @_;
print "on_backup_remove_button_clicked $this\n" if $DEBUG > 3;
my $selected = $this->tree_view->get_selection->get_selected;
my ( $hdate, $time ) = $this->tree_view->get_model->get( $selected, COL_HDATE, COL_TIME );
$this->backup_remove_from_label->set_text("$hdate $time");
$this->window->set_sensitive(FALSE);
$this->remove_dialog->show;
return;
}
sub on_backup_remove_dialog_cancel {
my ( $this, $widget ) = @_;
print "on_restore_folder_dialog_cancel $this\n" if $DEBUG > 3;
$this->remove_dialog->hide;
$this->window->set_sensitive(TRUE);
return 1;
}
sub on_backup_remove_dialog_ok {
my ( $this, $widget ) = @_;
$this->remove_dialog->hide;
$this->remove_backup;
$this->fill_tree;
$this->window->set_sensitive(TRUE);
$this->backup_remove_button(FALSE);
return;
}
sub remove_backup {
my ($this) = @_;
my $restore_to_folder = abs_path $this->restore_folder->get_filename;
my @files = $this->get_files_to_restore;
my $selected = $this->tree_view->get_selection->get_selected;
my ( $hdate, $date, $time, $file ) = $this->tree_view->get_model->get( $selected, COL_HDATE, COL_DATE, COL_TIME, COL_PATH );
my $folder = dirname $file;
my $store = $this->get_store_folder;
$this->log_add_text( sprintf "\n%s\n", "*" x 42 );
$this->log_add_text( sprintf __("%s removing backup from %s %s\n"), strftime( "%F %X", localtime ), $hdate, $time );
{
my $archive = "$store/$date $time.tar.bz2";
my $tardat = "$store/$date $time.dat.bz2";
my $infofile = "$folder/$date $time.info.txt";
print "$archive\n";
print "$tardat\n";
print "$infofile\n";
lib/Applications/BackupAndRestore/Helper.pm view on Meta::CPAN
sum
format_date
get_files
get_all_sub_folders
folder_size
strtime
estimated_time
);
use POSIX qw(strftime mktime);
#use Locale::TextDomain ('backup-and-restore');
sub __ { shift @_ }
=functions
print sum(1,2,3); # 6
print format_date('2007-01-30'); # Heute, Gestern, Montag ..
print get_files('/'); # ('a.txt', 'bin') nicht rekursiv
print folder_size('/'); # 2345, (in Bytes) nicht rekursiv
print strtime(1234); # 00:11:08
my ($elapsed_time, $estimated_time, $total_time) =