25
26
* This is a new part of Blender.
27
* Contributor(s): Willian P. Germano
28
* Contributor(s): Willian P. Germano, Campbell Barton
29
30
* ***** END GPL/BL DUAL LICENSE BLOCK *****
32
#include "BKE_utildefines.h"
33
#include <BKE_utildefines.h>
34
#include <BLI_blenlib.h>
35
#include <DNA_scene_types.h> /* G.scene->r.cfra */
39
#include "gen_utils.h"
37
static PyObject *g_sysmodule = NULL; /* pointer to Blender.sys module */
39
PyObject *sys_Init (void)
43
/*****************************************************************************/
44
/* Python API function prototypes for the sys module. */
45
/*****************************************************************************/
46
static PyObject *M_sys_basename( PyObject * self, PyObject * args );
47
static PyObject *M_sys_dirname( PyObject * self, PyObject * args );
48
static PyObject *M_sys_join( PyObject * self, PyObject * args );
49
static PyObject *M_sys_splitext( PyObject * self, PyObject * args );
50
static PyObject *M_sys_makename( PyObject * self, PyObject * args,
52
static PyObject *M_sys_exists( PyObject * self, PyObject * args );
53
static PyObject *M_sys_time( PyObject * self );
54
static PyObject *M_sys_sleep( PyObject * self, PyObject * args );
55
static PyObject *M_sys_expandpath( PyObject *self, PyObject *args);
57
/*****************************************************************************/
58
/* The following string definitions are used for documentation strings. */
59
/* In Python these will be written to the console when doing a */
60
/* Blender.sys.__doc__ */
61
/*****************************************************************************/
62
static char M_sys_doc[] = "The Blender.sys submodule\n\
64
This is a minimal system module to supply simple functionality available\n\
65
in the default Python module os.";
67
static char M_sys_basename_doc[] =
68
"(path) - Split 'path' in dir and filename.\n\
69
Return the filename.";
71
static char M_sys_dirname_doc[] =
72
"(path) - Split 'path' in dir and filename.\n\
75
static char M_sys_join_doc[] =
76
"(dir, file) - Join dir and file to form a full filename.\n\
77
Return the filename.";
79
static char M_sys_splitext_doc[] =
80
"(path) - Split 'path' in root and extension:\n\
81
/this/that/file.ext -> ('/this/that/file','.ext').\n\
82
Return the pair (root, extension).";
84
static char M_sys_makename_doc[] =
85
"(path = Blender.Get('filename'), ext = \"\", strip = 0) -\n\
86
Strip dir and extension from path, leaving only a name, then append 'ext'\n\
87
to it (if given) and return the resulting string.\n\n\
88
(path) - string: a pathname -- Blender.Get('filename') if 'path' isn't given;\n\
89
(ext = \"\") - string: the extension to append.\n\
90
(strip = 0) - int: strip dirname from 'path' if given and non-zero.\n\
91
Ex: makename('/path/to/file/myfile.foo','-01.abc') returns 'myfile-01.abc'\n\
92
Ex: makename(ext='.txt') returns 'untitled.txt' if Blender.Get('filename')\n\
93
returns a path to the file 'untitled.blend'";
95
static char M_sys_time_doc[] =
96
"() - Return a float representing time elapsed in seconds.\n\
97
Each successive call is garanteed to return values greater than or\n\
98
equal to the previous call.";
100
static char M_sys_sleep_doc[] =
101
"(milliseconds = 10) - Sleep for the specified time.\n\
102
(milliseconds = 10) - the amount of time in milliseconds to sleep.\n\
103
This function can be necessary in tight 'get event' loops.";
105
static char M_sys_exists_doc[] =
106
"(path) - Check if the given pathname exists.\n\
107
The return value is as follows:\n\
108
\t 0: path doesn't exist;\n\
109
\t 1: path is an existing filename;\n\
110
\t 2: path is an existing dirname;\n\
111
\t-1: path exists but is neither a regular file nor a dir.";
113
static char M_sys_expandpath_doc[] =
114
"(path) - Expand this Blender internal path to a proper file system path.\n\
115
(path) - the string path to convert.\n\n\
116
Note: internally Blender paths can contain two special character sequences:\n\
117
- '//' (at start) for base path directory (the current .blend's dir path);\n\
118
- '#' (at ending) for current frame number.\n\n\
119
This function expands these to their actual content, returning a valid path.\n\
120
If the special chars are not found in the given path, it is simply returned.";
122
/*****************************************************************************/
123
/* Python method structure definition for Blender.sys module: */
124
/*****************************************************************************/
125
struct PyMethodDef M_sys_methods[] = {
126
{"basename", M_sys_basename, METH_VARARGS, M_sys_basename_doc},
127
{"dirname", M_sys_dirname, METH_VARARGS, M_sys_dirname_doc},
128
{"join", M_sys_join, METH_VARARGS, M_sys_join_doc},
129
{"splitext", M_sys_splitext, METH_VARARGS, M_sys_splitext_doc},
130
{"makename", ( PyCFunction ) M_sys_makename,
131
METH_VARARGS | METH_KEYWORDS,
133
{"exists", M_sys_exists, METH_VARARGS, M_sys_exists_doc},
134
{"sleep", M_sys_sleep, METH_VARARGS, M_sys_sleep_doc},
135
{"time", ( PyCFunction ) M_sys_time, METH_NOARGS, M_sys_time_doc},
136
{"expandpath", M_sys_expandpath, METH_VARARGS, M_sys_expandpath_doc},
137
{NULL, NULL, 0, NULL}
140
/* Module Functions */
142
static PyObject *g_sysmodule = NULL; /* pointer to Blender.sys module */
144
PyObject *sys_Init( void )
41
PyObject *submodule, *dict, *sep;
146
PyObject *submodule, *dict, *sep;
43
submodule = Py_InitModule3("Blender.sys", M_sys_methods, M_sys_doc);
148
submodule = Py_InitModule3( "Blender.sys", M_sys_methods, M_sys_doc );
45
150
g_sysmodule = submodule;
47
dict = PyModule_GetDict(submodule);
152
dict = PyModule_GetDict( submodule );
50
sep = Py_BuildValue("s", "\\");
155
sep = Py_BuildValue( "s", "\\" );
52
sep = Py_BuildValue("s", "/");
157
sep = Py_BuildValue( "s", "/" );
57
PyDict_SetItemString(dict, "dirsep" , sep);
58
PyDict_SetItemString(dict, "sep" , sep);
162
PyDict_SetItemString( dict, "dirsep", sep );
163
PyDict_SetItemString( dict, "sep", sep );
64
static PyObject *M_sys_basename (PyObject *self, PyObject *args)
169
static PyObject *M_sys_basename( PyObject * self, PyObject * args )
72
if (!PyArg_ParseTuple(args, "s", &name))
73
return EXPP_ReturnPyObjError (PyExc_TypeError,
74
"expected string argument");
78
c = PyObject_GetAttrString (g_sysmodule, "dirsep");
79
sep = PyString_AsString(c)[0];
82
p = strrchr(name, sep);
85
n = name + len - p - 1; /* - 1 because we don't want the sep */
88
return EXPP_ReturnPyObjError(PyExc_RuntimeError, "path too long");
90
strncpy(basename, p+1, n); /* + 1 to skip the sep */
92
return Py_BuildValue("s", basename);
177
if( !PyArg_ParseTuple( args, "s", &name ) )
178
return EXPP_ReturnPyObjError( PyExc_TypeError,
179
"expected string argument" );
181
len = strlen( name );
183
c = PyObject_GetAttrString( g_sysmodule, "dirsep" );
184
sep = PyString_AsString( c )[0];
187
p = strrchr( name, sep );
190
n = name + len - p - 1; /* - 1 because we don't want the sep */
192
if( n > FILE_MAXFILE )
193
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
196
BLI_strncpy( basename, p + 1, n + 1 );
197
return Py_BuildValue( "s", basename );
95
return Py_BuildValue("s", name);
200
return Py_BuildValue( "s", name );
98
static PyObject *M_sys_dirname (PyObject *self, PyObject *args)
203
static PyObject *M_sys_dirname( PyObject * self, PyObject * args )
106
if (!PyArg_ParseTuple(args, "s", &name))
107
return EXPP_ReturnPyObjError (PyExc_TypeError,
108
"expected string argument");
110
c = PyObject_GetAttrString (g_sysmodule, "dirsep");
111
sep = PyString_AsString(c)[0];
114
p = strrchr(name, sep);
211
if( !PyArg_ParseTuple( args, "s", &name ) )
212
return EXPP_ReturnPyObjError( PyExc_TypeError,
213
"expected string argument" );
215
c = PyObject_GetAttrString( g_sysmodule, "dirsep" );
216
sep = PyString_AsString( c )[0];
219
p = strrchr( name, sep );
120
return EXPP_ReturnPyObjError (PyExc_RuntimeError, "path too long");
122
strncpy(dirname, name, n);
124
return Py_BuildValue("s", dirname);
127
return Py_BuildValue("s", "."); /* XXX need to fix this? (is crossplatform?)*/
130
static PyObject *M_sys_splitext (PyObject *self, PyObject *args)
224
if( n > FILE_MAXDIR )
225
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
228
BLI_strncpy( dirname, name, n + 1 );
229
return Py_BuildValue( "s", dirname );
232
return Py_BuildValue( "s", "." );
235
static PyObject *M_sys_join( PyObject * self, PyObject * args )
238
char *name = NULL, *path = NULL;
239
char filename[FILE_MAXDIR + FILE_MAXFILE];
241
int pathlen = 0, namelen = 0;
243
if( !PyArg_ParseTuple( args, "ss", &path, &name ) )
244
return EXPP_ReturnPyObjError( PyExc_TypeError,
245
"expected string argument" );
247
pathlen = strlen( path ) + 1;
248
namelen = strlen( name ) + 1; /* + 1 to account for '\0' for BLI_strncpy */
250
if( pathlen + namelen > FILE_MAXDIR + FILE_MAXFILE - 1 )
251
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
252
"filename is too long." );
254
c = PyObject_GetAttrString( g_sysmodule, "dirsep" );
255
sep = PyString_AsString( c )[0];
258
BLI_strncpy( filename, path, pathlen );
260
if( filename[pathlen - 2] != sep ) {
261
filename[pathlen - 1] = sep;
265
BLI_strncpy( filename + pathlen - 1, name, namelen );
267
return Py_BuildValue( "s", filename );
270
static PyObject *M_sys_splitext( PyObject * self, PyObject * args )
138
if (!PyArg_ParseTuple(args, "s", &name))
139
return EXPP_ReturnPyObjError (PyExc_TypeError,
140
"expected string argument");
144
c = PyObject_GetAttrString (g_sysmodule, "dirsep");
145
sep = PyString_AsString(c)[0];
148
dot = strrchr(name, '.');
150
if (!dot) return Py_BuildValue("ss", name, "");
152
p = strrchr(name, sep);
155
if (p > dot) return Py_BuildValue("ss", name, "");
278
if( !PyArg_ParseTuple( args, "s", &name ) )
279
return EXPP_ReturnPyObjError( PyExc_TypeError,
280
"expected string argument" );
282
len = strlen( name );
284
c = PyObject_GetAttrString( g_sysmodule, "dirsep" );
285
sep = PyString_AsString( c )[0];
288
dot = strrchr( name, '.' );
291
return Py_BuildValue( "ss", name, "" );
293
p = strrchr( name, sep );
297
return Py_BuildValue( "ss", name, "" );
158
300
n = name + len - dot;
160
302
/* loong extensions are supported -- foolish, but Python's os.path.splitext
161
303
* supports them, so ... */
162
if (n > FILE_MAXFILE || (len - n ) > FILE_MAXFILE)
163
EXPP_ReturnPyObjError(PyExc_RuntimeError, "path too long");
165
strncpy(ext, dot, n);
167
strncpy(path, name, dot - name);
168
path[dot - name] = 0;
170
return Py_BuildValue("ss", path, ext);
173
static PyObject *M_sys_time (PyObject *self)
175
double t = PIL_check_seconds_timer();
176
return Py_BuildValue("d", t);
304
if( n > FILE_MAXFILE || ( len - n ) > FILE_MAXFILE )
305
EXPP_ReturnPyObjError( PyExc_RuntimeError, "path too long" );
307
BLI_strncpy( ext, dot, n + 1 );
308
BLI_strncpy( path, name, dot - name + 1 );
310
return Py_BuildValue( "ss", path, ext );
313
static PyObject *M_sys_makename( PyObject * self, PyObject * args,
316
char *path = G.sce, *ext = NULL;
318
static char *kwlist[] = { "path", "ext", "strip", NULL };
319
char *dot = NULL, *p = NULL, basename[FILE_MAXDIR + FILE_MAXFILE];
321
int n, len, lenext = 0;
324
if( !PyArg_ParseTupleAndKeywords( args, kw, "|ssi", kwlist,
325
&path, &ext, &strip ) )
326
return EXPP_ReturnPyObjError( PyExc_TypeError,
327
"expected one or two strings and an int (or nothing) as arguments" );
329
len = strlen( path ) + 1; /* + 1 to consider ending '\0' */
331
lenext = strlen( ext ) + 1;
333
if( ( len + lenext ) > FILE_MAXDIR + FILE_MAXFILE )
334
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
337
c = PyObject_GetAttrString( g_sysmodule, "dirsep" );
338
sep = PyString_AsString( c )[0];
341
p = strrchr( path, sep );
345
BLI_strncpy( basename, p + 1, n ); /* + 1 to skip the sep */
347
BLI_strncpy( basename, path, len );
349
dot = strrchr( basename, '.' );
351
/* now the extension: always remove the one in basename */
354
basename[dot - basename] = '\0';
355
else { /* if user gave an ext, append it */
360
n = strlen( basename );
362
BLI_strncpy( basename + n, ext, lenext );
366
return PyString_FromString( basename );
369
static PyObject *M_sys_time( PyObject * self )
371
double t = PIL_check_seconds_timer( );
372
return Py_BuildValue( "d", t );
375
static PyObject *M_sys_sleep( PyObject * self, PyObject * args )
379
if( !PyArg_ParseTuple( args, "|i", &millisecs ) )
380
return EXPP_ReturnPyObjError( PyExc_TypeError,
381
"expected int argument" );
383
PIL_sleep_ms( millisecs );
385
return EXPP_incr_ret( Py_None );
388
static PyObject *M_sys_exists( PyObject * self, PyObject * args )
394
if( !PyArg_ParseTuple( args, "s", &fname ) )
395
return EXPP_ReturnPyObjError( PyExc_TypeError,
396
"expected string (pathname) argument" );
398
res = stat( fname, &st );
402
else if( S_ISREG( st.st_mode ) )
404
else if( S_ISDIR( st.st_mode ) )
406
/* i stays as -1 if path exists but is neither a regular file nor a dir */
408
return Py_BuildValue( "i", i );
411
static PyObject *M_sys_expandpath( PyObject * self, PyObject * args )
414
char expanded[FILE_MAXDIR + FILE_MAXFILE];
416
if (!PyArg_ParseTuple( args, "s", &path))
417
return EXPP_ReturnPyObjError( PyExc_TypeError,
418
"expected string argument" );
420
BLI_strncpy(expanded, path, FILE_MAXDIR + FILE_MAXFILE);
421
BLI_convertstringcode(expanded, G.sce, G.scene->r.cfra);
423
return PyString_FromString(expanded);