⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 feedfile.cpp.svn-base

📁 wince c++ 下 开发的 rss 阅读器源代码
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
			sDescription = value;
		else if (name.Compare(_T("content:encoded")) == 0)
			sContent = value;
		else if (name.Compare(_T("dc:creator")) == 0 || name.Compare(_T("author")) == 0) {
			item->Author = value;
		}
#endif
		else if (name.Compare(_T("link")) == 0)
			item->Link = value;
		else if (name.Compare(_T("pubDate")) == 0 || name.Compare(_T("date")) == 0 || name.Compare(_T("dc:date")) == 0) {
			SYSTEMTIME st = { 0 };
			if (ConvertToSytemTime(value, &st))
				item->PubDate = st;
		}

#if defined PRSSR_APP
		// enclosure tag has no data in
		if (name.Compare(_T("enclosure")) == 0) {
			CEnclosureItem *enclosure = new CEnclosureItem;
			if (RSSFillEnclosure(childNode, enclosure)) {
				item->Enclosures.AddTail(enclosure);
			}
			else {
				delete enclosure;
			}
		}
#endif

	}

#if defined PRSSR_APP
	if (!sContent.IsEmpty())
		item->Description = SanitizeHtml(sContent, BaseUrl);
	else
		item->Description = SanitizeHtml(sDescription, BaseUrl);
#endif

#if defined PRSSR_APP
	// create date for proper sorting
	if (item->PubDate.wYear == 0)
		GetSystemTime(&item->PubDate);

	item->Date = item->PubDate;
	Sleep(1);				// ensure that items in a feed will differ at least by 1 ms
#endif

	if (item->Hash.IsEmpty())
		item->ComputeHash();

	return TRUE;
}

//
// RDF specific methods
//

BOOL CFeedFile::RDFFill(CFeed *feed, CSiteItem *si) {
	LOG0(5, "CFeedFile::RDFFill()");

	BOOL ret = FALSE;

	CList<CFeedItem *, CFeedItem *> feedList;

	POSITION pos = RootNode->GetFirstChildPos();
	while (pos != NULL) {
		CXmlNode *child = RootNode->GetNextChild(pos);

		CString tagName = child->GetName();
		if (tagName.Compare(_T("channel")) == 0) {
			ret = RSSFillInfo(child, feed);
		}
		else if (tagName.Compare(_T("item")) == 0) {
			CFeedItem *item = new CFeedItem(si);
			if (RSSFillItem(child, item))
				feedList.AddTail(item);
			else
				delete item;
		}
	}

	// copy from temp list to feed
	feed->SetSize(feedList.GetCount());
	int idx = 0;
	while (!feedList.IsEmpty())
		feed->SetAt(idx++, feedList.RemoveHead());

	return ret;
}

//
// RSS specific methods
//

BOOL CFeedFile::RSSFill(CFeed *feed, CSiteItem *si) {
	LOG0(5, "CFeedFile::RSSFill()");

	BOOL ret = FALSE;
	POSITION pos;

	// root tag is <rss>
	pos = RootNode->GetFirstAttrPos();
	while (pos != NULL) {
		CXmlAttr *attr = RootNode->GetNextAttr(pos);
		if (attr->GetName().CompareNoCase(_T("xml:base")) == 0) {
			BaseUrl = attr->GetValue();
		}
	}

	// get channel tag
	pos = RootNode->GetFirstChildPos();
	if (pos != NULL) {
		CXmlNode *channel = RootNode->GetNextChild(pos);

		CString tagName = channel->GetName();
		if (tagName.Compare(_T("channel")) == 0) {
			ret = RSSFillInfo(channel, feed);

			// item list
			CList<CFeedItem *, CFeedItem *> feedList;
			POSITION posItem = channel->GetFirstChildPos();
			while (posItem != NULL) {
				CXmlNode *child = channel->GetNextChild(posItem);

				CString tagName = child->GetName();
				if (tagName.Compare(_T("item")) == 0) {
					CFeedItem *item = new CFeedItem(si);
					if (RSSFillItem(child, item))
						feedList.AddTail(item);
					else
						delete item;
				}
			}

			// copy from temp list to feed
			feed->SetSize(feedList.GetCount());
			int idx = 0;
			while (!feedList.IsEmpty())
				feed->SetAt(idx++, feedList.RemoveHead());
		}
	}

	return ret;
}

