live-value.rkt
#lang racket

(require net/url)

(provide (contract-out [live-web-value (-> string? string? string? 
                                           number?)]
                       [live-web-number (->* (string? string? string?)
                                             (number? number?)
                                             number?)])) 

(define (live-web-value url key-line regexp-pattern)
  (let* ((in (get-pure-port (string->url url)))
         (the-line (do ((the-line (read-line in) (read-line in)))
                     ((regexp-match key-line the-line) the-line))))
    (string->number (first (regexp-match regexp-pattern the-line)))))

(define (extract-number s)
  (let ([a (car (first (regexp-match-positions* "[0-9]" s)))]
        [b (cdr (last (regexp-match-positions* "[0-9]" s)))])
    (substring s a b)))

(define (convert-to-number s)
  (let ([x (string->number s)]) 
    (if (not x)
        (string->number (regexp-replace "," s ""))
        x)))

(define (live-web-number url key-line regexp-pattern [error-value 0] [delta-nb-lines 0])
  (with-handlers ([exn:fail? (lambda (exn) error-value)])
    (let* ([in (get-pure-port (string->url url))]
           [the-line (do ([the-line (read-line in) (read-line in)])
                       ((regexp-match key-line the-line) the-line))]
           [x error-value])
      (for ([i delta-nb-lines])
        (set! the-line (read-line in)))
      (set! x (convert-to-number (extract-number (first (regexp-match regexp-pattern the-line)))))
      (if (not x)
          error-value
          x))))