bugfix [#24087] Blender can not install add-ons unless running with root priviledges

now addon path is created using the same path functions and selecting where to save the startup.blend

also made some minor changes to path handling funcs.
This commit is contained in:
Campbell Barton 2010-10-03 20:00:22 +00:00
parent 3e3e10668e
commit ab8aa13b82
10 changed files with 94 additions and 33 deletions

View File

@ -27,7 +27,7 @@ import bpy as _bpy
import os as _os
import sys as _sys
from _bpy import blend_paths
from _bpy import blend_paths, user_resource
from _bpy import script_paths as _bpy_script_paths

View File

@ -1096,7 +1096,24 @@ class WM_OT_addon_install(bpy.types.Operator):
import zipfile
pyfile = self.filepath
path_addons = bpy.utils.script_paths("addons")[-1]
# dont use bpy.utils.script_paths("addons") because we may not be able to write to it.
path_addons = bpy.utils.user_resource('SCRIPTS', 'addons')
# should never happen.
if not path_addons:
self.report({'WARNING'}, "Failed to get addons path\n")
return {'CANCELLED'}
# create path if not existing.
if not os.path.exists(path_addons):
try:
os.makedirs(path_addons)
except:
self.report({'WARNING'}, "Failed to create %r\n" % path_addons)
traceback.print_exc()
return {'CANCELLED'}
contents = set(os.listdir(path_addons))
#check to see if the file is in compressed format (.zip)
@ -1115,7 +1132,7 @@ class WM_OT_addon_install(bpy.types.Operator):
path_dest = os.path.join(path_addons, os.path.basename(pyfile))
if os.path.exists(path_dest):
self.report({'WARNING'}, "File already installed to '%s'\n" % path_dest)
self.report({'WARNING'}, "File already installed to %r\n" % path_dest)
return {'CANCELLED'}
#if not compressed file just copy into the addon path
@ -1148,11 +1165,6 @@ class WM_OT_addon_install(bpy.types.Operator):
return {'FINISHED'}
def invoke(self, context, event):
paths = bpy.utils.script_paths("addons")
if not paths:
self.report({'ERROR'}, "No 'addons' path could be found in " + str(bpy.utils.script_paths()))
return {'CANCELLED'}
wm = context.window_manager
wm.add_fileselect(self)
return {'RUNNING_MODAL'}

View File

@ -44,6 +44,7 @@ char *BLI_getDefaultDocumentFolder(void);
char *BLI_get_folder(int folder_id, char *subfolder);
char *BLI_get_folder_create(int folder_id, char *subfolder);
char *BLI_get_user_folder_notest(int folder_id, char *subfolder);
/* folder_id */

View File

@ -477,7 +477,7 @@ int BLI_parent_dir(char *path)
static char *parent_dir="../";
#endif
char tmp[FILE_MAXDIR+FILE_MAXFILE+4];
BLI_strncpy(tmp, path, sizeof(tmp));
BLI_strncpy(tmp, path, sizeof(tmp)-4);
BLI_add_slash(tmp);
strcat(tmp, parent_dir);
BLI_cleanup_dir(NULL, tmp);
@ -839,8 +839,6 @@ static int get_path_local(char *targetpath, char *folder_name, char *subfolder_n
char bprogdir[FILE_MAX];
char relfolder[FILE_MAX];
char cwd[FILE_MAX];
char *s;
int i;
#ifdef PATH_DEBUG2
printf("get_path_local...\n");
@ -853,9 +851,7 @@ static int get_path_local(char *targetpath, char *folder_name, char *subfolder_n
}
/* use argv[0] (bprogname) to get the path to the executable */
s = BLI_last_slash(bprogname);
i = s - bprogname + 1;
BLI_strncpy(bprogdir, bprogname, i);
BLI_split_dirfile(bprogname, bprogdir, NULL);
/* try EXECUTABLE_DIR/folder_name */
if(test_path(targetpath, bprogdir, "", relfolder))
@ -1024,7 +1020,7 @@ char *BLI_get_folder(int folder_id, char *subfolder)
return path;
}
static char *BLI_get_user_folder_notest(int folder_id, char *subfolder)
char *BLI_get_user_folder_notest(int folder_id, char *subfolder)
{
static char path[FILE_MAX] = "";
@ -1038,6 +1034,9 @@ static char *BLI_get_user_folder_notest(int folder_id, char *subfolder)
case BLENDER_USER_AUTOSAVE:
get_path_user(path, "autosave", subfolder, "BLENDER_USER_AUTOSAVE");
break;
case BLENDER_USER_SCRIPTS:
get_path_user(path, "scripts", subfolder, "BLENDER_USER_SCRIPTS");
break;
}
if ('\0' == path[0]) {
return NULL;
@ -1050,7 +1049,7 @@ char *BLI_get_folder_create(int folder_id, char *subfolder)
char *path;
/* only for user folders */
if (!ELEM3(folder_id, BLENDER_USER_DATAFILES, BLENDER_USER_CONFIG, BLENDER_USER_AUTOSAVE))
if (!ELEM4(folder_id, BLENDER_USER_DATAFILES, BLENDER_USER_CONFIG, BLENDER_USER_SCRIPTS, BLENDER_USER_AUTOSAVE))
return NULL;
path = BLI_get_folder(folder_id, subfolder);
@ -1205,8 +1204,7 @@ void BLI_make_file_string(const char *relabase, char *string, const char *dir,
/* Get the file name, chop everything past the last slash (ie. the filename) */
strcpy(string, relabase);
lslash= (strrchr(string, '/')>strrchr(string, '\\'))?strrchr(string, '/'):strrchr(string, '\\');
lslash= BLI_last_slash(string);
if(lslash) *(lslash+1)= 0;
dir+=2; /* Skip over the relative reference */

View File

@ -281,8 +281,8 @@ static PyObject *blender_reload( PyObject * self, PyObject * module )
return newmodule;
}
PyMethodDef bpy_import_meth[] = { {"bpy_import_meth", (PyCFunction)blender_import, METH_VARARGS | METH_KEYWORDS, "blenders import"} };
PyMethodDef bpy_reload_meth[] = { {"bpy_reload_meth", (PyCFunction)blender_reload, METH_O, "blenders reload"} };
PyMethodDef bpy_import_meth = {"bpy_import_meth", (PyCFunction)blender_import, METH_VARARGS | METH_KEYWORDS, "blenders import"};
PyMethodDef bpy_reload_meth = {"bpy_reload_meth", (PyCFunction)blender_reload, METH_O, "blenders reload"};
/* Clear user modules.

View File

@ -53,8 +53,8 @@ PyObject* bpy_text_reimport( PyObject *module, int *found );
void bpy_text_filename_get(char *fn, struct Text *text);
extern PyMethodDef bpy_import_meth[];
extern PyMethodDef bpy_reload_meth[];
extern PyMethodDef bpy_import_meth;
extern PyMethodDef bpy_reload_meth;
/* The game engine has its own Main struct, if this is set search this rather then G.main */
struct Main *bpy_import_main_get(void);

View File

@ -112,8 +112,52 @@ static PyObject *bpy_blend_paths(PyObject * self, PyObject *args, PyObject *kw)
return list;
}
static PyMethodDef meth_bpy_script_paths[] = {{ "script_paths", (PyCFunction)bpy_script_paths, METH_NOARGS, bpy_script_paths_doc}};
static PyMethodDef meth_bpy_blend_paths[] = {{ "blend_paths", (PyCFunction)bpy_blend_paths, METH_VARARGS|METH_KEYWORDS, bpy_blend_paths_doc}};
static char bpy_user_resource_doc[] =
".. function:: user_resource(type, subdir)\n"
"\n"
" Returns a list of paths to external files referenced by the loaded .blend file.\n"
"\n"
" :arg type: Resource type in ['DATAFILES', 'CONFIG', 'SCRIPTS', 'AUTOSAVE'].\n"
" :type type: string\n"
" :arg subdir: Optional subdirectory.\n"
" :type subdir: string\n"
" :return: a path.\n"
" :rtype: string\n";
static PyObject *bpy_user_resource(PyObject * self, PyObject *args, PyObject *kw)
{
char *type;
char *subdir= NULL;
int folder_id;
static char *kwlist[] = {"type", "subdir", NULL};
char *path;
if (!PyArg_ParseTupleAndKeywords(args, kw, "s|s:user_resource", kwlist, &type, &subdir))
return NULL;
/* stupid string compare */
if (!strcmp(type, "DATAFILES")) folder_id= BLENDER_USER_DATAFILES;
else if(!strcmp(type, "CONFIG")) folder_id= BLENDER_USER_CONFIG;
else if(!strcmp(type, "SCRIPTS")) folder_id= BLENDER_USER_SCRIPTS;
else if(!strcmp(type, "AUTOSAVE")) folder_id= BLENDER_USER_AUTOSAVE;
else {
PyErr_SetString(PyExc_ValueError, "invalid resource argument");
return NULL;
}
/* same logic as BLI_get_folder_create(), but best leave it up to the script author to create */
path= BLI_get_folder(folder_id, subdir);
if (!path)
path = BLI_get_user_folder_notest(folder_id, subdir);
return PyUnicode_FromString(path ? path : "");
}
static PyMethodDef meth_bpy_script_paths = {"script_paths", (PyCFunction)bpy_script_paths, METH_NOARGS, bpy_script_paths_doc};
static PyMethodDef meth_bpy_blend_paths = {"blend_paths", (PyCFunction)bpy_blend_paths, METH_VARARGS|METH_KEYWORDS, bpy_blend_paths_doc};
static PyMethodDef meth_bpy_user_resource = {"user_resource", (PyCFunction)bpy_user_resource, METH_VARARGS|METH_KEYWORDS, bpy_user_resource_doc};
static void bpy_import_test(char *modname)
{
@ -186,8 +230,9 @@ void BPy_init_modules( void )
PyModule_AddObject(mod, "context", (PyObject *)bpy_context_module);
/* utility func's that have nowhere else to go */
PyModule_AddObject(mod, meth_bpy_script_paths->ml_name, (PyObject *)PyCFunction_New(meth_bpy_script_paths, NULL));
PyModule_AddObject(mod, meth_bpy_blend_paths->ml_name, (PyObject *)PyCFunction_New(meth_bpy_blend_paths, NULL));
PyModule_AddObject(mod, meth_bpy_script_paths.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_script_paths, NULL));
PyModule_AddObject(mod, meth_bpy_blend_paths.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_blend_paths, NULL));
PyModule_AddObject(mod, meth_bpy_user_resource.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_user_resource, NULL));
/* add our own modules dir, this is a python package */
bpy_import_test("bpy");

