//
// aegis - project change supervisor
// Copyright (C) 2006-2009, 2011, 2012 Peter Miller
// Copyright (C) 2005 Matthew Lee;
// Copyright (C) 2007 Walter Franzini
//
// 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 3 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, see
// .
//
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
const nstring rss_script_name_placeholder("@@SCRIPTNAME@@");
nstring
rss_feed_filename(project *pp, const nstring &state)
{
change::pointer cp = pp->change_get();
if (!cp->is_a_branch())
return "";
if (!cp->is_being_developed())
return "";
// Get the project-specific attributes.
pconf_ty *pconf_data = project_pconf_get(pp);
if (pconf_data->project_specific != 0)
{
// We are only interested in those with the correct prefix.
const nstring feed_filename_prefix = "rss:feedfilename-";
for
(
size_t idx = 0;
idx < pconf_data->project_specific->length;
++idx
)
{
attributes_ty *ap = pconf_data->project_specific->list[idx];
if
(
ap->name != 0
&&
ap->name->str_length > feed_filename_prefix.size()
&&
(
0
==
strncasecmp
(
ap->name->str_text,
feed_filename_prefix.c_str(),
feed_filename_prefix.size()
)
)
)
{
// Does the project-specific attribute we've found contain
// the correct state?
if (0 != strstr(ap->value->str_text, state.c_str()))
{
// We've found an entry with the right prefix and state.
// What's the associated filename? Return the full path.
nstring path = project_rss_path_get(pp, 1);
path += "/";
path += ap->name->str_text + feed_filename_prefix.size();
return path;
}
}
}
}
return "";
}
static const char *
rss_feed_attr_to_str(enum rss_feed_attribute attribute)
{
switch (attribute)
{
case rss_feed_description:
return "description";
case rss_feed_title:
return "title";
case rss_feed_language:
return "language";
}
//
// By having this default outside the switch, it gives GCC the
// chance to tell us we forgot an enum.
//
return "unknown";
}
nstring
rss_feed_attribute(project *pp, const nstring &filename,
enum rss_feed_attribute attribute)
{
trace(("rss_feed_attribute(pp, \"%s\", %s)\n{\n",
filename.c_str(), rss_feed_attr_to_str(attribute)));
// Get the project-specific attributes.
pconf_ty *pconf_data = project_pconf_get(pp);
if (pconf_data->project_specific != 0)
{
// We are only interested in those with the correct prefix.
nstring feed_attr_prefix("rss:feed");
feed_attr_prefix += rss_feed_attr_to_str(attribute);
feed_attr_prefix += "-";
//
// Create the string for the feed_attr using os_basename since
// this function may receive the full path name of the xml file.
//
nstring feed_attr = feed_attr_prefix + os_basename(filename);
// Search through each project-specific attribute.
for
(
size_t idx = 0;
idx < pconf_data->project_specific->length;
++idx
)
{
attributes_ty *ap = pconf_data->project_specific->list[idx];
if
(
(ap->name != 0)
&&
(ap->name->str_length > feed_attr_prefix.size())
&&
(
0
==
strncasecmp
(
ap->name->str_text,
feed_attr.c_str(),
feed_attr.size()
)
)
)
{
trace(("return \"%s\";\n", ap->value->str_text));
trace(("}\n"));
return nstring(ap->value);
}
}
}
trace(("return \"\";\n"));
trace(("}\n"));
return "";
}
nstring
rss_get_project_url(project *pp)
{
nstring url = rss_script_name_placeholder;
url += "/";
url += nstring(project_name_get(pp));
return url;
}
void
rss_add_item_by_change(project *pp, change::pointer cp)
{
trace(("rss_add_item_by_change()\n{\n"));
cstate_ty *cstate_data = cp->cstate_get();
nstring feed_filename =
rss_feed_filename(pp, cstate_state_ename(cstate_data->state));
if (!feed_filename.empty())
{
rss_add_item(feed_filename, pp, cp);
}
trace(("}\n"));
}
void
rss_add_item(const nstring &filename, project *pp, change::pointer cp)
{
trace(("rss_add_item()\n{\n"));
cstate_ty *cstate_data = cp->cstate_get();
if (!cstate_data->brief_description)
cstate_data->brief_description = str_from_c("none");
if (!cstate_data->description)
cstate_data->description = str_from_c("none");
rss_feed feed(pp, cp, filename);
feed.channel_elements_from_project();
//
// Add a feed item based on the given change.
//
feed.channel_elements_from_change();
//
// Append the existing contents of the file.
// Make sure we don't ever have too many elements.
// Write the file back out.
//
// FIXME: the number of items in the feed (the 20 you see below)
// needs to be configurable.
//
feed.parse();
while (feed.size() > 20)
delete feed.pop_back();
feed.print();
trace(("}\n"));
}
// vim: set ts=8 sw=4 et :