3
51
1dac369d-ebce-4ae0-8bdf-c73454fa7215
http://w3.zona.plus
234DF17B-418C-4FDC-9DFE-CD0C586D2E76
55
http://w3.zona.plus/apple-touch-icon.png
4
w3.zona.plus
515
1
700
0
701
-1
702
-1
517
578-720,722-1080,482-576,402-480,322-400,202-320,0-200
518
0
512
0
532
1
553
1
522
0
570
1
245
1dac369d-ebce-4ae0-8bdf-c73454fa7215
93
42422,8742304398
571
char gsUrlBase="http://w3.zona.plus"; int gnTotalItems=0; TDateTime gTimeStart=Now;
/////////////////////// Создание структуры подкаста /////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Функция создания динамической папки с указанным скриптом
THmsScriptMediaItem CreateDynamicItem(THmsScriptMediaItem prntItem, char sTitle, char sLink, char &sScript='') {
THmsScriptMediaItem Folder = prntItem.AddFolder(sLink, false, 32);
Folder[mpiTitle ] = sTitle;
Folder[mpiCreateDate] = VarToStr(IncTime(Now,0,-prntItem.ChildCount,0,0));
Folder[200] = 5; // mpiFolderType
Folder[500] = sScript; // mpiDynamicScript
Folder[501] = 'C++Script'; // mpiDynamicSyntaxType
Folder[mpiFolderSortOrder] = -mpiCreateDate;
return Folder;
}
///////////////////////////////////////////////////////////////////////////////
// Замена в тексте загруженного скрипта значения текстовой переменной
void ReplaceVarValue(char &sText, char sVarName, char sNewVal) {
char sVal, sVal2;
if (HmsRegExMatch2("("+sVarName+"\\s*?=.*?';)", sText, sVal, sVal2)) {
HmsRegExMatch(sVarName+"\\s*?=\\s*?'(.*)'", sVal, sVal2);
sText = ReplaceStr(sText, sVal, ReplaceStr(sVal , sVal2, sNewVal));
}
}
///////////////////////////////////////////////////////////////////////////////
// Создание папки ПОИСК (с загрузкой скрипта с форума homemediaserver.ru)
void CreateSearchFolder(THmsScriptMediaItem prntItem, char sTitle) {
char sScript='', sLink, sHtml, sRE, sVal; THmsScriptMediaItem Folder;
// Да да, загружаем скрипт с сайта форума HMS
sHtml = HmsUtf8Decode(HmsDownloadURL('http://homemediaserver.ru/forum/viewtopic.php?f=15&t=2793&p=17395#p17395', '', true));
HmsRegExMatch('BeginDynamicSearchScript\\*/(.*?)/\\*EndDynamicSearchScript', sHtml, sScript, 1, PCRE_SINGLELINE);
sScript = HmsHtmlToText(sScript, 1251);
sScript = ReplaceStr(sScript, #160, ' ');
// И меняем значения переменных на свои
//ReplaceVarValue(sScript, 'gsSuggestQuery' , 'http://bobfilm1.net/engine/ajax/search.php?query=');
//ReplaceVarValue(sScript, 'gsSuggestRegExpr', '<span class="searchheading">(.*?)</span>');
//ReplaceVarValue(sScript, 'gsSuggestMethod' , 'POST');
//sScript = ReplaceStr(sScript, 'gnSuggestNoUTFEnc = 0', 'gnSuggestNoUTFEnc = 1');
Folder = prntItem.AddFolder(sTitle, true);
Folder[mpiCreateDate ] = VarToStr(IncTime(gTimeStart,0,-gnTotalItems,0,0));
Folder[mpiFolderSortOrder] = "-mpCreateDate";
gnTotalItems++;
CreateDynamicItem(Folder, '"Набрать текст"', '-SearchCommands', sScript);
}
///////////////////////////////////////////////////////////////////////////////
// Создание подкаста или папки
THmsScriptMediaItem CreateItem(THmsScriptMediaItem Parent, char sTitle='', char sLink='') {
THmsScriptMediaItem Item; bool bForceFolder = false;
if (sLink=='') { sLink = sTitle; bForceFolder = true; }
else sLink = HmsExpandLink(sLink, gsUrlBase);
Item = Parent.AddFolder(sLink, bForceFolder);
Item[mpiTitle ] = sTitle;
Item[mpiCreateDate] = VarToStr(IncTime(gTimeStart,0,-gnTotalItems,0,0));
Item[mpiFolderSortOrder] = -mpiCreateDate;
gnTotalItems++;
return Item;
}
///////////////////////////////////////////////////////////////////////////////
// Поиск и создание ссылок категории
void SearchCategories(THmsScriptMediaItem Folder, string sHtml, string sCutPattern) {
string sName, sLink; TRegExpr RegExp;
HmsRegExMatch(sCutPattern, sHtml, sHtml); // Вырезаем нужный блок
// Ищем ссылки на категории и создаём их
RegExp = TRegExpr.Create('(<a.*?</a>)', PCRE_SINGLELINE);
try {
if (RegExp.Search(sHtml)) do {
sName = ""; sLink = "";
HmsRegExMatch('<a[^>]+href="(.*?)"', RegExp.Match, sLink);
HmsRegExMatch('(<a.*?</a>)' , RegExp.Match, sName);
sLink = HmsExpandLink(sLink, gsUrlBase);
sName = HmsHtmlToText(sName);
CreateItem(Folder, sName, sLink);
} while (RegExp.SearchAgain);
} finally { RegExp.Free; }
}
///////////////////////////////////////////////////////////////////////////////
// --------------------- M A I N P R O C E D U R E -------------------------
{
THmsScriptMediaItem Folder, Item; string sHtml, sName, sLink; TRegExpr RegExp;
FolderItem.DeleteChildItems();
CreateSearchFolder (FolderItem, '00. Поиск');
Folder = CreateItem(FolderItem, '01. Последние поступления', '/updates/movies');
Folder[mpiPodcastParameters] = '--maxpages=2';
Folder = CreateItem(FolderItem, '02. Популярные фильмы', '/movies');
Folder[mpiPodcastParameters] = '--maxpages=7';
Folder = CreateItem(FolderItem, '03. Сериалы', '/tvseries');
Folder[mpiPodcastParameters] = '--group=alph --maxpages=30';
// Загружаем страницу главную страницу
sHtml = HmsDownloadURL(gsUrlBase, '', true);
sHtml = HmsRemoveLineBreaks(HmsUtf8Decode(sHtml));
Folder = CreateItem(FolderItem, '04. Категории');
SearchCategories(Folder, sHtml, 'Фильмы по жанрам(.*?)</ul>');
Folder = CreateItem(FolderItem, '05. По странам');
SearchCategories(Folder, sHtml, 'Фильмы по странам(.*?)</ul>');
Folder = CreateItem(FolderItem, '06. Фильмы 2016 года', '/movies/filter/year-2016/sort-date');
Folder[mpiPodcastParameters] = '';
Folder = CreateItem(FolderItem, '07. Фильмы 2015 года', '/movies/filter/year-2015/sort-date');
Folder[mpiPodcastParameters] = '';
HmsLogMessage(1, mpTitle+': Создано ссылок - '+IntToStr(gnTotalItems));
}
572
C++Script
530
string gsUrlBase = 'http://w3.zona.plus'; // База для относительных ссылок
int gnTotalItems = 0; // Счётчик созданных элементов
TDateTime gStart = Now; // Время начала запуска скрипта
int gnMaxPages=10, gnMaxInGroup=120; bool gbYearInTitle=false; char gsGroupMode='';
string
gsHeaders = gsUrlBase+'\r\n'+
'Origin: '+gsUrlBase+'\r\n'+
'X-Requested-With: XMLHttpRequest\r\n'+
'User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36\r\n'+
'Accept: application/json, text/javascript, */*; q=0.01\r\n'+
'Accept-Encoding: gzip, deflate\r\n';
///////////////////////////////////////////////////////////////////////////////
// Создание папки или подкаста
THmsScriptMediaItem CreateFolder(THmsScriptMediaItem ParentFolder, string sName, string sLink, string sImg='') {
THmsScriptMediaItem Item = ParentFolder.AddFolder(sLink); // Создаём папку с указанной ссылкой
Item[mpiTitle ] = sName; // Присваиваем наименование
Item[mpiThumbnail ] = sImg; // Картинка
Item[mpiCreateDate] = DateTimeToStr(IncTime(gStart, 0, -gnTotalItems, 0, 0)); // Для обратной сортировки по дате создания
gnTotalItems++; // Увеличиваем счетчик созданных элементов
return Item; // Возвращаем созданный объект
}
///////////////////////////////////////////////////////////////////////////////
// Получение имени группировки по имени видео (первая буква, "A..Z" или "#")
string GetGroupName(string sName) {
string sGrp = '#';
if (HmsRegExMatch('([A-ZА-Я0-9])', sName, sGrp, 1, PCRE_CASELESS)) sGrp = UpperCase(sGrp);
if (HmsRegExMatch('[A-Z]', sGrp, sGrp)) sGrp = 'A..Z';
if (HmsRegExMatch('[0-9]', sGrp, sGrp)) sGrp = '#';
return sGrp;
}
///////////////////////////////////////////////////////////////////////////////
// Загрузка страниц и парсинг
void LoadAndParse() {
string sHtml, sData, sName, sLink, sImg, sYear, sPage, sVal, sID, sPost, sServ; // Объявляем переменные
THmsScriptMediaItem Item, Folder = FolderItem;
int i, n, nPages=0, iCnt=0, nGrp=0, nCount; char sGrp=""; bool bGroup=false;
TJsonObject JSON, MOVIE; TJsonArray ITEMS;
if (HmsRegExMatch('--maxingroup=(\\d+)', mpPodcastParameters, sVal)) gnMaxInGroup = StrToInt(sVal);
if (HmsRegExMatch('--maxpages=(\\d+)' , mpPodcastParameters, sVal)) gnMaxPages = StrToInt(sVal);
HmsRegExMatch('--group=(\\w+)', mpPodcastParameters, gsGroupMode);
gbYearInTitle = (Pos('--yearintitle', mpPodcastParameters)>0);
if (LeftCopy(mpFilePath, 4) != "http") {
// Если нет ссылки - делаем поиск названия
if (Length(mpTitle)<4) mpTitle += " :::"; // Фишка обхода ограничения на минимальную длину в 4 символа (двоеточие при самом поиске не учитывается)
mpFilePath = gsUrlBase+'/search/'+HmsUtf8Encode(mpTitle);
}
sData = HmsDownloadURL(mpFilePath, gsHeaders, true);
if (HmsRegExMatch('"total_pages":(\\d+)', sData, sVal)) nPages = StrToInt(sVal);
if ((gnMaxPages!=0) && (nPages>gnMaxPages)) nPages = gnMaxPages;
i = 60; if (HmsRegExMatch('"limit":(\\d+)', sData, sVal)) i = StrToInt(sVal);
nCount = i * nPages;
bGroup = (nCount > gnMaxInGroup);
JSON = TJsonObject.Create();
try {
// =========================================================================
// Цикл постаничной загрузки страниц
for (n=1; n<=nPages; n++) {
HmsSetProgress(Trunc(n*100/nPages));
HmsShowProgress(Format('%s: Загрузка страницы %d из %d', [mpTitle, n, nPages]));
if (n>1) sData = HmsDownloadURL(mpFilePath+'?page='+IntToStr(n), gsHeaders, true);
if (HmsCancelPressed) break;
JSON.LoadFromString(sData);
ITEMS = JSON.A['items'];
for (i=0; i<ITEMS.Length; i++) {
MOVIE = ITEMS[i];
sName = MOVIE.S['name_rus'];
sID = MOVIE.S['name_id' ];
sImg = MOVIE.S['cover' ];
sYear = MOVIE.S['year' ];
if (MOVIE.B['serial'])
sLink = gsUrlBase + '/tvseries/' + sID;
else
sLink = gsUrlBase + '/movies/' + sID;
sName = HmsUtf8Decode(sName);
// Если указано добавлять год вназвание и в названии его нет, добавляем
if (gbYearInTitle && (sYear!='') && (Pos(sYear, sName)<1)) sName += ' ('+sYear+')';
// Контроль группировки (создаём папку с именем группы)
if (gsGroupMode=='alph') {
Folder = FolderItem.AddFolder(GetGroupName(sName));
Folder[mpiFolderSortOrder] = "mpTitle";
} else if (gsGroupMode=='year') {
Folder = FolderItem.AddFolder(sYear);
Folder[mpiFolderSortOrder] = "mpTitle";
Folder[mpiYear ] = sYear;
} else if (bGroup) {
iCnt++; if (iCnt>=gnMaxInGroup) { nGrp++; iCnt=0; }
Folder = FolderItem.AddFolder(Format('%.2d', [nGrp]));
}
CreateFolder(Folder, sName, sLink, sImg); // Создание ссылки (папки с фильмом)
}
}
// =========================================================================
} finally { JSON.Free; HmsHideProgress(); }
if (gsGroupMode=='alph') FolderItem.Sort('mpTitle');
else if (gsGroupMode=='year') FolderItem.Sort('-mpYear');
HmsLogMessage(1, mpTitle+': создано элементов - '+IntToStr(gnTotalItems));
}
///////////////////////////////////////////////////////////////////////////////
// Г Л А В Н А Я П Р О Ц Е Д У Р А //
{
if (InteractiveMode && (HmsCurrentMediaTreeItem.ItemClassName=='TVideoPodcastsFolderItem')) {
if (gsUserVariable1== '-nomsg-') return;
HmsLogMessage(1, "Завязывайте таким образом обновлять подкасты! Вы делаете кучу ненужных запросов на сайты.");
HmsLogMessage(2, "Обновлять подкаст можно только в конкретной категории.");
ShowMessage("Таким образом подкаст обновлять запрещено!\nОбновите конекретную категорию.");
gsUserVariable1 = '-nomsg-';
return;
}
gsUserVariable1 = '';
FolderItem.DeleteChildItems(); // Удаляем созданные ранее элементы в текущей папке
LoadAndParse(); // Запускаем загрузку страниц и создание папок видео
}
531
C++Script
527
--yearintitle --addinfoitems
550
string gsUrlBase = "http://w3.zona.plus"; // База для относительных ссылок
int gnTotalItems = 0; // Счётчик созданных элементов
TDateTime gStart = Now; // Время начала запуска скрипта
string gsTime = "01:40:00.000"; // Продолжительность видео
int mpiCountry = 10012; // Идентификаторы для хранения дополнительной
int mpiTranslate = 10013; // информации в свойствах подкаста
int mpiQuality = 10014;
int mpiRatingIMDb = 10015;
int mpiRatingKP = 10016;
int mpiTrailer = 10017;
int mpiVideoMessage = 1001001;
string gsPodcastName = "w3.zona.plus";
string gsPreviewPrefix = 'zona'; // Префикс кеша информационных картинок на сервере wonky.lostcut.net
string
gsHeaders = gsUrlBase+'\r\n'+
'Origin: '+gsUrlBase+'\r\n'+
'X-Requested-With: XMLHttpRequest\r\n'+
'User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36\r\n'+
'Accept: application/json, text/javascript, */*; q=0.01\r\n'+
'Accept-Encoding: gzip, deflate\r\n';
///////////////////////////////////////////////////////////////////////////////
// Создание информационной ссылки
void CreateInfoItem(string sName, string sVal) {
THmsScriptMediaItem Item; sVal = Trim(sVal);
if (sVal=="") return;
Item = HmsCreateMediaItem('Info'+IntToStr(PodcastItem.ChildCount), PodcastItem.ItemID);
Item[mpiTitle ] = sName+': '+sVal;
Item[mpiThumbnail ] = 'http://wonky.lostcut.net/vids/info.jpg';
Item[mpiTimeLength] = 9;
Item[mpiCreateDate] = VarToStr(IncTime(gStart,0,-gnTotalItems,0,0));
gnTotalItems++;
}
///////////////////////////////////////////////////////////////////////////////
// Создание ссылки-ошибки
void CreateErrorItem(string sMsg) {
THmsScriptMediaItem Item = HmsCreateMediaItem('http://wonky.lostcut.net/vids/podcasterror_hd.mp4', PodcastItem.ItemID);
Item[mpiTitle ] = sMsg;
Item[mpiThumbnail ] = 'http://wonky.lostcut.net/icons/symbol-error.png';
}
///////////////////////////////////////////////////////////////////////////////
// Создание ссылки на видео
THmsScriptMediaItem CreateMediaItem(THmsScriptMediaItem Folder, string sTitle, string sLink='', string sGrp='') {
THmsScriptMediaItem Item = HmsCreateMediaItem(sLink, Folder.ItemID, sGrp);
Item[mpiTitle ] = sTitle;
Item[mpiCreateDate] = VarToStr(IncTime(gStart,0,-gnTotalItems,0,0));
Item[mpiTimeLength] = gsTime;
Item.CopyProperties(PodcastItem, [mpiThumbnail,mpiYear,mpiActor,mpiDirector,mpiProducer,mpiGenre]);
gnTotalItems++;
return Item;
}
///////////////////////////////////////////////////////////////////////////////
// Создание папки подкаста
THmsScriptMediaItem CreateFolder(THmsScriptMediaItem ParentFolder, string sName, string sLink, string sImg='') {
if (sImg=='') sImg = mpThumbnail;
THmsScriptMediaItem Item = ParentFolder.AddFolder(sLink); // Создаём папку с указанной ссылкой
Item[mpiTitle ] = sName; // Присваиваем наименование
Item[mpiThumbnail ] = sImg; // Картинка
Item[mpiCreateDate] = DateTimeToStr(IncTime(gStart, 0, -gnTotalItems, 0, 0)); // Для обратной сортировки по дате создания
gnTotalItems++; // Увеличиваем счетчик созданных элементов
return Item; // Возвращаем созданный объект
}
///////////////////////////////////////////////////////////////////////////////
// Вывод видео сообщения с заданным текстом
void ShowVideoMessage(string sMsg, string sTitle='', int nErr=0, string sDescr='') {
if (nErr==1) sMsg = '<c:#e22>'+Trim(sMsg);
TStrings INFO = TStringList.Create();
INFO.Values['Title' ] = sTitle;
INFO.Values['Info' ] = sMsg;
INFO.Values['Descr' ] = sDescr;
PodcastItem[mpiVideoMessage] = INFO.Text;
INFO.Free();
VideoPreview();
}
///////////////////////////////////////////////////////////////////////////////
// Формирование видео с картинкой с информацией о фильме
bool VideoPreview() {
string sVal, sFileImage, sPoster, sTitle, sDescr, sCateg, sInfo, sLink, sData;
int xMargin=7, yMargin=10, nSeconds=10, n; string sCacheDir;
float nH=cfgTranscodingScreenHeight, nW=cfgTranscodingScreenWidth;
// Проверяем и, если указаны в параметрах подкаста, выставляем значения смещения от краёв
if (HmsRegExMatch('--xmargin=(\\d+)', mpPodcastParameters, sVal)) xMargin=StrToInt(sVal);
if (HmsRegExMatch('--ymargin=(\\d+)', mpPodcastParameters, sVal)) yMargin=StrToInt(sVal);
sCacheDir = IncludeTrailingBackslash(HmsTempDirectory);
if (Trim(PodcastItem[mpiVideoMessage])=='') return; // Если нет инфы - выходим быстро!
TStrings INFO = TStringList.Create(); // Создаём объект TStrings
INFO.Text = PodcastItem[1001001]; // И загружаем туда информацию
sPoster = INFO.Values['Poster']; // Постер
sTitle = INFO.Values['Title' ]; // Самая верхняя надпись - Название
sCateg = INFO.Values['Genre' ]; // Жанр
sInfo = INFO.Values['Info' ]; // Блок информации
sDescr = INFO.Values['Descr' ]; // Описание
if (sTitle=='') sTitle = ' ';
ForceDirectories(sCacheDir);
sFileImage = ExtractShortPathName(sCacheDir)+'videopreview_'; // Файл-заготовка для сохранения картинки
sDescr = Copy(sDescr, 1, 3000); // Если блок описания получился слишком большой - обрезаем
INFO.Text = ""; // Очищаем объект TStrings для формирования параметров запроса
INFO.Values['prfx' ] = gsPreviewPrefix; // Префикс кеша сформированных картинок на сервере
INFO.Values['title'] = sTitle; // Блок - Название
INFO.Values['info' ] = sInfo; // Блок - Информация
INFO.Values['categ'] = sCateg; // Блок - Жанр/категории
INFO.Values['descr'] = sDescr; // Блок - Описание фильма
INFO.Values['mlinfo'] = '20'; // Максимальное число срок блока Info
INFO.Values['w' ] = IntToStr(Round(nW)); // Ширина кадра
INFO.Values['h' ] = IntToStr(Round(nH)); // Высота кадра
INFO.Values['xm'] = IntToStr(xMargin); // Отступ от краёв слева/справа
INFO.Values['ym'] = IntToStr(yMargin); // Отступ от краёв сверху/снизу
INFO.Values['bg'] = 'http://www.pageresource.com/wallpapers/wallpaper/noir-blue-dark_3512158.jpg'; // Катринка фона (кэшируется на сервере)
INFO.Values['fx'] = '3'; // Номер эффекта для фона: 0-нет, 1-Blur, 2-more Blur, 3-motion Blur, 4-radial Blur
INFO.Values['fztitle'] = IntToStr(Round(nH/14)); // Размер шрифта блока названия (тут относительно высоты кадра)
INFO.Values['fzinfo' ] = IntToStr(Round(nH/22)); // Размер шрифта блока информации
INFO.Values['fzcateg'] = IntToStr(Round(nH/26)); // Размер шрифта блока жанра/категории
INFO.Values['fzdescr'] = IntToStr(Round(nH/18)); // Размер шрифта блока описания
// Если текста описания больше чем нужно - немного уменьшаем шрифт блока
if (Length(sDescr)>890) INFO.Values['fzdescr'] = IntToStr(Round(nH/20));
// Если есть постер, задаём его параметры отображения (где, каким размером)
if (sPoster!='') {
INFO.Values['wpic' ] = IntToStr(Round(nW/4)); // Ширина постера (1/4 ширины кадра)
INFO.Values['xpic' ] = '10'; // x-координата постера
INFO.Values['ypic' ] = '10'; // y-координата постера
if (mpFilePath=='InfoUpdate') {
INFO.Values['wpic' ] = IntToStr(Round(nW/6)); // Ширина постера (1/6 ширины кадра)
INFO.Values['xpic' ] = IntToStr(Round(nW/2 - nW/12)); // центрируем
}
INFO.Values['urlpic'] = sPoster; // Адрес изображения постера
}
sData = ''; // Из установленных параметров формируем строку POST запроса
for (n=0; n<INFO.Count; n++) sData += '&'+Trim(INFO.Names[n])+'='+HmsHttpEncode(INFO.Values[INFO.Names[n]]);
INFO.Free(); // Освобождаем объект из памяти, теперь он нам не нужен
// Делаем POST запрос не сервер формирования картинки с информацией
sLink = HmsSendRequestEx('wonky.lostcut.net', '/videopreview.php?p='+gsPreviewPrefix, 'POST',
'application/x-www-form-urlencoded', '', sData, 80, 0, '', true);
// В ответе должна быть ссылка на сформированную картинку
if (LeftCopy(sLink, 4)!='http') {HmsLogMessage(2, 'Ошибка получения файла информации videopreview.'); return;}
// Сохраняем сформированную картинку с информацией в файл на диске
HmsDownloadURLToFile(sLink, sFileImage);
// Копируем и нумеруем файл картики столько раз, сколько секунд мы будем её показывать
for (n=1; n<=nSeconds; n++) CopyFile(sFileImage, sFileImage+Format('%.3d.jpg', [n]), false);
// Для некоторых телевизоров (Samsung) видео без звука отказывается проигрывать, поэтому скачиваем звук тишины
char sFileMP3 = ExtractShortPathName(HmsTempDirectory)+'\\silent.mp3';
try {
if (!FileExists(sFileMP3)) HmsDownloadURLToFile('http://wonky.lostcut.net/mp3/silent.mp3', sFileMP3);
sFileMP3 = '-i "'+sFileMP3+'"';
} except { sFileMP3=''; }
// Формируем из файлов пронумерованных картинок и звукового команду для формирования видео
MediaResourceLink = Format('%s -f image2 -r 1 -i "%s" -c:v libx264 -pix_fmt yuv420p ', [sFileMP3, sFileImage+'%03d.jpg']);
}
///////////////////////////////////////////////////////////////////////////////
// Вывод вместо видео заданного сообщения
bool VideoMessage(char sCaption, char sMessage, int nTime=30) {
char sFileImage = HmsTempDirectory+'\\videomessage.jpg'; char sCmd;
sCaption = HmsHttpEncode(ReplaceStr(sCaption, '\n', '|'));
sMessage = HmsHttpEncode(ReplaceStr(sMessage, '\n', '|'));
HmsDownloadURLToFile('http://wonky.lostcut.net/videomessage.php?testpic=1&caption='+sCaption+'&msg='+sMessage, sFileImage);
char sFileMP3 = HmsTempDirectory+'\\silent.mp3';
try {
if (!FileExists(sFileMP3)) HmsDownloadURLToFile('http://wonky.lostcut.net/mp3/silent.mp3', sFileMP3);
sFileMP3 = '-i "'+sFileMP3+'"';
} except {
sFileMP3 = '';
}
sCmd = Format('%s -loop 1 -f image2 -i "%s" -t %d -r 25 ', [ExtractShortPathName(sFileMP3), ExtractShortPathName(sFileImage), 7]);
MediaResourceLink = sCmd;
}
///////////////////////////////////////////////////////////////////////////////
// Вывод видео сообщения с информацией о фильме
void ShowVideoInfo() {
string sInfo; THmsScriptMediaItem Parent = PodcastItem.ItemParent;
sInfo = '';
if (Trim(Parent[mpiYear ])!='') sInfo += '<c:#FFC3BD>Год: </c>' +Parent[mpiYear ]+' ';
if (Trim(Parent[mpiCountry ])!='') sInfo += '<c:#FFC3BD>Страна: </c>' +Parent[mpiCountry ]+"|";
if (Trim(Parent[mpiTranslate ])!='') sInfo += '<c:#FFC3BD>Перевод: </c>' +Parent[mpiTranslate]+"|";
if (Trim(Parent[mpiQuality ])!='') sInfo += '<c:#FFC3BD>Качество: </c>'+Parent[mpiQuality ]+"|";
if (Trim(Parent[mpiDirector ])!='') sInfo += '<c:#FFC3BD>Режиссер: </c>'+Parent[mpiDirector ]+"|";
if (Trim(Parent[mpiProducer ])!='') sInfo += '<c:#FFC3BD>Продюсер: </c>'+Parent[mpiProducer ]+"|";
if (Trim(Parent[mpiAuthor ])!='') sInfo += '<c:#FFC3BD>Сценарий: </c>'+Parent[mpiAuthor ]+"|";
if (Trim(Parent[mpiActor ])!='') sInfo += '<c:#FFC3BD>В ролях: </c>' +Parent[mpiActor ]+"</c>|";
if (Trim(Parent[mpiRatingIMDb])!='') sInfo += '<c:#FFC3BD>Рейтинг IMDb: </c>' +Parent[mpiRatingIMDb]+"|";
if (Trim(Parent[mpiRatingKP ])!='') sInfo += '<c:#FFC3BD>Рейтинг Кинопоиск: </c>'+Parent[mpiRatingKP ]+"|";
sInfo = Copy(sInfo, 1, Length(sInfo)-1); // Обрезаем последний символ "|"
TStrings INFO = TStringList.Create();
INFO.Values['Poster'] = Parent[mpiThumbnail];
INFO.Values['Title' ] = Parent[mpiTitle];
INFO.Values['Genre' ] = Parent[mpiGenre];
INFO.Values['Info' ] = sInfo;
INFO.Values['Descr' ] = ReplaceStr(Parent[mpiComment], "\n", "|");
PodcastItem[mpiVideoMessage] = INFO.Text;
INFO.Free();
VideoPreview();
}
///////////////////////////////////////////////////////////////////////////////
/// Создание ссылок на файл(ы) по переданной ссылке (шаблону) -------------
void CreateVideoLink(THmsScriptMediaItem Folder, string sName, string sLink, bool bSeparateInFolders=false) {
string sCut, sQualArray, sQual, sFile; int i, nCount; // Объявляем переменные
// Проверяем, есть ли в переданной ссылке шаблон с массивом существующего качества "[720,480,360]"
if (HmsRegExMatch('\\[(.*?)\\]', sLink, sQualArray)) {
sCut = '['+sQualArray+']'; // Та часть, которая будет заменятся на индификатор качества
nCount = WordCount (sQualArray, ','); // Количество елементов, разделённых запятой
for (i=1; i<=nCount; i++) {
sQual = ExtractWord(i, sQualArray, ','); // Получаем очередной индификатор качества
if (sQual=='') continue; // Может быть пропущен, если не указан
sFile = ReplaceStr(sLink, sCut, sQual); // Формируем ссылку на файл, заменяя шаблон на индификатор качества
if (bSeparateInFolders) { // Если был передан флаг "Группировать файлы качества по разным папкам",
CreateMediaItem(Folder, sName, sFile, sQual); // то передаём индификатор качества как имя группы, где будет создана ссылка
} else {
if (sName=='') HmsRegExMatch('.*/(.*)', sLink, sName); // Получаем имя файла из ссылки (всё что идёт после последнего слеша)
sName = ReplaceStr(sName, sCut, ''); // Убираем перечисление качества из имени
sName = ReplaceStr(sName, '_', ''); // А также подчекривания (лишние)
CreateMediaItem(Folder, sQual+' '+sName, sFile); // Добавляем индификатор качества к началу имени и создаём ссылку
}
}
} else {
// Если шаблона выбора качества в ссылке нет, то просто создаём ссылку
if (sName=='') HmsRegExMatch('.*/(.*)', sLink, sName); // Если имя пустое, получаем имя файла из ссылки (всё что идёт после последнего слеша)
CreateMediaItem(Folder, sName, sLink);
}
}
///////////////////////////////////////////////////////////////////////////////
// Создание серий из плейлиста
void CreateSeriesFromPlaylist(THmsScriptMediaItem Folder, string sLink, string sName='') {
string sData, s1, s2, s3; int i; TJsonObject JSON, PLITEM; TJsonArray PLAYLIST; // Объявляем переменные
// Если передано имя плейлиста, то создаём папку, в которой будем создавать элементы
if (Trim(sName)!='') Folder = Folder.AddFolder(sName);
// Если в переменной sLink сожержится знак '{', то там не ссылка, а сами данные Json
if (Pos('{', sLink)>0) {
sData = sLink;
} else {
sData = HmsDownloadURL(sLink, "Referer: "+mpFilePath, true); // Загружаем плейлист
sData = HmsUtf8Decode(sData);
//sData = DecodeUppodTextHash(sData); // Дешифруем
}
JSON = TJsonObject.Create(); // Создаём объект для работы с Json
try {
JSON.LoadFromString(sData); // Загружаем json данные в объект
PLAYLIST = JSON.A['playlist']; // Пытаемся получить array с именем 'playlist'
if (PLAYLIST==nil) PLAYLIST = JSON.AsArray; // Если массив 'playlist' получить не получилось, то представляем все наши данные как массив
if (PLAYLIST!=nil) { // Если получили массив, то запускаем обход всех элементов в цикле
for (i=0; i<PLAYLIST.Length; i++) {
PLITEM = PLAYLIST[i]; // Получаем текущий элемент массива
sName = PLITEM.S['comment']; // Название - значение поля comment
sLink = PLITEM.S['file' ]; // Получаем значение ссылки на файл
sName = ReplaceStr(ReplaceStr(HmsHtmlToText(sName), "\n", ' '), "\r", '');
// Форматируем числовое представление серий в названии
// Если в названии есть число, то будет в s1 - то, что стояло перед ним, s2 - само число, s3 - то, что было после числа
if (HmsRegExMatch3('^(.*?)(\\d+)(.*)$', sName, s1, s2, s3))
sName = Trim(Format('%s %.2d %s', [s1, StrToInt(s2), s3])); // Форматируем имя - делаем число двухцифровое (01, 02...)
if (LeftCopy(sLink, 4)=='oid=') sLink = 'http://vk.com/video_ext.php?'+Trim(sLink);
// Проверяем, если это вложенный плейлист - запускаем создание элементов из этого плейлиста рекурсивно
if (PLITEM.B['playlist'])
CreateSeriesFromPlaylist(Folder, PLITEM.S['playlist'], sName);
else
CreateVideoLink(Folder, sName, sLink, true); // Иначе просто создаём ссылки на видео
}
} // end if (PLAYLIST!=nil)
} finally { JSON.Free; } // Какие бы ошибки не случились, освобождаем объект из памяти
}
///////////////////////////////////////////////////////////////////////////////
// Конвертация продолжительности из формата youtube (ISO8601) в формат HMS
string ConvertYoutubeTime(string sTime) {
string sVal; int nSeconds = 0;
if (HmsRegExMatch('(\\d+)H', sTime, sVal)) nSeconds += StrToInt(sVal)*3600;
if (HmsRegExMatch('(\\d+)M', sTime, sVal)) nSeconds += StrToInt(sVal)*60;
if (HmsRegExMatch('(\\d+)S', sTime, sVal)) nSeconds += StrToInt(sVal);
if (nSeconds==0) nSeconds = 600;
return HmsTimeFormat(nSeconds)+'.000';
}
///////////////////////////////////////////////////////////////////////////////
string GetNamesFromJsonArray(TJsonArray ITEMS) {
string sNames = '', sName;
if (ITEMS != nil) {
for (int i=0; i<ITEMS.Length; i++) {
if (sNames!='') sNames += ', ';
sName = HmsUtf8Decode(ITEMS[i].S['name']);
if (Length(sName)>0) sName[1] = Uppercase(sName[1]);
sNames += sName;
}
}
return sNames;
}
///////////////////////////////////////////////////////////////////////////////
// Создание ссылок видео
void CreateLinks() {
string sHtml, sData, sLink, sName, sTime, sImg, sVal, sID; int i, nCount, e;
THmsScriptMediaItem Item; TJsonObject JSON, INFO, MOVIE, PERSONS; TJsonArray EPISODES;
bool bLowQuality = (Pos('--lowq' , mpPodcastParameters)>0);
bool bIsSerial = (Pos('tvseries', mpFilePath )>0);
bool bSeason = (Pos('/season-', mpFilePath )>0);
sData = HmsDownloadURL(mpFilePath, gsHeaders, true);
JSON = TJsonObject.Create();
INFO = TJsonObject.Create();
try {
JSON.LoadFromString(sData);
if (bIsSerial)
MOVIE = JSON['serial'];
else
MOVIE = JSON['movie'];
if (MOVIE.B['abuse']) { CreateErrorItem('Видео заблокировано по просьбе правообладателя'); return; }
// =========================================================================
// Сбор информации о фильме
PodcastItem[mpiYear ] = MOVIE.S['year'];
PodcastItem[mpiComment ] = HmsUtf8Decode(MOVIE.S['description']);
PodcastItem[mpiGenre ] = GetNamesFromJsonArray(JSON.A['genres' ]);
PodcastItem[mpiCountry ] = GetNamesFromJsonArray(JSON.A['countries']);
PodcastItem[mpiTrailer ] = MOVIE.S['trailer_url'];
PERSONS = JSON['persons'];
if (PERSONS != nil) {
PodcastItem[mpiDirector] = GetNamesFromJsonArray(PERSONS.A['director' ]);
PodcastItem[mpiProducer] = GetNamesFromJsonArray(PERSONS.A['producer' ]);
PodcastItem[mpiActor ] = GetNamesFromJsonArray(PERSONS.A['actors' ]);
PodcastItem[mpiAuthor ] = GetNamesFromJsonArray(PERSONS.A['scenarist']);
}
if (Trim(MOVIE.S['rating_imdb_count'])!='')
PodcastItem[mpiRatingIMDb] = MOVIE.S['rating_imdb'] + ' ('+MOVIE.S['rating_imdb_count']+')';
if (Trim(MOVIE.S['rating_kinopoisk_count'])!='')
PodcastItem[mpiRatingKP ] = MOVIE.S['rating_kinopoisk'] + ' ('+MOVIE.S['rating_kinopoisk_count']+')';
if (LeftCopy(PodcastItem[mpiTrailer], 4)!='http') PodcastItem[mpiTrailer] = '';
// =========================================================================
sID = MOVIE.S['mobi_link_id'];
sData = HmsDownloadURL(gsUrlBase+'/ajax/video/'+sID, gsHeaders, true);
INFO.LoadFromString(sData);
if (HmsRegExMatch('(\\d+:\\d+:\\d+)', INFO.S['info'], sVal)) gsTime = sVal +'.000';
if (bIsSerial) {
if (bSeason) {
for (e=1; e <= JSON['episodes\\items'].Count; e++) {
INFO = JSON['episodes\\items\\'+IntToStr(e)];
sName = Trim(HmsUtf8Decode(INFO.S['title']));
if (sName=='') sName = 'серия';
sID = INFO.S['mobi_link_id'];
sName = Format('%.2d %s', [e, sName]);
sLink = gsUrlBase+'/ajax/video/'+sID;
sImg = JSON.S['images\\'+sID];
Item = CreateMediaItem(PodcastItem, sName, sLink);
Item[mpiThumbnail] = sImg;
}
return;
} else {
nCount = JSON.I['seasons\\count'];
for (i=0; i<nCount; i++) {
sLink = mpFilePath+'/season-'+IntToStr(i+1)+'?_='+VarToStr(Random);
sName = Format('%.2d cезон', [i+1]);
CreateFolder(PodcastItem, sName, sLink);
}
}
} else {
sLink = INFO.S['url'];
sName = HmsUtf8Decode(INFO.S['title']);
if (bLowQuality && (Trim(INFO.S['lqUrl'])!='')) sLink = INFO.S['lqUrl'];
CreateMediaItem(PodcastItem, sName, sLink);
}
} finally { JSON.Free; INFO.Free; }
// Если на странице есть ссылка на трейлер - создаём такую ссылку
if (Trim(PodcastItem[mpiTrailer])!='') {
Item = CreateMediaItem(PodcastItem, 'Трейлер', PodcastItem[mpiTrailer]);
Item[mpiTimeLength] = '00:03:40.000';
}
// Если установлен ключ отображения информационных ссылок - добавляем их
if (Pos('--addinfoitems', mpPodcastParameters)>0) {
if (Trim(PodcastItem[mpiGenre ])!='') CreateInfoItem('Жанр' , PodcastItem[mpiGenre ]);
if (Trim(PodcastItem[mpiCountry ])!='') CreateInfoItem('Страна' , PodcastItem[mpiCountry ]);
if (Trim(PodcastItem[mpiTranslate ])!='') CreateInfoItem('Перевод' , PodcastItem[mpiTranslate ]);
if (Trim(PodcastItem[mpiQuality ])!='') CreateInfoItem('Качество', PodcastItem[mpiQuality ]);
if (Trim(PodcastItem[mpiDirector ])!='') CreateInfoItem('Режиссер', PodcastItem[mpiDirector ]);
if (Trim(PodcastItem[mpiRatingIMDb])!='') CreateInfoItem('IMDb' , PodcastItem[mpiRatingIMDb]);
if (Trim(PodcastItem[mpiRatingKP ])!='') CreateInfoItem('КП' , PodcastItem[mpiRatingKP ]);
}
}
///////////////////////////////////////////////////////////////////////////////
void GetLinkZona() {
string sData, sLink; TJsonObject JSON; bool bLowQuality;
bLowQuality = (Pos('--lowq' , mpPodcastParameters)>0);
sData = HmsDownloadURL(mpFilePath, gsHeaders, true);
JSON = TJsonObject.Create();
try {
JSON.LoadFromString(sData);
sLink = JSON.S['url'];
if (bLowQuality && (Trim(JSON.S['lqUrl'])!='')) sLink = JSON.S['lqUrl'];
MediaResourceLink = sLink;
} finally { JSON.Free; }
}
///////////////////////////////////////////////////////////////////////////////
// Получение ссылки на медиаресурс в переменную MediaResourceLink
void GetLink() {
if (LeftCopy(mpFilePath, 4)=='Info') ShowVideoInfo();
else if (LeftCopy(mpFilePath, 3)=='Err' ) VideoMessage(gsPodcastName, mpTitle);
else if (Pos('w3.zona.plus/ajax/video', mpFilePath)>0) GetLinkZona();
else MediaResourceLink = mpFilePath;
}
///////////////////////////////////////////////////////////////////////////////
// Г Л А В Н А Я П Р О Ц Е Д У Р А //
{
// Проверяем, при каком событии было вызвано выполнение скрипта (не папка ли это)
if (PodcastItem.IsFolder) {
PodcastItem.DeleteChildItems();
CreateLinks(); // Это зашли в папку подкаста (фильма) - создаём ссылки
} else {
GetLink(); // Это запустили фильм - получаем ссылку на медиа-поток
// Если в MediaResourceLink пусто, значит получить ссылку не получилось - выводим видео об ошибке
if (MediaResourceLink=='') MediaResourceLink = 'http://wonky.lostcut.net/vids/podcasterror_hd.mp4';
}
}
551
C++Script
-
51
ff0e17fe53de3b65a330662c14859f0c
00. Поиск
1dac369d-ebce-4ae0-8bdf-c73454fa7215
515
2
512
2
532
2
700
2
553
2
42
3
35
42422,9270601852
215
-mpCreateDate
93
42422,9270793171
200104
1207bd41b60f6847bb0547c72e3de559
-
32
894827a7964704499d5b48df2b6efaf8
-SearchCommands
ff0e17fe53de3b65a330662c14859f0c
515
2
512
2
532
2
700
2
553
2
42
3
4
"Набрать текст"
35
42422,9263773148
200
5
500
// Var 21.12.2014
int mpiFolderType = 200;
int mpiDynamicScript = 500;
int mpiDynamicSyntaxType = 501;
int mpiPreviousItemID = 200104;
int mpiDoNothing = 201100;
char gsSpace = 'Пробел';
char gsDelLastChar = 'Удалить последний символ';
char gsClearSearch = 'Очистить текст поиска';
char gsClearHystoryIn = 'Очистить историю поиска в папке "%s"';
char gsMsgClearHistory = 'История поиска в папке "%s" очищена';
char gsMsgTextSaved = 'Подкаст "%s" добавлен в "%s"';
char gsMsgNothingSaved = 'Текст поиска не набран! Добавлять нечего.';
char gsMsgSearchText = 'Текст поиска: %s';
char gsAddSearchTo = 'Добавить в папку "%s"';
char gsSuggestQuery = 'http://w3.zona.plus/ajax/suggest/';
char gsSuggestResultCut= '';
char gsSuggestRegExpr = '"name_rus":"(.*?)",';
char gsSuggestMethod = 'GET';
int gnSuggestNoUTFEnc = 0;
char gsSuggestMessage = 'Вариант: ';
int gnTotalItems=0; TDateTime gTimeStart = Now; char gsTextSearch, gsMsg='';
THmsScriptMediaItem goRootItem, goCmdItem;
// ------------------------------------------ Создание папок команд поиска ----
void CreateSearchCommands() {
int i; char sText; THmsScriptMediaItem Item;
CreateDynamicItem(FolderItem, '#', '-SearchCreateChars=From:32To:58');
CreateDynamicItem(FolderItem, 'A-Z', '-SearchCreateChars=From:65To:91');
CreateDynamicItem(FolderItem, 'А-Я', '-SearchCreateChars=From:192To:224');
CreateDynamicItem(FolderItem, gsClearSearch, '-SearchCmd=ClearSearchText');
// Создание команды добавления в корневую папку поиска
CreateDynamicItem(FolderItem, Format(gsAddSearchTo, [goRootItem[mpiTitle]]), '-SearchCmd=SaveSearchText');
// Создание команд добавления в папки, находящиеся в корневой, если поле "Файл" (mpiFilePath) у них пустое
for (i=0; i<goRootItem.ChildCount; i++) {
Item = goRootItem.ChildItems[i];
if (Item.ItemClassID!=51) continue;
CreateDynamicItem(FolderItem, Format(gsAddSearchTo, [Item[mpiTitle]]), '-SaveSearchTextTo='+Item.ItemID);
}
// Создание команды очистки истории в корневой папке поиска
CreateDynamicItem(FolderItem, Format(gsClearHystoryIn, [goRootItem[mpiTitle]]), '-SearchCmd=ClearSearchHistory');
// Создание команд очистки истории в папках, которые наодятся в корневой
for (i=0; i<goRootItem.ChildCount; i++) {
Item = goRootItem.ChildItems[i];
if (Item.ItemClassID!=51) continue;
CreateDynamicItem(FolderItem, Format(gsClearHystoryIn, [Item[mpiTitle]]), '-ClearSearchHistoryIn='+Item.ItemID);
}
// Создание ссылки, информирующей о текущем набранном тексте поиска
sText = Format(gsMsgSearchText, [gsTextSearch]);
Item = HmsCreateMediaItem(sText, goCmdItem.ItemID);
Item[mpiTitle ] = sText;
Item[mpiThumbnail] = 'http://wonky.lostcut.net/icons/search-icon1.jpg';
}
// ---------------------------- Добавление подкаста с именем текста поиска ----
void AddPodcastSearch(THmsScriptMediaItem prntItem) {
THmsScriptMediaItem Item;
if (Trim(gsTextSearch)=='') {gsMsg = gsMsgNothingSaved; return;}
if (LowerCase(gsTextSearch)==gsTextSearch) gsTextSearch = NameCase(gsTextSearch);
Item = prntItem.AddFolder(gsTextSearch, false);
Item[mpiFilePath ] = Format('search="%s"', [gsTextSearch]);
Item[mpiTitle ] = gsTextSearch;
HmsDatabaseAutoSave(false);
gsMsg = Format(gsMsgTextSaved, [gsTextSearch, prntItem[mpiTitle]]);
//gsTextSearch = '';
}
// --------- Функция создания динамической папки с унаследованным скриптом ----
void CreateDynamicItem(THmsScriptMediaItem prntItem, char sTitle, char sLink) {
char s; THmsScriptMediaItem Folder;
if (Trim(sTitle)=='') sTitle = gsSpace;
Folder = prntItem.AddFolder(sLink, true);
Folder[mpiTitle ] = sTitle;
Folder[mpiCreateDate ] = VarToStr(IncTime(gTimeStart,0,-gnTotalItems,0,0)); gnTotalItems++;
Folder[mpiFolderType ] = prntItem[mpiFolderType];
Folder[mpiDynamicScript ] = prntItem[mpiDynamicScript];
Folder[mpiDynamicSyntaxType] = prntItem[mpiDynamicSyntaxType];
Folder[mpiFolderSortOrder ] = prntItem[mpiFolderSortOrder];
}
// ---------------------------- MAIN PROCEDURE ------------------------------
{
int i, nCnt; char sCh, sCh1, sCh2, sText; THmsScriptMediaItem Item;
char s, sUrlServer = '', sRequestPage = '/', sPostData = '', sHeaders = '';
if (LeftCopy(mpFilePath, 1) != '-') return; // Если это не команда - то и не обрабатываем
// Поиск корневого каталога поиска (папки, которая содержит динамическую папку с путем "-SearchCommands")
goRootItem = FolderItem; goCmdItem = FolderItem;
while ((goRootItem.ItemParent != HmsDatabaseRootItem) && (goRootItem.ItemParent != nil)) {
if (goRootItem[mpiFilePath] == '-SearchCommands') {goCmdItem=goRootItem; goRootItem=goCmdItem.ItemParent; break;}
goRootItem = goRootItem.ItemParent;
}
// Если это повторный вызов, смены папки не произошло - ничего не делаем
if ((FolderItem.ItemID==goRootItem[mpiPreviousItemID]) && !DebugMode && (FolderItem!=goCmdItem)) return;
FolderItem.DeleteChildItems(); goRootItem[mpiPreviousItemID] = FolderItem.ItemID;
gsTextSearch = HmsGetUserSearchText(); // Получаем текущее значение текста поиска
// ---- Проверяем команды - по значению в mpFilePath ----
if (goRootItem[mpiDoNothing]=='1') { // Флаг "Ничего не делать" - например, при возврате
goRootItem[mpiDoNothing] = ''; // в команду набирания буквы из подпапки варианта
} else if (HmsRegExMatch('-SearchCommands', mpFilePath, sCh1)) { // Создание корневых команд поиска
CreateSearchCommands(); return;
} else if (HmsRegExMatch('-SearchChar=(\\d+)', mpFilePath, sCh1)) { // Добавление буквы (символа) к набираемому тексту поиска
gsTextSearch += Chr(StrToInt(sCh1));
} else if (HmsRegExMatch('-SetSearchText=(.*)', mpFilePath, gsTextSearch)) { // Назначить текст поиска значением варианта подсказки
goRootItem[mpiDoNothing] = '1'; gsSuggestQuery = ''; // включаем флаг не выполнять команду при возврате из этой папки
} else if (HmsRegExMatch('-SaveSearchTextTo=(.*)', mpFilePath, sCh1)) { // Добавление в папку Х. Поиск этой папки по ItemID.
Item = goRootItem; // Ищем папку с ItemID равному идентификатору, переданному в mpFilePath
for (i=0; i<goRootItem.ChildCount; i++) {
if (goRootItem.ChildItems[i].ItemID==sCh1) {Item = goRootItem.ChildItems[i]; break;}
}
AddPodcastSearch(Item); // и добавляем в найденную папку подкаст текстом поиска
} else if (HmsRegExMatch('-ClearSearchHistoryIn=(.*)', mpFilePath, sCh1)) { // Очистка истории (добавленных ранее) поисковых значений
Item = goRootItem; // Ищем папку с ItemID равному идентификатору, переданному в mpFilePath
for (i=0; i<goRootItem.ChildCount; i++) {
if (goRootItem.ChildItems[i].ItemID==sCh1) {Item = goRootItem.ChildItems[i]; break;}
}
for(i=0; i<Item.ChildCount; i++) { // Удаляем все элементы с начинающимся словом 'search' в поле mpiFilePath
if (LeftCopy(Item.ChildItems[i].Properties[mpiFilePath], 6)=='search') {Item.ChildItems[i].Delete();i--;}
}
gsMsg = Format(gsMsgClearHistory, [Item[mpiTitle]]); // вывод сообщения, что история очищена
} else if (HmsRegExMatch('-SearchCmd=(\\w+)', mpFilePath, sCh1)) {
if (sCh1=='DeleteLastChar' ) gsTextSearch = LeftCopy(gsTextSearch, Length(gsTextSearch)-1); // Удаление последнего символа
else if (sCh1=='SaveSearchText' ) AddPodcastSearch(goRootItem); // Добавить текст поиска в корневую папку
else if (sCh1=='ClearSearchText') gsTextSearch = ''; // Очистка текста поиска
else if (sCh1=='ClearSearchHistory') { // Очистка истории (добавленных значений поиска)
for(i=0; i<goRootItem.ChildCount; i++) {
Item = goRootItem.ChildItems[i]; // Ищем все элементы, у которых значение mpiFilePath начиначется с 'search'
if (LeftCopy(Item[mpiFilePath], 6)=='search') {goRootItem.ChildItems[i].Delete();i--;}
}
gsMsg = Format(gsMsgClearHistory, [goRootItem[mpiTitle]]);
}
} else if (HmsRegExMatch2('-SearchCreateChars=From:(\\d+)To:(\\d+)', mpFilePath, sCh1, sCh2)) { // Создание списка букв/символов
CreateDynamicItem(FolderItem, gsDelLastChar, '-SearchCmd=DeleteLastChar Suggestions'); // В начало - команда удаления символа
CreateDynamicItem(FolderItem, ' ', '-SearchChar=32 Suggestions'); // Пробел
for (i= StrToInt(sCh1); i<StrToInt(sCh2); i++) CreateDynamicItem(FolderItem, Chr(i), '-SearchChar='+IntToStr(i)+' Suggestions');
// слово "Suggestions" добавлено к значению mpiFilePath тек команд, в которых возможно использование подсказок
}
else return; // Если неизвестная нам команда - просто выходим
HmsSetUserSearchText(gsTextSearch); // Устанавливаем значение текста поиска
Item = HmsCreateMediaItem('-command=none', FolderItem.ItemID);
if (gsMsg=='') { // Если сообщения небыло - просто выводим ссылку с текущим значением набранного текста
Item[mpiThumbnail] = 'http://wonky.lostcut.net/icons/search-icon1.jpg';
Item[mpiFilePath ] = Format(gsMsgSearchText, [gsTextSearch]);
} else { // Выводим сообщение
Item[mpiThumbnail] = 'http://wonky.lostcut.net/icons/ok.png';
Item[mpiFilePath ] = gsMsg;
}
Item = HmsCreateMediaItem('-command=none', FolderItem.ItemParent.ItemID); // В родительской папке (выше) обновляем информацию о текущем значении текста
Item[mpiFilePath] = Format(gsMsgSearchText, [gsTextSearch]);
Item[mpiThumbnail] = 'http://wonky.lostcut.net/icons/search-icon1.jpg';
Item = HmsCreateMediaItem('-command=none', goCmdItem.ItemID); // Также в папке, содержащую главные команды поиска
Item[mpiFilePath] = Format(gsMsgSearchText, [gsTextSearch]);
Item[mpiThumbnail] = 'http://wonky.lostcut.net/icons/search-icon1.jpg';
// Suggestions ------ Блок работы с подсказками -------
if ((gsSuggestQuery!='') && (Pos('Suggestions', mpFilePath)>0) && (Length(gsTextSearch)>1)) {
sText = gsTextSearch; if (gnSuggestNoUTFEnc==0) sText = HmsUtf8Encode(sText); // Если не указано не кодировать в UTF - кодируем
sText = HmsHttpEncode(sText);
// Если есть ключ <TEXT> в запросе - заменяем его на значение набранного текста, иначе просто добавляем в конец
if (Pos('<TEXT>', gsSuggestQuery)>0) gsSuggestQuery = ReplaceStr(gsSuggestQuery, '<TEXT>', sText);
else gsSuggestQuery = gsSuggestQuery + sText;
HmsRegExMatch2('https?://(.*?)(/.*)', gsSuggestQuery, sUrlServer, sRequestPage);
if (gsSuggestMethod=='POST') HmsRegExMatch2('^(.*?)\\?(.*)', sRequestPage, sRequestPage, sPostData);
sHeaders = 'http://'+sUrlServer+'/\r\n'+
'Accept-Encoding: gzip, deflate\r\n'+
'X-Requested-With: XMLHttpRequest\r\n'+
'User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko/20100101 Firefox/13.0\r\n'+
'Connection: Keep-Alive\r\n'+
'Accept: application/json, text/javascript, */*; q=0.01\r\n'; // Для включения возможности gzip в запросах
sText = HmsSendRequestEx(sUrlServer, sRequestPage, gsSuggestMethod, 'application/x-www-form-urlencoded; Charset=UTF-8', sHeaders, sPostData, 80, 0, '', true);
sText = HmsUtf8Decode(sText);
if (gsSuggestResultCut!='') HmsRegExMatch(gsSuggestResultCut, sText, sText);// Если есть выражение обрезки - обрезаем
sText = HmsJsonDecode(sText); TRegExpr t = TRegExpr.Create('(<[^>]+>)'); // Избавляемся от тегов в середине слов подсказки
TRegExpr reSearch = TRegExpr.Create(gsSuggestRegExpr, PCRE_SINGLELINE);
if (reSearch.Search(sText)) do {
s = reSearch.Match;
if (t.Search(s)) do s=ReplaceStr(s, t.Match, ''); while (t.SearchAgain());// (функция HmsHtmlToText не подходит т.к. ставит пробел в середине слова)
if (HmsRegExMatch('^(.*?)[/\\(\\|]', s, sCh)) { // Обрезаем подсказку до знаков /, ( или |
if (Pos(LowerCase(gsTextSearch), LowerCase(sCh))>0) s = sCh; // Если после этого в подсказке встречается набранный текст - то так и оставляем
}
if (LowerCase(s)==s) s = NameCase(s); // Если подсказки - все маленькие буквы, делаем NameCase
// Если в подсказке больше одного слова - дополнительно создаём сначала подсказки из слов, которые содержат набранный текст (выделяем слова отдельно)
if (WordCount(s, ' ')>1) {
nCnt = WordCount(s, ' ');
for (i=1; i<=nCnt; i++) {
sCh=ExtractWord(i, s, ' '); if (Trim(sCh)=='') continue;
if (Pos(LowerCase(gsTextSearch), LowerCase(sCh))<1) continue;
if (LowerCase(gsTextSearch)==LowerCase(sCh)) continue;
sCh = ReplaceStr(sCh, ':', ''); sCh=ReplaceStr(sCh, '\\', '');
CreateDynamicItem(FolderItem, gsSuggestMessage+sCh, '-SetSearchText='+sCh);
}
}
// Создаём папку с предложением варианта (подсказку)
if (LowerCase(s)!=LowerCase(gsTextSearch)) CreateDynamicItem(FolderItem, gsSuggestMessage+s, '-SetSearchText='+s);
if (gnTotalItems>100) break; // Ограничиваем количество создаваемых элементов = 100
} while (reSearch.SearchAgain());
}
HmsIncSystemUpdateID(); // Говорим устройству об обновлении содержания
}
501
C++Script
215
-mpCreateDate
93
42422,9270793171
245
894827a7964704499d5b48df2b6efaf8
-
53
dd373a5a8f795ca0961f61ce92e932f1
http://w3.zona.plus/updates/movies
1dac369d-ebce-4ae0-8bdf-c73454fa7215
515
2
512
2
532
2
700
2
553
2
42
3
4
01. Последние поступления
35
42422,9263657407
215
-35
527
--maxpages=2
93
42422,9270793171
525
42422,9305096528
-
53
a33f81635533244721a11b2e391423a2
http://w3.zona.plus/movies
1dac369d-ebce-4ae0-8bdf-c73454fa7215
515
2
512
2
532
2
700
2
553
2
42
3
4
02. Популярные фильмы
35
42422,9256712963
215
-35
527
--maxpages=7
93
42422,9270793171
525
42422,9303433681
-
53
b9bddd5622827929e7fa0e2103cc98ad
http://w3.zona.plus/tvseries
1dac369d-ebce-4ae0-8bdf-c73454fa7215
515
2
512
2
532
2
700
2
553
2
42
3
4
03. Сериалы
35
42422,9249768518
215
-35
527
--group=alph --maxpages=30
93
42422,9270793171
701
-1
702
-1
517
578-720,722-1080,482-576,402-480,322-400,202-320,0-200
518
0
522
0
245
b9bddd5622827929e7fa0e2103cc98ad
525
42423,0241832755
-
51
961d5bbe9869868ac81f88dee46171de
04. Категории
1dac369d-ebce-4ae0-8bdf-c73454fa7215
515
2
512
2
532
2
700
2
553
2
42
3
35
42422,9242824074
215
-35
93
42422,9270793171
-
53
663be5fccdaac342d7f4330cc3b3be16
http://w3.zona.plus/movies/filter/genre-multfilm
961d5bbe9869868ac81f88dee46171de
515
2
512
2
532
2
700
2
553
2
42
3
4
Мультфильм
35
42422,923587963
215
-35
93
42422,9270793171
-
53
eef6515ca2cf1fce009e968a94f861f4
http://w3.zona.plus/movies/filter/genre-komediia
961d5bbe9869868ac81f88dee46171de
515
2
512
2
532
2
700
2
553
2
42
3
4
Комедия
35
42422,9228935185
215
-35
93
42422,9270793171
-
53
4902af7e1592a019fe919ea642188502
http://w3.zona.plus/movies/filter/genre-melodrama
961d5bbe9869868ac81f88dee46171de
515
2
512
2
532
2
700
2
553
2
42
3
4
Мелодрама
35
42422,9221990741
215
-35
93
42422,9270793287
-
53
8187cc854f48b4a2eca605cfc0aeb829
http://w3.zona.plus/movies/filter/genre-drama
961d5bbe9869868ac81f88dee46171de
515
2
512
2
532
2
700
2
553
2
42
3
4
Драма
35
42422,9215046296
215
-35
93
42422,9270793287
-
53
66411932238412853a458da6bcd8172c
http://w3.zona.plus/movies/filter/genre-boevik
961d5bbe9869868ac81f88dee46171de
515
2
512
2
532
2
700
2
553
2
42
3
4
Боевик
35
42422,9208101852
215
-35
93
42422,9270793287
-
53
24d727436ec92b0f03db60ac41d204f6
http://w3.zona.plus/movies/filter/genre-uzhasy
961d5bbe9869868ac81f88dee46171de
515
2
512
2
532
2
700
2
553
2
42
3
4
Ужасы
35
42422,9201157407
215
-35
93
42422,9270793287
-
53
a6b3a6704842a2b616ea5749081de728
http://w3.zona.plus/movies/filter/genre-prikliucheniia
961d5bbe9869868ac81f88dee46171de
515
2
512
2
532
2
700
2
553
2
42
3
4
Приключения
35
42422,9194212963
215
-35
93
42422,9270793287
-
53
81e0a7991b01670ae5da74e6b95a0ae7
http://w3.zona.plus/movies/filter/genre-dokumentalnyi
961d5bbe9869868ac81f88dee46171de
515
2
512
2
532
2
700
2
553
2
42
3
4
Документальный
35
42422,9187268519
215
-35
93
42422,9270793287
-
53
18b45574de8cbd6a33c3d61f6320277a
http://w3.zona.plus/movies/filter/genre-triller
961d5bbe9869868ac81f88dee46171de
515
2
512
2
532
2
700
2
553
2
42
3
4
Триллер
35
42422,9180324074
215
-35
93
42422,9270793287
-
53
af3485fcc28cdfef4fa8f82a9e8f29ec
http://w3.zona.plus/movies/filter/genre-miuzikl
961d5bbe9869868ac81f88dee46171de
515
2
512
2
532
2
700
2
553
2
42
3
4
Мюзикл
35
42422,917337963
215
-35
93
42422,9270793287
-
53
415b66c0b014379db1eddd2f0c70ae6a
http://w3.zona.plus/movies/filter/genre-fantastika
961d5bbe9869868ac81f88dee46171de
515
2
512
2
532
2
700
2
553
2
42
3
4
Фантастика
35
42422,9166435185
215
-35
93
42422,9270793287
-
53
90aa39ac661421ed1b384d9ef155f18e
http://w3.zona.plus/movies/filter/genre-istoriia
961d5bbe9869868ac81f88dee46171de
515
2
512
2
532
2
700
2
553
2
42
3
4
История
35
42422,9159490741
215
-35
93
42422,9270793287
-
53
75aaf14486b2470906bbc54b8ebca29c
http://w3.zona.plus/movies/filter/genre-voennyi
961d5bbe9869868ac81f88dee46171de
515
2
512
2
532
2
700
2
553
2
42
3
4
Военный
35
42422,9152546296
215
-35
93
42422,9270793287
-
51
852cf7391a95d6b015f9f0de0b99299c
05. По странам
1dac369d-ebce-4ae0-8bdf-c73454fa7215
515
2
512
2
532
2
700
2
553
2
42
3
35
42422,9145601852
215
-35
93
42422,9270793287
-
53
f185f149586051ef1528d041b2bac85f
http://w3.zona.plus/movies/filter/country-rossiia
852cf7391a95d6b015f9f0de0b99299c
515
2
512
2
532
2
700
2
553
2
42
3
4
Россия
35
42422,9138657407
215
-35
93
42422,9270793287
525
42422,927238831
-
53
def7bc83b9ebfc9c356da782f3a7299a
http://w3.zona.plus/movies/filter/country-ssha
852cf7391a95d6b015f9f0de0b99299c
515
2
512
2
532
2
700
2
553
2
42
3
4
США
35
42422,9131712963
215
-35
93
42422,9270793287
-
53
bb9aac539a37fb6ca0e5603b5b75db28
http://w3.zona.plus/movies/filter/country-frantciia
852cf7391a95d6b015f9f0de0b99299c
515
2
512
2
532
2
700
2
553
2
42
3
4
Франция
35
42422,9124768519
215
-35
93
42422,9270793287
-
53
0bfa70dd7ffdec7ce9f7b2dcde2b332e
http://w3.zona.plus/movies/filter/country-italiia
852cf7391a95d6b015f9f0de0b99299c
515
2
512
2
532
2
700
2
553
2
42
3
4
Италия
35
42422,9117824074
215
-35
93
42422,9270793287
-
53
fe85a2e73cc261bc9bdd8169481fe36e
http://w3.zona.plus/movies/filter/country-koreia-iuzhnaia
852cf7391a95d6b015f9f0de0b99299c
515
2
512
2
532
2
700
2
553
2
42
3
4
Корея Южная
35
42422,911087963
215
-35
93
42422,9270793287
525
42422,9274542361
-
53
5f4f87a074185fbbcc5b2f001e67e5ed
http://w3.zona.plus/movies/filter/country-germaniia
852cf7391a95d6b015f9f0de0b99299c
515
2
512
2
532
2
700
2
553
2
42
3
4
Германия
35
42422,9103935185
215
-35
93
42422,9270793287
-
53
358316682437e763ddf5488e97e7c35e
http://w3.zona.plus/movies/filter/country-iaponiia
852cf7391a95d6b015f9f0de0b99299c
515
2
512
2
532
2
700
2
553
2
42
3
4
Япония
35
42422,9096990741
215
-35
93
42422,9270793287
-
53
a8b12ec058916b63638050f441a61202
http://w3.zona.plus/movies/filter/country-kitai
852cf7391a95d6b015f9f0de0b99299c
515
2
512
2
532
2
700
2
553
2
42
3
4
Китай
35
42422,9090046296
215
-35
93
42422,9270793287
-
53
aa87630c0890e2e7b4aa5d239e6930b0
http://w3.zona.plus/movies/filter/country-ukraina
852cf7391a95d6b015f9f0de0b99299c
515
2
512
2
532
2
700
2
553
2
42
3
4
Украина
35
42422,9083101852
215
-35
93
42422,9270793287
-
53
70486a2969ab2742280b39d55386f6d6
http://w3.zona.plus/movies/filter/country-ispaniia
852cf7391a95d6b015f9f0de0b99299c
515
2
512
2
532
2
700
2
553
2
42
3
4
Испания
35
42422,9076157407
215
-35
93
42422,9270793287
-
53
f08baada04580965bd39b10117740e01
http://w3.zona.plus/movies/filter/country-velikobritaniia
852cf7391a95d6b015f9f0de0b99299c
515
2
512
2
532
2
700
2
553
2
42
3
4
Великобритания
35
42422,9069212963
215
-35
93
42422,9270793287
-
53
06e4988890bbec118538079de09d02c2
http://w3.zona.plus/movies/filter/country-shvetciia
852cf7391a95d6b015f9f0de0b99299c
515
2
512
2
532
2
700
2
553
2
42
3
4
Швеция
35
42422,9062268519
215
-35
93
42422,9270793287
-
53
f43ad4976c86055e1c15eed749678106
http://w3.zona.plus/movies/filter/country-daniia
852cf7391a95d6b015f9f0de0b99299c
515
2
512
2
532
2
700
2
553
2
42
3
4
Дания
35
42422,9055324074
215
-35
93
42422,9270793287
-
53
b3b4ae039a19c971b0f25ae2705073f2
http://w3.zona.plus/movies/filter/year-2016/sort-date
1dac369d-ebce-4ae0-8bdf-c73454fa7215
515
2
512
2
532
2
700
2
553
2
42
3
4
06. Фильмы 2016 года
35
42422,904837963
215
-35
93
42422,9270793287
525
42422,9276389699
-
53
a8b6e59e18669b4910cafd1aee46eeeb
http://w3.zona.plus/movies/filter/year-2015/sort-date
1dac369d-ebce-4ae0-8bdf-c73454fa7215
515
2
512
2
532
2
700
2
553
2
42
3
4
07. Фильмы 2015 года
35
42422,9041435185
215
-35
93
42422,9270793287
525
42422,9277574768