refactor retrieving ICS file
This commit is contained in:
parent
52b86953aa
commit
a41992d53b
|
@ -1,47 +0,0 @@
|
|||
const request = require('request')
|
||||
const { checkURLFormat, checkNumberURLParameter } = require('./utils')
|
||||
|
||||
const useMobileURL = (originalURL) => {
|
||||
const urlWithProtocol = originalURL.includes('http') ?
|
||||
originalURL :
|
||||
`https://${originalURL}`
|
||||
const url = new URL(urlWithProtocol)
|
||||
|
||||
return `${url.protocol}//mobile.facebook.com${url.port}${url.pathname}${url.hash}`
|
||||
}
|
||||
|
||||
const createURL = (originalURL) => {
|
||||
if (checkURLFormat(originalURL)) {
|
||||
return originalURL
|
||||
}
|
||||
|
||||
if (checkNumberURLParameter(originalURL)) {
|
||||
return `https://facebook.com/events/${originalURL}`
|
||||
}
|
||||
|
||||
return ''
|
||||
}
|
||||
|
||||
const crawl = async (originalURL) => {
|
||||
const url = useMobileURL(createURL(originalURL))
|
||||
return new Promise((resolve, reject) => {
|
||||
console.info(`Started request for URL: ${url}`)
|
||||
request({
|
||||
url,
|
||||
headers: {
|
||||
'Accept-Language': 'en-US, en',
|
||||
'User-Agent': 'request',
|
||||
},
|
||||
}, (err, res, body) => {
|
||||
if (err) {
|
||||
reject(err)
|
||||
return
|
||||
}
|
||||
|
||||
console.info(`Finished request for URL: ${url}`)
|
||||
resolve(body)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = crawl
|
29
lib/index.js
29
lib/index.js
|
@ -4,10 +4,12 @@ const path = require('path')
|
|||
const favicon = require('serve-favicon')
|
||||
const rateLimit = require('express-rate-limit')
|
||||
|
||||
const crawl = require('./crawler')
|
||||
const parseHTML = require('./parser')
|
||||
const generateICS = require('./ics')
|
||||
const { genericErrorHandler, checkURLParameter, forceSecure } = require('./middlewares')
|
||||
const retrieveICS = require('./services/ics-retriever')
|
||||
const {
|
||||
genericErrorHandler,
|
||||
checkURLParameter,
|
||||
forceSecure,
|
||||
} = require('./middlewares')
|
||||
|
||||
const port = process.env.PORT
|
||||
const certEndpoint = process.env.CERT_ENDPOINT || ''
|
||||
|
@ -50,22 +52,17 @@ app.get('*', (req, res) => {
|
|||
app.use('/download', checkURLParameter)
|
||||
app.use('/download', rateLimit())
|
||||
app.post('/download', async (req, res, next) => {
|
||||
const { url } = req.body
|
||||
|
||||
try {
|
||||
const html = await crawl(url)
|
||||
const data = parseHTML(html)
|
||||
const ics = await generateICS(data)
|
||||
const { url } = req.body
|
||||
|
||||
if (ics) {
|
||||
return res
|
||||
.contentType('text/calendar')
|
||||
.status(200)
|
||||
.send(new Buffer(ics, 'utf8'))
|
||||
}
|
||||
const ics = await retrieveICS(url)
|
||||
|
||||
res
|
||||
.contentType('text/calendar')
|
||||
.status(200)
|
||||
.send(new Buffer(ics, 'utf8'))
|
||||
} catch (err) {
|
||||
next(err)
|
||||
return
|
||||
}
|
||||
})
|
||||
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
const request = require('request')
|
||||
|
||||
const crawl = async (url) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
console.info(`Started request for URL: ${url}`)
|
||||
request({
|
||||
url,
|
||||
headers: {
|
||||
'Accept-Language': 'en-US, en',
|
||||
'User-Agent': 'request',
|
||||
},
|
||||
}, (err, res, body) => {
|
||||
if (err) {
|
||||
reject(err)
|
||||
return
|
||||
}
|
||||
|
||||
console.info(`Finished request for URL: ${url}`)
|
||||
resolve(body)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = crawl
|
|
@ -0,0 +1,18 @@
|
|||
const crawl = require('./crawler')
|
||||
const parseHTML = require('./parser')
|
||||
const generateICS = require('./ics-generator')
|
||||
const { getNormalizedUrl } = require('../utils')
|
||||
|
||||
const retrieveICS = async (URLparameter) => {
|
||||
try {
|
||||
const url = getNormalizedUrl(URLparameter)
|
||||
const html = await crawl(url)
|
||||
const eventData = parseHTML(html)
|
||||
const icsFile = await generateICS(eventData)
|
||||
return icsFile
|
||||
} catch (err) {
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = retrieveICS
|
|
@ -1,6 +1,6 @@
|
|||
const dayjs = require('dayjs')
|
||||
const cheerio = require('cheerio')
|
||||
const { createParserError } = require('./utils')
|
||||
const { createParserError } = require('../utils')
|
||||
|
||||
// NOTE: Specific formatting for `ics` library
|
||||
const parseDates = (startDate, endDate) => {
|
35
lib/utils.js
35
lib/utils.js
|
@ -18,9 +18,44 @@ const createParserError = () => {
|
|||
return err
|
||||
}
|
||||
|
||||
// NOTE: Using mobile facebook URL because it usually
|
||||
// contains stringified JSON with event information
|
||||
const createMobileURL = (originalURL) => {
|
||||
const urlWithProtocol = originalURL.includes('http') ?
|
||||
originalURL :
|
||||
`https://${originalURL}`
|
||||
const url = new URL(urlWithProtocol)
|
||||
|
||||
return `${url.protocol}//mobile.facebook.com${url.port}${url.pathname}${url.hash}`
|
||||
}
|
||||
|
||||
// NOTE: Detect whether URL parameter contains
|
||||
// number or http address
|
||||
const createURL = (param) => {
|
||||
if (checkURLFormat(param)) {
|
||||
return param
|
||||
}
|
||||
|
||||
if (checkNumberURLParameter(param)) {
|
||||
return `https://facebook.com/events/${param}`
|
||||
}
|
||||
|
||||
return ''
|
||||
}
|
||||
|
||||
const getNormalizedUrl = (URLparameter) => {
|
||||
const fbURL = createURL(URLparameter)
|
||||
const mobileUrl = createMobileURL(fbURL)
|
||||
|
||||
return mobileUrl
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
checkValidURL,
|
||||
checkURLFormat,
|
||||
checkNumberURLParameter,
|
||||
createParserError,
|
||||
createMobileURL,
|
||||
createURL,
|
||||
getNormalizedUrl,
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue