📄 feed.cpp.svn-base
字号:
else if (strncmp(hdr.Id, "FRMT", 4) == 0)
ReadString(file, hdr.Size, Format);
else if (strncmp(hdr.Id, "UPIN", 4) == 0)
ReadNumber(file, UpdateInterval);
#endif
else
file.Seek(hdr.Size, FILE_CURRENT);
remain -= hdr.Size;
}
// load ITMS
if (!header.Load(file) || strncmp(header.Id, "ITMS", 4) != 0)
return FALSE;
// LOG0(5, "- loading items");
BOOL ok = TRUE;
DWORD remainItems = header.Size;
while (remainItems > 0) {
CArchiveFileChunkHeader hdrItem;
if (!hdrItem.Load(file) || strncmp(hdrItem.Id, "ITEM", 4) != 0)
return FALSE;
remainItems -= 8;
// LOG0(5, "- loading item");
// load item
BOOL itemOK = TRUE;
CFeedItem feedItem(si);
remain = hdrItem.Size;
while (remain > 0 && itemOK) {
CArchiveFileChunkHeader hdr;
if (!hdr.Load(file)) {
itemOK = FALSE;
break;
}
remain -= 8;
if (strncmp(hdr.Id, "TITL", 4) == 0)
ReadString(file, hdr.Size, feedItem.Title);
else if (strncmp(hdr.Id, "LINK", 4) == 0)
ReadString(file, hdr.Size, feedItem.Link);
else if (strncmp(hdr.Id, "FLGS", 4) == 0)
ReadNumber(file, feedItem.Flags);
else if (strncmp(hdr.Id, "TIME", 4) == 0)
ReadSystemTime(file, feedItem.PubDate);
else if (strncmp(hdr.Id, "ID ", 4) == 0)
ReadString(file, hdr.Size, feedItem.Hash);
#ifdef PRSSR_APP
else if (strncmp(hdr.Id, "DESC", 4) == 0)
ReadString(file, hdr.Size, feedItem.Description);
else if (strncmp(hdr.Id, "AUTH", 4) == 0)
ReadString(file, hdr.Size, feedItem.Author);
else if (strncmp(hdr.Id, "ENCS", 4) == 0) {
// read enclosures
DWORD remainEncsItems = hdr.Size;
while (remainEncsItems > 0) {
CArchiveFileChunkHeader enitItem;
if (enitItem.Load(file)) {
remainEncsItems -= 8;
if (strncmp(enitItem.Id, "ENIT", 4) == 0) {
// load enclosures
BOOL encOK = TRUE;
CEnclosureItem ei;
DWORD remainEnclosures = enitItem.Size;
while (remainEnclosures > 0) {
CArchiveFileChunkHeader hdrEnc;
if (!hdrEnc.Load(file)) {
encOK = FALSE;
break;
}
remainEnclosures -= 8; // sizeof(header)
if (strncmp(hdrEnc.Id, "URL ", 4) == 0)
ReadString(file, hdrEnc.Size, ei.URL);
else if (strncmp(hdrEnc.Id, "TYPE", 4) == 0) {
CString sMime;
// convert from older format
ReadString(file, hdrEnc.Size, sMime);
int nPos = sMime.Find('/');
if (nPos != -1) {
CString sType = sMime.Left(nPos);
if (sType.CompareNoCase(_T("video")) == 0) ei.Type = ENCLOSURE_TYPE_VIDEO;
else if (sType.CompareNoCase(_T("audio")) == 0) ei.Type = ENCLOSURE_TYPE_AUDIO;
else if (sType.CompareNoCase(_T("image")) == 0) ei.Type = ENCLOSURE_TYPE_IMAGE;
else ei.Type = ENCLOSURE_TYPE_UNKNOWN;
}
else ei.Type = ENCLOSURE_TYPE_UNKNOWN;
}
else if (strncmp(hdrEnc.Id, "ETYP", 4) == 0) {
DWORD encType;
ReadNumber(file, encType);
ei.Type = (EEnclosureType) encType;
}
else if (strncmp(hdrEnc.Id, "LENG", 4) == 0)
ReadNumber(file, ei.Length);
else
file.Seek(hdrEnc.Size, FILE_CURRENT);
remainEnclosures -= hdrEnc.Size;
} // while
if (encOK)
feedItem.Enclosures.AddTail(new CEnclosureItem(ei));
}
else
file.Seek(enitItem.Size, FILE_CURRENT);
}
else
break;
remainEncsItems -= enitItem.Size;
}
}
else if (strncmp(hdr.Id, "KWDS", 4) == 0) {
ReadIntArray(file, hdr.Size, feedItem.KeywordPos);
}
#endif
else
file.Seek(hdr.Size, FILE_CURRENT);
remain -= hdr.Size;
} // while
if (itemOK) {
#ifdef PRSSR_APP
if (feedItem.Hash.IsEmpty())
feedItem.ComputeHash();
// fill Date
feedItem.Date = feedItem.PubDate;
// fill milisecond field (crucial for proper sorting)
feedItem.Date.wMilliseconds = (WORD) (GetTickCount() & 0xFFFF);
Sleep(1);
#endif
Items.Add(new CFeedItem(feedItem));
}
else {
ok = FALSE;
break;
}
remainItems -= hdrItem.Size;
}
file.Close();
// LOG1(5, "- state: %d", ok);
return ok;
}
#ifdef PRSSR_APP
BOOL CFeed::Save(LPCTSTR fileName) {
LOG1(5, "CFeed::Save('%S')", fileName);
CBufferedFile file;
if (!file.Create(fileName, GENERIC_WRITE, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL))
return FALSE;
// id (PRSS)
CArchiveFileChunk *root = new CArchiveFileChunk("PRSS");
// header (HEAD)
CArchiveFileChunk *head = new CArchiveFileChunk("HEAD");
head->Add("TITL", Title);
head->Add("LINK", HtmlUrl);
head->Add("DESC", Description);
// TODO: image (IMAG)
head->Add("UPIN", UpdateInterval);
head->Add("PUBL", Published);
head->Add("LANG", Language);
head->Add("FRMT", Format);
root->Add(head);
if (Items.GetSize() > 0) {
// items (ITMS)
CArchiveFileChunk *items = new CArchiveFileChunk("ITMS");
for (int i = 0; i < Items.GetSize(); i++) {
CFeedItem *fi = Items.GetAt(i);
CArchiveFileChunk *itm = new CArchiveFileChunk("ITEM");
itm->Add("FLGS", fi->Flags);
if (fi->IsDeleted()) {
itm->Add("ID ", fi->Hash);
}
else {
itm->Add("TITL", fi->Title);
itm->Add("DESC", fi->Description);
itm->Add("LINK", fi->Link);
itm->Add("AUTH", fi->Author);
itm->Add("TIME", fi->PubDate);
itm->Add("ID ", fi->Hash);
if (fi->Enclosures.GetCount() > 0) {
// enclosures
CArchiveFileChunk *enclosures = new CArchiveFileChunk("ENCS");
POSITION pos = fi->Enclosures.GetHeadPosition();
while (pos != NULL) {
CEnclosureItem *ei = fi->Enclosures.GetNext(pos);
CArchiveFileChunk *eitm = new CArchiveFileChunk("ENIT");
eitm->Add("URL ", ei->URL);
eitm->Add("ETYP", ei->Type);
eitm->Add("LENG", ei->Length);
enclosures->Add(eitm);
}
itm->Add(enclosures);
}
// keywords
itm->Add("KWDS", fi->KeywordPos);
}
items->Add(itm);
}
root->Add(items);
}
root->CalcSize();
root->Save(file);
delete root;
file.Close();
return TRUE;
}
#endif
//
void CFeed::Detach() {
LOG0(5, "CFeed::Detach()");
Items.RemoveAll();
}
void CFeed::Destroy() {
LOG0(5, "CFeed::Destroy()");
for (int i = 0; i < Items.GetSize(); i++)
delete Items.GetAt(i);
Items.RemoveAll();
}
int CFeed::GetUnreadCount() const {
int count = 0;
for (int i = 0; i < GetItemCount(); i++) {
CFeedItem *fi = Items.GetAt(i);
if (!fi->IsDeleted() && fi->IsUnread())
count++;
}
return count;
}
int CFeed::GetNewCount() const {
int count = 0;
for (int i = 0; i < GetItemCount(); i++) {
CFeedItem *fi = Items.GetAt(i);
if (!fi->IsDeleted() && fi->IsNew())
count++;
}
return count;
}
int CFeed::GetFlaggedCount() const {
int count = 0;
for (int i = 0; i < GetItemCount(); i++) {
CFeedItem *fi = Items.GetAt(i);
if (!fi->IsDeleted() && fi->IsFlagged())
count++;
}
return count;
}
#if defined PRSSR_APP
/*
void CFeed::GetPlaylistItems(CList<CPlaylistItem*, CPlaylistItem*> &list, DWORD limit/* = 0*//*) {
LOG0(5, "CFeed::GetPlaylistItems()");
// collect enclosures
for (int i = 0; i < GetItemCount(); i++) {
CFeedItem *fi = GetItem(i);
POSITION pos = fi->Enclosures.GetHeadPosition();
while (pos != NULL) {
CEnclosureItem *enclosure = fi->Enclosures.GetNext(pos);
if (enclosure->Type.Left(5).CompareNoCase(_T("audio")) == 0 ||
enclosure->Type.Left(5).CompareNoCase(_T("video")) == 0)
{
if (limit == 0 || enclosure->Length <= limit) {
CString url = MakeOnlineFile(enclosure->URL, _T(""), _T(""));
CString outFileName = UrlToFileName(url, Config.EnclosuresLocation);
if (FileExists(outFileName)) {
// add only cached items
list.AddTail(new CPlaylistItem(fi->Title, outFileName));
}
}
}
}
}
}
BOOL CFeed::GenerateASX(const CString &strFileName, DWORD limit) {
LOG2(5, "CFeed::GenerateASX('%S', %d)", strFileName, limit);
// collect enclosures
CList<CPlaylistItem *, CPlaylistItem *> list;
GetPlaylistItems(list, limit);
// got no enclosures -> exit
if (list.GetCount() <= 0)
return TRUE;
// generate ASX
CString strASXFileName = strFileName;
if (strASXFileName.Right(4).CompareNoCase(_T(".xml")) == 0) {
strASXFileName = strASXFileName.Left(strASXFileName.GetLength() - 4) + _T(".asx");
}
else {
strASXFileName += _T(".asx");
}
BOOL ret = TRUE;
CString strPathFileName = FormatFilePath(Config.EnclosuresLocation, strASXFileName);
CBufferedFile file;
if (file.Create(strPathFileName, GENERIC_WRITE, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL)) {
ret = WriteFileString(file, _T("<asx version=\"3.0\">\n"), CP_ACP);
// enclosures
POSITION pos = list.GetHeadPosition();
while (pos != NULL) {
CPlaylistItem *pi = list.GetNext(pos);
ret = ret ? WriteFileString(file, _T("\t<entry>\n"), CP_ACP) : FALSE;
CString strTitle;
strTitle.Format(_T("\t\t<title>%s</title>\n"), pi->Title);
ret = ret ? WriteFileString(file, strTitle, CP_ACP) : FALSE;
CString strRef;
strRef.Format(_T("\t\t<ref href=\"%s\" />\n"), pi->FileName);
ret = ret ? WriteFileString(file, strRef, CP_ACP) : FALSE;
ret = ret ? WriteFileString(file, _T("\t</entry>\n"), CP_ACP) : FALSE;
}
ret = ret ? WriteFileString(file, _T("</asx>\n"), CP_ACP) : FALSE;
file.Close();
}
else
ret = FALSE;
while (!list.IsEmpty())
delete list.RemoveHead();
return ret;
}
BOOL CFeed::GenerateM3U(const CString &strFileName, DWORD limit) {
LOG2(5, "CFeed::GenerateM3U('%S', %d)", strFileName, limit);
// collect enclosures
CList<CPlaylistItem *, CPlaylistItem *> list;
GetPlaylistItems(list, limit);
// got no enclosures -> exit
if (list.GetCount() <= 0)
return TRUE;
// generate M3U
CString strM3UFileName = strFileName;
if (strM3UFileName.Right(4).CompareNoCase(_T(".xml")) == 0) {
strM3UFileName = strM3UFileName.Left(strM3UFileName.GetLength() - 4) + _T(".m3u");
}
else {
strM3UFileName += _T(".m3u");
}
BOOL ret = TRUE;
CString strPathFileName = FormatFilePath(Config.EnclosuresLocation, strM3UFileName);
CBufferedFile file;
if (file.Create(strPathFileName, GENERIC_WRITE, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL)) {
ret = ret ? WriteFileString(file, _T("#EXTM3U\n"), CP_ACP) : FALSE;
// enclosures
POSITION pos = list.GetHeadPosition();
while (pos != NULL) {
CPlaylistItem *pi = list.GetNext(pos);
CString strINF;
strINF.Format(_T("#EXTINF:,%s\n"), pi->Title);
ret = ret ? WriteFileString(file, strINF, CP_ACP) : FALSE;
CString strFile;
strFile.Format(_T("%s\n"), pi->FileName);
ret = ret ? WriteFileString(file, strFile, CP_ACP) : FALSE;
}
file.Close();
}
else
ret = FALSE;
while (!list.IsEmpty())
delete list.RemoveHead();
return ret;
}
*/
#endif
#ifdef PRSSR_APP
void CFeed::UpdateHiddenFlags() {
LOG0(5, "CFeed::UpdateHiddenFlags()");
for (int i = 0; i < GetItemCount(); i++)
GetItem(i)->UpdateHiddenFlag();
}
void CFeed::MarkAll(DWORD flag, DWORD mask) {
LOG1(5, "CFeed::MarkAll(%d)", flag);
for (int i = 0; i < GetItemCount(); i++) {
CFeedItem *fi = GetItem(i);
fi->SetFlags(flag, mask);
fi->UpdateHiddenFlag();
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -