Forum OpenACS Development: how to import image via url?

Collapse
Posted by Torben Brosten on
How should one code a proc to import an image into the file system from a url?
Collapse
Posted by Dave Bauer on
AOLserver specific
ns_http http://panoptic.com/wiki/aolserver/Ns_http
ns_httpopen http://panoptic.com/wiki/aolserver/Ns_httpopen

OpenACS specific
ad_httpget https://openacs.org/api-doc/proc-view?proc=ad%5fhttpget
util_httpget https://openacs.org/api-doc/proc-view?proc=util%5fhttpget

Not sure why there are two openacs specific procs.

It looks like the new aolserver 4 procs I listed there are sufficient and the OpenACS ones should be deprecated or at least improved to use the AOLserver 4 apis.

Collapse
Posted by Torben Brosten on
So.. the image is collected in to a variable, and then saved into the file system.

I assumed these only worked for text, and that binary encoded files would be handled differently. Thank you!

Collapse
Posted by Tom Jackson on

Torben,

Part of the problems is that there are so many ways to do it that are good, a lot of people roll their own to get exactly what they want. For instance, I have been looking at the new ns_http which is only available in AOLserver 4.5 (maybe ported to naviserver, but not in earlier AOLservers). This is good for handing off work to another thread. You can queue the request and an smart client thread could go about handling the details of download, retry, etc. You can't really do that in a connection thread. Or, you could queue the request, close the connection with [ns_conn close] then do a [ns_http wait] on the queued request. One advantage is that [ns_http queue] will complain if the request url doesn't look valid. Essentially, you simplify the logic of building a smart client. Nobody's really done it yet.

The four Tcl level AOLserver commands are ns_httpget, ns_httppost, ns_httpsget or ns_httpspost

Since these commands use ns_sock commands, the result should be 'binary', or exactly as received with no encoding conversions of other modifications. You should be able to open a file, fconfigure -binary and write the result.

Collapse
Posted by Torben Brosten on
Thanks, Tom. Amazingly, ns_http with queue and wait is working with aolserver 4.0.10. I just didn't expect it to work with images.. am going to try it with images later today (and will report results here).
Collapse
Posted by Torben Brosten on

It's not working for me..

Heres the code in the tcl page:

ad_page_contract {
    @ test
} {
    { url "http://kappacorp.com/fwgoofiness.jpg" }
}

if {[catch {set get_id [ns_http queue GET $url]} err ]} {
    set page $err
} else {
    set status [ns_http wait $get_id page]

    if { $status eq 1 } {
        ns_log Notice "get-image.tcl status $status , page $page"
    } else {
        # no page info returned, just record warning                                                                                                                                       
        ns_log Notice "ref 101: Error: status: $status , url: $url , page: $page"
    }
}
ns_return 200 image/jpeg $page

Whatever the image, it seems that 9 bytes are returned that get interpreted as 4 or 5 nonstandard characters.. depending on the interface. What am I doing wrong?

Collapse
Posted by Torben Brosten on

ns_http works for text in aolserver 4.0.10, but not images. ns_httpget does appear to get the image contents, but this code does not display it, still (at least for safari and firefox), but does see okay when I send an http test request via telnet 80.

ad_page_contract {
    @ test
} {
    { url "http://kappacorp.com/fwgoofiness.jpg" }
}
set mime_type "image/jpeg"
set status 200
set nsd_version [ns_info version]
if { $nsd_version < 4.5 } {
    # pre aolserver 4.5 technique                                                                                                                                                          
    if {[catch {set page [ns_httpget $url]} err ]} {
        set page $err
        set mime_type "text/plain"
    } else {
        set page_sample [string range $page 0 20]
        ns_log Notice "get-image.tcl nsd_version: $nsd_version , url: $url , page_sample $page_sample"
    }

} else {

    if {[catch {set get_id [ns_http queue GET $url]} err ]} {
        set page $err
        set mime_type "text/plain"
    } else {
        set status [ns_http wait $get_id page]
        set page_sample [string range $page 0 20]
        ns_log Notice "get-image.tcl nsd_version: $nsd_version , status $status , url: $url , page_sample: $page_sample"
    }

}
ns_return $status $mime_type $page

Any suggestions on getting the display part to work?

Collapse
Posted by Gustaf Neumann on
Torben,

here is a short version based on the relatively new xotcl-core class ::xo::HttpRequest (cvs head)

ad_page_contract {
    @ test
} {
    { url "http://kappacorp.com/fwgoofiness.jpg" }
}

set r [::xo::HttpRequest new -url $url]
ns_headers connid [$r set status_code] [$r set content_type] [$r set content_length]
ns_write [$r set data]

Note that this version does not require you to write into the file system. Most probably, you can do similar with ns_http*.

-gustaf neumann
Collapse
Posted by Tom Jackson on

In AOLserver 4.5, the following works for me:

set id [ns_http queue http://192.168.1.102:8000/sns-thumb.jpg]

set ok [ns_http wait -result image -status status $id]

if {"$status" == "200"} {
    set fd [open [file join [file dirname [info script]] myimage.jpg] w+]
} else {
    ns_return $status text/html $image
    return -code return
}

# Very important:
fconfigure $fd -translation binary

puts $fd $image
close $fd

ns_return $status text/html "Status: $status <br>
<la href=\"/myimage.jpg\">My Image</a>"

ns_http queue and ns_http wait can be in different threads.

Collapse
Posted by Dave Bauer on
Why not save it in a file and display it with ns_returnfile.

I am guessing you are not going to want to download the file every time.

Collapse
Posted by Torben Brosten on
Actually, yes, I do plan to save the file, as a form of cache, because we don't want to hammer the vendor sites. I'll try with ns_returnfile. Thanks.