Compare commits
No commits in common. "3e37af540efab8fac1b79aa9384a007a3a2d144a" and "8a73d3d9cb612d84729583a903d2c4484e01b54f" have entirely different histories.
3e37af540e
...
8a73d3d9cb
5 changed files with 94 additions and 19 deletions
|
@ -2,7 +2,7 @@
|
|||
|
||||
A safe, multi-threaded, async toolkit for adding Torznab APIs to programs. You just focus on the indexer itself, we abstract away the hell that is the Torznab API.
|
||||
|
||||
Just fill in your own relevant functions and config ([`Config`]), and torznab-toolkit will run the API for you
|
||||
Just fill in your own relevant functions and config, and torznab-toolkit will run the API for you
|
||||
|
||||
```rust
|
||||
use torznab_toolkit;
|
||||
|
@ -11,7 +11,7 @@ let config: torznab_toolkit::config::Config = /* config goes here */
|
|||
torznab_toolkit::run(config);
|
||||
```
|
||||
|
||||
To configure what it listens on, just change `ROCKET_ADDRESS` and `ROCKET_PORT`; see the [relevant docs](https://rocket.rs/guide/v0.5/deploying/) for details.
|
||||
The environment variables `ROCKET_ADDRESS` and `ROCKET_PORT` specify the address and port it will run on; these currently cannot be configured any other way. See the [relevant docs](https://rocket.rs/guide/v0.5/deploying/) for details.
|
||||
|
||||
---
|
||||
|
||||
|
|
65
src/api.rs
65
src/api.rs
|
@ -32,7 +32,7 @@ struct SearchForm {
|
|||
|
||||
impl SearchForm {
|
||||
/// Converts it to a SearchParameters object
|
||||
fn to_parameters(&self, conf: Config, search_type: &str) -> SearchParameters {
|
||||
fn to_parameters(&self, conf: Config) -> InternalSearchParameters {
|
||||
let mut categories: Option<Vec<u32>> = None;
|
||||
if !self.cat.is_none() {
|
||||
// unholy amalgation of code to make the comma-separated list of strings into a vector of integers
|
||||
|
@ -71,8 +71,7 @@ impl SearchForm {
|
|||
limit = 1
|
||||
}
|
||||
|
||||
return SearchParameters {
|
||||
search_type: search_type.to_string(),
|
||||
return InternalSearchParameters {
|
||||
q: self.q.clone(),
|
||||
apikey: self.apikey.clone(),
|
||||
categories: categories,
|
||||
|
@ -213,12 +212,12 @@ pub(crate) async fn search(
|
|||
form: SearchForm,
|
||||
) -> status::Custom<RawXml<String>> {
|
||||
// oh god this is horrible but it works
|
||||
let parameters = form.to_parameters((**conf).clone(), "search");
|
||||
let parameters = form.to_parameters((**conf).clone());
|
||||
|
||||
let mut unauthorized = false;
|
||||
match conf.auth {
|
||||
Some(auth) => {
|
||||
match parameters.apikey.clone() {
|
||||
match parameters.clone().apikey {
|
||||
Some(apikey) => {
|
||||
if !auth(apikey).unwrap() {
|
||||
unauthorized = true;
|
||||
|
@ -237,7 +236,9 @@ pub(crate) async fn search(
|
|||
return status::Custom(Status::Unauthorized, RawXml("401 Unauthorized".to_string()));
|
||||
}
|
||||
|
||||
return search_handler(conf, parameters).await;
|
||||
let search_parameters: SearchParameters = parameters.to_search_param("search");
|
||||
|
||||
return search_handler(conf, search_parameters).await;
|
||||
}
|
||||
|
||||
#[get("/api?t=tvsearch&<form..>", rank = 3)]
|
||||
|
@ -247,7 +248,7 @@ pub(crate) async fn tv_search(
|
|||
form: SearchForm,
|
||||
) -> status::Custom<RawXml<String>> {
|
||||
// oh god this is horrible but it works
|
||||
let parameters = form.to_parameters((**conf).clone(), "tv-search");
|
||||
let parameters = form.to_parameters((**conf).clone());
|
||||
|
||||
let mut unauthorized = false;
|
||||
match conf.auth {
|
||||
|
@ -271,7 +272,16 @@ pub(crate) async fn tv_search(
|
|||
return status::Custom(Status::Unauthorized, RawXml("401 Unauthorized".to_string()));
|
||||
}
|
||||
|
||||
return search_handler(conf, parameters).await;
|
||||
let search_parameters: SearchParameters = parameters.to_search_param("tv-search");
|
||||
|
||||
/*
|
||||
* return status::Custom(
|
||||
* Status::NotImplemented,
|
||||
* RawXml("501 Not Implemented: Search function not implemented".to_string()),
|
||||
* );
|
||||
*/
|
||||
|
||||
return search_handler(conf, search_parameters).await;
|
||||
}
|
||||
|
||||
#[get("/api?t=movie&<form..>", rank = 4)]
|
||||
|
@ -281,7 +291,7 @@ pub(crate) async fn movie_search(
|
|||
form: SearchForm,
|
||||
) -> status::Custom<RawXml<String>> {
|
||||
// oh god this is horrible but it works
|
||||
let parameters = form.to_parameters((**conf).clone(), "movie-search");
|
||||
let parameters = form.to_parameters((**conf).clone());
|
||||
|
||||
let mut unauthorized = false;
|
||||
match conf.auth {
|
||||
|
@ -305,7 +315,16 @@ pub(crate) async fn movie_search(
|
|||
return status::Custom(Status::Unauthorized, RawXml("401 Unauthorized".to_string()));
|
||||
}
|
||||
|
||||
return search_handler(conf, parameters).await;
|
||||
let search_parameters: SearchParameters = parameters.to_search_param("movie-search");
|
||||
|
||||
/*
|
||||
* return status::Custom(
|
||||
* Status::NotImplemented,
|
||||
* RawXml("501 Not Implemented: Search function not implemented".to_string()),
|
||||
* );
|
||||
*/
|
||||
|
||||
return search_handler(conf, search_parameters).await;
|
||||
}
|
||||
|
||||
#[get("/api?t=music&<form..>", rank = 5)]
|
||||
|
@ -315,7 +334,7 @@ pub(crate) async fn music_search(
|
|||
form: SearchForm,
|
||||
) -> status::Custom<RawXml<String>> {
|
||||
// oh god this is horrible but it works
|
||||
let parameters = form.to_parameters((**conf).clone(), "audio-search");
|
||||
let parameters = form.to_parameters((**conf).clone());
|
||||
|
||||
let mut unauthorized = false;
|
||||
match conf.auth {
|
||||
|
@ -339,7 +358,16 @@ pub(crate) async fn music_search(
|
|||
return status::Custom(Status::Unauthorized, RawXml("401 Unauthorized".to_string()));
|
||||
}
|
||||
|
||||
return search_handler(conf, parameters).await;
|
||||
let search_parameters: SearchParameters = parameters.to_search_param("audio-search");
|
||||
|
||||
/*
|
||||
* return status::Custom(
|
||||
* Status::NotImplemented,
|
||||
* RawXml("501 Not Implemented: Search function not implemented".to_string()),
|
||||
* );
|
||||
*/
|
||||
|
||||
return search_handler(conf, search_parameters).await;
|
||||
}
|
||||
|
||||
#[get("/api?t=book&<form..>", rank = 6)]
|
||||
|
@ -349,7 +377,7 @@ pub(crate) async fn book_search(
|
|||
form: SearchForm,
|
||||
) -> status::Custom<RawXml<String>> {
|
||||
// oh god this is horrible but it works
|
||||
let parameters = form.to_parameters((**conf).clone(), "book-search");
|
||||
let parameters = form.to_parameters((**conf).clone());
|
||||
|
||||
let mut unauthorized = false;
|
||||
match conf.auth {
|
||||
|
@ -373,7 +401,16 @@ pub(crate) async fn book_search(
|
|||
return status::Custom(Status::Unauthorized, RawXml("401 Unauthorized".to_string()));
|
||||
}
|
||||
|
||||
return search_handler(conf, parameters).await;
|
||||
let search_parameters: SearchParameters = parameters.to_search_param("book-search");
|
||||
|
||||
/*
|
||||
* return status::Custom(
|
||||
* Status::NotImplemented,
|
||||
* RawXml("501 Not Implemented: Search function not implemented".to_string()),
|
||||
* );
|
||||
*/
|
||||
|
||||
return search_handler(conf, search_parameters).await;
|
||||
}
|
||||
|
||||
async fn search_handler(
|
||||
|
|
40
src/data.rs
40
src/data.rs
|
@ -122,7 +122,45 @@ pub struct Config {
|
|||
pub caps: Caps,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
/// An internal struct to hold the parameters for a search
|
||||
///
|
||||
/// Before being sent to the "client" program, it's turned into a SearchParameters object by `to_search_param()`, adding the search type
|
||||
#[derive(Debug, Clone, PartialEq, Eq, FromForm)]
|
||||
pub(crate) struct InternalSearchParameters {
|
||||
/// The text query for the search
|
||||
pub(crate) q: Option<String>,
|
||||
/// The apikey, for authentication
|
||||
pub(crate) apikey: Option<String>,
|
||||
/// A [`Vec`] containing the numeric category IDs to be included in the search results
|
||||
pub(crate) categories: Option<Vec<u32>>,
|
||||
/// A [`Vec`] containing the extended attribute names to be included in the search results
|
||||
pub(crate) attributes: Option<Vec<String>>,
|
||||
/// Whether *all* extended attributes should be included in the search results; overrules `attributes`
|
||||
pub(crate) extended_attrs: Option<bool>,
|
||||
/// How many items to skip/offset by in the results.
|
||||
pub(crate) offset: Option<u32>,
|
||||
/// The maximum number of items to return - also limited to whatever `limits` is in [`Caps`]
|
||||
pub(crate) limit: u32,
|
||||
}
|
||||
|
||||
impl InternalSearchParameters {
|
||||
/// Converts InternalSearchParameters to SearchParmaters, i.e. add `search_type`
|
||||
///
|
||||
/// Search types: `search`, `tv-search`, `movie-search`, `audio-search`, `book-search`
|
||||
pub(crate) fn to_search_param(&self, search_type: &str) -> SearchParameters {
|
||||
return SearchParameters {
|
||||
search_type: search_type.to_string(),
|
||||
q: self.q.clone(),
|
||||
apikey: self.apikey.clone(),
|
||||
categories: self.categories.clone(),
|
||||
attributes: self.attributes.clone(),
|
||||
extended_attrs: self.extended_attrs,
|
||||
offset: self.offset,
|
||||
limit: self.limit,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// Holds the parameters for a search query
|
||||
pub struct SearchParameters {
|
||||
/// What type of search this is
|
||||
|
|
|
@ -4,7 +4,7 @@ pub(crate) mod api;
|
|||
pub mod data;
|
||||
mod dummy;
|
||||
|
||||
use rocket;
|
||||
use rocket::{self};
|
||||
|
||||
/// Runs the server
|
||||
pub async fn run(conf: data::Config) -> Result<bool, rocket::Error> {
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
pub mod implementation;
|
||||
pub mod usage;
|
||||
pub mod implementation;
|
Loading…
Add table
Add a link
Reference in a new issue