mirror of
https://github.com/dgtlmoon/changedetection.io.git
synced 2025-10-30 06:07:50 +00:00
Some checks failed
Build and push containers / metadata (push) Has been cancelled
Build and push containers / build-push-containers (push) Has been cancelled
Publish Python 🐍distribution 📦 to PyPI and TestPyPI / Build distribution 📦 (push) Has been cancelled
Publish Python 🐍distribution 📦 to PyPI and TestPyPI / Test the built 📦 package works basically. (push) Has been cancelled
Publish Python 🐍distribution 📦 to PyPI and TestPyPI / Publish Python 🐍 distribution 📦 to PyPI (push) Has been cancelled
ChangeDetection.io App Test / lint-code (push) Has been cancelled
ChangeDetection.io App Test / test-application-3-10 (push) Has been cancelled
ChangeDetection.io App Test / test-application-3-11 (push) Has been cancelled
ChangeDetection.io App Test / test-application-3-12 (push) Has been cancelled
ChangeDetection.io App Test / test-application-3-13 (push) Has been cancelled
2182 lines
98 KiB
HTML
2182 lines
98 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Changedetection.io - API Documentation</title>
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.0/font/bootstrap-icons.css" rel="stylesheet">
|
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism.min.css" rel="stylesheet">
|
|
<style>
|
|
body { background-color: #f8f9fa; }
|
|
.sidebar { position: sticky; top: 0; height: 100vh; overflow-y: auto; background: white; box-shadow: 2px 0 5px rgba(0,0,0,0.1); }
|
|
.content { padding: 20px; }
|
|
.endpoint { margin-bottom: 40px; padding: 20px; background: white; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
|
|
.method { font-weight: bold; text-transform: uppercase; padding: 4px 8px; border-radius: 4px; }
|
|
.method.get { background: #d4edda; color: #155724; }
|
|
.method.post { background: #cce5ff; color: #004085; }
|
|
.method.put { background: #fff3cd; color: #856404; }
|
|
.method.delete { background: #f8d7da; color: #721c24; }
|
|
.param-table { font-size: 0.9em; }
|
|
.optional { color: #6c757d; font-style: italic; }
|
|
.example { background: #f8f9fa; border-left: 4px solid #007bff; }
|
|
pre { font-size: 0.85em; }
|
|
.copy-btn { opacity: 0.7; transition: opacity 0.2s ease; }
|
|
.copy-btn:hover { opacity: 1; }
|
|
.example:hover .copy-btn { opacity: 1; }
|
|
.nav-link.active { background-color: #007bff; color: white; font-weight: bold; }
|
|
.nav-link { transition: all 0.2s ease; }
|
|
.nav-link:hover:not(.active) { background-color: #e3f2fd; color: #0056b3; }
|
|
.group-header.active { font-weight: bold; color: #007bff; }
|
|
|
|
/* Custom scrollbar styling */
|
|
.sidebar::-webkit-scrollbar { width: 8px; }
|
|
.sidebar::-webkit-scrollbar-track { background: #f8f9fa; border-radius: 4px; }
|
|
.sidebar::-webkit-scrollbar-thumb { background: #dee2e6; border-radius: 4px; }
|
|
.sidebar::-webkit-scrollbar-thumb:hover { background: #adb5bd; }
|
|
|
|
/* Firefox scrollbar */
|
|
.sidebar { scrollbar-width: thin; scrollbar-color: #dee2e6 #f8f9fa; }
|
|
|
|
/* Mobile styles - disable sticky sidebar */
|
|
@media (max-width: 800px) {
|
|
.sidebar {
|
|
position: static !important;
|
|
height: auto !important;
|
|
overflow-y: visible !important;
|
|
}
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container-fluid">
|
|
<div class="row">
|
|
<!-- Sidebar -->
|
|
<div class="col-md-3 sidebar">
|
|
<div class="p-3">
|
|
<a href="#introduction" class="text-decoration-none">
|
|
<h4>API Documentation</h4>
|
|
</a>
|
|
<hr>
|
|
|
|
|
|
<div class="mb-3">
|
|
<a href="#introduction" class="text-decoration-none">
|
|
<h6 class="text-muted">Introduction</h6>
|
|
</a>
|
|
</div>
|
|
|
|
|
|
|
|
<div class="mb-3">
|
|
<h6 class="text-muted group-header" data-group="Watch">Watch</h6>
|
|
|
|
<div class="ms-2 mb-1">
|
|
<a href="#watch_POST" class="nav-link py-1 px-2 rounded" data-endpoint="watch_POST">
|
|
<span class="method post">post</span>
|
|
Create a single watch
|
|
</a>
|
|
</div>
|
|
|
|
<div class="ms-2 mb-1">
|
|
<a href="#watch_DELETE" class="nav-link py-1 px-2 rounded" data-endpoint="watch_DELETE">
|
|
<span class="method delete">delete</span>
|
|
Delete a watch and related history
|
|
</a>
|
|
</div>
|
|
|
|
<div class="ms-2 mb-1">
|
|
<a href="#watch_PUT" class="nav-link py-1 px-2 rounded" data-endpoint="watch_PUT">
|
|
<span class="method put">put</span>
|
|
Update watch information
|
|
</a>
|
|
</div>
|
|
|
|
<div class="ms-2 mb-1">
|
|
<a href="#watch_GET" class="nav-link py-1 px-2 rounded" data-endpoint="watch_GET">
|
|
<span class="method get">get</span>
|
|
Single watch - get data, recheck, pause, mute.
|
|
</a>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<h6 class="text-muted group-header" data-group="Watch History">Watch History</h6>
|
|
|
|
<div class="ms-2 mb-1">
|
|
<a href="#watch_history_GET" class="nav-link py-1 px-2 rounded" data-endpoint="watch_history_GET">
|
|
<span class="method get">get</span>
|
|
Get a list of all historical snapshots available for a watch
|
|
</a>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<h6 class="text-muted group-header" data-group="Snapshots">Snapshots</h6>
|
|
|
|
<div class="ms-2 mb-1">
|
|
<a href="#snapshots_GET" class="nav-link py-1 px-2 rounded" data-endpoint="snapshots_GET">
|
|
<span class="method get">get</span>
|
|
Get single snapshot from watch
|
|
</a>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<h6 class="text-muted group-header" data-group="Favicon">Favicon</h6>
|
|
|
|
<div class="ms-2 mb-1">
|
|
<a href="#favicon_GET" class="nav-link py-1 px-2 rounded" data-endpoint="favicon_GET">
|
|
<span class="method get">get</span>
|
|
Get Favicon for a watch
|
|
</a>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<h6 class="text-muted group-header" data-group="Watch Management">Watch Management</h6>
|
|
|
|
<div class="ms-2 mb-1">
|
|
<a href="#watch_management_GET" class="nav-link py-1 px-2 rounded" data-endpoint="watch_management_GET">
|
|
<span class="method get">get</span>
|
|
List watches
|
|
</a>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<h6 class="text-muted group-header" data-group="Group / Tag">Group / Tag</h6>
|
|
|
|
<div class="ms-2 mb-1">
|
|
<a href="#group__tag_POST" class="nav-link py-1 px-2 rounded" data-endpoint="group__tag_POST">
|
|
<span class="method post">post</span>
|
|
Create a single tag
|
|
</a>
|
|
</div>
|
|
|
|
<div class="ms-2 mb-1">
|
|
<a href="#group__tag_DELETE" class="nav-link py-1 px-2 rounded" data-endpoint="group__tag_DELETE">
|
|
<span class="method delete">delete</span>
|
|
Delete a tag and remove it from all watches
|
|
</a>
|
|
</div>
|
|
|
|
<div class="ms-2 mb-1">
|
|
<a href="#group__tag_GET" class="nav-link py-1 px-2 rounded" data-endpoint="group__tag_GET">
|
|
<span class="method get">get</span>
|
|
Single tag - Get data, toggle notification muting, recheck all.
|
|
</a>
|
|
</div>
|
|
|
|
<div class="ms-2 mb-1">
|
|
<a href="#group__tag_PUT" class="nav-link py-1 px-2 rounded" data-endpoint="group__tag_PUT">
|
|
<span class="method put">put</span>
|
|
Update tag information
|
|
</a>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<h6 class="text-muted group-header" data-group="Group / Tag Management">Group / Tag Management</h6>
|
|
|
|
<div class="ms-2 mb-1">
|
|
<a href="#group__tag_management_GET" class="nav-link py-1 px-2 rounded" data-endpoint="group__tag_management_GET">
|
|
<span class="method get">get</span>
|
|
List tags
|
|
</a>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<h6 class="text-muted group-header" data-group="Import">Import</h6>
|
|
|
|
<div class="ms-2 mb-1">
|
|
<a href="#import_POST" class="nav-link py-1 px-2 rounded" data-endpoint="import_POST">
|
|
<span class="method post">post</span>
|
|
Import a list of watched URLs
|
|
</a>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<h6 class="text-muted group-header" data-group="Notifications">Notifications</h6>
|
|
|
|
<div class="ms-2 mb-1">
|
|
<a href="#notifications_POST" class="nav-link py-1 px-2 rounded" data-endpoint="notifications_POST">
|
|
<span class="method post">post</span>
|
|
Create Notification URLs
|
|
</a>
|
|
</div>
|
|
|
|
<div class="ms-2 mb-1">
|
|
<a href="#notifications_DELETE" class="nav-link py-1 px-2 rounded" data-endpoint="notifications_DELETE">
|
|
<span class="method delete">delete</span>
|
|
Delete Notification URLs
|
|
</a>
|
|
</div>
|
|
|
|
<div class="ms-2 mb-1">
|
|
<a href="#notifications_GET" class="nav-link py-1 px-2 rounded" data-endpoint="notifications_GET">
|
|
<span class="method get">get</span>
|
|
Return Notification URL List
|
|
</a>
|
|
</div>
|
|
|
|
<div class="ms-2 mb-1">
|
|
<a href="#notifications_PUT" class="nav-link py-1 px-2 rounded" data-endpoint="notifications_PUT">
|
|
<span class="method put">put</span>
|
|
Replace Notification URLs
|
|
</a>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<h6 class="text-muted group-header" data-group="Search">Search</h6>
|
|
|
|
<div class="ms-2 mb-1">
|
|
<a href="#search_GET" class="nav-link py-1 px-2 rounded" data-endpoint="search_GET">
|
|
<span class="method get">get</span>
|
|
Search for watches
|
|
</a>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<h6 class="text-muted group-header" data-group="System Information">System Information</h6>
|
|
|
|
<div class="ms-2 mb-1">
|
|
<a href="#system_information_GET" class="nav-link py-1 px-2 rounded" data-endpoint="system_information_GET">
|
|
<span class="method get">get</span>
|
|
Return system info
|
|
</a>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Main content -->
|
|
<div class="col-md-9 content">
|
|
|
|
<div id="introduction" class="mb-5">
|
|
<div class="introduction-content">
|
|
<h3>ChangeDetection.io, Web page monitoring and notifications API</h3>
|
|
<p>REST API for managing Page watches, Group tags, and Notifications.</p>
|
|
|
|
<p>changedetection.io can be driven by its built in simple API, in the examples below you will also find <code>curl</code> command line examples to help you.</p>
|
|
|
|
<p>
|
|
<h5>Where to find my API key?</h5>
|
|
The API key can be easily found under the <strong>SETTINGS</strong> then <strong>API</strong> tab of changedetection.io dashboard.<br>
|
|
Simply click the API key to automatically copy it to your clipboard.<br><br>
|
|
<img src="where-to-get-api-key.jpeg" alt="Where to find the API key" title="Where to find the API key" style="max-width: 80%"/>
|
|
</p>
|
|
|
|
<p>
|
|
<h5>Connection URL</h5>
|
|
The API can be found at <code>/api/v1/</code>, so for example if you run changedetection.io locally on port 5000, then URL would be
|
|
<code>http://localhost:5000/api/v1/watch/cc0cfffa-f449-477b-83ea-0caafd1dc091/history</code>.<br><br>
|
|
If you are using the hosted/subscription version of changedetection.io, then the URL is based on your login URL, for example.<br>
|
|
<code>https://<your login url>/api/v1/watch/cc0cfffa-f449-477b-83ea-0caafd1dc091/history</code>
|
|
</p>
|
|
<p>
|
|
<h5>Authentication</h5>
|
|
Almost all API requests require some authentication, this is provided as an <strong>API Key</strong> in the header of the HTTP request.<br><br>
|
|
For example;
|
|
<br><code>x-api-key: YOUR_API_KEY</code><br>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<h2 class="text-primary mb-4" id="group-watch">Watch</h2>
|
|
|
|
|
|
<div class="endpoint" id="watch_POST" data-group="Watch">
|
|
<div class="row">
|
|
<div class="col-md-8">
|
|
<h4>
|
|
<span class="method post">post</span>
|
|
<code>/api/v1/watch</code>
|
|
</h4>
|
|
<h5 class="text-muted">Create</h5>
|
|
|
|
<p class="mt-3">Requires atleast `url` set, can accept the same structure as <a href="#watch_GET">get single watch information</a> to create.</p>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h6 class="mt-4">Success Responses</h6>
|
|
|
|
<div class="mb-2">
|
|
<span class="badge bg-success">200</span>
|
|
<span class="badge bg-secondary ms-1">String</span>
|
|
<strong class="ms-2">OK</strong>
|
|
<span class="ms-2 text-muted">Was created</span>
|
|
</div>
|
|
|
|
<div class="mb-2">
|
|
<span class="badge bg-success">500</span>
|
|
<span class="badge bg-secondary ms-1">String</span>
|
|
<strong class="ms-2">ERR</strong>
|
|
<span class="ms-2 text-muted">Some other error</span>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h6 class="mt-4">Example</h6>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div class="example p-3 rounded position-relative">
|
|
<button class="btn btn-outline-secondary btn-sm position-absolute top-0 end-0 m-2 copy-btn"
|
|
data-bs-toggle="tooltip"
|
|
data-bs-placement="left"
|
|
title="Copy to clipboard"
|
|
onclick="copyToClipboard(this)">
|
|
<i class="bi bi-clipboard" aria-hidden="true"></i>
|
|
</button>
|
|
<pre><code class="language-bash">curl http://localhost:5000/api/v1/watch -H"x-api-key:813031b16330fe25e3780cf0325daa45" -H "Content-Type: application/json" -d '{"url": "https://my-nice.com" , "tag": "nice list"}'</code></pre>
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
<div class="endpoint" id="watch_DELETE" data-group="Watch">
|
|
<div class="row">
|
|
<div class="col-md-8">
|
|
<h4>
|
|
<span class="method delete">delete</span>
|
|
<code>/api/v1/watch/:uuid</code>
|
|
</h4>
|
|
<h5 class="text-muted">Delete</h5>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<h6 class="mt-4">Parameters</h6>
|
|
<div class="table-responsive">
|
|
<table class="table table-sm param-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Required</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
|
|
<tr>
|
|
<td><code>uuid</code></td>
|
|
<td><span class="badge bg-secondary">uuid</span></td>
|
|
<td><span class="text-danger">Required</span></td>
|
|
<td>Watch unique ID.</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<h6 class="mt-4">Success Responses</h6>
|
|
|
|
<div class="mb-2">
|
|
<span class="badge bg-success">200</span>
|
|
<span class="badge bg-secondary ms-1">String</span>
|
|
<strong class="ms-2">OK</strong>
|
|
<span class="ms-2 text-muted">Was deleted</span>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h6 class="mt-4">Example</h6>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div class="example p-3 rounded position-relative">
|
|
<button class="btn btn-outline-secondary btn-sm position-absolute top-0 end-0 m-2 copy-btn"
|
|
data-bs-toggle="tooltip"
|
|
data-bs-placement="left"
|
|
title="Copy to clipboard"
|
|
onclick="copyToClipboard(this)">
|
|
<i class="bi bi-clipboard" aria-hidden="true"></i>
|
|
</button>
|
|
<pre><code class="language-bash">curl http://localhost:5000/api/v1/watch/cc0cfffa-f449-477b-83ea-0caafd1dc091 -X DELETE -H"x-api-key:813031b16330fe25e3780cf0325daa45"</code></pre>
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
<div class="endpoint" id="watch_PUT" data-group="Watch">
|
|
<div class="row">
|
|
<div class="col-md-8">
|
|
<h4>
|
|
<span class="method put">put</span>
|
|
<code>/api/v1/watch/:uuid</code>
|
|
</h4>
|
|
<h5 class="text-muted">Update a watch</h5>
|
|
|
|
<p class="mt-3">Updates an existing watch using JSON, accepts the same structure as returned in <a href="#watch_GET">get single watch information</a></p>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<h6 class="mt-4">Parameters</h6>
|
|
<div class="table-responsive">
|
|
<table class="table table-sm param-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Required</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
|
|
<tr>
|
|
<td><code>uuid</code></td>
|
|
<td><span class="badge bg-secondary">uuid</span></td>
|
|
<td><span class="text-danger">Required</span></td>
|
|
<td>Watch unique ID.</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<h6 class="mt-4">Success Responses</h6>
|
|
|
|
<div class="mb-2">
|
|
<span class="badge bg-success">200</span>
|
|
<span class="badge bg-secondary ms-1">String</span>
|
|
<strong class="ms-2">OK</strong>
|
|
<span class="ms-2 text-muted">Was updated</span>
|
|
</div>
|
|
|
|
<div class="mb-2">
|
|
<span class="badge bg-success">500</span>
|
|
<span class="badge bg-secondary ms-1">String</span>
|
|
<strong class="ms-2">ERR</strong>
|
|
<span class="ms-2 text-muted">Some other error</span>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h6 class="mt-4">Example</h6>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div class="example p-3 rounded position-relative">
|
|
<button class="btn btn-outline-secondary btn-sm position-absolute top-0 end-0 m-2 copy-btn"
|
|
data-bs-toggle="tooltip"
|
|
data-bs-placement="left"
|
|
title="Copy to clipboard"
|
|
onclick="copyToClipboard(this)">
|
|
<i class="bi bi-clipboard" aria-hidden="true"></i>
|
|
</button>
|
|
<pre><code class="language-bash">Update (PUT)
|
|
curl http://localhost:5000/api/v1/watch/cc0cfffa-f449-477b-83ea-0caafd1dc091 -X PUT -H"x-api-key:813031b16330fe25e3780cf0325daa45" -H "Content-Type: application/json" -d '{"url": "https://my-nice.com" , "tag": "new list"}'
|
|
</code></pre>
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
<div class="endpoint" id="watch_GET" data-group="Watch">
|
|
<div class="row">
|
|
<div class="col-md-8">
|
|
<h4>
|
|
<span class="method get">get</span>
|
|
<code>/api/v1/watch/:uuid</code>
|
|
</h4>
|
|
<h5 class="text-muted">Watch</h5>
|
|
|
|
<p class="mt-3">Retrieve watch information and set muted/paused status</p>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<h6 class="mt-4">Parameters</h6>
|
|
<div class="table-responsive">
|
|
<table class="table table-sm param-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Required</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
|
|
<tr>
|
|
<td><code>uuid</code></td>
|
|
<td><span class="badge bg-secondary">uuid</span></td>
|
|
<td><span class="text-danger">Required</span></td>
|
|
<td>Watch unique ID.</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
|
|
|
|
<h6 class="mt-4">Query Parameters</h6>
|
|
<div class="table-responsive">
|
|
<table class="table table-sm param-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Required</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
|
|
<tr>
|
|
<td><code>recheck</code></td>
|
|
<td><span class="badge bg-info">Boolean</span></td>
|
|
<td><span class="optional">Optional</span></td>
|
|
<td>Recheck this watch `recheck=1`</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td><code>paused</code></td>
|
|
<td><span class="badge bg-info">String</span></td>
|
|
<td><span class="optional">Optional</span></td>
|
|
<td>=`paused` or =`unpaused` , Sets the PAUSED state</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td><code>muted</code></td>
|
|
<td><span class="badge bg-info">String</span></td>
|
|
<td><span class="optional">Optional</span></td>
|
|
<td>=`muted` or =`unmuted` , Sets the MUTE NOTIFICATIONS state</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
|
|
|
|
<h6 class="mt-4">Success Responses</h6>
|
|
|
|
<div class="mb-2">
|
|
<span class="badge bg-success">200</span>
|
|
<span class="badge bg-secondary ms-1">String</span>
|
|
<strong class="ms-2">OK</strong>
|
|
<span class="ms-2 text-muted">When paused/muted/recheck operation OR full JSON object of the watch</span>
|
|
</div>
|
|
|
|
<div class="mb-2">
|
|
<span class="badge bg-success">200</span>
|
|
<span class="badge bg-secondary ms-1">JSON</span>
|
|
<strong class="ms-2">WatchJSON</strong>
|
|
<span class="ms-2 text-muted">JSON Full JSON object of the watch</span>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h6 class="mt-4">Example</h6>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div class="example p-3 rounded position-relative">
|
|
<button class="btn btn-outline-secondary btn-sm position-absolute top-0 end-0 m-2 copy-btn"
|
|
data-bs-toggle="tooltip"
|
|
data-bs-placement="left"
|
|
title="Copy to clipboard"
|
|
onclick="copyToClipboard(this)">
|
|
<i class="bi bi-clipboard" aria-hidden="true"></i>
|
|
</button>
|
|
<pre><code class="language-bash">curl http://localhost:5000/api/v1/watch/cc0cfffa-f449-477b-83ea-0caafd1dc091 -H"x-api-key:813031b16330fe25e3780cf0325daa45"
|
|
curl "http://localhost:5000/api/v1/watch/cc0cfffa-f449-477b-83ea-0caafd1dc091?muted=unmuted" -H"x-api-key:813031b16330fe25e3780cf0325daa45"
|
|
curl "http://localhost:5000/api/v1/watch/cc0cfffa-f449-477b-83ea-0caafd1dc091?paused=unpaused" -H"x-api-key:813031b16330fe25e3780cf0325daa45"</code></pre>
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<h2 class="text-primary mb-4" id="group-watch_history">Watch History</h2>
|
|
|
|
|
|
<div class="endpoint" id="watch_history_GET" data-group="Watch History">
|
|
<div class="row">
|
|
<div class="col-md-8">
|
|
<h4>
|
|
<span class="method get">get</span>
|
|
<code>/api/v1/watch/<string:uuid>/history</code>
|
|
</h4>
|
|
<h5 class="text-muted">Get list of available stored snapshots for watch</h5>
|
|
|
|
<p class="mt-3">Requires `uuid`, returns list</p>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h6 class="mt-4">Success Responses</h6>
|
|
|
|
<div class="mb-2">
|
|
<span class="badge bg-success">200</span>
|
|
<span class="badge bg-secondary ms-1">String</span>
|
|
<strong class="ms-2">OK</strong>
|
|
<span class="ms-2 text-muted"></span>
|
|
</div>
|
|
|
|
<div class="mb-2">
|
|
<span class="badge bg-success">404</span>
|
|
<span class="badge bg-secondary ms-1">String</span>
|
|
<strong class="ms-2">ERR</strong>
|
|
<span class="ms-2 text-muted">Not found</span>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h6 class="mt-4">Example</h6>
|
|
|
|
|
|
<h7 class="mt-3 mb-2 text-muted">Request</h7>
|
|
<div class="example p-3 rounded position-relative mb-3">
|
|
<button class="btn btn-outline-secondary btn-sm position-absolute top-0 end-0 m-2 copy-btn"
|
|
data-bs-toggle="tooltip"
|
|
data-bs-placement="left"
|
|
title="Copy to clipboard"
|
|
onclick="copyToClipboard(this)">
|
|
<i class="bi bi-clipboard" aria-hidden="true"></i>
|
|
</button>
|
|
<pre><code class="language-bash">curl http://localhost:5000/api/v1/watch/cc0cfffa-f449-477b-83ea-0caafd1dc091/history -H"x-api-key:813031b16330fe25e3780cf0325daa45" -H "Content-Type: application/json"</code></pre>
|
|
</div>
|
|
|
|
|
|
|
|
<h7 class="mt-3 mb-2 text-muted">Response</h7>
|
|
<div class="example p-3 rounded position-relative mb-3">
|
|
<button class="btn btn-outline-secondary btn-sm position-absolute top-0 end-0 m-2 copy-btn"
|
|
data-bs-toggle="tooltip"
|
|
data-bs-placement="left"
|
|
title="Copy to clipboard"
|
|
onclick="copyToClipboard(this)">
|
|
<i class="bi bi-clipboard" aria-hidden="true"></i>
|
|
</button>
|
|
<pre><code class="language-json">{
|
|
"1676649279": "/tmp/data/6a4b7d5c-fee4-4616-9f43-4ac97046b595/cb7e9be8258368262246910e6a2a4c30.txt",
|
|
"1677092785": "/tmp/data/6a4b7d5c-fee4-4616-9f43-4ac97046b595/e20db368d6fc633e34f559ff67bb4044.txt",
|
|
"1677103794": "/tmp/data/6a4b7d5c-fee4-4616-9f43-4ac97046b595/02efdd37dacdae96554a8cc85dc9c945.txt"
|
|
}</code></pre>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<h2 class="text-primary mb-4" id="group-snapshots">Snapshots</h2>
|
|
|
|
|
|
<div class="endpoint" id="snapshots_GET" data-group="Snapshots">
|
|
<div class="row">
|
|
<div class="col-md-8">
|
|
<h4>
|
|
<span class="method get">get</span>
|
|
<code>/api/v1/watch/<string:uuid>/history/<int:timestamp></code>
|
|
</h4>
|
|
<h5 class="text-muted">Get single snapshot content</h5>
|
|
|
|
<p class="mt-3">Requires watch `uuid` and `timestamp`. `timestamp` of "`latest`" for latest available snapshot, or <a href="#watch_history_GET">use the list returned here</a></p>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<h6 class="mt-4">Parameters</h6>
|
|
<div class="table-responsive">
|
|
<table class="table table-sm param-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Required</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
|
|
<tr>
|
|
<td><code>html</code></td>
|
|
<td><span class="badge bg-secondary">String</span></td>
|
|
<td><span class="optional">Optional</span></td>
|
|
<td>Optional Set to =1 to return the last HTML (only stores last 2 snapshots, use `latest` as timestamp)</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<h6 class="mt-4">Success Responses</h6>
|
|
|
|
<div class="mb-2">
|
|
<span class="badge bg-success">200</span>
|
|
<span class="badge bg-secondary ms-1">String</span>
|
|
<strong class="ms-2">OK</strong>
|
|
<span class="ms-2 text-muted"></span>
|
|
</div>
|
|
|
|
<div class="mb-2">
|
|
<span class="badge bg-success">404</span>
|
|
<span class="badge bg-secondary ms-1">String</span>
|
|
<strong class="ms-2">ERR</strong>
|
|
<span class="ms-2 text-muted">Not found</span>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h6 class="mt-4">Example</h6>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div class="example p-3 rounded position-relative">
|
|
<button class="btn btn-outline-secondary btn-sm position-absolute top-0 end-0 m-2 copy-btn"
|
|
data-bs-toggle="tooltip"
|
|
data-bs-placement="left"
|
|
title="Copy to clipboard"
|
|
onclick="copyToClipboard(this)">
|
|
<i class="bi bi-clipboard" aria-hidden="true"></i>
|
|
</button>
|
|
<pre><code class="language-bash">curl http://localhost:5000/api/v1/watch/cc0cfffa-f449-477b-83ea-0caafd1dc091/history/1677092977 -H"x-api-key:813031b16330fe25e3780cf0325daa45" -H "Content-Type: application/json"</code></pre>
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<h2 class="text-primary mb-4" id="group-favicon">Favicon</h2>
|
|
|
|
|
|
<div class="endpoint" id="favicon_GET" data-group="Favicon">
|
|
<div class="row">
|
|
<div class="col-md-8">
|
|
<h4>
|
|
<span class="method get">get</span>
|
|
<code>/api/v1/watch/<string:uuid>/favicon</code>
|
|
</h4>
|
|
<h5 class="text-muted">Get latest Favicon</h5>
|
|
|
|
<p class="mt-3">Requires watch `uuid`</p>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h6 class="mt-4">Success Responses</h6>
|
|
|
|
<div class="mb-2">
|
|
<span class="badge bg-success">200</span>
|
|
<span class="badge bg-secondary ms-1">String</span>
|
|
<strong class="ms-2">OK</strong>
|
|
<span class="ms-2 text-muted"></span>
|
|
</div>
|
|
|
|
<div class="mb-2">
|
|
<span class="badge bg-success">404</span>
|
|
<span class="badge bg-secondary ms-1">String</span>
|
|
<strong class="ms-2">ERR</strong>
|
|
<span class="ms-2 text-muted">Not found</span>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h6 class="mt-4">Example</h6>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div class="example p-3 rounded position-relative">
|
|
<button class="btn btn-outline-secondary btn-sm position-absolute top-0 end-0 m-2 copy-btn"
|
|
data-bs-toggle="tooltip"
|
|
data-bs-placement="left"
|
|
title="Copy to clipboard"
|
|
onclick="copyToClipboard(this)">
|
|
<i class="bi bi-clipboard" aria-hidden="true"></i>
|
|
</button>
|
|
<pre><code class="language-bash">curl http://localhost:5000/api/v1/watch/cc0cfffa-f449-477b-83ea-0caafd1dc091/favicon -H"x-api-key:813031b16330fe25e3780cf0325daa45"</code></pre>
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<h2 class="text-primary mb-4" id="group-watch_management">Watch Management</h2>
|
|
|
|
|
|
<div class="endpoint" id="watch_management_GET" data-group="Watch Management">
|
|
<div class="row">
|
|
<div class="col-md-8">
|
|
<h4>
|
|
<span class="method get">get</span>
|
|
<code>/api/v1/watch</code>
|
|
</h4>
|
|
<h5 class="text-muted">ListWatches</h5>
|
|
|
|
<p class="mt-3">Return concise list of available watches and some very basic info</p>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<h6 class="mt-4">Parameters</h6>
|
|
<div class="table-responsive">
|
|
<table class="table table-sm param-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Required</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
|
|
<tr>
|
|
<td><code>recheck_all</code></td>
|
|
<td><span class="badge bg-secondary">String</span></td>
|
|
<td><span class="optional">Optional</span></td>
|
|
<td>Optional Set to =1 to force recheck of all watches</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td><code>tag</code></td>
|
|
<td><span class="badge bg-secondary">String</span></td>
|
|
<td><span class="optional">Optional</span></td>
|
|
<td>Optional name of tag to limit results</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<h6 class="mt-4">Success Responses</h6>
|
|
|
|
<div class="mb-2">
|
|
<span class="badge bg-success">200</span>
|
|
<span class="badge bg-secondary ms-1">String</span>
|
|
<strong class="ms-2">OK</strong>
|
|
<span class="ms-2 text-muted">JSON dict</span>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h6 class="mt-4">Example</h6>
|
|
|
|
|
|
<h7 class="mt-3 mb-2 text-muted">Request</h7>
|
|
<div class="example p-3 rounded position-relative mb-3">
|
|
<button class="btn btn-outline-secondary btn-sm position-absolute top-0 end-0 m-2 copy-btn"
|
|
data-bs-toggle="tooltip"
|
|
data-bs-placement="left"
|
|
title="Copy to clipboard"
|
|
onclick="copyToClipboard(this)">
|
|
<i class="bi bi-clipboard" aria-hidden="true"></i>
|
|
</button>
|
|
<pre><code class="language-bash">curl http://localhost:5000/api/v1/watch -H"x-api-key:813031b16330fe25e3780cf0325daa45"</code></pre>
|
|
</div>
|
|
|
|
|
|
|
|
<h7 class="mt-3 mb-2 text-muted">Response</h7>
|
|
<div class="example p-3 rounded position-relative mb-3">
|
|
<button class="btn btn-outline-secondary btn-sm position-absolute top-0 end-0 m-2 copy-btn"
|
|
data-bs-toggle="tooltip"
|
|
data-bs-placement="left"
|
|
title="Copy to clipboard"
|
|
onclick="copyToClipboard(this)">
|
|
<i class="bi bi-clipboard" aria-hidden="true"></i>
|
|
</button>
|
|
<pre><code class="language-json">{
|
|
"6a4b7d5c-fee4-4616-9f43-4ac97046b595": {
|
|
"last_changed": 1677103794,
|
|
"last_checked": 1677103794,
|
|
"last_error": false,
|
|
"title": "",
|
|
"url": "http://www.quotationspage.com/random.php"
|
|
},
|
|
"e6f5fd5c-dbfe-468b-b8f3-f9d6ff5ad69b": {
|
|
"last_changed": 0,
|
|
"last_checked": 1676662819,
|
|
"last_error": false,
|
|
"title": "QuickLook",
|
|
"url": "https://github.com/QL-Win/QuickLook/tags"
|
|
}
|
|
}</code></pre>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<h2 class="text-primary mb-4" id="group-group_/_tag">Group / Tag</h2>
|
|
|
|
|
|
<div class="endpoint" id="group__tag_POST" data-group="Group / Tag">
|
|
<div class="row">
|
|
<div class="col-md-8">
|
|
<h4>
|
|
<span class="method post">post</span>
|
|
<code>/api/v1/watch</code>
|
|
</h4>
|
|
<h5 class="text-muted">Create</h5>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h6 class="mt-4">Success Responses</h6>
|
|
|
|
<div class="mb-2">
|
|
<span class="badge bg-success">200</span>
|
|
<span class="badge bg-secondary ms-1">String</span>
|
|
<strong class="ms-2">OK</strong>
|
|
<span class="ms-2 text-muted">Was created</span>
|
|
</div>
|
|
|
|
<div class="mb-2">
|
|
<span class="badge bg-success">500</span>
|
|
<span class="badge bg-secondary ms-1">String</span>
|
|
<strong class="ms-2">ERR</strong>
|
|
<span class="ms-2 text-muted">Some other error</span>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h6 class="mt-4">Example</h6>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div class="example p-3 rounded position-relative">
|
|
<button class="btn btn-outline-secondary btn-sm position-absolute top-0 end-0 m-2 copy-btn"
|
|
data-bs-toggle="tooltip"
|
|
data-bs-placement="left"
|
|
title="Copy to clipboard"
|
|
onclick="copyToClipboard(this)">
|
|
<i class="bi bi-clipboard" aria-hidden="true"></i>
|
|
</button>
|
|
<pre><code class="language-bash">curl http://localhost:5000/api/v1/watch -H"x-api-key:813031b16330fe25e3780cf0325daa45" -H "Content-Type: application/json" -d '{"name": "Work related"}'</code></pre>
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
<div class="endpoint" id="group__tag_DELETE" data-group="Group / Tag">
|
|
<div class="row">
|
|
<div class="col-md-8">
|
|
<h4>
|
|
<span class="method delete">delete</span>
|
|
<code>/api/v1/tag/:uuid</code>
|
|
</h4>
|
|
<h5 class="text-muted">DeleteTag</h5>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<h6 class="mt-4">Parameters</h6>
|
|
<div class="table-responsive">
|
|
<table class="table table-sm param-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Required</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
|
|
<tr>
|
|
<td><code>uuid</code></td>
|
|
<td><span class="badge bg-secondary">uuid</span></td>
|
|
<td><span class="text-danger">Required</span></td>
|
|
<td>Tag unique ID.</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<h6 class="mt-4">Success Responses</h6>
|
|
|
|
<div class="mb-2">
|
|
<span class="badge bg-success">200</span>
|
|
<span class="badge bg-secondary ms-1">String</span>
|
|
<strong class="ms-2">OK</strong>
|
|
<span class="ms-2 text-muted">Was deleted</span>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h6 class="mt-4">Example</h6>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div class="example p-3 rounded position-relative">
|
|
<button class="btn btn-outline-secondary btn-sm position-absolute top-0 end-0 m-2 copy-btn"
|
|
data-bs-toggle="tooltip"
|
|
data-bs-placement="left"
|
|
title="Copy to clipboard"
|
|
onclick="copyToClipboard(this)">
|
|
<i class="bi bi-clipboard" aria-hidden="true"></i>
|
|
</button>
|
|
<pre><code class="language-bash">curl http://localhost:5000/api/v1/tag/cc0cfffa-f449-477b-83ea-0caafd1dc091 -X DELETE -H"x-api-key:813031b16330fe25e3780cf0325daa45"</code></pre>
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
<div class="endpoint" id="group__tag_GET" data-group="Group / Tag">
|
|
<div class="row">
|
|
<div class="col-md-8">
|
|
<h4>
|
|
<span class="method get">get</span>
|
|
<code>/api/v1/tag/:uuid</code>
|
|
</h4>
|
|
<h5 class="text-muted">Tag</h5>
|
|
|
|
<p class="mt-3">Retrieve tag information, set notification_muted status, recheck all in tag.</p>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<h6 class="mt-4">Parameters</h6>
|
|
<div class="table-responsive">
|
|
<table class="table table-sm param-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Required</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
|
|
<tr>
|
|
<td><code>uuid</code></td>
|
|
<td><span class="badge bg-secondary">uuid</span></td>
|
|
<td><span class="text-danger">Required</span></td>
|
|
<td>Tag unique ID.</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
|
|
|
|
<h6 class="mt-4">Query Parameters</h6>
|
|
<div class="table-responsive">
|
|
<table class="table table-sm param-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Required</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
|
|
<tr>
|
|
<td><code>muted</code></td>
|
|
<td><span class="badge bg-info">String</span></td>
|
|
<td><span class="optional">Optional</span></td>
|
|
<td>=`muted` or =`unmuted` , Sets the MUTE NOTIFICATIONS state</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td><code>recheck</code></td>
|
|
<td><span class="badge bg-info">String</span></td>
|
|
<td><span class="optional">Optional</span></td>
|
|
<td>= True, Queue all watches with this tag for recheck</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
|
|
|
|
<h6 class="mt-4">Success Responses</h6>
|
|
|
|
<div class="mb-2">
|
|
<span class="badge bg-success">200</span>
|
|
<span class="badge bg-secondary ms-1">String</span>
|
|
<strong class="ms-2">OK</strong>
|
|
<span class="ms-2 text-muted">When muted operation OR full JSON object of the tag</span>
|
|
</div>
|
|
|
|
<div class="mb-2">
|
|
<span class="badge bg-success">200</span>
|
|
<span class="badge bg-secondary ms-1">JSON</span>
|
|
<strong class="ms-2">TagJSON</strong>
|
|
<span class="ms-2 text-muted">JSON Full JSON object of the tag</span>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
<div class="endpoint" id="group__tag_PUT" data-group="Group / Tag">
|
|
<div class="row">
|
|
<div class="col-md-8">
|
|
<h4>
|
|
<span class="method put">put</span>
|
|
<code>/api/v1/tag/:uuid</code>
|
|
</h4>
|
|
<h5 class="text-muted">UpdateTag</h5>
|
|
|
|
<p class="mt-3">Updates an existing tag using JSON</p>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<h6 class="mt-4">Parameters</h6>
|
|
<div class="table-responsive">
|
|
<table class="table table-sm param-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Required</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
|
|
<tr>
|
|
<td><code>uuid</code></td>
|
|
<td><span class="badge bg-secondary">uuid</span></td>
|
|
<td><span class="text-danger">Required</span></td>
|
|
<td>Tag unique ID.</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<h6 class="mt-4">Success Responses</h6>
|
|
|
|
<div class="mb-2">
|
|
<span class="badge bg-success">200</span>
|
|
<span class="badge bg-secondary ms-1">String</span>
|
|
<strong class="ms-2">OK</strong>
|
|
<span class="ms-2 text-muted">Was updated</span>
|
|
</div>
|
|
|
|
<div class="mb-2">
|
|
<span class="badge bg-success">500</span>
|
|
<span class="badge bg-secondary ms-1">String</span>
|
|
<strong class="ms-2">ERR</strong>
|
|
<span class="ms-2 text-muted">Some other error</span>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h6 class="mt-4">Example</h6>
|
|
|
|
|
|
<h7 class="mt-3 mb-2 text-muted">Request</h7>
|
|
<div class="example p-3 rounded position-relative mb-3">
|
|
<button class="btn btn-outline-secondary btn-sm position-absolute top-0 end-0 m-2 copy-btn"
|
|
data-bs-toggle="tooltip"
|
|
data-bs-placement="left"
|
|
title="Copy to clipboard"
|
|
onclick="copyToClipboard(this)">
|
|
<i class="bi bi-clipboard" aria-hidden="true"></i>
|
|
</button>
|
|
<pre><code class="language-bash">curl http://localhost:5000/api/v1/tag/cc0cfffa-f449-477b-83ea-0caafd1dc091 -X PUT -H"x-api-key:813031b16330fe25e3780cf0325daa45" -H "Content-Type: application/json" -d '{"title": "New Tag Title"}'</code></pre>
|
|
</div>
|
|
|
|
|
|
|
|
<h7 class="mt-3 mb-2 text-muted">Response</h7>
|
|
<div class="example p-3 rounded position-relative mb-3">
|
|
<button class="btn btn-outline-secondary btn-sm position-absolute top-0 end-0 m-2 copy-btn"
|
|
data-bs-toggle="tooltip"
|
|
data-bs-placement="left"
|
|
title="Copy to clipboard"
|
|
onclick="copyToClipboard(this)">
|
|
<i class="bi bi-clipboard" aria-hidden="true"></i>
|
|
</button>
|
|
<pre><code class="language-json">"OK"</code></pre>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<h2 class="text-primary mb-4" id="group-group_/_tag_management">Group / Tag Management</h2>
|
|
|
|
|
|
<div class="endpoint" id="group__tag_management_GET" data-group="Group / Tag Management">
|
|
<div class="row">
|
|
<div class="col-md-8">
|
|
<h4>
|
|
<span class="method get">get</span>
|
|
<code>/api/v1/tags</code>
|
|
</h4>
|
|
<h5 class="text-muted">ListTags</h5>
|
|
|
|
<p class="mt-3">Return list of available tags</p>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h6 class="mt-4">Success Responses</h6>
|
|
|
|
<div class="mb-2">
|
|
<span class="badge bg-success">200</span>
|
|
<span class="badge bg-secondary ms-1">String</span>
|
|
<strong class="ms-2">OK</strong>
|
|
<span class="ms-2 text-muted">JSON dict</span>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h6 class="mt-4">Example</h6>
|
|
|
|
|
|
<h7 class="mt-3 mb-2 text-muted">Request</h7>
|
|
<div class="example p-3 rounded position-relative mb-3">
|
|
<button class="btn btn-outline-secondary btn-sm position-absolute top-0 end-0 m-2 copy-btn"
|
|
data-bs-toggle="tooltip"
|
|
data-bs-placement="left"
|
|
title="Copy to clipboard"
|
|
onclick="copyToClipboard(this)">
|
|
<i class="bi bi-clipboard" aria-hidden="true"></i>
|
|
</button>
|
|
<pre><code class="language-bash">curl http://localhost:5000/api/v1/tags -H"x-api-key:813031b16330fe25e3780cf0325daa45"</code></pre>
|
|
</div>
|
|
|
|
|
|
|
|
<h7 class="mt-3 mb-2 text-muted">Response</h7>
|
|
<div class="example p-3 rounded position-relative mb-3">
|
|
<button class="btn btn-outline-secondary btn-sm position-absolute top-0 end-0 m-2 copy-btn"
|
|
data-bs-toggle="tooltip"
|
|
data-bs-placement="left"
|
|
title="Copy to clipboard"
|
|
onclick="copyToClipboard(this)">
|
|
<i class="bi bi-clipboard" aria-hidden="true"></i>
|
|
</button>
|
|
<pre><code class="language-json">{
|
|
"cc0cfffa-f449-477b-83ea-0caafd1dc091": {
|
|
"title": "Tech News",
|
|
"notification_muted": false,
|
|
"date_created": 1677103794
|
|
},
|
|
"e6f5fd5c-dbfe-468b-b8f3-f9d6ff5ad69b": {
|
|
"title": "Shopping",
|
|
"notification_muted": true,
|
|
"date_created": 1676662819
|
|
}
|
|
}</code></pre>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<h2 class="text-primary mb-4" id="group-import">Import</h2>
|
|
|
|
|
|
<div class="endpoint" id="import_POST" data-group="Import">
|
|
<div class="row">
|
|
<div class="col-md-8">
|
|
<h4>
|
|
<span class="method post">post</span>
|
|
<code>/api/v1/import</code>
|
|
</h4>
|
|
<h5 class="text-muted">Import</h5>
|
|
|
|
<p class="mt-3">Accepts a line-feed separated list of URLs to import, additionally with ?tag_uuids=(tag id), ?tag=(name), ?proxy={key}, ?dedupe=true (default true) one URL per line.</p>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h6 class="mt-4">Success Responses</h6>
|
|
|
|
<div class="mb-2">
|
|
<span class="badge bg-success">200</span>
|
|
<span class="badge bg-secondary ms-1">List</span>
|
|
<strong class="ms-2">OK</strong>
|
|
<span class="ms-2 text-muted">List of watch UUIDs added</span>
|
|
</div>
|
|
|
|
<div class="mb-2">
|
|
<span class="badge bg-success">500</span>
|
|
<span class="badge bg-secondary ms-1">String</span>
|
|
<strong class="ms-2">ERR</strong>
|
|
<span class="ms-2 text-muted">Some other error</span>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h6 class="mt-4">Example</h6>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div class="example p-3 rounded position-relative">
|
|
<button class="btn btn-outline-secondary btn-sm position-absolute top-0 end-0 m-2 copy-btn"
|
|
data-bs-toggle="tooltip"
|
|
data-bs-placement="left"
|
|
title="Copy to clipboard"
|
|
onclick="copyToClipboard(this)">
|
|
<i class="bi bi-clipboard" aria-hidden="true"></i>
|
|
</button>
|
|
<pre><code class="language-bash">curl http://localhost:5000/api/v1/import --data-binary @list-of-sites.txt -H"x-api-key:8a111a21bc2f8f1dd9b9353bbd46049a"</code></pre>
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<h2 class="text-primary mb-4" id="group-notifications">Notifications</h2>
|
|
|
|
|
|
<div class="endpoint" id="notifications_POST" data-group="Notifications">
|
|
<div class="row">
|
|
<div class="col-md-8">
|
|
<h4>
|
|
<span class="method post">post</span>
|
|
<code>/api/v1/notifications</code>
|
|
</h4>
|
|
<h5 class="text-muted">CreateBatch</h5>
|
|
|
|
<p class="mt-3">Add one or more notification URLs from the configuration</p>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h6 class="mt-4">Success Responses</h6>
|
|
|
|
<div class="mb-2">
|
|
<span class="badge bg-success">201</span>
|
|
<span class="badge bg-secondary ms-1">Object[]</span>
|
|
<strong class="ms-2">notification_urls</strong>
|
|
<span class="ms-2 text-muted">List of added notification URLs</span>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<h6 class="mt-4">Error Responses</h6>
|
|
|
|
<div class="mb-2">
|
|
<span class="badge bg-danger">400</span>
|
|
<span class="badge bg-secondary ms-1">String</span>
|
|
<span class="ms-2 text-muted">Invalid input</span>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<h6 class="mt-4">Example</h6>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div class="example p-3 rounded position-relative">
|
|
<button class="btn btn-outline-secondary btn-sm position-absolute top-0 end-0 m-2 copy-btn"
|
|
data-bs-toggle="tooltip"
|
|
data-bs-placement="left"
|
|
title="Copy to clipboard"
|
|
onclick="copyToClipboard(this)">
|
|
<i class="bi bi-clipboard" aria-hidden="true"></i>
|
|
</button>
|
|
<pre><code class="language-bash">curl http://localhost:5000/api/v1/notifications/batch -H"x-api-key:813031b16330fe25e3780cf0325daa45" -H "Content-Type: application/json" -d '{"notification_urls": ["url1", "url2"]}'</code></pre>
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
<div class="endpoint" id="notifications_DELETE" data-group="Notifications">
|
|
<div class="row">
|
|
<div class="col-md-8">
|
|
<h4>
|
|
<span class="method delete">delete</span>
|
|
<code>/api/v1/notifications</code>
|
|
</h4>
|
|
<h5 class="text-muted">Delete</h5>
|
|
|
|
<p class="mt-3">Deletes one or more notification URLs from the configuration</p>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<h6 class="mt-4">Parameters</h6>
|
|
<div class="table-responsive">
|
|
<table class="table table-sm param-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Required</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
|
|
<tr>
|
|
<td><code>notification_urls</code></td>
|
|
<td><span class="badge bg-secondary">String[]</span></td>
|
|
<td><span class="text-danger">Required</span></td>
|
|
<td>The notification URLs to delete.</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<h6 class="mt-4">Success Responses</h6>
|
|
|
|
<div class="mb-2">
|
|
<span class="badge bg-success">204</span>
|
|
<span class="badge bg-secondary ms-1">String</span>
|
|
<strong class="ms-2">OK</strong>
|
|
<span class="ms-2 text-muted">Deleted</span>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<h6 class="mt-4">Error Responses</h6>
|
|
|
|
<div class="mb-2">
|
|
<span class="badge bg-danger">400</span>
|
|
<span class="badge bg-secondary ms-1">String</span>
|
|
<span class="ms-2 text-muted">No matching notification URLs found.</span>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<h6 class="mt-4">Example</h6>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div class="example p-3 rounded position-relative">
|
|
<button class="btn btn-outline-secondary btn-sm position-absolute top-0 end-0 m-2 copy-btn"
|
|
data-bs-toggle="tooltip"
|
|
data-bs-placement="left"
|
|
title="Copy to clipboard"
|
|
onclick="copyToClipboard(this)">
|
|
<i class="bi bi-clipboard" aria-hidden="true"></i>
|
|
</button>
|
|
<pre><code class="language-bash">curl http://localhost:5000/api/v1/notifications -X DELETE -H"x-api-key:813031b16330fe25e3780cf0325daa45" -H "Content-Type: application/json" -d '{"notification_urls": ["url1", "url2"]}'</code></pre>
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
<div class="endpoint" id="notifications_GET" data-group="Notifications">
|
|
<div class="row">
|
|
<div class="col-md-8">
|
|
<h4>
|
|
<span class="method get">get</span>
|
|
<code>/api/v1/notifications</code>
|
|
</h4>
|
|
<h5 class="text-muted">Get</h5>
|
|
|
|
<p class="mt-3">Return the Notification URL List from the configuration</p>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h6 class="mt-4">Example</h6>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div class="example p-3 rounded position-relative">
|
|
<button class="btn btn-outline-secondary btn-sm position-absolute top-0 end-0 m-2 copy-btn"
|
|
data-bs-toggle="tooltip"
|
|
data-bs-placement="left"
|
|
title="Copy to clipboard"
|
|
onclick="copyToClipboard(this)">
|
|
<i class="bi bi-clipboard" aria-hidden="true"></i>
|
|
</button>
|
|
<pre><code class="language-bash">curl http://localhost:5000/api/v1/notifications -H"x-api-key:813031b16330fe25e3780cf0325daa45"
|
|
HTTP/1.0 200
|
|
{
|
|
'notification_urls': ["notification-urls-list"]
|
|
}</code></pre>
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
<div class="endpoint" id="notifications_PUT" data-group="Notifications">
|
|
<div class="row">
|
|
<div class="col-md-8">
|
|
<h4>
|
|
<span class="method put">put</span>
|
|
<code>/api/v1/notifications</code>
|
|
</h4>
|
|
<h5 class="text-muted">Replace</h5>
|
|
|
|
<p class="mt-3">Replace all notification URLs with the provided list (can be empty)</p>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h6 class="mt-4">Success Responses</h6>
|
|
|
|
<div class="mb-2">
|
|
<span class="badge bg-success">200</span>
|
|
<span class="badge bg-secondary ms-1">Object[]</span>
|
|
<strong class="ms-2">notification_urls</strong>
|
|
<span class="ms-2 text-muted">List of current notification URLs</span>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<h6 class="mt-4">Error Responses</h6>
|
|
|
|
<div class="mb-2">
|
|
<span class="badge bg-danger">400</span>
|
|
<span class="badge bg-secondary ms-1">String</span>
|
|
<span class="ms-2 text-muted">Invalid input</span>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<h6 class="mt-4">Example</h6>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div class="example p-3 rounded position-relative">
|
|
<button class="btn btn-outline-secondary btn-sm position-absolute top-0 end-0 m-2 copy-btn"
|
|
data-bs-toggle="tooltip"
|
|
data-bs-placement="left"
|
|
title="Copy to clipboard"
|
|
onclick="copyToClipboard(this)">
|
|
<i class="bi bi-clipboard" aria-hidden="true"></i>
|
|
</button>
|
|
<pre><code class="language-bash">curl -X PUT http://localhost:5000/api/v1/notifications -H"x-api-key:813031b16330fe25e3780cf0325daa45" -H "Content-Type: application/json" -d '{"notification_urls": ["url1", "url2"]}'</code></pre>
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<h2 class="text-primary mb-4" id="group-search">Search</h2>
|
|
|
|
|
|
<div class="endpoint" id="search_GET" data-group="Search">
|
|
<div class="row">
|
|
<div class="col-md-8">
|
|
<h4>
|
|
<span class="method get">get</span>
|
|
<code>/api/v1/search</code>
|
|
</h4>
|
|
<h5 class="text-muted">Search</h5>
|
|
|
|
<p class="mt-3">Search watches by URL or title text</p>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<h6 class="mt-4">Query Parameters</h6>
|
|
<div class="table-responsive">
|
|
<table class="table table-sm param-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Required</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
|
|
<tr>
|
|
<td><code>q</code></td>
|
|
<td><span class="badge bg-info">String</span></td>
|
|
<td><span class="text-danger">Required</span></td>
|
|
<td>Search query to match against watch URLs and titles</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td><code>tag</code></td>
|
|
<td><span class="badge bg-info">String</span></td>
|
|
<td><span class="optional">Optional</span></td>
|
|
<td>Optional name of tag to limit results (name not UUID)</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td><code>partial</code></td>
|
|
<td><span class="badge bg-info">String</span></td>
|
|
<td><span class="optional">Optional</span></td>
|
|
<td>Allow partial matching of URL query</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
|
|
|
|
<h6 class="mt-4">Success Responses</h6>
|
|
|
|
<div class="mb-2">
|
|
<span class="badge bg-success">200</span>
|
|
<span class="badge bg-secondary ms-1">Object</span>
|
|
<strong class="ms-2">JSON</strong>
|
|
<span class="ms-2 text-muted">Object containing matched watches</span>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h6 class="mt-4">Example</h6>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div class="example p-3 rounded position-relative">
|
|
<button class="btn btn-outline-secondary btn-sm position-absolute top-0 end-0 m-2 copy-btn"
|
|
data-bs-toggle="tooltip"
|
|
data-bs-placement="left"
|
|
title="Copy to clipboard"
|
|
onclick="copyToClipboard(this)">
|
|
<i class="bi bi-clipboard" aria-hidden="true"></i>
|
|
</button>
|
|
<pre><code class="language-bash">curl "http://localhost:5000/api/v1/search?q=https://example.com/page1" -H"x-api-key:813031b16330fe25e3780cf0325daa45"
|
|
curl "http://localhost:5000/api/v1/search?q=https://example.com/page1?tag=Favourites" -H"x-api-key:813031b16330fe25e3780cf0325daa45"
|
|
curl "http://localhost:5000/api/v1/search?q=https://example.com?partial=true" -H"x-api-key:813031b16330fe25e3780cf0325daa45"</code></pre>
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<h2 class="text-primary mb-4" id="group-system_information">System Information</h2>
|
|
|
|
|
|
<div class="endpoint" id="system_information_GET" data-group="System Information">
|
|
<div class="row">
|
|
<div class="col-md-8">
|
|
<h4>
|
|
<span class="method get">get</span>
|
|
<code>/api/v1/systeminfo</code>
|
|
</h4>
|
|
<h5 class="text-muted">Get Info</h5>
|
|
|
|
<p class="mt-3">Return some info about the current system state</p>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h6 class="mt-4">Example</h6>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div class="example p-3 rounded position-relative">
|
|
<button class="btn btn-outline-secondary btn-sm position-absolute top-0 end-0 m-2 copy-btn"
|
|
data-bs-toggle="tooltip"
|
|
data-bs-placement="left"
|
|
title="Copy to clipboard"
|
|
onclick="copyToClipboard(this)">
|
|
<i class="bi bi-clipboard" aria-hidden="true"></i>
|
|
</button>
|
|
<pre><code class="language-bash">curl http://localhost:5000/api/v1/systeminfo -H"x-api-key:813031b16330fe25e3780cf0325daa45"
|
|
HTTP/1.0 200
|
|
{
|
|
'queue_size': 10 ,
|
|
'overdue_watches': ["watch-uuid-list"],
|
|
'uptime': 38344.55,
|
|
'watch_count': 800,
|
|
'version': "0.40.1"
|
|
}</code></pre>
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-core.min.js"></script>
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
|
|
|
|
<script>
|
|
$(document).ready(function() {
|
|
let isScrolling = false;
|
|
let isNavigating = false;
|
|
|
|
// Check if we should disable scroll handling on mobile
|
|
function isMobileWidth() {
|
|
return window.innerWidth < 800;
|
|
}
|
|
|
|
// Debounced scroll handler
|
|
function debounce(func, wait) {
|
|
let timeout;
|
|
return function executedFunction(...args) {
|
|
const later = () => {
|
|
clearTimeout(timeout);
|
|
func(...args);
|
|
};
|
|
clearTimeout(timeout);
|
|
timeout = setTimeout(later, wait);
|
|
};
|
|
}
|
|
|
|
// Function to scroll sidebar link into view if needed
|
|
function scrollIntoViewIfNeeded(element) {
|
|
if (!element) return;
|
|
|
|
const sidebar = $('.sidebar')[0];
|
|
const rect = element.getBoundingClientRect();
|
|
const sidebarRect = sidebar.getBoundingClientRect();
|
|
|
|
// Check if element is outside the sidebar viewport
|
|
const isAboveView = rect.top < sidebarRect.top;
|
|
const isBelowView = rect.bottom > sidebarRect.bottom;
|
|
|
|
if (isAboveView || isBelowView) {
|
|
element.scrollIntoView({
|
|
behavior: 'smooth',
|
|
block: 'center'
|
|
});
|
|
}
|
|
}
|
|
|
|
// Intersection Observer for more efficient viewport detection
|
|
const observerOptions = {
|
|
root: null,
|
|
rootMargin: '-20% 0px -70% 0px', // Trigger when element is in top 30% of viewport
|
|
threshold: 0
|
|
};
|
|
|
|
const observer = new IntersectionObserver((entries) => {
|
|
// Don't update if user is actively navigating or on mobile
|
|
if (isNavigating || isMobileWidth()) return;
|
|
|
|
entries.forEach(entry => {
|
|
if (entry.isIntersecting) {
|
|
const targetId = entry.target.id;
|
|
const targetGroup = entry.target.dataset.group;
|
|
|
|
// Update window location hash
|
|
if (window.location.hash !== '#' + targetId) {
|
|
history.replaceState(null, null, '#' + targetId);
|
|
}
|
|
|
|
// Remove all active states
|
|
$('.nav-link').removeClass('active');
|
|
$('.group-header').removeClass('active');
|
|
|
|
// Add active state to current item
|
|
const $activeLink = $(`.nav-link[data-endpoint="${targetId}"]`);
|
|
$activeLink.addClass('active');
|
|
$(`.group-header[data-group="${targetGroup}"]`).addClass('active');
|
|
|
|
// Handle introduction section
|
|
if (targetId === 'introduction') {
|
|
const $introLink = $('a[href="#introduction"]');
|
|
$introLink.addClass('active');
|
|
// Scroll intro link into view in sidebar
|
|
scrollIntoViewIfNeeded($introLink[0]);
|
|
} else {
|
|
// Scroll active link into view in sidebar
|
|
if ($activeLink.length) {
|
|
scrollIntoViewIfNeeded($activeLink[0]);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}, observerOptions);
|
|
|
|
// Observe all endpoints and introduction (only on desktop)
|
|
if (!isMobileWidth()) {
|
|
$('.endpoint').each(function() {
|
|
observer.observe(this);
|
|
});
|
|
|
|
if ($('#introduction').length) {
|
|
observer.observe($('#introduction')[0]);
|
|
}
|
|
}
|
|
|
|
// Smooth scrolling for navigation links
|
|
$('a[href^="#"]').on('click', function(e) {
|
|
e.preventDefault();
|
|
const targetHref = this.getAttribute('href');
|
|
const target = $(targetHref);
|
|
if (target.length) {
|
|
// Set navigation flag to prevent observer interference
|
|
isNavigating = true;
|
|
|
|
// Update window location hash immediately
|
|
history.pushState(null, null, targetHref);
|
|
|
|
$('html, body').animate({
|
|
scrollTop: target.offset().top - 20
|
|
}, 300, function() {
|
|
// Clear navigation flag after animation completes
|
|
setTimeout(() => {
|
|
isNavigating = false;
|
|
}, 100);
|
|
});
|
|
}
|
|
});
|
|
|
|
// Fallback scroll handler with debouncing
|
|
const handleScroll = debounce(() => {
|
|
if (isScrolling || isNavigating || isMobileWidth()) return;
|
|
|
|
let current = '';
|
|
let currentGroup = '';
|
|
|
|
// Check which section is currently in view
|
|
$('.endpoint, #introduction').each(function() {
|
|
const element = $(this);
|
|
const elementTop = element.offset().top;
|
|
const elementBottom = elementTop + element.outerHeight();
|
|
const scrollTop = $(window).scrollTop() + 100; // Offset for better UX
|
|
|
|
if (scrollTop >= elementTop && scrollTop < elementBottom) {
|
|
current = this.id;
|
|
currentGroup = element.data('group');
|
|
return false; // Break loop
|
|
}
|
|
});
|
|
|
|
if (current) {
|
|
// Update window location hash
|
|
if (window.location.hash !== '#' + current) {
|
|
history.replaceState(null, null, '#' + current);
|
|
}
|
|
|
|
$('.nav-link').removeClass('active');
|
|
$('.group-header').removeClass('active');
|
|
|
|
const $activeLink = $(`.nav-link[data-endpoint="${current}"]`);
|
|
$activeLink.addClass('active');
|
|
if (currentGroup) {
|
|
$(`.group-header[data-group="${currentGroup}"]`).addClass('active');
|
|
}
|
|
|
|
if (current === 'introduction') {
|
|
const $introLink = $('a[href="#introduction"]');
|
|
$introLink.addClass('active');
|
|
scrollIntoViewIfNeeded($introLink[0]);
|
|
} else if ($activeLink.length) {
|
|
scrollIntoViewIfNeeded($activeLink[0]);
|
|
}
|
|
}
|
|
}, 50);
|
|
|
|
// Only bind scroll handler on desktop
|
|
if (!isMobileWidth()) {
|
|
$(window).on('scroll', handleScroll);
|
|
|
|
// Initial call
|
|
handleScroll();
|
|
}
|
|
|
|
// Initialize tooltips
|
|
const tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
|
|
const tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
|
|
return new bootstrap.Tooltip(tooltipTriggerEl);
|
|
});
|
|
});
|
|
|
|
// Copy to clipboard function
|
|
function copyToClipboard(button) {
|
|
const codeBlock = button.parentElement.querySelector('code');
|
|
const text = codeBlock.textContent;
|
|
|
|
// Use modern clipboard API
|
|
if (navigator.clipboard && window.isSecureContext) {
|
|
navigator.clipboard.writeText(text).then(() => {
|
|
showCopyFeedback(button, true);
|
|
}).catch(() => {
|
|
fallbackCopyToClipboard(text, button);
|
|
});
|
|
} else {
|
|
fallbackCopyToClipboard(text, button);
|
|
}
|
|
}
|
|
|
|
// Fallback for older browsers
|
|
function fallbackCopyToClipboard(text, button) {
|
|
const textArea = document.createElement('textarea');
|
|
textArea.value = text;
|
|
textArea.style.position = 'fixed';
|
|
textArea.style.left = '-999999px';
|
|
textArea.style.top = '-999999px';
|
|
document.body.appendChild(textArea);
|
|
textArea.focus();
|
|
textArea.select();
|
|
|
|
try {
|
|
const successful = document.execCommand('copy');
|
|
showCopyFeedback(button, successful);
|
|
} catch (err) {
|
|
showCopyFeedback(button, false);
|
|
}
|
|
|
|
document.body.removeChild(textArea);
|
|
}
|
|
|
|
// Show copy feedback
|
|
function showCopyFeedback(button, success) {
|
|
const icon = button.querySelector('i');
|
|
const originalClass = icon.className;
|
|
const originalTitle = button.getAttribute('data-bs-original-title') || button.getAttribute('title');
|
|
|
|
if (success) {
|
|
icon.className = 'bi bi-check';
|
|
button.classList.remove('btn-outline-secondary');
|
|
button.classList.add('btn-success');
|
|
button.setAttribute('title', 'Copied!');
|
|
} else {
|
|
icon.className = 'bi bi-x';
|
|
button.classList.remove('btn-outline-secondary');
|
|
button.classList.add('btn-danger');
|
|
button.setAttribute('title', 'Failed to copy');
|
|
}
|
|
|
|
// Update tooltip
|
|
const tooltip = bootstrap.Tooltip.getInstance(button);
|
|
if (tooltip) {
|
|
tooltip.dispose();
|
|
new bootstrap.Tooltip(button);
|
|
}
|
|
|
|
// Reset after 2 seconds
|
|
setTimeout(() => {
|
|
icon.className = originalClass;
|
|
button.classList.remove('btn-success', 'btn-danger');
|
|
button.classList.add('btn-outline-secondary');
|
|
button.setAttribute('title', originalTitle);
|
|
|
|
// Update tooltip again
|
|
const tooltip = bootstrap.Tooltip.getInstance(button);
|
|
if (tooltip) {
|
|
tooltip.dispose();
|
|
new bootstrap.Tooltip(button);
|
|
}
|
|
}, 2000);
|
|
}
|
|
</script>
|
|
</body>
|
|
</html> |