From: pcanterino <> Date: Fri, 13 Feb 2004 12:40:18 +0000 (+0000) Subject: Began to implement the possibility to control the output using template files X-Git-Tag: version_2_0~38 X-Git-Url: https://git.p6c8.net/devedit.git/commitdiff_plain/03d83644ce2d958fe3e0466fa272c67f0566f4ab?hp=5a4bc87c675dd76627a0d413707139f2e0530eea Began to implement the possibility to control the output using template files and the configuration file. The source code became much cleaner and we can now easily change the output. The template system is not completely implemented yet, but I thought it's time to save the current state of development. --- diff --git a/devedit.dat b/devedit.dat index 63f2928..c34d150 100644 --- a/devedit.dat +++ b/devedit.dat @@ -3,11 +3,39 @@ # # Please don't use quotation marks around the keys and values! -fileroot = D:/Server/WWW/dokumente/devedit-test +fileroot = D:/WWW/dokumente/devedit-test httproot = /devedit-test/ timeformat = %d.%m.%Y %H:%M uselist_file = uselist lock_file = uselist.lock lock_timeout = 10 +# ======================================================== +# You don't need to change the values below this comment +# ======================================================== + +# Templates + +tpl_dirlist = templates/dirlist.htm +tpl_viewfile = templates/viewfile.htm +tpl_editfile = templates/editfile.htm +tpl_confirm_rmfile = templates/confirm_rmfile.htm +tpl_confirm_rmdir = templates/confirm_rmdir.htm +tpl_confirm_unlock = templates/confirm_unlock.htm +tpl_confirm_replace = templates/confirm_replace.htm +tpl_dirlist_file = templates/dirlist_file.htm +tpl_dirlist_dir = templates/dirlist_dir.htm +tpl_dirlist_up = templates/dirlist_up.htm +tpl_error = templates/error.htm + +# Error messages + +err_binary = This editor is not able to view/edit binary files. +err_editdir = You cannot edit directories. +err_noedit = You have not enough permissions to edit this file. +err_edit_failed = Saving of file '{FILE}' failed. The file could be damaged, please check its integrity. +err_delete_failed = Could not delete file '{FILE}'. +err_above_root = Accessing files and directories above the virtual root directory is forbidden. +err_create_ar = You aren't allowed to create files and directories above the virtual root directory. + # End of configuration file \ No newline at end of file diff --git a/devedit.pl b/devedit.pl index a525ec0..7a27e58 100644 --- a/devedit.pl +++ b/devedit.pl @@ -6,7 +6,7 @@ # Dev-Editor's main program # # Author: Patrick Canterino -# Last modified: 2004-01-16 +# Last modified: 2004-02-06 # use strict; @@ -27,6 +27,7 @@ use constant CONFIGFILE => 'devedit.dat'; # Read the configuration file my $config = read_config(CONFIGFILE); +error_template($config->{'tpl_error'}); # Yes, I'm lazy... # Read the most important form data @@ -64,7 +65,7 @@ if($newfile ne '') unless(($new_physical,$new_virtual) = check_path($config->{'fileroot'},$dir)) { - abort("You aren't allowed to create files and directories above the virtual root directory."); + abort($config->{'err_creat_ar'}); } # Create the physical and the virtual path @@ -105,7 +106,7 @@ if(-e clean_path($config->{'fileroot'}."/".$file)) } else { - abort("Accessing files and directories above the virtual root directory is forbidden."); + abort($config->{'err_above_root'}); } } else diff --git a/modules/Command.pm b/modules/Command.pm index ceee24d..d84d42f 100644 --- a/modules/Command.pm +++ b/modules/Command.pm @@ -6,7 +6,7 @@ package Command; # Execute Dev-Editor's commands # # Author: Patrick Canterino -# Last modified: 2003-12-22 +# Last modified: 2004-02-06 # use strict; @@ -17,26 +17,26 @@ use File::Access; use File::Copy; use File::Path; -use HTML::Entities; -use Output; use POSIX qw(strftime); use Tool; +use CGI qw(header); +use HTML::Entities; +use Output; +use Template; + my $script = $ENV{'SCRIPT_NAME'}; -my %dispatch = ('show' => \&exec_show, - 'beginedit' => \&exec_beginedit, - 'canceledit' => \&exec_unlock, - 'endedit' => \&exec_endedit, - 'mkdir' => \&exec_mkdir, - 'mkfile' => \&exec_mkfile, - 'workwithfile' => \&exec_workwithfile, - 'workwithdir' => \&exec_workwithdir, - 'copy' => \&exec_copy, - 'rename' => \&exec_rename, - 'remove' => \&exec_remove, - 'rmdir' => \&exec_rmdir, - 'unlock' => \&exec_unlock +my %dispatch = ('show' => \&exec_show, + 'beginedit' => \&exec_beginedit, + 'canceledit' => \&exec_canceledit, + 'endedit' => \&exec_endedit, + 'mkdir' => \&exec_mkdir, + 'mkfile' => \&exec_mkfile, + 'copy' => \&exec_copy, + 'rename' => \&exec_rename, + 'remove' => \&exec_remove, + 'unlock' => \&exec_unlock ); ### Export ### @@ -91,32 +91,22 @@ sub exec_show($$) my $files = $direntries->{'files'}; my $dirs = $direntries->{'dirs'}; - $output .= htmlhead("Directory listing of $virtual"); - $output .= equal_url($config->{'httproot'},$virtual); - $output .= "
\n\n
\n";
+  my $dirlist = "";
 
   # Create the link to the upper directory
   # (only if we are not in the root directory)
 
   unless($virtual eq "/")
   {
-   my $upper = $physical."/..";
-   my @stat  = stat($upper);
+   my @stat  = stat($physical."/..");
 
-   $output .= "  [SUBDIR]  ";
-   $output .= strftime("%d.%m.%Y %H:%M",localtime($stat[9]));
-   $output .= " " x 10;
-   $output .= "../\n";
-  }
+   my $udtpl = new Template;
+   $udtpl->read_file($config->{'tpl_dirlist_up'});
 
