WIP: improve search #1

Closed
rob wants to merge 26 commits from improve-search into master
4 changed files with 54 additions and 57 deletions
Showing only changes of commit f571ec261c - Show all commits

View File

@ -74,15 +74,6 @@ impl fmt::Display for Direction {
write!(f, "{}", s)
}
}
#[derive(Copy, Clone, Debug, Default, Deserialize)]
struct Sort(Key, Direction);
impl fmt::Display for Sort {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let s = format!("{} {}", self.0, self.1);
write!(f, "{}", s)
}
}
#[actix_rt::main]
async fn main() -> io::Result<()> {
@ -156,7 +147,8 @@ async fn search(
struct NewQuery {
page: Option<usize>,
size: Option<usize>,
sort: Option<Sort>,
sort_key: Option<Key>,
sort_dir: Option<Direction>,
type_: Option<String>,
}
@ -191,21 +183,20 @@ fn search_query(
let page = query.page.unwrap_or(1);
let key = query.sort_key.unwrap_or_default();
let direction = query.sort_dir.unwrap_or_default();
let sort = Sort(key, direction);
let size = cmp::min(100, query.size.unwrap_or(DEFAULT_SIZE));
let type_ = query.type_.as_ref().map_or("torrent", String::deref);
let offset = size * (page - 1);
dbg!(
"query = {}, type = {}, page = {}, size = {}, sort = {:?}",
q, type_, page, size, sort
println!(
"query = {}, type = {}, page = {}, size = {}, sort_key = {}, sort_dir = {}",
q, type_, page, size, key, direction
);
let res = if type_ == "file" {
let results = torrent_file_search(conn, q, size, offset)?;
serde_json::to_value(&results).unwrap()
} else {
let results = torrent_search(conn, q, sort, size, offset)?;
let results = torrent_search(conn, q, key, direction, size, offset)?;
serde_json::to_value(&results).unwrap()
};
@ -219,13 +210,14 @@ fn new_query(
let page = query.page.unwrap_or(1);
let size = cmp::min(100, query.size.unwrap_or(DEFAULT_SIZE));
let sort = query.sort.unwrap_or_default();
let key = query.sort_key.unwrap_or_default();
let direction = query.sort_dir.unwrap_or_default();
let type_ = query.type_.as_ref().map_or("torrent", String::deref);
let offset = size * (page - 1);
dbg!(
"new, type = {}, page = {}, size = {}, sort = {:?}",
type_, page, size, sort
"new, type = {}, page = {}, size = {}, sort_key = {}, sort_dir = {}",
type_, page, size, key, direction
);
let res = if type_ == "file" {
@ -254,33 +246,34 @@ struct Torrent {
fn torrent_search(
conn: r2d2::PooledConnection<SqliteConnectionManager>,
query: &str,
sort: Sort,
key: Key,
direction: Direction,
size: usize,
offset: usize,
) -> Result<Vec<Torrent>, Error> {
let stmt_str = format!("select * from torrents where name like '%' || :query || '%' order by {} limit :offset, :size", sort);
// `key` and `direction` are already sanitized and should not be escaped:
let stmt_str = format!("select * from torrents where name like '%' || ?1 || '%' order by {} {} limit ?2, ?3", key, direction);
let mut stmt = conn.prepare(&stmt_str)?;
let torrent_iter = stmt.query_map(params![
let torrent_iter = stmt.query_map(params!{
query.replace(" ", "%"),
offset.to_string(),
size.to_string(),
],
|row| {
},
|row| {
let size: isize = row.get(2)?;
println!("got size {:?}", size);
Ok(Torrent {
infohash: row.get(0)?,
name: row.get(1)?,
size_bytes: row.get(2)?,
created_unix: row.get(3)?,
seeders: row.get(4)?,
leechers: row.get(5)?,
completed: row.get(6)?,
scraped_date: row.get(7)?,
infohash: row.get(0)?,
name: row.get(1)?,
size_bytes: row.get(2)?,
created_unix: row.get(3)?,
seeders: row.get(4)?,
leechers: row.get(5)?,
completed: row.get(6)?,
scraped_date: row.get(7)?,
})
},
},
)?;
let mut torrents = Vec::new();

View File

@ -41,7 +41,8 @@ Sparky.task('config', _ => {
});
app = fuse.bundle('app').instructions('>index.tsx');
});
Sparky.task('clean', _ => Sparky.src('dist/').clean('dist/'));
//Sparky.task('clean', _ => Sparky.src('dist/').clean('dist/'));
Sparky.task('clean', _ => {});
Sparky.task('env', _ => (isProduction = true));
Sparky.task('copy-assets', () => Sparky.src('assets/*.ico').dest('dist/'));
Sparky.task('dev', ['clean', 'config', 'copy-assets'], _ => {

View File

@ -76,6 +76,7 @@ export class Navbar extends Component<any, State> {
}
searchChange(i: Navbar, event) {
console.log("in searchChange");
let searchParams: SearchParams = {
q: event.target.value,
page: 1,
@ -87,6 +88,7 @@ export class Navbar extends Component<any, State> {
}
searchTypeChange(i: Navbar, event) {
console.log("in searchTypeChange");
let searchParams: SearchParams = {
q: i.state.searchParams.q,
page: 1,

View File

@ -11,27 +11,19 @@ interface State {
searching: Boolean;
}
function buildSearchURL(sort_key, {state: { searchParams }) {
console.log("got search URL sort_key", sort_key, "searchParams", searchParams, "thing", searchParams);
//let searchParams = thing.state.searchParams;
if (sort_key === searchParams.sort_key) {
const sort_dir = searchParams.sort_dir === "asc" ? "desc" : "asc";
searchParams.sort_dir = sort_dir;
console.log("no change in sort key from", sort_key, "so switch direction instead.")
function buildSearchURL({state: { searchParams }}, key) {
let page, direction;
if (key === searchParams.sort_key) {
page = searchParams.page;
direction = searchParams.sort_dir === "Asc" ? "Desc" : "Asc";
} else {
console.log("change sort key from", searchParams.sort_key, "to", sort_key);
searchParams.sort_key = sort_key;
page = 1;
direction = "Desc";
}
const url = `/#/search/${searchParams.type_}/${searchParams.q}/${searchParams.page}/${searchParams.sort_key}/${searchParams.sort_dir}`
return url;
return `/#/search/${searchParams.type_}/${searchParams.q}/${page}/${key}/${direction}`;
}
export class Search extends Component<any, State> {
state: State = {
results: {
torrents: []
@ -51,7 +43,7 @@ export class Search extends Component<any, State> {
}
componentDidMount() {
console.log("got props", this.props);
console.log("loading page, got match", this.props.match.params);
this.state.searchParams = {
page: Number(this.props.match.params.page),
q: this.props.match.params.q,
@ -65,6 +57,7 @@ export class Search extends Component<any, State> {
// Re-do search if the props have changed
componentDidUpdate(lastProps: any) {
if (lastProps.match && lastProps.match.params !== this.props.match.params) {
console.log("updating component with sort_key", this.props.match.params.sort_key);
this.state.searchParams = {
page: Number(this.props.match.params.page),
q: this.props.match.params.q,
@ -78,7 +71,6 @@ export class Search extends Component<any, State> {
}
search() {
console.log("in search, state", this.state);
if (!!this.state.searchParams.q) {
this.setState({ searching: true, results: { torrents: [] } });
this.fetchData(this.state.searchParams)
@ -141,24 +133,33 @@ export class Search extends Component<any, State> {
<tr>
<th class="search-name-col">
<a
href={buildSearchURL('Name', this)}>
href={buildSearchURL(this, 'Name')}>
Name
</a>
</th>
<th class="text-right">
<a
href={buildSearchURL('Size', this)}>
href={buildSearchURL(this, 'Size')}>
Size
</a>
</th>
<th class="text-right">
<a href="#">Seeds</a>
<a
href={buildSearchURL(this, 'Seeders')}>
Seeds
</a>
</th>
<th class="text-right d-none d-md-table-cell">
<a href="#">Leeches</a>
<a
href={buildSearchURL(this, 'Leechers')}>
Leechers
</a>
</th>
<th class="text-right d-none d-md-table-cell">
<a href="#">Scraped</a>
<a
href={buildSearchURL(this, 'Date')}>
Scraped
</a>
</th>
<th></th>
</tr>