-; uri-download : String -> Void
-(define (uri-download uri)
- (define cache-file-path
- (expand-user-path (string-append "~/.tt/cache/" (hash-sha1 uri))))
- (log-info "uri-download ~a" uri)
- ; TODO Timeout. Currently hangs on slow connections.
- (let* ([resp (http-get uri)]
- [status (http-response-code resp)]
- [body (http-response-body resp)])
- (log-debug "finished GET ~a status:~a body length:~a"
- uri status (string-length body))
- ; TODO Handle redirects
- (if (= status 200)
- (display-to-file body cache-file-path #:exists 'replace)
- ; TODO A more-informative exception
- (raise status))))
+(define (str->feed str)
+ (log-debug "Parsing feed string: ~v" str)
+ (match (string-split str)
+ [(list nick u)
+ (with-handlers*
+ ([exn:fail?
+ (λ (e)
+ (log-error "Invalid URI: ~v, exn: ~v" u e)
+ #f)])
+ (feed nick (string->url u)))]
+ [_
+ (log-error "Invalid feed string: ~v" str)
+ #f]))
+
+(define (filter-comments lines)
+ (filter-not (λ (line) (string-prefix? line "#")) lines))
+
+(define (str->feeds str)
+ (filter-map str->feed (filter-comments (str->lines str))))
+
+(define (file->feeds filename)
+ (str->feeds (file->string filename)))
+
+(define user-agent
+ (let*
+ ([prog-name "tt"]
+ [prog-version ((info:get-info (list prog-name)) 'version)]
+ [prog-uri "https://github.com/xandkar/tt"]
+ [user-feed-file (expand-user-path "~/twtxt-me.txt")]
+ [user
+ (if (file-exists? user-feed-file)
+ (let ([user (first (file->feeds user-feed-file))])
+ (format "+~a; @~a" (url->string (feed-uri user)) (feed-nick user)))
+ (format "+~a" prog-uri))])
+ (format "~a/~a (~a)" prog-name prog-version user)))
+
+; uri-download : net/url-structs:url -> Void
+(define (uri-download u)
+ (define cache-file-path (url->cache-file-path u))
+ (log-debug "uri-download ~v into ~v" u cache-file-path)
+ (match* ((url-scheme u) (url-host u) (url-port u))
+ [(s h p)
+ #:when (and s h)
+ (define ssl? (string=? s "https"))
+ (define-values (status-line headers body-input)
+ ; TODO Timeout. Currently hangs on slow connections.
+ (http-sendrecv
+ h
+ (url->string (struct-copy url u [scheme #f] [host #f]))
+ #:ssl? ssl?
+ #:port (cond [p p] [ssl? 443] [else 80])
+ #:headers (list (format "User-Agent: ~a" user-agent))
+ ))
+ (log-debug "headers: ~v" headers)
+ (log-debug "status-line: ~v" status-line)
+ (define status
+ (string->number (second (string-split (bytes->string/utf-8 status-line)))))
+ (log-debug "status: ~v" status)
+ ; TODO Handle redirects
+ (if (= 200 status)
+ (call-with-output-file cache-file-path
+ (λ (cache-output)
+ (copy-port body-input cache-output))
+ #:exists 'replace)
+ (raise status))]
+ [(_ _ _)
+ (log-error "Invalid URI: ~v" u)]))