-  # Get the length of the longest file/directory name
+   $udtpl->fillin("UPPER_DIR",encode_entities(upper_path($virtual)));
+   $udtpl->fillin("DATE",strftime($config->{'timeformat'},localtime($stat[9])));
 
-  my $max_name_len = 0;
-
-  foreach(@$dirs,@$files)
-  {
-   my $length    = length($_);
-   $max_name_len = $length if($length > $max_name_len);
+   $dirlist .= $udtpl->get_template;
   }
 
   # Directories
@@ -126,13 +116,14 @@ sub exec_show($$)
    my @stat      = stat($physical."/".$dir);
    my $virt_path = encode_entities($virtual.$dir."/");
 
-   $output .= "  ";
-   $output .= "[SUBDIR]  ";
-   $output .= strftime($config->{'timeformat'},localtime($stat[9]));
-   $output .= " " x 10;
-   $output .= "".encode_entities($dir)."/";
-   $output .= " " x ($max_name_len - length($dir) - 1)."\t  (";
-   $output .= "Work with directory)\n";
+   my $dtpl = new Template;
+   $dtpl->read_file($config->{'tpl_dirlist_dir'});
+
+   $dtpl->fillin("DIR",$virt_path);
+   $dtpl->fillin("DIR_NAME",$dir);
+   $dtpl->fillin("DATE",strftime($config->{'timeformat'},localtime($stat[9])));
+
+   $dirlist .= $dtpl->get_template;
   }
 
   # Files
@@ -145,83 +136,37 @@ sub exec_show($$)
    my @stat      = stat($phys_path);
    my $in_use    = $data->{'uselist'}->in_use($virtual.$file);
 
-   $output .= " " x (10 - length($stat[7]));
-   $output .= $stat[7];
-   $output .= "  ";
-   $output .= strftime($config->{'timeformat'},localtime($stat[9]));
-   $output .= " " x 10;
-   $output .= encode_entities($file);
-   $output .= " " x ($max_name_len - length($file))."\t  (";
-
-   # Link "View"
+   my $ftpl = new Template;
+   $ftpl->read_file($config->{'tpl_dirlist_file'});
 
-   if(-r $phys_path && -T $phys_path)
-   {
-    $output .= "View";
-   }
-   else
-   {
-    $output .= 'fillin("FILE_NAME",$file);
+   $ftpl->fillin("SIZE",$stat[7]);
+   $ftpl->fillin("DATE",strftime($config->{'timeformat'},localtime($stat[9])));
 
-    $output .= (not -r $phys_path) ? "Not readable" :
-               (-B     $phys_path) ? "Binary file"  : "";
+   $ftpl->parse_if_block("not_readable",not -r $phys_path);
+   $ftpl->parse_if_block("binary",-B $phys_path);
+   $ftpl->parse_if_block("readonly",not -w $phys_path);
 
-    $output .= '">View';
-   }
+   $ftpl->parse_if_block("viewable",-r $phys_path && -T $phys_path);
+   $ftpl->parse_if_block("editable",-w $phys_path && -r $phys_path && -T $phys_path && not $in_use);
 
-   $output .= " | ";
+   $ftpl->parse_if_block("in_use",$in_use);
+   $ftpl->parse_if_block("unused",not $in_use);
 
-   # Link "Edit"
-
-   if(-w $phys_path && -r $phys_path && -T $phys_path && not $in_use)
-   {
-    $output .= "Edit";
-   }
-   else
-   {
-    $output .= 'get_template;
+  }
 
-   # Link "Do other stuff"
+  my $tpl = new Template;
+  $tpl->read_file($config->{'tpl_dirlist'});
 
-   $output .= " | Work with file)\n";
-  }
+  $tpl->fillin("DIRLIST",$dirlist);
+  $tpl->fillin("DIR",$virtual);
+  $tpl->fillin("SCRIPT",$script);
+  $tpl->fillin("URL",equal_url($config->{'httproot'},$virtual));
 
