hydrus/downloader_url_classes.html

2519 lines
69 KiB
HTML

<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="description" content="A personal booru-style media tagger that can import files and tags from your hard drive and popular websites. Content can be shared with other users via user-run servers.">
<link rel="canonical" href="https://hydrusnetwork.github.io/hydrus/downloader_url_classes.html">
<link rel="prev" href="downloader_gugs.html">
<link rel="next" href="downloader_parsers.html">
<link rel="icon" href="assets/favicon.svg">
<meta name="generator" content="mkdocs-1.5.3, mkdocs-material-9.5.15">
<title>URL Classes - hydrus network</title>
<link rel="stylesheet" href="assets/stylesheets/main.7e359304.min.css">
<link rel="stylesheet" href="assets/stylesheets/palette.06af60db.min.css">
<link rel="stylesheet" href="assets/stylesheets/extra.css">
<script>__md_scope=new URL(".",location),__md_hash=e=>[...e].reduce((e,_)=>(e<<5)-e+_.charCodeAt(0),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
</head>
<body dir="ltr" data-md-color-scheme="default" data-md-color-primary="blue-grey" data-md-color-accent="blue">
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
<a href="#url_classes" class="md-skip">
Skip to content
</a>
</div>
<div data-md-component="announce">
</div>
<header class="md-header" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="Header">
<a href="index.html" title="hydrus network" class="md-header__button md-logo" aria-label="hydrus network" data-md-component="logo">
<img src="assets/hydrus-white.svg" alt="logo">
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3V6m0 5h18v2H3v-2m0 5h18v2H3v-2Z"/></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
hydrus network
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
URL Classes
</span>
</div>
</div>
</div>
<form class="md-header__option" data-md-component="palette">
<input class="md-option" data-md-color-media="(prefers-color-scheme: light)" data-md-color-scheme="default" data-md-color-primary="blue-grey" data-md-color-accent="blue" aria-label="Switch to dark mode" type="radio" name="__palette" id="__palette_0">
<label class="md-header__button md-icon" title="Switch to dark mode" for="__palette_1" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17 6H7c-3.31 0-6 2.69-6 6s2.69 6 6 6h10c3.31 0 6-2.69 6-6s-2.69-6-6-6zm0 10H7c-2.21 0-4-1.79-4-4s1.79-4 4-4h10c2.21 0 4 1.79 4 4s-1.79 4-4 4zM7 9c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z"/></svg>
</label>
<input class="md-option" data-md-color-media="(prefers-color-scheme: dark)" data-md-color-scheme="slate" data-md-color-primary="black" data-md-color-accent="blue" aria-label="Switch to light mode" type="radio" name="__palette" id="__palette_1">
<label class="md-header__button md-icon" title="Switch to light mode" for="__palette_0" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17 7H7a5 5 0 0 0-5 5 5 5 0 0 0 5 5h10a5 5 0 0 0 5-5 5 5 0 0 0-5-5m0 8a3 3 0 0 1-3-3 3 3 0 0 1 3-3 3 3 0 0 1 3 3 3 3 0 0 1-3 3Z"/></svg>
</label>
</form>
<script>var media,input,key,value,palette=__md_get("__palette");if(palette&&palette.color){"(prefers-color-scheme)"===palette.color.media&&(media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']"),palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent"));for([key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
<label class="md-header__button md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5Z"/></svg>
</label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
<label class="md-search__icon md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5Z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12Z"/></svg>
</label>
<nav class="md-search__options" aria-label="Search">
<button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41Z"/></svg>
</button>
</nav>
<div class="md-search__suggest" data-md-component="search-suggest"></div>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" data-md-scrollfix>
<div class="md-search-result" data-md-component="search-result">
<div class="md-search-result__meta">
Initializing search
</div>
<ol class="md-search-result__list" role="presentation"></ol>
</div>
</div>
</div>
</div>
</div>
<div class="md-header__source">
<a href="https://github.com/hydrusnetwork/hydrus" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><!--! Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2023 Fonticons, Inc.--><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"/></svg>
</div>
<div class="md-source__repository">
hydrusnetwork/hydrus
</div>
</a>
</div>
</nav>
</header>
<div class="md-container" data-md-component="container">
<nav class="md-tabs" aria-label="Tabs" data-md-component="tabs">
<div class="md-grid">
<ul class="md-tabs__list">
<li class="md-tabs__item">
<a href="index.html" class="md-tabs__link">
Home
</a>
</li>
<li class="md-tabs__item">
<a href="introduction.html" class="md-tabs__link">
Getting Started
</a>
</li>
<li class="md-tabs__item md-tabs__item--active">
<a href="advanced_siblings.html" class="md-tabs__link">
Advanced
</a>
</li>
<li class="md-tabs__item">
<a href="client_api.html" class="md-tabs__link">
API
</a>
</li>
<li class="md-tabs__item">
<a href="faq.html" class="md-tabs__link">
Misc
</a>
</li>
</ul>
</div>
</nav>
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary md-nav--lifted" aria-label="Navigation" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href="index.html" title="hydrus network" class="md-nav__button md-logo" aria-label="hydrus network" data-md-component="logo">
<img src="assets/hydrus-white.svg" alt="logo">
</a>
hydrus network
</label>
<div class="md-nav__source">
<a href="https://github.com/hydrusnetwork/hydrus" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><!--! Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2023 Fonticons, Inc.--><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"/></svg>
</div>
<div class="md-source__repository">
hydrusnetwork/hydrus
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="index.html" class="md-nav__link">
<span class="md-ellipsis">
Home
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2" >
<label class="md-nav__link" for="__nav_2" id="__nav_2_label" tabindex="0">
<span class="md-ellipsis">
Getting Started
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_2_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2">
<span class="md-nav__icon md-icon"></span>
Getting Started
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="introduction.html" class="md-nav__link">
<span class="md-ellipsis">
Introduction and Statement of Principles
</span>
</a>
</li>
<li class="md-nav__item">
<a href="gettingStartedOverview.html" class="md-nav__link">
<span class="md-ellipsis">
Overview For Getting Started
</span>
</a>
</li>
<li class="md-nav__item">
<a href="getting_started_installing.html" class="md-nav__link">
<span class="md-ellipsis">
Installing and Updating
</span>
</a>
</li>
<li class="md-nav__item">
<a href="getting_started_files.html" class="md-nav__link">
<span class="md-ellipsis">
Files
</span>
</a>
</li>
<li class="md-nav__item">
<a href="filetypes.html" class="md-nav__link">
<span class="md-ellipsis">
Supported Filetypes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="getting_started_importing.html" class="md-nav__link">
<span class="md-ellipsis">
Importing and Exporting
</span>
</a>
</li>
<li class="md-nav__item">
<a href="getting_started_tags.html" class="md-nav__link">
<span class="md-ellipsis">
Tags
</span>
</a>
</li>
<li class="md-nav__item">
<a href="getting_started_searching.html" class="md-nav__link">
<span class="md-ellipsis">
Searching and Sorting
</span>
</a>
</li>
<li class="md-nav__item">
<a href="getting_started_more_tags.html" class="md-nav__link">
<span class="md-ellipsis">
More Tags
</span>
</a>
</li>
<li class="md-nav__item">
<a href="getting_started_downloading.html" class="md-nav__link">
<span class="md-ellipsis">
Downloading
</span>
</a>
</li>
<li class="md-nav__item">
<a href="getting_started_ratings.html" class="md-nav__link">
<span class="md-ellipsis">
Ratings
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_12" >
<label class="md-nav__link" for="__nav_2_12" id="__nav_2_12_label" tabindex="0">
<span class="md-ellipsis">
PTR
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_12_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2_12">
<span class="md-nav__icon md-icon"></span>
PTR
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="access_keys.html" class="md-nav__link">
<span class="md-ellipsis">
PTR Access Keys
</span>
</a>
</li>
<li class="md-nav__item">
<a href="PTR.html" class="md-nav__link">
<span class="md-ellipsis">
PTR Guide
</span>
</a>
</li>
<li class="md-nav__item">
<a href="petitionPractices.html" class="md-nav__link">
<span class="md-ellipsis">
Petition Practices
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_13" >
<label class="md-nav__link" for="__nav_2_13" id="__nav_2_13_label" tabindex="0">
<span class="md-ellipsis">
Next Steps
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_13_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2_13">
<span class="md-nav__icon md-icon"></span>
Next Steps
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="adding_new_downloaders.html" class="md-nav__link">
<span class="md-ellipsis">
Adding New Downloaders
</span>
</a>
</li>
<li class="md-nav__item">
<a href="getting_started_subscriptions.html" class="md-nav__link">
<span class="md-ellipsis">
Subscriptions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="duplicates.html" class="md-nav__link">
<span class="md-ellipsis">
Filtering Duplicates
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3" checked>
<label class="md-nav__link" for="__nav_3" id="__nav_3_label" tabindex="">
<span class="md-ellipsis">
Advanced
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_3_label" aria-expanded="true">
<label class="md-nav__title" for="__nav_3">
<span class="md-nav__icon md-icon"></span>
Advanced
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="advanced_siblings.html" class="md-nav__link">
<span class="md-ellipsis">
Tag Siblings
</span>
</a>
</li>
<li class="md-nav__item">
<a href="advanced_parents.html" class="md-nav__link">
<span class="md-ellipsis">
Tag Parents
</span>
</a>
</li>
<li class="md-nav__item">
<a href="advanced_sidecars.html" class="md-nav__link">
<span class="md-ellipsis">
Sidecars
</span>
</a>
</li>
<li class="md-nav__item">
<a href="advanced_multiple_local_file_services.html" class="md-nav__link">
<span class="md-ellipsis">
Multiple Local File Services
</span>
</a>
</li>
<li class="md-nav__item">
<a href="advanced.html" class="md-nav__link">
<span class="md-ellipsis">
General Clever Tricks
</span>
</a>
</li>
<li class="md-nav__item">
<a href="reducing_lag.html" class="md-nav__link">
<span class="md-ellipsis">
Reducing Lag
</span>
</a>
</li>
<li class="md-nav__item">
<a href="database_migration.html" class="md-nav__link">
<span class="md-ellipsis">
Database Migration
</span>
</a>
</li>
<li class="md-nav__item">
<a href="launch_arguments.html" class="md-nav__link">
<span class="md-ellipsis">
Launch Arguments
</span>
</a>
</li>
<li class="md-nav__item">
<a href="ipfs.html" class="md-nav__link">
<span class="md-ellipsis">
IPFS
</span>
</a>
</li>
<li class="md-nav__item">
<a href="local_booru.html" class="md-nav__link">
<span class="md-ellipsis">
Local Booru
</span>
</a>
</li>
<li class="md-nav__item">
<a href="server.html" class="md-nav__link">
<span class="md-ellipsis">
Running Your Own Server
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3_12" >
<label class="md-nav__link" for="__nav_3_12" id="__nav_3_12_label" tabindex="">
<span class="md-ellipsis">
Alternate Installations
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_3_12_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_3_12">
<span class="md-nav__icon md-icon"></span>
Alternate Installations
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="docker.html" class="md-nav__link">
<span class="md-ellipsis">
Docker
</span>
</a>
</li>
<li class="md-nav__item">
<a href="wine.html" class="md-nav__link">
<span class="md-ellipsis">
Running In Wine
</span>
</a>
</li>
<li class="md-nav__item">
<a href="running_from_source.html" class="md-nav__link">
<span class="md-ellipsis">
Running From Source
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3_13" checked>
<label class="md-nav__link" for="__nav_3_13" id="__nav_3_13_label" tabindex="">
<span class="md-ellipsis">
Downloader Creation
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_3_13_label" aria-expanded="true">
<label class="md-nav__title" for="__nav_3_13">
<span class="md-nav__icon md-icon"></span>
Downloader Creation
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="downloader_intro.html" class="md-nav__link">
<span class="md-ellipsis">
Introduction
</span>
</a>
</li>
<li class="md-nav__item">
<a href="downloader_gugs.html" class="md-nav__link">
<span class="md-ellipsis">
Gallery URL Generators
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
<span class="md-ellipsis">
URL Classes
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<a href="downloader_url_classes.html" class="md-nav__link md-nav__link--active">
<span class="md-ellipsis">
URL Classes
</span>
</a>
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#url_types" class="md-nav__link">
<span class="md-ellipsis">
the types of url
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#url_components" class="md-nav__link">
<span class="md-ellipsis">
the components of a url
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#string_matches" class="md-nav__link">
<span class="md-ellipsis">
string matches
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#match_details" class="md-nav__link">
<span class="md-ellipsis">
how do they match, exactly?
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#url_normalisation" class="md-nav__link">
<span class="md-ellipsis">
normalising urls
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#default_values" class="md-nav__link">
<span class="md-ellipsis">
'default' values
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#next_gallery_page_prediction" class="md-nav__link">
<span class="md-ellipsis">
can we predict the next gallery page?
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#api_links" class="md-nav__link">
<span class="md-ellipsis">
how do we link to APIs?
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3_13_4" >
<label class="md-nav__link" for="__nav_3_13_4" id="__nav_3_13_4_label" tabindex="0">
<span class="md-ellipsis">
Parsers
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="3" aria-labelledby="__nav_3_13_4_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_3_13_4">
<span class="md-nav__icon md-icon"></span>
Parsers
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="downloader_parsers.html" class="md-nav__link">
<span class="md-ellipsis">
Overview
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3_13_4_2" >
<label class="md-nav__link" for="__nav_3_13_4_2" id="__nav_3_13_4_2_label" tabindex="0">
<span class="md-ellipsis">
Components
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="4" aria-labelledby="__nav_3_13_4_2_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_3_13_4_2">
<span class="md-nav__icon md-icon"></span>
Components
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="downloader_parsers_formulae.html" class="md-nav__link">
<span class="md-ellipsis">
Formulae
</span>
</a>
</li>
<li class="md-nav__item">
<a href="downloader_parsers_content_parsers.html" class="md-nav__link">
<span class="md-ellipsis">
Content Parsers
</span>
</a>
</li>
<li class="md-nav__item">
<a href="downloader_parsers_page_parsers.html" class="md-nav__link">
<span class="md-ellipsis">
Page Parsers
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3_13_4_3" >
<label class="md-nav__link" for="__nav_3_13_4_3" id="__nav_3_13_4_3_label" tabindex="0">
<span class="md-ellipsis">
Walkthroughs
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="4" aria-labelledby="__nav_3_13_4_3_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_3_13_4_3">
<span class="md-nav__icon md-icon"></span>
Walkthroughs
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="downloader_parsers_full_example_gallery_page.html" class="md-nav__link">
<span class="md-ellipsis">
Gallery Page Example
</span>
</a>
</li>
<li class="md-nav__item">
<a href="downloader_parsers_full_example_file_page.html" class="md-nav__link">
<span class="md-ellipsis">
File Page Example
</span>
</a>
</li>
<li class="md-nav__item">
<a href="downloader_parsers_full_example_api.html" class="md-nav__link">
<span class="md-ellipsis">
API Example
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="downloader_completion.html" class="md-nav__link">
<span class="md-ellipsis">
Putting It All Together
</span>
</a>
</li>
<li class="md-nav__item">
<a href="downloader_sharing.html" class="md-nav__link">
<span class="md-ellipsis">
Sharing
</span>
</a>
</li>
<li class="md-nav__item">
<a href="downloader_login.html" class="md-nav__link">
<span class="md-ellipsis">
Login Manager
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4" >
<label class="md-nav__link" for="__nav_4" id="__nav_4_label" tabindex="0">
<span class="md-ellipsis">
API
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_4_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_4">
<span class="md-nav__icon md-icon"></span>
API
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="client_api.html" class="md-nav__link">
<span class="md-ellipsis">
Client API
</span>
</a>
</li>
<li class="md-nav__item">
<a href="developer_api.html" class="md-nav__link">
<span class="md-ellipsis">
API documentation
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5" >
<label class="md-nav__link" for="__nav_5" id="__nav_5_label" tabindex="0">
<span class="md-ellipsis">
Misc
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_5_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_5">
<span class="md-nav__icon md-icon"></span>
Misc
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="faq.html" class="md-nav__link">
<span class="md-ellipsis">
FAQ
</span>
</a>
</li>
<li class="md-nav__item">
<a href="privacy.html" class="md-nav__link">
<span class="md-ellipsis">
Privacy
</span>
</a>
</li>
<li class="md-nav__item">
<a href="contact.html" class="md-nav__link">
<span class="md-ellipsis">
Contact and Links
</span>
</a>
</li>
<li class="md-nav__item">
<a href="support.html" class="md-nav__link">
<span class="md-ellipsis">
Financial Support
</span>
</a>
</li>
<li class="md-nav__item">
<a href="changelog.html" class="md-nav__link">
<span class="md-ellipsis">
Changelog
</span>
</a>
</li>
<li class="md-nav__item">
<a href="about_docs.html" class="md-nav__link">
<span class="md-ellipsis">
About These Docs
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#url_types" class="md-nav__link">
<span class="md-ellipsis">
the types of url
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#url_components" class="md-nav__link">
<span class="md-ellipsis">
the components of a url
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#string_matches" class="md-nav__link">
<span class="md-ellipsis">
string matches
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#match_details" class="md-nav__link">
<span class="md-ellipsis">
how do they match, exactly?
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#url_normalisation" class="md-nav__link">
<span class="md-ellipsis">
normalising urls
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#default_values" class="md-nav__link">
<span class="md-ellipsis">
'default' values
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#next_gallery_page_prediction" class="md-nav__link">
<span class="md-ellipsis">
can we predict the next gallery page?
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#api_links" class="md-nav__link">
<span class="md-ellipsis">
how do we link to APIs?
</span>
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<a href="https://github.com/hydrusnetwork/hydrus/edit/master/docs/downloader_url_classes.md" title="Edit this page" class="md-content__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 20H6V4h7v5h5v3.1l2-2V8l-6-6H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h4v-2m10.2-7c.1 0 .3.1.4.2l1.3 1.3c.2.2.2.6 0 .8l-1 1-2.1-2.1 1-1c.1-.1.2-.2.4-.2m0 3.9L14.1 23H12v-2.1l6.1-6.1 2.1 2.1Z"/></svg>
</a>
<h1 id="url_classes">URL Classes<a class="headerlink" href="#url_classes" title="Permanent link">&para;</a></h1>
<p>The fundamental connective tissue of the downloader system is the 'URL Class'. This object identifies and normalises URLs and links them to other components. Whenever the client handles a URL, it tries to match it to a URL Class to figure out what to do.</p>
<h2 id="url_types">the types of url<a class="headerlink" href="#url_types" title="Permanent link">&para;</a></h2>
<p>For hydrus, an URL is useful if it is one of:</p>
<dl>
<dt>File URL</dt>
<dd>
<p>This returns the full, raw media file with no HTML wrapper. They typically end in a filename like <a href="http://safebooru.org//images/2333/cab1516a7eecf13c462615120ecf781116265f17.jpg">http://safebooru.org//images/2333/cab1516a7eecf13c462615120ecf781116265f17.jpg</a>, but sometimes they have a more complicated fetch command ending like 'file.php?id=123456' or '/post/content/123456'.</p>
<p>These URLs are remembered for the file in the 'known urls' list, so if the client happens to encounter the same URL in future, it can determine whether it can skip the download because the file is already in the database or has previously been deleted.</p>
<p>It is not important that File URLs be matched by a URL Class. File URL is considered the 'default', so if the client finds no match, it will assume the URL is a file and try to download and import the result. You might want to particularly specify them if you want to present them in the media viewer or discover File URLs are being confused for Post URLs or something.</p>
</dd>
<dt>Post URL</dt>
<dd>
<p>This typically return some HTML that contains a File URL and metadata such as tags and post time. They sometimes present multiple sizes (like 'sample' vs 'full size') of the file or even different formats (like 'ugoira' vs 'webm'). The Post URL for the file above, <a href="http://safebooru.org/index.php?page=post&amp;s=view&amp;id=2429668">http://safebooru.org/index.php?page=post&amp;s=view&amp;id=2429668</a> has this 'sample' presentation. Finding the best File URL in these cases can be tricky!</p>
<p>This URL is also saved to 'known urls' and will usually be similarly skipped if it has previously been downloaded. It will also appear in the media viewer as a clickable link.</p>
</dd>
<dt>Gallery URL</dt>
<dd>This presents a list of Post URLs or File URLs. They often also present a 'next page' URL. It could be a page like <a href="http://safebooru.org/index.php?page=post&amp;s=list&amp;tags=yorha_no._2_type_b&amp;pid=0">http://safebooru.org/index.php?page=post&amp;s=list&amp;tags=yorha_no._2_type_b&amp;pid=0</a> or an API URL like <a href="http://safebooru.org/index.php?page=dapi&amp;s=post&amp;tags=yorha_no._2_type_b&amp;q=index&amp;pid=0">http://safebooru.org/index.php?page=dapi&amp;s=post&amp;tags=yorha_no._2_type_b&amp;q=index&amp;pid=0</a>.</dd>
<dt>Watchable URL</dt>
<dd>This is the same as a Gallery URL but represents an ephemeral page that receives new files much faster than a gallery but will soon 'die' and be deleted. For our purposes, this typically means imageboard threads.</dd>
</dl>
<h2 id="url_components">the components of a url<a class="headerlink" href="#url_components" title="Permanent link">&para;</a></h2>
<p>As far as we are concerned, a URL string has four parts:</p>
<ul>
<li><strong>Scheme:</strong> <code>http</code> or <code>https</code></li>
<li><strong>Location/Domain:</strong> <code>safebooru.org</code> or <code>i.4cdn.org</code> or <code>cdn002.somebooru.net</code></li>
<li><strong>Path Components:</strong> <code>index.php</code> or <code>tesla/res/7518.json</code> or <code>pictures/user/daruak/page/2</code> or <code>art/Commission-animation-Elsa-and-Anna-541820782</code></li>
<li><strong>Parameters:</strong> <code>page=post&amp;s=list&amp;tags=yorha_no._2_type_b&amp;pid=40</code> or <code>page=post&amp;s=view&amp;id=2429668</code></li>
</ul>
<p>So, let's look at the 'edit url class' panel, which is found under <em>network-&gt;downloader components-&gt;manage url classes</em>:</p>
<p><img alt="" src="images/downloader_edit_url_class_panel.png" /></p>
<p>A TBIB File Page like <a href="https://tbib.org/index.php?page=post&amp;s=view&amp;id=6391256">https://tbib.org/index.php?page=post&amp;s=view&amp;id=6391256</a> is a Post URL. Let's look at the metadata first:</p>
<dl>
<dt>Name and type</dt>
<dd>
<p>Like with GUGs, we should set a good unambiguous name so the client can clearly summarise this url to the user. 'tbib file page' is good.</p>
<p>This is a Post URL, so we set the 'post url' type.</p>
</dd>
<dt>Association logic</dt>
<dd>
<p>All boorus and most sites only present one file per page, but some sites present multiple files on one page, usually several pages in a series/comic, as with pixiv. Danbooru-style thumbnail links to 'this file has a post parent' do not count here--I mean that a single URL embeds multiple full-size images, either with shared or separate tags. It is <strong>very important</strong> to the hydrus client's downloader logic (making decisions about whether it has previously visited a URL, so whether to skip checking it again) that if a site can present multiple files on a single page that 'can produce multiple files' is checked.</p>
<p>Related is the idea of whether a 'known url' should be associated. Typically, this should be checked for Post and File URLs, which are fixed, and unchecked for Gallery and Watchable URLs, which are ephemeral and give different results from day to day. There are some unusual exceptions, so give it a brief thought--but if you have no special reason, leave this as the default for the url type.</p>
</dd>
</dl>
<p>And now, for matching the string itself, let's revisit our four components:</p>
<dl>
<dt>Scheme</dt>
<dd>TBIB supports http and https, so I have set the 'preferred' scheme to https. Any 'http' TBIB URL a user inputs will be automatically converted to https.</dd>
<dt>Location/Domain</dt>
<dd>
<p>For Post URLs, the domain is always "tbib.org".</p>
<p>The 'allow' and 'keep' subdomains checkboxes let you determine if a URL with "artistname.artsite.com" will match a URL Class with "artsite.com" domain and if that subdomain should be remembered going forward. Most sites do not host content on subdomains, so you can usually leave 'match' unchecked. The 'keep' option (which is only available if 'keep' is checked) is more subtle, only useful for rare cases, and unless you have a special reason, you should leave it checked. (For keep: In cases where a site farms out File URLs to CDN servers on subdomains--like randomly serving a mirror of "https://muhbooru.org/file/123456" on "https://srv2.muhbooru.org/file/123456"--and removing the subdomain still gives a valid URL, you may not wish to keep the subdomain.) Since TBIB does not use subdomains, these options do not matter--we can leave both unchecked.</p>
<p>'www' and 'www2' and similar subdomains are automatically matched. Don't worry about them.</p>
</dd>
<dt>Path Components</dt>
<dd>TBIB just uses a single "index.php" on the root directory, so the path is not complicated. Were it longer (like "gallery/cgi/index.php", we would add more ("gallery" and "cgi"), and since the path of a URL has a strict order, we would need to arrange the items in the listbox there so they were sorted correctly.</dd>
<dt>Parameters</dt>
<dd>TBIB's index.php takes many parameters to render different page types. Note that the Post URL uses "s=view", while TBIB Gallery URLs use "s=list". In any case, for a Post URL, "id", "page", and "s" are necessary and sufficient.</dd>
</dl>
<h2 id="string_matches">string matches<a class="headerlink" href="#string_matches" title="Permanent link">&para;</a></h2>
<p>As you edit these components, you will be presented with the Edit String Match Panel:</p>
<p><img alt="" src="images/edit_string_match_panel.png" /></p>
<p>This lets you set the type of string that will be valid for that component. If a given path or query component does not match the rules given here, the URL will not match the URL Class. Most of the time you will probably want to set 'fixed characters' of something like "post" or "index.php", but if the component you are editing is more complicated and could have a range of different valid values, you can specify just numbers or letters or even a regex pattern. If you try to do something complicated, experiment with the 'example string' entry to make sure you have it set how you think.</p>
<p>Don't go overboard with this stuff, though--most sites do not have super-fine distinctions between their different URL types, and hydrus users will not be dropping user account or logout pages or whatever on the client, so you can be fairly liberal with the rules.</p>
<h2 id="match_details">how do they match, exactly?<a class="headerlink" href="#match_details" title="Permanent link">&para;</a></h2>
<p>This URL Class will be assigned to any URL that matches the location, path, and query. Missing path component or parameters in the URL will invalidate the match but additonal ones will not!</p>
<p>For instance, given:</p>
<ul>
<li>URL A: https://8ch.net/tv/res/1002432.html</li>
<li>URL B: https://8ch.net/tv/res</li>
<li>URL C: https://8ch.net/tv/res/1002432</li>
<li>URL D: https://8ch.net/tv/res/1002432.json</li>
<li>URL Class that looks for "(characters)/res/(numbers).html" for the path</li>
</ul>
<p>Only URL A will match</p>
<p>And:</p>
<ul>
<li>URL A: https://boards.4chan.org/m/thread/16086187</li>
<li>URL B: https://boards.4chan.org/m/thread/16086187/ssg-super-sentai-general-651</li>
<li>URL Class that looks for "(characters)/thread/(numbers)" for the path</li>
</ul>
<p>Both URL A and B will match</p>
<p>And:</p>
<ul>
<li>URL A: https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=66476204</li>
<li>URL B: https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=66476204&amp;lang=jp</li>
<li>URL C: https://www.pixiv.net/member_illust.php?mode=medium</li>
<li>URL Class that looks for "illust_id=(numbers)" in the query</li>
</ul>
<p>Both URL A and B will match, URL C will not</p>
<p>If multiple URL Classes match a URL, the client will try to assign the most 'complicated' one, with the most path components and then parameters.</p>
<p>Given two example URLs and URL Classes:</p>
<ul>
<li>URL A: https://somebooru.com/post/123456</li>
<li>URL B: https://somebooru.com/post/123456/manga_subpage/2</li>
<li>URL Class A that looks for "post/(number)" for the path</li>
<li>URL Class B that looks for "post/(number)/manga_subpage/(number)" for the path</li>
</ul>
<p>URL A will match URL Class A but not URL Class B and so will receive A.</p>
<p>URL B will match both and receive URL Class B as it is more complicated.</p>
<p>This situation is not common, but when it does pop up, it can be a pain. It is usually a good idea to match exactly what you need--no more, no less.</p>
<h2 id="url_normalisation">normalising urls<a class="headerlink" href="#url_normalisation" title="Permanent link">&para;</a></h2>
<p>Different URLs can give the same content. The http and https versions of a URL are typically the same, and:</p>
<ul>
<li><a href="https://gelbooru.com/index.php?page=post&amp;s=view&amp;id=3767497">https://gelbooru.com/index.php?page=post&amp;s=view&amp;id=3767497</a></li>
<li>gives the same as:</li>
<li><a href="https://gelbooru.com/index.php?id=3767497&amp;page=post&amp;s=view">https://gelbooru.com/index.php?id=3767497&amp;page=post&amp;s=view</a></li>
</ul>
<p>And:</p>
<ul>
<li><a href="https://e621.net/post/show/1421754/abstract_background-animal_humanoid-blush-brown_ey">https://e621.net/post/show/1421754/abstract_background-animal_humanoid-blush-brown_ey</a></li>
<li>is the same as:</li>
<li><a href="https://e621.net/post/show/1421754">https://e621.net/post/show/1421754</a></li>
<li><em>is the same as:</em></li>
<li><a href="https://e621.net/post/show/1421754/help_computer-made_up_tags-REEEEEEEE">https://e621.net/post/show/1421754/help_computer-made_up_tags-REEEEEEEE</a></li>
</ul>
<p>Since we are in the business of storing and comparing URLs, we want to 'normalise' them to a single comparable beautiful value. You see a preview of this normalisation on the edit panel. Normalisation happens to all URLs that enter the program.</p>
<p>Note that in e621's case (and for many other sites!), that text after the id is purely decoration. It can change when the file's tags change, so if we want to compare today's URLs with those we saw a month ago, we'd rather just be without it.</p>
<p>On normalisation, all URLs will get the preferred http/https switch, and their parameters will be alphabetised. File and Post URLs will also cull out any surplus path or query components. This wouldn't affect our TBIB example above, but it will clip the e621 example down to that 'bare' id URL, and it will take any surplus 'lang=en' or 'browser=netscape_24.11' garbage off the query text as well. URLs that are not associated and saved and compared (i.e. normal Gallery and Watchable URLs) are not culled of unmatched path components or query parameters, which can sometimes be useful if you want to match (and keep intact) gallery URLs that might or might not include an important 'sort=desc' type of parameter.</p>
<p>Since File and Post URLs will do this culling, be careful that you not leave out anything important in your rules. Make sure what you have is both necessary (nothing can be removed and still keep it valid) and sufficient (no more needs to be added to make it valid). It is a good idea to try pasting the 'normalised' version of the example URL into your browser, just to check it still works.</p>
<h2 id="default_values">'default' values<a class="headerlink" href="#default_values" title="Permanent link">&para;</a></h2>
<p>Some sites present the first page of a search like this:</p>
<p><a href="https://danbooru.donmai.us/posts?tags=skirt">https://danbooru.donmai.us/posts?tags=skirt</a></p>
<p>But the second page is:</p>
<p><a href="https://danbooru.donmai.us/posts?tags=skirt&amp;page=2">https://danbooru.donmai.us/posts?tags=skirt&amp;page=2</a></p>
<p>Another example is:</p>
<p><a href="https://www.hentai-foundry.com/pictures/user/Mister69M">https://www.hentai-foundry.com/pictures/user/Mister69M</a></p>
<p><a href="https://www.hentai-foundry.com/pictures/user/Mister69M/page/2">https://www.hentai-foundry.com/pictures/user/Mister69M/page/2</a></p>
<p>What happened to 'page=1' and '/page/1'? Adding those '1' values in works fine! Many sites, when an index is absent, will secretly imply an appropriate 0 or 1. This looks pretty to users looking at a browser address bar, but it can be a pain for us, who want to match both styles to one URL Class. It would be nice if we could recognise the 'bare' initial URL and fill in the '1' values to coerce it to the explicit, automation-friendly format. Defaults to the rescue:</p>
<p><img alt="" src="images/downloader_edit_url_class_panel_default.png" /></p>
<p>After you set a path component or parameter String Match, you will be asked for an optional 'default' value. You won't want to set one most of the time, but for Gallery URLs, it can be hugely useful--see how the normalisation process automatically fills in the missing path component with the default! There are plenty of examples in the default Gallery URLs of this, so check them out. Most sites use page indices starting at '1', but Gelbooru-style imageboards use 'pid=0' file index (and often move forward 42, so the next pages will be 'pid=42', 'pid=84', and so on, although others use deltas of 20 or 40).</p>
<h2 id="next_gallery_page_prediction">can we predict the next gallery page?<a class="headerlink" href="#next_gallery_page_prediction" title="Permanent link">&para;</a></h2>
<p>Now we can harmonise gallery urls to a single format, we can predict the next gallery page! If, say, the third path component or 'page' parameter is always a number referring to page, you can select this under the 'next gallery page' section and set the delta to change it by. The 'next gallery page url' section will be automatically filled in. This value will be consulted if the parser cannot find a 'next gallery page url' from the page content.</p>
<p>It is neat to set this up, but I only recommend it if you actually cannot reliably parse a next gallery page url from the HTML later in the process. It is neater to have searches stop naturally because the parser said 'no more gallery pages' than to have hydrus always one page beyond and end every single search on an uglier 'No results found' or 404 result.</p>
<p>Unfortunately, some sites will either not produce an easily parsable next page link or randomly just not include it due to some issue on their end (Gelbooru is a funny example of this). Also, APIs will often have a kind of 'start=200&amp;num=50', 'start=250&amp;num=50' progression but not include that state in the XML or JSON they return. These cases require the automatic next gallery page rules (check out Artstation and tumblr api gallery page URL Classes in the defaults for examples of this).</p>
<h2 id="api_links">how do we link to APIs?<a class="headerlink" href="#api_links" title="Permanent link">&para;</a></h2>
<p>If you know that a URL has an API backend, you can tell the client to use that API URL when it fetches data. The API URL needs its own URL Class.</p>
<p>To define the relationship, click the "String Converter" button, which gives you this:</p>
<p><img alt="" src="images/edit_string_converter_panel.png" /></p>
<p>You may have seen this panel elsewhere. It lets you convert a string to another over a number of transformation steps. The steps can be as simple as adding or removing some characters or applying a full regex substitution. For API URLs, you are mostly looking to isolate some unique identifying data ("m/thread/16086187" in this case) and then substituting that into the new API path. It is worth testing this with several different examples!</p>
<p>When the client links regular URLs to API URLs like this, it will still associate the human-pretty regular URL when it needs to display to the user and record 'known urls' and so on. The API is just a quick lookup when it actually fetches and parses the respective data.</p>
<aside class="md-source-file">
<span class="md-source-file__fact">
<span class="md-icon" title="Last update">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M21 13.1c-.1 0-.3.1-.4.2l-1 1 2.1 2.1 1-1c.2-.2.2-.6 0-.8l-1.3-1.3c-.1-.1-.2-.2-.4-.2m-1.9 1.8-6.1 6V23h2.1l6.1-6.1-2.1-2M12.5 7v5.2l4 2.4-1 1L11 13V7h1.5M11 21.9c-5.1-.5-9-4.8-9-9.9C2 6.5 6.5 2 12 2c5.3 0 9.6 4.1 10 9.3-.3-.1-.6-.2-1-.2s-.7.1-1 .2C19.6 7.2 16.2 4 12 4c-4.4 0-8 3.6-8 8 0 4.1 3.1 7.5 7.1 7.9l-.1.2v1.8Z"/></svg>
</span>
<span class="git-revision-date-localized-plugin git-revision-date-localized-plugin-date">November 30, 2022</span>
</span>
</aside>
</article>
</div>
<script>var tabs=__md_get("__tabs");if(Array.isArray(tabs))e:for(var set of document.querySelectorAll(".tabbed-set")){var tab,labels=set.querySelector(".tabbed-labels");for(tab of tabs)for(var label of labels.getElementsByTagName("label"))if(label.innerText.trim()===tab){var input=document.getElementById(label.htmlFor);input.checked=!0;continue e}}</script>
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
</div>
<button type="button" class="md-top md-icon" data-md-component="top" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8v12Z"/></svg>
Back to top
</button>
</main>
<footer class="md-footer">
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-copyright">
Made with
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
Material for MkDocs
</a>
</div>
<div class="md-social">
<a href="https://github.com/hydrusnetwork/hydrus" target="_blank" rel="noopener" title="github.com" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><!--! Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2023 Fonticons, Inc.--><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"/></svg>
</a>
<a href="https://twitter.com/hydrusnetwork" target="_blank" rel="noopener" title="twitter.com" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2023 Fonticons, Inc.--><path d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z"/></svg>
</a>
<a href="https://hydrus.tumblr.com/" target="_blank" rel="noopener" title="hydrus.tumblr.com" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--! Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2023 Fonticons, Inc.--><path d="M309.8 480.3c-13.6 14.5-50 31.7-97.4 31.7-120.8 0-147-88.8-147-140.6v-144H17.9c-5.5 0-10-4.5-10-10v-68c0-7.2 4.5-13.6 11.3-16 62-21.8 81.5-76 84.3-117.1.8-11 6.5-16.3 16.1-16.3h70.9c5.5 0 10 4.5 10 10v115.2h83c5.5 0 10 4.4 10 9.9v81.7c0 5.5-4.5 10-10 10h-83.4V360c0 34.2 23.7 53.6 68 35.8 4.8-1.9 9-3.2 12.7-2.2 3.5.9 5.8 3.4 7.4 7.9l22 64.3c1.8 5 3.3 10.6-.4 14.5z"/></svg>
</a>
<a href="mailto:hydrus.admin@gmail.com" target="_blank" rel="noopener" title="" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2023 Fonticons, Inc.--><path d="M48 64C21.5 64 0 85.5 0 112c0 15.1 7.1 29.3 19.2 38.4l217.6 163.2c11.4 8.5 27 8.5 38.4 0l217.6-163.2c12.1-9.1 19.2-23.3 19.2-38.4 0-26.5-21.5-48-48-48H48zM0 176v208c0 35.3 28.7 64 64 64h384c35.3 0 64-28.7 64-64V176L294.4 339.2a63.9 63.9 0 0 1-76.8 0L0 176z"/></svg>
</a>
<a href="https://discord.gg/wPHPCUZ" target="_blank" rel="noopener" title="discord.gg" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2023 Fonticons, Inc.--><path d="M524.531 69.836a1.5 1.5 0 0 0-.764-.7A485.065 485.065 0 0 0 404.081 32.03a1.816 1.816 0 0 0-1.923.91 337.461 337.461 0 0 0-14.9 30.6 447.848 447.848 0 0 0-134.426 0 309.541 309.541 0 0 0-15.135-30.6 1.89 1.89 0 0 0-1.924-.91 483.689 483.689 0 0 0-119.688 37.107 1.712 1.712 0 0 0-.788.676C39.068 183.651 18.186 294.69 28.43 404.354a2.016 2.016 0 0 0 .765 1.375 487.666 487.666 0 0 0 146.825 74.189 1.9 1.9 0 0 0 2.063-.676A348.2 348.2 0 0 0 208.12 430.4a1.86 1.86 0 0 0-1.019-2.588 321.173 321.173 0 0 1-45.868-21.853 1.885 1.885 0 0 1-.185-3.126 251.047 251.047 0 0 0 9.109-7.137 1.819 1.819 0 0 1 1.9-.256c96.229 43.917 200.41 43.917 295.5 0a1.812 1.812 0 0 1 1.924.233 234.533 234.533 0 0 0 9.132 7.16 1.884 1.884 0 0 1-.162 3.126 301.407 301.407 0 0 1-45.89 21.83 1.875 1.875 0 0 0-1 2.611 391.055 391.055 0 0 0 30.014 48.815 1.864 1.864 0 0 0 2.063.7A486.048 486.048 0 0 0 610.7 405.729a1.882 1.882 0 0 0 .765-1.352c12.264-126.783-20.532-236.912-86.934-334.541ZM222.491 337.58c-28.972 0-52.844-26.587-52.844-59.239s23.409-59.241 52.844-59.241c29.665 0 53.306 26.82 52.843 59.239 0 32.654-23.41 59.241-52.843 59.241Zm195.38 0c-28.971 0-52.843-26.587-52.843-59.239s23.409-59.241 52.843-59.241c29.667 0 53.307 26.82 52.844 59.239 0 32.654-23.177 59.241-52.844 59.241Z"/></svg>
</a>
<a href="https://www.patreon.com/hydrus_dev" target="_blank" rel="noopener" title="www.patreon.com" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2023 Fonticons, Inc.--><path d="M489.7 153.8c-.1-65.4-51-119-110.7-138.3C304.8-8.5 207-5 136.1 28.4 50.3 68.9 23.3 157.7 22.3 246.2 21.5 319 28.7 510.6 136.9 512c80.3 1 92.3-102.5 129.5-152.3 26.4-35.5 60.5-45.5 102.4-55.9 72-17.8 121.1-74.7 121-150z"/></svg>
</a>
</div>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<script id="__config" type="application/json">{"base": ".", "features": ["navigation.tracking", "navigation.sections", "navigation.tabs", "content.tabs.link", "navigation.top", "search.suggest", "content.code.annotate", "navigation.instant", "content.action.edit"], "search": "assets/javascripts/workers/search.b8dbb3d2.min.js", "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}}</script>
<script src="assets/javascripts/bundle.bd41221c.min.js"></script>
</body>
</html>