1 |
// Wiki |
2 |
// |
3 |
// Douglas Thrift |
4 |
// |
5 |
// $Id$ |
6 |
|
7 |
#include <cxx/standard.hh> |
8 |
|
9 |
#include <api/files.hpp> |
10 |
#include <api/pcre/regex.hpp> |
11 |
|
12 |
#include "Iconv/Iso88591ToUtf8.hpp" |
13 |
#include "Wiki.hpp" |
14 |
|
15 |
Wiki::Wiki(const cse::String &sitemap, const cse::String &base, ext::Queue<Url> &queue, api::ThreadMutex &queueLock, const _R<WikiCommand> &command) : CommandRunner(sitemap, queue, queueLock) |
16 |
{ |
17 |
api::Cout << _B("Wiki") << ios::NewLine; |
18 |
|
19 |
Entries(command->root, _S<ios::String>() << base << command->path); |
20 |
} |
21 |
|
22 |
void Wiki::Entries(const api::Path &directory, const cse::String &base) |
23 |
{ |
24 |
{ |
25 |
cse::String wiki(client.GetProperty(_B("GoogleTron:Wiki"), directory.GetPath())); |
26 |
|
27 |
if (wiki != _B("PmWiki")) |
28 |
throw ext::NotImplementedException(_S<ios::String>(_B("unknown wiki ")) << wiki); |
29 |
} |
30 |
|
31 |
api::Path wikiDirectory(directory.GetChild(_B("wiki.d"))); |
32 |
ext::RedBlackSet<cse::String> excludes(GetProperties<ext::RedBlackSet<cse::String> >(_B("GoogleTron:Exclude"), wikiDirectory.GetPath())); |
33 |
ext::RedBlackSet<cse::String> sections(GetProperties<ext::RedBlackSet<cse::String> >(_B("GoogleTron:Section"), wikiDirectory.GetPath())); |
34 |
api::Pcre::RegEx wikiEntry(_B("^([^a-z].*)\\.([^a-z].*)$")); |
35 |
|
36 |
_foreach (const _L<Subversion::Entry>, entry, client.GetEntries(wikiDirectory.GetPath())) |
37 |
{ |
38 |
api::Pcre::RegEx::Match match; |
39 |
|
40 |
if (!entry->GetName().StartsWith('.') && !excludes.Contains(entry->GetName()) && (match = wikiEntry(entry->GetName())) && sections.Contains(match[1])) |
41 |
Entry(wikiDirectory.GetChild(entry->GetName()), base, *entry, match[1], match[2]); |
42 |
} |
43 |
} |
44 |
|
45 |
void Wiki::Entry(const api::Path &file, const cse::String &base, const Subversion::Entry &entry, const cse::String §ion, const cse::String &page) |
46 |
{ |
47 |
std::time_t modified(entry.GetModified()); |
48 |
|
49 |
try |
50 |
{ |
51 |
_S<api::FileReader> reader(file.GetPath()); |
52 |
ext::Buffer key, value; |
53 |
api::Pcre::RegEx redirect(_B("^\\(:redirect .*:\\)$")); |
54 |
|
55 |
while (key = ios::ReadUntil(reader, '='), ios::ReadLine(reader, value)) |
56 |
if (key == _B("time")) |
57 |
{ |
58 |
modified = lexical_cast<std::time_t>(cse::String(value)); |
59 |
|
60 |
break; |
61 |
} |
62 |
// XXX: Menes should have something that converts from ISO-8859-1 to UTF-8 |
63 |
else if (key == _B("text") && redirect(Iconv::Iso88591ToUtf8(value))) |
64 |
return; |
65 |
} |
66 |
catch (ext::EosException) {} |
67 |
|
68 |
Url url(_S<ios::String>() << base << section << _B("/") << page, modified, always, GetPriority(client.GetProperty(_B("GoogleTron:Priority"), file.GetPath()))); |
69 |
|
70 |
_synchronized (queueLock) |
71 |
queue.Push(url); |
72 |
} |