Merge pull request #11 from comatory/fix-non-existent-event

Fix non existent event
This commit is contained in:
Ondrej Synacek 2020-12-26 21:12:54 +01:00 committed by GitHub
commit 3b7e69bd8e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 53 additions and 8 deletions

View File

@ -1,7 +1,12 @@
import { postURL } from '../services' import { postURL } from '../services'
import { eventStore, parseStatusStore, requestStore } from '../stores' import { eventStore, parseStatusStore, requestStore } from '../stores'
import { Request } from '../records' 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 { extractEventDataFromHTML } from '../../../lib/services/ics-retriever'
import generateICS from '../../../lib/services/ics-generator' import generateICS from '../../../lib/services/ics-generator'
@ -35,7 +40,7 @@ const createICS = async (html, url, { logger }) => {
const eventData = extractEventDataFromHTML(html, url, { logger }) const eventData = extractEventDataFromHTML(html, url, { logger })
const text = await generateICS(eventData) const text = await generateICS(eventData)
const dataUri = encodeURIComponent(text) const dataUri = encodeIcalString(text)
const uri = `data:text/calendar;charset=utf-8,${dataUri}` const uri = `data:text/calendar;charset=utf-8,${dataUri}`
const summaryMatch = text.match(/SUMMARY:.*/)[0] const summaryMatch = text.match(/SUMMARY:.*/)[0]
@ -59,10 +64,19 @@ const createICS = async (html, url, { logger }) => {
promptDownload(uri) promptDownload(uri)
} catch (err) { } catch (err) {
parseStatusStore.set(err) parseStatusStore.set(err)
throw err
} }
} }
export const createEvent = async (url, { logger }) => { export const createEvent = async (url, { logger }) => {
const html = await getEventHTML(url) try {
const ics = await createICS(html, url, { logger }) const html = await getEventHTML(url)
const ics = await createICS(html, url, { logger })
} catch(error) {
logger.log({
message: error.toString(),
level: 'error',
service: 'parser',
})
}
} }

View File

@ -1,3 +1,5 @@
const UNICODE_RE = /[\ud800-\udbff][\udc00-\udfff]|[\ud800-\udfff]/g
export const migrateRecord = (record) => { export const migrateRecord = (record) => {
// NOTE: v3 records // NOTE: v3 records
const id = record.id || record.order const id = record.id || record.order
@ -55,3 +57,13 @@ export const promptDownload = (uri) => {
link.setAttribute('href', '') link.setAttribute('href', '')
} }
export const encodeIcalString = (string) => {
try {
return encodeURIComponent(string)
} catch {
return string.replace(UNICODE_RE , ($0) => {
return $0.length > 1 ? $0 : '\ufffd';
})
}
}

View File

@ -2,6 +2,10 @@ const cheerio = require('cheerio')
const dayjs = require('dayjs') const dayjs = require('dayjs')
const { parseDates } = require('../parser-utils') const { parseDates } = require('../parser-utils')
const TITLE_BLACKLIST = [
'Content Not Found',
]
const parseDate = (timeText = '') => { const parseDate = (timeText = '') => {
const parts = timeText.split('at') const parts = timeText.split('at')
const datePart = parts[0] || null const datePart = parts[0] || null
@ -48,7 +52,8 @@ const parseUsingDOM = (html, { logger }) => {
} }
const $ = cheerio.load(html) 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 $eventSummary = $('#event_summary')
const $eventNode = $eventSummary ? $eventSummary.children()[1] : null const $eventNode = $eventSummary ? $eventSummary.children()[1] : null

2
package-lock.json generated
View File

@ -1,6 +1,6 @@
{ {
"name": "facebook-events-ical-converter", "name": "facebook-events-ical-converter",
"version": "1.4.3", "version": "1.4.4",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {

View File

@ -1,6 +1,6 @@
{ {
"name": "facebook-events-ical-converter", "name": "facebook-events-ical-converter",
"version": "1.4.3", "version": "1.4.4",
"private": true, "private": true,
"description": "App that converts events on Facebook event page to iCal file.", "description": "App that converts events on Facebook event page to iCal file.",
"main": "lib/index.js", "main": "lib/index.js",
@ -17,7 +17,7 @@
"deploy:firebase": "npm run build:firebase:hosting && firebase deploy", "deploy:firebase": "npm run build:firebase:hosting && firebase deploy",
"start": "npm run build && node lib/index.js", "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": "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\"", "start:dev:firebase": "concurrently \"npm run build:firebase:hosting:dev\" \"NODE_ENV=development firebase emulators:start\"",
"test": "jest" "test": "jest"
}, },

View File

@ -258,6 +258,20 @@ describe(parseUsingDOM, () => {
}) })
it('should return null if title was blacklisted', () => {
const html = `
<html>
<head>
<title>Content Not Found</title>
</head>
</html>
`
const eventData = parseUsingDOM(html, { logger })
expect(eventData).to.be.null
})
it('should NOT return start time without title', () => { it('should NOT return start time without title', () => {
const html = ` const html = `
<html> <html>