Skip to content

Commit

Permalink
Add atom feed.
Browse files Browse the repository at this point in the history
  • Loading branch information
MetroWind committed Nov 21, 2023
1 parent e4d2889 commit 8df4bf2
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 4 deletions.
29 changes: 27 additions & 2 deletions nspic/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,22 @@ fn handlePost(templates: &Tera, post_id: i64, data_manager: &data::Manager,
Ok(warp::reply::html(html).into_response())
}

fn handleFeed(templates: &Tera, data_manager: &data::Manager,
config: &Configuration) -> Result<Response, Error>
{
let feed_size = 10;
let posts = data_manager.getPosts(
0, feed_size, data::PostOrder::NewFirst)?;
let mut context = tera::Context::new();
context.insert("posts", &posts);
context.insert("site_info", &config.site_info);
let feed_str = templates.render("atom.xml", &context).map_err(
|e| rterr!("Failed to render template: {}", e))?;
Ok(warp::reply::with_header(feed_str, "Content-Type",
"application/atom+xml")
.into_response())
}

fn handleDeleteConfirm(
templates: &Tera, post_id: i64, data_manager: &data::Manager,
config: &Configuration, token: Option<String>) -> Result<Response, Error>
Expand Down Expand Up @@ -220,6 +236,7 @@ fn urlFor(name: &str, arg: &str) -> String
"index" => String::from("/"),
"upload" => String::from("/upload"),
"post" => String::from("/p/") + arg,
"feed" => String::from("/feed.xml"),
"delete_confirm" => String::from("/delete-confirm/") + arg,
"delete" => String::from("/delete/") + arg,
"login" => String::from("/login/"),
Expand Down Expand Up @@ -339,6 +356,14 @@ impl App
handlePost(&temp, id, &data_manager, &config).toResponse()
});

let temp = self.templates.clone();
let config = self.config.clone();
let data_manager = self.data_manager.clone();
let feed = warp::get().and(warp::path("feed.xml"))
.and(warp::path::end()).map(move || {
handleFeed(&temp, &data_manager, &config).toResponse()
});

let temp = self.templates.clone();
let config = self.config.clone();
let data_manager = self.data_manager.clone();
Expand Down Expand Up @@ -393,8 +418,8 @@ impl App
handleLogin(auth_value, &data_manager, &config).toResponse()
});

let bare_route = statics.or(index).or(post).or(delete_confirm).or(delete)
.or(upload_page).or(upload).or(login);
let bare_route = statics.or(index).or(post).or(feed).or(delete_confirm)
.or(delete).or(upload_page).or(upload).or(login);
let route = if self.config.serve_under_path == String::from("/") ||
self.config.serve_under_path.is_empty()
{
Expand Down
8 changes: 8 additions & 0 deletions nspic/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ fn defaultSessionLiftTimeSec() -> u64 { 2592000 }
fn defaultSiteTitle() -> String { String::from("NSPic") }
fn defaultFootnote() -> String { String::new() }
fn defaultUrlDomain() -> String { String::from("http://example.org") }
fn defaultUsername() -> String { String::from("User") }

#[derive(Deserialize, Serialize, Clone)]
pub struct SiteInfo
Expand All @@ -53,11 +54,17 @@ pub struct SiteInfo
pub site_title: String,
#[serde(default = "defaultFootnote")]
pub footnote: String,

/// The beginning part of the URL of the website, including only
/// the protocol and domain, without the trailing slash. This is
/// only used in the OGP metadata. Example: http://example.org.
#[serde(default = "defaultUrlDomain")]
pub url_domain: String,

/// This is only used for atom feed.
#[serde(default = "defaultUsername")]
pub username: String,

}

impl Default for SiteInfo
Expand All @@ -68,6 +75,7 @@ impl Default for SiteInfo
site_title: defaultSiteTitle(),
footnote: defaultFootnote(),
url_domain: defaultUrlDomain(),
username: defaultUsername(),
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions nspic/src/post.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ impl Serialize for Post
state.serialize_field(
"upload_time_utc_str", &self.upload_time.format(&format).map_err(
|_| serde::ser::Error::custom("Invalid upload time"))?)?;
state.serialize_field(
"upload_time_rfc3339", &self.upload_time.format(
&time::format_description::well_known::Rfc3339).map_err(
|_| serde::ser::Error::custom("Invalid upload time"))?)?;
state.serialize_field("album_id", &self.album_id)?;
state.end()
}
Expand Down
22 changes: 22 additions & 0 deletions nspic/templates/atom.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>{{ site_info.site_title }}</title>
<link href="http://example.org/"/>
<updated>{{ posts[0].upload_time_rfc3339 }}</updated>
<author>
<name>{{ site_info.username }}</name>
</author>
<id>{{ url_for(name='index', arg='') }}</id>
{% for post in posts -%}
<entry>
<link href="{{ url_for(name='post', arg=post.id | as_str)}}"
rel="self" type="text/html"/>
{% for image in post.images %}
<link rel="related" type="image/*"
href="{{ url_for(name='image_file', arg=image.path) }}"/>
<id>{{ url_for(name='post', arg=post.id | as_str)}}</id>
<published>{{ post.upload_time_rfc3339 }}</published>
<summary>{{ post.desc }}</summary>
</entry>
{% endfor %}
</feed>
2 changes: 1 addition & 1 deletion nspic/templates/include-footer.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<hr/>
<footer>
<div>{{ site_info.footnote }}</div>
<div><a href="https://github.com/MetroWind/nspic">Source code</a></div>
<div><a href="{{ url_for(name='feed', arg='') }}">Feed</a> | <a href="https://github.com/MetroWind/nspic">Source code</a></div>
</footer>
5 changes: 4 additions & 1 deletion nspic/templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@
<meta property="og:type" content="website" />
<meta property="og:description" content="{{ site_info.site_title }}" />
<meta property="og:url" content="{{ site_info.url_domain ~ url_for(name='index', arg='') }}" />
<meta property="og:image" content="{{ site_info.url_domain ~ url_for(name='static', arg='film.svg') }}" />
<meta property="og:image" content="{{ site_info.url_domain ~
url_for(name='static', arg='film.svg') }}" />
<link rel="alternate" type="application/atom+xml" title="Atom feed"
href="{{ url_for(name='feed', arg='') }}" />
<title>NSPic → Index</title>
</head>
<body>
Expand Down

0 comments on commit 8df4bf2

Please sign in to comment.