Skip to content

Commit f4c9cf2

Browse files
committed
Initial commit
0 parents  commit f4c9cf2

File tree

6 files changed

+6560
-0
lines changed

6 files changed

+6560
-0
lines changed

.gitignore

+102
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
2+
# Created by https://www.gitignore.io/api/node,macos,visualstudiocode
3+
4+
### macOS ###
5+
*.DS_Store
6+
.AppleDouble
7+
.LSOverride
8+
9+
# Icon must end with two \r
10+
Icon
11+
12+
# Thumbnails
13+
._*
14+
15+
# Files that might appear in the root of a volume
16+
.DocumentRevisions-V100
17+
.fseventsd
18+
.Spotlight-V100
19+
.TemporaryItems
20+
.Trashes
21+
.VolumeIcon.icns
22+
.com.apple.timemachine.donotpresent
23+
24+
# Directories potentially created on remote AFP share
25+
.AppleDB
26+
.AppleDesktop
27+
Network Trash Folder
28+
Temporary Items
29+
.apdisk
30+
31+
### Node ###
32+
# Logs
33+
logs
34+
*.log
35+
npm-debug.log*
36+
yarn-debug.log*
37+
yarn-error.log*
38+
39+
# Runtime data
40+
pids
41+
*.pid
42+
*.seed
43+
*.pid.lock
44+
45+
# Directory for instrumented libs generated by jscoverage/JSCover
46+
lib-cov
47+
48+
# Coverage directory used by tools like istanbul
49+
coverage
50+
51+
# nyc test coverage
52+
.nyc_output
53+
54+
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
55+
.grunt
56+
57+
# Bower dependency directory (https://bower.io/)
58+
bower_components
59+
60+
# node-waf configuration
61+
.lock-wscript
62+
63+
# Compiled binary addons (http://nodejs.org/api/addons.html)
64+
build/Release
65+
66+
# Dependency directories
67+
node_modules/
68+
jspm_packages/
69+
70+
# Typescript v1 declaration files
71+
typings/
72+
73+
# Optional npm cache directory
74+
.npm
75+
76+
# Optional eslint cache
77+
.eslintcache
78+
79+
# Optional REPL history
80+
.node_repl_history
81+
82+
# Output of 'npm pack'
83+
*.tgz
84+
85+
# Yarn Integrity file
86+
.yarn-integrity
87+
88+
# dotenv environment variables file
89+
.env
90+
91+
### VisualStudioCode ###
92+
.vscode/*
93+
!.vscode/settings.json
94+
!.vscode/tasks.json
95+
!.vscode/launch.json
96+
!.vscode/extensions.json
97+
.history
98+
99+
100+
# End of https://www.gitignore.io/api/node,macos,visualstudiocode
101+
102+
blogs/

.vscode/launch.json

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
// Use IntelliSense to learn about possible attributes.
3+
// Hover to view descriptions of existing attributes.
4+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5+
"version": "0.2.0",
6+
"configurations": [
7+
{
8+
"type": "node",
9+
"request": "launch",
10+
"name": "Launch via NPM",
11+
"runtimeExecutable": "npm",
12+
"runtimeArgs": [
13+
"run-script",
14+
"debug"
15+
],
16+
"port": 9229
17+
},
18+
{
19+
"type": "node",
20+
"request": "launch",
21+
"name": "Launch Program",
22+
"program": "${workspaceFolder}/index.js"
23+
}
24+
]
25+
}

index.js

+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
const fs = require('fs-extra')
2+
const path = require('path')
3+
const feedRead = require('davefeedread')
4+
const TurndownService = require('turndown')
5+
const turndownService = new TurndownService({
6+
headingStyle: 'atx',
7+
codeBlockStyle: 'fenced'
8+
})
9+
10+
const parseBlog = async (file) => {
11+
const feed = await parseFeed(file)
12+
13+
// Filter for only blog posts
14+
var items = feed.items.filter((item, index, array) => item['wp:post_type']['#'] === 'post')
15+
16+
// Map to new object type
17+
items = items.map(item => {
18+
if (item['wp:post_type']['#'] !== 'post') {
19+
return
20+
}
21+
22+
const mappedItem = {
23+
'title': item.title,
24+
'date': item.date,
25+
'content': item['content:encoded']['#'],
26+
'categories': item.categories,
27+
'slug': item['wp:post_name']['#']
28+
}
29+
30+
// Add passthroughUrl if exists
31+
const postMeta = item['wp:postmeta']
32+
if (postMeta) {
33+
const metaKey = postMeta['wp:meta_key']['#']
34+
if (metaKey == "passthrough_url") {
35+
mappedItem.passthroughUrl = postMeta['wp:meta_value']['#']
36+
}
37+
}
38+
39+
return mappedItem
40+
})
41+
42+
// Add Markdown conversion
43+
items = items.map(item => {
44+
item.markdownContent = turndownService.turndown(item.content)
45+
return item
46+
})
47+
48+
return items
49+
}
50+
51+
const parseFeed = (file) => {
52+
return new Promise((resolve, reject) => {
53+
feedRead.parseString(file, undefined, (error, result) => {
54+
if (error) {
55+
reject(error)
56+
} else {
57+
resolve(result)
58+
}
59+
})
60+
})
61+
}
62+
63+
const writeBlog = async (blog, path) => {
64+
if (!path.endsWith('/')) {
65+
path = path + '/'
66+
}
67+
68+
blog.forEach(async post => {
69+
const postPath = `${__dirname}/${path}${post.slug}`
70+
await fs.ensureDir(postPath)
71+
72+
const fileContents =
73+
`---
74+
title: ${post.title}
75+
date: "${post.date}"
76+
---
77+
78+
${post.markdownContent}`
79+
80+
await fs.outputFile(`${postPath}/index.md`, fileContents)
81+
})
82+
}
83+
84+
const runner = async () => {
85+
const file = fs.readFileSync(__dirname + '/squarespace.xml', 'utf8')
86+
const blog = await parseBlog(file)
87+
await writeBlog(blog, 'blogs')
88+
}
89+
90+
runner()

0 commit comments

Comments
 (0)