﻿(*	
SCRIPT INFO:

Following until 'SCRIPT BEGINS HERE...' is documentation.
	Please see 'USER OPTIONS' in the body of the script.

---------------------------------------------

SCRIPT:		Imdb Movie(cast) Script 
AUTHOR:			Ivek23
VERSION:		0.1.1.1
DATE:			14/05/2015

---------------------------------------------

TYPES AND FUNCTIONS
Additional types and functions that can be used in scripts:

Types
	TWIDEARRAY : array of String

Field functions
	procedure AddSearchResult(Title1, Title2, Year, URL, PreviewURL : String)
	procedure AddFieldValue(AField: Integer; AValue : String)
	procedure AddMoviePerson(Name, TransName, Role, URL : String; AType : Byte)
	procedure AddPersonMovie(Title, OrigTitle, Role, Year, URL : String; AType : Byte)
	procedure AddAward(Event, Award, Category, Recipient, Year: String; const Won : Boolean)
	procedure AddAwardEx(Event, Award, Category, RecipientVal1, RecipientVal2, Year : String; const Won : Boolean);
	procedure AddConnection(Title, OrigTitle, Category, URL, Year: String)
	procedure AddEpisode(Title, OrigTitle, Description, URL, Year, Season, Episode : String)

String functions
	function Pos(Substr : String; Str: String): Integer
	function PosFrom(const SubStr, Str : String; FromIndex : Integer) : Integer
	function LastPos(const SubStr, Str : String) : Integer
	function PrevPos(const SubStr, Str : String; APos : Integer) : Integer
	function RemoveTags(AText : String; doLineBreaks : Boolean) : String
	function ExplodeString(AText : String; var Items : TWideArray; Delimiters : String) : Integer
	function Copy(S: String; Index, Count: Integer): String
	procedure Delete(var S: String; Index, Count: Integer)
	procedure Insert(Source: String; var Dest: String; Index: Integer)
	function Length(S: String): Integer
	function Trim(S: String): String
	function CompareText(S1, S2: String): Integer
	function CompareStr(S1, S2: String): Integer
	function UpperCase(S: String): String
	function LowerCase(S: String): String
	function AnsiString(S, OldPattern, NewPattern: String; All : Boolean; IgnoreCase : Boolean; WholeWord: Boolean): String
	function StrToInt(const S: String): Integer
	function IntToStr(const Value: Integer): String
	function StrToFloat(const S: String): Extended
	function FloatToStr(const Value: Extended): String
	function CurrentDateTime : Extended
	function DateToStr(Value : Extended) : String
	function TimeToStr(Value : Extended) : String
	function HTMLValues(const HTML : String; ABegin, AEnd, ItemBegin, ItemEnd : String; ValDelim : String; var Pos : Integer) : String
	function HTMLValues2(const HTML : String; ABegin, AEnd, ItemBegin, ItemEnd : String; ValDelim : String; var Pos : Integer) : String
	function TextBetween(const HTML : String; ABegin, AEnd : String; doLineBreaks : Boolean; var Pos : Integer) : String
	function HTMLToText(const HTML : String) : String

  procedure ShowMessage(const Msg, Head : String)
*)

//SCRIPT BEGINS HERE...

//Some useful constants

const

//Script types
	stMovies		= 0;
	stPeople		= 1;
	stPoster		= 2;
	
//Script modes
	smSearch		= 0;
	smNormal		= 1;
	smCast			= 2;
	smReview		= 3;
	smCredits		= 4;
	smPoster		= 5;
	smFinished		= 6;
	
//Parse results
	prError			= 0;
	prFinished		= 1;
	prList			= 2;
	prListImage		= 3;
	prDownload		= 4;
	
//Prefix modes
	pmNone			= 0;
	pmEnd			= 1;
	pmBegin			= 2;
	pmRemove		= 3;
	
//Download methods
	dmGET			= 0;
	dmPOST			= 1;
	
