59c1c0bf7c206b52c3588249381a0579d51513bd
[blender.git] / source / blender / python / intern / bpy_app.c
1 /**
2  * $Id:
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * Contributor(s): Campbell Barton
21  *
22  * ***** END GPL LICENSE BLOCK *****
23  */
24
25 #include "bpy_app.h"
26 #include "bpy_util.h"
27
28 #include "BLI_path_util.h"
29
30 #include "BKE_blender.h"
31 #include "BKE_global.h"
32 #include "structseq.h"
33
34 #ifdef BUILD_DATE
35 extern const char * build_date;
36 extern const char * build_time;
37 extern const char * build_rev;
38 extern const char * build_platform;
39 extern const char * build_type;
40 #endif
41
42 static PyTypeObject BlenderAppType;
43
44 static PyStructSequence_Field app_info_fields[] = {
45         {"version", "The Blender version as a tuple of 3 numbers. eg. (2, 50, 11)"},
46         {"version_string", "The Blender version formatted as a string"},
47         {"home", "The blender home directory, normally matching $HOME"},
48         {"binary_path", "The location of blenders executable, useful for utilities that spawn new instances"},
49         {"debug", "Boolean, set when blender is running in debug mode (started with -d)"},
50
51         /* buildinfo */
52         {"build_date", "The date this blender instance was built"},
53         {"build_time", "The time this blender instance was built"},
54         {"build_revision", "The subversion revision this blender instance was built with"},
55         {"build_platform", "The platform this blender instance was built for"},
56         {"build_type", "The type of build (Release, Debug)"},
57         {0}
58 };
59
60 static PyStructSequence_Desc app_info_desc = {
61         "bpy.app",     /* name */
62         "This module contains application values that remain unchanged during runtime.",    /* doc */
63         app_info_fields,    /* fields */
64         10
65 };
66
67 static char *strip_quotes(char *buf, const char *input)
68 {
69         int i;
70         strcpy(buf, input);
71         if(buf[0]=='\0') return buf;
72         while(buf[1] && (buf[0]=='"' || buf[0]=='\'')) buf++;
73         if(buf[0]=='\0') return buf;
74         i= strlen(buf) - 1;
75         while(i>=0 && (buf[i]=='"' || buf[i]=='\'')) i--;
76         buf[i+1]= '\0';
77
78         return buf;
79 }
80
81 static PyObject *make_app_info(void)
82 {
83         extern char bprogname[]; /* argv[0] from creator.c */
84         char buf[256];
85
86         PyObject *app_info;
87         int pos = 0;
88
89         app_info = PyStructSequence_New(&BlenderAppType);
90         if (app_info == NULL) {
91                 return NULL;
92         }
93
94 #define SetIntItem(flag) \
95         PyStructSequence_SET_ITEM(app_info, pos++, PyLong_FromLong(flag))
96 #define SetStrItem(str) \
97         PyStructSequence_SET_ITEM(app_info, pos++, PyUnicode_FromString(str))
98 #define SetObjItem(obj) \
99         PyStructSequence_SET_ITEM(app_info, pos++, obj)
100
101         SetObjItem(Py_BuildValue("(iii)", BLENDER_VERSION/100, BLENDER_VERSION%100, BLENDER_SUBVERSION));
102         SetObjItem(PyUnicode_FromFormat("%d.%02d (sub %d)", BLENDER_VERSION/100, BLENDER_VERSION%100, BLENDER_SUBVERSION));
103         SetStrItem(BLI_gethome());
104         SetStrItem(bprogname);
105         SetObjItem(PyBool_FromLong(G.f & G_DEBUG));
106
107         /* build info */
108 #ifdef BUILD_DATE
109         SetStrItem(strip_quotes(buf, build_date));
110         SetStrItem(strip_quotes(buf, build_time));
111         SetStrItem(strip_quotes(buf, build_rev));
112         SetStrItem(strip_quotes(buf, build_platform));
113         SetStrItem(strip_quotes(buf, build_type));
114 #else
115         SetStrItem(strip_quotes(buf, "Unknown"));
116         SetStrItem(strip_quotes(buf, "Unknown"));
117         SetStrItem(strip_quotes(buf, "Unknown"));
118         SetStrItem(strip_quotes(buf, "Unknown"));
119         SetStrItem(strip_quotes(buf, "Unknown"));
120 #endif
121
122 #undef SetIntItem
123 #undef SetStrItem
124 #undef SetObjItem
125
126         if (PyErr_Occurred()) {
127                 Py_CLEAR(app_info);
128                 return NULL;
129         }
130         return app_info;
131 }
132
133 PyObject *BPY_app_struct(void)
134 {
135         PyObject *ret;
136
137         PyStructSequence_InitType(&BlenderAppType, &app_info_desc);
138
139         ret= make_app_info();
140
141         /* prevent user from creating new instances */
142         BlenderAppType.tp_init = NULL;
143         BlenderAppType.tp_new = NULL;
144         
145         return ret;
146 }