Code covered by the BSD License  

Highlights from
Recycle Bin

from Recycle Bin by Fahad Al Mahmood
Works like (delete) for files except for moving files to selected folder with restoring.

trash(varargin)
function trash(varargin)

%TRASH works like (delete) for files except for moving files to selected (Recycle Bin) folder with restoring option.
%
% trash file(s)        moves file(s) to Recycle Bin folder,
%                      (Recycle Bin folder will be created if necessary). 
% trash file(s) flag    
%                       FLAG can be:
%                       -ls   : lists contents of Recycle Bin.
%                       -r    : restores selected file to original directory.
%                               Wildcard works only when no multiple copies of same
%                               file are trashed.
%                       -rc   : restore file(s) to current directory.
%                               Wildcard works only when no multiple copies of same
%                               file are trashed.
%                       -e    : deletes files from Recycle Bin folder and deletes
%                               the folder afterwards if all files are deleted.
%                       -o    : deletes older versions of specified trashed file (no wildcard allowed)
%                       -log  : view "trash.log" file.
%                       -size : displays number of objects & total size
%
% trash   : works like (delete) except for moving files to selected (Recycle
%           Bin) folder.  If not specified, the default (Recycle Bin)
%           folder will be created in current directory.
%
% NOTES:     * Make sure you specify the path of your Recycle Bin folder by editing
%              the first line of the script!
%            * wildcard can be used for trashing files, trash options (ls), but
%               NOT (old).  For restore, wildcard works only if no multiple
%               copies of same file are trashed.
%            * this program has been tested only on (Windows) but not on (UNIX)!
%           
% Examples:
% 
%   trash myfile.m                  % Trashing one file.
%   trash myfile.m myotherfile.exe  % Trashing 2 files 
%   trash -ls                       % Listing files in Recycle Bin
%   trash *.exe -ls                 % Listing files in trash with extention (exe)
%   trash file.xls -o     % Deleting old versions of (file.xls) and keeping the latest one.
%   trash *.exe -r        % Restoring (*.exe) to original directory.
%   trash myfile.m -rc    % Restoring (myfile.m) to current directoty.
%   trash -e              % Emptying Recycle Bin
%   trash file.m -e       % Deleting (file.m) from Recycle Bin
%   trash -size           % Displaying number of files & total size in Recycle Bin

%   Copyright 2004 Fahad Al Mahmood
%   Version: 1.0 $  $Date: 30-Apr-2004
%   Version: 1.1 $  $Date: 30-Apr-2004 (Option for viewing log file added)
%   Version: 1.3 $  $Date: 03-May-2004 (Now keeps copy of old trashed files with same name
%                                       while being able to restore them)
%   Version: 1.5 $  $Date: 04-Jun-2004 (Added size feature + Fixed restore log bug)


%--------------------------------------------------------------
% Edit the following line to specify your (Recycle Bin) folder.
%--------------------------------------------------------------
Recycle_Bin_Directory = 'D:\Data\Fahad Almahmood\MATLAB\work\Recycle Bin';

current_path = pwd;
[target_path,Recycle_Bin_Name] = fileparts(Recycle_Bin_Directory);

%------------------------------
% Creating (Recycle Bin) folder
%------------------------------
if ~exist(Recycle_Bin_Directory,'dir')
    success = mkdir(Recycle_Bin_Directory);
    if ~success
        [Status, OSMessage] = dos(['mkdir "' Recycle_Bin_Directory '"']);
        if Status
            error(['Could not create directory (' Recycle_Bin_Directory ')']);
        end
    end

end