//Movie fields
	mfURL			= 0;
	mfTitle			= 1;
	mfOrigTitle		= 2;
	mfAka			= 3;
	mfYear			= 4;
	mfGenre			= 5;
	mfCategory		= 6;
	mfCountry		= 7;
	mfStudio		= 8;
	mfMPAA			= 9;
	mfRating		= 10;	
	mfTags			= 11;
	mfTagline		= 12;
	mfDescription	= 13;
	mfDuration		= 14;
	mfFeatures		= 15;
	
//People fields
    pfURL        	= 0;
	pfName       	= 1;
	pfTransName  	= 2;
	pfAltNames   	= 3;
	pfBirthday   	= 4;
	pfBirthplace 	= 5;
	pfGenre      	= 6;
	pfBio        	= 7;
	pfDeathDate  	= 8;   
	
//Credits types
	ctActors		= 0;
	ctDirectors		= 1;
	ctWriters		= 2;
	ctComposers		= 3;
	ctProducers		= 4;
	
//Script data
	SCRIPT_VERSION	= '0.1.1.1';
	SCRIPT_NAME		= 'Imdb Movie Script(cast)';
	SCRIPT_DESC		= '[EN] Get Movie Information from Imdb.com(cast)';
	SCRIPT_LANG		= $09; //English
	SCRIPT_TYPE		= stMovies;
	
	BASE_URL		= 'http://www.imdb.com';
	RATING_NAME		= 'Imdb Movie Script';
	SEARCH_STR		= 'http://www.imdb.com/find?q=%s&s=tt';
	CODE_PAGE		= 65001;	//Use 0 for Autodetect
	
//User Options
	GET_THEMES	= True;	//Set to False to ensure ~mfCategory~ not added even if 'Overwrite fields' setting allows
    GET_POSTER  = False; //Set to False or True

//Global variables
var
ELI : Integer;
//fullinfo2 : String;
Mode : Byte;
ExtraLinks : array [smCast..smPoster] of String;

//Functions
function GetScriptVersion : String;
begin
	Result := SCRIPT_VERSION;
end;

function GetScriptName : String;
begin
	Result :=  SCRIPT_NAME;
end;

function GetScriptDesc : String;
begin
	Result := SCRIPT_DESC;
end;

function GetRatingName : String;
begin
	Result := RATING_NAME;
end;

function GetScriptLang: Cardinal;
begin
	Result := SCRIPT_LANG;
end;

function GetCodePage : Cardinal;
begin
	Result := CODE_PAGE;
end;

function GetBaseURL : AnsiString;
begin
	Result := BASE_URL;
end;

function GetDownloadURL : AnsiString;
begin
	if (Mode = smSearch) then
		Result := SEARCH_STR
	else
		Result := ExtraLinks[Mode];
end;

function GetDownloadMethod : Byte;
begin
	Result := dmGET;
end;

function GetPrefixMode : Byte;
begin
	Result := pmBegin;
end;

function GetScriptType : Byte;
begin
	Result := SCRIPT_TYPE;
end;

function GetCurrentMode : Byte;
begin
	Result := Mode;
end;

procedure ParseMovie(MovieURL : String; HTML : String);
var
	curPos, endPos : Integer;
begin

MovieURL := StringReplace(MovieURL, 'fullcredits', '', true, false, true);
MovieURL := StringReplace(MovieURL, 'combined', '', true, false, true);
MovieURL := StringReplace(MovieURL, 'taglines', '', true, false, true);
MovieURL := StringReplace(MovieURL, 'releaseinfo', '', true, false, true);
MovieURL := StringReplace(MovieURL, 'soundtrack', '', true, false, true);
MovieURL := StringReplace(MovieURL, 'technical', '', true, false, true);
MovieURL := StringReplace(MovieURL, 'externalsites', '', true, false, true);
AddFieldValueXML('url', MovieURL);
GetFieldValueXML('url'); 


//Get ~Combined URL~ 
endPos := Pos('class="link" >Full Cast and Crew</a>', HTML);
if endPos > 0 then begin
	curPos := PrevPos('<a href="/title/', HTML, endPos);
	ExtraLinks[smCast] := BASE_URL + StringReplace(Copy(HTML, curPos + 9, endPos - curPos - 24), 'fullcredits', 'combined', true, false, true);
