/******************************************************************************
 * mod_uploader / RssView.cpp
 ******************************************************************************
 * Copyright (C) 2005 Tetsuya Kimata <kimata@acapulco.dyndns.org>
 *
 * All rights reserved.
 *
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the authors be held liable for any
 * damages arising from the use of this software.
 *
 * Permission is granted to anyone to use this software for any
 * purpose, including commercial applications, and to alter it and
 * redistribute it freely, subject to the following restrictions:
 *
 * 1. The origin of this software must not be misrepresented; you must
 *    not claim that you wrote the original software. If you use this
 *    software in a product, an acknowledgment in the product
 *    documentation would be appreciated but is not required.
 *
 * 2. Altered source versions must be plainly marked as such, and must
 *    not be misrepresented as being the original software.
 *
 * 3. This notice may not be removed or altered from any source
 *    distribution.
 *
 * $Id: UploadItemList.cpp 148 2005-03-19 03:57:09Z svn $
 *****************************************************************************/

// RSS は他の部分に比べて頻繁にアクセスされる可能性があるので，テンプレー
// ト機能を使わずハードコーディングしてます．

#include "RssView.h"
#include "TemplateVariableCreator.h"
#include "Misc.h"

#include "http_protocol.h"

#include <memory>

#ifdef DEBUG
#include <iostream>
#endif

const char RssView::content_type[]          = "application/xml";
const char RssView::image_type_prefix[]     = "image";
const apr_size_t RssView::MAX_TIME_LENGTH   = 64;
const char RssView::TIME_FORMAT[]           = "%Y-%m-%dT%H:%M:%S" TIMEZONE_OFFSET;
const apr_size_t RssView::TIME_ZONE_OFFSET  = UITEM_TIME_ZONE_OFFSET;


/******************************************************************************
 * public メソッド
 *****************************************************************************/
void RssView::exec(apr_pool_t *pool, request_rec *request, const char *base_url,
                   UploadItemList *item_list, apr_size_t per_page_item_number)
{
    UploadItemList::item_info **items;
    UploadItemList::item_info **item;
    handle h(pool, request, base_url);

    items = item_list->to_array(pool, 0, per_page_item_number);

    print(&h, "<?xml version=\"1.0\" encoding=\"EUC-JP\"?>\n");
    print(&h, "<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n");
    print(&h, "         xmlns=\"http://purl.org/rss/1.0/\"\n");
    print(&h, "         xmlns:dc=\"http://purl.org/dc/elements/1.1/\">\n");
    print(&h, " <channel rdf:about=\""); print(&h, base_url); print(&h, "\">\n");
    print(&h, "  <title>"); print(&h, "mod_uploader"); print(&h, "</title>\n");
    print(&h, "  <link>"); print(&h, base_url); print(&h, "</link>\n");
    print(&h, "  <description>" PACKAGE_STRING "</description>\n");
    print(&h, "  <dc:language>ja-jp</dc:language>\n");
    print(&h, "  <dc:date>");
    print(&h, time_str(h.pool, item_list->get_mtime()));
    print(&h, "</dc:date>\n");

    print(&h, " <items>\n");
    print(&h, "  <rdf:Seq>\n");
    for (item = items; *item != NULL; item++) {
        print(&h, "   <rdf:li rdf:resource=\"");
        print(&h, base_url);
        print(&h, "download/");
        print(&h, (*item)->file_path);
        print(&h, "\" />\n");
    }
    print(&h, "  </rdf:Seq>\n");
    print(&h, " </items>\n");

    print(&h, " </channel>\n");

    for (item = items; *item != NULL; item++) {
        print(&h, *item);
    }

    print(&h, "</rdf:RDF>\n");
}


/******************************************************************************
 * private メソッド
 *****************************************************************************/
void RssView::print(handle *h, item_info *item)
{
    print(h, "<item rdf:about=\"");
    print(h, h->base_url);
    print(h, "download/");
    print(h, item->file_path);
    print(h, "\">");

    print(h, "<title>");
    print(h, item->header->file_name);
    print(h, "</title>");

    print(h, "<link>");
    print(h, h->base_url);
    print(h, "download/");
    print(h, item->file_path);
    print(h, "</link>");

    print(h, "<description>");
    print(h, item->header->comment);
    print(h, "</description>");

    print(h, "<dc:date>");
    print(h, time_str(h->pool, item->header->time));
    print(h, "</dc:date>");

    print(h, "</item>");
}

void RssView::print(handle *h, const char *str)
{
#ifdef DEBUG_RssView
    cout << str;
#else
    ap_rputs(str, h->request);
#endif
}

const char *RssView::time_str(apr_pool_t *pool, apr_time_t time)
{
    apr_time_exp_t time_exp;
    char *time_str;
    apr_size_t size;

    APR_PALLOC(time_str, char *, pool, sizeof(char)*MAX_TIME_LENGTH);

    if (time_str == NULL) {
        throw "時間表記のためのメモリ確保に失敗しました．";
    }
    apr_time_exp_tz(&time_exp, time, TIME_ZONE_OFFSET);
    apr_strftime(time_str, &size, MAX_TIME_LENGTH, TIME_FORMAT, &time_exp);

    return time_str;
}


/******************************************************************************
 * テスト
 *****************************************************************************/
#ifdef DEBUG_RssView
#include "apr_general.h"

const apr_size_t TOTAL_NUMBER_LIMIT = 100;
const apr_size_t TOTAL_SIZE_LIMIT   = 1024*1024*1024;
const char BASE_URL[]               = "http://acapulco.dyndns.org/";

void usage(const char *prog_name)
{
    cerr << "Usage: " << prog_name << " <DIRECTORY>" << endl;
}

int main(int argc, const char * const *argv)
{
    apr_pool_t *pool;

    apr_app_initialize(&argc, &argv, NULL);
    apr_pool_create(&pool, NULL);

    try {
        if (argc != 2) {
            throw "ファイル用ディレクトリが指定されていません．";
        }

        auto_ptr<UploadItemList> item_list(UploadItemList::load(pool, argv[1], argv[1],
                                                                TOTAL_NUMBER_LIMIT, TOTAL_SIZE_LIMIT));

        RssView view;
        view.exec(pool, NULL, BASE_URL, item_list.get(), 20);
    } catch(const char *message) {
        cerr << "Error: " << message << endl;
        usage(argv[0]);

        return EXIT_FAILURE;
    }

    apr_terminate();

    return EXIT_SUCCESS;
}
#endif

// Local Variables:
// mode: c++
// buffer-file-coding-system: euc-japan-dos
// End:
