Skip to content

Commit

Permalink
Changes that allow for goodreads books to be re-read. Will still have…
Browse files Browse the repository at this point in the history
… to confirm workflow when I finish a book being re-read and when i start re-reading a new book
  • Loading branch information
brombaut committed Aug 27, 2022
1 parent 2020797 commit 9a65b73
Show file tree
Hide file tree
Showing 6 changed files with 5,769 additions and 8,226 deletions.
12,003 changes: 3,804 additions & 8,199 deletions package-lock.json

Large diffs are not rendered by default.

39 changes: 18 additions & 21 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"dependencies": {
"@babel/core": "^7.15.8",
"@babel/preset-env": "^7.15.8",
"@brombaut/types": "1.0.0",
"@brombaut/types": "1.2.0",
"@fortawesome/fontawesome-svg-core": "^1.2.35",
"@fortawesome/free-brands-svg-icons": "^5.15.3",
"@fortawesome/free-regular-svg-icons": "^5.15.3",
Expand All @@ -22,30 +22,27 @@
"copy-webpack-plugin": "^5.1.2",
"core-js": "^3.18.2",
"dotenv": "^10.0.0",
"firebase-firestore-facade": "1.1.0",
"firebase-firestore-facade": "1.2.0",
"vue": "^2.6.12",
"vue-router": "^3.5.1",
"xml2js": "^0.4.23"
},
"devDependencies": {
"@types/node": "^16.10.3",
"@typescript-eslint/eslint-plugin": "^4.33.0",
"@typescript-eslint/parser": "^2.34.0",
"@vue/cli-plugin-babel": "4.5.13",
"@vue/cli-plugin-eslint": "4.5.13",
"@vue/cli-plugin-typescript": "4.5.12",
"@vue/cli-service": "4.x.x",
"@vue/eslint-config-airbnb": "^5.1.0",
"@vue/eslint-config-typescript": "^7.0.0",
"babel-eslint": "^10.0.3",
"eslint": "^7.32.0",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-vue": "^7.19.1",
"husky": "^7.0.2",
"sass": "^1.35.1",
"sass-loader": "^8.0.2",
"typescript": "~4.4.3",
"vue-template-compiler": "^2.6.12"
"@types/node": "16.10.3",
"@typescript-eslint/eslint-plugin": "5.x.x",
"@typescript-eslint/parser": "5.x.x",
"@vue/cli-plugin-babel": "5.x.x",
"@vue/cli-plugin-typescript": "5.x.x",
"@vue/cli-service": "5.x.x",
"babel-eslint": "10.0.3",
"eslint": "8.x.x",
"eslint-plugin-import": "2.26.0",
"eslint-plugin-vue": "9.3.0",
"husky": "7.0.2",
"sass": "1.35.1",
"sass-loader": "8.0.2",
"typescript": "4.4.3",
"vue-template-compiler": "2.6.12"
},
"eslintConfig": {
"root": true,
Expand Down Expand Up @@ -111,4 +108,4 @@
"> 1%",
"last 2 versions"
]
}
}
49 changes: 49 additions & 0 deletions src/bookshelf/syncer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
On GitHub, this syncer is started by running `npm run sync-bookshelf`, which executes `bash ./scripts/sync_bookshelf.sh`.

```json
{
"title": "Health and Health Care Delivery in Canada",
"short_title": "Health and Health Care Delivery in Canada",
"authors": "Valerie D. Thompson",
"isbn13": "9781771721691",
"link": "https://www.goodreads.com/book/show/43973950-health-and-health-care-delivery-in-canada",
"num_pages": "368",
"dateStarted": "Wed Jun 08 19:34:26 -0700 2022",
"dateFinished": null,
"rating": "0",
"shelf": "currently-reading",
"goodreads_review_id": "4666835533",
"on_page": 0,
"to_read_order": null
},
{
"title": "Into Thin Air: A Personal Account of the Mount Everest Disaster",
"short_title": "Into Thin Air: A Personal Account of the Mount Everest Disaster",
"authors": "Jon Krakauer",
"isbn13": "9780385492089",
"link": "https://www.goodreads.com/book/show/271285.Into_Thin_Air",
"num_pages": "378",
"dateStarted": "Fri Jan 29 05:32:26 -0800 2021",
"dateFinished": "Sun Aug 21 00:00:00 -0700 2022",
"rating": "5",
"shelf": "currently-reading",
"goodreads_review_id": "3747054078",
"on_page": 130,
"to_read_order": null
},
```

When reading for first time
- shelf will be "currently-reading"
- to_read_order will be null
- dateStarted will be when you first started reading the book
- dateFinished will be null
- rating will be "0"

When re-reading
- shelf will be "currently-reading"
- to_read_order will be null
- dateStarted and dateFinished will be populated with values (dates) from when you first read the book
- rating will be what you rated the book the first time
- As far as I can tell, the goodreads_review_id will also be the same

54 changes: 50 additions & 4 deletions src/bookshelf/syncer/f3_syncer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,20 +41,28 @@ async function main() {
console.log("Starting Sync");
console.log("Init F3Bookshelf");
const f3: F3Bookshelf = await new F3Bookshelf(firebaseConfig).init();

console.log("Reading translated goodreads book file");
const booksFromGoodreads: GRBook[] = readTranslatedBooksFile();

console.log("Fetching existing F3 books");
const f3Books: Book[] = await fetchF3Books(f3);

console.log("Syncing existing F3 books");
const existingF3Books = syncExistingF3Books(f3Books, booksFromGoodreads);

console.log("Updating F3 with synced books");
await updateF3WithSyncedBooks(f3, existingF3Books);

console.log("Creating new F3 books");
const newF3Books = createNewF3Books(f3Books, booksFromGoodreads);

console.log("Updating F3 with added books");
await addNewBooksToF3(f3, newF3Books);

console.log("Closing F3 Connection");
await f3.closeConnection();

console.log("Done");
}

Expand All @@ -70,12 +78,32 @@ async function fetchF3Books(f3: F3Bookshelf): Promise<Book[]> {
}

function syncExistingF3Books(f3Books: Book[], grBooks: GRBook[]): Book[] {
/**
* This function will return a list of F3 books that need to be synced.
* We check a list of cases (see below), and based on which cases evaluate to true,
* we update the Book with the correct data (from the associated GRBook),
* and add it to the list to be returned.
*
* Case 1 - Both records are still to read and the toReadOrder value has changed
* Case 2 - We have started reading a book that was previously toRead.
* Case 3 - We have finished reading a book we were previously reading.
* Case 4 - A book has a higher onPage value.
* Case 5 - A book has a different rating value.
*
* Note that if we are re-reading a book, the previous record will have a "@X" suffix
* on the goodreads_review_id, which means it will never match here.
*
* We also handle creation of a new record of a book that is being re-read in the createNewF3Books function
*/
const result: Book[] = [];
f3Books.forEach((b: Book) => {
const grBook: GRBook | undefined = grBooks.find((grb: GRBook) => grb.goodreads_review_id === b.goodreads_review_id);
if (!grBook) return;
let needsSyncing = false;

// Case 1 - Both records are still to read...
// the only thing that might have changed that needs updating
// is the toReadOrder value
if (grBook.shelf == Shelf.TOREAD && b.shelf == Shelf.TOREAD) {
const toReadOrderIsNotMagicNumber = grBook.to_read_order !== 99;
const toReadOrderNumbersDoNotMatch = grBook.to_read_order !== b.toReadOrder
Expand All @@ -85,16 +113,19 @@ function syncExistingF3Books(f3Books: Book[], grBooks: GRBook[]): Book[] {
}
}

// Case 2 - We have started reading a book that was previously toRead.
if (grBook.shelf == Shelf.CURRENTLYREADING && b.shelf == Shelf.TOREAD) {
b.startReading();
needsSyncing = true;
}

// Case 3 - We have finished reading a book we were previously reading
if (grBook.shelf == Shelf.READ && b.shelf == Shelf.CURRENTLYREADING) {
b.finishedReading();
needsSyncing = true;
}

// Case 4 - A book has a higher onPage value
if (b.onPage !== null && grBook.on_page !== null) {
const changedAndGROnPageIsHigher = b.onPage !== grBook.on_page && grBook.on_page > b.onPage;
if (changedAndGROnPageIsHigher) {
Expand All @@ -103,6 +134,7 @@ function syncExistingF3Books(f3Books: Book[], grBooks: GRBook[]): Book[] {
}
}

// Case 5 - A book has a different rating value
if (b.rating !== parseInt(grBook.rating, PARSE_INT_RADIX)) {
b.rating = parseInt(grBook.rating, PARSE_INT_RADIX);
needsSyncing = true;
Expand All @@ -126,21 +158,35 @@ async function updateF3WithSyncedBooks(f3: F3Bookshelf, syncedF3Books: Book[]) {
}

function createNewF3Books(f3Books: Book[], grBooks: GRBook[]): FirestoreBook[] {
/**
* We will create new F3 Book records for Goodreads Books who have a goodreads_review_id
* that does not exist in our F3 database.
*
* This also will handle creating new "re-read" book records, since we should have manually
* added a "@X" suffix to the goodreads_review_id in F3 for the book we have started re-reading.
*/
const newGRBooks: GRBook[] = [];
grBooks.forEach((grb: GRBook) => {
const i = f3Books.findIndex((b: Book) => b.goodreads_review_id === grb.goodreads_review_id);
// We dont have a goodreads_review_id for the GoodReads book in our F3 database
let i = f3Books.findIndex((b: Book) => b.goodreads_review_id === grb.goodreads_review_id);
if (i < 0) {
newGRBooks.push(grb);
}
});

const newFirestoreBooks: FirestoreBook[] = newGRBooks.map((grb: GRBook) => {
// We are re-reading a book if the GoodReads good is currently-reading and
// we have a goodreads_review_id with the "@X" suffix removed record existing in our database.
const previousReviewIdRecordExists = f3Books.findIndex((b: Book) => b.goodreads_review_id.split("@")[0] === grb.goodreads_review_id) >= 0;
const isReRead = previousReviewIdRecordExists && grb.shelf === Shelf.CURRENTLYREADING;
let sDate = null;
if (grb.dateStarted) {
if (isReRead) {
sDate = new FirestoreDateTranslator().fromDate(new Date()).toFirestoreDate();
} else if (grb.dateStarted) {
sDate = new FirestoreDateTranslator().fromDate(new Date(grb.dateStarted)).toFirestoreDate();
}
let fDate = null;
if (grb.dateFinished) {
if (!isReRead && grb.dateFinished) {
fDate = new FirestoreDateTranslator().fromDate(new Date(grb.dateFinished)).toFirestoreDate();
}
return {
Expand All @@ -156,7 +202,7 @@ function createNewF3Books(f3Books: Book[], grBooks: GRBook[]): FirestoreBook[] {
onPage: grb.on_page,
dateStarted: sDate,
dateFinished: fDate,
rating: parseInt(grb.rating, PARSE_INT_RADIX),
rating: isReRead ? 0 : parseInt(grb.rating, PARSE_INT_RADIX),
toReadOrder: grb.to_read_order,
};
});
Expand Down
1,848 changes: 1,847 additions & 1 deletion src/bookshelf/syncer/translated_books_from_gr.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/footer/last-deployed.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export default "03/07/2022";
export default "27/08/2022";

0 comments on commit 9a65b73

Please sign in to comment.