end;
// If Get ~Combined URL~ empty
endPos := Pos('class="link ghost" >Full Cast and Crew</a>', HTML);
if endPos > 0 then begin
	curPos := PrevPos('<a href="/title/', HTML, endPos);
	ExtraLinks[smCast] := BASE_URL + StringReplace(Copy(HTML, curPos + 9, endPos - curPos - 24), 'fullcredits', 'combined', true, false, true);
end;

end;

procedure ParseCast(CastURL : String; HTML : String);
var
	curPos, endPos: Integer;
	URL, Name, Role : String;
begin

//Get ~Combined URL~ 
endPos := Pos('"og:url" content="', HTML);
if endPos > 0 then begin
	curPos := PrevPos('<link rel="canonical" href="', HTML, endPos);
	ExtraLinks[smCast] := Copy(HTML, curPos+28, endPos - curPos-47);
end;


//~Full cast and crew page~

//~ctActors~ or ~Cast~
curPos := PosFrom('<div class="headerinline"><h3>Cast</h3>', HTML, endPos);
if curPos > 0 then begin
	endPos := curPos;
	curPos := PosFrom('<a href="/name/', HTML, curPos);
	while (curPos > 0) AND (curPos < PosFrom('</table>', HTML, endPos)) do begin
		curPos := curPos + Length('<a href="/name/');
		endPos := PosFrom('" onclick="', HTML, curPos);
		URL := 'http://www.imdb.com/name/' + Copy(HTML, curPos, endPos - curPos);
		curPos := PosFrom(';">', HTML, EndPos);
	if curPos > 0 then begin 
	  curPos := curPos + 3;
		endPos := PosFrom('</a></td><td class="ddd">', HTML, curPos);
		Name := RemoveTags(Trim(Copy(HTML, curPos, endPos - curPos)), true);
	  curPos := EndPos;
	end;
		curPos := PosFrom('">', HTML, EndPos);
	if curPos > 0 then begin 
	  curPos := curPos + 2;
		EndPos := PosFrom('</td></tr>', HTML, curPos);
		Role := RemoveTags(Trim(Copy(HTML, curPos, endPos - curPos)), true);
//		Role := StringReplace(Role, ' and', ' ', true, false, true);
	end else begin
		Role := '';  
	  curPos := EndPos;
	end;	

		AddMoviePerson(Name, '', Role, URL, ctActors);
		
		curPos := PosFrom('<a href="/name/', HTML, curPos);
	end;
end else
curPos := endPos;

//~ctDirectors~
curPos := PosFrom('<h5><a class="glossary" name="directors" href="/glossary/D#director">Directed by</a>', HTML, endPos);
if curPos > 0 then begin
	endPos := curPos;
	curPos := PosFrom('<a href="/name/', HTML, curPos);
	while (curPos > 0) AND (curPos < PosFrom('</table>', HTML, endPos)) do begin
		curPos := curPos + Length('<a href="/name/');
		endPos := PosFrom('">', HTML, curPos);
		URL := 'http://www.imdb.com/name/' + Copy(HTML, curPos, endPos - curPos);
		curPos := endPos + 2;
		endPos := PosFrom('</a>', HTML, curPos);
		Name := RemoveTags(Trim(Copy(HTML, curPos, endPos - curPos)), true);	
		curPos := PosFrom('<td valign="top">', HTML, EndPos);
	if curPos > 0 then begin 
	  curPos := curPos + 17;
		EndPos := PosFrom('</td></tr>', HTML, curPos);
		Role := RemoveTags(Trim(Copy(HTML, curPos, endPos - curPos)), true);
//		Role := StringReplace(Role, ' and', ' ', true, false, true);
	end else begin
		Role := '';  
	  curPos := EndPos;
	end;	
	
		AddMoviePerson(Name, '', Role, URL, ctDirectors);
		
		curPos := PosFrom('<a href="/name/', HTML, curPos);
	end;
end else
curPos := endPos;
	
//~ctWriters~	
curPos := PosFrom('<h5><a class="glossary" name="writers" href="/glossary/W#writer">Writing credits</a></h5>', HTML, endPos);
if curPos > 0 then begin
	endPos := curPos;
	curPos := PosFrom('<td valign="top"><a href="/name/', HTML, curPos);
	while (curPos > 0) AND (curPos < PosFrom('</table>', HTML, endPos)) do begin
		curPos := curPos + Length('<td valign="top"><a href="/name/');
		endPos := PosFrom('">', HTML, curPos);
		URL := 'http://www.imdb.com/name/' + Copy(HTML, curPos, endPos - curPos);
		curPos	:= PosFrom('">', HTML, endPos) + 2;
//		curPos := endPos + 2;
//		endPos := PosFrom('</td></tr>', HTML, curPos);
		endPos := PosFrom('</a>', HTML, curPos);
		Name := RemoveTags(Trim(Copy(HTML, curPos, endPos - curPos)), false);	
		curPos := PosFrom('<td valign="top">', HTML, EndPos);
	if curPos > 0 then begin 
	  curPos := curPos + 17;
		EndPos := PosFrom('</td></tr>', HTML, curPos);
		Role := RemoveTags(Trim(Copy(HTML, curPos, endPos - curPos)), true);
//		Role := Trim(Copy(HTML, curPos, endPos - curPos));
//		Role := Copy(HTML, curPos, EndPos - curPos);
		Role := StringReplace(Role, ') and', ') ', true, false, true);
		Role := StringReplace(Role, ') &', ') ', true, false, true);
		Role := StringReplace(Role, 'novel &', 'novel ', true, false, true);
//		Role := StringReplace(Role, 'story and', 'story  ', true, false, true);
//		Role := StringReplace(Role, '&', ' ', true, false, true);
	  if Pos('and', Role) = 1 then Delete(Role, 1, 3);
	  if Pos('&', Role) = 1 then Delete(Role, 1, 2);
//	  if Pos('story and', Role) = 1 then Delete(Role, 7, 3);
	end else begin
		Role := '';  
	  curPos := EndPos;
	end;
	
		AddMoviePerson(Name, '', Role, URL, ctWriters);

		curPos := PosFrom('<td valign="top"><a href="/name/', HTML, curPos);
	end;
end else
curPos := endPos;

//~ctProducers~
curPos := PosFrom('<h5><a class="glossary" name="producers" href="/glossary/P#producer">Produced by</a>', HTML, endPos);
if curPos > 0 then begin
	endPos := curPos;
	curPos := PosFrom('<a href="/name/', HTML, curPos);
	while (curPos > 0) AND (curPos < PosFrom('</table>', HTML, endPos)) do begin
		curPos := curPos + Length('<a href="/name/');
		endPos := PosFrom('">', HTML, curPos);
		URL := 'http://www.imdb.com/name/' + Copy(HTML, curPos, endPos - curPos);
		curPos := endPos + 2;
		endPos := PosFrom('</a>', HTML, curPos);
		Name := RemoveTags(Trim(Copy(HTML, curPos, endPos - curPos)), true);	
		curPos := PosFrom('<td valign="top">', HTML, EndPos);
	if curPos > 0 then begin 
	  curPos := curPos + 17;
		EndPos := PosFrom('</td></tr>', HTML, curPos);
		Role := RemoveTags(Trim(Copy(HTML, curPos, endPos - curPos)), true);
//		Role := StringReplace(Role, ' and', ' ', true, false, true);
	end else begin
		Role := '';  
	  curPos := EndPos;
	end;	
	
		AddMoviePerson(Name, '', Role, URL, ctProducers);
	
		curPos := PosFrom('<a href="/name/', HTML, curPos);
	end;
