Compare commits
1 Commits
master
...
dependabot
Author | SHA1 | Date | |
---|---|---|---|
|
864c197dd8 |
281
README.md
281
README.md
@ -1,139 +1,142 @@
|
|||||||

|

|
||||||
|
|
||||||
# Tubio
|
# Tubio
|
||||||
The free, open source video downloader!
|
The free, open source video downloader!
|
||||||
|
|
||||||
No longer do you have to rely on shady websites, shoving tons of ads in your face to fulfil your downloady needs. No longer will you be held back by artificially crippled download speeds, login-/paywalls or even watermarks.
|
No longer do you have to rely on shady websites, shoving tons of ads in your face to fulfil your downloady needs. No longer will you be held back by artificially crippled download speeds, login-/paywalls or even watermarks.
|
||||||
|
|
||||||
## But what is Tubio?
|
## But what is Tubio?
|
||||||
Tubio in of itself is not a downloader, but a GUI for the widely known, open-source, public-domain cli [yt-dlp](https://github.com/yt-dlp/yt-dlp/). <sup>Thanks for this awesome tool! You guys are heroes! (Obviously, same goes for youtube-dl, which yt-dlp is based on)</sup>
|
Tubio in of itself is not a downloader, but a GUI for the widely known, open-source, public-domain cli [yt-dlp](https://github.com/yt-dlp/yt-dlp/). <sup>Thanks for this awesome tool! You guys are heroes! (Obviously, same goes for youtube-dl, which yt-dlp is based on)</sup>
|
||||||
The goal of Tubio is to make this awesome software more accessible. Not everyone knows how to use the command line!
|
The goal of Tubio is to make this awesome software more accessible. Not everyone knows how to use the command line!
|
||||||
|
|
||||||
## But, how does it work?
|
## But, how does it work?
|
||||||
It\`s quite easy! Make sure the Tubio service is running in the background, navigate to http://localhost, paste in your video/music url and chances are that it will work!
|
It\`s quite easy! Make sure the Tubio service is running in the background, navigate to http://localhost, paste in your video/music url and chances are that it will work!
|
||||||
|
|
||||||
This is because the set of supported websites is **extremely** large! See here: [supportedsites.md](https://github.com/blackjack4494/yt-dlc/blob/master/docs/supportedsites.md)
|
This is because the set of supported websites is **extremely** large! See here: [supportedsites.md](https://github.com/blackjack4494/yt-dlc/blob/master/docs/supportedsites.md)
|
||||||
|
|
||||||
When your download finished, just click "download" and have fun!
|
When your download finished, just click "download" and have fun!
|
||||||
|
|
||||||
## No, i mean on a more technical level
|
## No, i mean on a more technical level
|
||||||
The backend is a C++ webserver, powered by [casenta/mongoose](https://github.com/cesanta/mongoose).<sup>Thanks, you guys are awesome!</sup>
|
The backend is a C++ webserver, powered by [casenta/mongoose](https://github.com/cesanta/mongoose).<sup>Thanks, you guys are awesome!</sup>
|
||||||
The connection is **not** encrypted, but that\`s okay because it is intended for localhost only. Mongoose does support ssl, so you can always add it, if you fancy it.
|
The connection is **not** encrypted, but that\`s okay because it is intended for localhost only. Mongoose does support ssl, so you can always add it, if you fancy it.
|
||||||
|
|
||||||
The frontend is a nuxt.js web application.
|
The frontend is a nuxt.js web application.
|
||||||
|
|
||||||
## But how does it look?
|
## But how does it look?
|
||||||
Have a sneak peak!
|
Have a sneak peak!
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## There's also a Chrome Extension
|
## NEW! Get the Chrome Companion Extension!
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
## How can i configure it?
|
## How can i configure it?
|
||||||
See this json file (config.json).
|
See this json file (config.json).
|
||||||
Most of these values are configurable in the web-interface, but not all, such as the port.
|
Most of these values are configurable in the web-interface, but not all, such as the port.
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"access": {
|
"access": {
|
||||||
"enable_whitelist": true,
|
"enable_whitelist": true,
|
||||||
"only_allow_localhost": false,
|
"only_allow_localhost": false,
|
||||||
"whitelist": [
|
"whitelist": [
|
||||||
"127.0.0.1",
|
"127.0.0.1",
|
||||||
"192.168.1.12",
|
"192.168.1.12",
|
||||||
"192.168.1.14",
|
"192.168.1.14",
|
||||||
"192.168.1.10"
|
"192.168.1.10"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"downloader": {
|
"downloader": {
|
||||||
"cachedir": "dlcache",
|
"cachedir": "dlcache",
|
||||||
"max_dlrate_per_thread": "100M",
|
"max_dlrate_per_thread": "100M",
|
||||||
"num_threads": 10
|
"num_threads": 10
|
||||||
},
|
},
|
||||||
"general": {
|
"general": {
|
||||||
"show_console": true
|
"show_console": true
|
||||||
},
|
},
|
||||||
"httpServer": {
|
"httpServer": {
|
||||||
"polling_rate": 100,
|
"polling_rate": 100,
|
||||||
"port": "80",
|
"port": "80",
|
||||||
"rootdir": "./frontend"
|
"rootdir": "./frontend"
|
||||||
},
|
},
|
||||||
"logging": {
|
"logging": {
|
||||||
"autosave_interval": 20,
|
"autosave_interval": 20,
|
||||||
"logfile_json": "log.json",
|
"logfile_json": "log.json",
|
||||||
"logfile_text": "log.txt"
|
"logfile_text": "log.txt"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Can i use Tubio on multiple devices?
|
## Can i use Tubio on multiple devices?
|
||||||
Tubio hosts a webserver, after all. It is intended to be used for localhost only (since no encryption), but no one is preventing you from unticking `localhost only` under `/settings`. Then you could connect to it via your local IPv4 address (such as `192.168.1.12`) or even over the global WAN! However, regarding WAN, i would **strongly** advise against such a careless setup.
|
Tubio is a webserver, after all. It is intended to be used for localhost only (since no encryption), but no one is preventing you from unticking `localhost only` under /settings.
|
||||||
|
|
||||||
It wouldn't be that complicated to enable TLS. You'd have to install and link `libcryptopp`, obtain a certificate + key, and pass them to the mongoose webserver. But that would break that whole *"compiles without any dependencies thing"*. See [the mongoose docs TLS page](https://mongoose.ws/tutorials/tls/) for instructions. If you implement this cleanly, like with a special make target, a merge request would be greatly appreciated.
|
Then you could connect to it via your local IPv4 address (such as `192.168.1.12`) or even over the global WAN! However, regarding WAN, i would **strongly** advise against such a careless setup.
|
||||||
|
|
||||||
!!! IMPORTANT
|
!!! IMPORTANT
|
||||||
Tubio does NOT manage sessions or accounts! Everyone using your Tubio instance will see **all your downloads** and vica versa.
|
Tubio does NOT manage sessions or accounts! Everyone using your Tubio instance will see **all your downloads** and vica versa.
|
||||||
|
|
||||||
If you opt for unleashing Tubio on your LAN, i would **strongly** recommend enabling the whitelist! You can do this either in the `config.json` or in /settings. Either way, it is a json-array of strings which represent IPv4 addresses.
|
If you opt for unleashing Tubio on your LAN, i would **strongly** recommend enabling the whitelist! You can do this either in the `config.json` or in /settings. Either way, it is a json-array of strings which represent IPv4 addresses.
|
||||||
|
|
||||||
## Setup (Linux)
|
## Setup (Windows)
|
||||||
1) Clone this repository and build it with cmake
|
#### Install yt-dlp.exe:
|
||||||
2) Create some folder on your system. This will be the installation folder.
|
1) Download the latest Tubio build from [here](https://github.com/Leonetienne/Tubio/releases).
|
||||||
3) In this folder, dump the contents of /Tubio/.
|
2) Create some folder on your pc. This will be the installation folder.
|
||||||
4) Install python3 and then yt-dlp via `pip install yt-dlp`.
|
3) Dump in the contents of the Tubio build you just downloaded.
|
||||||
5) Launch the tubio executable
|
4) Launch vcredist_x86.exe and install it. This will install Microsoft Visual C++ 2010 Redistributable Package (x86) which is needed for dependencies.
|
||||||
6) Enjoy <3
|
5) Launch VC_redist.x64.exe and install it. This will install Microsoft Visual C++ 2015/17/19 Redistributable Package (x64) which is needed to run Tubio.exe
|
||||||
|
6) Launch Tubio.exe
|
||||||
## Frequently Asked Questions
|
7) Navigate to `http://localhost/settings` and click "Update ytdl", as the version Tubio shipped with might be out of date.
|
||||||
### My downloads hang at 99% or 100%
|
8) <Optional>: Set up `Tubio.exe` to launch with windows to have it\`s service always at hand.
|
||||||
This happens as there almost always is some post-processing to do after downloading. Like, audio-extracting and/or video recoding. If you're downloading
|
9) Enjoy <3
|
||||||
a video this may take a while, as it may be converting webm to mp4.
|
|
||||||
|
## Frequently Asked Questions
|
||||||
### My downloads fail!
|
### My downloads hang at 99% or 100%
|
||||||
First thing to do: Verify that are using the latest version of yt-dlp. The team behind its upstream, youtube-dl, are quite fast adjusting the downloading backend to changes in popular platforms, such as youtube. If your downloads still fail,
|
This happens as there often is some post-processing to do after downloading.
|
||||||
verify that yt-dlp is in fact capable of downloading the url you supplied by executing `yt-dlp $url`, replacing `$url` with your url. If this works, you can extract the tubio id of the url you just queued in `/settings`, and then open `<your-tubio-host>/downloadlog/<tubio-id>` to see the output stdout and stderr of the yt-dlp call. Then work from the error messages you see in there.
|
|
||||||
|
### My downloads fail!
|
||||||
If it\`s still not working, you\`re out of luck. :(
|
First thing to do: Navigate to /settings and click "Update ytdl". This will update your local instance of [yt-dlp](https://github.com/yt-dlp/yt-dlp/). Check the logs to see if it worked. If not, you can always download it yourself (from the [releases-page](https://github.com/yt-dlp/yt-dlp/releases) and put yt-dlp.exe in the same directory tubio.exe lies in.).
|
||||||
You may want to check youtube-dl compatible sites.
|
|
||||||
|
If it\`s still not working, you are most likely trying to download a video from a playlist with a weird url. Try a different one (The one from the share button, the one from right-clicking the video or the one from the url-bar in your browser).
|
||||||
### I locked myself out by enabling localhost only on another device!
|
|
||||||
This can only be undone from localhost. Open Tubio via, and this is important, either `localhost` or `127.0.0.1` and untick it again. If you can only ssh into the host, you can edit the `config.json` itself and restart Tubio.
|
If it\`s still not working, you\`re out of luck. :(
|
||||||
|
You may want to check youtube-dl compatible sites.
|
||||||
### Does it work on Windows?
|
|
||||||
Sure it does. You just have to compile it yourself using cmake, and put yt-dlp.exe, ffmpeg.exe, ffplay.exe and ffprobe.exe
|
### I locked myself out by enabling localhost only on another device!
|
||||||
in Tubios working directory (installation directory). You could then just launch it at startup.
|
This can only be undone from localhost. Open Tubio via, and this is important, either `localhost` or `127.0.0.1` and untick it again. If you can only ssh into the host, you can edit the `config.json` itself and restart Tubio.
|
||||||
|
|
||||||
### Can I use it on my phone?
|
### Does it work on linux?
|
||||||
You bet! That's what I'm mainly using it for :) Read [this](#user-content-can-i-use-tubio-on-multiple-devices).
|
Well, technically, yes. You would have to install youtube-dl and the ffmpeg suite yourself, and compile Tubio yourself though. I have not tried it yet, but it should work.
|
||||||
|
You may get warnings for missing .exe files, which are obviously not needed on linux.
|
||||||
### Can I use this to host my own downloader website?
|
|
||||||
On your own risk! Tubio is NOT designed for this! Also do note that tubio does NOT manage sessions or accounts! Everyone accessing this instance can see everyones downloads and access the admin panel! Tubio is really designed for one user!
|
### Can I use it on my phone?
|
||||||
|
Sure. Read [this](#user-content-can-i-use-tubio-on-multiple-devices).
|
||||||
### XY is not working, you have to fix it now!
|
|
||||||
I do not. Tubio is a tool I originally made for myself only. I just thought it\`s nice and worth sharing. I will address issues when I have time. Feel free to submit issues and I will have a look when I get to it. :)
|
### Can i use this to host my own downloader website?
|
||||||
|
On your own risk! Tubio is NOT designed for this! Also do note that tubio does NOT manage sessions or accounts! Everyone accessing this instance can see everyones downloads and access the admin panel! Tubio is really designed for one user!
|
||||||
### XY is not polished enough!
|
|
||||||
This is an alpha-version. What did you expect? :D
|
### XY is not working, you have to fix it now!
|
||||||
|
I do not. Tubio is a tool I originally made for myself only. I just thought it\`s nice and worth sharing. I will address issues when I have time. Feel free to submit issues and I will have a look when I get to it. :)
|
||||||
### Can you please add support for website XY?
|
|
||||||
Please address the awesome team at youtube-dl, as they make the downloading-backend: [github.com/ytdl-org/youtube-dl/issues](https://github.com/ytdl-org/youtube-dl/issues).
|
### XY is not polished enough!
|
||||||
The downloader uses ([yt-dlp](https://github.com/yt-dlp/yt-dlp/)), which is based on youtube-dl.
|
This is an alpha-version. What did you expect? :D
|
||||||
|
|
||||||
## Important notice!
|
### Can you please add support for website XY?
|
||||||
I do NOT endorse illegal downloads in any way, shape, or form. Tubio is a tool to download media from legal sources! Use Tubio at your own discretion! Neither do i provide ANY warranty in ANY way, shape, or form!
|
Please address the awesome team at youtube-dl, as they made the downloading-end: [github.com/ytdl-org/youtube-dl/issues](https://github.com/ytdl-org/youtube-dl/issues).
|
||||||
|
The downloader tubio uses ([yt-dlp](https://github.com/yt-dlp/yt-dlp/)) is based on youtube-dl.
|
||||||
## License
|
|
||||||
Tubio is distributed under the GNU General Public License v3.0.
|
## Important notice!
|
||||||
Please read the [license file](https://gitea.leonetienne.de/leonetienne/Tubio/src/branch/master/LICENSE).
|
I do NOT endorse illegal downloads in any way, shape, or form. Tubio is a tool to download media from legal sources! Use Tubio at your own discretion! Neither do i provide ANY warranty in ANY way, shape, or form!
|
||||||
|
|
||||||
|
## License
|
||||||
|
Tubio is distributed under the GNU General Public License v3.0.
|
||||||
|
Please read the [license file](https://github.com/Leonetienne/Tubio/blob/master/license.txt).
|
||||||
|
31
Tubio.sln
Normal file
31
Tubio.sln
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 16
|
||||||
|
VisualStudioVersion = 16.0.30413.136
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Tubio", "Tubio\Tubio.vcxproj", "{8AE799C5-CB17-4714-A362-D8B9817A723E}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
|
Debug|x86 = Debug|x86
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
Release|x86 = Release|x86
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{8AE799C5-CB17-4714-A362-D8B9817A723E}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{8AE799C5-CB17-4714-A362-D8B9817A723E}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{8AE799C5-CB17-4714-A362-D8B9817A723E}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{8AE799C5-CB17-4714-A362-D8B9817A723E}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{8AE799C5-CB17-4714-A362-D8B9817A723E}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{8AE799C5-CB17-4714-A362-D8B9817A723E}.Release|x64.Build.0 = Release|x64
|
||||||
|
{8AE799C5-CB17-4714-A362-D8B9817A723E}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{8AE799C5-CB17-4714-A362-D8B9817A723E}.Release|x86.Build.0 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {11C6C438-21D5-40CC-9CDC-FBA3AE6634F3}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
@ -49,5 +49,3 @@ add_executable(Tubio
|
|||||||
external_dependencies/leonetienne/stringtools/StringTools.h
|
external_dependencies/leonetienne/stringtools/StringTools.h
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(Tubio pthread)
|
|
||||||
|
|
||||||
|
@ -162,7 +162,7 @@ void DownloadManager::DownloadNext()
|
|||||||
std::string ytdl_call_video_base =
|
std::string ytdl_call_video_base =
|
||||||
"yt-dlp --newline --no-call-home --no-playlist --no-part --no-warnings --socket-timeout 5 --limit-rate $$DL_RATE"
|
"yt-dlp --newline --no-call-home --no-playlist --no-part --no-warnings --socket-timeout 5 --limit-rate $$DL_RATE"
|
||||||
" --no-mtime --no-cache-dir -f \"$$QUALITY\" --recode-video mp4 --prefer-ffmpeg"
|
" --no-mtime --no-cache-dir -f \"$$QUALITY\" --recode-video mp4 --prefer-ffmpeg"
|
||||||
" -o \"$$DL_FILE\" \"$$DL_URL\" > \"$$DL_PROG_BUF_FILE\" 2>&1";
|
" -o \"$$DL_FILE\" \"$$DL_URL\" > \"$$DL_PROG_BUF_FILE\"";
|
||||||
|
|
||||||
// Fill template
|
// Fill template
|
||||||
ytdl_call_video_base = Internal::StringHelpers::Replace(ytdl_call_video_base, "$$QUALITY", DownloadQualityToStringParams(entry->quality));
|
ytdl_call_video_base = Internal::StringHelpers::Replace(ytdl_call_video_base, "$$QUALITY", DownloadQualityToStringParams(entry->quality));
|
||||||
@ -180,7 +180,7 @@ void DownloadManager::DownloadNext()
|
|||||||
std::string ytdl_call_audio_base =
|
std::string ytdl_call_audio_base =
|
||||||
"yt-dlp --newline --no-call-home --no-playlist --no-part --no-warnings --socket-timeout 5 --limit-rate $$DL_RATE"
|
"yt-dlp --newline --no-call-home --no-playlist --no-part --no-warnings --socket-timeout 5 --limit-rate $$DL_RATE"
|
||||||
" --no-mtime --no-cache-dir -f worstvideo+bestaudio --audio-format mp3 --audio-quality 0 --extract-audio -o \"$$DL_FILE\""
|
" --no-mtime --no-cache-dir -f worstvideo+bestaudio --audio-format mp3 --audio-quality 0 --extract-audio -o \"$$DL_FILE\""
|
||||||
" \"$$DL_URL\" > \"$$DL_PROG_BUF_FILE\" 2>&1";
|
" \"$$DL_URL\" > \"$$DL_PROG_BUF_FILE\"";
|
||||||
|
|
||||||
|
|
||||||
// Fill template
|
// Fill template
|
||||||
|
@ -1,307 +1,277 @@
|
|||||||
#include "HttpServer.h"
|
#include "HttpServer.h"
|
||||||
#include "external_dependencies/leonetienne/stringtools/StringTools.h"
|
#include "external_dependencies/leonetienne/stringtools/StringTools.h"
|
||||||
|
|
||||||
using namespace Logging;
|
using namespace Logging;
|
||||||
using namespace Rest;
|
using namespace Rest;
|
||||||
using namespace JasonPP;
|
using namespace JasonPP;
|
||||||
|
|
||||||
HttpServer::HttpServer()
|
HttpServer::HttpServer()
|
||||||
{
|
{
|
||||||
pMgr = new mg_mgr();
|
pMgr = new mg_mgr();
|
||||||
pNc = nullptr;
|
pNc = nullptr;
|
||||||
log = new Logger("HttpServer");
|
log = new Logger("HttpServer");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpServer::~HttpServer()
|
HttpServer::~HttpServer()
|
||||||
{
|
{
|
||||||
delete pMgr;
|
delete pMgr;
|
||||||
delete log;
|
delete log;
|
||||||
|
|
||||||
log = nullptr;
|
log = nullptr;
|
||||||
pMgr = nullptr;
|
pMgr = nullptr;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HttpServer::PostInit()
|
void HttpServer::PostInit()
|
||||||
{
|
{
|
||||||
isBootedSuccessfully = InitWebServer();
|
isBootedSuccessfully = InitWebServer();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HttpServer::InitWebServer()
|
bool HttpServer::InitWebServer()
|
||||||
{
|
{
|
||||||
mg_mgr_init(pMgr, NULL);
|
mg_mgr_init(pMgr, NULL);
|
||||||
|
|
||||||
log->cout << "Starting http-server on port " << XGConfig::httpServer.port << "...";
|
log->cout << "Starting http-server on port " << XGConfig::httpServer.port << "...";
|
||||||
log->Flush();
|
log->Flush();
|
||||||
|
|
||||||
pNc = mg_bind(pMgr, XGConfig::httpServer.port.c_str(), this->EventHandler);
|
pNc = mg_bind(pMgr, XGConfig::httpServer.port.c_str(), this->EventHandler);
|
||||||
|
|
||||||
if (pNc == NULL)
|
if (pNc == NULL)
|
||||||
{
|
{
|
||||||
log->cout << log->Err() << "Failed to boot the http-server! - Unable to bind listener! (port: " << XGConfig::httpServer.port << ")";
|
log->cout << log->Err() << "Failed to boot the http-server! - Unable to bind listener! (port: " << XGConfig::httpServer.port << ")";
|
||||||
log->Flush();
|
log->Flush();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
mg_set_protocol_http_websocket(pNc);
|
mg_set_protocol_http_websocket(pNc);
|
||||||
frontend_serve_opts.document_root = XGConfig::httpServer.rootdir.c_str();
|
frontend_serve_opts.document_root = XGConfig::httpServer.rootdir.c_str();
|
||||||
frontend_serve_opts.enable_directory_listing = "no";
|
frontend_serve_opts.enable_directory_listing = "no";
|
||||||
|
|
||||||
log->cout << "Started http-server successfully!";
|
log->cout << "Started http-server successfully!";
|
||||||
log->Flush();
|
log->Flush();
|
||||||
isBootedSuccessfully = true;
|
isBootedSuccessfully = true;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HttpServer::Update()
|
void HttpServer::Update()
|
||||||
{
|
{
|
||||||
mg_mgr_poll(pMgr, XGConfig::httpServer.polling_rate);
|
mg_mgr_poll(pMgr, XGConfig::httpServer.polling_rate);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HttpServer::ServeStringToConnection(struct mg_connection* c, std::string str, int httpStatusCode)
|
void HttpServer::ServeStringToConnection(struct mg_connection* c, std::string str, int httpStatusCode)
|
||||||
{
|
{
|
||||||
mg_send_head(c, httpStatusCode, str.length(), "content-type: application/json\nAccess-Control-Allow-Origin: *");
|
mg_send_head(c, httpStatusCode, str.length(), "content-type: application/json\nAccess-Control-Allow-Origin: *");
|
||||||
mg_printf(c, "%s", str.c_str());
|
mg_printf(c, "%s", str.c_str());
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HttpServer::EventHandler(mg_connection* pNc, int ev, void* p)
|
void HttpServer::EventHandler(mg_connection* pNc, int ev, void* p)
|
||||||
{
|
{
|
||||||
switch (ev)
|
switch (ev)
|
||||||
{
|
{
|
||||||
case MG_EV_HTTP_REQUEST:
|
case MG_EV_HTTP_REQUEST:
|
||||||
// Reset standby timer
|
// Reset standby timer
|
||||||
XGControl::last_query_time = time(0);
|
XGControl::last_query_time = time(0);
|
||||||
|
|
||||||
http_message* hpm = (http_message*)p;
|
http_message* hpm = (http_message*)p;
|
||||||
std::string requestedUri = FixUnterminatedString(hpm->uri.p, hpm->uri.len);
|
std::string requestedUri = FixUnterminatedString(hpm->uri.p, hpm->uri.len);
|
||||||
|
|
||||||
// Get clients ip address
|
// Get clients ip address
|
||||||
std::string peer_addr;
|
std::string peer_addr;
|
||||||
{
|
{
|
||||||
char buf[32];
|
char buf[32];
|
||||||
mg_sock_addr_to_str(&pNc->sa, buf, sizeof(buf), MG_SOCK_STRINGIFY_IP);
|
mg_sock_addr_to_str(&pNc->sa, buf, sizeof(buf), MG_SOCK_STRINGIFY_IP);
|
||||||
peer_addr = buf;
|
peer_addr = buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string denialReason;
|
std::string denialReason;
|
||||||
if (IsConnectionAllowed(peer_addr, denialReason))
|
if (IsConnectionAllowed(peer_addr, denialReason))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (requestedUri == "/api")
|
if (requestedUri == "/api")
|
||||||
{
|
{
|
||||||
ProcessAPIRequest(pNc, ev, p, peer_addr);
|
ProcessAPIRequest(pNc, ev, p, peer_addr);
|
||||||
}
|
}
|
||||||
else if (requestedUri.substr(0, 12) == "/downloadlog")
|
else if (requestedUri.substr(0, 9) == "/download")
|
||||||
{
|
{
|
||||||
ServeDownloadLog(pNc, ev, p, requestedUri);
|
ServeDownloadeableResource(pNc, ev, p, requestedUri);
|
||||||
}
|
}
|
||||||
else if (requestedUri.substr(0, 9) == "/download")
|
else
|
||||||
{
|
{
|
||||||
ServeDownloadeableResource(pNc, ev, p, requestedUri);
|
// Just serve the files requested
|
||||||
}
|
mg_serve_http(pNc, (struct http_message*)p, frontend_serve_opts);
|
||||||
else
|
}
|
||||||
{
|
}
|
||||||
// Just serve the files requested
|
catch (std::exception& e)
|
||||||
mg_serve_http(pNc, (struct http_message*)p, frontend_serve_opts);
|
{
|
||||||
}
|
Json j;
|
||||||
}
|
j.CloneFrom(RestResponseTemplates::GetByCode(HTTP_STATUS_CODE::INTERNAL_SERVER_ERROR, e.what()));
|
||||||
catch (std::exception& e)
|
ServeStringToConnection(pNc, j.Render(), (int)HTTP_STATUS_CODE::INTERNAL_SERVER_ERROR);
|
||||||
{
|
}
|
||||||
Json j;
|
catch (...)
|
||||||
j.CloneFrom(RestResponseTemplates::GetByCode(HTTP_STATUS_CODE::INTERNAL_SERVER_ERROR, e.what()));
|
{
|
||||||
ServeStringToConnection(pNc, j.Render(), (int)HTTP_STATUS_CODE::INTERNAL_SERVER_ERROR);
|
Json j;
|
||||||
}
|
j.CloneFrom(RestResponseTemplates::GetByCode(HTTP_STATUS_CODE::INTERNAL_SERVER_ERROR, "Das not good"));
|
||||||
catch (...)
|
ServeStringToConnection(pNc, j.Render(), (int)HTTP_STATUS_CODE::INTERNAL_SERVER_ERROR);
|
||||||
{
|
}
|
||||||
Json j;
|
|
||||||
j.CloneFrom(RestResponseTemplates::GetByCode(HTTP_STATUS_CODE::INTERNAL_SERVER_ERROR, "Das not good"));
|
break;
|
||||||
ServeStringToConnection(pNc, j.Render(), (int)HTTP_STATUS_CODE::INTERNAL_SERVER_ERROR);
|
}
|
||||||
}
|
else // Client is not allowed, serve error json
|
||||||
|
{
|
||||||
break;
|
Json j;
|
||||||
}
|
j.CloneFrom(RestResponseTemplates::GetByCode(HTTP_STATUS_CODE::UNAUTHORIZED, denialReason));
|
||||||
else // Client is not allowed, serve error json
|
ServeStringToConnection(pNc, j.Render(), (int)HTTP_STATUS_CODE::UNAUTHORIZED);
|
||||||
{
|
}
|
||||||
Json j;
|
}
|
||||||
j.CloneFrom(RestResponseTemplates::GetByCode(HTTP_STATUS_CODE::UNAUTHORIZED, denialReason));
|
|
||||||
ServeStringToConnection(pNc, j.Render(), (int)HTTP_STATUS_CODE::UNAUTHORIZED);
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
std::string HttpServer::SanitizeString(std::string in) {
|
||||||
return;
|
in = StringTools::Replace(in, '`', "\\\\`");
|
||||||
}
|
in = StringTools::Replace(in, '|', "\\\\|");
|
||||||
|
in = StringTools::Replace(in, '$', "\\\\$");
|
||||||
std::string HttpServer::SanitizeString(std::string in) {
|
in = StringTools::Replace(in, "&&", "\\\\&\\\\&");
|
||||||
in = StringTools::Replace(in, '`', "\\\\`");
|
|
||||||
in = StringTools::Replace(in, '|', "\\\\|");
|
return in;
|
||||||
in = StringTools::Replace(in, '$', "\\\\$");
|
}
|
||||||
in = StringTools::Replace(in, "&&", "\\\\&\\\\&");
|
|
||||||
in = StringTools::Replace(in, ";", "\\\\;");
|
void HttpServer::ProcessAPIRequest(mg_connection* pNc, int ev, void* p, std::string peerAddress)
|
||||||
|
{
|
||||||
return in;
|
// Get struct with http message informations
|
||||||
}
|
http_message* hpm = (http_message*)p;
|
||||||
|
|
||||||
void HttpServer::ProcessAPIRequest(mg_connection* pNc, int ev, void* p, std::string peerAddress)
|
// Get the transmitted message body
|
||||||
{
|
std::string requestBodyRaw = FixUnterminatedString(hpm->body.p, hpm->body.len);
|
||||||
// Get struct with http message informations
|
|
||||||
http_message* hpm = (http_message*)p;
|
// Sanitize it
|
||||||
|
requestBodyRaw = SanitizeString(requestBodyRaw);
|
||||||
// Get the transmitted message body
|
|
||||||
std::string requestBodyRaw = FixUnterminatedString(hpm->body.p, hpm->body.len);
|
// Check for the body being valid json
|
||||||
|
if (IsJsonValid(requestBodyRaw))
|
||||||
// Sanitize it
|
{
|
||||||
requestBodyRaw = SanitizeString(requestBodyRaw);
|
Json requestBody;
|
||||||
|
requestBody.Parse(requestBodyRaw);
|
||||||
// Check for the body being valid json
|
|
||||||
if (IsJsonValid(requestBodyRaw))
|
|
||||||
{
|
|
||||||
Json requestBody;
|
JsonBlock responseBody;
|
||||||
requestBody.Parse(requestBodyRaw);
|
HTTP_STATUS_CODE returnCode;
|
||||||
|
RestQueryHandler::ProcessQuery(peerAddress, requestBody, responseBody, returnCode);
|
||||||
|
|
||||||
|
Json response(responseBody);
|
||||||
JsonBlock responseBody;
|
ServeStringToConnection(pNc, response.Render(), (int)returnCode);
|
||||||
HTTP_STATUS_CODE returnCode;
|
}
|
||||||
RestQueryHandler::ProcessQuery(peerAddress, requestBody, responseBody, returnCode);
|
else // return error message for invalid json
|
||||||
|
{
|
||||||
Json response(responseBody);
|
Json errorJson;
|
||||||
ServeStringToConnection(pNc, response.Render(), (int)returnCode);
|
errorJson.CloneFrom(RestResponseTemplates::GetByCode(HTTP_STATUS_CODE::BAD_REQUEST, "Received json is fucked"));
|
||||||
}
|
ServeStringToConnection(pNc, errorJson.Render(), (int)HTTP_STATUS_CODE::BAD_REQUEST);
|
||||||
else // return error message for invalid json
|
}
|
||||||
{
|
|
||||||
Json errorJson;
|
return;
|
||||||
errorJson.CloneFrom(RestResponseTemplates::GetByCode(HTTP_STATUS_CODE::BAD_REQUEST, "Received json is fucked"));
|
}
|
||||||
ServeStringToConnection(pNc, errorJson.Render(), (int)HTTP_STATUS_CODE::BAD_REQUEST);
|
|
||||||
}
|
void HttpServer::ServeDownloadeableResource(mg_connection* pNc, int ev, void* p, std::string uri)
|
||||||
|
{
|
||||||
return;
|
std::string fileId = uri.substr(10, uri.length() - 10);
|
||||||
}
|
|
||||||
|
if (Downloader::DownloadManager::DoesTubioIDExist(fileId))
|
||||||
void HttpServer::ServeDownloadeableResource(mg_connection* pNc, int ev, void* p, std::string uri)
|
{
|
||||||
{
|
Downloader::DownloadEntry& entry = Downloader::DownloadManager::GetDownloadEntryByTubioID(fileId);
|
||||||
std::string fileId = uri.substr(10, uri.length() - 10);
|
|
||||||
|
if (entry.status == Downloader::DOWNLOAD_STATUS::FINISHED)
|
||||||
if (Downloader::DownloadManager::DoesTubioIDExist(fileId))
|
{
|
||||||
{
|
std::stringstream ss;
|
||||||
Downloader::DownloadEntry& entry = Downloader::DownloadManager::GetDownloadEntryByTubioID(fileId);
|
std::string downloadedFilename = entry.title + (entry.mode == Downloader::DOWNLOAD_MODE::AUDIO ? ".mp3" : ".mp4");
|
||||||
|
|
||||||
if (entry.status == Downloader::DOWNLOAD_STATUS::FINISHED)
|
ss << "Access-Control-Allow-Origin: *\nContent-Disposition: attachment; filename=\"" << downloadedFilename << "\"\nPragma: public\nCache-Control: must-revalidate, post-check=0, pre-check=0";
|
||||||
{
|
mg_http_serve_file(pNc, (http_message*)p, entry.downloaded_filename.c_str(), mg_mk_str("application/octet-stream"), mg_mk_str(ss.str().c_str()));
|
||||||
std::stringstream ss;
|
}
|
||||||
std::string downloadedFilename = entry.title + (entry.mode == Downloader::DOWNLOAD_MODE::AUDIO ? ".mp3" : ".mp4");
|
else
|
||||||
|
{
|
||||||
ss << "Access-Control-Allow-Origin: *\nContent-Disposition: attachment; filename=\"" << downloadedFilename << "\"\nPragma: public\nCache-Control: must-revalidate, post-check=0, pre-check=0";
|
Json j;
|
||||||
mg_http_serve_file(pNc, (http_message*)p, entry.downloaded_filename.c_str(), mg_mk_str("application/octet-stream"), mg_mk_str(ss.str().c_str()));
|
j.CloneFrom(RestResponseTemplates::GetByCode(HTTP_STATUS_CODE::BAD_REQUEST, "File download not ready!"));
|
||||||
}
|
ServeStringToConnection(pNc, j.Render(), (int)HTTP_STATUS_CODE::BAD_REQUEST);
|
||||||
else
|
}
|
||||||
{
|
}
|
||||||
Json j;
|
else
|
||||||
j.CloneFrom(RestResponseTemplates::GetByCode(HTTP_STATUS_CODE::BAD_REQUEST, "File download not ready!"));
|
{
|
||||||
ServeStringToConnection(pNc, j.Render(), (int)HTTP_STATUS_CODE::BAD_REQUEST);
|
Json j;
|
||||||
}
|
j.CloneFrom(RestResponseTemplates::GetByCode(HTTP_STATUS_CODE::BAD_REQUEST, "Invalid tubio id!"));
|
||||||
}
|
ServeStringToConnection(pNc, j.Render(), (int)HTTP_STATUS_CODE::BAD_REQUEST);
|
||||||
else
|
}
|
||||||
{
|
|
||||||
Json j;
|
return;
|
||||||
j.CloneFrom(RestResponseTemplates::GetByCode(HTTP_STATUS_CODE::BAD_REQUEST, "Invalid tubio id!"));
|
}
|
||||||
ServeStringToConnection(pNc, j.Render(), (int)HTTP_STATUS_CODE::BAD_REQUEST);
|
|
||||||
}
|
bool HttpServer::IsConnectionAllowed(std::string peer_address, std::string& denialReason)
|
||||||
|
{
|
||||||
return;
|
// Localhost is always allowed!
|
||||||
}
|
if (peer_address == "127.0.0.1") return true;
|
||||||
|
|
||||||
void HttpServer::ServeDownloadLog(mg_connection* pNc, int ev, void* p, std::string uri)
|
// Peer is not localhost, but only localhost is allowed!
|
||||||
{
|
else if (XGConfig::access.only_allow_localhost)
|
||||||
std::string fileId = uri.substr(13, uri.length() - 13);
|
{
|
||||||
|
denialReason = "Only localhost allowed!";
|
||||||
if (Downloader::DownloadManager::DoesTubioIDExist(fileId))
|
return false;
|
||||||
{
|
}
|
||||||
Downloader::DownloadEntry& entry = Downloader::DownloadManager::GetDownloadEntryByTubioID(fileId);
|
|
||||||
|
// Let's check if the whitelist is active
|
||||||
std::stringstream ss;
|
else if (XGConfig::access.enable_whitelist)
|
||||||
std::string logFilename = std::string("./dlcache/dlprogbuf/") + fileId + ".buf";
|
{
|
||||||
|
// It is. Let's check if our peer is whitelisted
|
||||||
ss << "Access-Control-Allow-Origin: *\nContent-Type: text/plain; Cache-Control: must-revalidate, post-check=0, pre-check=0";
|
for (std::size_t i = 0; i < XGConfig::access.whitelist.size(); i++)
|
||||||
mg_http_serve_file(pNc, (http_message*)p, logFilename.c_str(), mg_mk_str("text/plain"), mg_mk_str(ss.str().c_str()));
|
{
|
||||||
}
|
// Whitelist is enabled, and peer is whitelisted
|
||||||
else
|
if (XGConfig::access.whitelist[i] == peer_address) return true;
|
||||||
{
|
}
|
||||||
Json j;
|
|
||||||
std::stringstream ss;
|
// Whitelist is enabled, but peer is NOT whitelisted
|
||||||
j.CloneFrom(RestResponseTemplates::GetByCode(HTTP_STATUS_CODE::BAD_REQUEST, "Invalid tubio id!"));
|
denialReason = std::string("Not whitelisted! Ask your tubio administrator to whitelist '") + peer_address + "' in order to gain access.";
|
||||||
ServeStringToConnection(pNc, j.Render(), (int)HTTP_STATUS_CODE::BAD_REQUEST);
|
return false;
|
||||||
}
|
}
|
||||||
|
else // Whitelist is NOT enabled and only_allow_localhost is FALSE!
|
||||||
return;
|
{
|
||||||
}
|
return true;
|
||||||
|
}
|
||||||
bool HttpServer::IsConnectionAllowed(std::string peer_address, std::string& denialReason)
|
|
||||||
{
|
// Should never come to this point
|
||||||
// Localhost is always allowed!
|
denialReason = "Access denied";
|
||||||
if (peer_address == "127.0.0.1") return true;
|
return false;
|
||||||
|
}
|
||||||
// Peer is not localhost, but only localhost is allowed!
|
|
||||||
else if (XGConfig::access.only_allow_localhost)
|
void HttpServer::OnExit()
|
||||||
{
|
{
|
||||||
denialReason = "Only localhost allowed!";
|
log->cout << "Shutting down http-server...";
|
||||||
return false;
|
log->Flush();
|
||||||
}
|
|
||||||
|
mg_mgr_free(pMgr);
|
||||||
// Let's check if the whitelist is active
|
|
||||||
else if (XGConfig::access.enable_whitelist)
|
return;
|
||||||
{
|
}
|
||||||
// It is. Let's check if our peer is whitelisted
|
|
||||||
for (std::size_t i = 0; i < XGConfig::access.whitelist.size(); i++)
|
|
||||||
{
|
std::string HttpServer::FixUnterminatedString(const char* cstr, const std::size_t len)
|
||||||
// Whitelist is enabled, and peer is whitelisted
|
{
|
||||||
if (XGConfig::access.whitelist[i] == peer_address) return true;
|
std::stringstream ss;
|
||||||
}
|
for (std::size_t i = 0; i < len; i++)
|
||||||
|
{
|
||||||
// Whitelist is enabled, but peer is NOT whitelisted
|
ss << *(cstr + i);
|
||||||
denialReason = std::string("Not whitelisted! Ask your tubio administrator to whitelist '") + peer_address + "' in order to gain access.";
|
}
|
||||||
return false;
|
|
||||||
}
|
return ss.str();
|
||||||
else // Whitelist is NOT enabled and only_allow_localhost is FALSE!
|
}
|
||||||
{
|
|
||||||
return true;
|
mg_serve_http_opts HttpServer::frontend_serve_opts;
|
||||||
}
|
|
||||||
|
|
||||||
// Should never come to this point
|
|
||||||
denialReason = "Access denied";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void HttpServer::OnExit()
|
|
||||||
{
|
|
||||||
log->cout << "Shutting down http-server...";
|
|
||||||
log->Flush();
|
|
||||||
|
|
||||||
mg_mgr_free(pMgr);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::string HttpServer::FixUnterminatedString(const char* cstr, const std::size_t len)
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
for (std::size_t i = 0; i < len; i++)
|
|
||||||
{
|
|
||||||
ss << *(cstr + i);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
mg_serve_http_opts HttpServer::frontend_serve_opts;
|
|
||||||
|
@ -24,7 +24,6 @@ namespace Rest
|
|||||||
bool InitWebServer();
|
bool InitWebServer();
|
||||||
static void ProcessAPIRequest(struct mg_connection* pNc, int ev, void* p, std::string peerAddress);
|
static void ProcessAPIRequest(struct mg_connection* pNc, int ev, void* p, std::string peerAddress);
|
||||||
static void ServeDownloadeableResource(struct mg_connection* pNc, int ev, void* p, std::string uri);
|
static void ServeDownloadeableResource(struct mg_connection* pNc, int ev, void* p, std::string uri);
|
||||||
static void ServeDownloadLog(struct mg_connection* pNc, int ev, void* p, std::string uri);
|
|
||||||
|
|
||||||
static void EventHandler(struct mg_connection* pNc, int ev, void* p);
|
static void EventHandler(struct mg_connection* pNc, int ev, void* p);
|
||||||
static void ServeStringToConnection(struct mg_connection* c, std::string str, int httpStatusCode = 200);
|
static void ServeStringToConnection(struct mg_connection* c, std::string str, int httpStatusCode = 200);
|
||||||
|
@ -115,11 +115,11 @@ bool RestQueryHandler::QueueDownload(const JsonBlock& request, JsonBlock& respon
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string tubId = DownloadManager::QueueDownload(videoUrl, mode, quality);
|
log->cout << "Queued video \"" << videoUrl << "\"...";
|
||||||
|
|
||||||
log->cout << "Queued video \"" << videoUrl << "\" with id \"" << tubId << "\"...";
|
|
||||||
log->Flush();
|
log->Flush();
|
||||||
|
|
||||||
|
std::string tubId = DownloadManager::QueueDownload(videoUrl, mode, quality);
|
||||||
|
|
||||||
responseCode = HTTP_STATUS_CODE::OK;
|
responseCode = HTTP_STATUS_CODE::OK;
|
||||||
responseBody.CloneFrom(RestResponseTemplates::GetByCode(HTTP_STATUS_CODE::OK));
|
responseBody.CloneFrom(RestResponseTemplates::GetByCode(HTTP_STATUS_CODE::OK));
|
||||||
responseBody.Set("message") = "Download queued!";
|
responseBody.Set("message") = "Download queued!";
|
||||||
|
195
Tubio/Tubio.vcxproj
Normal file
195
Tubio/Tubio.vcxproj
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<VCProjectVersion>16.0</VCProjectVersion>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<ProjectGuid>{8ae799c5-cb17-4714-a362-d8b9817a723e}</ProjectGuid>
|
||||||
|
<RootNamespace>Tubio</RootNamespace>
|
||||||
|
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="Shared">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>_WIN;JASONPP_RENDER_SORTED;_WIN32;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalDependencies>urlmon.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>_WIN;JASONPP_RENDER_SORTED;_WIN32;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalDependencies>urlmon.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>_WIN;JASONPP_RENDER_SORTED;_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalDependencies>urlmon.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>_WIN;JASONPP_RENDER_SORTED;_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalDependencies>urlmon.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="ConsoleManager.cpp" />
|
||||||
|
<ClCompile Include="DownloadManager.cpp" />
|
||||||
|
<ClCompile Include="external_dependencies\casenta\mongoose\mongoose.c">
|
||||||
|
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">TurnOffAllWarnings</WarningLevel>
|
||||||
|
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">TurnOffAllWarnings</WarningLevel>
|
||||||
|
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">TurnOffAllWarnings</WarningLevel>
|
||||||
|
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">TurnOffAllWarnings</WarningLevel>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="external_dependencies\leonetienne\JasonPP\JasonPP.cpp" />
|
||||||
|
<ClCompile Include="FileSystem.cpp" />
|
||||||
|
<ClCompile Include="Framework.cpp" />
|
||||||
|
<ClCompile Include="Idler.cpp" />
|
||||||
|
<ClCompile Include="Logger.cpp" />
|
||||||
|
<ClCompile Include="LogHistory.cpp" />
|
||||||
|
<ClCompile Include="main.cpp" />
|
||||||
|
<ClCompile Include="RestQueryHandler.cpp" />
|
||||||
|
<ClCompile Include="RestResponseTemplates.cpp" />
|
||||||
|
<ClCompile Include="HttpServer.cpp" />
|
||||||
|
<ClCompile Include="Updater.cpp" />
|
||||||
|
<ClCompile Include="XGConfig.cpp" />
|
||||||
|
<ClCompile Include="XGControl.cpp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="ConsoleManager.h" />
|
||||||
|
<ClInclude Include="DownloadManager.h" />
|
||||||
|
<ClInclude Include="external_dependencies\casenta\mongoose\mongoose.h" />
|
||||||
|
<ClInclude Include="external_dependencies\leonetienne\JasonPP\JasonPP.hpp" />
|
||||||
|
<ClInclude Include="FileSystem.h" />
|
||||||
|
<ClInclude Include="Framework.h" />
|
||||||
|
<ClInclude Include="Idler.h" />
|
||||||
|
<ClInclude Include="Logger.h" />
|
||||||
|
<ClInclude Include="LogHistory.h" />
|
||||||
|
<ClInclude Include="LogTypes.h" />
|
||||||
|
<ClInclude Include="RestQueryHandler.h" />
|
||||||
|
<ClInclude Include="RestResponseTemplates.h" />
|
||||||
|
<ClInclude Include="HttpServer.h" />
|
||||||
|
<ClInclude Include="TimeUnits.h" />
|
||||||
|
<ClInclude Include="Updater.h" />
|
||||||
|
<ClInclude Include="Version.h" />
|
||||||
|
<ClInclude Include="XGConfig.h" />
|
||||||
|
<ClInclude Include="XGControl.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
126
Tubio/Tubio.vcxproj.filters
Normal file
126
Tubio/Tubio.vcxproj.filters
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="Quelldateien">
|
||||||
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Headerdateien">
|
||||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
|
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Ressourcendateien">
|
||||||
|
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||||
|
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="_external_dependencies">
|
||||||
|
<UniqueIdentifier>{714ac1f3-3586-412c-9b83-bf00f08d58ab}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="main.cpp">
|
||||||
|
<Filter>Quelldateien</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Logger.cpp">
|
||||||
|
<Filter>Quelldateien</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="LogHistory.cpp">
|
||||||
|
<Filter>Quelldateien</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Framework.cpp">
|
||||||
|
<Filter>Quelldateien</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="RestResponseTemplates.cpp">
|
||||||
|
<Filter>Quelldateien</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="RestQueryHandler.cpp">
|
||||||
|
<Filter>Quelldateien</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="XGControl.cpp">
|
||||||
|
<Filter>Quelldateien</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="XGConfig.cpp">
|
||||||
|
<Filter>Quelldateien</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="FileSystem.cpp">
|
||||||
|
<Filter>Quelldateien</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="HttpServer.cpp">
|
||||||
|
<Filter>Quelldateien</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="DownloadManager.cpp">
|
||||||
|
<Filter>Quelldateien</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ConsoleManager.cpp">
|
||||||
|
<Filter>Quelldateien</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="external_dependencies\casenta\mongoose\mongoose.c">
|
||||||
|
<Filter>_external_dependencies</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="external_dependencies\leonetienne\JasonPP\JasonPP.cpp">
|
||||||
|
<Filter>_external_dependencies</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Updater.cpp">
|
||||||
|
<Filter>Quelldateien</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Idler.cpp">
|
||||||
|
<Filter>Quelldateien</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="Logger.h">
|
||||||
|
<Filter>Headerdateien</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="LogHistory.h">
|
||||||
|
<Filter>Headerdateien</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="LogTypes.h">
|
||||||
|
<Filter>Headerdateien</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Framework.h">
|
||||||
|
<Filter>Headerdateien</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="RestResponseTemplates.h">
|
||||||
|
<Filter>Headerdateien</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="RestQueryHandler.h">
|
||||||
|
<Filter>Headerdateien</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="XGControl.h">
|
||||||
|
<Filter>Headerdateien</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="XGConfig.h">
|
||||||
|
<Filter>Headerdateien</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="FileSystem.h">
|
||||||
|
<Filter>Headerdateien</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="HttpServer.h">
|
||||||
|
<Filter>Headerdateien</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="DownloadManager.h">
|
||||||
|
<Filter>Headerdateien</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="ConsoleManager.h">
|
||||||
|
<Filter>Headerdateien</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="external_dependencies\casenta\mongoose\mongoose.h">
|
||||||
|
<Filter>_external_dependencies</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="external_dependencies\leonetienne\JasonPP\JasonPP.hpp">
|
||||||
|
<Filter>_external_dependencies</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Updater.h">
|
||||||
|
<Filter>Headerdateien</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Idler.h">
|
||||||
|
<Filter>Headerdateien</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="TimeUnits.h">
|
||||||
|
<Filter>Headerdateien</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Version.h">
|
||||||
|
<Filter>Headerdateien</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
@ -1,2 +1,2 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#define TUBIO_SERVER_VERSION (0.66)
|
#define TUBIO_SERVER_VERSION (0.65)
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
# Chrome Extension for Tubio
|
# Chrome Extension for Tubio
|
||||||
Authors note:
|
|
||||||
Since I am no longer using chromium, this is no longer maintained.
|
|
||||||
|
|
||||||
Adds a context-menu and a popup to download videos instantly.
|
Adds a context-menu and a popup to download videos instantly.
|
||||||
It does not open Tubio for you. It just downloads the videos. But you can click a button in the extensions popup that takes you to Tubio.
|
It does not open Tubio for you. It just downloads the videos. But you can click a button in the extensions popup that takes you to Tubio.
|
||||||
|
|
||||||
For now this is not on the chrome store, but you can easily install unlisted extensions from source as shown [here](https://developer.chrome.com/docs/extensions/mv2/faq/#:~:text=Click%20the%20Chrome%20menu%20icon,a%20packaged%20extension%2C%20and%20more.).
|
For now this is not on the chrome store, but you can easily install unlisted extensions from source as shown [here](https://developer.chrome.com/docs/extensions/mv2/faq/#:~:text=Click%20the%20Chrome%20menu%20icon,a%20packaged%20extension%2C%20and%20more.).
|
||||||
|
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
FROM debian
|
|
||||||
MAINTAINER Leon Etienne
|
|
||||||
|
|
||||||
RUN apt-get update
|
|
||||||
|
|
||||||
RUN apt-get install -y \
|
|
||||||
python3 \
|
|
||||||
python3-pip
|
|
||||||
|
|
||||||
RUN pip install \
|
|
||||||
yt-dlp
|
|
||||||
|
|
||||||
RUN apt-get install -y \
|
|
||||||
ffmpeg
|
|
||||||
|
|
||||||
COPY ./entrypoint.sh /app/entrypoint.sh
|
|
||||||
RUN chmod +x /app/entrypoint.sh
|
|
||||||
|
|
||||||
WORKDIR /app/
|
|
||||||
|
|
||||||
ENTRYPOINT ["/app/entrypoint.sh"]
|
|
||||||
CMD ["./Tubio"]
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
|||||||
# Dockerfiles
|
|
||||||
Here are basic dockerfiles to get an image running.
|
|
||||||
They are expected (all three) to be lying within the same directory as the Tubio executable.
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
|||||||
version: '3'
|
|
||||||
|
|
||||||
services:
|
|
||||||
main:
|
|
||||||
build: .
|
|
||||||
restart: always
|
|
||||||
container_name: tubio
|
|
||||||
volumes:
|
|
||||||
- .:/app
|
|
||||||
- /etc/timezone:/etc/timezone:ro
|
|
||||||
- /etc/localtime:/etc/localtime:ro
|
|
||||||
|
|
||||||
ports:
|
|
||||||
- 80:80
|
|
||||||
|
|
||||||
environment:
|
|
||||||
- TZ=Europe/Berlin
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
cd instance
|
|
||||||
exec $@
|
|
||||||
|
|
@ -6297,9 +6297,9 @@ minimist-options@4.1.0:
|
|||||||
kind-of "^6.0.3"
|
kind-of "^6.0.3"
|
||||||
|
|
||||||
minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5:
|
minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5:
|
||||||
version "1.2.5"
|
version "1.2.6"
|
||||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
|
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
|
||||||
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
|
integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
|
||||||
|
|
||||||
minipass-collect@^1.0.2:
|
minipass-collect@^1.0.2:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user