English > Development

Creating own scripts

(1/2) > >>

nostra:
Information in this topic is outdated. Please refer to this document for most current state of the script engine plug-in: http://www.videodb.info/help/hlp_scripting.html

Beginning with version 0.9.8.11 there is a possibility to create scripts using Pascal syntax to download movie and person information from the internet.

Scripts were added to make it possible for users to add additional functionality to the program without deep programming knowledge.

There are already some scripts available, so the only thing you will need to do in most cases is to set some values for constants  and write code to parse HTML pages. Mostly it is just about finding unique texts around information needed.

I have added multiple useful functions to make creating scripts easier.


Scripts should be saved in Scripts directory and have a .psf extension. All the scripts communicate with the main program with help of a special Script Engine plugin scriptint.dll.
Scripts can not work without this plugin.

PVD treats the scripts just like plugins, so you can configure them, combine in bacth files etc.

The following information can be set using scripts:

* All movie information fields, including custom fields
* All person information fields
* Posters
Please take into account that only a small subset of information fields can be set up in the program to be overwritten or not. All other fields are always overwritten.

nostra:
1.
Open the Scripts directory and make a copy of an existing script with another name.

2.
Open the file in a text editor (I recommend Notepad++)


3. Constants
I the beginning of the file there are usually constants defined for ease of setting up the script and making it better readable. You do not have to use constants, but it is recommended. There must always be a const operator before constants definitions.

Constants after the line //Script data describe the script:
SCRIPT_VERSIONVersion of the scriptSCRIPT_NAMEShort script nameSCRIPT_DESCLong script descriptionSCRIPT_LANGLanguage of the information retrieved. Ex.: $09 - English, $19 - Russian, $07 - German. A full list can be found here: http://msdn.microsoft.com/en-us/library/ms776294(VS.85).aspx (you need the number after 0x from "Prim. lang. identifier" column). It is not very important to define the right language, but recommended for better usability.SCRIPT_TYPEScript type:
* movie information script (constant stMovies)
* person information script (constant stPeople)
* poster script (constant stPoster)BASE_URLThe first level domain of the web-site. Ex.: http://www.amazon.comRATING_NAMEName of the site rating with the word "rating"SEARCH_STRURL to use for searching the web-site. %s is replaced with a movie title or person nameCODE_PAGEWeb-site encoding. For example if the web-site encoding is windows-1250 than this constant should have a value of 1250. You can usually find the web-page encoding in the beginning of a html file. Needed HTML tags look like this: <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>. If you do not know what encoding to use, just enter 0 to let the program auto detect it. A full list of supported values can be found here: http://msdn.microsoft.com/en-us/library/ms776446.aspx
You can also define your own constants. (For example to enable users to turn some script functions on or off).


4. Global variables
Script global variables are defined after the line //Global variables. Global variables can store any information that should be available in all parts of the script. var operator has to precede global or local variables (local variables are only accessible from a function they are defined in)

It is not obligatory to define any global variables, but I recommend to define at least one variable to track current script state. In my scripts it is defined like this: Mode : Byte;

nostra:
5. Obligatory functions
When you are done with defining variables and constants, you can start to write some real code :). The following functions have to be implemented to provide a communication interface between the script and script engine:

function GetScriptVersion : WideString;Returns script versionfunction GetScriptName : WideString;Returns script namefunction GetScriptDesc : WideString;returns script descriptionfunction GetBaseURL : String;Returns web-site's base URLfunction GetScriptLang: Cardinal;Returns script languagefunction GetScriptType : Byte;Returns script typefunction GetCurrentMode : Byte;Returns current script state:
* Searching movie or person (constant smSearch)
* Retrieving data  (any value above 0)function GetDownloadURL : String;Returns URL, that the main program should download. If the script is in a search mode it should return SEARCH_STRfunction ParsePage(HTML : WideString; URL : String) : Cardinal;This is the most interesting function :) HTML variable will contain text of the downloaded page, URL variable will contain address of the page. Your main goal is to parse this data and fill movie/person fields.

6. Not obligatory functions:
function GetRatingName : WideString;Returns rating namefunction GetCodePage : Cardinal;Returns web-site encodingprocedure GetLoginInfo(out URL : String; out Params : String);Returns data needed to login to the user account on the web-site. URL variable should be set to the login script url. Params variable should be set to parameters needed to login into the account (usually login and password). (POST method is used to pass parameters)
If you use an existing script as a template then you will only need to change the function ParsePage(HTML : WideString; URL : String) : Cardinal; and maybe the function GetDownloadURL : String;

nostra:
7. function GetDownloadURL : String;

If you script just needs to find a movie/person and download one page with information you will need to write code like this:

Result := SEARCH_STR

If you need to download and parse more than one page I recommend to define extra variables or an array of URLs that need to be downloaded. Code for 2 information pages will look like this:

   
 if CreditsURL = '' then
  Result := SEARCH_STR
 else
  Result := SecondPageURL;


You can also use the Mode variable as an extra flag. This code is for 3 pages using Mode variable:


 if (Mode > smNormal) AND (PosterURL <> '') then
  Result := PosterURL
 else
 if CreditsURL <> '' then
  Result := CreditsURL
 else
  Result := SEARCH_STR;


If you download poster in a movie information script or a photo in a person information script than make sure URL to an image is passed after all other pages are retrived!

nostra:
8. function ParsePage(HTML : WideString; URL : String) : Cardinal;

This is the most important function you need to implement.

The following actions have to be made in this function:

* a. Determine what information does this page contain (search results, movie/person information, etc.)
* b. Set the Mode variable (if script state changes)
* c. Parse HTML and set information fields
* d. Return an appropriate result
a. Determine what information does this page contain

It's pretty simple: You need to find a unique marker in HTML for each page type and do some parsing according to what you have found on this page. Ex.:
if Pos('<title>Movie</title>', HTML) > 0 then begin

then...
б. Set the Mode variable
Mode := smNormal;

then...
в. Parse HTML and set information fields
ParseMovie(URL, HTML); //This is a helper procedure to make the code better readable.

then...
г. Return an appropriate result
Result := prFinished; //script has finished it's job

The part of the code that determines the type of the web-page and does the rest of the actions should look like this:

if Pos('<title>Фильм</title>', HTML) > 0 then begin
 Mode := smNormal;
 ParseMovie(URL, HTML); //This is a helper procedure to make the code better
 Result := prFinished; //script has finished it's job
end;


I recommend you to create a helper procedure to parse each page type. Ex.:
procedure ParseSearchResults(HTML : WideString); //parse search results
procedure ParseMovie(MovieURL : WideString; HTML : WideString); //parse main movie information
procedure ParseCredits(HTML : WideString); //parse movie credits

The whole ParsePage function should look like this:
function ParsePage(HTML : WideString; URL : String) : Cardinal;
begin
 if Pos('<title>Поиск по сайту</title>', HTML) > 0 then begin
  ParseSearchResults(HTML);
  Result := prList; //search results retrieved
end else
 if Pos('Ничего не найдено по запросу', HTML) > 0 then
  Result := prError //error (movie not found)
else
 if (Pos('<title>Фильм</title>', HTML) > 0) then begin
  Mode := smNormal;
  ParseMovie(URL, HTML);
  Result := prFinished; //script has finished it's job
end else
  Result := prError; //error (unknown page retrieved)
end;

Navigation

[0] Message Index

[#] Next page

Go to full version