1 /*
2  *  Copyright (C) 2005-2018 Team Kodi
3  *  This file is part of Kodi - https://kodi.tv
4  *
5  *  SPDX-License-Identifier: GPL-2.0-or-later
6  *  See LICENSES/README.md for more information.
7  */
8 
9 #include "ApplicationBuiltins.h"
10 
11 #include "Application.h"
12 #include "ServiceBroker.h"
13 #include "filesystem/ZipManager.h"
14 #include "interfaces/AnnouncementManager.h"
15 #include "messaging/ApplicationMessenger.h"
16 #include "network/Network.h"
17 #include "settings/AdvancedSettings.h"
18 #include "settings/Settings.h"
19 #include "settings/SettingsComponent.h"
20 #include "utils/FileOperationJob.h"
21 #include "utils/JSONVariantParser.h"
22 #include "utils/StringUtils.h"
23 #include "utils/URIUtils.h"
24 #include "utils/Variant.h"
25 #include "utils/log.h"
26 
27 #include <stdlib.h>
28 
29 using namespace KODI::MESSAGING;
30 
31 /*! \brief Extract an archive.
32  *  \param params The parameters
33  *  \details params[0] = The archive URL.
34  *           params[1] = Destination path (optional).
35  *                       If not given, extracts to folder with archive.
36  */
Extract(const std::vector<std::string> & params)37 static int Extract(const std::vector<std::string>& params)
38 {
39     // Detects if file is zip or rar then extracts
40     std::string strDestDirect;
41     if (params.size() < 2)
42       strDestDirect = URIUtils::GetDirectory(params[0]);
43     else
44       strDestDirect = params[1];
45 
46     URIUtils::AddSlashAtEnd(strDestDirect);
47 
48     if (URIUtils::IsZIP(params[0]))
49       g_ZipManager.ExtractArchive(params[0],strDestDirect);
50     else
51       CLog::Log(LOGERROR, "Extract, No archive given");
52 
53   return 0;
54 }
55 
56 /*! \brief Mute volume.
57  *  \param params (ignored)
58  */
Mute(const std::vector<std::string> & params)59 static int Mute(const std::vector<std::string>& params)
60 {
61   g_application.ToggleMute();
62 
63   return 0;
64 }
65 
66 /*! \brief Notify all listeners on announcement bus.
67  *  \param params The parameters.
68  *  \details params[0] = sender.
69  *           params[1] = data.
70  *           params[2] = JSON with extra parameters (optional).
71  */
NotifyAll(const std::vector<std::string> & params)72 static int NotifyAll(const std::vector<std::string>& params)
73 {
74   CVariant data;
75   if (params.size() > 2)
76   {
77     if (!CJSONVariantParser::Parse(params[2], data))
78     {
79       CLog::Log(LOGERROR, "NotifyAll failed to parse data: %s", params[2].c_str());
80       return -3;
81     }
82   }
83 
84   CServiceBroker::GetAnnouncementManager()->Announce(ANNOUNCEMENT::Other, params[0].c_str(), params[1].c_str(), data);
85 
86   return 0;
87 }
88 
89 /*! \brief Set volume.
90  *  \param params the parameters.
91  *  \details params[0] = Volume level.
92  *           params[1] = "showVolumeBar" to show volume bar (optional).
93  */
SetVolume(const std::vector<std::string> & params)94 static int SetVolume(const std::vector<std::string>& params)
95 {
96   float oldVolume = g_application.GetVolumePercent();
97   float volume = (float)strtod(params[0].c_str(), nullptr);
98 
99   g_application.SetVolume(volume);
100   if(oldVolume != volume)
101   {
102     if(params.size() > 1 && StringUtils::EqualsNoCase(params[1], "showVolumeBar"))
103     {
104       CApplicationMessenger::GetInstance().PostMsg(TMSG_VOLUME_SHOW, oldVolume < volume ? ACTION_VOLUME_UP : ACTION_VOLUME_DOWN);
105     }
106   }
107 
108   return 0;
109 }
110 
111 /*! \brief Toggle debug info.
112  *  \param params (ignored)
113  */
ToggleDebug(const std::vector<std::string> & params)114 static int ToggleDebug(const std::vector<std::string>& params)
115 {
116   bool debug = CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_DEBUG_SHOWLOGINFO);
117   CServiceBroker::GetSettingsComponent()->GetSettings()->SetBool(CSettings::SETTING_DEBUG_SHOWLOGINFO, !debug);
118   CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->SetDebugMode(!debug);
119 
120   return 0;
121 }
122 
123 /*! \brief Toggle DPMS state.
124  *  \param params (ignored)
125  */
ToggleDPMS(const std::vector<std::string> & params)126 static int ToggleDPMS(const std::vector<std::string>& params)
127 {
128   g_application.ToggleDPMS(true);
129 
130   return 0;
131 }
132 
133 /*! \brief Send a WOL packet to a given host.
134  *  \param params The parameters.
135  *  \details params[0] = The MAC of the host to wake.
136  */
WakeOnLAN(const std::vector<std::string> & params)137 static int WakeOnLAN(const std::vector<std::string>& params)
138 {
139   CServiceBroker::GetNetwork().WakeOnLan(params[0].c_str());
140 
141   return 0;
142 }
143 
144 // Note: For new Texts with comma add a "\" before!!! Is used for table text.
145 //
146 /// \page page_List_of_built_in_functions
147 /// \section built_in_functions_3 Application built-in's
148 ///
149 /// -----------------------------------------------------------------------------
150 ///
151 /// \table_start
152 ///   \table_h2_l{
153 ///     Function,
154 ///     Description }
155 ///   \table_row2_l{
156 ///     <b>`Extract(url [\, dest])`</b>
157 ///     ,
158 ///     Extracts a specified archive to an optionally specified 'absolute' path.
159 ///     @param[in] url                   The archive URL.
160 ///     @param[in] dest                  Destination path (optional).
161 ///             @note If not given\, extracts to folder with archive.
162 ///   }
163 ///   \table_row2_l{
164 ///     <b>`Mute`</b>
165 ///     ,
166 ///     Mutes (or unmutes) the volume.
167 ///   }
168 ///   \table_row2_l{
169 ///     <b>`NotifyAll(sender\, data [\, json])`</b>
170 ///     ,
171 ///     Notify all connected clients
172 ///     @param[in] sender                 Sender.
173 ///     @param[in] data                   Data.
174 ///     @param[in] json                   JSON with extra parameters (optional).
175 ///   }
176 ///   \table_row2_l{
177 ///     <b>`SetVolume(percent[\,showvolumebar])`</b>
178 ///     ,
179 ///     Sets the volume to the percentage specified. Optionally\, show the Volume
180 ///     Dialog in Kodi when setting the volume.
181 ///     @param[in] percent               Volume level.
182 ///     @param[in] showvolumebar         Add "showVolumeBar" to show volume bar (optional).
183 ///   }
184 ///   \table_row2_l{
185 ///     <b>`ToggleDebug`</b>
186 ///     ,
187 ///     Toggles debug mode on/off
188 ///   }
189 ///   \table_row2_l{
190 ///     <b>`ToggleDPMS`</b>
191 ///     ,
192 ///     Toggle DPMS mode manually
193 ///   }
194 ///   \table_row2_l{
195 ///     <b>`WakeOnLan(mac)`</b>
196 ///     ,
197 ///     Sends the wake-up packet to the broadcast address for the specified MAC
198 ///     address (Format: FF:FF:FF:FF:FF:FF or FF-FF-FF-FF-FF-FF).
199 ///     @param[in] mac                   The MAC of the host to wake.
200 ///   }
201 ///  \table_end
202 ///
203 
GetOperations() const204 CBuiltins::CommandMap CApplicationBuiltins::GetOperations() const
205 {
206   return {
207            {"extract", {"Extracts the specified archive", 1, Extract}},
208            {"mute", {"Mute the player", 0, Mute}},
209            {"notifyall", {"Notify all connected clients", 2, NotifyAll}},
210            {"setvolume", {"Set the current volume", 1, SetVolume}},
211            {"toggledebug", {"Enables/disables debug mode", 0, ToggleDebug}},
212            {"toggledpms", {"Toggle DPMS mode manually", 0, ToggleDPMS}},
213            {"wakeonlan", {"Sends the wake-up packet to the broadcast address for the specified MAC address", 1, WakeOnLAN}}
214          };
215 }
216