libgnomevfs2-mythtv/modules/mythtv-method.c
author leo_sobral
Fri Mar 23 22:54:24 2007 +0000 (2007-03-23)
branchtrunk
changeset 446 d260ed30f4de
parent 408 7d529c58a88f
child 447 c632a2009bee
permissions -rwxr-xr-x
[svn r451] various memory leaks and object counting fixed
melunko@38
     1
/*
melunko@38
     2
 * @author Hallyson Melo <hallyson.melo@indt.org.br>
melunko@38
     3
 *
melunko@38
     4
 * This program is free software; you can redistribute it and/or modify
melunko@38
     5
 * it under the terms of the GNU Lesser General Public License as published by
melunko@38
     6
 * the Free Software Foundation; either version 2 of the License, or
melunko@38
     7
 * (at your option) any later version.
melunko@38
     8
 *
melunko@38
     9
 * This program is distributed in the hope that it will be useful,
melunko@38
    10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
melunko@38
    11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
melunko@38
    12
 * GNU General Public License for more details.
melunko@38
    13
 *
melunko@38
    14
 * You should have received a copy of the GNU Lesser General Public License
melunko@38
    15
 * along with this program; if not, write to the Free Software
melunko@38
    16
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
melunko@38
    17
 */
melunko@38
    18
melunko@38
    19
#ifdef HAVE_CONFIG_H
melunko@38
    20
#include <config.h>
melunko@38
    21
#endif
melunko@38
    22
melunko@38
    23
#include <string.h>
melunko@38
    24
#include <glib.h>
leo_sobral@441
    25
#include <glib/gprintf.h>
leo_sobral@441
    26
#include <glib/gstdio.h>
melunko@38
    27
#include <math.h>
melunko@38
    28
melunko@38
    29
#include <libgnomevfs/gnome-vfs-module.h>
melunko@38
    30
#include <libgnomevfs/gnome-vfs-utils.h>
melunko@38
    31
rosfran@277
    32
#include <gmyth/gmyth_file_transfer.h>
rosfran@277
    33
#include <gmyth/gmyth_livetv.h>
rosfran@277
    34
#include <gmyth/gmyth_uri.h>
rosfran@277
    35
#include <gmyth/gmyth_recorder.h>
rosfran@277
    36
#include <gmyth/gmyth_backendinfo.h>
rosfran@277
    37
#include <gmyth/gmyth_util.h>
rosfran@332
    38
#include <gmyth/gmyth_remote_util.h>
rosfran@332
    39
#include <gmyth/gmyth_tvchain.h>
rosfran@357
    40
#include <gmyth/gmyth_programinfo.h>
melunko@38
    41
melunko@38
    42
#define GST_MYTHTV_ID_NUM               1
melunko@38
    43
#define MYTHTV_VERSION_DEFAULT          30
rosfran@277
    44
#define MYTHTV_TRANSFER_MAX_WAITS       100
melunko@38
    45
rosfran@361
    46
/* internal GnomeVFS plug-in buffer size ( 120 Kbytes ) */
leo_sobral@441
    47
#define MYTHTV_BUFFER_SIZE                          80*1024
rosfran@361
    48
/* internally sized GnomeVFS plug-in buffer ( 4 Kbytes ) */
leo_sobral@441
    49
#define MYTHTV_MAX_VFS_BUFFER_SIZE                  4096
rosfran@361
    50
/* maximum number of bytes to be requested to the MythTV backend ( 64 Kbytes ) */
leo_sobral@441
    51
#define MYTHTV_MAX_REQUEST_SIZE                     64*1024
melunko@111
    52
renatofilho@367
    53
static GnomeVFSResult do_read (GnomeVFSMethod * method,
renatofilho@367
    54
			       GnomeVFSMethodHandle * method_handle,
renatofilho@367
    55
			       gpointer buffer,
renatofilho@367
    56
			       GnomeVFSFileSize num_bytes,
renatofilho@367
    57
			       GnomeVFSFileSize * bytes_read,
renatofilho@367
    58
			       GnomeVFSContext * context);
melunko@38
    59
melunko@38
    60
typedef struct {
renatofilho@367
    61
	GMythFileTransfer *file_transfer;
renatofilho@367
    62
	GMythLiveTV *livetv;
renatofilho@367
    63
	gchar *channel_name;
melunko@111
    64
renatofilho@367
    65
	gint mythtv_version;
renatofilho@367
    66
	gint64 content_size;
renatofilho@367
    67
	guint64 bytes_read;
renatofilho@367
    68
renatofilho@367
    69
	GByteArray *buffer;
renatofilho@367
    70
	gsize buffer_remain;
renatofilho@367
    71
	gboolean is_livetv;
renatofilho@367
    72
renatofilho@367
    73
	gboolean configured;
renatofilho@367
    74
melunko@38
    75
} MythtvHandle;
melunko@38
    76
rosfran@357
    77
//static MythtvHandle *myth_handle = NULL;
leo_sobral@441
    78
#ifdef DEBUG
leo_sobral@441
    79
static FILE *fpout = NULL;
leo_sobral@441
    80
static gboolean first = TRUE;
leo_sobral@441
    81
#endif
rosfran@357
    82
melunko@38
    83
static GnomeVFSResult
renatofilho@367
    84
do_open (GnomeVFSMethod * method,
renatofilho@367
    85
	 GnomeVFSMethodHandle ** method_handle,
renatofilho@367
    86
	 GnomeVFSURI * uri,
renatofilho@367
    87
	 GnomeVFSOpenMode mode, GnomeVFSContext * context)
renatofilho@367
    88
{
renatofilho@367
    89
	MythtvHandle *myth_handle = NULL;
renatofilho@367
    90
	GMythBackendInfo *backend_info = NULL;
renatofilho@367
    91
	GMythURI *gmyth_uri = NULL;
renatofilho@367
    92
	gboolean ret = TRUE;
melunko@38
    93
renatofilho@367
    94
	_GNOME_VFS_METHOD_PARAM_CHECK (method_handle != NULL);
renatofilho@367
    95
	_GNOME_VFS_METHOD_PARAM_CHECK (uri != NULL);
melunko@38
    96
renatofilho@367
    97
	if (mode & GNOME_VFS_OPEN_WRITE) {
renatofilho@367
    98
		return GNOME_VFS_ERROR_NOT_PERMITTED;
renatofilho@367
    99
	}
melunko@38
   100
renatofilho@367
   101
	if (gnome_vfs_uri_get_host_name (uri) == NULL) {
renatofilho@367
   102
		return GNOME_VFS_ERROR_INVALID_HOST_NAME;
renatofilho@367
   103
	}
renatofilho@367
   104
leo_sobral@441
   105
    // FIXME: myth_handle is always NULL here
renatofilho@367
   106
	if ((NULL == myth_handle) || !myth_handle->configured) {
renatofilho@367
   107
		myth_handle = g_new0 (MythtvHandle, 1);
renatofilho@367
   108
renatofilho@367
   109
		myth_handle->configured = FALSE;
renatofilho@367
   110
renatofilho@367
   111
		myth_handle->is_livetv = FALSE;
renatofilho@367
   112
renatofilho@367
   113
		/* Initialize mythtv handler */
renatofilho@367
   114
		myth_handle->file_transfer = NULL;
renatofilho@367
   115
		myth_handle->livetv = NULL;
renatofilho@367
   116
		myth_handle->mythtv_version = MYTHTV_VERSION_DEFAULT;
renatofilho@367
   117
		myth_handle->bytes_read = 0;
renatofilho@367
   118
		myth_handle->content_size = (GnomeVFSFileSize) - 1;
renatofilho@367
   119
renatofilho@367
   120
		/* Creates and fills out the backend info structure */
renatofilho@367
   121
		backend_info =
renatofilho@367
   122
		    gmyth_backend_info_new_with_uri
renatofilho@367
   123
		    (gnome_vfs_unescape_string
renatofilho@367
   124
		     (gnome_vfs_uri_to_string
renatofilho@367
   125
		      (uri, GNOME_VFS_URI_HIDE_NONE), ""));
renatofilho@367
   126
renatofilho@367
   127
		/* creates an instance of  */
renatofilho@367
   128
		gmyth_uri =
renatofilho@367
   129
		    gmyth_uri_new_with_value (gnome_vfs_unescape_string
renatofilho@367
   130
					      (gnome_vfs_uri_to_string
renatofilho@367
   131
					       (uri,
renatofilho@367
   132
						GNOME_VFS_URI_HIDE_NONE),
renatofilho@367
   133
					       ""));
renatofilho@367
   134
renatofilho@367
   135
		myth_handle->is_livetv = gmyth_uri_is_livetv (gmyth_uri);
renatofilho@367
   136
renatofilho@367
   137
		/* Connect to the backend */
renatofilho@367
   138
		if (gmyth_uri != NULL && myth_handle->is_livetv == TRUE) {
renatofilho@367
   139
renatofilho@367
   140
			if (NULL == myth_handle->livetv) {
leo_sobral@441
   141
				myth_handle->livetv = gmyth_livetv_new (backend_info);
renatofilho@367
   142
renatofilho@367
   143
				myth_handle->channel_name =
renatofilho@367
   144
				    gmyth_uri_get_channel_name (gmyth_uri);
renatofilho@367
   145
renatofilho@367
   146
				g_debug ("[%s] Channel name = %s\n",
renatofilho@367
   147
					 __FUNCTION__,
renatofilho@367
   148
					 myth_handle->channel_name);
renatofilho@367
   149
renatofilho@367
   150
				if (myth_handle->channel_name != NULL) {
leo_sobral@441
   151
					if (gmyth_livetv_channel_name_setup (myth_handle->livetv,
leo_sobral@441
   152
    					     myth_handle->channel_name) == FALSE) {
renatofilho@367
   153
						g_object_unref (gmyth_uri);
rosfran@357
   154
						ret = FALSE;
rosfran@357
   155
					}
renatofilho@367
   156
				} else {
leo_sobral@441
   157
					if (gmyth_livetv_setup (myth_handle->livetv) == FALSE) {
renatofilho@367
   158
						g_object_unref (gmyth_uri);
renatofilho@367
   159
						ret = FALSE;
renatofilho@367
   160
					}
renatofilho@367
   161
				}
renatofilho@367
   162
			}
melunko@38
   163
renatofilho@367
   164
			if (NULL == myth_handle->file_transfer) {
renatofilho@367
   165
				myth_handle->file_transfer =
leo_sobral@441
   166
				    gmyth_livetv_create_file_transfer (myth_handle->livetv);
renatofilho@367
   167
renatofilho@367
   168
				if (NULL == myth_handle->file_transfer) {
renatofilho@367
   169
					ret = FALSE;
renatofilho@367
   170
					g_debug
renatofilho@367
   171
					    ("MythTV FileTransfer is NULL!\n");
renatofilho@367
   172
					return GNOME_VFS_ERROR_NOT_OPEN;
renatofilho@367
   173
				}
renatofilho@367
   174
renatofilho@367
   175
				if (!gmyth_file_transfer_open
renatofilho@367
   176
				    (myth_handle->file_transfer,
renatofilho@367
   177
				     myth_handle->livetv->uri !=
renatofilho@367
   178
				     NULL ?
renatofilho@367
   179
				     gmyth_uri_get_path (myth_handle->
renatofilho@367
   180
							 livetv->
renatofilho@367
   181
							 uri) :
renatofilho@367
   182
				     myth_handle->livetv->proginfo->
renatofilho@367
   183
				     pathname->str)) {
renatofilho@367
   184
					g_debug
renatofilho@367
   185
					    ("Couldn't open MythTV FileTransfer is NULL!\n");
renatofilho@367
   186
					g_object_unref (myth_handle->
renatofilho@367
   187
							file_transfer);
renatofilho@367
   188
					myth_handle->file_transfer = NULL;
renatofilho@367
   189
					ret = FALSE;
renatofilho@367
   190
				}
leo_sobral@441
   191
			} /* if - FileTransfer is NULL, or not */
renatofilho@367
   192
		} else {
renatofilho@367
   193
			if (NULL == myth_handle->file_transfer) {
renatofilho@367
   194
renatofilho@367
   195
				myth_handle->file_transfer =
renatofilho@367
   196
				    gmyth_file_transfer_new (backend_info);
renatofilho@367
   197
renatofilho@367
   198
				/* Verifies if the file exists */
renatofilho@367
   199
				if (!gmyth_util_file_exists
renatofilho@367
   200
				    (backend_info,
renatofilho@367
   201
				     gmyth_uri_get_path (gmyth_uri))) {
renatofilho@367
   202
					g_object_unref (backend_info);
renatofilho@367
   203
					ret = FALSE;
renatofilho@367
   204
				}
renatofilho@367
   205
renatofilho@367
   206
				/* sets the Playback monitor connection */
renatofilho@367
   207
				ret =
renatofilho@367
   208
				    gmyth_file_transfer_open (myth_handle->
renatofilho@367
   209
							      file_transfer,
renatofilho@367
   210
							      gmyth_uri_get_path
renatofilho@367
   211
							      (gmyth_uri));
renatofilho@367
   212
renatofilho@367
   213
			}
leo_sobral@441
   214
		} /* if - LiveTV or not? */
renatofilho@367
   215
renatofilho@367
   216
		if (ret == FALSE) {
renatofilho@367
   217
			g_debug ("MythTV FileTransfer open error.\n");
renatofilho@367
   218
			return GNOME_VFS_ERROR_NOT_OPEN;
renatofilho@367
   219
		}
renatofilho@367
   220
renatofilho@367
   221
		myth_handle->configured = TRUE;
renatofilho@367
   222
renatofilho@367
   223
		g_object_unref (backend_info);
renatofilho@367
   224
renatofilho@367
   225
		if (gmyth_uri != NULL)
renatofilho@367
   226
			g_object_unref (gmyth_uri);
renatofilho@367
   227
renatofilho@367
   228
		myth_handle->buffer =
renatofilho@367
   229
		    g_byte_array_sized_new (MYTHTV_BUFFER_SIZE);
renatofilho@367
   230
		myth_handle->buffer_remain = 0;
renatofilho@367
   231
renatofilho@367
   232
		g_return_val_if_fail (myth_handle->file_transfer != NULL,
renatofilho@367
   233
				      GNOME_VFS_ERROR_NOT_OPEN);
renatofilho@367
   234
renatofilho@367
   235
		if ( /*myth_handle->file_transfer->filesize <= 0 && */
renatofilho@367
   236
		    myth_handle->is_livetv) {
renatofilho@367
   237
			myth_handle->content_size =
leo_sobral@441
   238
			    gmyth_recorder_get_file_position (myth_handle->livetv->recorder);
renatofilho@367
   239
		} else {
renatofilho@367
   240
			myth_handle->content_size =
renatofilho@367
   241
			    myth_handle->file_transfer->filesize;
renatofilho@367
   242
		}
renatofilho@367
   243
renatofilho@367
   244
	}
renatofilho@367
   245
	/* if - configured or not? */
renatofilho@367
   246
	*method_handle = (GnomeVFSMethodHandle *) myth_handle;
renatofilho@367
   247
renatofilho@367
   248
	return GNOME_VFS_OK;
melunko@38
   249
}
melunko@38
   250