-  $output .= "
\n\n
\n\n"; - - # Bottom of directory listing - # (Fields for creating files and directories) - - $output .= < - -
- - -Create new directory: -$virtual -
- - -Create new file: -
- - -$virtual -
- - - -
-END - $output .= htmlfoot; + $output = header(-type => "text/html"); + $output .= $tpl->get_template; } else { @@ -237,22 +182,25 @@ END { # Binary file - return error("This editor is not able to view/edit binary files.",upper_path($virtual)); + return error($config->{'err_binary'},upper_path($virtual)); } else { # Text file - $output = htmlhead("Contents of file ".encode_entities($virtual)); - $output .= equal_url($config->{'httproot'},$virtual); - $output .= dir_link($virtual); + my $content = file_read($physical); + + my $tpl = new Template; + $tpl->read_file($config->{'tpl_viewfile'}); - $output .= '
'."\n"; - $output .= '
'."\n";
-   $output .= encode_entities(${file_read($physical)});
-   $output .= "\n
\n
"; + $tpl->fillin("FILE",$virtual); + $tpl->fillin("DIR",upper_path($virtual)); + $tpl->fillin("URL",equal_url($config->{'httproot'},$virtual)); + $tpl->fillin("SCRIPT",$script); + $tpl->fillin("CONTENT",encode_entities($$content)); - $output .= htmlfoot; + $output = header(-type => "text/html"); + $output .= $tpl->get_template; } } @@ -275,9 +223,9 @@ sub exec_beginedit($$) my $virtual = $data->{'virtual'}; my $uselist = $data->{'uselist'}; - return error("You cannot edit directories.",upper_path($virtual)) if(-d $physical); + return error($config->{'err_editdir'},upper_path($virtual)) if(-d $physical); return error_in_use($virtual) if($uselist->in_use($virtual)); - return error("You have not enough permissions to edit this file.",upper_path($virtual)) unless(-r $physical && -w $physical); + return error($config->{'err_noedit'},upper_path($virtual)) unless(-r $physical && -w $physical); # Check on binary files @@ -285,7 +233,7 @@ sub exec_beginedit($$) { # Binary file - return error("This editor is not able to view/edit binary files.",upper_path($virtual)); + return error($config->{'err_binary'},upper_path($virtual)); } else { @@ -294,49 +242,41 @@ sub exec_beginedit($$) $uselist->add_file($virtual); $uselist->save; - my $dir = upper_path($virtual); - my $content = encode_entities(${file_read($physical)}); + my $content = file_read($physical); - my $equal_url = equal_url($config->{'httproot'},$virtual); + my $tpl = new Template; + $tpl->read_file($config->{'tpl_editfile'}); - $virtual = encode_entities($virtual); + $tpl->fillin("FILE",$virtual); + $tpl->fillin("DIR",upper_path($virtual)); + $tpl->fillin("URL",equal_url($config->{'httproot'},$virtual)); + $tpl->fillin("SCRIPT",$script); + $tpl->fillin("CONTENT",encode_entities($$content)); - my $output = htmlhead("Edit file $virtual"); - $output .= $equal_url; - $output .= <Caution! This file is locked for other users while you are editing it. To unlock it, click Save and exit or Exit WITHOUT saving. Please don't click the Reload button in your browser! This will confuse the editor.

+ my $output = header(-type => "text/html"); + $output .= $tpl->get_template; -
- - -

-
- -
- - - - - - - - - - - - -
- - Save as new file: $dir Encode ISO-8859-1 special chars
+ return \$output; + } +} - -
-END +# exec_canceledit() +# +# Abort file editing +# +# Params: 1. Reference to user input hash +# 2. Reference to config hash +# +# Return: Output of the command (Scalar Reference) - $output .= htmlfoot; +sub exec_canceledit($$) +{ + my ($data,$config) = @_; + my $virtual = $data->{'virtual'}; + my $uselist = $data->{'uselist'}; - return \$output; - } + file_unlock($uselist,$virtual); + return devedit_reload({command => 'show', file => upper_path($virtual)}); } # exec_endedit() @@ -355,8 +295,8 @@ sub exec_endedit($$) my $virtual = $data->{'virtual'}; my $content = $data->{'cgi'}->param('filecontent'); - return error("You cannot edit directories.") if(-d $physical); - return error("You have not enough permissions to edit this file.",upper_path($virtual)) unless(-r $physical && -w $physical); + return error($config->{'err_editdir'},upper_path($virtual)) if(-d $physical); + return error($config->{'err_noedit'},upper_path($virtual)) unless(-r $physical && -w $physical); # Normalize newlines @@ -381,11 +321,12 @@ sub exec_endedit($$) { # Saving of the file was successful - so unlock it! - return exec_unlock($data,$config); + file_unlock($data->{'uselist'},$virtual); + return devedit_reload({command => 'show', file => upper_path($virtual)}); } else { - return error("Saving of file '".encode_entities($virtual)."' failed'. The file could be damaged, please check it's integrity.",upper_path($virtual)); + return error($config->{'err_editfailed'},upper_path($virtual),{FILE => $virtual}); } } @@ -435,159 +376,6 @@ sub exec_mkdir($$) return devedit_reload({command => 'show', file => $dir}); } -# exec_workwithfile() -# -# Display a form for renaming/copying/removing/unlocking a file -# -# Params: 1. Reference to user input hash -# 2. Reference to config hash -# -# Return: Output of the command (Scalar Reference) - -sub exec_workwithfile($$) -{ - my ($data,$config) = @_; - my $physical = $data->{'physical'}; - my $virtual = $data->{'virtual'}; - my $unused = $data->{'uselist'}->unused($virtual); - - my $dir = encode_entities(upper_path($virtual)); - - my $output = htmlhead("Work with file ".encode_entities($virtual)); - $output .= equal_url($config->{'httproot'},$virtual); - - $virtual = encode_entities($virtual); - - $output .= dir_link($virtual); - $output .= "

Note: On UNIX systems, filenames are case-sensitive!

\n\n"; - - $output .= "

Someone else is currently editing this file. So not all features are available.

\n\n" unless($unused); - - $output .= "
\n\n"; - - # Copying of the file is always allowed - but we need read access - - if(-r $physical) - { - $output .= <Copy - -
- - -

Copy file '$virtual' to:
$dir

