melunko@650
|
1 |
|
melunko@650
|
2 |
#ifdef HAVE_CONFIG_H
|
melunko@650
|
3 |
#include "config.h"
|
melunko@650
|
4 |
#endif
|
melunko@650
|
5 |
|
melunko@650
|
6 |
#include <stdio.h>
|
melunko@650
|
7 |
#include <glib.h>
|
melunko@650
|
8 |
|
melunko@650
|
9 |
#include "gmyth_backendinfo.h"
|
melunko@650
|
10 |
#include "gmyth_scheduler.h"
|
melunko@650
|
11 |
#include "gmyth_util.h"
|
melunko@650
|
12 |
#include "gmyth_epg.h"
|
melunko@650
|
13 |
|
renatofilho@754
|
14 |
typedef struct {
|
renatofilho@754
|
15 |
GMythBackendInfo *b_info;
|
renatofilho@754
|
16 |
gboolean list_channels;
|
ali@951
|
17 |
gboolean list_rules;
|
ali@951
|
18 |
gboolean list_upcoming;
|
melunko@650
|
19 |
} ls_options_t;
|
melunko@650
|
20 |
|
renatofilho@750
|
21 |
static ls_options_t *
|
renatofilho@750
|
22 |
_ls_options_new()
|
melunko@650
|
23 |
{
|
renatofilho@754
|
24 |
ls_options_t *options = g_new0(ls_options_t, 1);
|
renatofilho@754
|
25 |
options->b_info = gmyth_backend_info_new();
|
melunko@650
|
26 |
|
renatofilho@754
|
27 |
return options;
|
melunko@650
|
28 |
}
|
melunko@650
|
29 |
|
melunko@650
|
30 |
static void
|
renatofilho@750
|
31 |
_ls_options_free(ls_options_t * options)
|
melunko@650
|
32 |
{
|
renatofilho@754
|
33 |
g_return_if_fail(options != NULL);
|
melunko@650
|
34 |
|
renatofilho@754
|
35 |
if (options->b_info)
|
renatofilho@754
|
36 |
g_object_unref(options->b_info);
|
melunko@650
|
37 |
}
|
melunko@650
|
38 |
|
renatofilho@754
|
39 |
static gboolean
|
renatofilho@750
|
40 |
_parse_args(int argc, char *argv[], ls_options_t * options)
|
melunko@650
|
41 |
{
|
renatofilho@754
|
42 |
GError *error = NULL;
|
renatofilho@754
|
43 |
GOptionContext *context;
|
melunko@650
|
44 |
|
renatofilho@754
|
45 |
gchar *host_ip = NULL;
|
ali@951
|
46 |
gint host_port = 6543;
|
melunko@820
|
47 |
gint db_port = 0;
|
renatofilho@754
|
48 |
gchar *username = NULL;
|
renatofilho@754
|
49 |
gchar *password = NULL;
|
melunko@650
|
50 |
|
renatofilho@754
|
51 |
GOptionEntry entries[] = {
|
renatofilho@754
|
52 |
{"hostname", 'h', 0, G_OPTION_ARG_STRING, &host_ip,
|
renatofilho@754
|
53 |
"Mythtv backend hostname or " "IP address", "IP_ADDRESS"},
|
melunko@650
|
54 |
|
renatofilho@754
|
55 |
{"port", 'p', 0, G_OPTION_ARG_INT, &host_port,
|
renatofilho@754
|
56 |
"Mythtv backend port",
|
renatofilho@754
|
57 |
"PORT"},
|
melunko@650
|
58 |
|
ali@951
|
59 |
{"list_channels", 'c', 0, G_OPTION_ARG_NONE, &options->list_channels,
|
ali@951
|
60 |
"List channels", NULL},
|
melunko@650
|
61 |
|
ali@951
|
62 |
{"list_rules", 'r', 0, G_OPTION_ARG_NONE, &options->list_rules,
|
ali@951
|
63 |
"List recording rules", NULL},
|
ali@951
|
64 |
|
ali@951
|
65 |
{"list_upcoming", 'u', 0, G_OPTION_ARG_NONE, &options->list_upcoming,
|
ali@951
|
66 |
"List upcoming recordings", NULL},
|
ali@951
|
67 |
|
ali@951
|
68 |
{"username", 'n', 0, G_OPTION_ARG_STRING, &username,
|
melunko@820
|
69 |
"Mysql database username. Default: mythtv",
|
renatofilho@754
|
70 |
"MYSQL_USER"},
|
melunko@650
|
71 |
|
renatofilho@754
|
72 |
{"password", 'w', 0, G_OPTION_ARG_STRING, &password,
|
melunko@820
|
73 |
"Mysql database password. Default: mythtv",
|
renatofilho@754
|
74 |
"MYSQL_PASSWD"},
|
melunko@650
|
75 |
|
melunko@820
|
76 |
{"db_port", 'P', 0, G_OPTION_ARG_STRING, &db_port,
|
melunko@820
|
77 |
"Mysql database port. Default: 0",
|
melunko@820
|
78 |
"MYSQL_PORT"},
|
melunko@820
|
79 |
|
renatofilho@754
|
80 |
{NULL}
|
renatofilho@754
|
81 |
};
|
melunko@650
|
82 |
|
renatofilho@754
|
83 |
g_return_val_if_fail(options != NULL, FALSE);
|
melunko@650
|
84 |
|
ali@951
|
85 |
context = g_option_context_new("- list mythtv recorded programs etc.");
|
renatofilho@754
|
86 |
g_option_context_add_main_entries(context, entries, NULL);
|
renatofilho@754
|
87 |
g_option_context_parse(context, &argc, &argv, &error);
|
melunko@650
|
88 |
|
renatofilho@754
|
89 |
g_option_context_free(context);
|
melunko@650
|
90 |
|
ali@951
|
91 |
if (error) {
|
ali@951
|
92 |
g_printerr("%s.\n", error->message);
|
ali@951
|
93 |
g_error_free(error);
|
renatofilho@754
|
94 |
g_free(host_ip);
|
renatofilho@754
|
95 |
return FALSE;
|
renatofilho@754
|
96 |
}
|
melunko@650
|
97 |
|
ali@951
|
98 |
if (!!options->list_channels + !!options->list_rules +
|
ali@951
|
99 |
!!options->list_upcoming > 1) {
|
ali@951
|
100 |
g_printerr("Only one --list option may be given.\n");
|
ali@951
|
101 |
g_free(host_ip);
|
ali@951
|
102 |
return FALSE;
|
ali@951
|
103 |
}
|
ali@951
|
104 |
|
ali@951
|
105 |
gmyth_backend_info_set_hostname(options->b_info,
|
ali@951
|
106 |
host_ip ? host_ip : "localhost");
|
renatofilho@754
|
107 |
gmyth_backend_info_set_port(options->b_info, host_port);
|
melunko@650
|
108 |
|
renatofilho@754
|
109 |
if (username)
|
renatofilho@754
|
110 |
gmyth_backend_info_set_username(options->b_info, username);
|
renatofilho@754
|
111 |
else
|
renatofilho@754
|
112 |
gmyth_backend_info_set_username(options->b_info, "mythtv");
|
melunko@650
|
113 |
|
renatofilho@754
|
114 |
if (password)
|
renatofilho@754
|
115 |
gmyth_backend_info_set_password(options->b_info, password);
|
renatofilho@754
|
116 |
else
|
renatofilho@754
|
117 |
gmyth_backend_info_set_password(options->b_info, "mythtv");
|
melunko@650
|
118 |
|
renatofilho@754
|
119 |
gmyth_backend_info_set_db_name(options->b_info, "mythconverg");
|
melunko@650
|
120 |
|
ali@951
|
121 |
g_free(host_ip);
|
renatofilho@750
|
122 |
|
ali@951
|
123 |
return TRUE;
|
ali@951
|
124 |
}
|
ali@951
|
125 |
|
ali@951
|
126 |
static gboolean
|
ali@951
|
127 |
_ls_recording_rules(ls_options_t * options)
|
ali@951
|
128 |
{
|
ali@951
|
129 |
GMythScheduler *scheduler;
|
ali@951
|
130 |
GList *list,
|
ali@951
|
131 |
*iter;
|
ali@951
|
132 |
gint res = 0,
|
ali@951
|
133 |
count = 0;
|
ali@951
|
134 |
|
ali@951
|
135 |
g_return_val_if_fail(options != NULL, FALSE);
|
ali@951
|
136 |
g_return_val_if_fail(options->b_info != NULL, FALSE);
|
ali@951
|
137 |
|
ali@951
|
138 |
scheduler = gmyth_scheduler_new();
|
ali@951
|
139 |
|
ali@951
|
140 |
if (gmyth_scheduler_connect_with_timeout(scheduler,
|
ali@951
|
141 |
options->b_info, 10) == FALSE)
|
ali@951
|
142 |
{
|
ali@951
|
143 |
g_print("Could not connect to database server.\n");
|
ali@951
|
144 |
g_object_unref(scheduler);
|
ali@951
|
145 |
return FALSE;
|
ali@951
|
146 |
}
|
ali@951
|
147 |
|
ali@951
|
148 |
res = gmyth_scheduler_get_schedule_list(scheduler, &list);
|
ali@951
|
149 |
|
ali@951
|
150 |
gmyth_scheduler_disconnect(scheduler);
|
ali@951
|
151 |
g_object_unref(scheduler);
|
ali@951
|
152 |
|
ali@951
|
153 |
if (res < 0) {
|
ali@951
|
154 |
g_print("Could not retrieve list of recording rules.\n");
|
ali@951
|
155 |
return FALSE;
|
ali@951
|
156 |
}
|
ali@951
|
157 |
|
ali@951
|
158 |
iter = list;
|
ali@951
|
159 |
while (iter) {
|
ali@951
|
160 |
ScheduleInfo *schedule_info = (ScheduleInfo *) iter->data;
|
ali@951
|
161 |
|
ali@951
|
162 |
count++;
|
ali@951
|
163 |
g_print("%s\n", schedule_info->title->str);
|
ali@951
|
164 |
gmyth_schedule_info_free(schedule_info);
|
ali@951
|
165 |
iter = g_list_next(iter);
|
ali@951
|
166 |
}
|
ali@951
|
167 |
|
ali@951
|
168 |
if (!count)
|
ali@951
|
169 |
g_print("No recording rules.\n");
|
ali@951
|
170 |
|
ali@951
|
171 |
g_list_free(list);
|
ali@951
|
172 |
|
ali@951
|
173 |
return TRUE;
|
ali@951
|
174 |
}
|
ali@951
|
175 |
|
ali@951
|
176 |
static gboolean
|
ali@951
|
177 |
_ls_upcoming_recordings(ls_options_t * options)
|
ali@951
|
178 |
{
|
ali@951
|
179 |
GSList *list,
|
ali@951
|
180 |
*iter;
|
ali@951
|
181 |
gint count = 0;
|
ali@951
|
182 |
gboolean conflicts;
|
ali@951
|
183 |
time_t recstart;
|
ali@951
|
184 |
struct tm *tm;
|
ali@951
|
185 |
char buffer[64];
|
ali@951
|
186 |
|
ali@951
|
187 |
g_return_val_if_fail(options != NULL, FALSE);
|
ali@951
|
188 |
g_return_val_if_fail(options->b_info != NULL, FALSE);
|
ali@951
|
189 |
|
ali@951
|
190 |
list = gmyth_util_get_all_pending(options->b_info, &conflicts);
|
ali@951
|
191 |
|
ali@951
|
192 |
iter = list;
|
ali@951
|
193 |
while (iter) {
|
ali@951
|
194 |
GMythProgramInfo *program = (GMythProgramInfo *) iter->data;
|
ali@951
|
195 |
|
ali@951
|
196 |
if (program->recstatus == GMYTH_REC_STATUS_RECORDING ||
|
ali@951
|
197 |
program->recstatus == GMYTH_REC_STATUS_WILL_RECORD) {
|
ali@951
|
198 |
count++;
|
ali@951
|
199 |
recstart = program->recstartts->tv_sec;
|
ali@951
|
200 |
tm = localtime(&recstart);
|
ali@951
|
201 |
strftime(buffer, sizeof(buffer), "%F %R", tm);
|
ali@951
|
202 |
g_print("%s %s", buffer, program->title->str);
|
ali@951
|
203 |
if (program->subtitle->len)
|
ali@951
|
204 |
g_print(": %s", program->subtitle->str);
|
ali@951
|
205 |
g_print("\n");
|
ali@951
|
206 |
}
|
ali@951
|
207 |
|
ali@951
|
208 |
g_object_unref(program);
|
ali@951
|
209 |
iter = g_slist_next(iter);
|
ali@951
|
210 |
}
|
ali@951
|
211 |
|
ali@951
|
212 |
if (!count)
|
ali@951
|
213 |
g_print("No upcoming recordings.\n");
|
ali@951
|
214 |
else if (conflicts)
|
ali@951
|
215 |
g_print("Conflicts found.\n");
|
ali@951
|
216 |
else
|
ali@951
|
217 |
g_print("No conflicts found.\n");
|
ali@951
|
218 |
|
ali@951
|
219 |
g_slist_free(list);
|
renatofilho@750
|
220 |
|
renatofilho@754
|
221 |
return TRUE;
|
melunko@650
|
222 |
}
|
melunko@650
|
223 |
|
renatofilho@754
|
224 |
static gboolean
|
renatofilho@750
|
225 |
_ls_recorded_files(ls_options_t * options)
|
melunko@650
|
226 |
{
|
renatofilho@754
|
227 |
GMythScheduler *scheduler;
|
renatofilho@754
|
228 |
GList *list,
|
renatofilho@754
|
229 |
*iter;
|
ali@949
|
230 |
gint res = 0,
|
ali@949
|
231 |
count = 0;
|
ali@950
|
232 |
GMythSocket *socket;
|
ali@950
|
233 |
GString *path;
|
ali@950
|
234 |
GMythProgramInfo *program;
|
melunko@650
|
235 |
|
renatofilho@754
|
236 |
g_return_val_if_fail(options != NULL, FALSE);
|
renatofilho@754
|
237 |
g_return_val_if_fail(options->b_info != NULL, FALSE);
|
melunko@650
|
238 |
|
renatofilho@754
|
239 |
scheduler = gmyth_scheduler_new();
|
melunko@650
|
240 |
|
renatofilho@754
|
241 |
if (gmyth_scheduler_connect_with_timeout(scheduler,
|
renatofilho@754
|
242 |
options->b_info, 10) == FALSE)
|
renatofilho@754
|
243 |
{
|
ali@949
|
244 |
g_print("Could not connect to database server.\n");
|
renatofilho@754
|
245 |
g_object_unref(scheduler);
|
renatofilho@754
|
246 |
return FALSE;
|
renatofilho@754
|
247 |
}
|
melunko@650
|
248 |
|
renatofilho@754
|
249 |
res = gmyth_scheduler_get_recorded_list(scheduler, &list);
|
melunko@650
|
250 |
|
renatofilho@754
|
251 |
gmyth_scheduler_disconnect(scheduler);
|
ali@949
|
252 |
g_object_unref(scheduler);
|
melunko@650
|
253 |
|
ali@949
|
254 |
if (res < 0) {
|
ali@949
|
255 |
g_print("Could not retrieve list of recorded programs.\n");
|
ali@949
|
256 |
return FALSE;
|
renatofilho@754
|
257 |
}
|
melunko@650
|
258 |
|
renatofilho@754
|
259 |
iter = list;
|
ali@950
|
260 |
socket = gmyth_backend_info_get_connected_socket(options->b_info);
|
renatofilho@754
|
261 |
while (iter) {
|
renatofilho@754
|
262 |
RecordedInfo *recorded_info = (RecordedInfo *) iter->data;
|
melunko@650
|
263 |
|
ali@950
|
264 |
program = gmyth_program_info_new();
|
ali@950
|
265 |
program->pathname = g_string_new(recorded_info->basename->str);
|
ali@950
|
266 |
program->channel_id = recorded_info->channel_id;
|
ali@950
|
267 |
program->recstartts = g_memdup(recorded_info->start_time,
|
ali@950
|
268 |
sizeof(*program->startts));
|
ali@950
|
269 |
path = gmyth_util_check_file_from_socket(socket, program);
|
ali@950
|
270 |
if (path) {
|
ali@949
|
271 |
count++;
|
renatofilho@754
|
272 |
g_print("%s\n", recorded_info->basename->str);
|
ali@950
|
273 |
g_string_free(path, TRUE);
|
renatofilho@754
|
274 |
}
|
renatofilho@754
|
275 |
gmyth_recorded_info_free(recorded_info);
|
ali@950
|
276 |
g_object_unref(program);
|
renatofilho@754
|
277 |
iter = g_list_next(iter);
|
renatofilho@754
|
278 |
}
|
ali@950
|
279 |
g_object_unref(socket);
|
melunko@650
|
280 |
|
ali@949
|
281 |
if (!count)
|
ali@949
|
282 |
g_print("No recorded programs.\n");
|
ali@949
|
283 |
|
renatofilho@754
|
284 |
g_list_free(list);
|
melunko@650
|
285 |
|
renatofilho@754
|
286 |
return TRUE;
|
melunko@650
|
287 |
}
|
melunko@650
|
288 |
|
renatofilho@754
|
289 |
static gboolean
|
renatofilho@750
|
290 |
_ls_channels(ls_options_t * options)
|
melunko@650
|
291 |
{
|
renatofilho@754
|
292 |
GMythEPG *epg;
|
renatofilho@754
|
293 |
gint length;
|
renatofilho@754
|
294 |
GList *clist,
|
renatofilho@754
|
295 |
*ch;
|
melunko@650
|
296 |
|
renatofilho@754
|
297 |
g_return_val_if_fail(options != NULL, FALSE);
|
renatofilho@754
|
298 |
g_return_val_if_fail(options->b_info != NULL, FALSE);
|
melunko@650
|
299 |
|
melunko@650
|
300 |
|
renatofilho@754
|
301 |
epg = gmyth_epg_new();
|
renatofilho@754
|
302 |
if (!gmyth_epg_connect(epg, options->b_info)) {
|
renatofilho@754
|
303 |
g_object_unref(epg);
|
renatofilho@754
|
304 |
return FALSE;
|
renatofilho@754
|
305 |
}
|
melunko@650
|
306 |
|
renatofilho@754
|
307 |
length = gmyth_epg_get_channel_list(epg, &clist);
|
renatofilho@754
|
308 |
for (ch = clist; ch != NULL; ch = ch->next) {
|
renatofilho@754
|
309 |
GMythChannelInfo *info = (GMythChannelInfo *) ch->data;
|
melunko@650
|
310 |
|
renatofilho@754
|
311 |
if ((info->channel_name == NULL) || (info->channel_num == NULL)) {
|
renatofilho@754
|
312 |
continue;
|
renatofilho@754
|
313 |
}
|
melunko@650
|
314 |
|
renatofilho@754
|
315 |
g_print("%s\t\t%s\n", info->channel_num->str,
|
renatofilho@754
|
316 |
info->channel_name->str);
|
renatofilho@754
|
317 |
}
|
melunko@650
|
318 |
|
renatofilho@754
|
319 |
gmyth_free_channel_list(clist);
|
renatofilho@754
|
320 |
gmyth_epg_disconnect(epg);
|
renatofilho@754
|
321 |
g_object_unref(epg);
|
renatofilho@750
|
322 |
|
renatofilho@754
|
323 |
return TRUE;
|
melunko@650
|
324 |
}
|
melunko@650
|
325 |
|
melunko@650
|
326 |
int
|
renatofilho@750
|
327 |
main(int argc, char *argv[])
|
melunko@650
|
328 |
{
|
renatofilho@754
|
329 |
gboolean res = FALSE;
|
renatofilho@754
|
330 |
ls_options_t *options;
|
melunko@650
|
331 |
|
renatofilho@754
|
332 |
g_type_init();
|
renatofilho@754
|
333 |
g_thread_init(NULL);
|
melunko@650
|
334 |
|
renatofilho@754
|
335 |
options = _ls_options_new();
|
renatofilho@754
|
336 |
res = _parse_args(argc, argv, options);
|
renatofilho@754
|
337 |
if (!res) {
|
renatofilho@754
|
338 |
g_printerr("Argument invalid. Type --help\n");
|
renatofilho@754
|
339 |
return 1;
|
renatofilho@754
|
340 |
}
|
melunko@650
|
341 |
|
renatofilho@754
|
342 |
if (options->list_channels)
|
renatofilho@754
|
343 |
res = _ls_channels(options);
|
ali@951
|
344 |
else if (options->list_rules)
|
ali@951
|
345 |
res = _ls_recording_rules(options);
|
ali@951
|
346 |
else if (options->list_upcoming)
|
ali@951
|
347 |
res = _ls_upcoming_recordings(options);
|
renatofilho@754
|
348 |
else
|
renatofilho@754
|
349 |
res = _ls_recorded_files(options);
|
melunko@650
|
350 |
|
renatofilho@754
|
351 |
_ls_options_free(options);
|
melunko@650
|
352 |
|
renatofilho@754
|
353 |
return 0;
|
melunko@650
|
354 |
}
|