melunko@38
   251
static GnomeVFSResult
renatofilho@367
   252
do_read (GnomeVFSMethod * method,
renatofilho@367
   253
	 GnomeVFSMethodHandle * method_handle,
renatofilho@367
   254
	 gpointer buffer,
renatofilho@367
   255
	 GnomeVFSFileSize num_bytes,
leo_sobral@441
   256
	 GnomeVFSFileSize * bytes_read, 
leo_sobral@441
   257
     GnomeVFSContext * context)
melunko@38
   258
{
renatofilho@367
   259
	MythtvHandle *myth_handle = (MythtvHandle *) method_handle;
renatofilho@367
   260
	GnomeVFSFileSize bytes_to_read = num_bytes;
melunko@38
   261
renatofilho@367
   262
	if (!myth_handle->is_livetv
renatofilho@367
   263
	    && (myth_handle->bytes_read >= myth_handle->content_size))
renatofilho@367
   264
		return GNOME_VFS_ERROR_EOF;
melunko@38
   265
renatofilho@367
   266
	/* fixme: change this to min math function */
renatofilho@367
   267
	if ((myth_handle->content_size > 0)) {
renatofilho@367
   268
		if (!myth_handle->is_livetv &&
renatofilho@367
   269
		    (num_bytes >
renatofilho@367
   270
		     (myth_handle->content_size -
renatofilho@367
   271
		      myth_handle->bytes_read))) {
renatofilho@367
   272
			bytes_to_read =
renatofilho@367
   273
			    myth_handle->content_size -
renatofilho@367
   274
			    myth_handle->bytes_read;
renatofilho@367
   275
		}
renatofilho@367
   276
	}
melunko@38
   277
renatofilho@367
   278
	/* Loop sending the Myth File Transfer request:
renatofilho@367
   279
	 * Retry whilst authentication fails and we supply it. */
renatofilho@367
   280
	if ((myth_handle->buffer_remain =
renatofilho@367
   281
	     myth_handle->buffer->len) < bytes_to_read) {
renatofilho@367
   282
		gint buffer_size;
renatofilho@367
   283
renatofilho@367
   284
		while (MYTHTV_BUFFER_SIZE != myth_handle->buffer_remain) {
renatofilho@367
   285
			/* resize buffer length request to no more than MYTHTV_MAX_REQUEST_SIZE */
renatofilho@367
   286
			if ((MYTHTV_BUFFER_SIZE -
renatofilho@367
   287
			     myth_handle->buffer_remain) <=
renatofilho@367
   288
			    MYTHTV_MAX_REQUEST_SIZE)
renatofilho@367
   289
				buffer_size =
renatofilho@367
   290
				    MYTHTV_BUFFER_SIZE -
renatofilho@367
   291
				    myth_handle->buffer_remain;
renatofilho@367
   292
			else
renatofilho@367
   293
				buffer_size = MYTHTV_MAX_REQUEST_SIZE;
renatofilho@367
   294
renatofilho@367
   295
			GByteArray *tmp_buffer = g_byte_array_new ();
renatofilho@367
   296
leo_sobral@441
   297
			g_debug ("Asking %d bytes (there is %d bytes in the buffer)\n",
renatofilho@367
   298
			     buffer_size, myth_handle->buffer_remain);
renatofilho@367
   299
renatofilho@367
   300
			gint len =
renatofilho@367
   301
			    gmyth_file_transfer_read (myth_handle->
renatofilho@367
   302
						      file_transfer,
renatofilho@367
   303
						      tmp_buffer,
renatofilho@367
   304
						      buffer_size, TRUE);
renatofilho@367
   305
rosfran@408
   306
			if ( !myth_handle->is_livetv ) {
rosfran@408
   307
				if ( len < 0 ) {
rosfran@408
   308
					g_byte_array_free (tmp_buffer, TRUE);
rosfran@408
   309
					g_debug ("Fail to read bytes");
rosfran@408
   310
					return GNOME_VFS_ERROR_IO;
rosfran@408
   311
				} else if ( len == 0 ) {
rosfran@408
   312
				   g_byte_array_free (tmp_buffer, TRUE);
rosfran@408
   313
				   g_warning ("End of file probably achieved");
rosfran@408
   314
				   return GNOME_VFS_ERROR_EOF;
rosfran@408
   315
			   }
rosfran@408
   316
			} /* if */
rosfran@408
   317
			
renatofilho@367
   318
			myth_handle->buffer =
renatofilho@367
   319
			    g_byte_array_append (myth_handle->buffer,
renatofilho@367
   320
						 tmp_buffer->data, len);
renatofilho@367
   321
rosfran@327
   322
			myth_handle->buffer_remain += len;
melunko@111
   323
renatofilho@367
   324
			if (tmp_buffer != NULL) {
renatofilho@367
   325
				g_byte_array_free (tmp_buffer, TRUE);
renatofilho@367
   326
				tmp_buffer = NULL;
rosfran@354
   327
			}
renatofilho@367
   328
		}		/* while - iterates until fills the internal buffer */
rosfran@116
   329
renatofilho@367
   330
	}
leo_sobral@441
   331
        
renatofilho@367
   332
	/* if - got from the network, or not */
renatofilho@367
   333
	bytes_to_read =
renatofilho@367
   334
	    (bytes_to_read >
renatofilho@367
   335
	     myth_handle->buffer_remain) ? myth_handle->
renatofilho@367
   336
	    buffer_remain : bytes_to_read;
renatofilho@367
   337
	/* gets the first buffer_size bytes from the byte array buffer variable */
rosfran@116
   338
renatofilho@367
   339
	g_memmove (buffer, myth_handle->buffer->data, bytes_to_read);
renatofilho@367
   340
renatofilho@367
   341
	myth_handle->bytes_read += bytes_to_read;
renatofilho@367
   342
	myth_handle->buffer_remain -= bytes_to_read;
rosfran@116
   343
rosfran@355
   344
	/* flushs the newly buffer got from byte array */
renatofilho@367
   345
	myth_handle->buffer =
renatofilho@367
   346
	    g_byte_array_remove_range (myth_handle->buffer, 0,
renatofilho@367
   347
				       bytes_to_read);
renatofilho@367
   348
	g_debug
renatofilho@367
   349
	    ("Got from %llu bytes from internal buffer. (there are %d bytes in the buffer, from a total of %llu dispatched.)\n",
renatofilho@367
   350
	     bytes_to_read, myth_handle->buffer_remain,
renatofilho@367
   351
	     myth_handle->bytes_read);
rosfran@355
   352
renatofilho@367
   353
	*bytes_read = bytes_to_read;
renatofilho@367
   354
renatofilho@367
   355
	return GNOME_VFS_OK;
melunko@38
   356
}
melunko@38
   357
