Skip to content

Commit 34c21c7

Browse files
[update] fix intro
1 parent 88e8c0c commit 34c21c7

File tree

3 files changed

+178
-10
lines changed

3 files changed

+178
-10
lines changed

components/intro.tsx

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,22 @@ const Intro = ({ totalPostNumber }: Props) => {
1717
</p>
1818
</div>
1919
</div>
20-
<div className="max-w-3xl sm:text-justify">
21-
<h1 className="text-[24.4px] font-semibold tracking-none leading-[150%] text-gray-400 mb-4 lg:leading-[200%] lg:mb-0">
22-
Hi <span className="wave">👋🏻</span>{" "}
23-
<span className="text-[#E8E8FD]">I&apos;m Prajwal</span>. I currently work as an SRE 1 at{" "} PhonePe, India. I have a passion for writing about tech, philosophy, life, books, and my travel experiences. Exploring new places is something I truly enjoy.
24-
My work primarily involves building scalable and reliable systems. You can check out some of the projects we work on at PhonePe here: <a href="https://phonepe.github.io/" target="_blank" rel="noreferrer">PhonePe GitHub</a> and <a href="https://tech.phonepe.com/" target="_blank" rel="noreferrer">PhonePe Tech Blog</a>.
25-
Working on such large-scale systems is both interesting and rewarding, you learn new things almost everyday.
26-
<p className="text-center">Thoughts on tech, philosophy, and books.</p>
27-
</h1>
28-
</div>
20+
<div className="max-w-3xl text-center">
21+
<article className="text-[24.4px] font-semibold tracking-none leading-[150%] text-gray-400 mb-4 lg:leading-[200%] lg:mb-0">
22+
<header>
23+
Hi <span className="wave">👋🏻</span>{" "}
24+
<span className="text-[#E8E8FD]">I&apos;m Prajwal</span>. I currently work as an SRE 1 at PhonePe, India. I have a passion for writing about tech, philosophy, life, books, and my travel experiences.
25+
</header>
26+
27+
<p>
28+
My work primarily involves building scalable and reliable systems, When I&apos;m not in the tech zone, I&apos;m probably pushing myself at the gym, on a trip, or experimenting in the kitchen.
29+
</p>
30+
31+
<p className="text-center">
32+
Thoughts on tech, philosophy, and books.
33+
</p>
34+
</article>
35+
</div>
2936
<div>
3037
<div className="grid gap-8 items-start justify-center mt-4">
3138
<div className="relative">

export.py

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
import os
2+
import frontmatter
3+
import json
4+
from datetime import datetime
5+
import uuid
6+
import re
7+
8+
def convert_markdown_to_lexical(markdown_content):
9+
"""Convert markdown content to Ghost's Lexical format"""
10+
return {
11+
"root": {
12+
"children": [
13+
{
14+
"children": [
15+
{
16+
"detail": 0,
17+
"format": 0,
18+
"mode": "normal",
19+
"style": "",
20+
"text": markdown_content,
21+
"type": "text",
22+
"version": 1
23+
}
24+
],
25+
"direction": "ltr",
26+
"format": "",
27+
"indent": 0,
28+
"type": "paragraph",
29+
"version": 1
30+
}
31+
],
32+
"direction": "ltr",
33+
"format": "",
34+
"indent": 0,
35+
"type": "root",
36+
"version": 1
37+
}
38+
}
39+
40+
def sanitize_slug(text):
41+
"""Generate a Ghost-compatible slug from text"""
42+
slug = re.sub(r'[^\w\s-]', '', text).strip().lower()
43+
slug = re.sub(r'[-\s]+', '-', slug)
44+
return slug
45+
46+
def convert_mdx_to_ghost_import(mdx_directory, output_file):
47+
# Initialize Ghost export structure
48+
ghost_export = {
49+
"db": [
50+
{
51+
"meta": {
52+
"exported_on": int(datetime.now().timestamp() * 1000),
53+
"version": "5.71.0"
54+
},
55+
"data": {
56+
"users": [
57+
{
58+
"id": "1",
59+
"name": "Prajwal P",
60+
"slug": "prajwal",
61+
"email": "[email protected]",
62+
"created_at": datetime.now().isoformat() + "Z",
63+
"updated_at": datetime.now().isoformat() + "Z"
64+
}
65+
],
66+
"posts": [],
67+
"posts_authors": [],
68+
"tags": [],
69+
"posts_tags": []
70+
}
71+
}
72+
]
73+
}
74+
75+
post_id = 1
76+
tag_id = 1
77+
posts_tags_id = 1
78+
79+
for filename in os.listdir(mdx_directory):
80+
if filename.endswith('.mdx'):
81+
file_path = os.path.join(mdx_directory, filename)
82+
83+
with open(file_path, 'r', encoding='utf-8') as f:
84+
post = frontmatter.loads(f.read())
85+
86+
# Process dates
87+
post_date = post.metadata.get("date", datetime.now())
88+
if isinstance(post_date, str):
89+
try:
90+
post_date = datetime.fromisoformat(post_date.replace('Z', '+00:00'))
91+
except:
92+
post_date = datetime.now()
93+
94+
# Generate slug
95+
slug = sanitize_slug(post.metadata.get("slug", os.path.splitext(filename)[0]))
96+
97+
# Convert content to Lexical format
98+
lexical_content = convert_markdown_to_lexical(post.content)
99+
100+
# Create post object
101+
ghost_post = {
102+
"id": str(post_id),
103+
"uuid": str(uuid.uuid4()),
104+
"title": post.metadata.get("title", "Untitled Post"),
105+
"slug": slug,
106+
"mobiledoc": None,
107+
"lexical": json.dumps(lexical_content),
108+
"html": post.content,
109+
"comment_id": str(post_id),
110+
"feature_image": post.metadata.get("coverImage"),
111+
"featured": 0,
112+
"type": "post",
113+
"status": "draft" if post.metadata.get("draft", False) else "published",
114+
"created_at": post_date.isoformat() + "Z",
115+
"updated_at": post_date.isoformat() + "Z",
116+
"published_at": post_date.isoformat() + "Z",
117+
"custom_excerpt": post.metadata.get("excerpt", ""),
118+
"visibility": "public",
119+
"authors": [{"id": "1"}]
120+
}
121+
122+
# Add post to export
123+
ghost_export["db"][0]["data"]["posts"].append(ghost_post)
124+
125+
# Handle tags/categories
126+
category = post.metadata.get("category")
127+
if category:
128+
tag_slug = sanitize_slug(category)
129+
130+
# Add tag if not exists
131+
if not any(tag['slug'] == tag_slug for tag in ghost_export["db"][0]["data"]["tags"]):
132+
ghost_tag = {
133+
"id": str(tag_id),
134+
"name": category,
135+
"slug": tag_slug,
136+
"created_at": post_date.isoformat() + "Z",
137+
"updated_at": post_date.isoformat() + "Z"
138+
}
139+
ghost_export["db"][0]["data"]["tags"].append(ghost_tag)
140+
tag_id += 1
141+
142+
# Create post-tag relationship
143+
ghost_export["db"][0]["data"]["posts_tags"].append({
144+
"id": str(posts_tags_id),
145+
"post_id": str(post_id),
146+
"tag_id": str(tag_id - 1) # Use last assigned tag ID
147+
})
148+
posts_tags_id += 1
149+
150+
post_id += 1
151+
152+
# Write to JSON file
153+
with open(output_file, 'w', encoding='utf-8') as f:
154+
json.dump(ghost_export, f, indent=2, ensure_ascii=False)
155+
156+
if __name__ == "__main__":
157+
MDX_DIRECTORY = "_posts"
158+
OUTPUT_FILE = "ghost_import.json"
159+
160+
convert_mdx_to_ghost_import(MDX_DIRECTORY, OUTPUT_FILE)
161+
print(f"Ghost import file created: {OUTPUT_FILE}")

public/rss.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<title>Prajwals Blog</title>
55
<link>http://localhost:3000</link>
66
<description>Hi I'm Prajwal, and this is my blog. Here, I share through my writing my experience as a Computer science student and everything I'm learning about on React, Typescript, Go, Serverless, System Design and Testing.</description>
7-
<lastBuildDate>Sun, 02 Feb 2025 09:17:26 GMT</lastBuildDate>
7+
<lastBuildDate>Mon, 03 Feb 2025 05:44:50 GMT</lastBuildDate>
88
<docs>https://validator.w3.org/feed/docs/rss2.html</docs>
99
<generator>Feed for Node.js</generator>
1010
<image>

0 commit comments

Comments
 (0)