#if defined PRSSR_APP

static EEnclosureType GetEnclosureType(const CString &type) {
	int nPos = type.Find('/');
	if (nPos != -1) {
		CString sType = type.Left(nPos);
		if (sType.CompareNoCase(_T("video")) == 0) return ENCLOSURE_TYPE_VIDEO;
		else if (sType.CompareNoCase(_T("audio")) == 0) return ENCLOSURE_TYPE_AUDIO;
		else if (sType.CompareNoCase(_T("image")) == 0) return ENCLOSURE_TYPE_IMAGE;
		else return ENCLOSURE_TYPE_UNKNOWN;
	}
	else return ENCLOSURE_TYPE_UNKNOWN;
}

BOOL CFeedFile::RSSFillEnclosure(CXmlNode *xmlElem, CEnclosureItem *enclosure) {
	LOG0(5, "CFeedFile::RSSFillEnclosure()");

	BOOL ret = FALSE;

	CString url, type;
	long length = 0;
	POSITION pos = xmlElem->GetFirstAttrPos();
	while (pos != NULL) {
		CXmlAttr *attr = xmlElem->GetNextAttr(pos);

		CString attrName = attr->GetName();
		if (attrName.Compare(_T("url")) == 0)
			url = attr->GetValue();
		else if (attrName.Compare(_T("length")) == 0)
			swscanf(attr->GetValue(), _T("%ld"), &length);
		else if (attrName.Compare(_T("type")) == 0)
			type = attr->GetValue();
	}

	// set read values
	if (!url.IsEmpty() && !type.IsEmpty()) {
		enclosure->URL = url;
		if (length < 0) length = 0;
		enclosure->Length = length;
		enclosure->Type = GetEnclosureType(type);

		ret = TRUE;
	}

	return ret;
}

#endif

//
// Atom specific methods
//

BOOL CFeedFile::AtomFill(CFeed *feed, CSiteItem *si) {
	LOG0(5, "CFeedFile::AtomFill()");

	BOOL ret = AtomFillInfo(RootNode, feed);

	// item list
	CList<CFeedItem *, CFeedItem *> feedList;
	POSITION posItem = RootNode->GetFirstChildPos();
	while (posItem != NULL) {
		CXmlNode *child = RootNode->GetNextChild(posItem);

		CString tagName = child->GetName();
		if (tagName.Compare(_T("entry")) == 0) {
			CFeedItem *item = new CFeedItem(si);
			if (AtomFillItem(child, item))
				feedList.AddTail(item);
			else
				delete item;
		}
	}

	// copy from temp list to feed
	feed->SetSize(feedList.GetCount());
	int idx = 0;
	while (!feedList.IsEmpty())
		feed->SetAt(idx++, feedList.RemoveHead());

	return ret;
}


BOOL CFeedFile::AtomFillInfo(CXmlNode *xmlElem, CFeed *feed) {
	LOG0(5, "CFeedFile::AtomFillInfo()");

	BOOL ret = FALSE;

	POSITION pos = xmlElem->GetFirstChildPos();
	while (pos != NULL) {
		CXmlNode *child = xmlElem->GetNextChild(pos);

		CString name = child->GetName();
		if (name.Compare(_T("title")) == 0) {
			feed->Title = child->GetValue();
			ret = TRUE;
		}
#if defined PRSSR_APP
		else if (name.Compare(_T("copyright")) == 0)
			feed->Copyright = child->GetValue();
		else if (name.Compare(_T("tagline")) == 0 || name.Compare(_T("subtitle")) == 0)
			feed->Description = child->GetValue();
		else if (name.Compare(_T("link")) == 0) {
			CString rel, type, href;
			POSITION posAttr = child->GetFirstAttrPos();
			while (posAttr != NULL) {
				CXmlAttr *attr = child->GetNextAttr(posAttr);

				CString attrName = attr->GetName();
				if (attrName.Compare(_T("rel")) == 0)
					rel = attr->GetValue();
				else if (attrName.Compare(_T("type")) == 0)
					type = attr->GetValue();
				else if (attrName.Compare(_T("href")) == 0)
					href = attr->GetValue();
			}


			// href value of tag with attribute type="text/html" and rel="alternate" (0.3) or rel empty)
			if ((rel.Compare(_T("alternate")) == 0 || rel.IsEmpty()) &&
				type.Compare(_T("text/html")) == 0)
				feed->HtmlUrl = href;
		}
#endif
	}

	return ret;
}

#ifdef PRSSR_APP
BOOL CFeedFile::AtomFillPerson(CXmlNode *xmlItem, CString &name) {
	LOG0(5, "CFeedFile::AtomFillPerson()");

	POSITION pos = xmlItem->GetFirstChildPos();
	while (pos != NULL) {
		CXmlNode *child = xmlItem->GetNextChild(pos);

		CString tag = child->GetName();
		if (tag.Compare(_T("name")) == 0)
			name = child->GetValue();
	}

	return TRUE;
}
#endif

BOOL CFeedFile::AtomFillItem(CXmlNode *xmlItem, CFeedItem *item) {
	LOG0(5, "CFeedFile::AtomFillItem()");

	SYSTEMTIME issued = { 0 };
	SYSTEMTIME created = { 0 };
	SYSTEMTIME modified = { 0 };
	SYSTEMTIME updated = { 0 };
	SYSTEMTIME published = { 0 };
	CString summary, content;
	CString itemId;

	DWORD flagsMask = 0;
	DWORD flags = 0;

	POSITION pos = xmlItem->GetFirstChildPos();
	while (pos != NULL) {
		CXmlNode *child = xmlItem->GetNextChild(pos);

		CString name = child->GetName();

		if (name.Compare(_T("title")) == 0) {
			CString value = child->GetValue();
			value.Remove('\r');
			value.Remove('\n');
			item->Title = StripHtmlTags(value);
		}
#if defined PRSSR_APP
		else if (wcscmp(name, _T("content")) == 0) {
			content = child->GetXML();
		}
		else if (wcscmp(name, _T("summary")) == 0) {
			summary = child->GetXML();
		}
		else if (wcscmp(name, _T("author")) == 0) {
			BOOL knownAuthor = TRUE;

			POSITION posAttr = child->GetFirstAttrPos();
			while (posAttr != NULL) {
				CXmlAttr *attr = child->GetNextAttr(posAttr);
				CString attrName = attr->GetName();
				CString attrVal = attr->GetValue();

				// GoogleReader specific
				if (attrName.Compare(_T("gr:unknown-author")) == 0 && attrVal.CompareNoCase(_T("true")) == 0)
					knownAuthor = FALSE;
			}

			if (knownAuthor)
				AtomFillPerson(child, item->Author);
		}
		// GoogleReader specific
		else if (wcscmp(name, _T("category")) == 0) {
			CString term, label;

			POSITION posAttr = child->GetFirstAttrPos();
			while (posAttr != NULL) {
				CXmlAttr *attr = child->GetNextAttr(posAttr);
				CString attrName = attr->GetName();
				if (attrName.Compare(_T("term")) == 0) term = attr->GetValue();
				else if (attrName.Compare(_T("label")) == 0) label = attr->GetValue();
			}

			if (term.Right(11).Compare(_T("kept-unread")) == 0 && label.Compare(_T("kept-unread")) == 0) { flagsMask |= MESSAGE_READ_STATE; flags |= MESSAGE_UNREAD; }
			else if (term.Right(4).Compare(_T("read")) == 0 && label.Compare(_T("read")) == 0) { flagsMask |= MESSAGE_READ_STATE; flags &= ~MESSAGE_READ_STATE; }
			else if (term.Right(7).Compare(_T("starred")) == 0 && label.Compare(_T("starred")) == 0) { flagsMask |= MESSAGE_FLAG; flags |= MESSAGE_FLAG; }
		}
		// GoogleReader specific
		else if (wcscmp(name, _T("id")) == 0) {
			itemId = child->GetValue();
		}
#endif
		else if (wcscmp(name, _T("link")) == 0) {
			CString rel, type, href;
			long length;
			POSITION posAttr = child->GetFirstAttrPos();
			while (posAttr != NULL) {
				CXmlAttr *attr = child->GetNextAttr(posAttr);

				CString attrName = attr->GetName();
				if (attrName.Compare(_T("rel")) == 0)
					rel = attr->GetValue();
				else if (attrName.Compare(_T("type")) == 0)
					type = attr->GetValue();
				else if (attrName.Compare(_T("href")) == 0)
					href = attr->GetValue();
				else if (attrName.Compare(_T("length")) == 0)
					swscanf(attr->GetValue(), _T("%ld"), &length);
			}


			// href value of tag with attributes rel="alternate" and type="text/html"
			if (rel.Compare(_T("alternate")) == 0 && type.Compare(_T("text/html")) == 0)
				item->Link = href;
			else if (rel.Compare(_T("enclosure")) == 0) {
				if (!href.IsEmpty() && !type.IsEmpty()) {
					CEnclosureItem *enclosure = new CEnclosureItem;

					enclosure->URL = href;
					if (length < 0) length = 0;
					enclosure->Length = length;
					enclosure->Type = GetEnclosureType(type);
					item->Enclosures.AddTail(enclosure);
				}
			}
		}
		else if (name.Compare(_T("issued")) == 0)
			ConvertToSytemTime(child->GetValue(), &issued);
		else if (name.Compare(_T("updated")) == 0)
			ConvertToSytemTime(child->GetValue(), &updated);
		else if (name.Compare(_T("modified")) == 0)
			ConvertToSytemTime(child->GetValue(), &modified);
		else if (name.Compare(_T("created")) == 0)
			ConvertToSytemTime(child->GetValue(), &created);
		else if (name.Compare(_T("published")) == 0)
			ConvertToSytemTime(child->GetValue(), &published);
	}

	if (issued.wYear != 0)
		item->PubDate = issued;
	else if (updated.wYear != 0)
		item->PubDate = updated;
	else if (modified.wYear != 0)
		item->PubDate = modified;
	else if (published.wYear != 0)
		item->PubDate = updated;
	else if (created.wYear != 0)
		item->PubDate = created;

#if defined PRSSR_APP
	// GoogleReader specific
	if (flagsMask != 0)
		item->SetFlags(flags, flagsMask);
	if (itemId.IsEmpty())
		item->ComputeHash();
	else
		item->Hash = itemId;


	// create date for proper sorting
	if (item->PubDate.wYear == 0)
		GetSystemTime(&item->PubDate);

	item->Date = item->PubDate;
	Sleep(1);
#endif

#if defined PRSSR_APP
	// if <content> is empty, then use <summary>
	if (!content.IsEmpty())
		item->Description = SanitizeHtml(content, BaseUrl);
	else
		item->Description = SanitizeHtml(summary, BaseUrl);
#endif

	return TRUE;
}

#if defined PRSSR_APP

static CString SanitizeHtml(const CString &html, const CString &baseUrl) {
	// sanitize HTML
	CLocalHtmlFile file(baseUrl);
	CString s;

	s.Format(_T("<div>%s</div>"), html);		// libsgml workaround
	file.LoadFromMemory(s);
	file.Filter();
	file.RewriteRelativeUrls();

	return file.ToString();

}

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -