From cfa7db4f9e16301f284ab2085f42d9cca743fc8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Syn=C3=A1=C4=8Dek?= Date: Sat, 26 Dec 2020 20:33:16 +0100 Subject: [PATCH 1/5] fix: handle errors on front-end when parsing event data & track them (optionally) --- lib/frontend/actions/events.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/frontend/actions/events.js b/lib/frontend/actions/events.js index f89bcfa..60d41b4 100644 --- a/lib/frontend/actions/events.js +++ b/lib/frontend/actions/events.js @@ -59,10 +59,19 @@ const createICS = async (html, url, { logger }) => { promptDownload(uri) } catch (err) { parseStatusStore.set(err) + throw err } } export const createEvent = async (url, { logger }) => { - const html = await getEventHTML(url) - const ics = await createICS(html, url, { logger }) + try { + const html = await getEventHTML(url) + const ics = await createICS(html, url, { logger }) + } catch(error) { + logger.log({ + message: error.toString(), + level: 'error', + service: 'parser', + }) + } } From 0683ef9666672f12031148fc63c4ca4cdb22e68f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Syn=C3=A1=C4=8Dek?= Date: Sat, 26 Dec 2020 20:57:19 +0100 Subject: [PATCH 2/5] fix: error due to inability to parse invalid unicode sequences --- lib/frontend/actions/events.js | 9 +++++++-- lib/frontend/utils.js | 12 ++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/lib/frontend/actions/events.js b/lib/frontend/actions/events.js index 60d41b4..136ae15 100644 --- a/lib/frontend/actions/events.js +++ b/lib/frontend/actions/events.js @@ -1,7 +1,12 @@ import { postURL } from '../services' import { eventStore, parseStatusStore, requestStore } from '../stores' import { Request } from '../records' -import { uuidv4, parseStartTimeFromiCalString, promptDownload } from '../utils' +import { + uuidv4, + parseStartTimeFromiCalString, + promptDownload, + encodeIcalString, +} from '../utils' import { extractEventDataFromHTML } from '../../../lib/services/ics-retriever' import generateICS from '../../../lib/services/ics-generator' @@ -35,7 +40,7 @@ const createICS = async (html, url, { logger }) => { const eventData = extractEventDataFromHTML(html, url, { logger }) const text = await generateICS(eventData) - const dataUri = encodeURIComponent(text) + const dataUri = encodeIcalString(text) const uri = `data:text/calendar;charset=utf-8,${dataUri}` const summaryMatch = text.match(/SUMMARY:.*/)[0] diff --git a/lib/frontend/utils.js b/lib/frontend/utils.js index 9abeb83..68032e3 100644 --- a/lib/frontend/utils.js +++ b/lib/frontend/utils.js @@ -1,3 +1,5 @@ +const UNICODE_RE = /[\ud800-\udbff][\udc00-\udfff]|[\ud800-\udfff]/g + export const migrateRecord = (record) => { // NOTE: v3 records const id = record.id || record.order @@ -55,3 +57,13 @@ export const promptDownload = (uri) => { link.setAttribute('href', '') } + +export const encodeIcalString = (string) => { + try { + return encodeURIComponent(string) + } catch { + return string.replace(UNICODE_RE , ($0) => { + return $0.length > 1 ? $0 : '\ufffd'; + }) + } +} From ae700330b92da0c3dff91bb1685896cf0fc8b898 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Syn=C3=A1=C4=8Dek?= Date: Sat, 26 Dec 2020 21:03:03 +0100 Subject: [PATCH 3/5] fix: do not attempt to parse non-existent FB pages When user enters something invalid (like number 123), it wuold still hit FB webpage and return HTML. I do simple detection by looking at title when it attempts to parse the DOM directly. When it contains "Content Not Found", it is skipped. Non-existent web pages cannot be parsed by using LDJSON parser and looking at null data. --- lib/services/dom-parser.js | 7 ++++++- test/services/dom-parser.spec.js | 14 ++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/lib/services/dom-parser.js b/lib/services/dom-parser.js index 666210f..808ac1f 100644 --- a/lib/services/dom-parser.js +++ b/lib/services/dom-parser.js @@ -2,6 +2,10 @@ const cheerio = require('cheerio') const dayjs = require('dayjs') const { parseDates } = require('../parser-utils') +const TITLE_BLACKLIST = [ + 'Content Not Found', +] + const parseDate = (timeText = '') => { const parts = timeText.split('at') const datePart = parts[0] || null @@ -48,7 +52,8 @@ const parseUsingDOM = (html, { logger }) => { } const $ = cheerio.load(html) - const title = $('title').text() + const titleText = $('title').text() + const title = TITLE_BLACKLIST.includes(titleText) ? null : titleText const $eventSummary = $('#event_summary') const $eventNode = $eventSummary ? $eventSummary.children()[1] : null diff --git a/test/services/dom-parser.spec.js b/test/services/dom-parser.spec.js index d110c71..05c9f48 100644 --- a/test/services/dom-parser.spec.js +++ b/test/services/dom-parser.spec.js @@ -258,6 +258,20 @@ describe(parseUsingDOM, () => { }) + it('should return null if title was blacklisted', () => { + const html = ` + + + Content Not Found + + + ` + const eventData = parseUsingDOM(html, { logger }) + + expect(eventData).to.be.null + }) + + it('should NOT return start time without title', () => { const html = ` From 9207dbd12bc70b568d0125efb4ee229044449fdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Syn=C3=A1=C4=8Dek?= Date: Sat, 26 Dec 2020 21:09:15 +0100 Subject: [PATCH 4/5] fix: dev mode with inspect script should run FE and BE at the same time --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 334a7eb..63a3801 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "deploy:firebase": "npm run build:firebase:hosting && firebase deploy", "start": "npm run build && node lib/index.js", "start:dev": "concurrently \"npm run build:dev\" \"NODE_ENV=development PORT=3000 nodemon lib/index.js\"", - "start:dev:inspect": "npm run build:dev && NODE_ENV=development PORT=3000 nodemon --inspect lib/index.js", + "start:dev:inspect": "concurrently \"npm run build:dev\" \"NODE_ENV=development PORT=3000 nodemon --inspect lib/index.js\"", "start:dev:firebase": "concurrently \"npm run build:firebase:hosting:dev\" \"NODE_ENV=development firebase emulators:start\"", "test": "jest" }, From b544cd38f780c51f6b5ad415409ef231d034501f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Syn=C3=A1=C4=8Dek?= Date: Sat, 26 Dec 2020 21:09:39 +0100 Subject: [PATCH 5/5] 1.4.4 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 183a544..c3282c2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "facebook-events-ical-converter", - "version": "1.4.3", + "version": "1.4.4", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 63a3801..a65ab2c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "facebook-events-ical-converter", - "version": "1.4.3", + "version": "1.4.4", "private": true, "description": "App that converts events on Facebook event page to iCal file.", "main": "lib/index.js",