mirror of
https://github.com/comatory/fb2iCal
synced 2025-06-05 22:09:25 +02:00
initial commit
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
node_modules/
|
||||||
|
dist/
|
15
lib/crawler.js
Normal file
15
lib/crawler.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
const puppeteer = require('puppeteer')
|
||||||
|
|
||||||
|
const crawl = async (url) => {
|
||||||
|
const browser = await puppeteer.launch()
|
||||||
|
const page = await browser.newPage()
|
||||||
|
await page.goto(url)
|
||||||
|
|
||||||
|
const html = await page.evaluate(() => document.body.innerHTML)
|
||||||
|
|
||||||
|
await browser.close()
|
||||||
|
|
||||||
|
return html
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = crawl
|
40
lib/index.js
Normal file
40
lib/index.js
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
const express = require('express')
|
||||||
|
const bodyParser = require('body-parser')
|
||||||
|
const path = require('path')
|
||||||
|
|
||||||
|
const crawl = require('./crawler')
|
||||||
|
const parseHTML = require('./parser')
|
||||||
|
|
||||||
|
const port = process.env.PORT || 3000
|
||||||
|
const app = express()
|
||||||
|
|
||||||
|
app.set('view engine', 'ejs')
|
||||||
|
app.set('views', path.join(__dirname, 'views'))
|
||||||
|
app.use(bodyParser())
|
||||||
|
|
||||||
|
app.get('/', (req, res) => {
|
||||||
|
res.render('index')
|
||||||
|
})
|
||||||
|
|
||||||
|
app.get('*', (req, res) => {
|
||||||
|
res.render('404')
|
||||||
|
})
|
||||||
|
|
||||||
|
app.post('/download', async (req, res) => {
|
||||||
|
const { url } = req.body
|
||||||
|
|
||||||
|
try {
|
||||||
|
const html = await crawl(url)
|
||||||
|
const data = parseHTML(html)
|
||||||
|
console.log(data)
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err)
|
||||||
|
return res.render('error', { error: err.toString() })
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.render('download', { url })
|
||||||
|
})
|
||||||
|
|
||||||
|
app.listen(port, () => {
|
||||||
|
console.log(`App running on port ${port}`)
|
||||||
|
})
|
26
lib/parser.js
Normal file
26
lib/parser.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
const { parse } = require('node-html-parser')
|
||||||
|
|
||||||
|
const parseHTML = (html) => {
|
||||||
|
let data = {}
|
||||||
|
|
||||||
|
const root = parse(html)
|
||||||
|
const eventSummary = root.querySelector('#event_summary')
|
||||||
|
|
||||||
|
const timeInfo = eventSummary.querySelector('#event_time_info')
|
||||||
|
const timeContent = timeInfo.querySelector('[content]')
|
||||||
|
|
||||||
|
if (
|
||||||
|
timeContent &&
|
||||||
|
timeContent.attributes &&
|
||||||
|
timeContent.attributes.content
|
||||||
|
) {
|
||||||
|
data = {
|
||||||
|
...data,
|
||||||
|
time: timeContent.attributes.content.value,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = parseHTML
|
17
lib/views/404.ejs
Normal file
17
lib/views/404.ejs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>Facebook Events to iCal Converter | 404</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h2>Page does not exist</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The page you requested does not exist.
|
||||||
|
|
||||||
|
<a href="/">Go back</a>
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
20
lib/views/download.ejs
Normal file
20
lib/views/download.ejs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>Facebook Events to iCal Converter | download</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h2>Your ICS file is ready</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The <code>ics</code> file was created successfully from url
|
||||||
|
<a href="<%= url %>"><%= url %></a>.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Your download will start automatically.
|
||||||
|
</p>
|
||||||
|
<a href="/">Go back</a>
|
||||||
|
</body>
|
||||||
|
</html>
|
18
lib/views/error.ejs
Normal file
18
lib/views/error.ejs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>Facebook Events to iCal Converter | error</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h2>Error</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
There was an error parsing the URL:
|
||||||
|
|
||||||
|
<%= error || '' %>
|
||||||
|
</p>
|
||||||
|
<a href="/">Go back</a>
|
||||||
|
</body>
|
||||||
|
</html>
|
23
lib/views/index.ejs
Normal file
23
lib/views/index.ejs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>Facebook Events to iCal Converter</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h1>Facebook Events to iCal Converter</h1>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Insert Facebook event URL into the form. When you submit it
|
||||||
|
you will get <a href="https://en.wikipedia.org/wiki/ICalendar"><code>ics</code></a>
|
||||||
|
file that you can import
|
||||||
|
into your calendar.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<form action='/download' method='POST'>
|
||||||
|
<input type='text' name='url' placeholder='Paste / type FB event URL here...' />
|
||||||
|
<input type='submit' value='Submit' />
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
3075
package-lock.json
generated
Normal file
3075
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
30
package.json
Normal file
30
package.json
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"name": "facebook-events-ical-converter",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "App that converts events on Facebook event page to iCal file.",
|
||||||
|
"main": "lib/index.js",
|
||||||
|
"scripts": {
|
||||||
|
"start": "PORT=80 node lib/index.js",
|
||||||
|
"start:dev": "nodemon lib/index.js",
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"facebook",
|
||||||
|
"event",
|
||||||
|
"ical",
|
||||||
|
"convert",
|
||||||
|
"download"
|
||||||
|
],
|
||||||
|
"author": "Ondrej Synacek <ondrejsynacek@fastmail.com>",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"body-parser": "^1.19.0",
|
||||||
|
"ejs": "^2.7.1",
|
||||||
|
"express": "^4.17.1",
|
||||||
|
"node-html-parser": "^1.1.16",
|
||||||
|
"puppeteer": "^1.20.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"nodemon": "^1.19.3"
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user