Skip to content

Commit

Permalink
Add Atom feed export
Browse files Browse the repository at this point in the history
Add Result type.

Return also the more general DateTime<FixedOffset> type instead of DateTime<Utc> in parse_from_str().

For failed tests: also output pretty-printed export XML for easier comparison with expected output.

Code refactoring. Edit install instructions and usage. Edit comments.
  • Loading branch information
willemw12 committed Jun 5, 2024
1 parent 21b9912 commit 88f5d8b
Show file tree
Hide file tree
Showing 16 changed files with 802 additions and 304 deletions.
262 changes: 117 additions & 145 deletions Cargo.lock

Large diffs are not rendered by default.

19 changes: 11 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "xmltv2rss"
version = "0.1.1"
version = "0.1.2"
authors = ["willemw12 <[email protected]>"]
edition = "2021"
license = "GPL-3.0-or-later"
Expand All @@ -9,11 +9,9 @@ homepage = "https://github.com/willemw12/xmltv2rss-rs"
#documentation = "https://github.com/willemw12/xmltv2rss-rs"
repository = "https://github.com/willemw12/xmltv2rss-rs"
readme = "README.md"
keywords = ["epg", "rss", "tv", "xmltv"]
keywords = ["atom", "epg", "rss", "tv", "xmltv"]
categories = ["command-line-utilities"]

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

# [[bin]]
# name = "xmltv2rss"
# required-features = ["build-binary"]
Expand All @@ -22,11 +20,16 @@ categories = ["command-line-utilities"]
# build-binary = ["dep:clap"]

[dependencies]
# clap = { version = "4.5.4", features = ["cargo", "derive"], optional = true }
clap = { version = "4.5.4", features = ["cargo", "derive"] }
atom_syndication = "0.12.3"
chrono = "0.4.38"
# clap = { version = "...", features = ["cargo", "derive"], optional = true }
clap = { version = "4.5.4", features = ["cargo", "derive"] }
derive_builder = "0.20.0"
quick-xml = { version = "0.31", features = ["serialize"] }
rss = "2.0.7"
thiserror = "1.0.59"
rss = "2.0.8"
thiserror = "1.0.61"
uuid = { version = "1.8.0", features = ["v4", "macro-diagnostics", "serde"] }
xmltv = "0.9.6"

[dev-dependencies]
pretty_assertions = "1.4.0"
55 changes: 37 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
xmltv2rss
=========

Generate an RSS feed from an XMLTV TV listing.
Generate an RSS or Atom feed from an XMLTV TV listing.


