Skip to content

Commit

Permalink
feat: Atom feed
Browse files Browse the repository at this point in the history
  • Loading branch information
ankush committed Jun 1, 2024
1 parent d2d49b4 commit 3ace29e
Show file tree
Hide file tree
Showing 10 changed files with 67 additions and 15 deletions.
2 changes: 1 addition & 1 deletion content/posts/glorious-past.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
layout: post
title: "On our glorious past"
subtitle: "We were not alone!"
description: "We were not alone!"
date: 2021-09-14
---

Expand Down
2 changes: 1 addition & 1 deletion content/posts/mastery-cycling-mental-health.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
layout: post
title: "On mastery, cycling and mental health"
subtitle: "Story of my transition to Computer Science"
description: "Story of my transition to Computer Science"
date: 2018-11-25
---

Expand Down
2 changes: 1 addition & 1 deletion content/posts/mediocre-internship.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
layout: post
title: "How a mediocre internship shaped my life."
subtitle: "Story of my transition to Computer Science"
description: "Story of my transition to Computer Science"
date: 2018-01-31
---

Expand Down
2 changes: 1 addition & 1 deletion content/posts/shell-tools-speed.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
layout: post
title: "Parsing 140 gigabytes of chess games without compute clusters"
subtitle: "or why you should learn unix shell tools"
description: "or why you should learn unix shell tools"
date: 2021-08-28
---

Expand Down
2 changes: 1 addition & 1 deletion content/posts/tip-concurrency-schedule.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
layout: post
title: "Solving Concurrency Bugs Using Schedules and Imagination"
subtitle: "Race conditions are hard, debugging them without right approach is even harder."
description: "Race conditions are hard, debugging them without right approach is even harder."
date: 2024-05-29
---

Expand Down
2 changes: 1 addition & 1 deletion content/posts/vim-notetaking-workflow.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
layout: post
title: "Taking notes and managing tasks with Vim"
subtitle: "My semi-finished VimWiki Frankenstein system"
description: "My semi-finished VimWiki Frankenstein system"
date: 2020-11-09
---

Expand Down
45 changes: 37 additions & 8 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use axum::extract::{Path, State};
use axum::http::StatusCode;
use axum::response::Redirect;
use axum::http::{HeaderMap, StatusCode};
use axum::response::{IntoResponse, Redirect};
use axum::{response::Html, routing::get, Router};
use chrono::NaiveDate;
use minijinja::{context, Environment};
Expand All @@ -9,6 +9,12 @@ use std::cmp::Reverse;
use std::fs::{self, DirEntry};
use std::sync::Arc;

#[cfg(debug_assertions)]
const BASE_URL: &str = "http://localhost:3000";

#[cfg(not(debug_assertions))]
const BASE_URL: &str = "https://ankush.dev";

struct AppState {
env: Environment<'static>,
posts: Vec<Post>,
Expand All @@ -27,6 +33,7 @@ async fn main() {
.route("/", get(homepage))
.route("/p/:slug", get(get_posts))
.route("/:year/:month/:day/:slug", get(redirect_old_routes))
.route("/feed.xml", get(atom_feed))
.fallback(not_found)
.with_state(app_state);

Expand All @@ -43,16 +50,19 @@ fn get_jenv() -> Environment<'static> {
.unwrap();
env.add_template("post", include_str!("./templates/post.jinja"))
.unwrap();
env.add_template("feed", include_str!("./templates/feed.xml"))
.unwrap();
env
}

fn read_posts() -> Vec<Post> {
let post_files = fs::read_dir(POSTS_DIR).expect("Invalid content directory");
let mut posts: Vec<Post> = post_files
.map(|file| file.unwrap().into())
.collect();
let mut posts: Vec<Post> = post_files.map(|file| file.unwrap().into()).collect();
posts.sort_by_key(|p| Reverse(p.meta.date));
posts.into_iter().filter(|p| p.meta.published.unwrap_or(true)).collect()
posts
.into_iter()
.filter(|p| p.meta.published.unwrap_or(true))
.collect()
}

async fn homepage(State(state): State<Arc<AppState>>) -> Result<Html<String>, StatusCode> {
Expand Down Expand Up @@ -112,7 +122,8 @@ struct PostMeta {
title: String,
external_url: Option<String>,
date: NaiveDate,
subtitle: Option<String>,
iso_timestamp: Option<String>,
description: Option<String>,
published: Option<bool>,
}

Expand All @@ -126,7 +137,8 @@ impl From<DirEntry> for Post {
let sections: Vec<_> = raw_content.split("---").collect();
let frontmatter = sections[1];
let body = sections[2..].join("");
let meta = serde_yaml::from_str(frontmatter).expect("Invalid Frontmatter");
let mut meta: PostMeta = serde_yaml::from_str(frontmatter).expect("Invalid Frontmatter");
meta.iso_timestamp = Some(meta.date.format("%Y-%m-%dT00:00:00Z").to_string());

let content = markdown::to_html_with_options(&body, &markdown::Options::gfm()).unwrap();

Expand All @@ -137,3 +149,20 @@ impl From<DirEntry> for Post {
}
}
}

async fn atom_feed(State(state): State<Arc<AppState>>) -> impl IntoResponse {
// Reference: https://datatracker.ietf.org/doc/html/rfc4287
let template = state.env.get_template("feed").unwrap();

let rendered = template
.render(context! {
title => "Ankush Menat's Blog",
posts => state.posts,
author => "Ankush Menat",
BASE_URL => BASE_URL,
})
.unwrap();
let mut headers = HeaderMap::new();
headers.insert("Content-Type", "application/atom+xml".parse().unwrap());
(headers, rendered)
}
22 changes: 22 additions & 0 deletions src/templates/feed.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Example Feed</title>
<link href="{{ BASE_URL }}"/>
<link rel="self" type="application/atom+xml" href="{{ BASE_URL }}/feed.xml"/>
<updated>{{ posts[0].meta.iso_timestamp }}</updated>
<id>{{ BASE_URL }}/</id>
<author><name>{{ author }}</name></author>
{% for post in posts %}
<entry>
<title>{{ post.meta.title }}</title>
{% if post.meta.external_url %}
<link href="{{ post.meta.external_url }}"/>
{% else %}
<link href="{{ BASE_URL }}/p/{{ post.slug }}"/>
{% endif %}
<id>{{ BASE_URL }}/p/{{ post.slug }}</id>
<updated>{{ post.meta.iso_timestamp }}</updated>
{% if post.meta.description %}<summary>{{ post.meta.description }}</summary>{% endif %}
</entry>
{% endfor %}
</feed>
1 change: 1 addition & 0 deletions src/templates/layout.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
<a target="_blank" href="https://github.com/ankush">GitHub</a> ·
<a href="mailto:[email protected]">Email</a> ·
<a target="_blank" href="/assets/resume.pdf">Resume</a> ·
<a target="_blank" href="/feed.xml">Feed</a> ·
<a target="_blank" href="{% block source %}https://github.com/ankush/ankush.dev{% endblock %}">Source</a>
</nav>
</footer>
Expand Down
2 changes: 1 addition & 1 deletion src/templates/post.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
{% block meta %}
<meta property="og:title" content="{{ post.meta.title }}">
<meta property="og:type" content="article">
<meta property="og:description" content="{{ post.meta.subtitle }}">
<meta property="og:description" content="{{ post.meta.description }}">
{% endblock %}

{% block body %}
Expand Down

0 comments on commit 3ace29e

Please sign in to comment.