melunko@38
   358
static GnomeVFSResult
renatofilho@367
   359
do_close (GnomeVFSMethod * method,
renatofilho@367
   360
	  GnomeVFSMethodHandle * method_handle, GnomeVFSContext * context)
melunko@38
   361
{
melunko@111
   362
renatofilho@367
   363
	MythtvHandle *myth_handle = (MythtvHandle *) method_handle;
renatofilho@367
   364
renatofilho@367
   365
	//if ( NULL == myth_handle || myth_handle->configured ) {
renatofilho@367
   366
leo_sobral@441
   367
	if (myth_handle->is_livetv && myth_handle->livetv != NULL) {
leo_sobral@441
   368
		g_object_unref (myth_handle->livetv);
leo_sobral@441
   369
		myth_handle->livetv = NULL;
leo_sobral@441
   370
	}
leo_sobral@441
   371
   
renatofilho@367
   372
	if (myth_handle->file_transfer != NULL) {
renatofilho@367
   373
		g_object_unref (myth_handle->file_transfer);
renatofilho@367
   374
		myth_handle->file_transfer = NULL;
renatofilho@367
   375
	}
renatofilho@367
   376
renatofilho@367
   377
	if (myth_handle->buffer) {
renatofilho@367
   378
		g_byte_array_free (myth_handle->buffer, TRUE);
renatofilho@367
   379
		myth_handle->buffer = NULL;
renatofilho@367
   380
	}
renatofilho@367
   381
renatofilho@367
   382
	myth_handle->configured = FALSE;
renatofilho@367
   383
leo_sobral@441
   384
	g_free (myth_handle->channel_name);
leo_sobral@441
   385
    
renatofilho@367
   386
	g_free (myth_handle);
renatofilho@367
   387
renatofilho@367
   388
	myth_handle = NULL;
renatofilho@367
   389
renatofilho@367
   390
	// }
renatofilho@367
   391
renatofilho@367
   392
	return GNOME_VFS_OK;
melunko@38
   393
}
melunko@38
   394
