Skip to content

Commit

Permalink
Merge pull request #167 from izderadicka/playlist
Browse files Browse the repository at this point in the history
Playlis for playable media
  • Loading branch information
ikatson authored Aug 7, 2024
2 parents 8c2788c + e7829bf commit e83c3d5
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 1 deletion.
41 changes: 41 additions & 0 deletions crates/librqbit/src/http_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use crate::torrent_state::peer::stats::snapshot::PeerStatsFilter;
type ApiState = Api;

use crate::api::Result;
use crate::ApiError;

/// An HTTP server for the API.
pub struct HttpApi {
Expand Down Expand Up @@ -128,6 +129,45 @@ impl HttpApi {
state.api_torrent_details(idx).map(axum::Json)
}

async fn torrent_playlist(
State(state): State<ApiState>,
headers: HeaderMap,
Path(idx): Path<usize>,
) -> Result<impl IntoResponse> {
let host = headers
.get("host")
.ok_or_else(|| {
ApiError::new_from_text(StatusCode::BAD_REQUEST, "Missing host header")
})?
.to_str()
.context("hostname is not string")?;

let playlist_items = state
.api_torrent_details(idx)?
.files
.into_iter()
.enumerate()
.filter_map(|(file_idx, f)| {
let is_playable = mime_guess::from_path(&f.name)
.first()
.map(|mime| {
mime.type_() == mime_guess::mime::VIDEO
|| mime.type_() == mime_guess::mime::AUDIO
})
.unwrap_or(false);
if is_playable {
let file_name = urlencoding::encode(&f.name);
Some(format!(
"http://{host}/torrents/{idx}/stream/{file_idx}/{file_name}"
))
} else {
None
}
});

Ok(playlist_items.collect::<Vec<_>>().join("\r\n"))
}

async fn torrent_haves(
State(state): State<ApiState>,
Path(idx): Path<usize>,
Expand Down Expand Up @@ -289,6 +329,7 @@ impl HttpApi {
.route("/torrents/:id/stats/v1", get(torrent_stats_v1))
.route("/torrents/:id/peer_stats", get(peer_stats))
.route("/torrents/:id/stream/:file_id", get(torrent_stream_file))
.route("/torrents/:id/playlist", get(torrent_playlist))
.route(
"/torrents/:id/stream/:file_id/*filename",
get(torrent_stream_file),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { TorrentStats } from "../../api-types";
import { APIContext, RefreshTorrentStatsContext } from "../../context";
import { IconButton } from "./IconButton";
import { DeleteTorrentModal } from "../modal/DeleteTorrentModal";
import { FaCog, FaPause, FaPlay, FaTrash } from "react-icons/fa";
import { FaCog, FaPause, FaPlay, FaTrash, FaClipboardList } from "react-icons/fa";
import { useErrorStore } from "../../stores/errorStore";

export const TorrentActions: React.FC<{
Expand Down Expand Up @@ -94,6 +94,11 @@ export const TorrentActions: React.FC<{
<IconButton onClick={startDeleting} disabled={disabled}>
<FaTrash className="hover:text-red-500" />
</IconButton>
<IconButton onClick={() => {alert("Open this playlist link in external player like VLC")}}>
<a target="_blank" href={"/torrents/"+id+"/playlist"}>
<FaClipboardList className="hover:text-green-500"/>
</a>
</IconButton>
<DeleteTorrentModal id={id} show={deleting} onHide={cancelDeleting} />
</div>
);
Expand Down

0 comments on commit e83c3d5

Please sign in to comment.