-
- -
- -END - } - - if($unused) - { - # File is not locked - # Allow renaming and deleting the file - - $output .= <Move/rename - -
- - -

Move/Rename file '$virtual' to:
$dir

-
- -
- -

Remove

- -

Click on the button below to remove the file '$virtual'.

- -
- - -

-
-END - } - else - { - # File is locked - # Just display a button for unlocking it - - $output .= <Unlock file - -

Someone else is currently editing this file. At least, the file is marked so. Maybe, someone who was editing the file has forgotten to unlock it. In this case (and only in this case) you can unlock the file using this button:

- -
- - -

-
-END - } - - $output .= "\n
"; - $output .= htmlfoot; - - return \$output; -} - -# exec_workwithdir() -# -# Display a form for renaming/removing a directory -# -# Params: 1. Reference to user input hash -# 2. Reference to config hash -# -# Return: Output of the command (Scalar Reference) - -sub exec_workwithdir($$) -{ - my ($data,$config) = @_; - my $physical = $data->{'physical'}; - my $virtual = $data->{'virtual'}; - - my $dir = encode_entities(upper_path($virtual)); - - my $output = htmlhead("Work with directory ".encode_entities($virtual)); - $output .= equal_url($config->{'httproot'},$virtual); - - $virtual = encode_entities($virtual); - - $output .= dir_link($virtual); - $output .= "

Note: On UNIX systems, filenames are case-sensitive!

\n\n"; - $output .= "
\n\n"; - - $output .= <Move/rename - -
- - -

Move/Rename directory '$virtual' to:
$dir

-
- -
- -

Remove

- -

Click on the button below to completely remove the directory '$virtual' and oll of it's files and sub directories.

- -
- - -

-
-END - - $output .= "\n
"; - $output .= htmlfoot; - - return \$output; -} - # exec_copy() # # Copy a file and return to directory view @@ -618,30 +406,18 @@ sub exec_copy($$) } elsif(not $data->{'cgi'}->param('confirmed')) { - $dir = encode_entities($dir); - - my $output = htmlhead("Replace existing file"); - $output .= <<"END"; -

A file called '$new_virtual' already exists. Do you want to replace it?

- -
- - - - + my $tpl = new Template; + $tpl->read_file($config->{'tpl_confirm_replace'}); -

-
+ $tpl->fillin("FILE",$virtual); + $tpl->fillin("NEW_FILE",$new_virtual); + $tpl->fillin("DIR",upper_path($virtual)); + $tpl->fillin("COMMAND","copy"); + $tpl->fillin("URL",equal_url($config->{'httproot'},$virtual)); + $tpl->fillin("SCRIPT",$script); -
- - - -

-
-END - - $output .= htmlfoot; + my $output = header(-type => "text/html"); + $output .= $tpl->get_template; return \$output; } @@ -685,30 +461,18 @@ sub exec_rename($$) } elsif(not $data->{'cgi'}->param('confirmed')) { - $dir = encode_entities($dir); - - my $output = htmlhead("Replace existing file"); - $output .= <<"END"; -

A file called '$new_virtual' already exists. Do you want to replace it?

- -
- - - - - -

-
- -
- - + my $tpl = new Template; + $tpl->read_file($config->{'tpl_confirm_replace'}); -

-
-END + $tpl->fillin("FILE",$virtual); + $tpl->fillin("NEW_FILE",$new_virtual); + $tpl->fillin("DIR",upper_path($virtual)); + $tpl->fillin("COMMAND","rename"); + $tpl->fillin("URL",equal_url($config->{'httproot'},$virtual)); + $tpl->fillin("SCRIPT",$script); - $output .= htmlfoot; + my $output = header(-type => "text/html"); + $output .= $tpl->get_template; return \$output; } @@ -725,7 +489,7 @@ END # exec_remove() # -# Remove a file and return to directory view +# Remove a file or a directory and return to directory view # # Params: 1. Reference to user input hash # 2. Reference to config hash @@ -738,132 +502,98 @@ sub exec_remove($$) my $physical = $data->{'physical'}; my $virtual = $data->{'virtual'}; - return exec_rmdir($data,$config) if(-d $physical); - return error_in_use($virtual) if($data->{'uselist'}->in_use($virtual)); - - if($data->{'cgi'}->param('confirmed')) - { - unlink($physical) or return error("Could not delete file '".encode_entities($virtual)."'.",upper_path($virtual)); - return devedit_reload({command => 'show', file => upper_path($virtual)}); - } - else + if(-d $physical) { - my $dir = encode_entities(upper_path($virtual)); - my $output; - - $output = htmlhead("Remove file ".encode_entities($virtual)); - $output .= equal_url($config->{'httproot'},$virtual); + # Remove a directory - $virtual = encode_entities($virtual); + if($data->{'cgi'}->param('confirmed')) + { + rmtree($physical); + return devedit_reload({command => 'show', file => upper_path($virtual)}); + } + else + { + my $tpl = new Template; + $tpl->read_file($config->{'tpl_confirm_rmdir'}); - $output .= dir_link($virtual); + $tpl->fillin("DIR",$virtual); + $tpl->fillin("UPPER_DIR",upper_path($virtual)); + $tpl->fillin("URL",equal_url($config->{'httproot'},$virtual)); + $tpl->fillin("SCRIPT",$script); - $output .= <<"END"; -

Do you really want to remove the file '$virtual'?

