mirror of
https://github.com/tuxbox-neutrino/neutrino.git
synced 2025-09-01 01:41:23 +02:00
Merge branch 'master' into pu/mp
This commit is contained in:
@@ -33,6 +33,7 @@ libneutrino_driver_a_SOURCES = \
|
||||
fontrenderer.cpp \
|
||||
genpsi.cpp \
|
||||
moviecut.cpp \
|
||||
movieinfo.cpp \
|
||||
neutrinofonts.cpp \
|
||||
radiotext.cpp \
|
||||
radiotools.cpp \
|
||||
|
@@ -20,7 +20,7 @@
|
||||
#ifndef __MOVIE_CUT__
|
||||
#define __MOVIE_CUT__
|
||||
|
||||
#include <gui/movieinfo.h>
|
||||
#include <driver/movieinfo.h>
|
||||
#include <gui/components/cc.h>
|
||||
|
||||
class CFrameBuffer;
|
||||
|
592
src/driver/movieinfo.cpp
Normal file
592
src/driver/movieinfo.cpp
Normal file
@@ -0,0 +1,592 @@
|
||||
/*
|
||||
movieinfo - Neutrino-GUI
|
||||
|
||||
Copyright (C) 2005 Günther <Günther@tuxbox.berlios.org>
|
||||
|
||||
Copyright (C) 2009, 2012 Stefan Seyfried
|
||||
Copyright (C) 2015 Sven Hoefer (svenhoefer)
|
||||
|
||||
License: GPL
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <global.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <driver/movieinfo.h>
|
||||
#include <system/helpers.h>
|
||||
|
||||
#include <neutrino.h>
|
||||
|
||||
#define TRACE printf
|
||||
|
||||
CMovieInfo::CMovieInfo()
|
||||
{
|
||||
//TRACE("[mi] new\n");
|
||||
}
|
||||
|
||||
CMovieInfo::~CMovieInfo()
|
||||
{
|
||||
//TRACE("[mi] del\n");
|
||||
;
|
||||
}
|
||||
|
||||
bool CMovieInfo::convertTs2XmlName(std::string& filename)
|
||||
{
|
||||
size_t lastdot = filename.find_last_of(".");
|
||||
if (lastdot != string::npos) {
|
||||
filename.erase(lastdot + 1);
|
||||
filename.append("xml");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void XML_ADD_TAG_STRING(std::string &_xml_text_, const char *_tag_name_, std::string _tag_content_)
|
||||
{
|
||||
_xml_text_ += "\t\t<";
|
||||
_xml_text_ += _tag_name_;
|
||||
_xml_text_ += ">";
|
||||
_xml_text_ += ZapitTools::UTF8_to_UTF8XML(_tag_content_.c_str());
|
||||
_xml_text_ += "</";
|
||||
_xml_text_ += _tag_name_;
|
||||
_xml_text_ += ">\n";
|
||||
}
|
||||
|
||||
static void XML_ADD_TAG_UNSIGNED(std::string &_xml_text_, const char *_tag_name_, unsigned int _tag_content_)
|
||||
{
|
||||
_xml_text_ += "\t\t<";
|
||||
_xml_text_ += _tag_name_;
|
||||
_xml_text_ += ">";
|
||||
_xml_text_ += to_string(_tag_content_);
|
||||
_xml_text_ += "</";
|
||||
_xml_text_ += _tag_name_;
|
||||
_xml_text_ += ">\n";
|
||||
}
|
||||
|
||||
static void XML_ADD_TAG_LONG(std::string &_xml_text_, const char *_tag_name_, uint64_t _tag_content_)
|
||||
{
|
||||
_xml_text_ += "\t\t<";
|
||||
_xml_text_ += _tag_name_;
|
||||
_xml_text_ += ">";\
|
||||
_xml_text_ += to_string(_tag_content_);
|
||||
_xml_text_ += "</";
|
||||
_xml_text_ += _tag_name_;
|
||||
_xml_text_ += ">\n";
|
||||
}
|
||||
|
||||
bool CMovieInfo::encodeMovieInfoXml(std::string * extMessage, MI_MOVIE_INFO * movie_info)
|
||||
{
|
||||
//TRACE("[mi]->encodeMovieInfoXml\n");
|
||||
|
||||
*extMessage = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n"
|
||||
"<" MI_XML_TAG_NEUTRINO " commandversion=\"1\">\n"
|
||||
"\t<" MI_XML_TAG_RECORD " command=\""
|
||||
"record"
|
||||
"\">\n";
|
||||
XML_ADD_TAG_STRING(*extMessage, MI_XML_TAG_CHANNELNAME, movie_info->channelName);
|
||||
XML_ADD_TAG_STRING(*extMessage, MI_XML_TAG_EPGTITLE, movie_info->epgTitle);
|
||||
XML_ADD_TAG_LONG(*extMessage, MI_XML_TAG_ID, movie_info->channelId);
|
||||
XML_ADD_TAG_STRING(*extMessage, MI_XML_TAG_INFO1, movie_info->epgInfo1);
|
||||
XML_ADD_TAG_STRING(*extMessage, MI_XML_TAG_INFO2, movie_info->epgInfo2);
|
||||
XML_ADD_TAG_LONG(*extMessage, MI_XML_TAG_EPGID, movie_info->epgId); // %llu
|
||||
XML_ADD_TAG_UNSIGNED(*extMessage, MI_XML_TAG_MODE, movie_info->mode); // %d
|
||||
XML_ADD_TAG_UNSIGNED(*extMessage, MI_XML_TAG_VIDEOPID, movie_info->VideoPid); // %u
|
||||
XML_ADD_TAG_UNSIGNED(*extMessage, MI_XML_TAG_VIDEOTYPE, movie_info->VideoType); // %u
|
||||
if ( !movie_info->audioPids.empty() ) {
|
||||
*extMessage += "\t\t<" MI_XML_TAG_AUDIOPIDS ">\n";
|
||||
|
||||
for (unsigned int i = 0; i < movie_info->audioPids.size(); i++) // pids.APIDs.size()
|
||||
{
|
||||
*extMessage += "\t\t\t<" MI_XML_TAG_AUDIO " " MI_XML_TAG_PID "=\"";
|
||||
*extMessage += to_string(movie_info->audioPids[i].AudioPid);
|
||||
*extMessage += "\" " MI_XML_TAG_ATYPE "=\"";
|
||||
*extMessage += to_string(movie_info->audioPids[i].atype);
|
||||
*extMessage += "\" " MI_XML_TAG_SELECTED "=\"";
|
||||
*extMessage += to_string(movie_info->audioPids[i].selected);
|
||||
*extMessage += "\" " MI_XML_TAG_NAME "=\"";
|
||||
*extMessage += ZapitTools::UTF8_to_UTF8XML(movie_info->audioPids[i].AudioPidName.c_str());
|
||||
*extMessage += "\"/>\n";
|
||||
}
|
||||
*extMessage += "\t\t</" MI_XML_TAG_AUDIOPIDS ">\n";
|
||||
}
|
||||
XML_ADD_TAG_UNSIGNED(*extMessage, MI_XML_TAG_VTXTPID, movie_info->VtxtPid); // %u
|
||||
|
||||
XML_ADD_TAG_UNSIGNED(*extMessage, MI_XML_TAG_GENRE_MAJOR, movie_info->genreMajor);
|
||||
XML_ADD_TAG_UNSIGNED(*extMessage, MI_XML_TAG_GENRE_MINOR, movie_info->genreMinor);
|
||||
XML_ADD_TAG_STRING(*extMessage, MI_XML_TAG_SERIE_NAME, movie_info->serieName);
|
||||
XML_ADD_TAG_UNSIGNED(*extMessage, MI_XML_TAG_LENGTH, movie_info->length);
|
||||
XML_ADD_TAG_STRING(*extMessage, MI_XML_TAG_PRODUCT_COUNTRY, movie_info->productionCountry);
|
||||
XML_ADD_TAG_UNSIGNED(*extMessage, MI_XML_TAG_PRODUCT_DATE, movie_info->productionDate);
|
||||
XML_ADD_TAG_UNSIGNED(*extMessage, MI_XML_TAG_RATING, movie_info->rating);
|
||||
XML_ADD_TAG_UNSIGNED(*extMessage, MI_XML_TAG_QUALITY, movie_info->quality);
|
||||
XML_ADD_TAG_UNSIGNED(*extMessage, MI_XML_TAG_PARENTAL_LOCKAGE, movie_info->parentalLockAge);
|
||||
XML_ADD_TAG_UNSIGNED(*extMessage, MI_XML_TAG_DATE_OF_LAST_PLAY, movie_info->dateOfLastPlay);
|
||||
*extMessage += "\t\t<" MI_XML_TAG_BOOKMARK ">\n"
|
||||
"\t";
|
||||
XML_ADD_TAG_UNSIGNED(*extMessage, MI_XML_TAG_BOOKMARK_START, movie_info->bookmarks.start);
|
||||
*extMessage += "\t";
|
||||
XML_ADD_TAG_UNSIGNED(*extMessage, MI_XML_TAG_BOOKMARK_END, movie_info->bookmarks.end);
|
||||
*extMessage += "\t";
|
||||
XML_ADD_TAG_UNSIGNED(*extMessage, MI_XML_TAG_BOOKMARK_LAST, movie_info->bookmarks.lastPlayStop);
|
||||
for (int i = 0; i < MI_MOVIE_BOOK_USER_MAX; i++) {
|
||||
if (movie_info->bookmarks.user[i].pos != 0 || i == 0) {
|
||||
// encode any valid book, at least 1
|
||||
*extMessage += "\t\t\t<" MI_XML_TAG_BOOKMARK_USER " " MI_XML_TAG_BOOKMARK_USER_POS "=\"";
|
||||
*extMessage += to_string(movie_info->bookmarks.user[i].pos);
|
||||
*extMessage += "\" " MI_XML_TAG_BOOKMARK_USER_TYPE "=\"";
|
||||
*extMessage += to_string(movie_info->bookmarks.user[i].length);
|
||||
*extMessage += "\" " MI_XML_TAG_BOOKMARK_USER_NAME "=\"";
|
||||
*extMessage += ZapitTools::UTF8_to_UTF8XML(movie_info->bookmarks.user[i].name.c_str());
|
||||
*extMessage += "\"/>\n";
|
||||
}
|
||||
}
|
||||
|
||||
*extMessage += "\t\t</" MI_XML_TAG_BOOKMARK ">\n"
|
||||
"\t</" MI_XML_TAG_RECORD ">\n"
|
||||
"</" MI_XML_TAG_NEUTRINO ">\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CMovieInfo::saveMovieInfo(MI_MOVIE_INFO & movie_info, CFile * file)
|
||||
{
|
||||
//TRACE("[mi]->saveMovieInfo\n");
|
||||
|
||||
bool result = true;
|
||||
std::string text;
|
||||
CFile file_xml;
|
||||
|
||||
if (file == NULL) {
|
||||
file_xml.Name = movie_info.file.Name;
|
||||
result = convertTs2XmlName(file_xml.Name);
|
||||
} else {
|
||||
file_xml.Name = file->Name;
|
||||
}
|
||||
TRACE("[mi] saveMovieInfo: %s\n", file_xml.Name.c_str());
|
||||
|
||||
if (result == true) {
|
||||
result = encodeMovieInfoXml(&text, &movie_info);
|
||||
if (result == true) {
|
||||
result = saveFile(file_xml, text); // save
|
||||
if (result == false) {
|
||||
TRACE("[mi] saveMovieInfo: save error\n");
|
||||
}
|
||||
} else {
|
||||
TRACE("[mi] saveMovieInfo: encoding error\n");
|
||||
}
|
||||
} else {
|
||||
TRACE("[mi] saveMovieInfo: error\n");
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
|
||||
bool CMovieInfo::loadMovieInfo(MI_MOVIE_INFO * movie_info, CFile * file)
|
||||
{
|
||||
//TRACE("[mi]->loadMovieInfo\n");
|
||||
|
||||
bool result = true;
|
||||
CFile file_xml;
|
||||
|
||||
if (file == NULL) {
|
||||
// if there is no give file, we use the file name from movie info
|
||||
// but we have to convert the ts name to xml name first
|
||||
file_xml.Name = movie_info->file.Name;
|
||||
result = convertTs2XmlName(file_xml.Name);
|
||||
} else {
|
||||
file_xml.Name = file->Name;
|
||||
}
|
||||
|
||||
if (result == true) {
|
||||
// load xml file in buffer
|
||||
std::string text;
|
||||
result = loadFile(file_xml, text);
|
||||
if (result == true)
|
||||
result = parseXmlTree(text, movie_info);
|
||||
}
|
||||
if (movie_info->productionDate > 50 && movie_info->productionDate < 200) // backwardcompaibility
|
||||
movie_info->productionDate += 1900;
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
static int find_next_char(char to_find, const char *text, int start_pos, int end_pos)
|
||||
{
|
||||
while (start_pos < end_pos) {
|
||||
if (text[start_pos] == to_find) {
|
||||
return (start_pos);
|
||||
}
|
||||
start_pos++;
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#define GET_XML_DATA_STRING(_text_,_pos_,_tag_,_dest_)\
|
||||
if(strncmp(&_text_[_pos_],_tag_,sizeof(_tag_)-1) == 0)\
|
||||
{\
|
||||
_pos_ += sizeof(_tag_) ;\
|
||||
int pos_prev = _pos_;\
|
||||
while(_pos_ < bytes && _text_[_pos_] != '<' ) _pos_++;\
|
||||
_dest_ = "";\
|
||||
_dest_.append(&_text_[pos_prev],_pos_ - pos_prev );\
|
||||
_dest_ = htmlEntityDecode(_dest_);\
|
||||
_pos_ += sizeof(_tag_);\
|
||||
continue;\
|
||||
}
|
||||
|
||||
#define GET_XML_DATA_INT(_text_,_pos_,_tag_,_dest_)\
|
||||
if(strncmp(&_text_[pos],_tag_,sizeof(_tag_)-1) == 0)\
|
||||
{\
|
||||
_pos_ += sizeof(_tag_) ;\
|
||||
int pos_prev = _pos_;\
|
||||
while(_pos_ < bytes && _text_[_pos_] != '<' ) pos++;\
|
||||
_dest_ = atoi(&_text_[pos_prev]);\
|
||||
continue;\
|
||||
}
|
||||
#define GET_XML_DATA_LONG(_text_,_pos_,_tag_,_dest_)\
|
||||
if(strncmp(&_text_[pos],_tag_,sizeof(_tag_)-1) == 0)\
|
||||
{\
|
||||
_pos_ += sizeof(_tag_) ;\
|
||||
int pos_prev = _pos_;\
|
||||
while(_pos_ < bytes && _text_[_pos_] != '<' ) pos++;\
|
||||
_dest_ = strtoull(&_text_[pos_prev], NULL, 10);\
|
||||
continue;\
|
||||
}
|
||||
|
||||
bool CMovieInfo::parseXmlTree(std::string &_text, MI_MOVIE_INFO *movie_info)
|
||||
{
|
||||
int bookmark_nr = 0;
|
||||
movie_info->dateOfLastPlay = 0; //100*366*24*60*60; // (date, month, year)
|
||||
//bool result = false;
|
||||
|
||||
const char *text = _text.c_str();
|
||||
int bytes = _text.length();
|
||||
|
||||
int pos = 0;
|
||||
|
||||
AUDIO_PIDS audio_pids;
|
||||
|
||||
while ((pos = find_next_char('<', text, pos, bytes)) != -1) {
|
||||
pos++;
|
||||
GET_XML_DATA_STRING(text, pos, MI_XML_TAG_CHANNELNAME, movie_info->channelName)
|
||||
GET_XML_DATA_STRING(text, pos, MI_XML_TAG_EPGTITLE, movie_info->epgTitle)
|
||||
GET_XML_DATA_LONG(text, pos, MI_XML_TAG_ID, movie_info->channelId)
|
||||
GET_XML_DATA_STRING(text, pos, MI_XML_TAG_INFO1, movie_info->epgInfo1)
|
||||
GET_XML_DATA_STRING(text, pos, MI_XML_TAG_INFO2, movie_info->epgInfo2)
|
||||
GET_XML_DATA_LONG(text, pos, MI_XML_TAG_EPGID, movie_info->epgId)
|
||||
GET_XML_DATA_INT(text, pos, MI_XML_TAG_MODE, movie_info->mode)
|
||||
GET_XML_DATA_INT(text, pos, MI_XML_TAG_VIDEOPID, movie_info->VideoPid)
|
||||
GET_XML_DATA_INT(text, pos, MI_XML_TAG_VIDEOTYPE, movie_info->VideoType)
|
||||
GET_XML_DATA_STRING(text, pos, MI_XML_TAG_NAME, movie_info->channelName)
|
||||
GET_XML_DATA_INT(text, pos, MI_XML_TAG_VTXTPID, movie_info->VtxtPid)
|
||||
GET_XML_DATA_INT(text, pos, MI_XML_TAG_GENRE_MAJOR, movie_info->genreMajor)
|
||||
GET_XML_DATA_INT(text, pos, MI_XML_TAG_GENRE_MINOR, movie_info->genreMinor)
|
||||
GET_XML_DATA_STRING(text, pos, MI_XML_TAG_SERIE_NAME, movie_info->serieName)
|
||||
GET_XML_DATA_INT(text, pos, MI_XML_TAG_LENGTH, movie_info->length)
|
||||
GET_XML_DATA_STRING(text, pos, MI_XML_TAG_PRODUCT_COUNTRY, movie_info->productionCountry)
|
||||
GET_XML_DATA_INT(text, pos, MI_XML_TAG_PRODUCT_DATE, movie_info->productionDate)
|
||||
GET_XML_DATA_INT(text, pos, MI_XML_TAG_PARENTAL_LOCKAGE, movie_info->parentalLockAge)
|
||||
GET_XML_DATA_INT(text, pos, MI_XML_TAG_RATING, movie_info->rating)
|
||||
GET_XML_DATA_INT(text, pos, MI_XML_TAG_QUALITIY, movie_info->quality)
|
||||
GET_XML_DATA_INT(text, pos, MI_XML_TAG_QUALITY, movie_info->quality)
|
||||
GET_XML_DATA_INT(text, pos, MI_XML_TAG_DATE_OF_LAST_PLAY, movie_info->dateOfLastPlay)
|
||||
|
||||
if (strncmp(&text[pos], MI_XML_TAG_AUDIOPIDS, sizeof(MI_XML_TAG_AUDIOPIDS) - 1) == 0)
|
||||
pos += sizeof(MI_XML_TAG_AUDIOPIDS);
|
||||
|
||||
/* parse audio pids */
|
||||
if (strncmp(&text[pos], MI_XML_TAG_AUDIO, sizeof(MI_XML_TAG_AUDIO) - 1) == 0) {
|
||||
pos += sizeof(MI_XML_TAG_AUDIO);
|
||||
|
||||
int pos2;
|
||||
const char *ptr;
|
||||
|
||||
pos2 = -1;
|
||||
ptr = strstr(&text[pos], MI_XML_TAG_PID);
|
||||
if (ptr)
|
||||
pos2 = (int)(ptr - &text[pos]);
|
||||
//pos2 = strcspn(&text[pos],MI_XML_TAG_PID);
|
||||
if (pos2 >= 0) {
|
||||
pos2 += sizeof(MI_XML_TAG_PID);
|
||||
while (text[pos + pos2] != '\"' && text[pos + pos2] != 0 && text[pos + pos2] != '/')
|
||||
pos2++;
|
||||
if (text[pos + pos2] == '\"')
|
||||
audio_pids.AudioPid = atoi(&text[pos + pos2 + 1]);
|
||||
} else
|
||||
audio_pids.AudioPid = 0;
|
||||
|
||||
audio_pids.atype = 0;
|
||||
pos2 = -1;
|
||||
ptr = strstr(&text[pos], MI_XML_TAG_ATYPE);
|
||||
if (ptr)
|
||||
pos2 = (int)(ptr - &text[pos]);
|
||||
//pos2 = strcspn(&text[pos],MI_XML_TAG_ATYPE);
|
||||
if (pos2 >= 0) {
|
||||
pos2 += sizeof(MI_XML_TAG_ATYPE);
|
||||
while (text[pos + pos2] != '\"' && text[pos + pos2] != 0 && text[pos + pos2] != '/')
|
||||
pos2++;
|
||||
if (text[pos + pos2] == '\"')
|
||||
audio_pids.atype = atoi(&text[pos + pos2 + 1]);
|
||||
}
|
||||
|
||||
audio_pids.selected = 0;
|
||||
pos2 = -1;
|
||||
ptr = strstr(&text[pos], MI_XML_TAG_SELECTED);
|
||||
if (ptr)
|
||||
pos2 = (int)(ptr - &text[pos]);
|
||||
//pos2 = strcspn(&text[pos],MI_XML_TAG_SELECTED);
|
||||
if (pos2 >= 0) {
|
||||
pos2 += sizeof(MI_XML_TAG_SELECTED);
|
||||
while (text[pos + pos2] != '\"' && text[pos + pos2] != 0 && text[pos + pos2] != '/')
|
||||
pos2++;
|
||||
if (text[pos + pos2] == '\"')
|
||||
audio_pids.selected = atoi(&text[pos + pos2 + 1]);
|
||||
}
|
||||
|
||||
audio_pids.AudioPidName = "";
|
||||
//pos2 = strcspn(&text[pos],MI_XML_TAG_NAME);
|
||||
pos2 = -1;
|
||||
ptr = strstr(&text[pos], MI_XML_TAG_NAME);
|
||||
if (ptr)
|
||||
pos2 = (int)(ptr - &text[pos]);
|
||||
if (pos2 >= 0) {
|
||||
pos2 += sizeof(MI_XML_TAG_PID);
|
||||
while (text[pos + pos2] != '\"' && text[pos + pos2] != 0 && text[pos + pos2] != '/')
|
||||
pos2++;
|
||||
if (text[pos + pos2] == '\"') {
|
||||
int pos3 = pos2 + 1;
|
||||
while (text[pos + pos3] != '\"' && text[pos + pos3] != 0 && text[pos + pos3] != '/')
|
||||
pos3++;
|
||||
if (text[pos + pos3] == '\"')
|
||||
{
|
||||
audio_pids.AudioPidName.append(&text[pos + pos2 + 1], pos3 - pos2 - 1);
|
||||
audio_pids.AudioPidName = htmlEntityDecode(audio_pids.AudioPidName);
|
||||
}
|
||||
}
|
||||
}
|
||||
//printf("MOVIE INFO: apid %d type %d name %s selected %d\n", audio_pids.AudioPid, audio_pids.atype, audio_pids.AudioPidName.c_str(), audio_pids.selected);
|
||||
movie_info->audioPids.push_back(audio_pids);
|
||||
}
|
||||
/* parse bookmarks */
|
||||
GET_XML_DATA_INT(text, pos, MI_XML_TAG_BOOKMARK_START, movie_info->bookmarks.start)
|
||||
GET_XML_DATA_INT(text, pos, MI_XML_TAG_BOOKMARK_END, movie_info->bookmarks.end)
|
||||
GET_XML_DATA_INT(text, pos, MI_XML_TAG_BOOKMARK_LAST, movie_info->bookmarks.lastPlayStop)
|
||||
|
||||
if (bookmark_nr < MI_MOVIE_BOOK_USER_MAX) {
|
||||
if (strncmp(&text[pos], MI_XML_TAG_BOOKMARK_USER, sizeof(MI_XML_TAG_BOOKMARK_USER) - 1) == 0) {
|
||||
pos += sizeof(MI_XML_TAG_BOOKMARK_USER);
|
||||
//int pos2 = strcspn(&text[pos],MI_XML_TAG_BOOKMARK_USER_POS);
|
||||
if (strcspn(&text[pos], MI_XML_TAG_BOOKMARK_USER_POS) == 0) {
|
||||
int pos2 = 0;
|
||||
pos2 += sizeof(MI_XML_TAG_BOOKMARK_USER_POS);
|
||||
while (text[pos + pos2] != '\"' && text[pos + pos2] != 0 && text[pos + pos2] != '/')
|
||||
pos2++;
|
||||
if (text[pos + pos2] == '\"') {
|
||||
movie_info->bookmarks.user[bookmark_nr].pos = atoi(&text[pos + pos2 + 1]);
|
||||
|
||||
//pos2 = strcspn(&text[pos],MI_XML_TAG_BOOKMARK_USER_TYPE);
|
||||
pos++;
|
||||
while (text[pos + pos2] == ' ')
|
||||
pos++;
|
||||
if (strcspn(&text[pos], MI_XML_TAG_BOOKMARK_USER_TYPE) == 0) {
|
||||
pos2 += sizeof(MI_XML_TAG_BOOKMARK_USER_TYPE);
|
||||
while (text[pos + pos2] != '\"' && text[pos + pos2] != 0 && text[pos + pos2] != '/')
|
||||
pos2++;
|
||||
if (text[pos + pos2] == '\"') {
|
||||
movie_info->bookmarks.user[bookmark_nr].length = atoi(&text[pos + pos2 + 1]);
|
||||
|
||||
movie_info->bookmarks.user[bookmark_nr].name = "";
|
||||
//pos2 = ;
|
||||
if (strcspn(&text[pos], MI_XML_TAG_BOOKMARK_USER_NAME) == 0) {
|
||||
pos2 += sizeof(MI_XML_TAG_BOOKMARK_USER_NAME);
|
||||
while (text[pos + pos2] != '\"' && text[pos + pos2] != 0 && text[pos + pos2] != '/')
|
||||
pos2++;
|
||||
if (text[pos + pos2] == '\"') {
|
||||
int pos3 = pos2 + 1;
|
||||
while (text[pos + pos3] != '\"' && text[pos + pos3] != 0 && text[pos + pos3] != '/')
|
||||
pos3++;
|
||||
if (text[pos + pos3] == '\"')
|
||||
{
|
||||
movie_info->bookmarks.user[bookmark_nr].name.append(&text[pos + pos2 + 1], pos3 - pos2 - 1);
|
||||
movie_info->bookmarks.user[bookmark_nr].name = htmlEntityDecode(movie_info->bookmarks.user[bookmark_nr].name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else
|
||||
movie_info->bookmarks.user[bookmark_nr].length = 0;
|
||||
}
|
||||
bookmark_nr++;
|
||||
} else
|
||||
movie_info->bookmarks.user[bookmark_nr].pos = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (movie_info->epgInfo2.empty()) {
|
||||
movie_info->epgInfo2 = movie_info->epgInfo1;
|
||||
//movie_info->epgInfo1 = "";
|
||||
}
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
|
||||
bool CMovieInfo::addNewBookmark(MI_MOVIE_INFO * movie_info, MI_BOOKMARK & new_bookmark)
|
||||
{
|
||||
TRACE("[mi] addNewBookmark\n");
|
||||
|
||||
bool result = false;
|
||||
if (movie_info != NULL) {
|
||||
// search for free entry
|
||||
bool loop = true;
|
||||
for (int i = 0; i < MI_MOVIE_BOOK_USER_MAX && loop == true; i++) {
|
||||
if (movie_info->bookmarks.user[i].pos == 0) {
|
||||
// empty entry found
|
||||
result = true;
|
||||
loop = false;
|
||||
movie_info->bookmarks.user[i].pos = new_bookmark.pos;
|
||||
movie_info->bookmarks.user[i].length = new_bookmark.length;
|
||||
//if(movie_info->bookmarks.user[i].name.empty())
|
||||
if (movie_info->bookmarks.user[i].name.empty() ) {
|
||||
if (new_bookmark.length == 0)
|
||||
movie_info->bookmarks.user[i].name = g_Locale->getText(LOCALE_MOVIEBROWSER_BOOK_NEW);
|
||||
if (new_bookmark.length < 0)
|
||||
movie_info->bookmarks.user[i].name = g_Locale->getText(LOCALE_MOVIEBROWSER_BOOK_TYPE_BACKWARD);
|
||||
if (new_bookmark.length > 0)
|
||||
movie_info->bookmarks.user[i].name = g_Locale->getText(LOCALE_MOVIEBROWSER_BOOK_TYPE_FORWARD);
|
||||
} else {
|
||||
movie_info->bookmarks.user[i].name = new_bookmark.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
|
||||
void MI_MOVIE_INFO::clear(void)
|
||||
{
|
||||
tm timePlay;
|
||||
timePlay.tm_hour = 0;
|
||||
timePlay.tm_min = 0;
|
||||
timePlay.tm_sec = 0;
|
||||
timePlay.tm_year = 100;
|
||||
timePlay.tm_mday = 0;
|
||||
timePlay.tm_mon = 1;
|
||||
timePlay.tm_isdst = -1;
|
||||
|
||||
file.Name = "";
|
||||
file.Url = "";
|
||||
file.Size = 0; // Megabytes
|
||||
file.Time = mktime(&timePlay);
|
||||
dateOfLastPlay = mktime(&timePlay);
|
||||
dirItNr = 0;
|
||||
genreMajor = 0;
|
||||
genreMinor = 0;
|
||||
length = 0;
|
||||
rating = 0;
|
||||
quality = 0;
|
||||
productionDate = 0;
|
||||
parentalLockAge = 0;
|
||||
//format = 0;
|
||||
//audio = 0;
|
||||
|
||||
channelId = 0;
|
||||
epgId = 0;
|
||||
mode = 0;
|
||||
VideoPid = 0;
|
||||
VideoType = 0;
|
||||
VtxtPid = 0;
|
||||
|
||||
audioPids.clear();
|
||||
|
||||
productionCountry = "";
|
||||
epgTitle = "";
|
||||
epgInfo1 = "";
|
||||
epgInfo2 = "";
|
||||
channelName = "";
|
||||
serieName = "";
|
||||
bookmarks.end = 0;
|
||||
bookmarks.start = 0;
|
||||
bookmarks.lastPlayStop = 0;
|
||||
for (int i = 0; i < MI_MOVIE_BOOK_USER_MAX; i++) {
|
||||
bookmarks.user[i].pos = 0;
|
||||
bookmarks.user[i].length = 0;
|
||||
bookmarks.user[i].name = "";
|
||||
}
|
||||
tfile = "";
|
||||
|
||||
ytdate = "";
|
||||
ytid = "";
|
||||
ytitag = 0;
|
||||
|
||||
marked = false;
|
||||
delAsk = true;
|
||||
source = UNKNOWN;
|
||||
}
|
||||
|
||||
bool CMovieInfo::loadFile(CFile &file, std::string &buffer)
|
||||
{
|
||||
bool result = true;
|
||||
|
||||
int fd = open(file.Name.c_str(), O_RDONLY);
|
||||
if (fd == -1)
|
||||
{
|
||||
TRACE("[mi] loadFile: cannot open (%s)\n", file.Name.c_str());
|
||||
return false;
|
||||
}
|
||||
struct stat st;
|
||||
if (fstat(fd, &st)) {
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
char buf[st.st_size];
|
||||
if (st.st_size != read(fd, buf, st.st_size)) {
|
||||
TRACE("[mi] loadFile: cannot read (%s)\n", file.Name.c_str());
|
||||
result = false;
|
||||
} else
|
||||
buffer = std::string(buf, st.st_size);
|
||||
|
||||
close(fd);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool CMovieInfo::saveFile(const CFile & file, std::string &text)
|
||||
{
|
||||
bool result = false;
|
||||
int fd;
|
||||
if ((fd = open(file.Name.c_str(), O_SYNC | O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) >= 0) {
|
||||
write(fd, text.c_str(), text.size());
|
||||
//fdatasync(fd);
|
||||
close(fd);
|
||||
result = true;
|
||||
//TRACE("[mi] saved (%d)\n",nr);
|
||||
} else {
|
||||
TRACE("[mi] ERROR: cannot open\n");
|
||||
}
|
||||
return (result);
|
||||
}
|
187
src/driver/movieinfo.h
Normal file
187
src/driver/movieinfo.h
Normal file
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
movieinfo - Neutrino-GUI
|
||||
|
||||
Copyright (C) 2005 Günther <Günther@tuxbox.berlios.org>
|
||||
Copyright (C) 2015 Sven Hoefer (svenhoefer)
|
||||
|
||||
License: GPL
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef MOVIEINFO_H_
|
||||
#define MOVIEINFO_H_
|
||||
|
||||
#define __USE_FILE_OFFSET64 1
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <stdint.h>
|
||||
#include "driver/file.h"
|
||||
|
||||
/* XML tags for xml file*/
|
||||
#define MI_XML_TAG_NEUTRINO "neutrino"
|
||||
#define MI_XML_TAG_RECORD "record"
|
||||
#define MI_XML_TAG_CHANNELNAME "channelname"
|
||||
#define MI_XML_TAG_EPGTITLE "epgtitle"
|
||||
#define MI_XML_TAG_ID "id"
|
||||
#define MI_XML_TAG_INFO1 "info1"
|
||||
#define MI_XML_TAG_INFO2 "info2"
|
||||
#define MI_XML_TAG_EPGID "epgid"
|
||||
#define MI_XML_TAG_MODE "mode"
|
||||
#define MI_XML_TAG_VIDEOPID "videopid"
|
||||
#define MI_XML_TAG_VIDEOTYPE "videotype"
|
||||
#define MI_XML_TAG_AUDIOPIDS "audiopids"
|
||||
#define MI_XML_TAG_AUDIO "audio"
|
||||
#define MI_XML_TAG_PID "pid"
|
||||
#define MI_XML_TAG_NAME "name"
|
||||
#define MI_XML_TAG_ATYPE "audiotype"
|
||||
#define MI_XML_TAG_SELECTED "selected"
|
||||
#define MI_XML_TAG_VTXTPID "vtxtpid"
|
||||
#define MI_XML_TAG_GENRE_MAJOR "genremajor"
|
||||
#define MI_XML_TAG_GENRE_MINOR "genreminor"
|
||||
#define MI_XML_TAG_SERIE_NAME "seriename"
|
||||
#define MI_XML_TAG_LENGTH "length"
|
||||
#define MI_XML_TAG_PRODUCT_COUNTRY "productioncountry"
|
||||
#define MI_XML_TAG_PRODUCT_DATE "productiondate"
|
||||
#define MI_XML_TAG_RATING "rating"
|
||||
#define MI_XML_TAG_QUALITY "quality"
|
||||
#define MI_XML_TAG_QUALITIY "qualitiy" // just to keep compatibility to older xml-files
|
||||
#define MI_XML_TAG_PARENTAL_LOCKAGE "parentallockage"
|
||||
#define MI_XML_TAG_BOOKMARK "bookmark"
|
||||
#define MI_XML_TAG_BOOKMARK_START "bookmarkstart"
|
||||
#define MI_XML_TAG_BOOKMARK_END "bookmarkend"
|
||||
#define MI_XML_TAG_BOOKMARK_LAST "bookmarklast"
|
||||
#define MI_XML_TAG_BOOKMARK_USER "bookmarkuser"
|
||||
#define MI_XML_TAG_BOOKMARK_USER_POS "bookmarkuserpos"
|
||||
#define MI_XML_TAG_BOOKMARK_USER_TYPE "bookmarkusertype"
|
||||
#define MI_XML_TAG_BOOKMARK_USER_NAME "bookmarkusername"
|
||||
#define MI_XML_TAG_DATE_OF_LAST_PLAY "dateoflastplay"
|
||||
|
||||
#define MI_MAX_AUDIO_PIDS 4 // just to avoid the buffer is filled endless, might be increased later on , but 4 audio pids might be enough
|
||||
#define MI_MOVIE_BOOK_USER_MAX 20 // just to avoid the buffer is filled endless, might be increased later on. Make sure to increase the bookmark menu as well
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MI_PARENTAL_OVER0 = 0,
|
||||
MI_PARENTAL_OVER6 = 6,
|
||||
MI_PARENTAL_OVER12 = 12,
|
||||
MI_PARENTAL_OVER16 = 16,
|
||||
MI_PARENTAL_OVER18 = 18,
|
||||
MI_PARENTAL_ALWAYS = 99,
|
||||
MI_PARENTAL_MAX_NUMBER = 100
|
||||
} MI_PARENTAL_LOCKAGE;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int pos; // position in seconds from file start
|
||||
int length; // bookmark type, 0: just a bookmark, < 0 jump back (seconds), > 0 jump forward (seconds)
|
||||
std::string name; // bookmark name to be displayed
|
||||
} MI_BOOKMARK;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int start; // movie start in seconds from file start
|
||||
int end; // movie end in seconds from file start
|
||||
int lastPlayStop; // position of last play stop in seconds from file start
|
||||
MI_BOOKMARK user[MI_MOVIE_BOOK_USER_MAX]; // other user defined bookmarks
|
||||
} MI_MOVIE_BOOKMARKS;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int atype;
|
||||
int selected;
|
||||
int AudioPid; // audio pid nr, usually filled by VCR
|
||||
std::string AudioPidName; // audio pid name, usually filled by VCR
|
||||
} AUDIO_PIDS;
|
||||
|
||||
class MI_MOVIE_INFO //MI_MOVIE_INFO &operator=(const MI_MOVIE_INFO& src);
|
||||
{
|
||||
public:
|
||||
CFile file; // not stored in xml
|
||||
std::string productionCountry; // user defined Country (not from EPG yet, but might be possible)
|
||||
std::string epgTitle; // plain movie name, usually filled by EPG
|
||||
std::string epgInfo1; // used for Genre (Premiere) or second title, usually filled by EPG
|
||||
std::string epgInfo2; // detailed movie content, usually filled by EPG
|
||||
std::string channelName; // channel name, auto filled
|
||||
std::string serieName; // user defines series name
|
||||
|
||||
time_t dateOfLastPlay; // last play date of movie in seconds since 1970
|
||||
int dirItNr; // handle for quick directory path access only, this is not saved in xml, might be used by the owner of the movie info struct
|
||||
int genreMajor; // see showEPG class for more info, usually filled by EPG
|
||||
char genreMinor; // genreMinor not used so far
|
||||
int length; // movie length in minutes, usually filled by EPG
|
||||
int rating; // user rating (like IMDb rating; 75 means 7.5/10)
|
||||
int quality; // user classification (3 stars: classics, 2 stars: very good, 1 star: good, 0 stars: OK)
|
||||
int productionDate; // user defined Country (not from EPG yet, but might be possible)
|
||||
int parentalLockAge; // used for age rating(0:never,6,12,16,18 years,99:always), usually filled by EPG (if available)
|
||||
//char format; // currently not used
|
||||
//char audio; // currently not used
|
||||
MI_MOVIE_BOOKMARKS bookmarks; // bookmark collecton for this movie
|
||||
std::vector<AUDIO_PIDS> audioPids; // available AudioPids, usually filled by VCR. Note: Vectors are easy to is also using the heap (memory fragmentation), might be changed to array [MI_MAX_AUDIO_PIDS]
|
||||
|
||||
uint64_t channelId; // channel id, auto filled
|
||||
uint64_t epgId; // EPG id, usually filled by EPG
|
||||
int mode; // record mode (0: unknown; 1: tv record; 2: radio record)
|
||||
int VideoPid; // currently not used, we just do not want to loose this info if movie info is saved backed
|
||||
int VideoType;
|
||||
int VtxtPid; // currently not used, we just do not want to loose this info if movie info is saved backed
|
||||
|
||||
bool marked;
|
||||
bool delAsk;
|
||||
|
||||
std::string tfile; // thumbnail/cover file name
|
||||
|
||||
std::string ytdate; // youtube published
|
||||
std::string ytid; // youtube published
|
||||
int ytitag; // youtube quality profile
|
||||
|
||||
enum miSource {
|
||||
UNKNOWN = 0,
|
||||
YT,
|
||||
NK
|
||||
};
|
||||
miSource source;
|
||||
|
||||
void clear(void);
|
||||
MI_MOVIE_INFO() { clear(); }
|
||||
};
|
||||
|
||||
typedef std::vector<MI_MOVIE_INFO> MI_MOVIE_LIST;
|
||||
typedef std::vector<MI_MOVIE_INFO*> P_MI_MOVIE_LIST;
|
||||
|
||||
class CMovieInfo
|
||||
{
|
||||
public: // Functions
|
||||
CMovieInfo();
|
||||
~CMovieInfo();
|
||||
bool convertTs2XmlName(std::string &filename); // convert a ts file name in .xml file name
|
||||
bool loadMovieInfo(MI_MOVIE_INFO *movie_info, CFile *file = NULL ); // load movie information for the given .xml filename. If there is no filename, the filename (ts) from movie_info is converted to xml and used instead
|
||||
bool encodeMovieInfoXml(std::string *extMessage, MI_MOVIE_INFO *movie_info); // encode the movie_info structure to xml string
|
||||
bool saveMovieInfo(MI_MOVIE_INFO &movie_info, CFile *file = NULL ); // encode the movie_info structure to xml and save it to the given .xml filename. If there is no filename, the filename (ts) from movie_info is converted to xml and used instead
|
||||
bool addNewBookmark(MI_MOVIE_INFO *movie_info, MI_BOOKMARK &new_bookmark); // add a new bookmark to the given movie info. If there is no space false is returned
|
||||
|
||||
private: // Functions
|
||||
bool parseXmlTree(std::string &text, MI_MOVIE_INFO *movie_info);
|
||||
bool loadFile(CFile &file, std::string &buffer);
|
||||
bool saveFile(const CFile &file, std::string &buffer);
|
||||
};
|
||||
|
||||
#endif /*MOVIEINFO_H_*/
|
@@ -30,7 +30,7 @@
|
||||
#include <timerdclient/timerdtypes.h>
|
||||
|
||||
#include <neutrinoMessages.h>
|
||||
#include <gui/movieinfo.h>
|
||||
#include <driver/movieinfo.h>
|
||||
|
||||
#if HAVE_COOL_HARDWARE
|
||||
#include <record_cs.h>
|
||||
|
Reference in New Issue
Block a user