| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* | ||
| 2 | * This file is part of the Falcon Player (FPP) and is Copyright (C) | ||
| 3 | * 2013-2022 by the Falcon Player Developers. | ||
| 4 | * | ||
| 5 | * The Falcon Player (FPP) is free software, and is covered under | ||
| 6 | * multiple Open Source licenses. Please see the included 'LICENSES' | ||
| 7 | * file for descriptions of what files are covered by each license. | ||
| 8 | * | ||
| 9 | * This source file is covered under the LGPL v2.1 as described in the | ||
| 10 | * included LICENSE.LGPL file. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include "fpp-pch.h" | ||
| 14 | |||
| 15 | #include "../common.h" | ||
| 16 | #include "../log.h" | ||
| 17 | #include <thread> // std::this_thread::sleep_for -- needed directly for NOPCH builds | ||
| 18 | |||
| 19 | #include "Player.h" | ||
| 20 | #include "PlaylistCommands.h" | ||
| 21 | #include "Scheduler.h" | ||
| 22 | |||
| 23 | // A playlist name is the one argument every command in this file needs, and an | ||
| 24 | // empty one is never a playlist: it is a UI that posted with nothing selected, | ||
| 25 | // or a %VAR:name% that resolved to nothing. CommandManager's missing-argument | ||
| 26 | // check (invokeCommand(), Commands.cpp) only catches an argument that is not | ||
| 27 | // there at all - an explicit "" still reaches run() and gets treated as a name. | ||
| 28 | // That is how "Start Playlist At Item" with an empty name matched the (equally | ||
| 29 | // empty) name of the playlist the scheduler thought should be running, deferred | ||
| 30 | // to the scheduler, started nothing, and still returned success, leaving the web | ||
| 31 | // UI to report "Playlist Started" with the player sitting idle (issue #2944). | ||
| 32 | 1609 | static std::unique_ptr<Command::Result> MissingPlaylistName(const std::vector<std::string>& args, | |
| 33 | const std::string& command) { | ||
| 34 |
5/6✓ Branch 0 taken 1609 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 1602 times.
✓ Branch 4 taken 7 times.
✓ Branch 5 taken 1602 times.
|
1609 | if (args.empty() || args[0].empty()) { |
| 35 | 7 | LogWarn(VB_COMMAND, "Ignoring \"%s\" - no playlist name was given\n", command.c_str()); | |
| 36 |
3/6✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
|
7 | return std::make_unique<Command::ErrorResult>("\"" + command + "\" requires a playlist name"); |
| 37 | } | ||
| 38 | 1602 | return nullptr; | |
| 39 | } | ||
| 40 | |||
| 41 | 1888 | StopPlaylistCommand::StopPlaylistCommand() : | |
| 42 |
2/4✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
|
3776 | Command("Stop Now") { |
| 43 | 1888 | } | |
| 44 | 580 | std::unique_ptr<Command::Result> StopPlaylistCommand::run(const std::vector<std::string>& args) { | |
| 45 | 580 | Player::INSTANCE.StopNow(1); | |
| 46 | 580 | return std::make_unique<Command::Result>("Stopped"); | |
| 47 | } | ||
| 48 | |||
| 49 | 1888 | StopGracefullyPlaylistCommand::StopGracefullyPlaylistCommand() : | |
| 50 |
2/4✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
|
3776 | Command("Stop Gracefully") { |
| 51 | // Optional: run() has always treated a missing argument as "false", and | ||
| 52 | // "Stop Gracefully" with no arguments at all is a normal way to call it. | ||
| 53 | // Saying so here is what keeps CommandManager's missing-argument check | ||
| 54 | // (invokeCommand(), Commands.cpp) from refusing that call. | ||
| 55 |
6/12✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1888 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1888 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1888 times.
✗ Branch 11 not taken.
|
11328 | args.push_back(CommandArg("loop", "bool", "After Loop", true).setDefaultValue("false")); |
| 56 | 1888 | } | |
| 57 | 6 | std::unique_ptr<Command::Result> StopGracefullyPlaylistCommand::run(const std::vector<std::string>& args) { | |
| 58 | 6 | bool loop = false; | |
| 59 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
|
6 | if (args.size()) { |
| 60 |
3/4✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
|
3 | loop = args[0] == "true" || args[0] == "1"; |
| 61 | } | ||
| 62 | 6 | Player::INSTANCE.StopGracefully(1, loop); | |
| 63 | 6 | return std::make_unique<Command::Result>("Stopping"); | |
| 64 | } | ||
| 65 | |||
| 66 | 1888 | RestartPlaylistCommand::RestartPlaylistCommand() : | |
| 67 |
2/4✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
|
3776 | Command("Restart Playlist Item") { |
| 68 | 1888 | } | |
| 69 | 9050 | std::unique_ptr<Command::Result> RestartPlaylistCommand::run(const std::vector<std::string>& args) { | |
| 70 | 9050 | Player::INSTANCE.RestartItem(); | |
| 71 | 9050 | return std::make_unique<Command::Result>("Restarting"); | |
| 72 | } | ||
| 73 | |||
| 74 | 1888 | NextPlaylistCommand::NextPlaylistCommand() : | |
| 75 |
2/4✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
|
3776 | Command("Next Playlist Item") { |
| 76 | 1888 | } | |
| 77 | 9112 | std::unique_ptr<Command::Result> NextPlaylistCommand::run(const std::vector<std::string>& args) { | |
| 78 | 9112 | Player::INSTANCE.NextItem(); | |
| 79 | 9112 | return std::make_unique<Command::Result>("Next Item Playing"); | |
| 80 | } | ||
| 81 | |||
| 82 | 1888 | PrevPlaylistCommand::PrevPlaylistCommand() : | |
| 83 |
2/4✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
|
3776 | Command("Prev Playlist Item") { |
| 84 | 1888 | } | |
| 85 | 9080 | std::unique_ptr<Command::Result> PrevPlaylistCommand::run(const std::vector<std::string>& args) { | |
| 86 | 9080 | Player::INSTANCE.PrevItem(); | |
| 87 | 9080 | return std::make_unique<Command::Result>("Prev Item Playing"); | |
| 88 | } | ||
| 89 | |||
| 90 | 1888 | StartPlaylistCommand::StartPlaylistCommand() : | |
| 91 |
2/4✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
|
3776 | Command("Start Playlist") { |
| 92 |
4/8✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1888 times.
✗ Branch 7 not taken.
|
13216 | args.push_back(CommandArg("name", "string", "Playlist Name") |
| 93 |
3/6✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
|
3776 | .setContentListUrl("api/playlists/playable")); |
| 94 |
6/12✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1888 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1888 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1888 times.
✗ Branch 11 not taken.
|
11328 | args.push_back(CommandArg("repeat", "bool", "Repeat", true).setDefaultValue("false")); |
| 95 |
4/8✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1888 times.
✗ Branch 7 not taken.
|
13216 | args.push_back(CommandArg("ifNotRunning", "bool", "If Not Running", true) |
| 96 |
1/2✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
|
1888 | .setDefaultValue("false") |
| 97 |
3/6✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
|
3776 | .setHelp("Checks to see if this exact item is already running and " |
| 98 | "prevents it from running again.")); | ||
| 99 |
6/12✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1888 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1888 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1888 times.
✗ Branch 11 not taken.
|
11328 | args.push_back(CommandArg("scheduleProtected", "bool", "Protected from Schedule Override", true).setDefaultValue("false")); |
| 100 | 1888 | } | |
| 101 | 993 | std::unique_ptr<Command::Result> StartPlaylistCommand::run(const std::vector<std::string>& args) { | |
| 102 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 992 times.
|
993 | if (auto missing = MissingPlaylistName(args, name)) { |
| 103 | 1 | return missing; | |
| 104 | 992 | } | |
| 105 | 992 | bool r = false; | |
| 106 | 992 | bool iNR = false; | |
| 107 | 992 | bool scheduleProtected = false; | |
| 108 |
1/2✓ Branch 0 taken 992 times.
✗ Branch 1 not taken.
|
992 | if (args.size() > 1) { |
| 109 |
3/4✓ Branch 0 taken 745 times.
✓ Branch 1 taken 247 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 745 times.
|
992 | r = args[1] == "true" || args[1] == "1"; |
| 110 | } | ||
| 111 |
1/2✓ Branch 0 taken 992 times.
✗ Branch 1 not taken.
|
992 | if (args.size() > 2) { |
| 112 |
2/4✓ Branch 0 taken 992 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 992 times.
|
992 | iNR = args[2] == "true" || args[2] == "1"; |
| 113 | } | ||
| 114 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 989 times.
|
992 | if (args.size() > 3) { |
| 115 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
3 | scheduleProtected = args[3] == "true" || args[3] == "1"; |
| 116 | } | ||
| 117 |
3/12✗ Branch 0 not taken.
✓ Branch 1 taken 992 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 992 times.
✓ Branch 8 taken 992 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
|
992 | if (!iNR || args[0] != Player::INSTANCE.GetPlaylistName()) { |
| 118 | // The stop and the wait below are part of the start: the scheduler | ||
| 119 | // must not act on the player being idle in between. | ||
| 120 |
1/2✓ Branch 0 taken 992 times.
✗ Branch 1 not taken.
|
992 | Player::SwitchScope switching; |
| 121 |
3/6✓ Branch 0 taken 992 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 992 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 992 times.
✗ Branch 5 not taken.
|
992 | LogInfo(VB_COMMAND, "StartPlaylistCommand: Requesting playlist '%s', current='%s', status=%d\n", |
| 122 | args[0].c_str(), Player::INSTANCE.GetPlaylistName().c_str(), Player::INSTANCE.GetStatus()); | ||
| 123 | |||
| 124 | // Always stop if not idle to avoid deferred start mechanism | ||
| 125 |
3/4✓ Branch 0 taken 992 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 117 times.
✓ Branch 3 taken 875 times.
|
992 | if (Player::INSTANCE.GetStatus() != FPP_STATUS_IDLE) { |
| 126 |
1/2✓ Branch 0 taken 117 times.
✗ Branch 1 not taken.
|
117 | LogInfo(VB_COMMAND, "StartPlaylistCommand: Stopping current playlist\n"); |
| 127 | // Clear force-stopped flag to allow scheduler to work if needed | ||
| 128 |
1/2✓ Branch 0 taken 117 times.
✗ Branch 1 not taken.
|
117 | Player::INSTANCE.ClearForceStopped(); |
| 129 |
1/2✓ Branch 0 taken 117 times.
✗ Branch 1 not taken.
|
117 | Player::INSTANCE.StopNow(1); |
| 130 | // Brief wait to let stop complete - don't wait too long to avoid scheduler interference | ||
| 131 |
1/2✓ Branch 0 taken 117 times.
✗ Branch 1 not taken.
|
117 | std::this_thread::sleep_for(std::chrono::milliseconds(150)); |
| 132 |
2/4✓ Branch 0 taken 117 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 117 times.
✗ Branch 3 not taken.
|
117 | LogInfo(VB_COMMAND, "StartPlaylistCommand: After stop wait, status=%d\n", Player::INSTANCE.GetStatus()); |
| 133 | } | ||
| 134 |
1/2✓ Branch 0 taken 992 times.
✗ Branch 1 not taken.
|
992 | Player::INSTANCE.StartPlaylist(args[0], r, -1, -1, -1, !scheduleProtected); |
| 135 | 992 | } | |
| 136 | 992 | return std::make_unique<Command::Result>("Playlist Starting"); | |
| 137 | } | ||
| 138 | |||
| 139 | 1888 | TogglePlaylistCommand::TogglePlaylistCommand() : | |
| 140 |
2/4✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
|
3776 | Command("Toggle Playlist") { |
| 141 |
4/8✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1888 times.
✗ Branch 7 not taken.
|
13216 | args.push_back(CommandArg("name", "string", "Playlist Name") |
| 142 |
3/6✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
|
3776 | .setContentListUrl("api/playlists/playable")); |
| 143 |
6/12✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1888 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1888 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1888 times.
✗ Branch 11 not taken.
|
11328 | args.push_back(CommandArg("repeat", "bool", "Repeat", true).setDefaultValue("false")); |
| 144 |
4/8✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1888 times.
✗ Branch 7 not taken.
|
13216 | args.push_back(CommandArg("stop", "string", "Stop Type") |
| 145 |
1/2✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
|
5664 | .setContentList({ "Gracefully", "After Loop", "Now" }) |
| 146 |
2/4✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
|
1888 | .setDefaultValue("Gracefully")); |
| 147 | 1888 | } | |
| 148 | 3 | std::unique_ptr<Command::Result> TogglePlaylistCommand::run(const std::vector<std::string>& args) { | |
| 149 |
3/4✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 2 times.
|
3 | if (auto missing = MissingPlaylistName(args, name)) { |
| 150 | 1 | return missing; | |
| 151 | 2 | } | |
| 152 | 2 | bool r = false; | |
| 153 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | std::string stopType = "Gracefully"; |
| 154 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | if (args.size() > 1) { |
| 155 |
4/8✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
|
2 | r = args[1] == "true" || args[1] == "1"; |
| 156 | } | ||
| 157 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | if (args.size() > 2) { |
| 158 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | stopType = args[2]; |
| 159 | } | ||
| 160 |
9/14✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 1 times.
✓ Branch 10 taken 1 times.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
|
2 | if (Player::INSTANCE.IsPlaying() && Player::INSTANCE.GetPlaylistName() == args[0]) { |
| 161 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | if (stopType == "Now") { |
| 162 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | Player::INSTANCE.StopNow(1); |
| 163 | ✗ | } else if (stopType == "After Loop") { | |
| 164 | ✗ | Player::INSTANCE.StopGracefully(true, true); | |
| 165 | } else { | ||
| 166 | ✗ | Player::INSTANCE.StopGracefully(true, false); | |
| 167 | } | ||
| 168 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | return std::make_unique<Command::Result>("Playlist Stopping"); |
| 169 | } | ||
| 170 | |||
| 171 |
3/6✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | LogInfo(VB_COMMAND, "TogglePlaylistCommand: Requesting playlist '%s', current='%s', status=%d\n", |
| 172 | args[0].c_str(), Player::INSTANCE.GetPlaylistName().c_str(), Player::INSTANCE.GetStatus()); | ||
| 173 | |||
| 174 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | Player::SwitchScope switching; // see StartPlaylistCommand |
| 175 | // If a different playlist is playing, stop it first to avoid race conditions | ||
| 176 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
|
1 | if (Player::INSTANCE.GetStatus() != FPP_STATUS_IDLE) { |
| 177 | ✗ | LogInfo(VB_COMMAND, "TogglePlaylistCommand: Stopping current playlist\n"); | |
| 178 | ✗ | Player::INSTANCE.ClearForceStopped(); | |
| 179 | ✗ | Player::INSTANCE.StopNow(1); | |
| 180 | ✗ | std::this_thread::sleep_for(std::chrono::milliseconds(150)); | |
| 181 | ✗ | LogInfo(VB_COMMAND, "TogglePlaylistCommand: After stop wait, status=%d\n", Player::INSTANCE.GetStatus()); | |
| 182 | } | ||
| 183 | |||
| 184 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | Player::INSTANCE.StartPlaylist(args[0], r); |
| 185 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | return std::make_unique<Command::Result>("Playlist Starting"); |
| 186 | 2 | } | |
| 187 | |||
| 188 | 1888 | StartPlaylistAtCommand::StartPlaylistAtCommand() : | |
| 189 |
2/4✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
|
3776 | Command("Start Playlist At Item") { |
| 190 |
4/8✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1888 times.
✗ Branch 7 not taken.
|
13216 | args.push_back(CommandArg("name", "string", "Playlist Name") |
| 191 |
3/6✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
|
3776 | .setContentListUrl("api/playlists")); |
| 192 |
5/10✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1888 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1888 times.
✗ Branch 9 not taken.
|
11328 | args.push_back(CommandArg("item", "int", "Item Index").setRange(1, 100)); |
| 193 |
6/12✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1888 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1888 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1888 times.
✗ Branch 11 not taken.
|
11328 | args.push_back(CommandArg("repeat", "bool", "Repeat", true).setDefaultValue("false")); |
| 194 |
4/8✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1888 times.
✗ Branch 7 not taken.
|
13216 | args.push_back(CommandArg("ifNotRunning", "bool", "If Not Running", true) |
| 195 |
1/2✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
|
1888 | .setDefaultValue("false") |
| 196 |
3/6✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
|
3776 | .setHelp("Checks to see if this exact item is already running and " |
| 197 | "prevents it from running again.")); | ||
| 198 |
6/12✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1888 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1888 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1888 times.
✗ Branch 11 not taken.
|
11328 | args.push_back(CommandArg("scheduleProtected", "bool", "Protected from Schedule Override", true).setDefaultValue("false")); |
| 199 | 1888 | } | |
| 200 | 18 | std::unique_ptr<Command::Result> StartPlaylistAtCommand::run(const std::vector<std::string>& args) { | |
| 201 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 17 times.
|
18 | if (auto missing = MissingPlaylistName(args, name)) { |
| 202 | 1 | return missing; | |
| 203 | 17 | } | |
| 204 | 17 | bool r = false; | |
| 205 | 17 | bool scheduleProtected = false; | |
| 206 | |||
| 207 | 17 | int idx = 1; | |
| 208 |
1/2✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
|
17 | if (args.size() > 1) { |
| 209 | 17 | idx = std::atoi(args[1].c_str()); | |
| 210 | } | ||
| 211 | 17 | bool iNR = false; | |
| 212 |
1/2✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
|
17 | if (args.size() > 2) { |
| 213 |
3/4✓ Branch 0 taken 12 times.
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
|
17 | r = args[2] == "true" || args[2] == "1"; |
| 214 | } | ||
| 215 |
1/2✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
|
17 | if (args.size() > 3) { |
| 216 |
2/4✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 17 times.
|
17 | iNR = args[3] == "true" || args[3] == "1"; |
| 217 | } | ||
| 218 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
|
17 | if (args.size() > 4) { |
| 219 | ✗ | scheduleProtected = args[4] == "true" || args[4] == "1"; | |
| 220 | } | ||
| 221 |
3/12✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 17 times.
✓ Branch 8 taken 17 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
|
17 | if (!iNR || args[0] != Player::INSTANCE.GetPlaylistName()) { |
| 222 | 17 | int scheduledRepeat = 0; | |
| 223 |
1/2✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
|
17 | std::string playlistName = scheduler->GetPlaylistThatShouldBePlaying(scheduledRepeat); |
| 224 | 17 | bool repeat = scheduledRepeat; | |
| 225 | |||
| 226 |
3/6✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 17 times.
✗ Branch 5 not taken.
|
17 | LogInfo(VB_COMMAND, "StartPlaylistAtCommand: args[0]='%s', status=%d, currentPlaylist='%s', scheduledPlaylist='%s'\n", |
| 227 | args[0].c_str(), Player::INSTANCE.GetStatus(), | ||
| 228 | Player::INSTANCE.GetPlaylistName().c_str(), playlistName.c_str()); | ||
| 229 | |||
| 230 | // Only defer to scheduler if we're idle AND the requested playlist matches what should be scheduled | ||
| 231 | // AND it's not currently being played. This prevents the race condition where we're playing a | ||
| 232 | // scheduled background playlist and want to start a different playlist via API. | ||
| 233 |
2/4✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 7 times.
|
24 | if ((Player::INSTANCE.GetStatus() == FPP_STATUS_IDLE) && |
| 234 |
3/6✓ Branch 0 taken 7 times.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 17 times.
|
24 | (args[0] == playlistName) && |
| 235 | (r == repeat)) { | ||
| 236 | ✗ | LogInfo(VB_COMMAND, "StartPlaylistAtCommand: Deferring to scheduler\n"); | |
| 237 | // Allow the scheduler to restart even if force stopped | ||
| 238 | ✗ | Player::INSTANCE.ClearForceStopped(); | |
| 239 | ✗ | scheduler->CheckIfShouldBePlayingNow(1); | |
| 240 | } else { | ||
| 241 |
1/2✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
|
17 | Player::SwitchScope switching; // see StartPlaylistCommand |
| 242 | // Always directly start the playlist if: | ||
| 243 | // 1. Something is already playing (even if it's the scheduled playlist) | ||
| 244 | // 2. The requested playlist doesn't match what's scheduled | ||
| 245 | // 3. The repeat mode doesn't match | ||
| 246 | |||
| 247 | // If playing a different playlist, stop the current one first | ||
| 248 |
3/4✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 7 times.
|
27 | if ((Player::INSTANCE.GetStatus() != FPP_STATUS_IDLE) && |
| 249 |
7/10✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 9 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 7 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 16 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
27 | (Player::INSTANCE.GetPlaylistName() != args[0])) { |
| 250 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | LogInfo(VB_COMMAND, "StartPlaylistAtCommand: Stopping current playlist '%s' before starting '%s'\n", |
| 251 | Player::INSTANCE.GetPlaylistName().c_str(), args[0].c_str()); | ||
| 252 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | Player::INSTANCE.StopNow(1); |
| 253 | } | ||
| 254 | |||
| 255 |
1/2✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
|
17 | LogInfo(VB_COMMAND, "StartPlaylistAtCommand: Starting playlist '%s'\n", args[0].c_str()); |
| 256 |
1/2✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
|
17 | Player::INSTANCE.StartPlaylist(args[0], r, idx - 1, -1, -1, !scheduleProtected); |
| 257 | 17 | } | |
| 258 | 17 | } | |
| 259 | 17 | return std::make_unique<Command::Result>("Playlist Starting"); | |
| 260 | } | ||
| 261 | |||
| 262 | 1888 | StartPlaylistAtRandomCommand::StartPlaylistAtRandomCommand() : | |
| 263 |
2/4✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
|
3776 | Command("Start Playlist At Random Item") { |
| 264 |
4/8✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1888 times.
✗ Branch 7 not taken.
|
13216 | args.push_back(CommandArg("name", "string", "Playlist Name") |
| 265 |
3/6✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
|
3776 | .setContentListUrl("api/playlists")); |
| 266 |
6/12✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1888 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1888 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1888 times.
✗ Branch 11 not taken.
|
11328 | args.push_back(CommandArg("repeat", "bool", "Repeat", true).setDefaultValue("false")); |
| 267 |
4/8✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1888 times.
✗ Branch 7 not taken.
|
13216 | args.push_back(CommandArg("ifNotRunning", "bool", "If Not Running", true) |
| 268 |
1/2✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
|
1888 | .setDefaultValue("false") |
| 269 |
3/6✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
|
3776 | .setHelp("Checks to see if this exact item is already running and " |
| 270 | "prevents it from running again.")); | ||
| 271 | 1888 | } | |
| 272 | 1 | std::unique_ptr<Command::Result> StartPlaylistAtRandomCommand::run(const std::vector<std::string>& args) { | |
| 273 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (auto missing = MissingPlaylistName(args, name)) { |
| 274 | 1 | return missing; | |
| 275 | ✗ | } | |
| 276 | ✗ | bool r = false; | |
| 277 | ✗ | bool iNR = false; | |
| 278 | ✗ | if (args.size() > 1) { | |
| 279 | ✗ | r = args[1] == "true" || args[1] == "1"; | |
| 280 | } | ||
| 281 | ✗ | if (args.size() > 2) { | |
| 282 | ✗ | iNR = args[2] == "true" || args[2] == "1"; | |
| 283 | } | ||
| 284 | ✗ | if (!iNR || args[0] != Player::INSTANCE.GetPlaylistName()) { | |
| 285 | ✗ | Player::SwitchScope switching; // see StartPlaylistCommand | |
| 286 | ✗ | LogInfo(VB_COMMAND, "StartPlaylistAtRandomCommand: Requesting playlist '%s', current='%s', status=%d\n", | |
| 287 | args[0].c_str(), Player::INSTANCE.GetPlaylistName().c_str(), Player::INSTANCE.GetStatus()); | ||
| 288 | |||
| 289 | // Always stop if not idle to avoid deferred start mechanism | ||
| 290 | ✗ | if (Player::INSTANCE.GetStatus() != FPP_STATUS_IDLE) { | |
| 291 | ✗ | LogInfo(VB_COMMAND, "StartPlaylistAtRandomCommand: Stopping current playlist\n"); | |
| 292 | // Clear force-stopped flag to allow scheduler to work if needed | ||
| 293 | ✗ | Player::INSTANCE.ClearForceStopped(); | |
| 294 | ✗ | Player::INSTANCE.StopNow(1); | |
| 295 | // Brief wait to let stop complete - don't wait too long to avoid scheduler interference | ||
| 296 | ✗ | std::this_thread::sleep_for(std::chrono::milliseconds(150)); | |
| 297 | ✗ | LogInfo(VB_COMMAND, "StartPlaylistAtRandomCommand: After stop wait, status=%d\n", Player::INSTANCE.GetStatus()); | |
| 298 | } | ||
| 299 | ✗ | Player::INSTANCE.StartPlaylist(args[0], r, -2); | |
| 300 | ✗ | } | |
| 301 | ✗ | return std::make_unique<Command::Result>("Playlist Starting"); | |
| 302 | } | ||
| 303 | |||
| 304 | 1888 | InsertPlaylistCommand::InsertPlaylistCommand() : | |
| 305 |
3/6✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
|
7552 | Command("Insert Playlist After Current", "After the current item of the currently running playlist is complete, run the new playlist. When complete, resumes the original playlist at the next position.") { |
| 306 |
4/8✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1888 times.
✗ Branch 7 not taken.
|
13216 | args.push_back(CommandArg("name", "string", "Playlist Name") |
| 307 |
3/6✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
|
3776 | .setContentListUrl("api/playlists/playable")); |
| 308 |
6/12✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1888 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1888 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1888 times.
✗ Branch 11 not taken.
|
11328 | args.push_back(CommandArg("startItem", "int", "Start Item Index", true).setRange(-1, 100).setDefaultValue("-1")); |
| 309 |
6/12✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1888 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1888 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1888 times.
✗ Branch 11 not taken.
|
11328 | args.push_back(CommandArg("endItem", "int", "End Item Index", true).setRange(-1, 100).setDefaultValue("-1")); |
| 310 |
4/8✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1888 times.
✗ Branch 7 not taken.
|
13216 | args.push_back(CommandArg("ifNotRunning", "bool", "If Not Running", true) |
| 311 |
1/2✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
|
1888 | .setDefaultValue("false") |
| 312 |
3/6✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
|
3776 | .setHelp("Checks to see if this exact item is already running and " |
| 313 | "prevents it from running again.")); | ||
| 314 | 1888 | } | |
| 315 | 10 | std::unique_ptr<Command::Result> InsertPlaylistCommand::run(const std::vector<std::string>& args) { | |
| 316 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 9 times.
|
10 | if (auto missing = MissingPlaylistName(args, name)) { |
| 317 | 1 | return missing; | |
| 318 | 9 | } | |
| 319 | 9 | int start = -1; | |
| 320 | 9 | int end = -1; | |
| 321 | 9 | bool iNR = false; | |
| 322 |
1/2✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
|
9 | if (args.size() > 1) { |
| 323 | 9 | start = std::atoi(args[1].c_str()); | |
| 324 | } | ||
| 325 |
1/2✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
|
9 | if (args.size() > 2) { |
| 326 | 9 | end = std::atoi(args[2].c_str()); | |
| 327 | } | ||
| 328 |
1/2✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
|
9 | if (args.size() > 3) { |
| 329 |
2/4✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
|
9 | iNR = args[3] == "true" || args[3] == "1"; |
| 330 | } | ||
| 331 |
3/12✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 9 times.
✓ Branch 8 taken 9 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
|
9 | if (!iNR || args[0] != Player::INSTANCE.GetPlaylistName()) { |
| 332 | 9 | Player::INSTANCE.InsertPlaylistAsNext(args[0], start > 0 ? start - 1 : -1, end > 0 ? end - 1 : -1); | |
| 333 | } | ||
| 334 | 9 | return std::make_unique<Command::Result>("Playlist Inserted"); | |
| 335 | } | ||
| 336 | |||
| 337 | 1888 | InsertPlaylistImmediate::InsertPlaylistImmediate() : | |
| 338 |
3/6✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
|
7552 | Command("Insert Playlist Immediate", "If possible, pauses the currently running playlist and then runs the new playlist. When complete, resumes the original playlist where it was paused.") { |
| 339 |
4/8✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1888 times.
✗ Branch 7 not taken.
|
13216 | args.push_back(CommandArg("name", "string", "Playlist Name") |
| 340 |
3/6✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
|
3776 | .setContentListUrl("api/playlists/playable")); |
| 341 |
6/12✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1888 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1888 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1888 times.
✗ Branch 11 not taken.
|
11328 | args.push_back(CommandArg("startItem", "int", "Start Item Index", true).setRange(0, 100).setDefaultValue("0")); |
| 342 |
6/12✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1888 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1888 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1888 times.
✗ Branch 11 not taken.
|
11328 | args.push_back(CommandArg("endItem", "int", "End Item Index", true).setRange(0, 100).setDefaultValue("0")); |
| 343 |
4/8✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1888 times.
✗ Branch 7 not taken.
|
13216 | args.push_back(CommandArg("ifNotRunning", "bool", "If Not Running", true) |
| 344 |
1/2✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
|
1888 | .setDefaultValue("false") |
| 345 |
3/6✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
|
3776 | .setHelp("Checks to see if this exact item is already running and " |
| 346 | "prevents it from running again.")); | ||
| 347 | 1888 | } | |
| 348 | 577 | std::unique_ptr<Command::Result> InsertPlaylistImmediate::run(const std::vector<std::string>& args) { | |
| 349 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 576 times.
|
577 | if (auto missing = MissingPlaylistName(args, name)) { |
| 350 | 1 | return missing; | |
| 351 | 576 | } | |
| 352 | 576 | int start = -1; | |
| 353 | 576 | int end = -1; | |
| 354 | 576 | bool iNR = false; | |
| 355 |
1/2✓ Branch 0 taken 576 times.
✗ Branch 1 not taken.
|
576 | if (args.size() > 1) { |
| 356 | 576 | start = std::atoi(args[1].c_str()); | |
| 357 | } | ||
| 358 |
1/2✓ Branch 0 taken 576 times.
✗ Branch 1 not taken.
|
576 | if (args.size() > 2) { |
| 359 | 576 | end = std::atoi(args[2].c_str()); | |
| 360 | } | ||
| 361 |
1/2✓ Branch 0 taken 576 times.
✗ Branch 1 not taken.
|
576 | if (args.size() > 3) { |
| 362 |
2/4✓ Branch 0 taken 576 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 576 times.
|
576 | iNR = args[3] == "true" || args[3] == "1"; |
| 363 | } | ||
| 364 |
3/12✗ Branch 0 not taken.
✓ Branch 1 taken 576 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 576 times.
✓ Branch 8 taken 576 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
|
576 | if (!iNR || args[0] != Player::INSTANCE.GetPlaylistName()) { |
| 365 | 576 | Player::INSTANCE.InsertPlaylistImmediate(args[0], start > 0 ? start - 1 : -1, end > 0 ? end - 1 : -1); | |
| 366 | } | ||
| 367 | 576 | return std::make_unique<Command::Result>("Playlist Inserted"); | |
| 368 | } | ||
| 369 | |||
| 370 | 1888 | InsertRandomItemFromPlaylistCommand::InsertRandomItemFromPlaylistCommand() : | |
| 371 |
3/6✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
|
7552 | Command("Insert Random Item From Playlist", "Run a random item from the given playlist. When complete, resumes the original playlist.") { |
| 372 |
4/8✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1888 times.
✗ Branch 7 not taken.
|
13216 | args.push_back(CommandArg("name", "string", "Playlist Name") |
| 373 |
3/6✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
|
3776 | .setContentListUrl("api/playlists/playable")); |
| 374 |
6/12✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1888 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1888 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1888 times.
✗ Branch 11 not taken.
|
11328 | args.push_back(CommandArg("immediate", "bool", "Immediate", true).setDefaultValue("false")); |
| 375 | 1888 | } | |
| 376 | 7 | std::unique_ptr<Command::Result> InsertRandomItemFromPlaylistCommand::run(const std::vector<std::string>& args) { | |
| 377 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6 times.
|
7 | if (auto missing = MissingPlaylistName(args, name)) { |
| 378 | 1 | return missing; | |
| 379 | 6 | } | |
| 380 | 6 | bool immediate = false; | |
| 381 |
1/2✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
|
6 | if (args.size() > 1) { |
| 382 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
6 | immediate = args[1] == "true" || args[1] == "1"; |
| 383 | } | ||
| 384 |
1/2✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
|
6 | if (immediate) { |
| 385 | 6 | Player::INSTANCE.InsertPlaylistImmediate(args[0], -2, 0); | |
| 386 | } else { | ||
| 387 | ✗ | Player::INSTANCE.InsertPlaylistAsNext(args[0], -2, 0); | |
| 388 | } | ||
| 389 | 6 | return std::make_unique<Command::Result>("Playlist Inserted"); | |
| 390 | } | ||
| 391 | |||
| 392 | 1888 | PlaylistPauseCommand::PlaylistPauseCommand() : | |
| 393 |
3/6✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
|
7552 | Command("Pause Playlist", "If possible, pauses the currently running playlist. This command can not be run from inside a playlist") { |
| 394 | 1888 | } | |
| 395 | 15 | std::unique_ptr<Command::Result> PlaylistPauseCommand::run(const std::vector<std::string>& args) { | |
| 396 | 15 | Player::INSTANCE.Pause(); | |
| 397 | 15 | return std::make_unique<Command::Result>("Playlist Paused"); | |
| 398 | } | ||
| 399 | |||
| 400 | 1888 | PlaylistResumeCommand::PlaylistResumeCommand() : | |
| 401 |
2/4✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
|
3776 | Command("Resume Playlist") { |
| 402 | 1888 | } | |
| 403 | 13 | std::unique_ptr<Command::Result> PlaylistResumeCommand::run(const std::vector<std::string>& args) { | |
| 404 | 13 | Player::INSTANCE.Resume(); | |
| 405 | 13 | return std::make_unique<Command::Result>("Playlist Restarted"); | |
| 406 | } | ||
| 407 | |||
| 408 | 1888 | SetPlaylistRepeatCommand::SetPlaylistRepeatCommand() : | |
| 409 |
3/6✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
|
7552 | Command("Set Playlist Repeat", "Turns repeat on or off for the running playlist. Nothing is started, stopped or restarted; the new setting is read when the playlist reaches the end of its current loop.") { |
| 410 |
6/12✓ Branch 0 taken 1888 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1888 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1888 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1888 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1888 times.
✗ Branch 11 not taken.
|
11328 | args.push_back(CommandArg("repeat", "bool", "Repeat").setDefaultValue("true")); |
| 411 | 1888 | } | |
| 412 | 4 | std::unique_ptr<Command::Result> SetPlaylistRepeatCommand::run(const std::vector<std::string>& args) { | |
| 413 | 4 | bool repeat = true; | |
| 414 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | if (args.size()) { |
| 415 |
3/4✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
|
4 | repeat = args[0] == "true" || args[0] == "1"; |
| 416 | } | ||
| 417 | |||
| 418 | // Repeat is a property of a *running* playlist, and only there. The idle | ||
| 419 | // playlist has been Cleanup()ed back to repeat=0, Play() reloads the value | ||
| 420 | // from the playlist file and then overwrites it with whatever the start | ||
| 421 | // command passed, and GetCurrentStatus() reports a hard-coded "0" while | ||
| 422 | // idle. Setting it now would therefore report success, never show up in | ||
| 423 | // /api/fppd/status, and be thrown away by the next start - so refuse | ||
| 424 | // instead of lying about it (issue #2971). | ||
| 425 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
|
4 | if (Player::INSTANCE.GetStatus() == FPP_STATUS_IDLE) { |
| 426 | 1 | LogWarn(VB_COMMAND, "Ignoring \"Set Playlist Repeat\" - no playlist is running\n"); | |
| 427 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | return std::make_unique<Command::ErrorResult>("No playlist is running; pass the repeat flag to \"Start Playlist\" instead"); |
| 428 | } | ||
| 429 | |||
| 430 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
|
3 | Player::INSTANCE.SetRepeat(repeat ? 1 : 0); |
| 431 |
3/4✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
3 | return std::make_unique<Command::Result>(repeat ? "Repeat Enabled" : "Repeat Disabled"); |
| 432 | } | ||
| 433 |