+ my $output = header(-type => "text/html"); + $output .= $tpl->get_template; -
- - - + return \$output; + } + } + else + { + # Remove a file -

-
+ return error_in_use($virtual) if($data->{'uselist'}->in_use($virtual)); -
- - + if($data->{'cgi'}->param('confirmed')) + { + unlink($physical) or return error($config->{'err_editfailed'},upper_path($virtual),{FILE => $virtual}); + return devedit_reload({command => 'show', file => upper_path($virtual)}); + } + else + { + my $tpl = new Template; + $tpl->read_file($config->{'tpl_confirm_rmfile'}); -

-
-END + $tpl->fillin("FILE",$virtual); + $tpl->fillin("DIR",upper_path($virtual)); + $tpl->fillin("URL",equal_url($config->{'httproot'},$virtual)); + $tpl->fillin("SCRIPT",$script); - $output .= htmlfoot; + my $output = header(-type => "text/html"); + $output .= $tpl->get_template; - return \$output; + return \$output; + } } } -# exec_rmdir() +# exec_unlock() # -# Remove a directory and return to directory view +# Remove a file from the list of used files and +# return to directory view # # Params: 1. Reference to user input hash # 2. Reference to config hash # # Return: Output of the command (Scalar Reference) -sub exec_rmdir($$) +sub exec_unlock($$) { my ($data,$config) = @_; - my $physical = $data->{'physical'}; my $virtual = $data->{'virtual'}; - - return exec_remove($data,$config) if(not -d $physical); + my $uselist = $data->{'uselist'}; if($data->{'cgi'}->param('confirmed')) { - rmtree($physical); + file_unlock($uselist,$virtual); return devedit_reload({command => 'show', file => upper_path($virtual)}); } else { - my $dir = encode_entities(upper_path($virtual)); - my $output; - - $output = htmlhead("Remove directory ".encode_entities($virtual)); - $output .= equal_url($config->{'httproot'},$virtual); - - $virtual = encode_entities($virtual); - - $output .= dir_link($virtual); - - $output .= <<"END"; -

Do you really want to remove the directory '$virtual' and all of it's files and sub directories?

- -
- - - - -

-
+ my $tpl = new Template; + $tpl->read_file($config->{'tpl_confirm_unlock'}); -
- - + $tpl->fillin("FILE",$virtual); + $tpl->fillin("DIR",upper_path($virtual)); + $tpl->fillin("URL",equal_url($config->{'httproot'},$virtual)); + $tpl->fillin("SCRIPT",$script); -

-
-END - - $output .= htmlfoot; + my $output = header(-type => "text/html"); + $output .= $tpl->get_template; return \$output; } } -# exec_unlock() -# -# Remove a file from the list of used files and -# return to directory view -# -# Params: 1. Reference to user input hash -# 2. Reference to config hash -# -# Return: Output of the command (Scalar Reference) - -sub exec_unlock($$) -{ - my ($data,$config) = @_; - my $virtual = $data->{'virtual'}; - my $uselist = $data->{'uselist'}; - - $uselist->remove_file($virtual); - $uselist->save; - - return devedit_reload({command => 'show', file => upper_path($virtual)}); -} - # it's true, baby ;-) 1; diff --git a/modules/File/Access.pm b/modules/File/Access.pm index 6c3862b..9dcd7e5 100644 --- a/modules/File/Access.pm +++ b/modules/File/Access.pm @@ -7,7 +7,7 @@ package File::Access; # with only one command # # Author: Patrick Canterino -# Last modified: 2003-12-01 +# Last modified: 2004-02-06 # use strict; @@ -23,7 +23,8 @@ use base qw(Exporter); @EXPORT = qw(dir_read file_create file_read - file_save); + file_save + file_unlock); # dir_read() # @@ -134,6 +135,25 @@ sub file_save($$) return 1; } +# file_unlock() +# +# Remove a file from the list of files in use +# +# Params: 1. File::UseList object +# 2. File to remove +# +# Return: -nothing- + +sub file_unlock($$) +{ + my ($uselist,$file) = @_; + + $uselist->remove_file($file); + $uselist->save; + + return; +} + # it's true, baby ;-) 1; diff --git a/modules/Output.pm b/modules/Output.pm index 6e48bf3..449731f 100644 --- a/modules/Output.pm +++ b/modules/Output.pm @@ -6,7 +6,7 @@ package Output; # HTML generating routines # # Author: Patrick Canterino -# Last modified: 2003-12-13 +# Last modified: 2004-02-06 # use strict; @@ -14,65 +14,32 @@ use strict; use vars qw(@EXPORT); use CGI qw(header); -use HTML::Entities; use Tool; +use HTML::Entities; +use Template; + ### Export ### use base qw(Exporter); -@EXPORT = qw(htmlhead - htmlfoot +@EXPORT = qw(error_template error abort - error_in_use - equal_url - dir_link); - -# htmlhead() -# -# Generate the head of a HTML document -# (a text/html HTTP header will also be created) -# -# Params: Title/heading -# -# Return: Head for the HTML document - -sub htmlhead($) -{ - my $title = shift; + error_in_use); - my $html = header(-type => "text/html"); +my $tpl_error; - $html .= < - - - -$title - - - - -

$title

- -END - - return $html; -} - -# htmlfoot() -# -# Generate the foot of a HTML document +# error_template() # -# Params: -nothing- +# Set the path to the template file using for error messages +# (I'm lazy...) # -# Return: Foot for the HTML document +# Params: Template file -sub htmlfoot +sub error_template($) { - return "\n\n"; + $tpl_error = shift; } # error() @@ -81,25 +48,33 @@ sub htmlfoot # # Params: 1. Error message # 2. Virtual path to which a link should be displayed (optional) +# 3. Hash reference: Template variables (optional) # # Return: Formatted message (Scalar Reference) -sub error($;$) +sub error($;$$) { - my ($message,$path) = @_; + my ($message,$path,$vars) = @_; - my $output = htmlhead("Error"); - $output .= "

