Browse Source

Initial Commit of Library Manager

Samuel W. Flint 7 years ago
commit
a9d2dcb9cf
1 changed files with 411 additions and 0 deletions
  1. 411 0
      library.org

+ 411 - 0
library.org

@@ -0,0 +1,411 @@
+#+Title: Library Management for Small Users
+#+Subtitle: Simple software for average users
+#+AUTHOR: Samuel W. Flint
+#+EMAIL: swflint@flintfam.org
+#+DATE: \today
+#+INFOJS_OPT: view:info toc:nil path:http://flintfam.org/org-info.js
+#+OPTIONS: toc:nil H:5 ':t *:t todo:nil stat:nil d:nil
+#+PROPERTY: header-args :noweb tangle :comments noweb
+#+LATEX_HEADER: \usepackage[margins=0.75in]{geometry}
+#+LATEX_HEADER: \parskip=5pt
+#+LATEX_HEADER: \parindent=0pt
+#+LATEX_HEADER: \lstset{texcl=true,breaklines=true,columns=fullflexible,basicstyle=\ttfamily,frame=lines,literate={<=}{$\leq$}1 {>=}{$\geq$}1}
+#+LATEX_CLASS_OPTIONS: [10pt,twoside]
+#+LATEX_HEADER: \pagestyle{headings}
+
+* Export                                                           :noexport:
+:PROPERTIES:
+:CREATED:  <2016-10-06 Thu 14:21>
+:END:
+
+#+Caption: Export Document
+#+Name: export-document
+#+BEGIN_SRC emacs-lisp :exports none :results none
+  (save-buffer)
+  (let ((org-confirm-babel-evaluate
+         (lambda (lang body)
+           (declare (ignorable lang body))
+           nil)))
+    (org-latex-export-to-pdf))
+#+END_SRC
+
+* Tangle                                                           :noexport:
+:PROPERTIES:
+:CREATED:  <2016-10-06 Thu 14:21>
+:END:
+
+#+Caption: Tangle Document
+#+Name: tangle-document
+#+BEGIN_SRC emacs-lisp :exports none :results none
+  (save-buffer)
+  (let ((python-indent-offset 4))
+    (org-babel-tangle))
+#+END_SRC
+
+* DONE Introduction
+CLOSED: [2016-04-16 Sat 15:15]
+:PROPERTIES:
+:CREATED:  <2016-04-13 Wed 20:15>
+:UNNUMBERED: t
+:END:
+
+As a person who has a lot of books, I like to be able to keep track of them.  I've tried other pre-built solutions, but they've been flaky and don't do well for the types of books I have.  I've also tried to use basic spreadsheets, but in the end, they've not been able to keep up with my desire to search through or produce reports.  So, when I stumbled on GNU recutils, I decided that building a script around it would be useful.  This is the script and system.
+
+* TOC                                                                :ignore:
+:PROPERTIES:
+:CREATED:  <2016-04-13 Wed 20:15>
+:END:
+
+#+TOC: headlines 3
+#+TOC: listings
+
+* WORKING File Format
+:PROPERTIES:
+:CREATED:  <2016-04-13 Wed 20:17>
+:ID:       1745de61-6511-4257-bed8-112df2362fe7
+:END:
+
+#+Caption: File Format
+#+Name: file-format
+#+BEGIN_SRC text
+  # -*- mode: rec -*-
+
+  %rec: Book
+  %doc: Foo
+  %key: ID
+  %unique: Title
+  %type: ID int
+  %type: Title line
+  %type: Author line
+  %type: LCCN line
+  %type: ISBN regexp /[0-9]*X?/
+  %type: Publisher line
+  %type: Copyright int
+  %type: Location line
+  %type: Inserted date
+  %mandatory: Title Author LCCN Inserted
+  %allowed: ISBN Publisher Copyright Location
+  %auto: ID Inserted
+#+END_SRC
+
+* WORKING Initialize
+:PROPERTIES:
+:CREATED:  <2016-04-13 Wed 22:13>
+:ID:       8308ab62-05a0-4240-a073-d2e4baab9ab2
+:END:
+
+#+Caption: Initialize a Database
+#+Name: initialize-database
+#+BEGIN_SRC sh
+  function initialize {
+      OLD=`pwd`
+      mkdir -p ${LIBRARYDIRECTORY}
+      cd ${LIBRARYDIRECTORY}
+      [[ -ne `basename ${LIBRARYFILE}` ]] && \
+          cat <<EOF > `basename ${LIBRARYFILE}`
+  <<file-format>>
+  EOF
+  }
+#+END_SRC
+
+* WORKING Handle Git
+:PROPERTIES:
+:CREATED:  <2016-04-13 Wed 20:17>
+:ID:       68ee8e3d-3280-4280-8dd4-e824b5c81929
+:END:
+
+#+Caption: Handle Git
+#+Name: handle-git
+#+BEGIN_SRC sh
+  function do-git {
+      FIRST=$1
+      if [[ $FIRST == "init" ]] ; then
+          OLD=`pwd`
+          cd ${LIBRARYDIRECTORY}
+          git $@
+          cd ${OLD}
+      else
+          if [[ $GIT == "detect" ]] ; then
+              OLD=`pwd`
+              cd ${LIBRARYDIRECTORY}
+              git $@
+              cd ${OLD}
+          fi
+      fi
+  }
+#+END_SRC
+
+* WORKING Run Queries
+:PROPERTIES:
+:CREATED:  <2016-04-13 Wed 20:17>
+:ID:       9cc04c91-08ea-49db-a0ac-f3789e22ff33
+:END:
+
+#+Caption: Handle Query
+#+Name: handle-query
+#+BEGIN_SRC sh
+  function run-query {
+      recsel -t Book $@ ${LIBRARYFILE}
+  }
+#+END_SRC
+
+* WORKING Add Book
+:PROPERTIES:
+:CREATED:  <2016-04-13 Wed 20:17>
+:ID:       7b842d87-7f13-483e-96ee-5a318877eeb7
+:END:
+
+#+Caption: Add Book
+#+Name: add-book
+#+BEGIN_SRC sh
+  function add-single {
+      echo -n "Title: "
+      read TITLE
+      echo -n "Author: "
+      read AUTHOR
+      echo -n "LCCN: "
+      read LCCN
+      echo -n "Copyright: "
+      read COPYRIGHT
+      echo -n "Publisher: "
+      read PUBLISHER
+      echo -n "ISBN: "
+      read ISBN
+      echo -n "Location: "
+      read LOCATION
+      recins -t Book \
+             -f Title -v "${TITLE}" \
+             -f Author -v "${AUTHOR}" \
+             -f LCCN -v "${LCCN}" \
+             -f Copyright -v "${COPYRIGHT}" \
+             -f Publisher -v "${PUBLISHER}" \
+             -f ISBN -v "${ISBN}" \
+             -f Location -v "${LOCATION}" \
+             ${LIBRARYFILE}
+      do-git add `basename ${LIBRARYFILE}`
+      do-git commit -m "Added record for \"${TITLE}\""
+  }
+#+END_SRC
+
+* WORKING Add Books in Bulk
+:PROPERTIES:
+:CREATED:  <2016-04-13 Wed 20:17>
+:ID:       2316a78c-88d7-4629-b310-b6b0c8b848b6
+:END:
+
+#+Caption: Add Books in Bulk
+#+Name: add-in-bulk
+#+BEGIN_SRC sh
+  function bulk-add {
+      GITOLD=${GIT}
+      GIT=FALSE
+      for i in {1..$1} ; do
+          echo "Adding book number ${i}"
+          add-single
+      done
+      GIT=${GITOLD}
+      do-git add `basename ${LIBRARYFILE}`
+      do-git commit -m "Added ${1} records"
+  }
+#+END_SRC
+
+* WORKING View the File in Emacs with Rec Mode
+:PROPERTIES:
+:CREATED:  <2016-04-13 Wed 20:17>
+:ID:       adfb988b-508b-4b3e-91a7-fd549ef3779e
+:END:
+
+#+Caption: View in Emacs
+#+Name: view-in-emacs
+#+BEGIN_SRC sh
+  function view-in-emacs {
+      emacsclient --alternate-editor="" -n ${LIBRARYFILE}
+  }
+#+END_SRC
+
+* WORKING Handle Reporting
+:PROPERTIES:
+:CREATED:  <2016-04-13 Wed 20:18>
+:ID:       1e6d79cb-aa8d-4a44-9268-5c5d502c5c38
+:END:
+
+#+Caption: Reporting
+#+Name: handle-reports
+#+BEGIN_SRC sh
+  function do-report {
+      NAME=$1
+      shift
+      case ${NAME} in
+          list)
+              for report in ${LIBRARYDIRECTORY}/*.report ;
+              do
+                  echo " - $(basename -- ${report} .report)"
+              done
+          ;;
+          new)
+              REPORT=$1
+              shift
+              echo "# -*- mode: sh-script -*-" > ${LIBRARYDIRECTORY}/${REPORT}.report
+              emacsclient --alternate-editor="" -n ${LIBRARYDIRECTORY}/${REPORT}.report
+          ;;
+          ,*)
+              if [[ -e ${LIBRARYDIRECTORY}/${NAME}.report ]] ; then
+                 sh ${LIBRARYDIRECTORY}/${NAME}.report $@
+              fi
+      esac
+  }
+#+END_SRC
+
+* WORKING Edit Field
+:PROPERTIES:
+:CREATED:  <2016-04-15 Fri 11:50>
+:ID:       56281ec3-8323-4f9c-892f-7edaff86393f
+:END:
+
+#+Caption: Edit Fields
+#+Name: edit-field
+#+BEGIN_SRC sh
+  function do-edit {
+      ID=$1
+      shift
+      FIELD=$1
+      shift
+
+      if [[ $FIELD = "Withdrawn" ]] ; then
+          recins -e "ID = ${ID}" \
+                 -f "Withdrawn" -v `date "%a, %d %b %Y %H:%M:%S %z"` \
+                 ${LIBRARYFILE}
+      else
+          VALUE=$1
+          shift
+          recins -e "ID = ${ID}" \
+                 -f "${FIELD}" -v "${VALUE}" \
+                 ${LIBRARYFILE}
+      fi
+      do-git add `basename ${LIBRARYFILE}`
+      do-git commit -m "Edited record id ${ID}"
+  }
+#+END_SRC
+
+* WORKING Help Message
+:PROPERTIES:
+:CREATED:  <2016-04-13 Wed 22:04>
+:ID:       3d90ee25-d8af-4590-b6bc-80e0430299f2
+:END:
+
+#+Caption: Help Message
+#+Name: help-message
+#+BEGIN_SRC sh
+  if [[ $# -eq 0 ]] ; then
+      echo "library [ help | query query-expressions | add | emacs | git [ other-args ] | bulk-add number | report [ name | list | new name ] | edit id field [ value ] | init ]"
+      exit
+  fi
+
+  function display-help {
+      cat <<EOF
+  library [ help | query query-expressions | add | emacs | git [ other-args ] | bulk-add number | report [ name | list | new name ] | edit id field [ value ] | init ]
+
+  help:     Display this help message.
+  query:    Query Library Database.
+  add:      Add a singular book record.
+  emacs:    View records in emacs.
+  edit:     Edit the value of a specified field in a specified record.
+  git:      Run a git command.
+  report:   Run a report.
+  init:     Initialize the database.
+  bulk-add: Add a specified number of records.
+  EOF
+  }
+#+END_SRC
+
+* WORKING Process Commands
+:PROPERTIES:
+:CREATED:  <2016-04-13 Wed 22:07>
+:ID:       9d10ce06-45f0-4957-85c3-b8fcfff42da8
+:END:
+
+#+Caption: Process Commands
+#+Name: process-commands
+#+BEGIN_SRC sh
+  COMMAND=$1
+  shift
+
+  case ${COMMAND} in
+      help)
+          display-help
+          exit
+          ;;
+      query)
+          run-query $@
+          exit
+          ;;
+      add)
+          add-single
+          exit
+          ;;
+      git)
+          do-git $@
+          exit
+          ;;
+      bulk-add)
+          bulk-add $@
+          exit
+          ;;
+      report)
+          do-report $@
+          exit
+          ;;
+      emacs)
+          view-in-emacs
+          exit
+          ;;
+      edit)
+          do-edit $@
+          exit
+          ;;
+      init)
+          initialize
+          exit
+          ;;
+      ,*)
+          display-help
+          exit
+  esac
+#+END_SRC
+
+* DONE Packaging
+CLOSED: [2016-04-16 Sat 15:20]
+:PROPERTIES:
+:CREATED:  <2016-04-13 Wed 22:07>
+:ID:       57c4d5f0-9fc7-41bd-a2f6-1ab6b8d12ae6
+:END:
+
+Finally, this is what puts the application together.  Placing each function in its place, making sure that everything is included is done here, fairly simply, by referencing the code block and being expanded here.
+
+#+Caption: Packaging
+#+Name: packaging
+#+BEGIN_SRC sh :tangle "~/bin/library" :shebang "#!/bin/zsh -f"
+  LIBRARYFILE=~/.library/library.rec
+  LIBRARYDIRECTORY=~/.library
+  GIT=detect
+
+  <<help-message>>
+
+  <<handle-reports>>
+
+  <<handle-git>>
+
+  <<handle-query>>
+
+  <<add-book>>
+
+  <<add-in-bulk>>
+
+  <<edit-field>>
+
+  <<initialize-database>>
+
+  <<view-in-emacs>>
+
+  <<process-commands>>
+#+END_SRC