You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
116 lines
4.0 KiB
116 lines
4.0 KiB
#lang racket
|
|
|
|
(require json
|
|
gregor
|
|
redis
|
|
simple-http
|
|
"votes.rkt")
|
|
|
|
|
|
(provide get-commits/github
|
|
get-commits/redis
|
|
store-commits!
|
|
remove-expired-commits!
|
|
remove-all-commits!
|
|
vote-commit!
|
|
(struct-out feed-commit))
|
|
|
|
|
|
; A struct type to store details about commits from various places
|
|
(struct feed-commit (author repository content timeposted hash url repository-url) #:transparent)
|
|
|
|
;; Check for tweets that have expired and remove them
|
|
(define (remove-expired-commits! client)
|
|
(remove-expired-keys! client (list "commit-score:" "commit-time:")))
|
|
|
|
|
|
;; Remove all commits
|
|
(define (remove-all-commits! client)
|
|
(remove-all-keys! client "commit*"))
|
|
|
|
|
|
;; Get tweets from github, storing them in a struct
|
|
(define (get-commits/github username reponame #:page [page 1] #:per-page [per-page 10])
|
|
(define (->struct commit)
|
|
(let* [(commit-dict (hash-ref commit 'commit))
|
|
(author-dict (hash-ref commit-dict 'committer))
|
|
(author (hash-ref author-dict 'name))
|
|
(content (hash-ref commit-dict 'message))
|
|
(timeposted (hash-ref author-dict 'date))
|
|
(url (hash-ref commit 'html_url))
|
|
(repository-url (string->bytes/utf-8
|
|
(string-append
|
|
"https://github.com/"
|
|
username
|
|
"/"
|
|
reponame)))
|
|
(hash (hash-ref commit 'sha))]
|
|
(feed-commit author reponame content timeposted hash url repository-url)))
|
|
|
|
(let* ([requester (update-ssl (update-host json-requester "api.github.com") #t)]
|
|
[params `((page . ,(number->string page)) (per_page . ,(number->string per-page)))]
|
|
[commits (json-response-body
|
|
(get requester
|
|
(string-append
|
|
"/repos/"
|
|
username
|
|
"/"
|
|
reponame
|
|
"/commits")
|
|
#:params params))])
|
|
(map
|
|
(lambda (commit)
|
|
(->struct commit))
|
|
commits)))
|
|
|
|
|
|
(define (get-commits/redis
|
|
client
|
|
#:key [key "commit-time:"]
|
|
#:start [start 0]
|
|
#:stop [stop -1]
|
|
#:reverse? [reverse? #t])
|
|
(map (lambda (commit/key)
|
|
(redis-hash-get client commit/key))
|
|
(redis-subzset
|
|
client
|
|
key
|
|
#:start start
|
|
#:stop stop
|
|
#:reverse? reverse?)))
|
|
|
|
|
|
(define (store-commits! client commits)
|
|
(define (store-commit! c commit*)
|
|
(let [(key (string-append
|
|
"commit:"
|
|
(feed-commit-hash commit*)))
|
|
(timeposted/seconds (->posix
|
|
(iso8601->datetime
|
|
(feed-commit-timeposted commit*))))]
|
|
(cond
|
|
[(not (redis-has-key? c key))
|
|
(redis-hash-set! c key "author" (feed-commit-author commit*))
|
|
(redis-hash-set! c key "content" (feed-commit-content commit*))
|
|
(redis-hash-set! c key "repository" (feed-commit-repository commit*))
|
|
(redis-hash-set! c key "repository-url" (feed-commit-repository-url commit*))
|
|
(redis-hash-set! c key "timeposted" (feed-commit-timeposted commit*))
|
|
(redis-hash-set! c key "url" (feed-commit-url commit*))
|
|
(redis-hash-set! c key "hash" (feed-commit-hash commit*))
|
|
(redis-hash-set! c key "score" "0")
|
|
(redis-zset-add! c "commit-score:"
|
|
key
|
|
(/ timeposted/seconds 1000000000.0))
|
|
(redis-zset-add! c "commit-time:" key timeposted/seconds)
|
|
(redis-expire-in! c key (* 7 24 60 60 100))
|
|
(redis-zset-add! c "score:" key 0)])))
|
|
(cond
|
|
[(not (null? commits))
|
|
(for-each (lambda (commit*)
|
|
(store-commit! client commit*))
|
|
(if (list? commits)
|
|
commits
|
|
`(,commits)))]))
|
|
|
|
(define (vote-commit! client key #:upvote? [upvote #t])
|
|
(vote! client "commit-score:" key #:upvote? upvote))
|