melunko@38
   395
static GnomeVFSResult
renatofilho@367
   396
do_get_file_info (GnomeVFSMethod * method,
renatofilho@367
   397
		  GnomeVFSURI * uri,
renatofilho@367
   398
		  GnomeVFSFileInfo * file_info,
renatofilho@367
   399
		  GnomeVFSFileInfoOptions options,
renatofilho@367
   400
		  GnomeVFSContext * context)
melunko@38
   401
{
renatofilho@367
   402
	GMythFileTransfer *file_transfer = NULL;
renatofilho@367
   403
	GMythRecorder *recorder = NULL;
renatofilho@367
   404
	GMythTVChain *tvchain = NULL;
renatofilho@367
   405
	GMythBackendInfo *backend_info = NULL;
renatofilho@367
   406
	GMythURI *gmyth_uri = NULL;
renatofilho@367
   407
	GMythSocket *socket = NULL;
renatofilho@367
   408
	gboolean is_livetv = FALSE;
renatofilho@367
   409
	gboolean ret = TRUE;
renatofilho@367
   410
	gboolean res = TRUE;
renatofilho@188
   411
renatofilho@367
   412
	/* Creates and fills out the backend info structure */
renatofilho@367
   413
	backend_info =
renatofilho@367
   414
	    gmyth_backend_info_new_with_uri (gnome_vfs_unescape_string
renatofilho@367
   415
					     (gnome_vfs_uri_to_string
renatofilho@367
   416
					      (uri,
renatofilho@367
   417
					       GNOME_VFS_URI_HIDE_NONE),
renatofilho@367
   418
					      ""));
rosfran@297
   419
renatofilho@367
   420
	/* creates an instance of */
renatofilho@367
   421
	gmyth_uri =
renatofilho@367
   422
	    gmyth_uri_new_with_value (gnome_vfs_unescape_string
renatofilho@367
   423
				      (gnome_vfs_uri_to_string
renatofilho@367
   424
				       (uri, GNOME_VFS_URI_HIDE_NONE),
renatofilho@367
   425
				       ""));
melunko@38
   426
renatofilho@367
   427
	is_livetv = gmyth_uri_is_livetv (gmyth_uri);
rosfran@332
   428
leo_sobral@441
   429
    file_info->valid_fields = 0;
renatofilho@367
   430
	file_info->valid_fields = file_info->valid_fields
renatofilho@367
   431
	    | GNOME_VFS_FILE_INFO_FIELDS_TYPE
renatofilho@367
   432
	    | GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE
renatofilho@367
   433
	    | GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS;
renatofilho@367
   434
	file_info->type = GNOME_VFS_FILE_TYPE_REGULAR;
renatofilho@367
   435
	/* fixme: get from file extension? */
renatofilho@367
   436
	file_info->mime_type = g_strdup ("video/x-nuv");
renatofilho@367
   437
	file_info->permissions =
renatofilho@367
   438
	    GNOME_VFS_PERM_USER_READ |
renatofilho@367
   439
	    GNOME_VFS_PERM_OTHER_READ | GNOME_VFS_PERM_GROUP_READ;
rosfran@346
   440
rosfran@368
   441
	g_debug ("gnome_vfs_uri == %s | gmyth_uri == %s.\n",
renatofilho@367
   442
		 gnome_vfs_uri_get_path (uri),
renatofilho@367
   443
		 gmyth_uri_get_path (gmyth_uri));
rosfran@331
   444
renatofilho@367
   445
	/* Connect to the backend */
renatofilho@367
   446
	if (gmyth_uri != NULL && is_livetv == TRUE) {
rosfran@338
   447
renatofilho@367
   448
		/* start to get file info from LiveTV remote encoder */
renatofilho@367
   449
		socket = gmyth_socket_new ();
rosfran@301
   450
renatofilho@367
   451
		/* FIME: Implement this at gmyth_socket */
renatofilho@367
   452
		res =
renatofilho@367
   453
		    gmyth_socket_connect_to_backend (socket,
leo_sobral@441
   454
						     backend_info->hostname,
renatofilho@367
   455
						     backend_info->port,
renatofilho@367
   456
						     TRUE);
renatofilho@367
   457
		if (!res) {
leo_sobral@441
   458
			g_debug ("[%s] LiveTV can not connect to backend",  __FUNCTION__);
renatofilho@367
   459
			res = FALSE;
renatofilho@367
   460
			goto error;
renatofilho@367
   461
		}
renatofilho@367
   462
leo_sobral@441
   463
		if (gmyth_remote_util_get_free_recorder_count (socket) <= 0) {
rosfran@368
   464
			g_debug ("No free remote encoder available.");
renatofilho@367
   465
			res = FALSE;
renatofilho@367
   466
			goto error;
renatofilho@367
   467
		}
renatofilho@367
   468
renatofilho@367
   469
		/* Gets the recorder num */
renatofilho@367
   470
		recorder = remote_request_next_free_recorder (socket, -1);
renatofilho@367
   471
leo_sobral@441
   472
		if (socket != NULL)
rosfran@368
   473
			g_object_unref (socket);
renatofilho@367
   474
renatofilho@367
   475
		if (recorder == NULL) {
leo_sobral@441
   476
			g_debug ("[%s] None remote encoder available", __FUNCTION__);
renatofilho@367
   477
			res = FALSE;
renatofilho@367
   478
			goto error;
renatofilho@367
   479
		}
renatofilho@367
   480
renatofilho@367
   481
		/* Init remote encoder. Opens its control socket. */
renatofilho@367
   482
		res = gmyth_recorder_setup (recorder);
renatofilho@367
   483
		if (!res) {
leo_sobral@441
   484
			g_debug ("[%s] Fail while setting remote encoder\n", __FUNCTION__);
renatofilho@367
   485
			res = FALSE;
renatofilho@367
   486
			goto error;
renatofilho@367
   487
		}
renatofilho@367
   488
renatofilho@367
   489
		/* Creates livetv chain handler */
renatofilho@367
   490
		tvchain = gmyth_tvchain_new ();
renatofilho@367
   491
		gmyth_tvchain_initialize (tvchain, backend_info);
renatofilho@367
   492
renatofilho@367
   493
		if (tvchain == NULL || tvchain->tvchain_id == NULL) {
renatofilho@367
   494
			res = FALSE;
renatofilho@367
   495
			goto error;
renatofilho@367
   496
		}
rosfran@368
   497
		/* Spawn live tv. Uses the socket to send mythprotocol data to start livetv in the backend (remotelly) */
leo_sobral@441
   498
		res = gmyth_recorder_spawntv (recorder, gmyth_tvchain_get_id(tvchain));
renatofilho@367
   499
		if (!res) {
renatofilho@367
   500
			g_warning ("[%s] Fail while spawn tv\n",
renatofilho@367
   501
				   __FUNCTION__);
renatofilho@367
   502
			res = FALSE;
renatofilho@367
   503
			goto error;
renatofilho@367
   504
		}
rosfran@372
   505
		
rosfran@372
   506
		sleep(1);
renatofilho@367
   507
renatofilho@367
   508
		/* DEBUG message */
renatofilho@367
   509
		GMythProgramInfo *prog_info =
renatofilho@367
   510
		    gmyth_recorder_get_current_program_info (recorder);
renatofilho@367
   511
renatofilho@367
   512
		if (prog_info != NULL) {
renatofilho@367
   513
rosfran@368
   514
			g_debug ("path = %s", prog_info->pathname->str);
renatofilho@367
   515
renatofilho@367
   516
			file_info->name =
renatofilho@367
   517
			    g_strdup (g_strrstr
renatofilho@367
   518
				      (prog_info->pathname->str, "/"));
renatofilho@367
   519
renatofilho@367
   520
		} else {
renatofilho@367
   521
			file_info->name = g_strdup ("LiveTV.nuv");
leo_sobral@441
   522
            /* Size being overrided below ... */
leo_sobral@441
   523
			//file_info->size = gmyth_recorder_get_file_position (recorder);
renatofilho@367
   524
		}
renatofilho@367
   525
renatofilho@367
   526
		if (recorder != NULL)
renatofilho@367
   527
			g_object_unref (recorder);
renatofilho@367
   528
renatofilho@367
   529
		if (prog_info != NULL)
renatofilho@367
   530
			g_object_unref (prog_info);
renatofilho@367
   531
renatofilho@367
   532
		if (tvchain != NULL)
renatofilho@367
   533
			g_object_unref (tvchain);
renatofilho@367
   534
leo_sobral@441
   535
		//file_info->size = (GnomeVFSFileSize) - 1;
renatofilho@367
   536
renatofilho@367
   537
	} else {
renatofilho@367
   538
leo_sobral@441
   539
        /* start to get file info from remote file encoder */
leo_sobral@441
   540
        file_transfer = gmyth_file_transfer_new (backend_info);
renatofilho@367
   541
renatofilho@367
   542
		/* Verifies if the file exists */
leo_sobral@441
   543
    	if (!gmyth_util_file_exists (backend_info, gmyth_uri_get_path (gmyth_uri))) {
leo_sobral@441
   544
            g_object_unref (backend_info);
leo_sobral@441
   545
            return GNOME_VFS_ERROR_NOT_FOUND;
renatofilho@367
   546
		}
renatofilho@367
   547
renatofilho@367
   548
		/* sets the Playback monitor connection */
leo_sobral@441
   549
		ret = gmyth_file_transfer_open (file_transfer,
leo_sobral@441
   550
					      gmyth_uri_get_path (gmyth_uri));
renatofilho@367
   551
renatofilho@367
   552
		file_info->name = g_strdup (gnome_vfs_uri_get_path (uri));
renatofilho@367
   553
leo_sobral@441
   554
	} /* if - LiveTV or not? */
renatofilho@367
   555
renatofilho@367
   556
	if (ret == FALSE) {
renatofilho@367
   557
		g_debug ("MythTV FileTransfer open error\n");
renatofilho@367
   558
		return GNOME_VFS_ERROR_NOT_OPEN;
renatofilho@367
   559
	}
renatofilho@367
   560
leo_sobral@441
   561
    /* Just for recorded content */
renatofilho@367
   562
	if (ret == TRUE && file_transfer != NULL) {
renatofilho@367
   563
		file_info->size =
renatofilho@367
   564
		    gmyth_file_transfer_get_filesize (file_transfer);
leo_sobral@441
   565
leo_sobral@441
   566
        file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_SIZE;
leo_sobral@441
   567
        
renatofilho@367
   568
		if (file_transfer)
renatofilho@367
   569
			g_object_unref (file_transfer);
renatofilho@367
   570
	}
renatofilho@367
   571
leo_sobral@441
   572
error:
renatofilho@367
   573
	if (backend_info)
renatofilho@367
   574
		g_object_unref (backend_info);
renatofilho@367
   575
renatofilho@367
   576
	if (!res)
renatofilho@367
   577
		return GNOME_VFS_ERROR_IO;
renatofilho@367
   578
renatofilho@367
   579
	return GNOME_VFS_OK;
melunko@38
   580
}
melunko@38
   581
