Skip to content

Commit 0bff416

Browse files
committed
add --resume command line option
Close #8
1 parent 3ad34c5 commit 0bff416

6 files changed

+128
-4
lines changed

src/CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ add_executable(
3535
playlist.cpp
3636
notification.cpp
3737
config.cpp
38+
options.cpp
3839
${PLAYLIST_DECODERS}
3940
${THIRD_PARTY}
4041
)
@@ -66,6 +67,7 @@ if (CMAKE_BUILD_TYPE STREQUAL "Debug")
6667
player.cpp
6768
playlist.cpp
6869
config.cpp
70+
options.cpp
6971
${PLAYLIST_DECODERS}
7072
${THIRD_PARTY}
7173
)

src/options.cpp

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#include "options.hpp"
2+
3+
namespace radiotray
4+
{
5+
6+
// clang-format off
7+
static const struct option longopts[] = {
8+
{ "resume", no_argument, NULL, 'r' },
9+
{ "help", no_argument, NULL, 'h' },
10+
{ NULL, 0, NULL, 0 }
11+
};
12+
// clang-format on
13+
14+
bool
15+
CmdLineOptions::parse(int argc, char** argv)
16+
{
17+
int opt, optidx;
18+
19+
while ((opt = getopt_long(argc, argv, "rh", longopts, &optidx)) != -1) {
20+
switch (opt) {
21+
case 'r':
22+
resume = true;
23+
break;
24+
case 'h':
25+
help = true;
26+
break;
27+
default:
28+
return false;
29+
}
30+
}
31+
32+
return true;
33+
}
34+
35+
void
36+
CmdLineOptions::show_help()
37+
{
38+
std::cout << "Online radio streaming player" << std::endl;
39+
std::cout << "Usage:" << std::endl;
40+
std::cout << " radiotray-lite [OPTIONS...]" << std::endl << std::endl;
41+
std::cout << " -h, --help show this help and exit" << std::endl;
42+
std::cout << " -r, --resume resume last played station on startup" << std::endl;
43+
std::cout << std::endl;
44+
}
45+
46+
} // namespace

src/options.hpp

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#ifndef __OPTIONS_HPP_INCLUDED__
2+
#define __OPTIONS_HPP_INCLUDED__
3+
4+
#include <iostream>
5+
#include <memory>
6+
7+
#include <getopt.h>
8+
9+
namespace radiotray
10+
{
11+
class CmdLineOptions
12+
{
13+
public:
14+
CmdLineOptions() = default;
15+
16+
bool parse(int argc, char** argv);
17+
void show_help();
18+
19+
bool resume = false;
20+
bool help = false;
21+
};
22+
23+
} // namespace
24+
25+
#endif

src/radiotray-lite.cpp

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "tray.hpp"
2+
#include "options.hpp"
23

34
INITIALIZE_EASYLOGGINGPP
45

@@ -26,9 +27,20 @@ main(int argc, char* argv[])
2627
// default logger uses default configurations
2728
el::Loggers::reconfigureLogger("default", easylogging_config);
2829

30+
auto opts = std::make_shared<CmdLineOptions>();
2931
RadioTrayLite rtl;
3032

31-
auto ok = rtl.init(argc, argv);
33+
auto ok = opts->parse(argc, argv);
34+
if (not ok) {
35+
return EXIT_FAILURE;
36+
}
37+
38+
if (opts->help) {
39+
opts->show_help();
40+
return EXIT_SUCCESS;
41+
}
42+
43+
ok = rtl.init(argc, argv, opts);
3244
if (not ok) {
3345
LOG(ERROR) << "Initialization failed";
3446
return EXIT_FAILURE;

src/tray.cpp

+37-2
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,15 @@ RadioTrayLite::~RadioTrayLite()
6767
}
6868

6969
bool
70-
RadioTrayLite::init(int argc, char** argv)
70+
RadioTrayLite::init(int argc, char** argv, std::shared_ptr<CmdLineOptions>& opts)
7171
{
72+
cmd_line_options = opts;
7273
config = std::make_shared<Config>();
7374

7475
load_configuration();
7576

76-
app = Gtk::Application::create(argc, argv, "github.com.thekvs.radiotray-lite");
77+
// app = Gtk::Application::create(argc, argv, "github.com.thekvs.radiotray-lite");
78+
app = Gtk::Application::create("github.com.thekvs.radiotray-lite");
7779
app->register_application();
7880
if (app->is_remote()) {
7981
LOG(WARNING) << "This application is already running!";
@@ -124,6 +126,11 @@ RadioTrayLite::run()
124126
build_menu();
125127

126128
app->hold();
129+
130+
// resume the last played staion in timer callback
131+
sigc::slot<bool> resume_slot = sigc::bind(sigc::mem_fun(*this, &RadioTrayLite::resume), cmd_line_options->resume);
132+
sigc::connection conn = Glib::signal_timeout().connect(resume_slot, 200);
133+
127134
auto rc = app->run();
128135

129136
return rc;
@@ -175,6 +182,34 @@ RadioTrayLite::on_current_station_button()
175182
}
176183
}
177184

185+
bool
186+
RadioTrayLite::resume(bool resume_last_station)
187+
{
188+
if (resume_last_station) {
189+
if (config->has_last_station()) {
190+
Glib::ustring data_url;
191+
try {
192+
std::stringstream xpath_query;
193+
xpath_query << "//bookmark[@name='" << config->get_last_played_station() << "']";
194+
195+
pugi::xpath_node node = bookmarks_doc.select_node(xpath_query.str().c_str());
196+
if (not node.node().empty()) {
197+
data_url = node.node().attribute("url").as_string();
198+
}
199+
} catch (pugi::xpath_exception& exc) {
200+
LOG(WARNING) << "XPath error: " << exc.what();
201+
}
202+
203+
LOG(DEBUG) << "Resuming the last played station: " << config->get_last_played_station() << " (stream url: " << data_url << ")";
204+
player->play(data_url, config->get_last_played_station());
205+
}
206+
}
207+
208+
// When we return false from the timer callback it deletes itself automatically
209+
// and won't be executed any more. So we have one time event here.
210+
return false;
211+
}
212+
178213
void
179214
RadioTrayLite::build_menu()
180215
{

src/tray.hpp

+5-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "constants.hpp"
2121
#include "notification.hpp"
2222
#include "player.hpp"
23+
#include "options.hpp"
2324

2425
namespace radiotray
2526
{
@@ -32,7 +33,7 @@ class RadioTrayLite
3233

3334
~RadioTrayLite();
3435

35-
bool init(int argc, char** argv);
36+
bool init(int argc, char** argv, std::shared_ptr<CmdLineOptions>& opts);
3637
int run();
3738

3839
private:
@@ -52,6 +53,7 @@ class RadioTrayLite
5253
std::shared_ptr<EventManager> em;
5354
std::shared_ptr<Notification> notifier;
5455
std::shared_ptr<Config> config;
56+
std::shared_ptr<CmdLineOptions> cmd_line_options;
5557

5658
class BookmarksWalker : public pugi::xml_tree_walker
5759
{
@@ -78,6 +80,8 @@ class RadioTrayLite
7880
void on_reload_button();
7981
void on_current_station_button();
8082

83+
bool resume(bool resume_last_station);
84+
8185
void build_menu();
8286
void rebuild_menu();
8387
void clear_menu();

0 commit comments

Comments
 (0)