guile-pastebin/pastebin/data.scm

data.scm

1
(define-module (pastebin data))
2
3
(use-modules (srfi srfi-9)
4
             (srfi srfi-1)
5
             (ice-9 ftw)
6
             (ice-9 textual-ports))
7
8
(export <pb-data>
9
        <pb-entry>
10
        pb-entry-id
11
        pb-entry-text
12
        pb-data-open
13
        pb-data-close
14
        call-with-dir-as-pb-data
15
        pb-data-get-top
16
        pb-data-new-entry
17
        pb-get-file-path)
18
19
(define-record-type <pb-data>
20
  (make-pb-data dir)
21
  pb-data?
22
  (dir pb-data-dir set-pb-data-dir!))
23
24
(define-record-type <pb-entry>
25
  (make-pb-entry id text)
26
  pb-entry?
27
  (id pb-entry-id set-pb-entry-id!)
28
  (text pb-entry-text set-pb-entry-text!))
29
30
;; input: dir: string
31
;; output: <pb-data>
32
(define (pb-data-open dir)
33
  (make-pb-data dir))
34
35
(define (pb-data-close pb-data) #t)
36
37
(define (call-with-dir-as-pb-data dir p)
38
  (let ((pb-data (pb-data-open dir)))
39
    (let ((R (p pb-data)))
40
      (pb-data-close pb-data)
41
      R)))
42
43
(define (pb-get-file-path pb-data filename)
44
  (string-append (pb-data-dir pb-data) "/" filename))
45
46
;; input: <pb-data>, integer
47
;; output: list of <pb-entry>
48
(define (pb-data-get-top pb-data n)
49
  (map
50
   (lambda (filename)
51
     (make-pb-entry
52
      filename
53
      (call-with-input-file (pb-get-file-path pb-data filename)
54
        (lambda (port)
55
          (get-string-all port)))))
56
   (let ((file-ls (list-files pb-data)))
57
     (reverse (take-right file-ls (min n (length file-ls)))))))
58
59
;; input: <pb-data>, text
60
;; output: <pb-entry>
61
(define (pb-data-new-entry pb-data text)
62
  (let ((next-filename (get-next-filename pb-data)))
63
    (call-with-output-file (pb-get-file-path pb-data next-filename)
64
      (lambda (port)
65
        (put-string port text)))
66
    (make-pb-entry next-filename text)))
67
68
(define (list-files pb-data)
69
  (scandir (pb-data-dir pb-data) (lambda (filename) (= (string-length filename) 5))))
70
71
(define (get-next-filename pb-data)
72
  (let ((entries (list-files pb-data)))
73
    (if (null? entries)
74
        "00000"
75
        (get-next-5digit (last entries)))))
76
77
(define (get-next-5digit str)
78
  (let A ((add #t)
79
          (char-int-ls (reverse (map char->integer (string->list str))))
80
          (result '()))
81
    (if (null? char-int-ls)
82
        (list->string (map integer->char result))
83
        (if add
84
            (let* ((hd (car char-int-ls)) (tl (cdr char-int-ls)))
85
              (if (= hd #x7A)
86
                  (A #t tl (cons #x30 result))
87
                  (A #f tl (cons (case hd
88
                                   ((#x39) #x41)
89
                                   ((#x5A) #x61)
90
                                   (else (1+ hd))) result))))
91
            (A #f '() (append (reverse char-int-ls) result))))))
92