%--------------------------------------------------
% If (trash file(s) -e) is entered, do the following ...
%--------------------------------------------------
if strmatch(lower(varargin{end}),'-e','exact')

    full_list = {[]};
    k=1;
    for n=1:length(varargin)-1
        if ~isempty(findstr(varargin{n},'*'))
            WF = wildfiles([Recycle_Bin_Directory filesep varargin{n}]);
            full_list = [full_list WF];
        else
            full_list = [full_list varargin(n)];
        end
    end
    if ~iscell(full_list)
        full_list={full_list};
    else 
        full_list = full_list(2:end);
    end
    
    % if (trash -e) is specified
    if length(varargin)==1
        delete([Recycle_Bin_Directory  filesep '*.*']);
    end
    
    for n=1:length(full_list)
        % Storing (trash.log) lines in a cell array (log_lines)
        % & locating line containing file to be restored 
        fid3 = fopen([Recycle_Bin_Directory filesep 'trash.log'],'r');
        line_counter = 1;
        line = fgetl(fid3);
        while line~=-1
            log_lines{line_counter} = line;
            x = findstr(line,full_list{n});
            if x==1 & length(x)==1
                f_loc(k) = line_counter;
                k=k+1;
            end
            line = fgetl(fid3);
            line_counter = line_counter + 1;
        end
        fclose(fid3);
        
        % Deleting trashed file
        delete([Recycle_Bin_Directory filesep log_lines{f_loc(end)}]);
        
        % Rewriting (trash.log) after taking out the lines of restored file
        fileattrib([Recycle_Bin_Directory filesep 'trash.log'],'-h');
        fid4 = fopen([Recycle_Bin_Directory filesep 'trash.log'],'w');
        for g=1:4:length(log_lines)
            if isempty(intersect(g,f_loc(end-1)))
                fprintf(fid4,'%s\n%s\n%s\n%s\n',log_lines{g},log_lines{g+1},log_lines{g+2},log_lines{g+3});
            end
        end
        fclose(fid4);  
        fileattrib([Recycle_Bin_Directory filesep 'trash.log'],'+h');
        clear f_loc log_lines;        
    end
    
    %----------------------------------------------------
    % If (trash file(s) -r) or (trash file(s) -rc) is entered, do the following ...
    %----------------------------------------------------
elseif ~isempty(strmatch(lower(varargin{end}),'-r','exact')) | ~isempty(strmatch(lower(varargin{end}),'-rc','exact'))

    full_list = [];
    for n=1:length(varargin)-1
        if ~isempty(findstr(varargin{n},'*'))
            WF = wildfiles([Recycle_Bin_Directory filesep varargin{n}]);
            full_list = [full_list WF];
        else
            full_list = [full_list varargin{n}];
        end
    end
    if ~iscell(full_list)
        full_list={full_list};
    end
    current = 0;
    if ~isempty(strmatch(varargin{end},'-rc'))
        current = 1;
    end
    if ~iscell(full_list)
        full_list={full_list};
    end
    k=1;
    for n=1:length(full_list)
        % Storing (trash.log) lines in a cell array (log_lines)
        % & locating line containing file to be restored 
        fid3 = fopen([Recycle_Bin_Directory filesep 'trash.log'],'r');
        line_counter = 1;
        line = fgetl(fid3);
        while line~=-1
            log_lines{line_counter} = line;
            x = findstr(line,full_list{n});
            if x==1 & length(x)==1
                f_loc(k) = line_counter;
                k=k+1;
            end
            line = fgetl(fid3);
            line_counter = line_counter + 1;
        end
        fclose(fid3);
        
        % Moving trashed file to its original directory
        source = [Recycle_Bin_Directory filesep log_lines{f_loc(end)}];
        destination = [log_lines{f_loc(end)+1} filesep log_lines{f_loc(end)-1}];
        if current
            destination = [current_path filesep log_lines{f_loc(end)-1}];
        end
        success = movefile(source,destination);
        if ~success
            [Status, OSMessage] = dos(['move /y "'  source '" "'  destination '"']);
            if Status
                error(['Could not restore (' full_list{n} ') or it does not exist in (' Recycle_Bin_Directory ')']);
            end        
        end
        
        % Rewriting (trash.log) after taking out the lines of restored file
        fileattrib([Recycle_Bin_Directory filesep 'trash.log'],'-h');
        fid4 = fopen([Recycle_Bin_Directory filesep 'trash.log'],'w');
        for g=1:4:length(log_lines)
            if isempty(intersect(g,f_loc(end-1)))
                fprintf(fid4,'%s\n%s\n%s\n%s\n',log_lines{g},log_lines{g+1},log_lines{g+2},log_lines{g+3});
            end
        end
        fclose(fid4);  
        fileattrib([Recycle_Bin_Directory filesep 'trash.log'],'+h');
        clear f_loc log_lines;        
    end
    
    %-------------------------
    % If (trash -ls) is entered
    %-------------------------