$message

"; + my $tpl = new Template; + $tpl->read_file($tpl_error); - if($path) - { - $path = encode_entities($path); + $tpl->fillin("ERROR",$message); + $tpl->fillin("DIR",$path); + $tpl->fillin("SCRIPT",encode_entities($ENV{'SCRIPT_NAME'})); + + $tpl->parse_if_block("dir",defined $path); - $output .= "\n\n"; - $output .= "

Back to $path

"; + if(ref($vars) eq "HASH") + { + while(my ($key,$value) = each(%$vars)) + { + $tpl->fillin($key,$value); + } } - $output .= htmlfoot; + my $output = header(-type => "text/html"); + $output .= $tpl->get_template; return \$output; } @@ -134,44 +109,6 @@ sub error_in_use($) return error("The file '".encode_entities($file)."' is currently edited by someone else.",upper_path($file)); } -# equal_url() -# -# Create an "equals"-link -# -# Params: 1. HTTP root -# 2. Relative path -# -# Return: Formatted link (String) - -sub equal_url($$) -{ - my ($root,$path) = @_; - my $url; - - $root =~ s!/$!!; - $path =~ s!^/!!; - $url = $root."/".$path; - $url = encode_entities($url); - - return "

(equals $url)

\n\n"; -} - -# dir_link() -# -# Create the link to the directory of a file -# -# Params: File -# -# Return: Formatted link (String) - -sub dir_link($) -{ - my $dir = upper_path(shift); - $dir = encode_entities($dir); - - return "

Back to $dir

