[MKDoc-commit] Implemented links to attached files.

sam at mkdoc.demon.co.uk sam at mkdoc.demon.co.uk
Mon May 22 03:12:30 BST 2006


Log Message:
-----------
Implemented links to attached files.

Tags:
----
mkdoc-1-6

Modified Files:
--------------
    mkd/MKDoc/Util:
        LinkParser.pm

-------------- next part --------------
Index: LinkParser.pm
===================================================================
RCS file: /var/spool/cvs/mkd/MKDoc/Util/Attic/LinkParser.pm,v
retrieving revision 1.1.2.7
retrieving revision 1.1.2.8
diff -LMKDoc/Util/LinkParser.pm -LMKDoc/Util/LinkParser.pm -u -r1.1.2.7 -r1.1.2.8
--- MKDoc/Util/LinkParser.pm
+++ MKDoc/Util/LinkParser.pm
@@ -43,7 +43,12 @@
   if ($parser->is_internal) {
      if ($parser->is_valid) {
         $document_id = $parser->document_id;
-        print "Found a link to document ID $document_id.\n";
+        if ($parser->is_attachment) {
+          $file_name   = $parser->file_name;
+          print "Found a link to $file_name, attached to doc $document_id.\n";
+        } else {
+          print "Found a link to doc $document_id.\n";
+        }
      } else {
         die "Invalid internal link found!";
      }
@@ -51,6 +56,12 @@
      print "External link found.\n";
   }
 
+  # get a canonical URL, following redirects as needed
+  $url = $parser->as_string;
+
+  # get a canonical path, following redirects as needed
+  $path = $parser->as_path;
+
 =head1 DESCRIPTION
 
 This module parses links and determines whether they are internal
@@ -87,9 +98,19 @@
 Returns true if the last link was a valid internal link.  When this is
 true document_id will be available.
 
+=head2 is_attachment
+
+Returns true if the last link was a link to an attachment.  When this
+is true document_id and file_name will be available.
+
 =head2 document_id
 
-Returns the document_id for the last link parsed.
+Returns the document_id for the last link parsed.  For attachments
+this is the document to which the attachment is attached.
+
+=head2 file_name
+
+Returns the file-name for links to attachments.
 
 =head2 uri
 
@@ -217,18 +238,33 @@
         $uri->path($path . $self->{operation});
     }
 
+    # add in a file_name if this is an attachment
+    if ($self->{file_name}) {
+        my $path = $uri->path();
+        $path .= '/' unless $path =~ m!/$!;
+        $uri->path($path . $self->{file_name});
+    }
+
     return $uri->as_string;
 }
 
 sub as_path {
     my $self = shift;
+    my $path = '';
+
     # setup path based on document_id if we've got one
     if ($self->{document_id}) {
         my $dbh    = lib::sql::DBH->get();
-        my ($path) = $dbh->selectrow_array('SELECT Full_Path FROM Document WHERE ID = ?', undef, $self->{document_id});
-        return $path;
+        ($path) = $dbh->selectrow_array('SELECT Full_Path FROM Document WHERE ID = ?', undef, $self->{document_id});
     }
-    return '';
+    
+    # add in file-name for attachments
+    if ($self->{file_name}) {
+        $path .= '/' unless $path =~ m!/$!;
+        $path .= $self->{file_name};
+    }
+
+    return $path;
 }
 
 sub operation { shift->{operation} }
@@ -262,9 +298,28 @@
     return 1 if $self->document_id;
 }
 
+sub is_attachment {
+    my $self = shift;
+    return 0 unless $self->is_internal 
+      and $self->is_valid 
+      and $self->{file_name};
+    return 1;
+}
+
+sub file_name {
+    my $self = shift;
+    return unless $self->is_internal 
+      and $self->is_valid 
+      and $self->{file_name};
+    return $self->{file_name};
+}
+
 sub document_id {
     my $self = shift;
-    return $self->{document_id} if $self->{document_id};
+    return $self->{document_id}
+      if $self->{document_id};
+
+    $self->{file_name} = undef;
 
     my $uri  = $self->uri;
     my $dbh  = lib::sql::DBH->get();
@@ -273,11 +328,48 @@
     my $path = $uri->path;
     $path .= '/' unless $path =~ m!/$!;
 
+    # find an ID, following redirects as needed
+    my $id = $self->path_to_document_id($path, $dbh);
+
+    # return document_id if found
+    return $self->{document_id} = $id if $id;
+
+    # else, try treating it as a file attachement
+    my $file_name;
+    ($path, $file_name) = $uri->path =~ m!^(.*/)([^/]+)!;
+
+    # find an ID, following redirects as needed
+    $id = $self->path_to_document_id($path, $dbh);
+
+    # load up the document and look for a file attachment with the
+    # right name
+    my $found;
+    if ($id) {
+        my $doc_t  = flo::Standard::table('Document');
+        my $doc    = $doc_t->get($id);
+        my $editor = flo::Editor->_new();
+        $editor->parse_xml($doc->{Body}, $id);
+        $found = grep { $_->isa('flo::editor::File') and
+                        $_->{uri_name} eq $file_name     } $editor->access();
+    }
+
+    # found a matching attachment
+    if ($found) {
+        $self->{file_name}          = $file_name;
+        return $self->{document_id} = $id;
+    }    
+    
+    # no match
+    return $self->{document_id} = 0;
+}
+
+sub path_to_document_id {
+    my ($self, $path, $dbh) = @_;
+
     # limit redirection to 100 links to avoid infinite loops
     my $redirect_limit = 100;
 
-    # find an ID, following redirects as needed
-    my $id;
+    my $id = 0;
     while (1) {
         # does this path exist in the DB?
         last if $id = $self->lookup_path($path, $dbh);
@@ -289,8 +381,7 @@
         last unless --$redirect_limit;
     } 
 
-    # return what we found, 0 or a real ID
-    return $self->{document_id} = $id;
+    return $id;
 }
 
 # lookup a path in Document and Redirect.  Returns the ID or a
@@ -344,6 +435,7 @@
     $return{is_internal} = $self->{is_internal};
     $return{operation}   = $self->{operation};
     $return{document_id} = $self->{document_id};
+    $return{file_name}   = $self->{file_name};
 
     # save necessary URI parts
     $return{scheme}      = $uri->scheme;
@@ -368,6 +460,7 @@
     $self->{is_internal} = $data->{is_internal};
     $self->{operation}   = $data->{operation};
     $self->{document_id} = $data->{document_id};
+    $self->{file_name}   = $data->{file_name};
 }
 
 1;


More information about the MKDoc-commit mailing list