Class ::xowiki::File

::xowiki::File[i] create ... \
           [ -render_adp (default "0") ]

Defined in

Class Relations

  • class: ::xo::db::CrClass[i]
  • superclass: ::xowiki::Page[i]
  • subclass: ::xowiki::PodcastItem[i]
::xo::db::CrClass create ::xowiki::File \
     -superclass ::xowiki::Page

Methods (to be applied on instances)

  • build_name (scripted)

    if {$name ne ""} {
      set stripped_name $name
      regexp {^(.*):(.*)$} $name _ _t stripped_name
    } else {
      set stripped_name $fn
      # Internet explorer seems to transmit the full path of the
      # filename. Just use the last part in such cases as name.
      regexp {[/\\]([^/\\]+)$} $stripped_name _ stripped_name
    }
    return file:[::${:package_id} normalize_name $stripped_name]
  • demarshall (scripted)

    next
    # we have to care about saving the file content
    
    if {[info exists :__file_content]} {
      ::xo::write_tmp_file :import_file [::base64::decode ${:__file_content}]
      unset :__file_content
    
    } elseif {[info exists :__file_name]} {
      set :import_file ${:__file_name}
      unset :__file_name
    
    } else {
      error "either __file_content or __file_name must be set"
    }
  • file_id (setter)

  • full_file_name (scripted)

    if {![info exists :full_file_name]} {
      if {[info exists :revision_id]} {
        #
        # For a given revision_id, the full_file_name will never
        # change.  Therefore, we can easily cache the full filename
        # for the revision_id.
        #
        set :full_file_name [::xowiki::cache eval -partition_key ${:revision_id} ffn-${:revision_id} {
          return [content::revision::get_cr_file_path -revision_id ${:revision_id}]
        }]
        #:log "--F setting full-file-name of ${:revision_id}  ${:full_file_name}"
      }
    }
    return ${:full_file_name}
  • html_content (scripted)

    set parent_id ${:parent_id}
    set fileName [:full_file_name]
    
    set f [open $fileName r]; set data [read $f]; close $f
    
    # Ugly hack to fight against a problem with tDom: asHTML strips
    # spaces between a </span> and the following <span>"
    #regsub -all -- "/span>      <span" $data "/span>\\&nbsp;\\&nbsp;\\&nbsp;\\&nbsp;\\&nbsp;\\&nbsp;<span" data
    #regsub -all -- "/span>     <span" $data "/span>\\&nbsp;\\&nbsp;\\&nbsp;\\&nbsp;\\&nbsp;<span" data
    #regsub -all -- "/span>    <span" $data "/span>\\&nbsp;\\&nbsp;\\&nbsp;\\&nbsp;<span" data
    #regsub -all -- "/span>   <span" $data "/span>\\&nbsp;\\&nbsp;\\&nbsp;<span" data
    #regsub -all -- "/span>  <span" $data "/span>\\&nbsp;\\&nbsp;<span" data
    
    regsub -all -- "/span> " $data "/span>\\&nbsp;" data
    regsub -all -- " <span " $data "\\&nbsp;<span " data
    regsub -all -- "/span>\n<span " $data "/span><br><span " data
    regsub -all -- "/span>\n\n<span " $data "/span><br><br><span " data
    
    dom parse -simple -- $data doc
    $doc documentElement root
    
    #
    # substitute relative links to download links in the same folder
    #
    set prefix [::$parent_id pretty_link -absolute true -download true]
    foreach n [$root selectNodes //img] {
      set src [$n getAttribute src]
      if {[regexp {^[^/]} $src]} {
        $n setAttribute src $prefix/$src
        #:msg "setting src to $prefix/$src"
      }
    }
    
    #
    # In case, the switch is activated, and we have a menubar, add the
    # top level section
    #
    if {$add_sections_to_folder_tree && [nsf::is object ::__xowiki__MenuBar]} {
      $owner set book_mode 1
      set pages [::xo::OrderedComposite new -destroy_on_cleanup]
      if {$add_sections_to_folder_tree == 1} {
        set selector //h2
      } else {
        set selector {//h2 | //h3}
      }
    
      set order 0
      foreach n [$root selectNodes $selector] {
        if {[$n hasAttribute id]} {
          set name [$n getAttribute id]
        } else {
          set name "section $n"
        }
        set o [::xotcl::Object new]
        $o set page_order [incr $order]
        $o set title [$n asText]
    
        set e [$doc createElement a]
        $e setAttribute name $name
        [$n parentNode] insertBefore $e $n
    
        $o set name $name
        $pages add $o
      }
    
      #$o instvar page_order title name
    
      ::__xowiki__MenuBar additional_sub_menu -kind folder -pages $pages -owner $owner
    }
    
    #
    # return content of body
    #
    set content ""
    foreach n [$root selectNodes //body/*] { append content [$n asHTML] \n }
    
    return $content
  • marshall (scripted)

    set fn [:full_file_name]
    if {$mode eq "export"} {
      set :__file_content [::base64::encode [::xo::read_file $fn]]
    } else {
      set :__file_name $fn
    }
    next
  • mime_type (setter)

  • pretty_name (scripted)

    set name ${:name}
    regsub {^file:} $name "" name
    return $name
  • render_adp (setter)

  • render_content (scripted)

    set parent_id ${:parent_id}
    set package_id ${:package_id}
    # don't require permissions here, such that rss can present the link
    #set page_link [::$package_id make_link -privilege public [self] download ""]
    
    set ctx [::$package_id context]
    set revision_id [$ctx query_parameter revision_id:integer]
    set query [expr {$revision_id ne "" ? "revision_id=$revision_id" : ""}]
    set page_link [:pretty_link -download true -query $query]
    if {[$ctx query_parameter html-content] ne ""} {
      return [:html_content]
    }
    
    #:log "--F page_link=$page_link ---- "
    set t [TableWidget new -volatile  -columns {
                 AnchorField name -label [_ xowiki.Page-name]
                 Field mime_type -label "#xowiki.content_type#"
                 Field last_modified -label "#xowiki.Page-last_modified#"
                 Field mod_user -label "#xowiki.By_user#"
                 Field size -label "#xowiki.Size# (Bytes)"
               }]
    
    regsub {[.][0-9]+([^0-9])} ${:last_modified} {\1} last_modified
    ::$package_id get_lang_and_name -name ${:name} lang stripped_name
    set label $stripped_name
    
    $t add  -name $stripped_name  -mime_type ${:mime_type}  -name.href $page_link  -last_modified $last_modified  -mod_user [::xo::get_user_name ${:creation_user}]  -size [file size [:full_file_name]]
    
    switch -glob ${:mime_type} {
      image/* {
        set l [Link new  -page [self] -query $query  -type image -name ${:name} -lang ""  -stripped_name $stripped_name -label $label  -parent_id $parent_id -item_id ${:item_id} -package_id $package_id]
        set preview "<div >[$l render]</div>"
        $l destroy
      }
      text/plain {
        set text [::xo::read_file [:full_file_name]]
        set preview "<pre class='code'>[::xowiki::Includelet html_encode $text]</pre>"
      }
      default {set preview ""}
    }
    return "$preview[$t asHTML]\n<p>${:description}</p>"
  • render_icon (scripted)

    return {text "<a title='file' class='file-icon'>&nbsp;</a>" is_richtext true}
  • search_render (scripted)

    #  array set "" {mime text/html text "" html "" keywords ""}
    if {${:mime_type} eq "text/plain"} {
      set f [open [:full_file_name] r]; set data [read $f]; close $f
      set result [list text $data mime text/plain]
    } elseif {[::namespace which ::search::convert::binary_to_text] ne ""} {
      set txt [search::convert::binary_to_text  -filename [:full_file_name]  -mime_type ${:mime_type}]
      set result [list text $txt mime text/plain]
    } else {
      set result [list text "" mime text/plain]
    }
    
    #ns_log notice "search_render returns $result"
    return $result
  • storage_type (setter)

  • www-download (scripted, public)

     <instance of xowiki::File[i]> www-download

    This web-callable method downloads the file content of the current File object. The following query parameter can be used to influence the behavior

    Testcases:
    xowiki_test_cases
    #
    # The package where the object is coming from might be different
    # from the package on which it is delivered. Use the latter one
    # with the proper delivery information.
    #
    set package_id [::xo::cc package_id]
    #
    # Use always ad_returnfile_background, it is clever enough to use
    # the right delivery mode in case of doubt.
    #
    
    if {[:exists_query_parameter filename]} {
      set fn [::xo::backslash_escape \" [:query_parameter filename]]
      ns_set put [ns_conn outputheaders] Content-Disposition "attachment;filename=\"$fn\""
    }
    
    set full_file_name [:full_file_name]
    
    if {![ad_file exists $full_file_name]} {
      #
      # This should not happen on a production system. In certain
      # testing setups, a system admin might not have provided the
      # full content repository.  We fail more gracefully in this
      # case.
      #
      ad_log error "The file '$full_file_name' does not exist."  "Maybe the content repository is (partially) missing?"
    
      return [::${:package_id} error_msg -status_code 500 [subst {
        No file for link <b>'[ns_quotehtml [ns_conn url]]'</b> available.<br>
        Please report this to the web master of this site.
      }]]
    }
    
    ::$package_id set mime_type ${:mime_type}
    ::$package_id set delivery ad_returnfile_background
    
    #:log "--F FILE=$full_file_name // ${:mime_type}"
    
    set geometry [::xo::cc query_parameter geometry ""]
    if {[string match "image/*" ${:mime_type}]
        && $geometry ne ""
      } {
      if {![regexp {^\d*x?\d*$} $geometry]} {
        error "invalid geometry $geometry"
      }
      set tmpdir [ad_tmpdir]
      if {![ad_file isdirectory $tmpdir/$geometry]} {
        file mkdir $tmpdir/$geometry
      }
      set scaled_image $tmpdir/$geometry/${:revision_id}
      if {![ad_file readable $scaled_image]} {
        set cmd [::util::which convert]
        if {$cmd ne ""} {
          if {![catch {exec $cmd -geometry $geometry -interlace None -sharpen 1x2  $full_file_name $scaled_image}]} {
            return $scaled_image
          }
        }
      } else {
        return $scaled_image
      }
    }
    set modtime [ad_file mtime $full_file_name]
    set cmptime [ns_set iget [ns_conn headers] If-Modified-Since]
    if {$cmptime ne ""} {
      if {[clock scan $cmptime] >= $modtime} {
        #
        # TODO: we should set the status_code and delivery the same
        # way, ... but keep things compatible for now.
        #
        ::xo::cc set status_code 304
        ::$package_id set delivery ns_return
        return ""
      }
    }
    ns_set put [ns_conn outputheaders] Last-Modified [ns_httptime $modtime]
    
    return $full_file_name