\n\n"; -} - # it's true, baby ;-) 1; diff --git a/modules/Template.pm b/modules/Template.pm new file mode 100644 index 0000000..e3fbb98 --- /dev/null +++ b/modules/Template.pm @@ -0,0 +1,311 @@ +package Template; + +# +# Template (Version 1.2a) +# +# Klasse zum Parsen von Templates +# +# Autor: Patrick Canterino +# Letzte Aenderung: 12.9.2003 +# + +use strict; + +use Carp qw(croak); + +# new() +# +# Konstruktor +# +# Parameter: -keine- +# +# Rueckgabe: Template-Objekt + +sub new +{ + my $class = shift; + my $self = {template => ''}; + return bless($self,$class); +} + +# get_template() +# +# Kompletten Vorlagentext zurueckgeben +# +# Parameter: -keine- +# +# Rueckgabe: Kompletter Vorlagentext (String) + +sub get_template +{ + return shift->{'template'}; +} + +# set_template() +# +# Kompletten Vorlagentext aendern +# +# Parameter: Vorlagentext +# +# Rueckgabe: -nichts- (Template-Objekt wird modifiziert) + +sub set_template($) +{ + # Geht nur so... + + my ($self,$template) = @_; + $self->{'template'} = $template; +} + +# add_text() +# +# Vorlagentext ans Template-Objekt anhaengen +# +# Parameter: Vorlagentext +# +# Rueckgabe: -nichts- (Template-Objekt wird modifiziert) + +sub add_text($) +{ + my ($self,$text) = @_; + $self->set_template($self->get_template.$text); +} + +# read_file() +# +# Einlesen einer Vorlagendatei +# (Inhalt wird an bereits vorhandenen Text angehaengt) +# +# Parameter: Datei zum Einlesen +# +# Rueckgabe: -nichts- (Template-Objekt wird modifiziert) + +sub read_file($) +{ + my ($self,$tfile) = @_; + local *FILE; + + open(FILE,"<$tfile") or croak "Open $tfile: $!"; + read(FILE, my $content, -s $tfile); + close(FILE) or croak "Closing $tfile: $!"; + + $self->add_text($content); +} + +# fillin() +# +# Variablen durch Text ersetzen +# +# Parameter: 1. Variable zum Ersetzen +# 2. Text, durch den die Variable ersetzt werden soll +# +# Rueckgabe: -nichts- (Template-Objekt wird modifiziert) + +sub fillin($$) +{ + my ($self,$var,$text) = @_; + + $var = quotemeta($var); + $text = "" unless defined $text; # Um Fehler zu vermeiden + + my $template = $self->get_template; + $template =~ s/\{$var\}/$text/g; + + $self->set_template($template); +} + +# fillin_array() +# +# Variable durch Array ersetzen +# +# Parameter: 1. Variable zum Ersetzen +# 2. Array-Referenz, durch die die Variable ersetzt werden soll +# 3. Zeichenkette, mit der das Array verbunden werden soll +# (Standard: "") +# +# Rueckgabe: -nichts- (Template-Objekt wird modifiziert) + +sub fillin_array($$;$) +{ + my ($self,$var,$array,$glue) = @_; + $glue = '' unless defined $glue; + + $self->fillin($var,join($glue,@$array)); +} + +# parse_if_block() +# +# IF-Bloecke verarbeiten +# +# Parameter: 1. Name des IF-Blocks (das, was nach dem IF steht) +# 2. Statuscode (true => Inhalt anzeigen +# false => Inhalt nicht anzeigen +# +# Rueckgabe: -nichts- (Template-Objekt wird modifiziert) + +sub parse_if_block($$) +{ + my ($self,$name,$state) = @_; + my $template = $self->get_template; + + while(index($template,"{IF ".$name."}") >= 0) + { + # Das alles hier ist nicht wirklich elegant geloest... + # ... aber solange es funktioniert... ;-) + + my $start = index($template,"{IF ".$name."}"); + my $tpl_tmp = substr($template,$start); + my @splitted = split(/\{ENDIF\}/,$tpl_tmp); + + my $block = ""; # Kompletter bedingter Block + my $ifs = 0; # IF-Zaehler (wird fuer jedes IF erhoeht und fuer jedes ENDIF erniedrigt) + + # {IF} + + for(my $x=0;$x<@splitted;$x++) + { + $ifs += substr_count($splitted[$x],"{IF"); # Zum Zaehler jedes Vorkommen von IF hinzuzaehlen + $ifs--; # Zaehler um 1 erniedrigen + $block .= $splitted[$x]."{ENDIF}"; # Daten zum Block hinzufuegen + + if($ifs == 0) + { + # Zaehler wieder 0, also haben wir das Ende des IF-Blocks gefunden :-)) + + last; + } + } + + my $if_block = substr($block,length($name)+5,-7); # Alles zwischen {IF} und {ENDIF} + + # {ELSE} + + my $else_block = ""; # Alles ab {ELSE} + $ifs = 0; # IF-Zaehler + + @splitted = split(/\{ELSE\}/,$if_block); + + for(my $x=0;$x<@splitted;$x++) + { + $ifs += substr_count($splitted[$x],"{IF"); # Zum Zaehler jedes Vorkommen von IF hinzuzaehlen + $ifs -= substr_count($splitted[$x],"{ENDIF}"); # Vom Zaehler jedes Vorkommen von ENDIF abziehen + + if($ifs == 0) + { + # Zaehler 0, also haben wir das Ende des IF-Abschnitts gefunden + + # Aus dem Rest den ELSE-Block zusammenbauen + + for(my $y=$x+1;$y<@splitted;$y++) + { + $else_block .= "{ELSE}".$splitted[$y]; + } + + if($else_block) + { + $if_block = substr($if_block,0,length($if_block)-length($else_block)); + $else_block = (length($else_block) > 6) ? substr($else_block,6) : ""; # Ansonsten gibt es Fehler + } + + last; + } + } + + my $replacement = ($state) ? $if_block : $else_block; + + my $qmblock = quotemeta($block); + + $template =~ s/$qmblock/$replacement/; + } + + $self->set_template($template); +} + +# parse_condtag() +# +# Bedingungstags in einem Vorlagentext verarbeiten +# +# Parameter: 1. Tagname +# 2. Statuscode (true => Tag-Inhalt anzeigen +# false => Tag-Inhalt nicht anzeigen +# +# Rueckgabe: -nichts- (Template-Objekt wird modifiziert) + +sub parse_condtag($$) +{ + my ($self,$condtag,$state) = @_; + + my $template = $self->get_template; + + while(index($template,"<$condtag>") >= 0) + { + my $start = index($template,"<$condtag>"); # Beginn des Blocks + my $end = index($template,"")+length($condtag)+3; # Ende des Blocks + + my $extract = substr($template,$start,$end-$start); # Kompletten Bedingungsblock extrahieren... + + my $replacement = ($state) ? substr($extract,length($condtag)+2,0-length($condtag)-3) : ""; + + $extract = quotemeta($extract); + + $template =~ s/$extract/$replacement/g; # Block durch neue Daten ersetzen + } + $self->set_template($template); +} + +# ================== +# Private Funktion +# ================== + +# substr_count() +# +# Zaehlt, wie oft ein String in einem String vorkommt +# (Emulation der PHP-Funktion substr_count()) +# +# Parameter: 1. Zu durchsuchender String +# 2. Zu suchender String +# +# Rueckgabe: Anzahl der Vorkommnisse (Integer) + +sub substr_count($$) +{ + my ($haystack,$needle) = @_; + my $qmneedle = quotemeta($needle); + + my $count = 0; + + $count++ while($haystack =~ /$qmneedle/g); + + return $count; +} + +# ================== +# Alias-Funktionen +# ================== + +sub addtext($) +{ + shift->add_text(shift); +} + +sub as_string +{ + return shift->get_template; +} + +sub condtag($$) +{ + shift->parse_condtag(@_); +} + +sub readin($) +{ + shift->read_file(shift); +} + +# it's true, baby ;-) + +1; + +# +### Ende ### \ No newline at end of file diff --git a/modules/Tool.pm b/modules/Tool.pm index fc1b3b4..0b15f90 100644 --- a/modules/Tool.pm +++ b/modules/Tool.pm @@ -6,7 +6,7 @@ package Tool; # Some shared sub routines # # Author: Patrick Canterino -# Last modified: 2003-12-02 +# Last modified: 2004-02-03 # use strict; @@ -24,6 +24,7 @@ use base qw(Exporter); @EXPORT = qw(check_path clean_path devedit_reload + equal_url file_name upper_path); @@ -125,6 +126,28 @@ sub devedit_reload($) return \$header; } +# equal_url() +# +# Create URL equal to a file or directory +# +# Params: 1. HTTP root +# 2. Relative path +# +# Return: Formatted link (String) + +sub equal_url($$) +{ + my ($root,$path) = @_; + my $url; + + $root =~ s!/$!!; + $path =~ s!^/!!; + $url = $root."/".$path; + #$url = encode_entities($url); + + return $url; +} + # file_name() # # Returns the last path of a path diff --git a/templates/confirm_replace.htm b/templates/confirm_replace.htm new file mode 100644 index 0000000..52450f5 --- /dev/null +++ b/templates/confirm_replace.htm @@ -0,0 +1,31 @@ + + + + +Replace exisiting file + + + + +

Replace exisiting file

+ +

A file called '{FILE}' already exists. Do you want to replace it?

+ +
+ + + + + +

+
+ +
+ + + +

+
+ + \ No newline at end of file diff --git a/templates/confirm_rmdir.htm b/templates/confirm_rmdir.htm new file mode 100644 index 0000000..9d83f40 --- /dev/null +++ b/templates/confirm_rmdir.htm @@ -0,0 +1,33 @@ + + + + +Remove directory {DIR} + + + + +

Remove directory {DIR}

+ +

(equals {URL})

+ +

Do you really want to remove the directory '{DIR}' and all of it's files and sub directories?

+ +
+ + + + +

+
+ +
+ + + +

+
+ + + \ No newline at end of file diff --git a/templates/confirm_rmfile.htm b/templates/confirm_rmfile.htm new file mode 100644 index 0000000..dc01faa --- /dev/null +++ b/templates/confirm_rmfile.htm @@ -0,0 +1,33 @@ + + + + +Remove file {FILE} + + + + +

Remove file {FILE}

+ +

(equals {URL})

+ +

Do you really want to remove the file '{FILE}'?

+ +
+ + + + +

+
+ +
+ + + +

+
+ + + \ No newline at end of file diff --git a/templates/confirm_unlock.htm b/templates/confirm_unlock.htm new file mode 100644 index 0000000..882fde1 --- /dev/null +++ b/templates/confirm_unlock.htm @@ -0,0 +1,27 @@ + + + + +Unlock file {FILE} + + + + +

Unlock file {FILE}

+ +

(equals {URL})

+ +

Back to {DIR}

+ +

Someone else is currently editing this file. At least, the file is marked so. Maybe, someone who was editing the file has forgotten to unlock it. In this case (and only in this case) you can unlock the file using this button:

+ +
+ + + + +

+
+ + \ No newline at end of file diff --git a/templates/dirlist.htm b/templates/dirlist.htm new file mode 100644 index 0000000..ca83e30 --- /dev/null +++ b/templates/dirlist.htm @@ -0,0 +1,45 @@ + + + + +Directory listing of {DIR} + + + + +

Directory listing of {DIR}

+ +

(equals {URL})

+ +
+ + +{DIRLIST}
+ +
+ + + + + + + + + + + + + + + + + + + +
Create new directory:{DIR}
Create new file:
{DIR}
+ +
+ + + \ No newline at end of file diff --git a/templates/dirlist_dir.htm b/templates/dirlist_dir.htm new file mode 100644 index 0000000..e69b3f5 --- /dev/null +++ b/templates/dirlist_dir.htm @@ -0,0 +1,6 @@ + +[SUBDIR] +{DATE} +{DIR_NAME}/ +(Rename | Delete) + \ No newline at end of file diff --git a/templates/dirlist_file.htm b/templates/dirlist_file.htm new file mode 100644 index 0000000..a010fb5 --- /dev/null +++ b/templates/dirlist_file.htm @@ -0,0 +1,6 @@ + +{SIZE} +{DATE} +{FILE_NAME} +({IF viewable}View{ELSE}View{ENDIF} | {IF editable}Edit{ELSE}Edit{ENDIF} | Copy{IF unused} | Rename | Delete{ENDIF}{IF in_use} | Unlock{ENDIF}) + \ No newline at end of file diff --git a/templates/dirlist_up.htm b/templates/dirlist_up.htm new file mode 100644 index 0000000..d35f7a4 --- /dev/null +++ b/templates/dirlist_up.htm @@ -0,0 +1,5 @@ + +[SUBDIR] +{DATE} +../ + \ No newline at end of file diff --git a/templates/editfile.htm b/templates/editfile.htm new file mode 100644 index 0000000..3790055 --- /dev/null +++ b/templates/editfile.htm @@ -0,0 +1,44 @@ + + + + +Edit file {FILE} + + + + +

Edit file {FILE}

+ +

(equals {URL})

+ +

Caution! This file is locked for other users while you are editing it. To unlock it, click Save and exit or Exit WITHOUT saving. Please don't click the Reload button in your browser! This will confuse the editor.

+ +
+ + +

+
+ +
+ + + + + + + + + + + + +
+ + Save as new file: {DIR} Encode ISO-8859-1 special chars
+ + +
+ + + \ No newline at end of file diff --git a/templates/error.htm b/templates/error.htm new file mode 100644 index 0000000..4cbd60a --- /dev/null +++ b/templates/error.htm @@ -0,0 +1,17 @@ + + + + +Error + + + + +

Error

+ +

{ERROR}

{IF dir} + +

Back to {DIR}

{ENDIF} + + \ No newline at end of file diff --git a/templates/viewfile.htm b/templates/viewfile.htm new file mode 100644 index 0000000..556e017 --- /dev/null +++ b/templates/viewfile.htm @@ -0,0 +1,23 @@ + + + + +Contents of file {FILE} + + + + +

Contents of file {FILE}

+ +

(equals {URL})

+ +

Back to {DIR}

+ +
+
+{CONTENT}
+
+
+ + \ No newline at end of file