mirror of
https://github.com/Crocmagnon/blog.git
synced 2024-12-21 13:22:00 +01:00
add (incomplete) migration script
This commit is contained in:
parent
64b42cf8bc
commit
71c7debb7d
3 changed files with 154 additions and 0 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -3,3 +3,4 @@
|
|||
public/
|
||||
resources
|
||||
.DS_Store
|
||||
.venv
|
||||
|
|
2
.rtx.toml
Normal file
2
.rtx.toml
Normal file
|
@ -0,0 +1,2 @@
|
|||
[tools]
|
||||
python = {version="latest", virtualenv=".venv"}
|
151
to_ghost.py
Normal file
151
to_ghost.py
Normal file
|
@ -0,0 +1,151 @@
|
|||
import json
|
||||
import logging
|
||||
import sys
|
||||
import time
|
||||
from pathlib import Path
|
||||
import frontmatter
|
||||
import dateparser
|
||||
|
||||
logger = logging.getLogger("to_ghost")
|
||||
logging.basicConfig(stream=sys.stderr, level=logging.INFO)
|
||||
|
||||
|
||||
def main():
|
||||
meta = {"exported_on": round(time.time() * 1000), "version": "5.75.0"}
|
||||
posts = []
|
||||
seen_tags = []
|
||||
tags = []
|
||||
posts_tags = []
|
||||
post_id = 0
|
||||
for folder in (Path() / "content" / "posts").iterdir():
|
||||
if not folder.is_dir():
|
||||
logger.info("%s is not dir, ignoring", folder)
|
||||
continue
|
||||
|
||||
post_id += 1
|
||||
index = folder / "index.md"
|
||||
with index.open("r") as f:
|
||||
article = frontmatter.load(f)
|
||||
ghost_post = make_post(article)
|
||||
if not ghost_post.get("slug"):
|
||||
ghost_post["slug"] = folder.name
|
||||
ghost_post["id"] = post_id
|
||||
posts.append(ghost_post)
|
||||
|
||||
for tag in article.get("tags", []):
|
||||
if tag not in seen_tags:
|
||||
seen_tags.append(tag)
|
||||
tags.append({"id": seen_tags.index(tag), "name": tag})
|
||||
posts_tags.append({"tag_id": seen_tags.index(tag), "post_id": post_id})
|
||||
|
||||
print(json.dumps({"meta": meta, "data": {"posts": posts, "tags": tags, "posts_tags": posts_tags}}))
|
||||
|
||||
|
||||
def make_post(article: frontmatter.Post) -> dict:
|
||||
article_date = article["date"].timestamp() * 1000
|
||||
ghost_post = {
|
||||
"title": article["title"],
|
||||
# Lexical is used to represent your content
|
||||
"lexical": "",
|
||||
"feature_image": None,
|
||||
"feature_image_alt": None,
|
||||
"feature_image_caption": None,
|
||||
"featured": 0, # boolean indicating featured status
|
||||
"page": 0, # boolean indicating if this is a page or post
|
||||
"status": "published", # or draft
|
||||
"published_at": article_date, # epoch time in milliseconds
|
||||
"published_by": 1, # the first user created has an id of 1
|
||||
"meta_title": None,
|
||||
"meta_description": None,
|
||||
"email_only": False, # boolean indicating email-only type of post
|
||||
"author_id": 1, # the first user created has an id of 1
|
||||
"created_at": article_date, # epoch time in milliseconds
|
||||
"created_by": 1, # the first user created has an id of 1
|
||||
"updated_at": article_date, # epoch time in milliseconds
|
||||
"updated_by": 1 # the first user created has an id of 1
|
||||
}
|
||||
if slug := article.get("canonicalURL"):
|
||||
ghost_post["slug"] = slug
|
||||
|
||||
return ghost_post
|
||||
|
||||
|
||||
def convert_date(article_date: str) -> int:
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
|
||||
d = {
|
||||
"meta": {
|
||||
"exported_on": 1388805572000, # epoch time in milliseconds
|
||||
"version": "2.14.0"
|
||||
},
|
||||
"data": {
|
||||
"posts": [
|
||||
{
|
||||
"id": 1,
|
||||
"title": "my blog post title",
|
||||
"slug": "my-blog-post-title", # Optional, will be generated by Ghost if missing
|
||||
# Lexical is used to represent your content
|
||||
"lexical": "{\"root\":{\"children\":[{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"Hello, beautiful world! 👋\",\"type\":\"extended-text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"root\",\"version\":1}}",
|
||||
"feature_image": None,
|
||||
"feature_image_alt": None,
|
||||
"feature_image_caption": None,
|
||||
"featured": 0, # boolean indicating featured status
|
||||
"page": 0, # boolean indicating if this is a page or post
|
||||
"status": "published", # or draft
|
||||
"published_at": 1283780649000, # epoch time in milliseconds
|
||||
"published_by": 1, # the first user created has an id of 1
|
||||
"meta_title": None,
|
||||
"meta_description": None,
|
||||
"email_only": False, # boolean indicating email-only type of post
|
||||
"author_id": 1, # the first user created has an id of 1
|
||||
"created_at": 1283780649000, # epoch time in milliseconds
|
||||
"created_by": 1, # the first user created has an id of 1
|
||||
"updated_at": 1286958624000, # epoch time in milliseconds
|
||||
"updated_by": 1 # the first user created has an id of 1
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
{
|
||||
"id": 5,
|
||||
"name": "Colorado Ho!",
|
||||
"slug": "colorado-ho", # Optional, will be generated by Ghost if missing
|
||||
"description": ""
|
||||
}
|
||||
],
|
||||
"posts_tags": [
|
||||
{"tag_id": 5, "post_id": 1},
|
||||
],
|
||||
"users": [
|
||||
{
|
||||
"id": 3,
|
||||
"name": "Jo Bloggs",
|
||||
"slug": "jo-blogs", # Optional, will be generated by Ghost if missing
|
||||
"email": "jo@example.com",
|
||||
"profile_image": None,
|
||||
"cover_image": None,
|
||||
"bio": None,
|
||||
"website": None,
|
||||
"location": None,
|
||||
"accessibility": None,
|
||||
"meta_title": None,
|
||||
"meta_description": None,
|
||||
"created_at": 1283780649000, # epoch time in millis
|
||||
"created_by": 1,
|
||||
"updated_at": 1286958624000, # epoch time in millis
|
||||
"updated_by": 1
|
||||
}
|
||||
],
|
||||
# Provide this if you want different roles to the default "Author" role
|
||||
"roles_users": [
|
||||
# {
|
||||
# "user_id": 2,
|
||||
# "role_id": ObjectId # This must reference the id from your database
|
||||
# }
|
||||
]
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue