std::string AptCacheFile::getLongDescription(const pkgCache::VerIterator &ver) { if (ver.end() || ver.FileList().end() || GetPkgRecords() == 0) { return string(); } pkgCache::DescIterator d = ver.TranslatedDescription(); if (d.end()) { return string(); } pkgCache::DescFileIterator df = d.FileList(); if (df.end()) { return string(); } else { return m_packageRecords->Lookup(df).LongDesc(); } }
string fetchChangelogData(AptCacheFile &CacheFile, pkgAcquire &Fetcher, pkgCache::VerIterator Ver, pkgCache::VerIterator currver, string *update_text, string *updated, string *issued) { string changelog; pkgAcqChangelog *c = new pkgAcqChangelog(&Fetcher, Ver); // try downloading it, if that fails, try third-party-changelogs location // FIXME: Fetcher.Run() is "Continue" even if I get a 404?!? Fetcher.Run(); // error pkgRecords Recs(CacheFile); pkgCache::PkgIterator Pkg = Ver.ParentPkg(); pkgRecords::Parser &rec=Recs.Lookup(Ver.FileList()); string srcpkg = rec.SourcePkg().empty() ? Pkg.Name() : rec.SourcePkg(); changelog = "Changelog for this version is not yet available"; // return empty string if we don't have a file to read if (!FileExists(c->DestFile)) { return changelog; } if (_error->PendingError()) { return changelog; } ifstream in(c->DestFile.c_str()); string line; g_autoptr(GRegex) regexVer = NULL; regexVer = g_regex_new("(?'source'.+) \\((?'version'.*)\\) " "(?'dist'.+); urgency=(?'urgency'.+)", G_REGEX_CASELESS, G_REGEX_MATCH_ANCHORED, 0); g_autoptr(GRegex) regexDate = NULL; regexDate = g_regex_new("^ -- (?'maintainer'.+) (?'mail'<.+>) (?'date'.+)$", G_REGEX_CASELESS, G_REGEX_MATCH_ANCHORED, 0); changelog = ""; while (getline(in, line)) { // we don't want the additional whitespace, because it can confuse // some markdown parsers used by client tools if (starts_with(line, " ")) line.erase(0,1); // no need to free str later, it is allocated in a static buffer const char *str = utf8(line.c_str()); if (strcmp(str, "") == 0) { changelog.append("\n"); continue; } else { changelog.append(str); changelog.append("\n"); } if (starts_with(str, srcpkg.c_str())) { // Check to see if the the text isn't about the current package, // otherwise add a == version == GMatchInfo *match_info; if (g_regex_match(regexVer, str, G_REGEX_MATCH_ANCHORED, &match_info)) { gchar *version; version = g_match_info_fetch_named(match_info, "version"); // Compare if the current version is shown in the changelog, to not // display old changelog information if (_system != 0 && _system->VS->DoCmpVersion(version, version + strlen(version), currver.VerStr(), currver.VerStr() + strlen(currver.VerStr())) <= 0) { g_free (version); break; } else { if (!update_text->empty()) { update_text->append("\n\n"); } update_text->append(" == "); update_text->append(version); update_text->append(" =="); g_free (version); } } g_match_info_free (match_info); } else if (starts_with(str, " ")) { // update descritption update_text->append("\n"); update_text->append(str); } else if (starts_with(str, " --")) { // Parse the text to know when the update was issued, // and when it got updated GMatchInfo *match_info; if (g_regex_match(regexDate, str, G_REGEX_MATCH_ANCHORED, &match_info)) { GTimeVal dateTime = {0, 0}; gchar *date; date = g_match_info_fetch_named(match_info, "date"); time_t time; g_warn_if_fail(RFC1123StrToTime(date, time)); dateTime.tv_sec = time; g_free(date); *issued = g_time_val_to_iso8601(&dateTime); if (updated->empty()) { *updated = g_time_val_to_iso8601(&dateTime); } } g_match_info_free(match_info); } } return changelog; }