Added list of supported players with flag overrides and checks for support, reformatted code, added .editorconfig
This commit is contained in:
@@ -2,12 +2,12 @@
|
|||||||
Language: Cpp
|
Language: Cpp
|
||||||
# BasedOnStyle: LLVM
|
# BasedOnStyle: LLVM
|
||||||
AccessModifierOffset: -2
|
AccessModifierOffset: -2
|
||||||
AlignAfterOpenBracket: Align
|
AlignAfterOpenBracket: AlwaysBreak
|
||||||
AlignConsecutiveMacros: false
|
AlignConsecutiveMacros: true
|
||||||
AlignConsecutiveAssignments: false
|
AlignConsecutiveAssignments: false
|
||||||
AlignConsecutiveBitFields: false
|
AlignConsecutiveBitFields: false
|
||||||
AlignConsecutiveDeclarations: false
|
AlignConsecutiveDeclarations: false
|
||||||
AlignEscapedNewlines: Right
|
AlignEscapedNewlines: Left
|
||||||
AlignOperands: Align
|
AlignOperands: Align
|
||||||
AlignTrailingComments: true
|
AlignTrailingComments: true
|
||||||
AllowAllArgumentsOnNextLine: true
|
AllowAllArgumentsOnNextLine: true
|
||||||
@@ -29,7 +29,7 @@ BinPackParameters: true
|
|||||||
BraceWrapping:
|
BraceWrapping:
|
||||||
AfterCaseLabel: false
|
AfterCaseLabel: false
|
||||||
AfterClass: false
|
AfterClass: false
|
||||||
AfterControlStatement: Never
|
AfterControlStatement: false
|
||||||
AfterEnum: false
|
AfterEnum: false
|
||||||
AfterFunction: false
|
AfterFunction: false
|
||||||
AfterNamespace: false
|
AfterNamespace: false
|
||||||
@@ -48,10 +48,10 @@ BraceWrapping:
|
|||||||
BreakBeforeBinaryOperators: None
|
BreakBeforeBinaryOperators: None
|
||||||
BreakBeforeBraces: Attach
|
BreakBeforeBraces: Attach
|
||||||
BreakBeforeInheritanceComma: false
|
BreakBeforeInheritanceComma: false
|
||||||
BreakInheritanceList: BeforeColon
|
BreakInheritanceList: AfterColon
|
||||||
BreakBeforeTernaryOperators: true
|
BreakBeforeTernaryOperators: false
|
||||||
BreakConstructorInitializersBeforeComma: false
|
BreakConstructorInitializersBeforeComma: false
|
||||||
BreakConstructorInitializers: BeforeColon
|
BreakConstructorInitializers: AfterColon
|
||||||
BreakAfterJavaFieldAnnotations: false
|
BreakAfterJavaFieldAnnotations: false
|
||||||
BreakStringLiterals: true
|
BreakStringLiterals: true
|
||||||
ColumnLimit: 80
|
ColumnLimit: 80
|
||||||
@@ -60,7 +60,7 @@ CompactNamespaces: false
|
|||||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||||
ConstructorInitializerIndentWidth: 4
|
ConstructorInitializerIndentWidth: 4
|
||||||
ContinuationIndentWidth: 4
|
ContinuationIndentWidth: 4
|
||||||
Cpp11BracedListStyle: true
|
Cpp11BracedListStyle: false
|
||||||
DeriveLineEnding: true
|
DeriveLineEnding: true
|
||||||
DerivePointerAlignment: false
|
DerivePointerAlignment: false
|
||||||
DisableFormat: false
|
DisableFormat: false
|
||||||
@@ -70,7 +70,7 @@ ForEachMacros:
|
|||||||
- foreach
|
- foreach
|
||||||
- Q_FOREACH
|
- Q_FOREACH
|
||||||
- BOOST_FOREACH
|
- BOOST_FOREACH
|
||||||
IncludeBlocks: Preserve
|
IncludeBlocks: Regroup
|
||||||
IncludeCategories:
|
IncludeCategories:
|
||||||
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||||
Priority: 2
|
Priority: 2
|
||||||
|
9
.editorconfig
Normal file
9
.editorconfig
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
end_of_line = lf
|
||||||
|
charset = utf-8
|
||||||
|
trim_trailing_whitespace = false
|
||||||
|
insert_final_newline = false
|
@@ -24,7 +24,7 @@ class ipc {
|
|||||||
int socklen_;
|
int socklen_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ipc() : ipc(DEFAULT_SOCK) {};
|
ipc() : ipc(DEFAULT_SOCK){};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Constructor for oim::ipc
|
* Constructor for oim::ipc
|
||||||
|
@@ -11,7 +11,8 @@ using std::string;
|
|||||||
const char *help[2] = {
|
const char *help[2] = {
|
||||||
"This program is not supposed to be called from the command line!",
|
"This program is not supposed to be called from the command line!",
|
||||||
"Call with 'install-protocol' to instal the xdg-compatible protocol file "
|
"Call with 'install-protocol' to instal the xdg-compatible protocol file "
|
||||||
"in ~/.local/share/applications/"};
|
"in ~/.local/share/applications/"
|
||||||
|
};
|
||||||
|
|
||||||
bool install_protocol() {
|
bool install_protocol() {
|
||||||
const char *protocol_file = R"([Desktop Entry]
|
const char *protocol_file = R"([Desktop Entry]
|
||||||
@@ -27,8 +28,8 @@ MimeType=x-scheme-handler/mpv
|
|||||||
if (!homedir)
|
if (!homedir)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
std::ofstream protfile(string(homedir) +
|
std::ofstream protfile(
|
||||||
"/.local/share/applications/open-in-mpv.desktop");
|
string(homedir) + "/.local/share/applications/open-in-mpv.desktop");
|
||||||
protfile << protocol_file;
|
protfile << protocol_file;
|
||||||
protfile.flush();
|
protfile.flush();
|
||||||
protfile.close();
|
protfile.close();
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "players.hpp"
|
||||||
#include "url.hpp"
|
#include "url.hpp"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
@@ -17,6 +18,7 @@ namespace oim {
|
|||||||
*/
|
*/
|
||||||
class options {
|
class options {
|
||||||
private:
|
private:
|
||||||
|
player *player_info_;
|
||||||
string url_;
|
string url_;
|
||||||
string flags_;
|
string flags_;
|
||||||
string player_;
|
string player_;
|
||||||
@@ -60,23 +62,23 @@ options::options() {
|
|||||||
fullscreen_ = false;
|
fullscreen_ = false;
|
||||||
pip_ = false;
|
pip_ = false;
|
||||||
enqueue_ = false;
|
enqueue_ = false;
|
||||||
|
new_window_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
string options::build_cmd() {
|
string options::build_cmd() {
|
||||||
std::ostringstream ret;
|
std::ostringstream ret;
|
||||||
|
|
||||||
// TODO: some of these options work only in mpv and not other players
|
if (player_info_ == nullptr) {
|
||||||
// This can be solved by adding a list of some sorts (json/toml/whatever)
|
return "";
|
||||||
// containing the flags to use for each functionality and each player
|
}
|
||||||
ret << player_ << " ";
|
|
||||||
|
ret << player_info_->executable << " ";
|
||||||
if (fullscreen_)
|
if (fullscreen_)
|
||||||
ret << "--fs ";
|
ret << player_info_->fullscreen << " ";
|
||||||
if (pip_)
|
if (pip_)
|
||||||
ret << "--ontop --no-border --autofit=384x216 --geometry=98\%:98\% ";
|
ret << player_info_->pip << " ";
|
||||||
if (!flags_.empty())
|
if (!flags_.empty())
|
||||||
ret << flags_ << " ";
|
ret << flags_ << " ";
|
||||||
// NOTE: this is not needed for mpv (it always opens a new window), maybe
|
|
||||||
// for other players? if (this->new_window_) ret << "--new-window";
|
|
||||||
ret << url_;
|
ret << url_;
|
||||||
|
|
||||||
return ret.str();
|
return ret.str();
|
||||||
@@ -109,10 +111,14 @@ void options::parse(const char *url_s) {
|
|||||||
if (u.query().empty())
|
if (u.query().empty())
|
||||||
throw string("Empty query");
|
throw string("Empty query");
|
||||||
|
|
||||||
url_ = oim::percent_decode(u.query_value("url"));
|
url_ = percent_decode(u.query_value("url"));
|
||||||
flags_ = oim::percent_decode(u.query_value("flags"));
|
flags_ = percent_decode(u.query_value("flags"));
|
||||||
player_ = u.query_value("player", "mpv");
|
player_ = u.query_value("player", "mpv");
|
||||||
|
|
||||||
|
player_info_ = get_player_info(player_);
|
||||||
|
if (player_info_ == nullptr)
|
||||||
|
throw string("Unsupported player: ") + player_;
|
||||||
|
|
||||||
fullscreen_ = u.query_value("fullscreen") == "1";
|
fullscreen_ = u.query_value("fullscreen") == "1";
|
||||||
pip_ = u.query_value("pip") == "1";
|
pip_ = u.query_value("pip") == "1";
|
||||||
enqueue_ = u.query_value("enqueue") == "1";
|
enqueue_ = u.query_value("enqueue") == "1";
|
||||||
|
82
src/players.hpp
Normal file
82
src/players.hpp
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
using std::string;
|
||||||
|
using std::unordered_map;
|
||||||
|
|
||||||
|
namespace oim {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Struct `oim::player` contains useful informations for an mpv-based player,
|
||||||
|
* such as binary name and fullscreen/pip/enqueue/new_window flags overrides for
|
||||||
|
* use in `options::build_ipc()`. A way to override any generic flags is also
|
||||||
|
* provided through the map `flag_overrides`.
|
||||||
|
*/
|
||||||
|
struct player {
|
||||||
|
string name;
|
||||||
|
string executable;
|
||||||
|
|
||||||
|
string fullscreen;
|
||||||
|
string pip;
|
||||||
|
string enqueue;
|
||||||
|
string new_window;
|
||||||
|
|
||||||
|
bool needs_ipc;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Override syntax:
|
||||||
|
* `"*"`: matches anything and will take precedence over any other
|
||||||
|
* override e.g. the pair `{"*", ""}` will void all flags
|
||||||
|
* `"flag"`: matches the flag `--flag`
|
||||||
|
* e.g. the pair `{"foo", "bar"}` will replace `--foo` with
|
||||||
|
* `--bar`
|
||||||
|
* `"%s"`: is replaced with the original flag without the leading `--`
|
||||||
|
* e.g. the pair `{"foo", "--%s-bar"}` will replace `--foo` with
|
||||||
|
* `--foo-bar`
|
||||||
|
*
|
||||||
|
* Note: command line options with parameters such as --foo=bar are
|
||||||
|
* considered a flags as a whole
|
||||||
|
*/
|
||||||
|
unordered_map<string, string> flag_overrides;
|
||||||
|
};
|
||||||
|
|
||||||
|
unordered_map<string, player> player_info = {
|
||||||
|
{ "mpv",
|
||||||
|
{ .name = "mpv",
|
||||||
|
.executable = "mpv",
|
||||||
|
.fullscreen = "--fs",
|
||||||
|
.pip = "--ontop --no-border --autofit=384x216 --geometry=98\%:98\%",
|
||||||
|
.enqueue = "",
|
||||||
|
.new_window = "",
|
||||||
|
.needs_ipc = true,
|
||||||
|
.flag_overrides = {} } },
|
||||||
|
{ "celluloid",
|
||||||
|
{ .name = "Celluloid",
|
||||||
|
.executable = "celluloid",
|
||||||
|
.fullscreen = "",
|
||||||
|
.pip = "",
|
||||||
|
.enqueue = "--enqueue",
|
||||||
|
.new_window = "--new-window",
|
||||||
|
.needs_ipc = false,
|
||||||
|
.flag_overrides = { { "*", "--mpv-options=%s" } } } }
|
||||||
|
};
|
||||||
|
|
||||||
|
player *get_player_info(string name) {
|
||||||
|
if (name.empty())
|
||||||
|
return &player_info["mpv"];
|
||||||
|
|
||||||
|
string lower_name(name);
|
||||||
|
std::transform(name.begin(), name.end(), lower_name.begin(), ::tolower);
|
||||||
|
|
||||||
|
auto info = player_info.find(lower_name);
|
||||||
|
if (info == player_info.end()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &(*info).second;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace oim
|
11
src/url.hpp
11
src/url.hpp
@@ -83,8 +83,8 @@ url::url(const string &url_s) {
|
|||||||
url_s.begin(), url_s.end(), prot_end.begin(), prot_end.end());
|
url_s.begin(), url_s.end(), prot_end.begin(), prot_end.end());
|
||||||
protocol_.reserve(std::distance(url_s.begin(), prot_i));
|
protocol_.reserve(std::distance(url_s.begin(), prot_i));
|
||||||
// The protocol is case insensitive
|
// The protocol is case insensitive
|
||||||
std::transform(url_s.begin(), prot_i, std::back_inserter(protocol_),
|
std::transform(
|
||||||
std::ptr_fun<int, int>(tolower));
|
url_s.begin(), prot_i, std::back_inserter(protocol_), ::tolower);
|
||||||
if (prot_i == url_s.end())
|
if (prot_i == url_s.end())
|
||||||
return;
|
return;
|
||||||
std::advance(prot_i, prot_end.length());
|
std::advance(prot_i, prot_end.length());
|
||||||
@@ -93,8 +93,7 @@ url::url(const string &url_s) {
|
|||||||
string::const_iterator path_i = std::find(prot_i, url_s.end(), '/');
|
string::const_iterator path_i = std::find(prot_i, url_s.end(), '/');
|
||||||
host_.reserve(std::distance(prot_i, path_i));
|
host_.reserve(std::distance(prot_i, path_i));
|
||||||
// The host is also case insensitive
|
// The host is also case insensitive
|
||||||
std::transform(prot_i, path_i, std::back_inserter(host_),
|
std::transform(prot_i, path_i, std::back_inserter(host_), ::tolower);
|
||||||
std::ptr_fun<int, int>(tolower));
|
|
||||||
|
|
||||||
// Everything else is query
|
// Everything else is query
|
||||||
string::const_iterator query_i = std::find(path_i, url_s.end(), '?');
|
string::const_iterator query_i = std::find(path_i, url_s.end(), '?');
|
||||||
@@ -146,8 +145,8 @@ string percent_decode(const string encoded) {
|
|||||||
std::byte b1 = ::alnum_to_hex(*++i);
|
std::byte b1 = ::alnum_to_hex(*++i);
|
||||||
std::byte b2 = ::alnum_to_hex(*++i);
|
std::byte b2 = ::alnum_to_hex(*++i);
|
||||||
|
|
||||||
char parsed =
|
char parsed = static_cast<char>(
|
||||||
static_cast<char>((0x10u * std::to_integer<unsigned int>(b1)) +
|
(0x10u * std::to_integer<unsigned int>(b1)) +
|
||||||
std::to_integer<unsigned int>(b2));
|
std::to_integer<unsigned int>(b2));
|
||||||
ret += parsed;
|
ret += parsed;
|
||||||
} else {
|
} else {
|
||||||
|
Reference in New Issue
Block a user