Installation
Expand All @@ -11,6 +11,10 @@ The following requires [Rust](https://www.rust-lang.org/).

To install xmltv2rss, for example, in folder ~/.local/bin, run:

$ cargo install --git=https://github.com/willemw12/xmltv2rss-rs.git --no-track --root=$HOME/.local

Or the same, but download separately:

$ git clone https://github.com/willemw12/xmltv2rss-rs.git
$ cargo install --no-track --path=./xmltv2rss-rs --root=$HOME/.local

Expand All @@ -19,7 +23,7 @@ Usage
-----

$ xmltv2rss --help
Generate an RSS feed from an XMLTV TV listing. Print the result to standard output.
Generate an RSS or Atom feed from an XMLTV TV listing. Print the result to standard output.

For information about date and time format strings ("%Y", "%H", etc.), search for "strftime" on <https://docs.rs/chrono/latest/chrono/index.html>.

Expand All @@ -31,36 +35,45 @@ Usage

Options:
-d, --feed-date-format <FEED_DATE_FORMAT>
RSS feed date format. Examples: "%%Y-%%m-%%d", "%%a %%d %%B, %%Y", "%%x"
Output feed date format. Examples: "%%Y-%%m-%%d", "%%a %%d %%B, %%Y", "%%x"

[default: "%a %d %B, %Y"]

--feed-description <FEED_DESCRIPTION>
RSS feed description
Output feed description

--feed-indent <FEED_INDENT>
RSS feed indentation
Output feed indentation

[default: 2]

--feed-language <FEED_LANGUAGE>
RSS feed language
Output feed language

--feed-link <FEED_LINK>
RSS feed URL
Output feed URL

[default: ]

-t, --feed-time-format <FEED_TIME_FORMAT>
RSS feed time format. Examples: "%%H:%%M", "%%I:%%M %%p", "%%X"
Output feed time format. Examples: "%%H:%%M", "%%I:%%M %%p", "%%X"

[default: %H:%M]

--feed-title <FEED_TITLE>
RSS feed title
Output feed title

[default: "XMLTV feed"]

--feed-type <FEED_TYPE>
Output feed type

[default: rss]

Possible values:
- atom
- rss: Rss 2.0

--xmltv-datetime-format <XMLTV_DATETIME_FORMAT>
XMLTV date and time format
[default fallback: "%Y%m%d%H%M%S"]
Expand All @@ -79,18 +92,24 @@ Library usage

```rust
use std::io;
use xmltv2rss::export::rss::{export, OptionsBuilder};
use xmltv2rss::error::Result;
use xmltv2rss::export::{rss, OptionsBuilder};

fn print() -> Result<()> {
// let options = rss::Options::default();
let options = OptionsBuilder::default()
// .language(&*string)
// .language(string.as_str())
.language("en")
.build()?;

// let options = Options::default();
let options = OptionsBuilder::default()
// .language(string.as_str())
.language("en")
.build()?;
let channel = rss::export("Title", "https://example.com/", Some("Description"),
&options, Some("./tests/input/simple.xml"))?;

let channel = export("Title", "https://example.com/", Some("Description"),
&options, Some("file.xml"))?;
channel.pretty_write_to(io::stdout(), b' ', 2)?;

channel.pretty_write_to(io::stdout(), b' ', 2)?;
Ok(())
}
```


Expand Down
24 changes: 24 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use thiserror::Error;

pub type Result<T> = std::result::Result<T, Error>;

#[derive(Error, Debug)]
pub enum Error {
#[error(transparent)]
Atom(#[from] atom_syndication::Error),

#[error(transparent)]
De(#[from] quick_xml::DeError),

#[error(transparent)]
Io(#[from] std::io::Error),

#[error(transparent)]
OptionsBuilder(#[from] crate::export::OptionsBuilderError),

#[error(transparent)]
Parse(#[from] chrono::ParseError),

#[error(transparent)]
Rss(#[from] rss::Error),
}
49 changes: 46 additions & 3 deletions src/export.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,52 @@
//! Common export module.
use derive_builder::Builder;
use xmltv::{Programme, Tv};

pub mod atom;
pub mod rss;

use crate::xmltv::Error;
use crate::error::Error;
use crate::xmltv::DEFAULT_XMLTV_DATETIME_FORMAT;

pub const DEFAULT_FEED_CHANNEL_DESCRIPTION: &str = "Generated by xmltv2rss";
pub const DEFAULT_FEED_CHANNEL_TITLE: &str = "XMLTV feed";

pub const DEFAULT_FEED_DATE_FORMAT: &str = "%a %d %B, %Y";
pub const DEFAULT_FEED_TIME_FORMAT: &str = "%H:%M";

const GUID_DATETIME_FORMAT: &str = "%Y%m%d%H%M%S";

/// Feed export options struct.
#[derive(Builder)]
pub struct Options<'a> {
#[builder(default, setter(into, strip_option))]
pub language: Option<&'a str>,

/// See [`DEFAULT_FEED_DATE_FORMAT`].
#[builder(default = "DEFAULT_FEED_DATE_FORMAT")]
pub date_format: &'a str,

/// See [`DEFAULT_FEED_TIME_FORMAT`].
#[builder(default = "DEFAULT_FEED_TIME_FORMAT")]
pub time_format: &'a str,

/// See [`DEFAULT_XMLTV_DATETIME_FORMAT`].
#[builder(default = "DEFAULT_XMLTV_DATETIME_FORMAT")]
pub xmltv_datetime_format: &'a str,
}

impl Default for Options<'_> {
fn default() -> Self {
Self {
language: None,
date_format: DEFAULT_FEED_DATE_FORMAT,
time_format: DEFAULT_FEED_TIME_FORMAT,

xmltv_datetime_format: DEFAULT_XMLTV_DATETIME_FORMAT,
}
}
}

//

/// XMLTV export trait.
pub trait Visitor {
Expand Down Expand Up @@ -55,6 +97,7 @@ pub trait Visitor {

//

/// Returns the export result.
fn result(&self) -> Result<Self::Output, Error>;
}

Expand Down
Loading

0 comments on commit 88f5d8b

Please sign in to comment.