elseif strmatch(lower(varargin{end}),'-ls','exact')
    if length(varargin)==2
        ls([Recycle_Bin_Directory filesep varargin{n}]);
    elseif length(varargin)==1
        ls(Recycle_Bin_Directory);
    end
    
    %--------------------------
    % If (trash -log) is entered
    %--------------------------
elseif strmatch(lower(varargin{end}),'-log','exact')
    if exist([Recycle_Bin_Directory filesep 'trash.log'],'file')
        edit([Recycle_Bin_Directory filesep 'trash.log']);  
    else
        disp('No Log Found!');
    end
 
    %--------------------------
    % If (trash -size) is entered
    %--------------------------
elseif strmatch(lower(varargin{end}),'-size','exact')
    RB = dir(Recycle_Bin_Directory);
    bytes = 0;
    disp(' ')
    for n=1:size(RB,1);
        if isempty(strmatch(RB(n).name,'trash.log'))
            bytes = bytes + RB(n).bytes;
        end
        text = sprintf('%-20s \t %-10d \t %s',RB(n).name,RB(n).bytes,RB(n).date);
        disp(text)
    end
    disp(' ')
    RB(n+1).name = 'TOTAL';
    RB(n+1).bytes = bytes;
    text = sprintf('%-20s \t %-10d \t',RB(n+1).name,RB(n+1).bytes);
    disp(text)
    
    %--------------------------
    % If (trash file -o) is entered   
    %--------------------------
elseif strmatch(lower(varargin{end}),'-o','exact')
    for n=1:length(varargin)-1
        k=1;
        if ~isempty(findstr(varargin{n},'*'))
            error(['file (' varargin{n} ') cannot contain (*) wildcard']);
        end
        
        % Storing (trash.log) lines in a cell array (log_lines)
        % & locating line containing file to be restored 
        
        fid3 = fopen([Recycle_Bin_Directory filesep 'trash.log'],'r');
        line_counter = 1;
        line = fgetl(fid3);
        while line~=-1
            log_lines{line_counter} = line;
            x = findstr(line,varargin{n});
            if x==1 & length(x)==1
                f_loc(k) = line_counter;
                k=k+1;
            end
            line = fgetl(fid3);
            line_counter = line_counter + 1;
        end
        fclose(fid3);
        
        if ~exist('f_loc','var')
            error(['No older versions of (' varargin{n} ') found']);
        end
        
        % Deleting older versions of trashed files
        for t=1:2:length(f_loc)-2
            old_file = [Recycle_Bin_Directory filesep log_lines{f_loc(t+1)}];
            try
                delete(old_file);
            catch
                [Status, OSMessage] = dos(['del /f "'  old_file '"']);
                if Status
                    error(['Could not delete (' old_file ') or it does not exist in (' Recycle_Bin_Directory ')']);
                end        
            end
        end
        old_file = [Recycle_Bin_Directory filesep log_lines{f_loc(end)}];
        new_file = [Recycle_Bin_Directory filesep log_lines{f_loc(end)-1}];
        success = movefile(old_file,new_file);
        if ~success
            [Status, OSMessage] = dos(['move /y "' old_file '" "'  new_file '"']);
            if Status
                error(['Could not rename file (' old_file ' to (' new_file ')']);
            end    
        end
        % Rewriting (trash.log) after taking out the lines of deleted file
        fileattrib([Recycle_Bin_Directory filesep 'trash.log'],'-h');
        fid4 = fopen([Recycle_Bin_Directory filesep 'trash.log'],'w');
        if length(f_loc)==2
            error(['No older versions of file exist']);
        end
        for g=1:4:length(log_lines)
            if g~=f_loc(end-1) & isempty(intersect(g,f_loc(1:end-2)))
                fprintf(fid4,'%s\n%s\n%s\n%s\n',log_lines{g},log_lines{g+1},log_lines{g+2},log_lines{g+3});
            end
            if ~isempty(intersect(g,f_loc(end-1:end)))
                fprintf(fid4,'%s\n%s\n%s\n%s\n',log_lines{g},log_lines{g},log_lines{g+2},log_lines{g+3});
            end
        end
        fclose(fid4);   
        fileattrib([Recycle_Bin_Directory filesep 'trash.log'],'+h');
        clear f_loc log_lines;
    end
    
    %----------------------------
    % trash file(s) specified ...      
    %----------------------------
