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.

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. ConstantsI 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_VERSION

Version of the script

SCRIPT_NAME

Short script name

SCRIPT_DESC

Long script description

SCRIPT_LANG

Language 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.

URL to use for searching the web-site. %s is replaced with a movie title or person name

CODE_PAGE

Web-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 variablesScript 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;

5. Obligatory functionsWhen 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 version

function GetScriptName : WideString;

Returns script name

function GetScriptDesc : WideString;

returns script description

function GetBaseURL : String;

Returns web-site's base URL

function GetScriptLang: Cardinal;

Returns script language

function GetScriptType : Byte;

Returns script type

function 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_STR

function 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 name

function GetCodePage : Cardinal;

Returns web-site encoding

procedure 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;

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 variableMode := smNormal;

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

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 betterResult := prFinished; //script has finished it's jobend;

9. Built in parsing functionsfunction Pos(Substr : WideString; Str: WideString): IntegerReturns the index value of the first character in a specified substring that occurs in a given string.

function PosFrom(const SubStr, Str : WideString; FromIndex : Integer) : IntegerReturns the index value of the first character in a specified substring that occurs in a given string. Search starts from FromIndex[/b]

function LastPos(const SubStr, Str : WideString) : IntegerReturns the last index value of the first character in a specified substring that occurs in a given string.

function PrevPos(const SubStr, Str : WideString; APos : Integer) : IntegerReturns the index value of the first character in a specified substring that occurs in a given string before APos.

function RemoveTags(AText : WideString; doLineBreaks : Boolean) : WideStringRemoves all HTML tags from AText. Ex.: <a href="http://test.com">Test</a> will be converted to Test. If doLineBreaks is set to True, then <br> will be converted to a line break.

function UpperCase(S: WideString): WideStringReturns a copy of a string in uppercase.

function LowerCase(S: WideString): WideStringReturns a copy of a string in lowercase.

function StringReplace(S, OldPattern, NewPattern: WideString; ReplaceAll : Boolean; IgnoreCase : Boolean; WholeWord: Boolean): WideStringReturns a string with occurrences of one substring replaced by another substring. If ReplaceAll is set to True, the all occurrences of OldPattern will be replaced. If IgnoreCase is set to True, then the comparison operation is case insensitive.

function StrToInt(const S: WideString): IntegerConverts a string that represents an integer (decimal or hex notation) to a number.

function IntToStr(const Value: Integer): WideStringConverts an integer number to a string.

function StrToFloat(const S: WideString): ExtendedConverts a given string to a floating-point value.

function FloatToStr(const Value: Extended): WideStringConverts a floating point value to a string.

function HTMLValues(const HTML : WideString; ABegin, AEnd, ItemBegin, ItemEnd : WideString; ValDelim : WideString; var Pos : Integer) : WideStringGathers all values from HTML into a string using ValDelim as delimiter. The function searches for ABegin first starting from Pos, from this point it gathers values between ItemBegin and ItemEnd until AEnd is found. The last position is returned in Pos variable.

function HTMLValues2(const HTML : WideString; ABegin, AEnd, ItemBegin, ItemEnd : WideString; ValDelim : WideString; var Pos : Integer) : WideStringThe same as HTMLValues, but this version searches for an end tag character > after each ItemBegin.

10.1. Functions for filling standard fields (for information import plugins) procedure AddSearchResult(Title1, Title2, Year, URL, PreviewURL : WideString)Adds search result. You do not need to provide information for all the variables. Most import is to assign at least Title1 or Title2 and URL. If you do not have information to assign to a certain variable just pass ''. Ex.: AddSearchResult('Terminator', '', '', 'http://www.web-site.com/terminator.html', ''); //passes Title and URL only

procedure AddFieldValue(AField: Integer; AValue : WideString)Fill a certain standard field with (AValue). AField can have following values:For movies:

procedure AddPersonMovie(Title, OrigTitle, Role, Year, URL : WideString; AType : Byte)Adds a movie to a person's filmography. AType can have one of the following values:

0

Actor

1

Director

2

Writer

3

Composer

4

Producer

procedure AddAward(Event, Award, Category, Recipient, Year: WideString; const Won : Boolean)Adds an award. If you do not have information to assign to a certain variable just pass ''.

procedure AddConnection(Title, OrigTitle, Category, URL, Year: WideString)Adds movie connection. If you do not have information to assign to a certain variable just pass ''.

procedure AddEpisode(Title, OrigTitle, Description, URL, Year, Season, Episode : WideString)Adds an episode. If you do not have information to assign to a certain variable just pass ''.

10.2. Functions for filling other fieldsprocedure AddFieldValueXML(AField: WideString; AValue : WideString)This function can be used to fill all fields except custom fields and structured fields like (credits, connections, episodes, filmography). Pass field value in AValue variable. AField is a name of the field and can have one of the following values:

For movies:

num

title

origtitle

aka

year

genre

country

studio

release

mpaa

location

category

tagline

description

count

type

rating

imdbrating

orating

orname

rip

length

langs

translation

resolution

videocodec

videobitrate

audiocodec

audiobitrate

size

url

path

comment

dateadded

code

label

loan

subs

framerate

label

features

viewed

bookmark

wish

loandate

viewdate

tags

For persons:

name

transname

altnames

birthday

birthplace

bio

death

procedure AddCustomFieldValueByNumber(CustomNumber: Integer; AValue : WideString)Sets value of a custom field by field number.CustomNumber - number of a custom fieldAValue - field value (use '-1' for True(checked) and '0' for False)

procedure AddCustomFieldValueByName(CustomName: WideString; AValue : WideString)Sets value of a custom field by field name.CustomName - field nameAValue - field value (use '-1' for True(checked) and '0' for False)

11. Other built in functionsprocedure ShowMessage(const Msg, Head : WideString)Show a message box with OK button. Head - Window titleMsg - Message text

12. Debugging the script (check for errors) Before you can tell the script is ready you must test it first. Start PVD with -debug command line parameter, like this: viddb.exe -debugWhen you do this an additional menu item will become visible in "Help" menu called "Log".In the log you can track following information:

what plugins are loaded by PVD

what scripts are compiled and executed

what errors were found while compiling a script

what URLs are downloaded by PVD

If a script is wrong (contains errors) it will not be loaded into the program, so it can not be selected from the Import menu or visible in Preferences -> Plugins.

If an error acquired while compiling a script, an error message apears in log with detailed information about the wrong line in script code and type of an error. Ex.: [Error] (366:2): Semicolon (';') expected

Sometimes you can find hints produced by script compiler. Ex.: [Hint] (368:2): Variable 'TEST' never used

If a script can be compiled but does not work as it should you could use the ShowMessage function to output variable values and check the URLs PVD downloads in program log.

The last page downloaded is save into a file page.html in program directory while in -debug mode.