// 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")); _L<_R > commands; api::Pcre::RegEx sitemap_(_B("^-sitemap=(.+)$")), fs_(_B("^-fs=(.*)$")), exclude(_B("^-exclude=(.+)$")); _foreach (const app::ArgumentList, arg, app::GetArguments()) { api::Pcre::RegEx::Match match; _R fs; if (match = sitemap_(*arg)) sitemap = match[1]; else if (match = fs_(*arg)) commands.InsertLast(new _H(match[1])); else if (commands.GetSize() && (fs = dynamic_cast(commands.Last().GetValue())) && (match = exclude(*arg))) fs->excludes.InsertLast(match[1]); else { api::Cout << _B("Usage: ") << api::GetExecutablePath().GetName() << _B(" [-sitemap=.+] [-fs=.* [-exclude=.+] ...] ...") << ios::NewLine; return 1; } } GoogleTron tron(sitemap, commands); return 0; } GoogleTron::GoogleTron(const cse::String &sitemap, const _L<_R > &commands) : working(true), sitemap(sitemap), output(hop::BindAll(&GoogleTron::Output, this)) { _foreach (const _L<_R >, command_, commands) if (_R command = dynamic_cast(command_->GetValue())) threads.Add(hop::BindAll(&GoogleTron::FileSystem_, this, command)); } GoogleTron::~GoogleTron() { threads.Join(); working = false; output.Join(); } 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")); do { Sleep(); _synchronized (queueLock) if (queue.size()) { 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()); } queue.pop(); } } while (working); return 0; } int GoogleTron::FileSystem_(const _R &command) { FileSystem fs(sitemap, queue, queueLock, command); return 0; }