else
    full_list = [];
    for n=1:length(varargin)
        if ~isempty(findstr(varargin{n},'*'))
            full_list = [full_list wildfiles(varargin{n})];
        else
            full_list = [full_list varargin{n}];
        end
    end
    if ~iscell(full_list)
        full_list={full_list};
    end
    for n=1:length(full_list)
        fid = fopen([Recycle_Bin_Directory filesep 'trash.log'],'a');
        file_old_name = full_list{n};
        file_new_name = file_old_name;
        m=1;
        while exist([Recycle_Bin_Directory filesep file_new_name],'file')
            file_new_name = [file_old_name '_' int2str(m)];
            m=m+1;
        end
        success = movefile(file_old_name,[Recycle_Bin_Directory filesep file_new_name]);
        if ~success
            [Status, OSMessage] = dos(['move /y "'  full_list{n} '" "'  Recycle_Bin_Directory filesep '"']);
            if Status
                error(['Could not move file(s) to directory (' Recycle_Bin_Directory filesep ')']);
            end    
        end
        
        % Creating/Opening (trash.log) file in (Recycle Bin) folder
        fprintf(fid,'%s\n%s\n%s\n%s\n',file_old_name,file_new_name,pwd,datestr(now));
        fclose(fid);
    end
    fileattrib([Recycle_Bin_Directory filesep 'trash.log'],'+h');
    
end
fclose('all');


function files_names = wildfiles(varargin);

%WILDFILES converts a wildcard expression to a list of files in a cell array.  
%
% 
% NOTE:     * Tested only in (Windows) but not in (UNIX).
%           * If no files found, the function will return (0).
%
% Examples:
% 
%   wildfiles *.*
%   D = wildfiles('m*.*');
%   D = wildfiles('m*.*','s*.m');
%
%   Copyright 2004 Fahad Al Mahmood
%   Version: 1.0 $  $Date: 1-May-2004


k=1;
for n=1:nargin
    [pathstr,name,ext]=fileparts(varargin{n});
    if isempty(pathstr);
        pathstr=pwd;
    end
    if isempty(name) & ~isempty(ext)
        name = '*';
    end
    if strmatch(ext,'.','exact')
        ext = '.*';
    end
    full_name = [pathstr filesep name ext];
    if isempty(pathstr)
        full_name = [name ext];
    end
    if isdir([pathstr filesep name])
        full_name = [pathstr filesep name filesep '*.*'];
    end
    files = dir(full_name);
    
    % Assigning file names to a cell array after making sure they do not
    % contain directories.
    for m=1:length(files)
        if ~files(m).isdir & isempty(strmatch(files(m).name,'trash.log'))
            files_names{k} = files(m).name;
            k=k+1;
        end
    end
    
    % Flag (0) is case no file is found.
    if ~exist('files_names','var')
        files_names = 0;
    end
    files_names = files_names';
end

Contact us at files@mathworks.com