diff --git a/Makefile b/Makefile old mode 100755 new mode 100644 index a79fcb4..3787dd1 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ prefix=/usr/local bindir=$(prefix)${exec_prefix}/bin DESTDIR= FLAGS=$(CFLAGS) -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DSTDC_HEADERS=1 -DHAVE_LIBZ=1 -D_LARGEFILE64_SOURCE=1 -D_FILE_OFFSET_BITS=64 -DHAVE_LIBSSL=1 -DHAVE_LIBCRYPTO=1 -OBJ=containerfiles.o outputfiles.o common.o ehow.o youtube.o servicetypes.o extract_text.o download.o display.o +OBJ=containerfiles.o outputfiles.o common.o ehow.o ign.o youtube.o servicetypes.o extract_text.o download.o display.o selectformat.o all: $(OBJ) @cd libUseful-2.6; $(MAKE) @@ -28,6 +28,9 @@ common.o: common.c common.h ehow.o: ehow.c ehow.h $(CC) $(FLAGS) -c ehow.c +ign.o: ign.c ign.h + $(CC) $(FLAGS) -c ign.c + youtube.o: youtube.c youtube.h $(CC) $(FLAGS) -c youtube.c @@ -40,6 +43,9 @@ download.o: download.c download.h display.o: display.c display.h $(CC) $(FLAGS) -c display.c +selectformat.o: selectformat.c selectformat.h + $(CC) $(FLAGS) -c selectformat.c + extract_text.o: extract_text.c extract_text.h $(CC) $(FLAGS) -c extract_text.c diff --git a/Makefile.in b/Makefile.in index 6276234..0a1ed13 100755 --- a/Makefile.in +++ b/Makefile.in @@ -7,7 +7,7 @@ prefix=@prefix@ bindir=$(prefix)@bindir@ DESTDIR= FLAGS=$(CFLAGS) @DEFS@ -OBJ=containerfiles.o outputfiles.o common.o ehow.o youtube.o servicetypes.o extract_text.o download.o display.o +OBJ=containerfiles.o outputfiles.o common.o ehow.o ign.o youtube.o servicetypes.o extract_text.o download.o display.o selectformat.o all: $(OBJ) @cd libUseful-2.6; $(MAKE) @@ -28,6 +28,9 @@ common.o: common.c common.h ehow.o: ehow.c ehow.h $(CC) $(FLAGS) -c ehow.c +ign.o: ign.c ign.h + $(CC) $(FLAGS) -c ign.c + youtube.o: youtube.c youtube.h $(CC) $(FLAGS) -c youtube.c @@ -40,6 +43,9 @@ download.o: download.c download.h display.o: display.c display.h $(CC) $(FLAGS) -c display.c +selectformat.o: selectformat.c selectformat.h + $(CC) $(FLAGS) -c selectformat.c + extract_text.o: extract_text.c extract_text.h $(CC) $(FLAGS) -c extract_text.c diff --git a/common.c b/common.c index ea00639..3d2b35a 100755 --- a/common.c +++ b/common.c @@ -2,6 +2,8 @@ char *FileTypes[]={".flv",".mp3",".mp4",".mov",".wma",".m4a",".m4v",".wmv",".webm",".avi",".3gp",NULL}; char *ItemSelectionArg=NULL; +char *NowPlayingFile=NULL; +char *FormatPreference=NULL; char *FileTypeFromURL(char *URL) { @@ -55,3 +57,22 @@ DestroyString(Tempstr); return(RetStr); } + +void VarsAddDownloadItem(const char *ItemName, const char *URL, ListNode *Vars, int AddFlags) +{ +const char *ptr; +char *Token=NULL; + + //Do this without disturbing ptr, as we must return ptr + ptr=ItemName; + if (AddFlags & EXTRACT_GUESSTYPE) + { + Token=ItemCodeFromFileExtension(Token, ItemName, URL); + if (StrValid(Token)) ptr=Token; + } + + SetVar(Vars,ptr,URL); + if (Flags & FLAG_DEBUG2) fprintf(stderr,"Extracted Item: [%s] [%s]\n",ptr,URL); + +DestroyString(Token); +} diff --git a/common.h b/common.h index be1f2fb..b7f6803 100755 --- a/common.h +++ b/common.h @@ -34,9 +34,12 @@ extern int Type, Flags; extern char *FileTypes[]; extern char *ItemSelectionArg; +extern char *NowPlayingFile; +extern char *FormatPreference; char *FileTypeFromURL(char *URL); char *ItemCodeFromFileExtension(char *RetBuf, const char *Default, const char *URL); +void VarsAddDownloadItem(const char *ItemName, const char *URL, ListNode *Vars, int AddFlags); #endif diff --git a/config.log b/config.log index 8397b1a..e3fec90 100755 --- a/config.log +++ b/config.log @@ -10,11 +10,11 @@ generated by GNU Autoconf 2.69. Invocation command line was ## Platform. ## ## --------- ## -hostname = colums-hp +hostname = rack1 uname -m = x86_64 -uname -r = 4.7.4-64 +uname -r = 4.8.6-64 uname -s = Linux -uname -v = #1 SMP Fri Sep 16 22:00:54 UTC 2016 +uname -v = #13 SMP Mon Nov 21 20:22:55 UTC 2016 /usr/bin/uname -p = unknown /bin/uname -X = unknown @@ -34,23 +34,13 @@ PATH: /usr/X11R7/bin PATH: /bin PATH: /usr/games/bin PATH: . -PATH: /opt/Csound-6.05/bin -PATH: /opt/Qt4/bin -PATH: /opt/SDL/bin -PATH: /opt/SDL2/bin PATH: /opt/chkrootkit-0.50/bin -PATH: /opt/ghostscript-9.19/bin -PATH: /opt/git-2.9.3/bin -PATH: /opt/jx9-1.0/bin +PATH: /opt/gdbm-1.12/bin +PATH: /opt/git-2.10.2/bin +PATH: /opt/httpd/bin PATH: /opt/lua-5.3.3/bin -PATH: /opt/lxc-2.0.3/bin PATH: /opt/mujs-b005928/bin -PATH: /opt/perl-5.20.1/bin -PATH: /opt/poppler-0.43.0/bin -PATH: /opt/qemu-2.5.0/bin -PATH: /opt/schily/bin -PATH: /opt/wine-1.9.18/bin -PATH: /opt/x86_64/bin +PATH: /opt/perl-5.24.0/bin ## ----------- ## @@ -196,10 +186,10 @@ generated by GNU Autoconf 2.69. Invocation command line was CONFIG_COMMANDS = $ ./config.status -on colums-hp +on rack1 config.status:729: creating Makefile -configure:4604: === configuring in libUseful-2.6 (/mnt/Movgrab-2.0.0/libUseful-2.6) +configure:4604: === configuring in libUseful-2.6 (/home/metacosm89/Movgrab/libUseful-2.6) configure:4667: running /bin/sh ./configure --disable-option-checking '--prefix=/usr/local' '--enable-ssl' --cache-file=/dev/null --srcdir=. ## ---------------- ## diff --git a/config.status b/config.status index 408a943..0116640 100755 --- a/config.status +++ b/config.status @@ -427,7 +427,7 @@ Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." -ac_pwd='/mnt/Movgrab-2.0.0' +ac_pwd='/home/metacosm89/Movgrab' srcdir='.' INSTALL='/bin/install -c' test -n "$AWK" || AWK=awk diff --git a/display.c b/display.c index 951e31d..e9bd605 100755 --- a/display.c +++ b/display.c @@ -75,6 +75,19 @@ return(result); } +void WriteNowPlayingFile(const char *Title) +{ +STREAM *S; + +S=STREAMOpenFile(NowPlayingFile, SF_WRONLY | SF_CREAT | SF_TRUNC); +if (S) +{ +STREAMWriteLine(Title, S); +STREAMWriteLine("\n", S); +STREAMClose(S); +} +} + //Display progress of download void DisplayProgress(const char *FullTitle, const char *Format, double bytes_read, double DocSize, int PrintName) @@ -93,14 +106,18 @@ if (CheckForKeyboardInput()) PrintName=TRUE; if ((DisplayTitleWidth > 0) && (StrLen(FullTitle) > DisplayTitleWidth)) { -Title=CopyStrLen(Title, FullTitle, DisplayTitleWidth); -Title=CatStr(Title,"..."); + Title=CopyStrLen(Title, FullTitle, DisplayTitleWidth); + Title=CatStr(Title,"..."); } else Title=CopyStr(Title, FullTitle); if (! (Flags & FLAG_QUIET)) { -if (PrintName) fprintf(stderr,"\nGetting: %s Size: %s Format: %s\n",Title,GetHumanReadableDataQty(DocSize,0), Format); +if (PrintName) +{ + fprintf(stderr,"\nGetting: %s Size: %s Format: %s\n",Title,GetHumanReadableDataQty(DocSize,0), Format); + if (StrLen(NowPlayingFile)) WriteNowPlayingFile(Title); +} } if ((Now != SpeedStart) && (Now != LastDisplay)) diff --git a/download.c b/download.c index 7288f2c..5073e01 100755 --- a/download.c +++ b/download.c @@ -34,7 +34,7 @@ if (BytesRange > 0) SetVar(Info->CustomSendHeaders,"Range",Tempstr); } -SetVar(Info->CustomSendHeaders,"Icy-MetaData","1"); +//SetVar(Info->CustomSendHeaders,"Icy-MetaData","1"); Con=HTTPTransact(Info); if ((! Con) && (! (Flags & FLAG_QUIET))) @@ -43,6 +43,7 @@ if ((! Con) && (! (Flags & FLAG_QUIET))) else fprintf(stderr,"ERROR: Connection failed to %s can't get file=%s \n",Info->Host, Info->Doc); } + DestroyString(Tempstr); DestroyString(Method); diff --git a/extract_text.c b/extract_text.c index fe70e72..46d1d87 100755 --- a/extract_text.c +++ b/extract_text.c @@ -1,6 +1,7 @@ #include "extract_text.h" + //This function Extracts Text from a line that's found between two specified //chunks of text 'ItemStart' and 'ItemEnd' char *GenericExtractFromLine(char *Line, const char *ItemName, const char *ItemStart, const char *ItemEnd, ListNode *Vars, int ExtractFlags) @@ -55,16 +56,7 @@ int GTF=0; } } - //Do this without disturbing ptr, as we must return ptr - ptr2=ItemName; - if (ExtractFlags & EXTRACT_GUESSTYPE) - { - Token=ItemCodeFromFileExtension(Token, ItemName, Item); - if (StrValid(Token)) ptr2=Token; - } - - SetVar(Vars,ptr2,Item); - if (Flags & FLAG_DEBUG2) fprintf(stderr,"Extracted Item: [%s] [%s]\n",ptr2,Item); + VarsAddDownloadItem(ItemName, Item, Vars, ExtractFlags); DestroyString(Token); DestroyString(Item); @@ -72,3 +64,18 @@ DestroyString(Item); return(ptr); } + +void GenericTitleExtract(const char *Line, ListNode *Vars) +{ +if (strstr(Line,"")) GenericExtractFromLine(Line, "Title:html","<title>","", Vars,EXTRACT_DEQUOTE); + +if (strstr(Line,"&5 -/tmp/ccWDByHS.o: In function `main': -/mnt/Movgrab-2.0.0/libUseful-2.6/conftest.c:59: undefined reference to `OpenSSL_add_all_algorithms' +/tmp/ccQx0Pjv.o: In function `main': +/home/metacosm89/Movgrab/libUseful-2.6/conftest.c:59: undefined reference to `OpenSSL_add_all_algorithms' collect2: error: ld returned 1 exit status configure:3731: $? = 1 configure: failed program was: @@ -370,8 +360,8 @@ configure:3731: $? = 0 configure:3731: result: yes configure:3731: checking for EVP_rc5_32_12_16_cbc configure:3731: gcc -o conftest -g -O2 conftest.c -lcrypto -lssl -lc >&5 -/tmp/ccK0AmXk.o: In function `main': -/mnt/Movgrab-2.0.0/libUseful-2.6/conftest.c:62: undefined reference to `EVP_rc5_32_12_16_cbc' +/tmp/cc6WIzAl.o: In function `main': +/home/metacosm89/Movgrab/libUseful-2.6/conftest.c:62: undefined reference to `EVP_rc5_32_12_16_cbc' collect2: error: ld returned 1 exit status configure:3731: $? = 1 configure: failed program was: @@ -492,7 +482,7 @@ generated by GNU Autoconf 2.69. Invocation command line was CONFIG_COMMANDS = $ ./config.status -on colums-hp +on rack1 config.status:727: creating Makefile diff --git a/libUseful-2.6/config.status b/libUseful-2.6/config.status index 5c5f067..65f9971 100755 --- a/libUseful-2.6/config.status +++ b/libUseful-2.6/config.status @@ -427,7 +427,7 @@ Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." -ac_pwd='/mnt/Movgrab-2.0.0/libUseful-2.6' +ac_pwd='/home/metacosm89/Movgrab/libUseful-2.6' srcdir='.' test -n "$AWK" || AWK=awk # The default lists apply if the user does not specify any file. diff --git a/libUseful-2.6/http.c b/libUseful-2.6/http.c index 4900f88..a91c5a7 100755 --- a/libUseful-2.6/http.c +++ b/libUseful-2.6/http.c @@ -481,6 +481,11 @@ char *AppendCookies(char *InStr, ListNode *CookieList) return(Tempstr); } +void HTTPClearCookies() +{ +ListClear(Cookies, DestroyString); +} + int HTTPHandleWWWAuthenticate(char *Line, int *Type, char **Config) { char *ptr, *ptr2, *Token=NULL, *Name=NULL, *Value=NULL; @@ -853,7 +858,7 @@ else } ptr=LibUsefulGetValue("HTTP:User-Agent"); -//if (StrValid(ptr)) SendStr=MCatStr(SendStr,"User-Agent: ",ptr, "\r\n",NULL); +if (StrValid(ptr)) SendStr=MCatStr(SendStr,"User-Agent: ",ptr, "\r\n",NULL); Curr=ListGetNext(Info->CustomSendHeaders); while (Curr) diff --git a/libUseful-2.6/http.h b/libUseful-2.6/http.h index 3e1b050..0efe1b1 100755 --- a/libUseful-2.6/http.h +++ b/libUseful-2.6/http.h @@ -118,6 +118,8 @@ char *HTTPReadDocument(char *RetStr, STREAM *S); void HTTPCopyToSTREAM(STREAM *Con, STREAM *S); int HTTPDownload(char *URL, char *Login, char *Password, STREAM *S); +void HTTPClearCookies(); + #ifdef __cplusplus } #endif diff --git a/libUseful-2.6/libUseful-2.6.a b/libUseful-2.6/libUseful-2.6.a old mode 100755 new mode 100644 index 43adac1..5ec06ee Binary files a/libUseful-2.6/libUseful-2.6.a and b/libUseful-2.6/libUseful-2.6.a differ diff --git a/libUseful-2.6/libUseful-2.6.so b/libUseful-2.6/libUseful-2.6.so index 0a84b7a..2d632f7 100755 Binary files a/libUseful-2.6/libUseful-2.6.so and b/libUseful-2.6/libUseful-2.6.so differ diff --git a/main.c b/main.c index 2ba5ffa..83b8a67 100755 --- a/main.c +++ b/main.c @@ -31,7 +31,6 @@ int Flags=0; char *ProgName=NULL, *CmdLine=NULL; -char *FormatPreference=NULL; ListNode *DownloadQueue=NULL; STREAM *StdIn=NULL; char *Username=NULL, *Password=NULL; @@ -115,118 +114,6 @@ return(RetVal); -char *GatherMatchingFormats(char *Buffer, char *Type, ListNode *Vars) -{ -ListNode *Curr; -char *Tempstr=NULL; - -Tempstr=CopyStr(Buffer,""); -Curr=ListGetNext(Vars); -while (Curr) -{ -if (strncmp(Curr->Tag,"item:",5)==0) -{ -if ((StrLen(Type)==0) || (strncmp(Curr->Tag,Type,StrLen(Type))==0)) Tempstr=MCatStr(Tempstr,Curr->Tag+5," ",NULL); -} - -Curr=ListGetNext(Curr); -} - -return(Tempstr); -} - -int FmtIDMatches(char *FmtID, char *CurrItem, char *ItemData) -{ - if (strncmp(CurrItem,"item:",5) !=0) return(FALSE); - if (StrLen(FmtID)==0) return(TRUE); - if (strcmp(FmtID,"item:*")==0) return(TRUE); - if ((strncmp(CurrItem,FmtID,StrLen(FmtID))==0) && (StrLen(ItemData))) return(TRUE); - return(FALSE); -} - - - -//this function compares the video formats found on the page to the list of -//preferences expressed by the user with the '-f' flag, and contained in the -//global variable 'FormatPreference' -int SelectDownloadFormat(ListNode *Vars, int WebsiteType, int DisplaySize) -{ -ListNode *Curr; -char *ptr, *Tempstr=NULL, *Fmt=NULL, *FmtID=NULL, *Selected=NULL, *p_ItemFormat; -int RetVal=-1, FoundMatch=FALSE, i; - -Tempstr=GatherMatchingFormats(Tempstr,"",Vars); - if (! (Flags & FLAG_QUIET)) - { - for (i=0; i < 3; i++) - { - if (DisplayAvailableFormats(Vars, Tempstr, DisplaySize)) break; - //printf("Connection Refused, sleeping for 20 secs before retry\n"); - //sleep(10); - break; - } - } - - ptr=GetToken(FormatPreference,",",&Fmt,0); - while (ptr) - { - if (StrLen(Fmt)) FmtID=MCopyStr(FmtID,"item:",Fmt,NULL); - else FmtID=CopyStr(FmtID,""); - - if (Flags & FLAG_DEBUG) fprintf(stderr," %s ",Fmt); - - FoundMatch=FALSE; - Curr=ListGetNext(Vars); - while (Curr) - { - if (FmtIDMatches(FmtID,Curr->Tag, (char *) Curr->Item)) - { - if (Flags & (FLAG_DEBUG)) - { - Tempstr=GatherMatchingFormats(Tempstr,FmtID,Vars); - fprintf(stderr,"... YES! %s\n",Tempstr); - } - - FoundMatch=TRUE; - //where available a local filetype overrides a reference - if ((RetVal==-1) || (RetVal==TYPE_REFERENCE)) - { - Selected=CopyStr(Selected,Curr->Tag); - SetVar(Vars,"ID",(char *) Curr->Item); - } - break; - } - Curr=ListGetNext(Curr); - } - if ((! FoundMatch) && (Flags & (FLAG_DEBUG))) fprintf(stderr,"... no\n",Fmt); - ptr=GetToken(ptr,",",&Fmt,0); - } - - -if (StrLen(Selected)) -{ - if (strcmp(Selected,"item:reference")==0) RetVal=TYPE_REFERENCE; - if (strncmp(Selected,"item:m3u8-stream",16)==0) RetVal=TYPE_CONTAINERFILE_M3U8; - else RetVal=WebsiteType; -} - -if (! (Flags & FLAG_TEST_SITES)) -{ - if (RetVal==-1) fprintf(stderr,"No suitable download format found from '%s'\n\n",FormatPreference); - else if (RetVal==TYPE_REFERENCE) fprintf(stderr,"Reference to another site: %s\n",GetVar(Vars,"ID")); - else fprintf(stderr,"Selected format %s\n",Selected); -} - - -//+5 to get past leading 'item:' in variable name -if (StrLen(Selected)) SetVar(Vars,"DownloadFormat",Selected+5); - -DestroyString(Selected); -DestroyString(Tempstr); -DestroyString(Fmt); -return(RetVal); -} - void PrintVersion() @@ -262,6 +149,7 @@ fprintf(stdout,"'-proxy' address of http/https/socks4/socks5/sstunnel proxy ser fprintf(stdout,"'-w' Wait for addresses to be entered on stdin.\n"); fprintf(stdout,"'-st' Connection inactivity timeout in seconds. Set high for sites that 'throttle'\n"); fprintf(stdout,"'-tw ' Set max width of item title in progress display (Default 50 chars)\n"); +fprintf(stdout,"'-np ' File to write current title to. Useful as 'now plaing' for internet radio streams\n"); fprintf(stdout,"'-t' specifies website type.\n"); fprintf(stdout,"'-r' Resume download (only works when writing a single file, not with +o).\n"); fprintf(stdout,"'-f' specifies preferred video/audio formats for sites that offer more than one\n"); @@ -358,6 +246,7 @@ for (i=1; i < argc; i++) else if (strcmp(argv[i],"-T")==0) Flags |= FLAG_TEST; else if (strcmp(argv[i],"-w")==0) Flags |= FLAG_STDIN; else if (strcmp(argv[i],"-dt")==0) DisplayTitleWidth=atoi(argv[++i]); + else if (strcmp(argv[i],"-np")==0) NowPlayingFile=CopyStr(NowPlayingFile, argv[++i]); else if (strcmp(argv[i],"-st")==0) STREAMTimeout=atoi(argv[++i]); else if (strcmp(argv[i],"-P")==0) Player=CopyStr(Player,argv[++i]); else if (strcmp(argv[i],"-Pp")==0) PlayerLaunchPercent=atoi(argv[++i]); @@ -456,7 +345,7 @@ ParseEnvironmentVariables(); DownloadQueue=ListCreate(); Tempstr=MCopyStr(Tempstr,"Movgrab ",Version,NULL); HTTPSetUserAgent(Tempstr); -FormatPreference=CopyStr(FormatPreference,"mp4,flv,webm,m4v,mov,mpg,mpeg,wmv,avi,3gp,reference,mp3,m4a,wma,m3u8,m3u8-stream"); +FormatPreference=CopyStr(FormatPreference,"mp4,flv,webm,m4v,mov,mpg,mpeg,wmv,avi,3gp,mp3,m4a,wma,m3u8,m3u8-stream,reference"); AddOutputFile("", TRUE); ParseCommandLine(argc, argv, DownloadQueue, &OverrideType); @@ -510,6 +399,7 @@ while (1) } ListDeleteNode(Curr); + HTTPClearCookies(); Curr=Next; } diff --git a/selectformat.c b/selectformat.c new file mode 100644 index 0000000..ccad474 --- /dev/null +++ b/selectformat.c @@ -0,0 +1,123 @@ +#include "selectformat.h" +#include "servicetypes.h" + +char *GatherMatchingFormats(char *Buffer, char *Type, ListNode *Vars) +{ +ListNode *Curr; +char *Tempstr=NULL; + +Tempstr=CopyStr(Buffer,""); +Curr=ListGetNext(Vars); +while (Curr) +{ +if (strncmp(Curr->Tag,"item:",5)==0) +{ +if ((StrLen(Type)==0) || (strncmp(Curr->Tag,Type,StrLen(Type))==0)) Tempstr=MCatStr(Tempstr,Curr->Tag+5," ",NULL); +} + +Curr=ListGetNext(Curr); +} + +return(Tempstr); +} + +int FmtIDMatches(const char *FmtID, const char *CurrItem, const char *ItemData) +{ +int len; + +len=StrLen(FmtID); + +if (len==0) return(TRUE); +if (strcmp(FmtID,"item:*")==0) return(TRUE); +if (strncmp(CurrItem,"item:",5) !=0) return(FALSE); + +if ((strncmp(CurrItem,FmtID,StrLen(FmtID))==0) && StrValid(ItemData)) return(TRUE); +return(FALSE); +} + + + +//this function compares the video formats found on the page to the list of +//preferences expressed by the user with the '-f' flag, and contained in the +//global variable 'FormatPreference' +int SelectDownloadFormat(ListNode *Vars, int WebsiteType, int DisplaySize) +{ +ListNode *Curr; +char *ptr, *Tempstr=NULL, *Fmt=NULL, *FmtID=NULL, *Selected=NULL, *p_ItemFormat; +int RetVal=-1, FoundMatch=FALSE, i; + +Tempstr=GatherMatchingFormats(Tempstr,"",Vars); + if (! (Flags & FLAG_QUIET)) + { + for (i=0; i < 3; i++) + { + if (DisplayAvailableFormats(Vars, Tempstr, DisplaySize)) break; + //printf("Connection Refused, sleeping for 20 secs before retry\n"); + //sleep(10); + break; + } + } + + ptr=GetToken(FormatPreference,",",&Fmt,0); + while (ptr) + { + if (StrLen(Fmt)) FmtID=MCopyStr(FmtID,"item:",Fmt,NULL); + else FmtID=CopyStr(FmtID,""); + + if (Flags & FLAG_DEBUG) fprintf(stderr," %s ",Fmt); + + FoundMatch=FALSE; + Curr=ListGetNext(Vars); + while (Curr) + { + if (FmtIDMatches(FmtID,Curr->Tag, (char *) Curr->Item)) + { + if (Flags & (FLAG_DEBUG)) + { + Tempstr=GatherMatchingFormats(Tempstr,FmtID,Vars); + fprintf(stderr,"... YES! %s\n",Tempstr); + } + + if (! StrValid(Selected)) + { + Selected=CopyStr(Selected,Curr->Tag); + SetVar(Vars,"ID",(char *) Curr->Item); + } + + FoundMatch=TRUE; + break; + } + Curr=ListGetNext(Curr); + } + + if ((! FoundMatch) && (Flags & FLAG_DEBUG)) fprintf(stderr,"... no\n",Fmt); + + + ptr=GetToken(ptr,",",&Fmt,0); + } + + +if (StrValid(Selected)) +{ + if (strcmp(Selected,"item:reference")==0) RetVal=TYPE_REFERENCE; + else if (strncmp(Selected,"item:m3u8-stream",16)==0) RetVal=TYPE_CONTAINERFILE_M3U8; + else RetVal=WebsiteType; +} + +if (! (Flags & FLAG_TEST_SITES)) +{ + if (RetVal==-1) fprintf(stderr,"No suitable download format found from '%s'\n\n",FormatPreference); + else if (RetVal==TYPE_REFERENCE) fprintf(stderr,"Reference to another site: %s\n",GetVar(Vars,"ID")); + else fprintf(stderr,"Selected format %s\n",Selected); +} + + +//+5 to get past leading 'item:' in variable name +if (StrLen(Selected)) SetVar(Vars,"DownloadFormat",Selected+5); + +DestroyString(Selected); +DestroyString(Tempstr); +DestroyString(Fmt); +return(RetVal); +} + diff --git a/selectformat.h b/selectformat.h new file mode 100644 index 0000000..9604ca6 --- /dev/null +++ b/selectformat.h @@ -0,0 +1,8 @@ +#ifndef MOVGRAB_SELECTFORMAT +#define MOVGRAB_SELECTFORMAT + +#include "common.h" + +int SelectDownloadFormat(ListNode *Vars, int WebsiteType, int DisplaySize); + +#endif diff --git a/servicetypes.c b/servicetypes.c index 4820812..8e21236 100755 --- a/servicetypes.c +++ b/servicetypes.c @@ -1,5 +1,6 @@ #include "servicetypes.h" #include "containerfiles.h" +#include "selectformat.h" /* This file and it's header (servicetypes.h) holds all the functions and data @@ -13,7 +14,7 @@ Then site specific //Site type names used at the command line etc -char *DownloadTypes[]={"none","generic","youtube","youtu.be","metacafe","dailymotion","break","ehow","vimeo","ted","redbalcony","yale","reuters","liveleak","photobucket","iviewtube","washingtonpost","cbsnews","france24","euronews","metatube","guardian","redorbit","scivee","izlese","uctv.tv","royalsociety.tv","britishacademy","kitp","dotsub","astronomy.com","discovery","bloomberg","nationalgeographic","videobash","ibtimes","smh","animehere","funnyordie",NULL}; +char *DownloadTypes[]={"none","generic","youtube","youtu.be","metacafe","dailymotion","break","ehow","vimeo","ted","yale","reuters","liveleak","photobucket","iviewtube","washingtonpost","cbsnews","france24","euronews","metatube","guardian","redorbit","scivee","izlese","uctv.tv","royalsociety.tv","britishacademy","kitp","dotsub","astronomy.com","discovery","bloomberg","nationalgeographic","videobash","ibtimes","smh","animehere","funnyordie","ign","ebaumsworld",NULL}; //Longer names used in display char *DownloadNames[]={"none", @@ -26,7 +27,6 @@ char *DownloadNames[]={"none", "www.ehow.com", "www.vimeo.com", "www.ted.com", -"www.redbalcony.com", "Yale University: http://oyc.yale.edu", "Reuters: http://www.reuters.com/", "Liveleak: http://www.liveleak.com", @@ -56,6 +56,8 @@ char *DownloadNames[]={"none", "Sidney Morning Herald", "www.animehere.com", "Funny or Die (http://www.funnyordie.com)", +"IGN", +"Ebaums World", NULL}; //"http://vimeo.com/33204284", @@ -66,11 +68,10 @@ char *TestLinks[]={"", "", "http://youtu.be/OdrEId7YI1k", "http://www.metacafe.com/watch/6063075/how_to_use_chopsticks/", "http://www.dailymotion.com/video/x5790e_hubblecast-16-galaxies-gone-wild_tech", -"http://www.break.com/index/ninja-cat.html", +"http://www.break.com/video/break-compilations-2591623/cats-vs-the-world-iii-breaking-videos-3075295", "http://www.ehow.com/video_6819748_creamy-thyme-scrambled-eggs-recipe.html", "broken", "http://www.ted.com/talks/janine_benyus_shares_nature_s_designs.html", -"http://www.redbalcony.com/?vid=29433", "http://oyc.yale.edu/economics/game-theory/contents/sessions/session-1-introduction-five-first-lessons", "http://www.reuters.com/video/2016/05/02/foam-swords-drawn-in-mass-play-fight-in?videoId=368328211", "http://www.liveleak.com/view?i=e28_1462299205", @@ -82,7 +83,7 @@ char *TestLinks[]={"", "", "http://www.euronews.com/news/bulletin/", "http://www.metatube.com/en/videos/cid2/Funny-Videos/53210/Rail-Jump-Fail/", "http://www.guardian.co.uk/world/video/2011/may/13/fukushima-radiation-dairy-farmers-video", -"http://www.redorbit.com/video/using-f1-technology-to-transform-healthcare-012016/" +"http://www.redorbit.com/video/using-f1-technology-to-transform-healthcare-012016/", "http://www.scivee.tv/node/5300", "http://www.izlese.org/hot-girl-hot-cars-911-turbo-vs-mercedes-s550-vs-rally-car.html", "http://www.uctv.tv/search-details.aspx?showID=20888", @@ -99,11 +100,11 @@ char *TestLinks[]={"", "", "http://www.smh.com.au/technology/sci-tech/newly-discovered-planets-include-superearth-20110913-1k7tl.html", "http://www.animehere.com/accel-world-episode-1.html", "http://www.funnyordie.com/videos/032785be3a/genie-on-hard-times-with-parker-posey?playlist=featured_videos", +"http://www.ign.com/videos/2013/06/05/the-last-of-us-review", +"http://www.ebaumsworld.com/videos/a-giant-python-opens-the-door/83367677/", NULL}; -int SelectDownloadFormat(ListNode *Vars, int WebsiteType, int DisplaySize); - //Guess service type from servername in URL int IdentifyServiceType(const char *URL) @@ -159,10 +160,6 @@ else if (strstr(Server,"photobucket.com")) { Type=TYPE_PHOTOBUCKET; } -else if (strstr(Server,"redbalcony.com")) -{ - Type=TYPE_REDBALCONY; -} else if (strstr(Server,"izlese.org")) { Type=TYPE_IZLESE; @@ -279,6 +276,14 @@ else if (strstr(Server,"funnyordie.com")) { Type=TYPE_FUNNYORDIE; } +else if (strstr(Server,".ign.")) +{ + Type=TYPE_IGN; +} +else if (strstr(Server,".ebaumsworld.com")) +{ + Type=TYPE_EBAUMSWORLD; +} else if (strstr(Server,".google.")) { Type=TYPE_GOOGLE_URL; @@ -300,14 +305,14 @@ char *ExtractMetacafeMediaURL(char *RetStr, char *Data, char *Start, char *End) char *Tempstr=NULL, *Token=NULL, *ptr; - ptr=strstr(Data,Start); - ptr+=StrLen(Start); - ptr=GetToken(ptr,End,&Token,0); - Tempstr=HTTPUnQuote(Tempstr,Token); - RetStr=MCopyStr(RetStr,Tempstr,"?__gda__=",NULL); - ptr=GetToken(Data,"gdaKey=",&Token,0); - ptr=GetToken(ptr,"&",&Token,0); - RetStr=CatStr(RetStr,Token); +ptr=strstr(Data,Start); +ptr+=StrLen(Start); +ptr=GetToken(ptr,End,&Token,0); +Tempstr=HTTPUnQuote(Tempstr,Token); +RetStr=MCopyStr(RetStr,Tempstr,"?__gda__=",NULL); +ptr=GetToken(Data,"gdaKey=",&Token,0); +ptr=GetToken(ptr,"&",&Token,0); +RetStr=CatStr(RetStr,Token); DestroyString(Tempstr); DestroyString(Token); @@ -570,13 +575,8 @@ break; case TYPE_BREAK_COM: - Tempstr=CopyStr(Tempstr,GetVar(Vars,"ID")); - RetVal=DownloadItem(Tempstr, Title, Fmt, Flags); -break; - -case TYPE_DAILYMOTION: - Tempstr=SubstituteVarsInString(Tempstr,"$(ID)",Vars,0); - RetVal=DownloadItem(Tempstr, Title, Fmt, Flags); + Tempstr=SubstituteVarsInString(Tempstr,"http://www.break.com/$(ID)",Vars,0); + RetVal=DownloadPage(Tempstr,TYPE_BREAK_STAGE2,Title,Flags); break; case TYPE_WASHINGTONPOST_JSON: @@ -599,18 +599,6 @@ case TYPE_VIMEO_STAGE2: break; -case TYPE_YALE: - Tempstr=SubstituteVarsInString(Tempstr,"$(ID)",Vars,0); - RetVal=DownloadItem(Tempstr,Title, Fmt, Flags); -break; - -case TYPE_REDBALCONY: - Tempstr=SubstituteVarsInString(Tempstr,"$(ID)",Vars,0); - RetVal=DownloadPage(Tempstr,TYPE_REDBALCONY_STAGE2, Title,Flags); -break; - - - case TYPE_ROYALSOCIETY: ptr=GetVar(Vars,"ID"); if (ptr && (strncmp(ptr,"http:",5)==0)) RetVal=DownloadItem(ptr,Title, Fmt, Flags); @@ -653,16 +641,18 @@ case TYPE_BLOOMBERG: RetVal=DownloadItem(Tempstr, Title, Fmt, Flags); break; -case TYPE_VIDEOBASH: - Tempstr=SubstituteVarsInString(Tempstr,"http://$(ID)",Vars,0); - RetVal=DownloadItem(Tempstr, Title, Fmt, Flags); -break; case TYPE_ANIMEHERE: Tempstr=SubstituteVarsInString(Tempstr,"$(ID)",Vars,0); RetVal=DownloadPage(Tempstr,TYPE_ANIMEHERE_STAGE2, Title,Flags); break; +case TYPE_IGN: + Tempstr=SubstituteVarsInString(Tempstr,"http://apis.ign.com/video/v3/videos/$(ID)",Vars,0); + RetVal=DownloadPage(Tempstr,TYPE_IGN_STAGE2, Title,Flags); +break; + + case TYPE_DOTSUB: case TYPE_KAVLIINSTITUTE_STAGE2: case TYPE_SCIVEE: @@ -685,17 +675,21 @@ case TYPE_FRANCE24: case TYPE_METATUBE: case TYPE_GUARDIAN: case TYPE_REDORBIT_STAGE2: -case TYPE_REDBALCONY_STAGE2: case TYPE_ASTRONOMYCOM_STAGE2: case TYPE_ANIMEHERE_STAGE2: +case TYPE_BREAK_STAGE2: +case TYPE_IGN_STAGE2: case TYPE_FUNNYORDIE: +case TYPE_EBAUMSWORLD: +case TYPE_DAILYMOTION: +case TYPE_VIDEOBASH: case TYPE_EHOW: +case TYPE_YALE: case TYPE_CONTAINERFILE_PLS: case TYPE_CONTAINERFILE_ASX: case TYPE_CONTAINERFILE_M3U8: - Tempstr=SubstituteVarsInString(Tempstr,"$(ID)",Vars,0); - if ((strncmp(Tempstr,"http:",5)!=0) && (strncmp(Tempstr,"https:",6)!=0)) Tempstr=SubstituteVarsInString(Tempstr,"http:$(ID)",Vars,0); - + Tempstr=CopyStr(Tempstr, GetVar(Vars,"ID")); + if ((strncmp(Tempstr,"http:",5)!=0) && (strncmp(Tempstr,"https:",6)!=0)) Tempstr=MCopyStr(Tempstr,"http:",GetVar(Vars,"ID"),NULL); RetVal=DownloadItem(Tempstr, Title, Fmt, Flags); break; } @@ -783,9 +777,6 @@ char *ptr, *ptr2; int MediaCount=0, i, Port; int RetVal=FALSE, State=0; -#define GENERIC_TITLE_START "" -#define GENERIC_TITLE_END "" - ParseURL(URL,NULL,&Server,&Token,NULL,NULL,NULL,NULL); Port=atoi(Token); @@ -795,9 +786,8 @@ SetVar(Vars,"Server",Server); Tempstr=FormatStr(Tempstr,"%d",Port); SetVar(Vars,"Port",Tempstr); -SetVar(Vars,"Title",Title); - if (Flags & (FLAG_DEBUG2 | FLAG_DEBUG3)) fprintf(stderr,"\n------- DOWNLOADING DOCUMENT ------\n"); +if (Flags & (FLAG_DEBUG2 | FLAG_DEBUG3)) fprintf(stderr,"\n------- DOWNLOADING DOCUMENT ------\n"); Tempstr=STREAMReadLine(Tempstr, S); while (Tempstr) @@ -861,7 +851,7 @@ else if (strncmp(Tempstr,"#EXT-X-STREAM-INF:",18)==0) } } } -else if (*Tempstr !=0) +else if (*Tempstr !=0) VarsAddDownloadItem("item:mp3", Tempstr, Vars, EXTRACT_GUESSTYPE); break; @@ -909,48 +899,70 @@ break; case TYPE_METACAFE: #define METACAFE_ITEM "&mediaData=" #define METACAFE_MEDIA_URL ",\"mediaURL\":\"" - if (strstr(Tempstr,GENERIC_TITLE_START)) - { - GenericExtractFromLine(Tempstr, "Title",GENERIC_TITLE_START,GENERIC_TITLE_END, Vars,EXTRACT_DEQUOTE); - } +GenericTitleExtract(Tempstr, Vars); - if (strstr(Tempstr,METACAFE_ITEM)) - { - GenericExtractFromLine(Tempstr, "metacafe:mediaData",METACAFE_ITEM,"&", Vars, EXTRACT_DEQUOTE); - ptr=GetVar(Vars,"metacafe:mediaData"); - GenericExtractFromLine(ptr, "item:mp4",METACAFE_MEDIA_URL,"\"", Vars, EXTRACT_DESLASHQUOTE|EXTRACT_GUESSTYPE); - } +if (strstr(Tempstr,METACAFE_ITEM)) +{ + GenericExtractFromLine(Tempstr, "metacafe:mediaData",METACAFE_ITEM,"&", Vars, EXTRACT_DEQUOTE); + ptr=GetVar(Vars,"metacafe:mediaData"); + GenericExtractFromLine(ptr, "item:mp4",METACAFE_MEDIA_URL,"\"", Vars, EXTRACT_DESLASHQUOTE|EXTRACT_GUESSTYPE); +} break; case TYPE_BREAK_COM: -#define BREAK_ITEM_START "videoPath: '" -#define BREAK_EXTRA_START "icon: '" -#define BREAK_END "'" -#define BREAK_TITLE "sVidTitle: '" +#define BREAK_ITEM_START "name=\"Break.com Video Player\" src=\"" +#define BREAK_END "\"" + + GenericTitleExtract(Tempstr, Vars); + if (strstr(Tempstr,BREAK_ITEM_START)) GenericExtractFromLine(Tempstr, "ID",BREAK_ITEM_START,BREAK_END,Vars,EXTRACT_DEQUOTE | EXTRACT_NOSPACES); +break; - ptr=strstr(Tempstr,BREAK_ITEM_START); - if (ptr) GenericExtractFromLine(Tempstr, "item:flv",BREAK_ITEM_START,BREAK_END,Vars,EXTRACT_DEQUOTE | EXTRACT_NOSPACES); +case TYPE_BREAK_STAGE2: +#define BREAK_STAGE2_REF " 0) + { + VarName=FormatStr(VarName,"width:%d",State); + Token=MCopyStr(Token, "item:mp4:",GetVar(Vars,VarName),"x",NULL); + VarName=FormatStr(VarName,"height:%d",State); + Token=CatStr(Token, GetVar(Vars,VarName)); + VarName=FormatStr(VarName,"ID:%d",State); + SetVar(Vars,Token,GetVar(Vars,VarName)); + } -break; + VarName=FormatStr(VarName,"ID:%d",++State); + GenericExtractFromLine(Tempstr, VarName,BREAK_STAGE2_URI,BREAK_STAGE2_END,Vars,EXTRACT_DEQUOTE | EXTRACT_NOSPACES); + } + if (strstr(Tempstr,BREAK_STAGE2_WIDTH)) + { + VarName=FormatStr(VarName,"width:%d",State); + GenericExtractFromLine(Tempstr, VarName,BREAK_STAGE2_WIDTH,",",Vars,EXTRACT_DEQUOTE | EXTRACT_NOSPACES); + } + if (strstr(Tempstr,BREAK_STAGE2_HEIGHT)) + { + VarName=FormatStr(VarName,"height:%d",State); + GenericExtractFromLine(Tempstr, VarName,BREAK_STAGE2_HEIGHT,",",Vars,EXTRACT_DEQUOTE | EXTRACT_NOSPACES); + } +break; case TYPE_EHOW: #define EHOW_LINE "property=\"og:video\"" @@ -1060,6 +1072,7 @@ case TYPE_TED: #define TED2_ITEM_START "name="flashvars" value="vu=" #define TED2_ITEM_END "&" +GenericTitleExtract(Tempstr, Vars); if (strstr(Tempstr,TED_ITEM_LINE)) { @@ -1071,12 +1084,6 @@ if (strstr(Tempstr,TED2_ITEM_LINE)) { GenericExtractFromLine(Tempstr, "item:mp4:alt",TED2_ITEM_START,TED2_ITEM_END,Vars,EXTRACT_DEQUOTE | EXTRACT_NOSPACES); } - - -if (strstr(Tempstr,GENERIC_TITLE_START)) -{ - GenericExtractFromLine(Tempstr, "Title",GENERIC_TITLE_START,GENERIC_TITLE_END,Vars,EXTRACT_DEQUOTE); -} break; @@ -1089,6 +1096,8 @@ case TYPE_YALE: #define YALE_TYPE_START "id=\"" + +GenericTitleExtract(Tempstr, Vars); if (strstr(Tempstr,YALE_ITEM_LINE)) { GenericExtractFromLine(Tempstr, "YI_TYPE",YALE_TYPE_START,YALE_ITEM_END,Vars,EXTRACT_DEQUOTE | EXTRACT_NOSPACES); @@ -1104,45 +1113,9 @@ if (strstr(Tempstr,YALE_ITEM_LINE)) GenericExtractFromLine(Tempstr, Token,YALE_ITEM_START,YALE_ITEM_END,Vars,EXTRACT_DEQUOTE | EXTRACT_NOSPACES); } - -if (strstr(Tempstr,GENERIC_TITLE_START)) -{ - GenericExtractFromLine(Tempstr, "Title",GENERIC_TITLE_START,GENERIC_TITLE_END,Vars,EXTRACT_DEQUOTE); -} - -break; - -case TYPE_REDBALCONY: -#define REDBALCONY_ITEM_START "playlist\":\"" -#define REDBALCONY_ITEM_END "\"" - -if (strstr(Tempstr,REDBALCONY_ITEM_START)) -{ - GenericExtractFromLine(Tempstr, "ID",REDBALCONY_ITEM_START,REDBALCONY_ITEM_END,Vars,EXTRACT_DEQUOTE | EXTRACT_NOSPACES); -} - - -if (strstr(Tempstr,GENERIC_TITLE_START)) -{ - GenericExtractFromLine(Tempstr, "Title",GENERIC_TITLE_START,GENERIC_TITLE_END,Vars,EXTRACT_DEQUOTE); -} - -break; - -case TYPE_REDBALCONY_STAGE2: -#define REDBALCONY_S2_VID_LINE "medium=\"video\"" -#define REDBALCONY_S2_ITEM_START " url=\"" -#define REDBALCONY_S2_ITEM_END "\"" - -if (strstr(Tempstr,REDBALCONY_S2_VID_LINE)) -{ - GenericExtractFromLine(Tempstr, "item:flv",REDBALCONY_S2_ITEM_START,REDBALCONY_S2_ITEM_END,Vars,EXTRACT_DEQUOTE | EXTRACT_NOSPACES ); -} - break; - case TYPE_IVIEWTUBE: //#define IVIEWTUBE_ITEM_START "('ltas.mediaid','" //#define IVIEWTUBE_ITEM_END "'" @@ -1153,17 +1126,11 @@ case TYPE_IVIEWTUBE: #define IVIEWTUBE_ITEM_START " 0) HandleMultipleMedia(Type,Server,Flags,Vars,MediaCount); else { - if (StrLen(GetVar(Vars,"ID"))==0) + if (! StrValid(GetVar(Vars,"ID"))) { Type=SelectDownloadFormat(Vars,Type,TRUE); } diff --git a/servicetypes.h b/servicetypes.h index 76d4638..d753978 100755 --- a/servicetypes.h +++ b/servicetypes.h @@ -4,9 +4,9 @@ #include "common.h" -typedef enum {TYPE_NONE, TYPE_GENERIC, TYPE_YOUTUBE, TYPE_YOUTUBE_SHORT, TYPE_METACAFE, TYPE_DAILYMOTION, TYPE_BREAK_COM, TYPE_EHOW, TYPE_VIMEO, TYPE_TED, TYPE_REDBALCONY, TYPE_YALE, TYPE_REUTERS, TYPE_LIVELEAK, TYPE_PHOTOBUCKET,TYPE_IVIEWTUBE,TYPE_WASHINGTONPOST,TYPE_CBSNEWS,TYPE_FRANCE24,TYPE_EURONEWS,TYPE_METATUBE,TYPE_GUARDIAN,TYPE_REDORBIT,TYPE_SCIVEE,TYPE_IZLESE, TYPE_UCTV, TYPE_ROYALSOCIETY, TYPE_BRITISHACADEMY, TYPE_KAVLIINSTITUTE,TYPE_DOTSUB,TYPE_ASTRONOMYCOM, TYPE_DISCOVERY, TYPE_BLOOMBERG,TYPE_NATGEO,TYPE_VIDEOBASH,TYPE_IBTIMES,TYPE_SMH,TYPE_ANIMEHERE,TYPE_FUNNYORDIE, +typedef enum {TYPE_NONE, TYPE_GENERIC, TYPE_YOUTUBE, TYPE_YOUTUBE_SHORT, TYPE_METACAFE, TYPE_DAILYMOTION, TYPE_BREAK_COM, TYPE_EHOW, TYPE_VIMEO, TYPE_TED, TYPE_YALE, TYPE_REUTERS, TYPE_LIVELEAK, TYPE_PHOTOBUCKET,TYPE_IVIEWTUBE,TYPE_WASHINGTONPOST,TYPE_CBSNEWS,TYPE_FRANCE24,TYPE_EURONEWS,TYPE_METATUBE,TYPE_GUARDIAN,TYPE_REDORBIT,TYPE_SCIVEE,TYPE_IZLESE, TYPE_UCTV, TYPE_ROYALSOCIETY, TYPE_BRITISHACADEMY, TYPE_KAVLIINSTITUTE,TYPE_DOTSUB,TYPE_ASTRONOMYCOM, TYPE_DISCOVERY, TYPE_BLOOMBERG,TYPE_NATGEO,TYPE_VIDEOBASH,TYPE_IBTIMES,TYPE_SMH,TYPE_ANIMEHERE,TYPE_FUNNYORDIE,TYPE_IGN,TYPE_EBAUMSWORLD, /*Following ones are not real types, but used by internal processes */ -TYPE_VIMEO_STAGE2, TYPE_VIMEO_STAGE3, TYPE_CLIPSHACK_STAGE2, TYPE_CLIPSHACK_STAGE3, TYPE_VIDEOEMO_STAGE2,TYPE_MYVIDO1_STAGE2, TYPE_REFERENCE, TYPE_WASHINGTONPOST_JSON, TYPE_WASHINGTONPOST_STAGE2, TYPE_REDORBIT_STAGE2, TYPE_REDBALCONY_STAGE2,TYPE_BRITISHACADEMY_STAGE2, TYPE_KAVLIINSTITUTE_STAGE2,TYPE_ASTRONOMYCOM_STAGE2,TYPE_CONTAINERFILE, TYPE_ANIMEHERE_STAGE2, TYPE_GOOGLE_URL, TYPE_YOUTUBE_PLAYLIST, TYPE_ROYALSOCIETY_STAGE2, TYPE_M3U8_STREAM, TYPE_CONTAINERFILE_M3U8, TYPE_CONTAINERFILE_PLS, TYPE_CONTAINERFILE_ASX} TDT; +TYPE_BREAK_STAGE2, TYPE_VIMEO_STAGE2, TYPE_VIMEO_STAGE3, TYPE_CLIPSHACK_STAGE2, TYPE_CLIPSHACK_STAGE3, TYPE_VIDEOEMO_STAGE2,TYPE_MYVIDO1_STAGE2, TYPE_REFERENCE, TYPE_WASHINGTONPOST_JSON, TYPE_WASHINGTONPOST_STAGE2, TYPE_REDORBIT_STAGE2, TYPE_REDBALCONY_STAGE2,TYPE_BRITISHACADEMY_STAGE2, TYPE_KAVLIINSTITUTE_STAGE2,TYPE_ASTRONOMYCOM_STAGE2,TYPE_CONTAINERFILE, TYPE_ANIMEHERE_STAGE2, TYPE_GOOGLE_URL, TYPE_YOUTUBE_PLAYLIST, TYPE_ROYALSOCIETY_STAGE2, TYPE_IGN_STAGE2, TYPE_M3U8_STREAM, TYPE_CONTAINERFILE_M3U8, TYPE_CONTAINERFILE_PLS, TYPE_CONTAINERFILE_ASX} TDT; extern char *DownloadTypes[], *DownloadNames[], *TestLinks[];