namespace eval feed { proc ::feed::serve_skeleton {feeds publisher _ sock path query headers} { if ![dict exists $query feed] { puts $sock "HTTP/1.0 400 Bad Request" puts $sock "Content-Type: text/plain" puts $sock "" puts $sock "Missing 'feed' query parameter." puts $sock "" close $sock return } if ![dict exists $query cursor] { dict set query cursor 0 } if ![dict exists $query limit] { dict set query limit 50 } if [catch { set feed [dict get $query feed] set cursor [expr {max(0, [dict get $query cursor])}] set limit [expr {max(1, min(100, [dict get $query limit]))}] }] { puts $sock "HTTP/1.0 400 Bad Request" puts $sock "Content-Type: text/plain" puts $sock "" puts $sock "Check your parameter syntax, IDK." puts $sock "" close $sock return } set feed [::at::uri $feed] if {[llength $feed] != 6 || [dict get $feed authority] != $publisher || [dict get $feed collection] != "app.bsky.feed.generator"} { puts $sock "HTTP/1.0 400 Bad Request" puts $sock "Content-Type: text/plain" puts $sock "" puts $sock "Invalid at:// URI." puts $sock "" close $sock return } set feed [dict get $feed rkey] if {[lsearch -exact $feeds $feed] == -1} { puts $sock "HTTP/1.0 404 Not Found" puts $sock "Content-Type: text/plain" puts $sock "" puts $sock "Not a feed." puts $sock "" close $sock return } set feed_data {} foreach uri [db eval "SELECT uri FROM $feed ORDER BY ord DESC LIMIT $limit OFFSET $cursor;"] { lappend feed_data [::json::write object \ post [::json::write string $uri]] } set feed_data_arr [::json::write array {*}$feed_data] set feed_contents [::json::write object \ cursor [::json::write string \ [expr {$cursor + min([llength $feed_data], $limit)}]] \ feed $feed_data_arr] puts $sock "HTTP/1.0 200 OK" puts $sock "Content-Type: application/json" puts $sock "Content-Length: [string length $feed_contents]" puts $sock "" fconfigure $sock -translation binary puts -nonewline $sock $feed_contents close $sock return } proc ::feed::generator_description {feeds publisher self_host} { set feed_uris {} foreach feed $feeds { lappend feed_uris [::json::write object \ uri [::json::write string "at://$publisher/app.bsky.feed.generator/$feed"]] } set feed_uris [::json::write array {*}$feed_uris] set description [::json::write object \ did [::json::write string "did:web:$self_host"] \ feeds $feed_uris] return $description } proc ::feed::well_known {feeds self_host} { ::json::write object \ @context {["https://www.w3.org/ns/did/v1"]} \ id [::json::write string did:web:$self_host] \ service [::json::write array \ [::json::write object \ id {"#bsky_fg"} \ serviceEndpoint [::json::write string https://$self_host] \ type {"BskyFeedGenerator"}]] } }