end else
curPos := endPos;
   
   
//~ctComposers~ or ~Original Music~
curPos := PosFrom('<h5><a class="glossary" name="music_original" href="/glossary/C#composer">Original Music by</a>', HTML, endPos);
if curPos > 0 then begin
	endPos := curPos;
	curPos := PosFrom('<a href="/name/', HTML, curPos);
	while (curPos > 0) AND (curPos < PosFrom('</table>', HTML, endPos)) do begin
		curPos := curPos + Length('<a href="/name/');
		endPos := PosFrom('">', HTML, curPos);
		URL := 'http://www.imdb.com/name/' + Copy(HTML, curPos, endPos - curPos);
		curPos := endPos + 2;
		endPos := PosFrom('</a>', HTML, curPos);
		Name := RemoveTags(Trim(Copy(HTML, curPos, endPos - curPos)), true);	
		curPos := PosFrom('<td valign="top">', HTML, EndPos);
	if curPos > 0 then begin 
	  curPos := curPos + 17;
		EndPos := PosFrom('</td></tr>', HTML, curPos);
		Role := RemoveTags(Trim(Copy(HTML, curPos, endPos - curPos)), true);
//		Role := StringReplace(Role, ' and', ' ', true, false, true);
	end else begin
		Role := '';  
	  curPos := EndPos;
	end;	

		AddMoviePerson(Name, '', Role, URL, ctComposers);
		
		curPos := PosFrom('<a href="/name/', HTML, curPos);
	end;
end else
curPos := endPos;
 
end;

procedure ParseSearchResults(HTML : String);
var
	curPos, endPos : Integer;
	Title, URL, Preview : String;
begin
	curPos := Pos('<table class="findList">', HTML);
	if curPos < 1 then
		Exit;

LogMessage('Parsing search results...');

	curPos  := PosFrom('<img src="', HTML, curPos) + 10;
	endPos  := PosFrom('</td> ', HTML, curPos);
	Preview := Trim(Copy(HTML, curPos, endPos - curPos));
curPos := PosFrom('<a href="/title/', HTML, curPos);
while curPos > 0 do begin
	endPos	:= PosFrom('?ref_=fn_tt_tt_', HTML, curPos);
	URL		:= Trim(Copy(HTML, curPos+9, endPos - curPos-9));
	URL		:= BASE_URL + URL;
	curPos	:= PosFrom('>', HTML, curPos)+1;
	endPos	:= PosFrom('</td> </tr>', HTML, curPos);
	Title	:= RemoveTags(Trim(Copy(HTML, curPos, endPos - curPos)), false); 
//	Title   := StringReplace(Title, ' - ', #13, true, false, true);  
	curPos  := PosFrom('<img src="', HTML, curPos) + 10;
	endPos  := PosFrom('</td> ', HTML, curPos);
	Preview := Trim(Copy(HTML, curPos, endPos - curPos));
	AddSearchResult(Title, '', '', URL, '');	
	curPos := PosFrom('<a href="/title/', HTML, curPos);
 end;
end;

function NextMode(curMode : Integer) : Integer;
var
	I : Integer;
begin
Result := smFinished;
if curMode < Low(ExtraLinks) - 1 then
	curMode := Low(ExtraLinks) - 1;

for I := curMode + 1 to High(ExtraLinks) do
	if ExtraLinks[I] <> '' then begin
		Result := I;
		Break;
	end;
end;

function ParsePage(HTML : String; URL : AnsiString) : Cardinal;
begin
HTML := HTMLToText(HTML);
HTML := StringReplace (HTML, 'http://imdb.com', 'http://www.imdb.com', True, True, False);

if Pos('Find - IMDb', HTML) > 0 then begin
	ParseSearchResults(HTML);
	Result := prList;
	Exit;

end else 
 if (Mode = 0) AND (Pos(')</title>', HTML) > 0) then begin	
    ParseMovie(URL, HTML)	
end else
 if (Mode = 0) AND (Pos('<title>IMDb - ', HTML) > 0) then begin
	ParseMovie(URL, HTML)	
end else
 if Pos('<title>IMDb - ', HTML) > 0 then
    ParseMovie(URL, HTML)
else
 if Pos(' - IMDb</title>', HTML) > 0 then
    ParseMovie(URL, HTML)
else
 if Pos(')</title>', HTML) > 0 then
    ParseCast(URL, HTML);

Mode := NextMode(Mode);
if Mode <> smFinished then
	Result := prDownload
else
	Result := prFinished;
end;

begin
Mode := smSearch;
for ELI := Low(ExtraLinks) to High(ExtraLinks) do
	ExtraLinks[ELI] := '';
end.