;;; markam -- Store/retrieve/manage bookmarks ;; Copyright (C) 2012,2013 Tom Willemsen ;; This program is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with this program. If not, see . ;;; Commentary: ;; The main program. For documentation you should consult the ;; README.org and/or any Texinfo documentation provided. ;;; Code: (declare (uses paths common)) (require-extension sqlite3) (require-library posix srfi-4) (define version "0.1.0") ;; If STR contains a \0 byte at the end, remove it, otherwise return ;; STR unchanged. (: string-no-null (string -> string)) (define (string-no-null str) (if (and (> (string-length str) 0) (char=? (string-ref str (- (string-length str) 1)) #\nul)) (substring str 0 (- (string-length str) 1)) str)) ;; Print URL, SECONDS, NAME and DESCRIPTION to the standard output ;; stream. (: print-row (string fixnum string string -> void)) (define (print-row url seconds name description) (if script? (format #t "~a~a~a" (string-no-null name) (string-no-null description) (string-no-null url)) (format #t "~a~% ~a~% ~a~% ~a~%~%" (string-no-null name) (string-no-null description) (string-no-null url) (seconds->string seconds)))) ;; Add NAME to the `tag' table in DB. (define (add-tag db name) (execute db "INSERT INTO tag VALUES (?)" name) (last-insert-rowid db)) ;; Add a bookmark to the `bookmark' table in DB. URL is the url of the ;; bookmark, NAME the title, DESCRIPTION a (possibly longer) ;; description of the bookmark and TAGS is a list of tags to assign to ;; it. Each tag will be created if necessary. (define (add-bookmark db url name description tags) (execute db "INSERT INTO bookmark VALUES (?, STRFTIME('%s'), ?, ?)" url name description) (let ((bookmark-id (last-insert-rowid db))) (for-each (lambda (tag) (let ((tag-id '())) (condition-case (set! tag-id (first-result db "SELECT rowid FROM tag WHERE name = ?" tag)) (exn (exn sqlite3) (if (eq? (get-condition-property exn 'sqlite3 'status) 'done) (set! tag-id (add-tag db tag)) (signal exn)))) (execute db "INSERT INTO bookmark_tag VALUES (?, ?)" bookmark-id tag-id))) tags))) (define (search-bookmarks db str) (for-each-row print-row db #< (string-length str) 7) (or (string= (substring str 0 7) "http://") (string= (substring str 0 8) "https://")))) ;; Display markam's help message. (define (display-help) (format #t (string-append "Usage: markam [options]...~%" " markam [...]~%" "~%" "Possible options:~%" "~%" "--help, -h Display this help and exit~%" "--version, -v Output version information and exit~%"))) ;; Parse "other" command-line arguments (define (handle-regular-args args) (do ((arg (car args) (and (not (null? args)) (car args)))) ((or (null? arg) (not arg))) (cond ((or (string= arg "-v") (string= arg "--version")) (display-version) (exit 0)) ((or (string= arg "-h") (string= arg "--help")) (display-help) (exit 0)) (else (format #t "Unrecognized option: ~a~%" (car args)))) (set! args (cdr args)))) (define (check-script args) (if (member "--script" args) (begin (set! script? #t) (delete "--script" args)) args)) (define script? #f) ;; Open a database connection, list bookmarks, create a bookmark or ;; pass arguments on to `handle-regular-args'. (define (main args) (set! args (check-script args)) (let ((db (open-database (data-file "markam.db")))) (cond ((null? args) (for-each-row print-row db "select * from bookmark")) ((url-string? (car args)) (with-transaction db (lambda () (add-bookmark db (car args) (cadr args) (caddr args) (cdddr args)) #t))) ((string= (car args) "search") (search-bookmarks db (cadr args))) (else (handle-regular-args args))) (finalize! db #t))) (main (command-line-arguments))