Move http functions to new javascript file http.js.
This commit is contained in:
parent
de22dff161
commit
2bd8f42eb0
5 changed files with 280 additions and 166 deletions
|
@ -6,80 +6,100 @@ api.channels = {};
|
|||
api.channels.add_channel =
|
||||
function add_channel(channel_id, callback)
|
||||
{
|
||||
const url = "/add_channel";
|
||||
const data = {"channel_id": channel_id};
|
||||
return common.post(url, data, callback);
|
||||
return http.post({
|
||||
url: "/add_channel",
|
||||
data: {"channel_id": channel_id},
|
||||
callback: callback,
|
||||
});
|
||||
}
|
||||
|
||||
api.channels.delete_channel =
|
||||
function delete_channel(channel_id, callback)
|
||||
{
|
||||
const url = `/channel/${channel_id}/delete`;
|
||||
const data = {};
|
||||
return common.post(url, data, callback);
|
||||
return http.post({
|
||||
url: `/channel/${channel_id}/delete`,
|
||||
data: {},
|
||||
callback: callback,
|
||||
});
|
||||
}
|
||||
|
||||
api.channels.refresh_channel =
|
||||
function refresh_channel(channel_id, force, callback)
|
||||
{
|
||||
const url = `/channel/${channel_id}/refresh`;
|
||||
const data = {"force": force};
|
||||
return common.post(url, data, callback);
|
||||
return http.post({
|
||||
url: `/channel/${channel_id}/refresh`,
|
||||
data: {"force": force},
|
||||
callback: callback,
|
||||
});
|
||||
}
|
||||
|
||||
api.channels.refresh_all_channels =
|
||||
function refresh_all_channels(force, callback)
|
||||
{
|
||||
const url = "/refresh_all_channels";
|
||||
const data = {"force": force};
|
||||
return common.post(url, data, callback);
|
||||
return http.post({
|
||||
url: "/refresh_all_channels",
|
||||
data: {"force": force},
|
||||
callback: callback,
|
||||
});
|
||||
}
|
||||
|
||||
api.channels.set_automark =
|
||||
function set_automark(channel_id, state, callback)
|
||||
{
|
||||
const url = `/channel/${channel_id}/set_automark`;
|
||||
const data = {"state": state};
|
||||
return common.post(url, data, callback);
|
||||
return http.post({
|
||||
url: `/channel/${channel_id}/set_automark`,
|
||||
data: {"state": state},
|
||||
callback: callback,
|
||||
});
|
||||
}
|
||||
|
||||
api.channels.set_autorefresh =
|
||||
function set_autorefresh(channel_id, autorefresh, callback)
|
||||
{
|
||||
const url = `/channel/${channel_id}/set_autorefresh`;
|
||||
const data = {"autorefresh": autorefresh};
|
||||
return common.post(url, data, callback);
|
||||
return http.post({
|
||||
url: `/channel/${channel_id}/set_autorefresh`,
|
||||
data: {"autorefresh": autorefresh},
|
||||
callback: callback,
|
||||
});
|
||||
}
|
||||
|
||||
api.channels.set_download_directory =
|
||||
function set_download_directory(channel_id, download_directory, callback)
|
||||
{
|
||||
const url = `/channel/${channel_id}/set_download_directory`;
|
||||
const data = {"download_directory": download_directory};
|
||||
return common.post(url, data, callback);
|
||||
return http.post({
|
||||
url: `/channel/${channel_id}/set_download_directory`,
|
||||
data: {"download_directory": download_directory},
|
||||
callback: callback,
|
||||
});
|
||||
}
|
||||
|
||||
api.channels.set_name =
|
||||
function set_name(channel_id, name, callback)
|
||||
{
|
||||
const url = `/channel/${channel_id}/set_name`;
|
||||
const data = {"name": name};
|
||||
return common.post(url, data, callback);
|
||||
return http.post({
|
||||
url: `/channel/${channel_id}/set_name`,
|
||||
data: {"name": name},
|
||||
callback: callback,
|
||||
});
|
||||
}
|
||||
|
||||
api.channels.set_queuefile_extension =
|
||||
function set_queuefile_extension(channel_id, extension, callback)
|
||||
{
|
||||
const url = `/channel/${channel_id}/set_queuefile_extension`;
|
||||
const data = {"extension": extension};
|
||||
return common.post(url, data, callback);
|
||||
return http.post({
|
||||
url: `/channel/${channel_id}/set_queuefile_extension`,
|
||||
data: {"extension": extension},
|
||||
callback: callback,
|
||||
});
|
||||
}
|
||||
|
||||
api.channels.show_download_directory =
|
||||
function show_download_directory(channel_id, callback)
|
||||
{
|
||||
const url = `/channel/${channel_id}/show_download_directory`;
|
||||
return common.post(url, null, callback);
|
||||
return http.post({
|
||||
url: `/channel/${channel_id}/show_download_directory`,
|
||||
callback: callback,
|
||||
});
|
||||
}
|
||||
|
||||
api.channels.callback_go_to_channels =
|
||||
|
@ -101,15 +121,19 @@ api.videos = {};
|
|||
api.videos.mark_state =
|
||||
function mark_state(video_ids, state, callback)
|
||||
{
|
||||
const url = "/mark_video_state";
|
||||
const data = {"video_ids": video_ids, "state": state};
|
||||
return common.post(url, data, callback);
|
||||
return http.post({
|
||||
url: "/mark_video_state",
|
||||
data: {"video_ids": video_ids, "state": state},
|
||||
callback: callback,
|
||||
});
|
||||
}
|
||||
|
||||
api.videos.start_download =
|
||||
function start_download(video_ids, callback)
|
||||
{
|
||||
const url = "/start_download";
|
||||
const data = {"video_ids": video_ids};
|
||||
return common.post(url, data, callback);
|
||||
return http.post({
|
||||
url: "/start_download",
|
||||
data: {"video_ids": video_ids},
|
||||
callback: callback,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -34,6 +34,12 @@ function is_wide_mode()
|
|||
return getComputedStyle(document.documentElement).getPropertyValue("--wide").trim() === "1";
|
||||
}
|
||||
|
||||
common.go_to_root =
|
||||
function go_to_root()
|
||||
{
|
||||
window.location.href = "/";
|
||||
}
|
||||
|
||||
common.refresh =
|
||||
function refresh()
|
||||
{
|
||||
|
@ -51,146 +57,18 @@ function refresh_or_alert(response)
|
|||
window.location.reload();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// HTTP ////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
common.formdata =
|
||||
function formdata(data)
|
||||
{
|
||||
fd = new FormData();
|
||||
for (let [key, value] of Object.entries(data))
|
||||
{
|
||||
if (value === undefined)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (value === null)
|
||||
{
|
||||
value = '';
|
||||
}
|
||||
fd.append(key, value);
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
common._request =
|
||||
function _request(method, url, callback)
|
||||
{
|
||||
/*
|
||||
Perform an HTTP request and call the `callback` with the response.
|
||||
|
||||
The response will have the following structure:
|
||||
{
|
||||
"meta": {
|
||||
"completed": true / false,
|
||||
"status": If the connection failed or request otherwise could not
|
||||
complete, `status` will be 0. If the request completed,
|
||||
`status` will be the HTTP response code.
|
||||
"json_ok": If the server responded with parseable json, `json_ok`
|
||||
will be true, and that data will be in `response.data`. If the
|
||||
server response was not parseable json, `json_ok` will be false
|
||||
and `response.data` will be undefined.
|
||||
"request_url": The URL exactly as given to this call.
|
||||
}
|
||||
"data": {JSON parsed from server response if json_ok}.
|
||||
}
|
||||
|
||||
So, from most lenient to most strict, error catching might look like:
|
||||
if response.meta.completed
|
||||
if response.meta.json_ok
|
||||
if response.meta.status === 200
|
||||
if response.meta.status === 200 and response.meta.json_ok
|
||||
*/
|
||||
const request = new XMLHttpRequest();
|
||||
const response = {
|
||||
"meta": {
|
||||
"completed": false,
|
||||
"status": 0,
|
||||
"json_ok": false,
|
||||
"request_url": url,
|
||||
},
|
||||
};
|
||||
|
||||
request.onreadystatechange = function()
|
||||
{
|
||||
/*
|
||||
readystate values:
|
||||
0 UNSENT / ABORTED
|
||||
1 OPENED
|
||||
2 HEADERS_RECEIVED
|
||||
3 LOADING
|
||||
4 DONE
|
||||
*/
|
||||
if (request.readyState != 4)
|
||||
{return;}
|
||||
|
||||
if (callback == null)
|
||||
{return;}
|
||||
|
||||
response.meta.status = request.status;
|
||||
|
||||
if (request.status != 0)
|
||||
{
|
||||
response.meta.completed = true;
|
||||
try
|
||||
{
|
||||
response.data = JSON.parse(request.responseText);
|
||||
response.meta.json_ok = true;
|
||||
}
|
||||
catch (exc)
|
||||
{
|
||||
response.meta.json_ok = false;
|
||||
}
|
||||
}
|
||||
callback(response);
|
||||
};
|
||||
const asynchronous = true;
|
||||
request.open(method, url, asynchronous);
|
||||
return request;
|
||||
}
|
||||
|
||||
common.get =
|
||||
function get(url, callback)
|
||||
{
|
||||
request = common._request("GET", url, callback);
|
||||
request.send();
|
||||
return request;
|
||||
}
|
||||
|
||||
common.post =
|
||||
function post(url, data, callback)
|
||||
{
|
||||
/*
|
||||
`data`:
|
||||
a FormData object which you have already filled with values, or a
|
||||
dictionary from which a FormData will be made, using common.formdata.
|
||||
*/
|
||||
if (data instanceof FormData || data === null)
|
||||
{
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
data = common.formdata(data);
|
||||
}
|
||||
request = common._request("POST", url, callback);
|
||||
request.send(data);
|
||||
return request;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// STRING TOOLS ////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
common.join_and_trail =
|
||||
function join_and_trail(l, s)
|
||||
function join_and_trail(list, separator)
|
||||
{
|
||||
if (l.length === 0)
|
||||
if (list.length === 0)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
return l.join(s) + s
|
||||
return list.join(separator) + separator
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
210
frontends/ycdl_flask/static/js/http.js
Normal file
210
frontends/ycdl_flask/static/js/http.js
Normal file
|
@ -0,0 +1,210 @@
|
|||
const http = {};
|
||||
|
||||
http.HEADERS = {};
|
||||
|
||||
http.requests_in_flight = 0;
|
||||
|
||||
http.request_queue = {};
|
||||
http.request_queue.array = [];
|
||||
|
||||
http.request_queue.push =
|
||||
function request_queue_push(func)
|
||||
{
|
||||
http.request_queue.array.push(func)
|
||||
if (http.requests_in_flight == 0)
|
||||
{
|
||||
http.request_queue_next();
|
||||
}
|
||||
}
|
||||
|
||||
http.request_queue.unshift =
|
||||
function request_queue_unshift(func)
|
||||
{
|
||||
http.request_queue.array.unshift(func)
|
||||
if (http.requests_in_flight == 0)
|
||||
{
|
||||
http.request_queue_next();
|
||||
}
|
||||
}
|
||||
http.request_queue.pushleft = http.request_queue.unshift;
|
||||
|
||||
http.request_queue_next =
|
||||
function request_queue_next()
|
||||
{
|
||||
if (http.requests_in_flight > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (http.request_queue.array.length === 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
const func = http.request_queue.array.shift();
|
||||
func();
|
||||
}
|
||||
|
||||
http.formdata =
|
||||
function formdata(data)
|
||||
{
|
||||
const fd = new FormData();
|
||||
for (let [key, value] of Object.entries(data))
|
||||
{
|
||||
if (value === undefined)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (value === null)
|
||||
{
|
||||
value = '';
|
||||
}
|
||||
fd.append(key, value);
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
http._request =
|
||||
function _request(kwargs)
|
||||
{
|
||||
/*
|
||||
Perform an HTTP request and call the `callback` with the response.
|
||||
|
||||
The response will have the following structure:
|
||||
{
|
||||
"meta": {
|
||||
"request": the XMLHttpRequest object,
|
||||
"completed": true / false,
|
||||
"status": If the connection failed or request otherwise could not
|
||||
complete, `status` will be 0. If the request completed,
|
||||
`status` will be the HTTP response code.
|
||||
"json_ok": If the server responded with parseable json, `json_ok`
|
||||
will be true, and that data will be in `response.data`. If the
|
||||
server response was not parseable json, `json_ok` will be false
|
||||
and `response.data` will be undefined.
|
||||
"kwargs": The kwargs exactly as given to this call.
|
||||
}
|
||||
"data": {JSON parsed from server response if json_ok},
|
||||
"retry": function you can call to retry the request.
|
||||
}
|
||||
|
||||
So, from most lenient to most strict, error catching might look like:
|
||||
if response.meta.completed
|
||||
if response.meta.json_ok
|
||||
if response.meta.status === 200
|
||||
if response.meta.status === 200 and response.meta.json_ok
|
||||
*/
|
||||
const request = new XMLHttpRequest();
|
||||
const response = {
|
||||
"meta": {
|
||||
"request": request,
|
||||
"completed": false,
|
||||
"status": 0,
|
||||
"json_ok": false,
|
||||
"kwargs": kwargs,
|
||||
},
|
||||
"retry": function(){http._request(kwargs)},
|
||||
};
|
||||
|
||||
request.onreadystatechange = function()
|
||||
{
|
||||
/*
|
||||
readystate values:
|
||||
0 UNSENT / ABORTED
|
||||
1 OPENED
|
||||
2 HEADERS_RECEIVED
|
||||
3 LOADING
|
||||
4 DONE
|
||||
*/
|
||||
if (request.readyState != 4)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
http.requests_in_flight -= 1;
|
||||
setTimeout(http.request_queue_next, 0);
|
||||
|
||||
if (kwargs["callback"] == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
response.meta.status = request.status;
|
||||
|
||||
if (request.status != 0)
|
||||
{
|
||||
response.meta.completed = true;
|
||||
try
|
||||
{
|
||||
response.data = JSON.parse(request.responseText);
|
||||
response.meta.json_ok = true;
|
||||
}
|
||||
catch (exc)
|
||||
{
|
||||
response.meta.json_ok = false;
|
||||
}
|
||||
}
|
||||
kwargs["callback"](response);
|
||||
};
|
||||
|
||||
// Headers
|
||||
|
||||
const asynchronous = "asynchronous" in kwargs ? kwargs["asynchronous"] : true;
|
||||
request.open(kwargs["method"], kwargs["url"], asynchronous);
|
||||
|
||||
for (const [header, value] of Object.entries(http.HEADERS))
|
||||
{
|
||||
request.setRequestHeader(header, value);
|
||||
}
|
||||
|
||||
const more_headers = kwargs["headers"] || {};
|
||||
for (const [header, value] of Object.entries(more_headers))
|
||||
{
|
||||
request.setRequestHeader(header, value);
|
||||
}
|
||||
|
||||
if (kwargs["with_credentials"])
|
||||
{
|
||||
request.withCredentials = true;
|
||||
}
|
||||
|
||||
// Send
|
||||
|
||||
let data = kwargs["data"];
|
||||
if (data === undefined || data === null)
|
||||
{
|
||||
request.send();
|
||||
}
|
||||
else if (data instanceof FormData)
|
||||
{
|
||||
request.send(data);
|
||||
}
|
||||
else if (typeof(data) === "string" || data instanceof String)
|
||||
{
|
||||
request.send(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
request.send(http.formdata(data));
|
||||
}
|
||||
http.requests_in_flight += 1;
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
http.get =
|
||||
function get(kwargs)
|
||||
{
|
||||
kwargs["method"] = "GET";
|
||||
return http._request(kwargs);
|
||||
}
|
||||
|
||||
http.post =
|
||||
function post(kwargs)
|
||||
{
|
||||
/*
|
||||
`data`:
|
||||
a FormData object which you have already filled with values, or a
|
||||
dictionary from which a FormData will be made, using http.formdata.
|
||||
*/
|
||||
kwargs["method"] = "POST";
|
||||
return http._request(kwargs);
|
||||
}
|
|
@ -11,6 +11,7 @@
|
|||
<script src="/static/js/common.js"></script>
|
||||
<script src="/static/js/api.js"></script>
|
||||
<script src="/static/js/hotkeys.js"></script>
|
||||
<script src="/static/js/http.js"></script>
|
||||
<script src="/static/js/spinners.js"></script>
|
||||
|
||||
<style>
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
<link rel="stylesheet" href="/static/css/ycdl.css">
|
||||
<script src="/static/js/common.js"></script>
|
||||
<script src="/static/js/api.js"></script>
|
||||
<script src="/static/js/http.js"></script>
|
||||
<script src="/static/js/spinners.js"></script>
|
||||
|
||||
<style>
|
||||
|
|
Loading…
Reference in a new issue