00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00031
00032 #ifdef HAVE_CONFIG_H
00033 #include "autoconfig.h"
00034 #endif
00035
00036 #if defined(HAVE_JS) && defined(HAVE_LIBDVDNAV)
00037
00038 #include "dvd_image_import_script.h"
00039 #include "config_manager.h"
00040 #include "js_functions.h"
00041 #include "metadata/dvd_handler.h"
00042 using namespace zmm;
00043
00044 extern "C" {
00045
00046
00047 static JSBool js_addDVDObject(JSContext *cx, JSObject *obj, uintN argc,
00048 jsval *argv, jsval *rval)
00049 {
00050 try
00051 {
00052 jsval arg;
00053 JSObject *js_cds_obj;
00054 Ref<CdsObject> cds_obj;
00055 Ref<CdsObject> processed;
00056 int title;
00057 int chapter;
00058 int audio_track;
00059 String chain;
00060 String containerclass;
00061 JSString *str;
00062
00063
00064 DVDImportScript *self = (DVDImportScript *)JS_GetPrivate(cx, obj);
00065
00066 if (self->whoami() != S_DVD)
00067 {
00068 log_error("Function must be called from the DVD import script!\n");
00069 return JS_TRUE;
00070 }
00071
00072 arg = argv[0];
00073 if (!JSVAL_IS_OBJECT(arg))
00074 {
00075 log_error("Invalid argument!");
00076 return JS_TRUE;
00077 }
00078
00079 if (!JS_ValueToObject(cx, arg, &js_cds_obj))
00080 {
00081 log_error("Could not convert object!");
00082 return JS_TRUE;
00083 }
00084
00085
00086 argv[0] = OBJECT_TO_JSVAL(js_cds_obj);
00087
00088 if (!JS_ValueToInt32(cx, argv[1], &title))
00089 {
00090 log_error("addDVDObject: Invalid DVD title number given!\n");
00091 return JS_TRUE;
00092 }
00093
00094 if (!JS_ValueToInt32(cx, argv[2], &chapter))
00095 {
00096 log_error("addDVDObject: Invalid DVD chapter number given!\n");
00097 return JS_TRUE;
00098 }
00099
00100 if (!JS_ValueToInt32(cx, argv[3], &audio_track))
00101 {
00102 log_error("addDVDObject: Invalid DVD audio track number given!\n");
00103 return JS_TRUE;
00104 }
00105
00106 str = JS_ValueToString(cx, argv[4]);
00107 if (!str)
00108 {
00109 log_error("addDVDObject: Invalid DVD container chain given!\n");
00110 return JS_TRUE;
00111 }
00112
00113 chain = JS_GetStringBytes(str);
00114 if (!string_ok(chain) || chain == "undefined")
00115 {
00116 log_error("addDVDObject: Invalid DVD container chain given!\n");
00117 return JS_TRUE;
00118 }
00119
00120 JSString *cont = JS_ValueToString(cx, argv[5]);
00121 if (cont)
00122 {
00123 containerclass = JS_GetStringBytes(cont);
00124 if (!string_ok(containerclass) || containerclass == "undefined")
00125 containerclass = nil;
00126 }
00127
00128 processed = self->getProcessedObject();
00129 if (processed == nil)
00130 {
00131 log_error("addDVDObject: could not retrieve original object!\n");
00132 return JS_TRUE;
00133 }
00134
00135
00136
00137 cds_obj = self->jsObject2cdsObject(js_cds_obj, processed);
00138 if (cds_obj == nil)
00139 {
00140 log_error("addDVDObject: could not convert js object!\n");
00141 return JS_TRUE;
00142 }
00143
00144 self->addDVDObject(cds_obj, title, chapter, audio_track, chain,
00145 containerclass);
00146
00147 }
00148 catch (ServerShutdownException se)
00149 {
00150 log_warning("Aborting script execution due to server shutdown.\n");
00151 return JS_FALSE;
00152 }
00153 catch (Exception ex)
00154 {
00155 log_error("%s\n", ex.getMessage().c_str());
00156 ex.printStackTrace();
00157 }
00158
00159 return JS_TRUE;
00160 }
00161
00162 }
00163
00164 void DVDImportScript::addDVDObject(Ref<CdsObject> obj, int title,
00165 int chapter, int audio_track, String chain,
00166 String containerclass)
00167 {
00168
00169 if (processed == nil)
00170 throw _Exception(_("Invalid original object!"));
00171
00172 if (processed->getID() == INVALID_OBJECT_ID)
00173 throw _Exception(_("Original object not yet in database!"));
00174
00175 obj->setRefID(processed->getID());
00176 obj->setID(INVALID_OBJECT_ID);
00177 obj->setVirtual(1);
00178 obj->clearFlag(OBJECT_FLAG_USE_RESOURCE_REF);
00179
00180 Ref<ContentManager> cm = ContentManager::getInstance();
00181
00182 int id = cm->addContainerChain(chain, containerclass, processed->getID());
00183 obj->setParentID(id);
00184
00185 RefCast(obj, CdsItem)->setMimeType(mimetype);
00186 obj->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_PROTOCOLINFO), renderProtocolInfo(mimetype));
00187
00189 obj->getResource(0)->removeAttribute(MetadataHandler::getResAttrName(R_SIZE));
00190 obj->getResource(0)->addParameter(DVDHandler::renderKey(DVD_AudioStreamID), processed->getAuxData(DVDHandler::renderKey(DVD_AudioTrackStreamID, title, 0,
00191 audio_track)));
00192
00193 String tmp = processed->getAuxData(DVDHandler::renderKey(DVD_AudioTrackChannels, title, 0, audio_track));
00194 if (string_ok(tmp))
00195 {
00196 obj->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_NRAUDIOCHANNELS), tmp);
00197 log_debug("Setting Audio Channels, object %s - num: %s\n",
00198 obj->getLocation().c_str(), tmp.c_str());
00199 }
00200
00201 tmp = processed->getAuxData(DVDHandler::renderKey(DVD_AudioTrackSampleFreq, title, 0, audio_track));
00202 if (string_ok(tmp))
00203 obj->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_SAMPLEFREQUENCY), tmp);
00204
00205 obj->getResource(0)->addParameter(DVDHandler::renderKey(DVD_Chapter),
00206 String::from(chapter));
00207
00208
00209
00210
00211
00212
00213 obj->getResource(0)->addParameter(DVDHandler::renderKey(DVD_Title),
00214 String::from(title));
00215
00216 cm->addObject(obj);
00217 }
00218
00219 DVDImportScript::DVDImportScript(Ref<Runtime> runtime) : Script(runtime)
00220 {
00221
00222 #ifdef JS_THREADSAFE
00223 JS_SetContextThread(cx);
00224 JS_BeginRequest(cx);
00225 #endif
00226
00227 try
00228 {
00229 defineFunction(_("addDVDObject"), js_addDVDObject, 7);
00230
00231 setProperty(glob, _("DVD"), _("DVD"));
00232
00233 String scriptPath = ConfigManager::getInstance()->getOption(CFG_IMPORT_SCRIPTING_DVD_SCRIPT);
00234 load(scriptPath);
00235 root = JS_NewScriptObject(cx, script);
00236 JS_AddNamedRoot(cx, &root, "DVDImportScript");
00237 log_info("Loaded %s\n", scriptPath.c_str());
00238
00239 Ref<Dictionary> mappings =
00240 ConfigManager::getInstance()->getDictionaryOption(
00241 CFG_IMPORT_MAPPINGS_MIMETYPE_TO_CONTENTTYPE_LIST);
00242
00243 mimetype = mappings->get(_(CONTENT_TYPE_MPEG));
00244 if (!string_ok(mimetype))
00245 mimetype = _("video/mpeg");
00246 }
00247 catch (Exception ex)
00248 {
00249 #ifdef JS_THREADSAFE
00250 JS_EndRequest(cx);
00251 JS_ClearContextThread(cx);
00252 #endif
00253 throw ex;
00254 }
00255 #ifdef JS_THREADSAFE
00256 JS_EndRequest(cx);
00257 JS_ClearContextThread(cx);
00258 #endif
00259 }
00260
00261 void DVDImportScript::processDVDObject(Ref<CdsObject> obj)
00262 {
00263 #ifdef JS_THREADSAFE
00264 JS_SetContextThread(cx);
00265 JS_BeginRequest(cx);
00266 #endif
00267 processed = obj;
00268 try
00269 {
00270 JSObject *orig = JS_NewObject(cx, NULL, NULL, glob);
00271 setObjectProperty(glob, _("dvd"), orig);
00272 cdsObject2jsObject(obj, orig);
00273 execute();
00274 }
00275 catch (Exception ex)
00276 {
00277 processed = nil;
00278 #ifdef JS_THREADSAFE
00279 JS_EndRequest(cx);
00280 JS_ClearContextThread(cx);
00281 #endif
00282 throw ex;
00283 }
00284
00285 processed = nil;
00286
00287 gc_counter++;
00288 if (gc_counter > JS_CALL_GC_AFTER_NUM)
00289 {
00290 JS_MaybeGC(cx);
00291 gc_counter = 0;
00292 }
00293 #ifdef JS_THREADSAFE
00294 JS_EndRequest(cx);
00295 JS_ClearContextThread(cx);
00296 #endif
00297 }
00298
00299 DVDImportScript::~DVDImportScript()
00300 {
00301 #ifdef JS_THREADSAFE
00302 JS_SetContextThread(cx);
00303 JS_BeginRequest(cx);
00304 #endif
00305
00306 if (root)
00307 JS_RemoveRoot(cx, &root);
00308
00309 #ifdef JS_THREADSAFE
00310 JS_EndRequest(cx);
00311 JS_ClearContextThread(cx);
00312 #endif
00313
00314 }
00315
00316 #endif // HAVE_JS