// Google Tron // // Douglas Thrift // // $Id$ #include #include #include #include #include #include #include #include "GoogleTron.hpp" #include "Sleep.hpp" #include "Zlib/GzipWriter.hpp" int Main(const app::Options &options) { cse::String sitemap(_B("sitemap.gz")), base; _L<_R > commands; api::Pcre::RegEx sitemap_(_B("^-sitemap=(.+)$")), base_(_B("^-base=(.+)$")), fs(_B("^-fs=(.*)$")), blog(_B("^-blog=(.*)$")), wiki(_B("^-wiki=(.*)$")); _foreach (const app::ArgumentList, arg, app::GetArguments()) { api::Pcre::RegEx::Match match; if (match = sitemap_(*arg)) sitemap = match[1]; else if (match = base_(*arg)) base = match[1]; else if (match = fs(*arg)) commands.InsertLast(new _H(match[1])); else if (match = blog(*arg)) commands.InsertLast(new _H(match[1])); else if (match = wiki(*arg)) commands.InsertLast(new _H(match[1])); else goto usage; } if (base.IsEmpty() || commands.IsEmpty()) { usage: api::Cout << _B("Usage: ") << api::GetExecutablePath().GetName() << _B(" [-sitemap=.+] -base=.+ [-fs=.*] [-blog=.*] [-wiki=.*] [...]") << ios::NewLine; return 1; } GoogleTron tron(sitemap, base, commands); return 0; } GoogleTron::GoogleTron(const cse::String &sitemap, const cse::String &base, const _L<_R > &commands) : working(true), sitemap(sitemap), base(base), output(hop::BindAll(&GoogleTron::Output, this)) { api::Apr::CheckError(::apr_initialize()); _foreach (const _L<_R >, command_, commands) if (_R command = dynamic_cast(command_->GetValue())) threads.Add(hop::BindAll(&GoogleTron::FileSystem_, this, command)); else if (_R command = dynamic_cast(command_->GetValue())) threads.Add(hop::BindAll(&GoogleTron::Blog_, this, command)); else if (_R command = dynamic_cast(command_->GetValue())) threads.Add(hop::BindAll(&GoogleTron::Wiki_, this, command)); } GoogleTron::~GoogleTron() { threads.Join(); working = false; output.Join(); ::apr_terminate(); } int GoogleTron::Output() { _S gzip(sitemap); _S writer(gzip); xml::ScopeElement urlset(writer, _B("urlset")); writer.SetAttribute(_B("xmlns"), _B("http://www.google.com/schemas/sitemap/0.84")); writer.SetAttribute(_B("xmlns:xsi"), _B("http://www.w3.org/2001/XMLSchema-instance")); writer.SetAttribute(_B("xsi:schemaLocation"), _B("http://www.google.com/schemas/sitemap/0.84 http://www.google.com/schemas/sitemap/0.84/sitemap.xsd")); _synchronized (queueLock) do _desynchronized (queueLock) { Sleep(); _synchronized (queueLock) if (queue.GetSize()) { xml::ScopeElement url_(writer, _B("url")); const Url &url(queue.Front()); { xml::ScopeElement loc(writer, _B("loc")); writer.OutputText(url.GetLocation()); } { xml::ScopeElement lastmod(writer, _B("lastmod")); writer.OutputText(url.GetModified()); } { xml::ScopeElement changefreq(writer, _B("changefreq")); writer.OutputText(url.GetFrequency()); } { xml::ScopeElement priority(writer, _B("priority")); writer.OutputText(url.GetPriority()); } api::Cout << _B("Url: ") << url.GetLocation() << _B(" ") << url.GetModified() << _B(" ") << url.GetFrequency() << _B(" ") << url.GetPriority() << ios::NewLine; queue.Pop(); } } while (working || queue.GetSize()); return 0; } int GoogleTron::FileSystem_(const _R &command) { FileSystem fs(sitemap, base, queue, queueLock, command); return 0; } int GoogleTron::Blog_(const _R &command) { Blog blog(sitemap, base, queue, queueLock, command); return 0; } int GoogleTron::Wiki_(const _R &command) { Wiki wiki(sitemap, base, queue, queueLock, command); return 0; }