import { render, Component, linkEvent } from 'inferno'; import * as moment from 'moment'; import { endpoint } from './env'; import { SearchParams, Results, State } from './interfaces'; import { convertCsvToJson, humanFileSize, magnetLink } from './utils'; import './Main.css'; const container = document.getElementById('app'); class TorrentSearchComponent extends Component { state: State = { results: { torrents: [] }, searchParams: { q: "", page: 1 }, searching: false }; constructor(props, context) { super(props, context); } search(i: TorrentSearchComponent, event) { event.preventDefault(); if (!!i.state.searchParams.q) { i.setState({ searching: true, results: { torrents: [] } }); i.fetchData(i.state.searchParams) .then(results => { if (!!results) { i.setState({ results: results }); } }).catch(error => { console.error('request failed', error); }).then(() => i.setState({ searching: false })); } else { i.setState({ results: { torrents: [] } }); } } fetchData(searchParams: SearchParams): Promise { let q = encodeURI(searchParams.q); return fetch(`${endpoint}/service/search?q=${q}&page=${searchParams.page}`) .then(data => data.text()) .then(csv => convertCsvToJson(csv)); } render() { return (
{this.navbar()}
{ this.state.searching ? this.spinner() : this.state.results.torrents[0] ? this.table() : this.onboard() }
); } table() { return (
{this.state.results.torrents.map(torrent => ( ))}
Name Size Seeds Leeches Created Scraped
{torrent.name} {humanFileSize(torrent.size_bytes, true)} {torrent.seeders} {torrent.leechers} {moment(torrent.created_unix * 1000).fromNow()} {moment(torrent.scraped_date * 1000).fromNow()}
{this.paginator()}
); } navbar() { return ( ); } // TODO // https://www.codeply.com/go/xBVaM3q5X4/bootstrap-4-navbar-search-full-width searchForm() { return (
); } spinner() { return (
); } onboard() { let site: string = "https://gitlab.com/dessalines/torrents.csv"; return (
Torrents.csv is a collaborative, vetted git repository of torrents, consisting of a single, searchable torrents.csv file. Its initially populated with a January 2017 backup of the pirate bay, and new torrents are periodically added from various torrents sites via a rust script.



Torrents.csv will only store torrents with at least one seeder to keep the file small, and will be periodically purged of non-seeded torrents, and sorted by seeders descending.



To request more torrents, or add your own to the file, go here.



Made with Rust, ripgrep, Actix, Inferno, and Typescript.
); } paginator() { return ( ); } searchChange(i, event) { let searchParams: SearchParams = { q: event.target.value, page: 1 } i.setState({ searchParams: searchParams }); } switchPage(a: { i: TorrentSearchComponent, nextPage: boolean }, event) { let newSearch = a.i.state.searchParams; newSearch.page += (a.nextPage) ? 1 : -1; a.i.setState({ searchParams: newSearch }); a.i.search(a.i, event); } } render(, container);