X-Git-Url: https://git.xandkar.net/?a=blobdiff_plain;f=tt;h=46059434d82510efacb51cb1d2975da08f969e58;hb=e5c3ae92a01b721a4f9ac27daaed6b2dfff7a060;hp=62499bbfbfeb285ac728aa5b5d897e97f92a36c3;hpb=d6a187b7487fd369119d018a238696ba750793e7;p=tt.git diff --git a/tt b/tt index 62499bb..4605943 100755 --- a/tt +++ b/tt @@ -1,6 +1,7 @@ #! /usr/bin/env racket ; vim: filetype=racket +; TODO optional text wrap ; TODO write ; TODO caching (use cache by default, unless explicitly asked for update) ; TODO timeline limits @@ -10,11 +11,32 @@ ; TODO named timelines ; TODO CLI params ; TODO config files +; TODO parse mentions: +; - @ | @ ; TODO highlight mentions ; TODO filter on mentions ; TODO highlight hashtags ; TODO filter on hashtags +; TODO hashtags as channels? initial hashtag special? ; TODO query language +; TODO concurrency +; TODO console logger colors by level ('error) +; TODO file logger ('debug) +; TODO commands: +; - r | read +; - see timeline ops above +; - w | write +; - arg or stdin +; - nick expand to URI +; - q | query +; - see timeline ops above +; - see hashtag and channels above +; - d | download +; - u | upload +; - calls user-configured command to upload user's own feed file to their server +; TODO user-agent format: / (+; @) +; - requires configurability +; - ref: https://twtxt.readthedocs.io/en/latest/user/discoverability.html #lang racket @@ -23,21 +45,26 @@ (require http-client) (require rfc3339-old) -(struct msg (tm_epoch tm_rfc3339 nick text)) +(struct msg (tm_epoch tm_rfc3339 nick uri text)) (struct feed (nick uri)) -(define (msg-print odd m) - (printf "~a \033[1;37m<~a>\033[0m \033[0;~am~a\033[0m~n" - (date->string (seconds->date [msg-tm_epoch m]) #t) - [msg-nick m] - [if odd 36 33] - [msg-text m])) +(define (msg-print out-format odd msg) + (printf + (match out-format + ['single-line "~a \033[1;37m<~a ~a>\033[0m \033[0;~am~a\033[0m~n"] + ['multi-line "~a~n\033[1;37m<~a ~a>\033[0m~n\033[0;~am~a\033[0m~n~n"] + [_ (raise (format "Invalid output format: ~a" out-format))]) + (date->string (seconds->date [msg-tm_epoch msg]) #t) + (msg-nick msg) + (msg-uri msg) + (if odd 36 33) + (msg-text msg))) (define re-msg-begin ; TODO Zulu offset. Maybe in several formats. Which ones? (pregexp "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}")) -(define (str->msg nick str) +(define (str->msg nick uri str) (if (not (regexp-match? re-msg-begin str)) (begin (log-debug "Non-msg line from nick:~a, line:~a" nick str) @@ -58,13 +85,13 @@ [rfc3339-record:mday t] [rfc3339-record:month t] [rfc3339-record:year t])]) - (msg tm_epoch tm_rfc3339 nick tok_text)))))) + (msg tm_epoch tm_rfc3339 nick uri tok_text)))))) (define (str->lines str) (string-split str (regexp "[\r\n]+"))) -(define (str->msgs nick str) - (filter-map (λ (line) (str->msg nick line)) (str->lines str))) +(define (str->msgs nick uri str) + (filter-map (λ (line) (str->msg nick uri line)) (str->lines str))) (define (uri-fetch uri) (log-info "GET ~a" uri) @@ -76,40 +103,37 @@ ; TODO Handle redirects (if (= status 200) body (raise status))) -(define (timeline-print timeline) +(define (timeline-print out-format timeline) (for ([msg timeline] [i (in-naturals)]) - (msg-print (odd? i) msg))) - + (msg-print out-format (odd? i) msg))) + +(define (feed->msgs feed) + (log-info "downloading feed nick:~a uri:~a" + (feed-nick feed) + (feed-uri feed)) + (with-handlers + ([exn:fail:network? + (λ (e) + (log-error "network error nick:~a uri:~a exn:~a" + (feed-nick feed) + (feed-uri feed) + e) + #f)] + [integer? + (λ (status) + (log-error "http error nick:~a uri:~a status:~a" + (feed-nick feed) + (feed-uri feed) + status) + #f)]) + (define uri (feed-uri feed)) + (str->msgs [feed-nick feed] uri [uri-fetch uri]))) + +; TODO timeline contract : time-sorted list of messages (define (timeline feeds) - (let* ([timelines - (filter-map - (λ (feed) - (log-info "processing feed nick:~a uri:~a" - (feed-nick feed) - (feed-uri feed)) - (with-handlers - ([exn:fail:network? - (λ (e) - (log-error "network error nick:~a uri:~a exn:~a" - (feed-nick feed) - (feed-uri feed) - e) - #f)] - [integer? - (λ (status) - (log-error "http error nick:~a uri:~a status:~a" - (feed-nick feed) - (feed-uri feed) - status) - #f)]) - (str->msgs [feed-nick feed] [uri-fetch (feed-uri feed)]))) - feeds)] - [timeline - (append* timelines)] - [timeline - (sort timeline (λ (a b) [< (msg-tm_epoch a) (msg-tm_epoch b)]))]) - timeline)) + (sort (append* (filter-map feed->msgs feeds)) + (λ (a b) [< (msg-tm_epoch a) (msg-tm_epoch b)]))) (define (we-are-twtxt) (let* ([uri @@ -120,6 +144,7 @@ (str->lines payload)] [feeds (map (λ (line) + ; TODO validation (define toks (string-split line)) (feed [list-ref toks 0] @@ -148,6 +173,7 @@ (date-display-format 'rfc2822) (define feeds (we-are-twtxt)) - (timeline-print (timeline feeds))) + (define out-format 'multi-line) + (timeline-print out-format (timeline feeds))) (main)