Coder Social home page Coder Social logo

bookshelf's Introduction

Bookshelf

A personal project to fix a minor annoyance that I've had for a while but should you have the same annoyance and find this useful, then the code is here under an MIT License so make use of it as you will. It is very much still under development so it may change beyond all recognition or, if I really lose my temper with it, disappear without warning.

Backstory

Over the past few years, through purchases and give-aways from various online stores and event promos, I have found myself to be the proud owner of a big pile of e-books that live outside of Amazon's Kindle or Apple's iBooks platforms. A big old jumble of files on my computer. I find the file viewer less than helpful in keeping things organised and have occasionally, and I know I'm not alone in this as I've seen others on Twitter do the same, bought the same book twice having not realised I already owned it until the Save As dialogue asked if I wanted to replace an older file of the same name (uh oh!).

Concept

This is a place for me - hopefully with some help from my friends - to tinker with writing a command line script to generate a flat HTML page or 3 to help me keep track of my book collection. It's being worked on as an occasional side project alongside a full-time job so updates are likely to be infrequent and either in service of fixing a random thing that's bugging me or to try out a new idea I've recently read about. It will pander also pander to the idiosyncratic file structure that I've developed while trying to keep the file sprawl in check. We're deep in "scratch your own itch" territory here.

Oh and the use of flat files (CSS and JavaScript welcome, just no backend stuff) is a deliberate trick to allow the resulting file(s) to run right out of the filesystem rather than needing a webserver running in the background to quickly look something up. This restriction has caused some interesting problems, particularly around not being able to use JavasScript modules or certain kinds of include statements that are seen as cross-domain when served over file:// rather than http://; I can't serve a source map, for example.

File structure

The basic current file structure inside my bookshelf folder, which has changed slightly since starting the project, looks a bit like this (but longer, much, much longer)

├── A Little Riak Book
│   ├── _meta
│   │   ├── cover.jpg
│   │   └── info.js
│   ├── riaklil-en.epub
│   ├── riaklil-en.mobi
│   └── riaklil-en.pdf
├── The Little MongoDB Book
│   ├── Little_MongoDB_Book.pdf
│   └── _meta
│       ├── cover.jpg
│       └── info.js

As you can see, each book has it's own named folder containing the book file itself - or files plural if I own it in more than one format - and a _meta folder containing a JSON file (currently generated by hand) containing stuff like - sorry to be so handwavy here, but this bit's very much under construction - the book's full title, the publisher, the authors (they're mostly tech books so having an array of authors seems logical), the ISBN (if it has one, some freebie "use my product!" books don't), the publisher, a notes field that's currently only used to highlight which edition/printing of Agile Web Development with Rails covers which Rails version but could be more generally useful. And a cover image, currently 160px high with a varying width as it turns out, as I should have been able to spot right away by turning round and looking at my actual book shelf, not all books are the same size (or even in the same aspect ratio), but I hate the screen jumping around as it loads so as it's my ************, I've arbitrarily declared 160px high to be a standard.

At some point, I'm going to need a Librarian app to manage the metadata and images. Manually creating JSON files and creating screenshot images is pretty annoying at scale (it turns out).

A complication of file structures

It also turns out that in some cases I own more than one edition/printing/version/whatevs of the same book. A recent addition to the file structure spec, therefore makes it look something like this...

├── Agile Web Development with Rails
│   ├── 4th Edition v3.0
│   │   ├── _meta
│   │   │   ├── cover.jpg
│   │   │   └── info.js
│   │   ├── book.epub
│   │   ├── book.mobi
│   ├── 4th Edition v3.1
│   │   ├── _meta
│   │   │   ├── cover.jpg
│   │   │   └── info.js
│   │   ├── book.mobi
│   │   └── book.pdf

Which allows me to a) group them in a way that looks reasonably sensible to me (and, as I said before - my files, my rules) and b) that stops the file list from getting cluttered up with "Book A v1", "Book A v2" and so on.

