Initial commit
This commit is contained in:
commit
493d019352
9 changed files with 1798 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/target
|
1598
Cargo.lock
generated
Normal file
1598
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
7
Cargo.toml
Normal file
7
Cargo.toml
Normal file
|
@ -0,0 +1,7 @@
|
|||
[package]
|
||||
name = "torznab-toolkit"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
rocket = "0.5.1"
|
21
README.md
Normal file
21
README.md
Normal file
|
@ -0,0 +1,21 @@
|
|||
# Torznab Toolkit
|
||||
|
||||
A toolkit for adding Torznab APIs to programs.
|
||||
|
||||
## Functionality
|
||||
|
||||
| API call | Explanation | Compatibility |
|
||||
| -------- | ------------------------------------------------------------ | -------------- |
|
||||
| caps | Returns the capabilities of the api. | ❌ |
|
||||
| search | Free text search query. | ❌ |
|
||||
| tvsearch | Search query with tv specific query params and filtering. | ❌ |
|
||||
| movie | Search query with movie specific query params and filtering. | ❌ |
|
||||
| music | Search query with music specific query params and filtering. | ❌ |
|
||||
| book | Search query with book specific query params and filtering. | ❌ |
|
||||
|
||||
<!-- for copy-pasting: ❌ ✅ -->
|
||||
(copied from [torznab.github.io](https://torznab.github.io/spec-1.3-draft/torznab/Specification-v1.3.html))
|
||||
|
||||
## Notes
|
||||
|
||||
Thanks to [torznab.github.io](https://torznab.github.io), as it's my primary reference for this.
|
22
dev-notes.md
Normal file
22
dev-notes.md
Normal file
|
@ -0,0 +1,22 @@
|
|||
# Dev notes
|
||||
|
||||
## Resources
|
||||
|
||||
- <https://torznab.github.io/spec-1.3-draft/index.html>
|
||||
- <https://www.git.je/Mirrors/Sonarr/wiki/Implementing-a-Torznab-indexer>
|
||||
- for testing: <https://fosstorrents.com/thankyou/?name=debian&cat=Installation%20-%20amd64&id=0&hybrid=0>
|
||||
|
||||
---
|
||||
|
||||
```rs
|
||||
struct TorznabToolkitConfig {
|
||||
auth_func: auth,
|
||||
search_func: search,
|
||||
whateverotherfunc: otherfunc,
|
||||
port: 5309
|
||||
}
|
||||
|
||||
fn launch() -> Result {
|
||||
rocket::build().mount("/", routes![tt::search, tt:otherfunc])
|
||||
}
|
||||
```
|
4
src/api.rs
Normal file
4
src/api.rs
Normal file
|
@ -0,0 +1,4 @@
|
|||
use rocket::get;
|
||||
|
||||
#[get("/api?t=caps")]
|
||||
pub(crate) fn caps() -> Result<String, String> {}
|
51
src/config.rs
Normal file
51
src/config.rs
Normal file
|
@ -0,0 +1,51 @@
|
|||
use crate::data::*;
|
||||
|
||||
type AuthFunc = fn(String) -> Result<String, String>;
|
||||
type SearchFunc = fn(String, Vec<String>) -> Result<String, String>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Config {
|
||||
/// A struct that holds configuration for torznab-toolkit
|
||||
/// A search function (/api?t=search) and capabilities (/api?t=caps - struct Caps) required
|
||||
/// Everything else is optional
|
||||
pub search: SearchFunc,
|
||||
pub auth: Option<AuthFunc>,
|
||||
pub caps: Caps,
|
||||
pub tvsearch: Option<SearchFunc>,
|
||||
pub movie: Option<SearchFunc>,
|
||||
pub music: Option<SearchFunc>,
|
||||
pub book: Option<SearchFunc>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Caps {
|
||||
/// Holds the configuration for the capabilities of the Torznab server
|
||||
///
|
||||
/// - server_info: `ServerInfo`
|
||||
/// - see: `ServerInfo` docs
|
||||
/// - limits: `Limits`
|
||||
/// - specifies the max and default items listed when searching
|
||||
/// - see: `Limits` docs
|
||||
/// - searching: `Vec<SearchInfo>`
|
||||
/// - specifies the capabilities of each search mode
|
||||
/// - see: `SearchInfo` docs
|
||||
/// - categories: `Vec<Category>`
|
||||
/// - lists known categories
|
||||
/// - see: `Category` docs
|
||||
/// - genres: `Option<Vec<Genre>>`
|
||||
/// - lists known genres, optional
|
||||
/// - see: `Genre` docs
|
||||
///
|
||||
/// <div class="warning">Note that this library might not support all the capabilities listed in yet, so check the README before listing capabilities, or just accept that unsupported capabilities will return error 404.
|
||||
///
|
||||
/// It's recommended to add any capabilities you want, and set `available` to `false` in the `Caps` struct for any currently unsupported search types.</div>
|
||||
///
|
||||
///
|
||||
/// TODO: Add a way to partially generate search capabilities automatically from the Config
|
||||
pub server_info: ServerInfo,
|
||||
pub limits: Limits,
|
||||
pub searching: Vec<SearchInfo>,
|
||||
pub categories: Vec<Category>,
|
||||
pub genres: Option<Vec<Genre>>,
|
||||
pub tags: Option<Vec<Tag>>,
|
||||
}
|
62
src/data.rs
Normal file
62
src/data.rs
Normal file
|
@ -0,0 +1,62 @@
|
|||
#[derive(Debug)]
|
||||
pub struct ServerInfo {
|
||||
/// Specify the ServerInfo to be listed in <server> for `/api?t=caps`
|
||||
///
|
||||
/// These fields are just those listed in the example on [torznab.github.io](https://torznab.github.io), there's no actual specification for thse fields.
|
||||
/// TODO: Update this to have customizable fields instead
|
||||
pub title: Option<String>,
|
||||
pub email: Option<String>,
|
||||
pub image: Option<String>,
|
||||
pub version: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Limits {
|
||||
/// The maximum and defaults for the `limit` parameter in queries
|
||||
/// `max` is the maximum number of results the program can return
|
||||
/// `default` is the default number of results the program will return
|
||||
/*
|
||||
I don't know why this would possibly need to be a u64, I can't imagine you'll be returning 18 quintillion results or whatever
|
||||
In fact, I *really* hope you aren't - if you are, you're doing something extremely wrong
|
||||
But hey, it's an option
|
||||
*/
|
||||
pub max: u64,
|
||||
pub default: u64,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct SearchInfo {
|
||||
/// A struct holding the info for a type of search
|
||||
/// - `search_type` must be `search`, `tv-search`, `movie-search`, `audio-search`, or `book-search`
|
||||
/// - `available`
|
||||
pub search_type: String,
|
||||
pub available: bool,
|
||||
pub supported_params: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Subcategory {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Category {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
pub subcategories: Vec<Subcategory>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Genre {
|
||||
pub id: String,
|
||||
pub category_id: String,
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Tag {
|
||||
pub id: String,
|
||||
pub category_id: String,
|
||||
pub name: String,
|
||||
}
|
32
src/lib.rs
Normal file
32
src/lib.rs
Normal file
|
@ -0,0 +1,32 @@
|
|||
#![warn(missing_docs)]
|
||||
//! A toolkit for adding Torznab APIs to programs.
|
||||
//!
|
||||
//! Just fill in your own relevant functions and config, and
|
||||
//! torznab-toolkit will run the API for you
|
||||
//!
|
||||
//! ```rs
|
||||
//! use torznab_toolkit;
|
||||
//! let config: torznab_toolkit::config::Config =
|
||||
//!
|
||||
//! ```
|
||||
//!
|
||||
//! 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.
|
||||
//!
|
||||
//! ---
|
||||
//!
|
||||
//! This program is brought to you by: metaphorical *and* literal truckloads of structs!
|
||||
//!
|
||||
//! Note: I wrote the line above when I was tired. Don't ask me what *literal* truckloads of structs means, I don't know either.
|
||||
|
||||
mod api;
|
||||
pub mod config;
|
||||
pub mod data;
|
||||
|
||||
use config::{Caps, Config};
|
||||
use rocket;
|
||||
|
||||
pub fn run(config: Config, caps: Caps) -> Result<bool, String> {
|
||||
/// Runs the server
|
||||
rocket::build().mount("/", rocket::routes![api::caps]);
|
||||
return Ok(true);
|
||||
}
|
Loading…
Reference in a new issue