Skip to content

Commit 85f1045

Browse files
committed
Add #:contact-info to commands
Docs not yet written
1 parent a3c7e87 commit 85f1045

File tree

7 files changed

+195
-63
lines changed

7 files changed

+195
-63
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@
55
compiled/
66
/doc/
77
session.key
8+
contact.txt

answer.rkt

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,28 @@
44
net/uri-codec
55
racket/port
66
racket/format
7-
advent-of-code/request
8-
(only-in advent-of-code/input advent-day? advent-year?))
7+
"request.rkt"
8+
"meta.rkt"
9+
(only-in "input.rkt" advent-day? advent-year?))
910

1011
(provide (contract-out
11-
[aoc-submit (-> aoc-session? advent-year? advent-day?
12-
(or/c 1 2) any/c
13-
string?)]
14-
[aoc-submit* (-> aoc-session? advent-year? advent-day?
15-
(or/c 1 2) any/c
16-
input-port?)])
12+
[aoc-submit (->* (aoc-session?
13+
advent-year? advent-day?
14+
(or/c 1 2) any/c)
15+
(#:contact-info string?)
16+
string?)]
17+
[aoc-submit* (->* (aoc-session?
18+
advent-year? advent-day?
19+
(or/c 1 2) any/c)
20+
(#:contact-info string?)
21+
input-port?)])
1722
advent-day?
1823
advent-year?)
1924

20-
(define (aoc-submit* session year day part answer)
25+
(define (aoc-submit* session year day part answer
26+
#:contact-info [contact-info (find-contact-info)])
2127
(aoc-request session year "day" day "answer"
28+
#:contact-info contact-info
2229
#:post
2330
(lambda (hs)
2431
(values
@@ -29,8 +36,10 @@
2936
`((level . ,(~a part))
3037
(answer . ,(~a answer))))))))
3138

32-
(define (aoc-submit session year day part answer)
33-
(define response (port->string (aoc-submit* session year day part answer)))
39+
(define (aoc-submit session year day part answer
40+
#:contact-info [contact-info (find-contact-info)])
41+
(define response (port->string (aoc-submit* session year day part answer
42+
#:contact-info contact-info)))
3443
(define matches (regexp-match #px"<article><p>(.*)</p></article>" response))
3544
(if matches
3645
(regexp-replace*

info.rkt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
(define build-deps '("scribble-lib" "racket-doc" "net-doc"))
55
(define scribblings '(("scribblings/advent-of-code.scrbl" ())))
66
(define pkg-desc "Package for fetching Advent of Code input.")
7-
(define version "1.0.2")
7+
(define version "1.1.0")
88
(define pkg-authors '(eutro))
99
(define raco-commands
1010
'(("aoc" (submod advent-of-code main) "Fetch Advent of Code puzzle input" #f)))

input.rkt

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,34 @@
22

33
(require racket/contract/base
44
racket/port
5-
advent-of-code/request)
5+
"request.rkt"
6+
"meta.rkt")
67

78
(provide (contract-out
89
[open-aoc-input (->* (aoc-session? advent-year? advent-day?)
9-
(#:cache (or/c boolean? path-string?))
10+
(#:cache (or/c boolean? path-string?)
11+
#:contact-info string?)
1012
input-port?)]
1113
[fetch-aoc-input (->* (aoc-session? advent-year? advent-day?)
12-
(#:cache (or/c boolean? path-string?))
14+
(#:cache (or/c boolean? path-string?)
15+
#:contact-info string?)
1316
string?)]
1417
[advent-day? flat-contract?]
1518
[advent-year? flat-contract?]))
1619

1720
(define advent-day? (integer-in 1 25))
1821
(define advent-year? (and/c exact-integer? (>=/c 2015)))
1922

20-
(define (open-aoc-input session year day #:cache [cache #f])
21-
(aoc-request session year "day" day "input" #:cache cache))
23+
(define (open-aoc-input session year day
24+
#:contact-info [contact-info (find-contact-info)]
25+
#:cache [cache #t])
26+
(aoc-request session year "day" day "input"
27+
#:cache cache
28+
#:contact-info contact-info))
2229

23-
(define (fetch-aoc-input session year day #:cache [cache #f])
24-
(port->string (open-aoc-input session year day #:cache cache)))
30+
(define (fetch-aoc-input session year day
31+
#:cache [cache #t]
32+
#:contact-info [contact-info (find-contact-info)])
33+
(port->string (open-aoc-input session year day
34+
#:cache cache
35+
#:contact-info contact-info)))

main.rkt

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
#lang racket/base
22

3-
(require advent-of-code/request
4-
advent-of-code/input
5-
advent-of-code/answer
6-
advent-of-code/meta)
3+
(require "request.rkt"
4+
"input.rkt"
5+
"answer.rkt"
6+
"meta.rkt")
77

8-
(provide (all-from-out
9-
advent-of-code/request
10-
advent-of-code/input
11-
advent-of-code/answer
12-
advent-of-code/meta))
8+
(provide (all-from-out "request.rkt"
9+
"input.rkt"
10+
"answer.rkt"
11+
"meta.rkt"))
1312

1413
(module+ main
1514
(require racket/cmdline
1615
raco/command-name
1716
racket/port)
1817

1918
(define sessionb (box #f))
19+
(define contactb (box #f))
2020
(define yearb (box #f))
2121
(define dayb (box #f))
2222
(define cacheb (box #t))
@@ -26,6 +26,7 @@
2626
#:program (short-program+command-name)
2727
#:once-each
2828
[("-s" "--session") session "The session cookie" (set-box! sessionb session)]
29+
[("-i" "--contact-info") email-or-url "Contact information" (set-box! contactb email-or-url)]
2930
[("-y" "--year") year "The year to query for" (set-box! yearb (string->number year))]
3031
[("-d" "--day") day "The day to fetch the input for" (set-box! dayb (string->number day))]
3132
#:once-any
@@ -50,6 +51,7 @@
5051
(raise e))])
5152
(define now (current-aoc-time))
5253
(define session (or (unbox sessionb) (find-session)))
54+
(define contact (or (unbox contactb) (find-contact-info)))
5355
(define year
5456
(or (unbox yearb)
5557
((if (= (date-month now) 12) values sub1)
@@ -59,6 +61,8 @@
5961
(max 1 (min 25 (date-day now)))))
6062
(define ans (unbox answerb))
6163
(if ans
62-
(displayln (aoc-submit session year day (car ans) (cdr ans)))
63-
(copy-port (open-aoc-input session year day #:cache (unbox cacheb))
64+
(displayln (aoc-submit session year day (car ans) (cdr ans)
65+
#:contact-info contact))
66+
(copy-port (open-aoc-input session year day #:cache (unbox cacheb)
67+
#:contact-info contact)
6468
(current-output-port)))))

meta.rkt

Lines changed: 126 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,28 @@
22

33
(require racket/contract/base
44
racket/runtime-path
5+
racket/system
6+
racket/port
57
racket/file
68
racket/string
7-
advent-of-code/request
89
net/sendurl
9-
net/url)
10+
net/url
11+
(for-syntax racket/base
12+
racket/path
13+
setup/getinfo))
1014

1115
(provide (contract-out
16+
[aoc-url url?]
17+
[aoc-session? predicate/c]
1218
[current-aoc-time (-> date?)]
1319
[session-file path-string?]
14-
[find-session (-> aoc-session?)]))
20+
[contact-info-file path-string?]
21+
[find-session (-> aoc-session?)]
22+
[find-contact-info (-> string?)]
23+
[contact-info->user-agent (-> string? bytes?)]))
24+
25+
(define (aoc-session? s) (string? s))
26+
(define aoc-url (string->url "https://adventofcode.com"))
1527

1628
(define (current-aoc-time)
1729
(define aoc-offset (- (* 5 60 60)))
@@ -20,6 +32,7 @@
2032
#f))
2133

2234
(define-runtime-path session-file "session.key")
35+
(define-runtime-path contact-info-file "contact.txt")
2336

2437
(define (y-or-n prompt [default #f])
2538
(printf "~a [~a/~a] "
@@ -42,34 +55,125 @@
4255
(parameterize ([current-output-port (current-error-port)])
4356
(displayln "Session key unset or expired.")
4457
(printf "Please set ~a~n" session-file)
45-
(when (not (eq? 'y (y-or-n "Set interactively now?" 'y)))
46-
(exit 1))
58+
(unless (eq? 'y (y-or-n "Set interactively now?" 'y))
59+
(raise-user-error "Session key unset or expired"))
4760
(when (eq? 'y (y-or-n "Open Advent of Code in browser?" 'y))
4861
(send-url (url->string aoc-url)))
4962
(displayln "Hint: Your cookies can typically be found in the developer console.")
5063
(displayln "- Firefox: \"Storage\" tab (Shift + F9)")
5164
(displayln "- Chrome: \"Application\" tab")
5265
(displayln "Enter the contents of your session cookie below:")
5366
(define session (read-line (current-input-port) 'any))
54-
(when (eof-object? session)
55-
(exit 1))
56-
(with-output-to-file session-file
57-
#:exists 'replace
58-
(lambda ()
59-
(display session)
60-
(flush-output)))
67+
(when (or (eof-object? session) (string=? "" session))
68+
(raise-user-error "No input provided"))
69+
(display-to-file session session-file #:exists 'replace)
6170
(displayln "Session set successfully!")))
6271

72+
(define month-seconds (* 31 24 60 60))
73+
(define (older-than-seconds? path seconds)
74+
(let/ec return
75+
(define csec (current-seconds))
76+
(define file-seconds
77+
(file-or-directory-modify-seconds
78+
path #f (lambda () (return #t))))
79+
(<= seconds (- csec file-seconds))))
80+
6381
(define (find-session)
64-
(define csec (current-seconds))
65-
(define month-seconds (* 31 24 60 60))
66-
(when (<=
67-
month-seconds
68-
(-
69-
csec
70-
(file-or-directory-modify-seconds
71-
session-file
72-
#f
73-
(lambda () (- csec month-seconds)))))
82+
(when (older-than-seconds? session-file month-seconds)
7483
(refresh-session!))
7584
(string-trim (file->string session-file)))
85+
86+
(define (raw-find-contact-info)
87+
(and (file-exists? contact-info-file)
88+
(string-trim (file->string contact-info-file))))
89+
90+
(define (refresh-contact-info!)
91+
(let/ec return
92+
(parameterize ([current-output-port (current-error-port)])
93+
(displayln "Contact information unset or possibly outdated.")
94+
(displayln "Eric Wastl asks that you include a way to be contacted in automated requests.")
95+
(cond
96+
[(raw-find-contact-info)
97+
=>
98+
(lambda (contact-info)
99+
(printf "Your current contact information at ~a is:~n" contact-info-file)
100+
(printf " ~a~n" contact-info))]
101+
[else
102+
(printf "Please set ~a to a suitable email address or URL.~n" contact-info-file)])
103+
(unless (eq? 'y (y-or-n "Set interactively now?" 'y))
104+
(cond
105+
[(raw-find-contact-info)
106+
(file-or-directory-modify-seconds contact-info-file (current-seconds)
107+
#;fail void)
108+
(return (void))]
109+
[else
110+
(raise-user-error "Could not find contact information")]))
111+
(define contact-info
112+
(cond
113+
[(and (find-executable-path "git")
114+
(eq? 'y (y-or-n "Use contact information from git?" 'y))
115+
(or (contact-info-from-git)
116+
(begin
117+
(displayln "Error calling git")
118+
#f)))
119+
=> values]
120+
[else
121+
(displayln "Enter your contact information below:")
122+
(read-line (current-input-port) 'any)]))
123+
(when (or (eof-object? contact-info) (string=? "" contact-info))
124+
(raise-user-error "No input provided"))
125+
(displayln "This library will send the following User-Agent to Advent of Code:")
126+
(printf " ~s~n" (contact-info->user-agent contact-info))
127+
(unless (eq? 'y (y-or-n "Is that okay?" 'y))
128+
(raise-user-error "Not accepted"))
129+
(display-to-file contact-info contact-info-file #:exists 'replace)
130+
(displayln "Contact information set successfully!"))))
131+
132+
(define (guess-interactive?)
133+
(terminal-port? (current-input-port)))
134+
135+
(define (find-contact-info)
136+
(when (and (guess-interactive?)
137+
(older-than-seconds? contact-info-file month-seconds))
138+
(refresh-contact-info!))
139+
(cond
140+
[(raw-find-contact-info) => values]
141+
[else
142+
(define-logger advent-of-code-racket)
143+
(log-advent-of-code-racket-error
144+
"No contact information set. Please set ~a to an email address or URL."
145+
contact-info-file)
146+
"unknownlibraryuser@example.com"]))
147+
148+
(define (contact-info-from-git)
149+
(define git (find-executable-path "git"))
150+
(define (git-config key)
151+
(let/ec return
152+
(parameterize ([current-error-port (open-output-nowhere)])
153+
(string-trim
154+
(with-output-to-string
155+
(lambda ()
156+
(unless (zero? (system*/exit-code git "config" key))
157+
(return #f))))))))
158+
(git-config "user.email"))
159+
160+
;; Taken from http-easy
161+
(begin-for-syntax
162+
(define this-path (path-only (syntax-source #'here)))
163+
(define info-ref (get-info/full this-path)))
164+
(define-syntax (get-lib-version stx)
165+
(datum->syntax stx (info-ref 'version) stx))
166+
(define lib-version (get-lib-version))
167+
168+
(define (contact-info->user-agent contact-info)
169+
(call-with-output-bytes
170+
(lambda (out)
171+
(fprintf out
172+
"advent-of-code-racket/~a (~a; racket[~a] ~a; +~a)"
173+
lib-version
174+
(system-type 'os)
175+
(case (system-type 'vm)
176+
[(chez-scheme) 'CS]
177+
[else 'BC])
178+
(version)
179+
contact-info))))

0 commit comments

Comments
 (0)