(As soon as I got this more or less working, Sandi Metz published a second edition of the excellent 99 Bottles of OOP which completely broke my folder structure and delivered an instant lesson in assumptions. I've cheated for now but at some point I need to sit down and figure out how to model an "edition" that has multiple variants of the book title, each with its own group of formats.)

How do I make it go?

Ok, sorry, probably should have done this bit sooner...

  1. Git clone your own copy of the repository
  2. Drop assets and app directories and the Rakefile into the top level directory of a folder structure that's arranged a bit like mine and has lots of books in it
  3. From the command line, navigate to the folder you copied the files into
  4. Install the prerequisites
    • Let's assume you already have ruby
    • Install the bundler gem (if you don't already have it) with gem install bundler (the version used by the project is at the end of the Gemfile.lock file)
    • Run rake install to install the bundled gems and npm
  5. Run the rake file to generate the HTML:
    rake generate_index_file shelf="."
  6. Load the resulting index.html into your favourite browser

Tip: vary the value of shelf= to change the target directory for the script


If you don't have a folder with lots of books in it, you may have come to the wrong place

If you would like a folder with lots of books in it, may I suggest Project Gutenberg as a good starting point

bookshelf's People

Contributors

dependabot[bot] avatar lizconlan avatar robertbrook avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar  avatar

bookshelf's Issues

Factor out ISBN simplifications / assumptions

Just recording this here to document the oversight/lazy implementation of ISBNs as shorthand for a unique reference id for objects.

  • Not all books will have an ISBN (particularly self-published or vendor/show giveaways and quickstarts)
  • Some things that are not technically books might have ISBNs anyway
  • Sometimes different "editions" of a book (revised reprints, ebook errata fix releases and other more informal definitions of "editions" such as early release PDFs that packrats may like to keep to get a sense of the book's progress) may have the same ISBN but mostly each edition's ISBN will be unique; looking at it now, the way I glossed over this reads like an assumption of the first case
    • If you're browsing a shared library to find things you might like to buy, not having the correct ISBN could be frustrating
    • If reinstating Robert's cool third party javascript library ideas - scripts that can go off and fetch detailed catalogue records which which I removed from the index page for performance reasons* - fetching the wrong ISBN is going to make an unholy mess

Future effects - if I absently-mindedly drop a magazine or a technical paper into the mix, should the ISSN (or DOI) be clumsily pasted in to the ISBN field as a quick fix? Should ISBNs etc be hidden behind some kind of Identifier class that knows about schemas, different lookup sources and which can be treated as a URL?


* Could become the basis of either some long-desired admin functionality that relieves the data entry tedium of manual data entry for each new book added to the structure and/or an enhanced feature on a improved book-level view (page?) with graceful degradation features that only pulls in enhanced detail in a non-blocking way with graceful degradation features etc, etc

Filter by format

e.g. hide things that are only available as PDF, show me all the .mobi books etc

(I'm thinking checkboxes)

Add README file

Include explanation of what it's supposed to be for, outline of folder structure etc

Remote JSON?

If I have some remote JSON to call: better to do that in the script (slower) or in the HTML using JS (faster, but requires JS, obv)?

In-page grouping and ordering

Initially between publisher and title, author's harder because it's an array (um, duplicate all the things..? A decision for later)

Reskin / redesign

Current layout considered unhelpful with upwards of 40 titles. Time to reconsider

Rewrite gen.rb as a Rakefile?

If it's intended to be self-contained, a rakefile might offer some advantages.

If it might end up in something bigger, rake's likely not the best route.

Pre-check of info.js files for openlibrary.org images?

Stealing from @robertbrook's idea (no change there)...

Could it be worth writing a routine that jumps through all the info.js files (or at least, all the ones that don't have the completed attribute we're looking for and checks the ISBN against openlibrary.org. If there's a cover image available, add the line openlib_cover: true AND (optionally?) output a "report" to the screen of books that will need a cover.jp(e)g file to be dropped into the _meta folder?

Revisit the "formats" stuff

Now less clear which formats are available:

  • are there any standard icon images for this?
  • I forgot that, especially with the A Book Apart stuff, the folder may contain more than just "book" files
  • do we want the links to always open in iBooks? Should that be an option? Is that part of this ticket? Probably not but I needed to write it down while I thought of it

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.