View File

@ -248,8 +248,8 @@ void BPY_start_python( int argc, char **argv )
//PyObject *m = PyImport_AddModule("__builtin__");
//PyObject *d = PyModule_GetDict(m);
PyObject *d = PyEval_GetBuiltins( );
PyDict_SetItemString(d, "reload", item=PyCFunction_New(bpy_reload_meth, NULL)); Py_DECREF(item);
PyDict_SetItemString(d, "__import__", item=PyCFunction_New(bpy_import_meth, NULL)); Py_DECREF(item);
PyDict_SetItemString(d, "reload", item=PyCFunction_New(&bpy_reload_meth, NULL)); Py_DECREF(item);
PyDict_SetItemString(d, "__import__", item=PyCFunction_New(&bpy_import_meth, NULL)); Py_DECREF(item);
}
pyrna_alloc_types();

View File

@ -681,15 +681,20 @@ int WM_write_homefile(bContext *C, wmOperator *op)
wm_window_close(C, wm, win);
BLI_make_file_string("/", tstr, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_STARTUP_FILE);
printf("trying to save homefile at %s \n", tstr);
printf("trying to save homefile at %s ", tstr);
/* force save as regular blend file */
fileflags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_AUTOPLAY | G_FILE_LOCK | G_FILE_SIGN);
BLO_write_file(CTX_data_main(C), tstr, fileflags, op->reports, NULL);
if(BLO_write_file(CTX_data_main(C), tstr, fileflags, op->reports, NULL) == 0) {
printf("fail\n");
return OPERATOR_CANCELLED;
}
printf("ok\n");
G.save_over= 0;
return OPERATOR_FINISHED;
}

View File

@ -1760,8 +1760,8 @@ static void setSandbox(TPythonSecurityLevel level)
*/
default:
/* Allow importing internal text, from bpy_internal_import.py */
PyDict_SetItemString(d, "reload", item=PyCFunction_New(bpy_reload_meth, NULL)); Py_DECREF(item);
PyDict_SetItemString(d, "__import__", item=PyCFunction_New(bpy_import_meth, NULL)); Py_DECREF(item);
PyDict_SetItemString(d, "reload", item=PyCFunction_New(&bpy_reload_meth, NULL)); Py_DECREF(item);
PyDict_SetItemString(d, "__import__", item=PyCFunction_New(&bpy_import_meth, NULL)); Py_DECREF(item);
break;
}
}