static int js_init(void) { JSContext *cx; JS_SetCStringsAreUTF8(); runtime = JS_NewRuntime(0x1000000); cx = js_newctx(err_reporter); JS_BeginRequest(cx); showtimeobj = JS_NewObject(cx, &showtime_class, NULL, NULL); JS_DefineFunctions(cx, showtimeobj, showtime_functions); JSFunction *fn = JS_DefineFunction(cx, showtimeobj, "RichText", js_RichText, 1, 0); RichText = JS_GetFunctionObject(fn); JS_AddNamedRoot(cx, &showtimeobj, "showtime"); JS_EndRequest(cx); JS_DestroyContext(cx); return 0; }
static int js_init(void) { JSContext *cx; jsval val; JS_SetCStringsAreUTF8(); runtime = JS_NewRuntime(0x1000000); cx = js_newctx(err_reporter); JS_BeginRequest(cx); showtimeobj = JS_NewObject(cx, &showtime_class, NULL, NULL); JS_DefineFunctions(cx, showtimeobj, showtime_functions); val = INT_TO_JSVAL(showtime_get_version_int()); JS_SetProperty(cx, showtimeobj, "currentVersionInt", &val); val = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, htsversion)); JS_SetProperty(cx, showtimeobj, "currentVersionString", &val); JSFunction *fn = JS_DefineFunction(cx, showtimeobj, "RichText", js_RichText, 1, 0); RichText = JS_GetFunctionObject(fn); JS_AddNamedRoot(cx, &showtimeobj, "showtime"); JS_EndRequest(cx); JS_DestroyContext(cx); return 0; }
static void js_fini(void) { js_plugin_t *jsp, *n; JSContext *cx; cx = js_newctx(err_reporter); JS_BeginRequest(cx); for(jsp = LIST_FIRST(&js_plugins); jsp != NULL; jsp = n) { n = LIST_NEXT(jsp, jsp_link); js_plugin_unload(cx, jsp); } JS_RemoveRoot(cx, &showtimeobj); JS_EndRequest(cx); JS_GC(cx); JS_DestroyContext(cx); JS_DestroyRuntime(runtime); JS_ShutDown(); }
void js_plugin_unload(const char *id) { JSContext *cx; js_plugin_t *jsp; LIST_FOREACH(jsp, &js_plugins, jsp_link) if(!strcmp(jsp->jsp_id, id)) break; if(jsp == NULL) return; fa_unreference(jsp->jsp_ref); cx = js_newctx(NULL); JS_BeginRequest(cx); js_plugin_unload0(cx, jsp); JS_EndRequest(cx); JS_GC(cx); JS_DestroyContext(cx); }
int js_plugin_load(const char *id, const char *url, char *errbuf, size_t errlen) { char *sbuf; struct fa_stat fs; JSContext *cx; js_plugin_t *jsp; JSObject *pobj, *gobj, *confobj; JSScript *s; char path[PATH_MAX]; jsval val; if((sbuf = fa_quickload(url, &fs, NULL, errbuf, errlen)) == NULL) return -1; cx = js_newctx(err_reporter); JS_BeginRequest(cx); /* Remove any plugin with same URL */ LIST_FOREACH(jsp, &js_plugins, jsp_link) if(!strcmp(jsp->jsp_id, id)) break; if(jsp != NULL) js_plugin_unload(cx, jsp); jsp = calloc(1, sizeof(js_plugin_t)); jsp->jsp_url = strdup(url); jsp->jsp_id = strdup(id); LIST_INSERT_HEAD(&js_plugins, jsp, jsp_link); gobj = JS_NewObject(cx, &global_class, NULL, NULL); JS_InitStandardClasses(cx, gobj); JS_DefineProperty(cx, gobj, "showtime", OBJECT_TO_JSVAL(showtimeobj), NULL, NULL, JSPROP_READONLY | JSPROP_PERMANENT); /* Plugin object */ pobj = JS_NewObject(cx, &plugin_class, NULL, gobj); JS_AddNamedRoot(cx, &pobj, "plugin"); JS_SetPrivate(cx, pobj, jsp); JS_DefineFunctions(cx, pobj, plugin_functions); /* Plugin config object */ confobj = JS_DefineObject(cx, pobj, "config", &plugin_conf_class, NULL, 0); JS_SetPrivate(cx, confobj, jsp); val = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, url)); JS_SetProperty(cx, confobj, "url", &val); if(!fa_parent(path, sizeof(path), url)) { val = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, path)); JS_SetProperty(cx, confobj, "path", &val); } JS_DefineProperty(cx, confobj, "URIRouting", BOOLEAN_TO_JSVAL(1), NULL, jsp_setEnableURIRoute, JSPROP_PERMANENT); JS_DefineProperty(cx, confobj, "search", BOOLEAN_TO_JSVAL(1), NULL, jsp_setEnableSearch, JSPROP_PERMANENT); s = JS_CompileScript(cx, pobj, sbuf, fs.fs_size, url, 1); free(sbuf); if(s != NULL) { JSObject *sobj = JS_NewScriptObject(cx, s); jsval result; JS_AddNamedRoot(cx, &sobj, "script"); JS_ExecuteScript(cx, pobj, s, &result); JS_RemoveRoot(cx, &sobj); } JS_RemoveRoot(cx, &pobj); JS_EndRequest(cx); JS_GC(cx); JS_DestroyContext(cx); return 0; }
static void js_sub_query(subtitle_provider_t *SP, sub_scanner_t *ss, int score, int autosel) { js_subprovider_t *sp = (js_subprovider_t *)SP; JSContext *cx = js_newctx(NULL); JS_BeginRequest(cx); if(ss != NULL) { JSObject *obj = JS_NewObject(cx, &subreq_class, NULL, NULL); JS_AddNamedRoot(cx, &obj, "subscanner"); if(sp->sp_jsp != NULL) usage_inc_plugin_counter(sp->sp_jsp->jsp_id, "subsearch", 1); js_sub_job_t *jsj = malloc(sizeof(js_sub_job_t)); jsj->jsj_ss = ss; jsj->jsj_score = score; jsj->jsj_autosel = autosel; sub_scanner_retain(ss); JS_SetPrivate(cx, obj, jsj); JS_DefineFunctions(cx, obj, sub_functions); js_set_prop_rstr(cx, obj, "title", ss->ss_title); js_set_prop_rstr(cx, obj, "imdb", ss->ss_imdbid); if(ss->ss_season > 0) js_set_prop_int(cx, obj, "season", ss->ss_season); if(ss->ss_year > 0) js_set_prop_int(cx, obj, "year", ss->ss_year); if(ss->ss_episode > 0) js_set_prop_int(cx, obj, "episode", ss->ss_episode); if(ss->ss_fsize > 0) js_set_prop_dbl(cx, obj, "filesize", ss->ss_fsize); if(ss->ss_hash_valid) { char str[64]; snprintf(str, sizeof(str), "%016" PRIx64, ss->ss_opensub_hash); js_set_prop_str(cx, obj, "opensubhash", str); bin2hex(str, sizeof(str), ss->ss_subdbhash, 16); js_set_prop_str(cx, obj, "subdbhash", str); } if(ss->ss_duration > 0) js_set_prop_int(cx, obj, "duration", ss->ss_duration); jsval result; jsval arg = OBJECT_TO_JSVAL(obj); JS_CallFunctionValue(cx, NULL, sp->sp_func, 1, &arg, &result); JS_RemoveRoot(cx, &obj); } js_subprovider_release(cx, sp); JS_DestroyContext(cx); }