melunko@38
   582
static gboolean
renatofilho@367
   583
do_is_local (GnomeVFSMethod * method, const GnomeVFSURI * uri)
melunko@38
   584
{
melunko@38
   585
	return FALSE;
melunko@38
   586
}
melunko@38
   587
melunko@38
   588
static GnomeVFSMethod method = {
melunko@38
   589
	sizeof (GnomeVFSMethod),
melunko@38
   590
	do_open,
melunko@38
   591
	NULL,
melunko@38
   592
	do_close,
melunko@38
   593
	do_read,
melunko@38
   594
	NULL,
melunko@38
   595
	NULL,
melunko@38
   596
	NULL,
melunko@38
   597
	NULL,
melunko@38
   598
	NULL,
melunko@38
   599
	NULL,
melunko@38
   600
	NULL,
melunko@38
   601
	do_get_file_info,
melunko@38
   602
	NULL,
melunko@38
   603
	do_is_local,
melunko@38
   604
	NULL,
melunko@38
   605
	NULL,
melunko@38
   606
	NULL,
melunko@38
   607
	NULL,
melunko@38
   608
	NULL,
melunko@38
   609
	NULL,
melunko@38
   610
	NULL,
melunko@38
   611
	NULL,
melunko@38
   612
	NULL,
melunko@38
   613
	NULL,
melunko@38
   614
	NULL,
melunko@38
   615
	NULL,
melunko@38
   616
};
melunko@38
   617
melunko@38
   618
melunko@38
   619
GnomeVFSMethod *
melunko@38
   620
vfs_module_init (const char *method_name, const char *args)
melunko@38
   621
{
melunko@38
   622
	return &method;
melunko@38
   623
}
melunko@38
   624
melunko@38
   625
void
renatofilho@367
   626
vfs_module_shutdown (GnomeVFSMethod * method)
melunko@38
   627
{
melunko@38
   628
}