ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/repos/FeepingCreaturism/FeepingCreaturism.cpp
Revision: 1084
Committed: 2008-08-21T19:45:28-07:00 (16 years, 10 months ago) by douglas
File size: 5655 byte(s)
Log Message:
Menes has strange errors; I'll probably completely replace this with Python at some point anyway, grr!

File Contents

# User Rev Content
1 Douglas Thrift 191 // Feeping Creaturism
2     //
3     // Douglas Thrift
4     //
5     // $Id$
6    
7 douglas 792 #include <cxx/standard.hh>
8    
9     #include <api/environment.hpp>
10     #include <api/exename.hpp>
11     #include <api/pcre/regex.hpp>
12     #include <api/random.hpp>
13     #include <app/simple.hpp>
14     #include <cse/traits.hpp>
15    
16     #include <ctime>
17    
18 Douglas Thrift 196 #include "Jargon.hpp"
19 Douglas Thrift 191
20 douglas 792 template <typename Environment>
21     cse::String Get(const Environment &environment, const cse::String &name)
22     {
23     try { return environment.Get(name); }
24     catch (ext::NotFoundException) { return cse::EmptyString; }
25     }
26 Douglas Thrift 261
27 douglas 792 int Main(const app::Options &options)
28 Douglas Thrift 191 {
29 douglas 792 try
30     {
31     FeepingCreaturism creaturism;
32 Douglas Thrift 201
33 douglas 792 return 0;
34     }
35     catch (const ext::Exception &exception)
36     {
37     api::Cout << _B("Content-Type: text/plain\r\n\r\n") << exception << ios::NewLine;
38 Douglas Thrift 191
39 douglas 792 return 1;
40     }
41 Douglas Thrift 251 }
42 Douglas Thrift 194
43     FeepingCreaturism::FeepingCreaturism()
44     {
45 douglas 797 if (Initialize())
46     return;
47    
48 douglas 792 Parse();
49 Douglas Thrift 194
50 douglas 792 cse::String path(Get(api::TheEnvironment, _B("PATH_INFO")));
51     api::Pcre::RegEx::Match match;
52 Douglas Thrift 194
53 douglas 792 if (match = api::Pcre::RegEx(_B("^/daily/(\\d{4}-\\d{2}-\\d{2})?$"))(path))
54     Daily(match[1]);
55     else if (match = api::Pcre::RegEx(_B("^/random/(\\d+)?$"))(path))
56     Random(match[1]);
57     else if (match = api::Pcre::RegEx(_S<ios::String>() << _B("^/(") << matcher << _B(")$"))(path))
58     Select(match[1], true);
59 Douglas Thrift 198 else
60 douglas 792 api::Cout << _B("Location: http://") << Get(api::TheEnvironment, "HTTP_HOST") << Get(api::TheEnvironment, "SCRIPT_NAME") << _B("/daily/\r\n\r\n");
61 Douglas Thrift 194 }
62    
63 douglas 792 bool FeepingCreaturism::CaseLess::Execute(const cse::String &one, const cse::String &two)
64 Douglas Thrift 206 {
65 douglas 792 cse::String one_(cse::ToLower(one)), two_(cse::ToLower(two));
66 Douglas Thrift 206
67 douglas 792 if (one_ == two_)
68 douglas 796 return ext::Compare(one.GetData().Begin(), two.GetData().Begin(), one.GetData().GetSize() < two.GetData().GetSize() ? one.GetData().GetSize() : two.GetData().GetSize()) < 0;
69 Douglas Thrift 206
70 douglas 796 return ext::Compare(one_.GetData().Begin(), two_.GetData().Begin(), one_.GetData().GetSize() < two_.GetData().GetSize() ? one_.GetData().GetSize() : two_.GetData().GetSize()) < 0;
71 Douglas Thrift 206 }
72    
73 douglas 797 bool FeepingCreaturism::Initialize()
74 Douglas Thrift 194 {
75 douglas 792 _R<xml::Document> document(xml::Parse(_B("jargon.xml")));
76     _R<xml::Node> node(*document/_B("feepingcreaturism"));
77 Douglas Thrift 194
78 douglas 792 path = *node/_B("jargon");
79     matcher = *node/_B("matcher");
80 Douglas Thrift 194
81 douglas 797 if (Get(api::TheEnvironment, _B("GATEWAY_INTERFACE")).IsEmpty())
82     {
83     _L<cse::String> args(1, path);
84 Douglas Thrift 194
85 douglas 797 args.InsertLast(_B("-type"));
86     args.InsertLast(_B("f"));
87 Douglas Thrift 194
88 douglas 797 _S<api::Process> find(_B("/usr/bin/find"), args);
89     api::Pcre::RegEx matcher_(_S<ios::String>() << _B("^") << path << _B("/(") << matcher << _B(")$"));
90     ext::Buffer path;
91 Douglas Thrift 194
92 douglas 797 while (ios::ReadLine(*find.GetReader(), path))
93     if (api::Pcre::RegEx::Match match = matcher_(path))
94     jargon.Insert(match[1]);
95    
96     _S<api::FileWriter> writer(_B("jargon.dat"));
97    
98     _foreach (Set, path, jargon)
99     _S<ios::FormatWriter>(writer) << *path << ios::NewLine;
100    
101     return true;
102     }
103     else
104     {
105     _S<api::FileReader> reader(_B("jargon.dat"));
106     ext::Buffer path;
107    
108     while (ios::ReadLine(reader, path))
109     jargon.Insert(path);
110     }
111    
112     return false;
113 Douglas Thrift 194 }
114    
115 douglas 792 void FeepingCreaturism::Parse()
116 Douglas Thrift 203 {
117 douglas 1084 /*_S<ios::Buffer> query(Get(api::TheEnvironment, _B("QUERY_STRING")));
118 Douglas Thrift 203
119 douglas 792 if (Get(api::TheEnvironment, _B("REQUEST_METHOD")) == _B("POST"))
120 Douglas Thrift 203 {
121 douglas 792 query.Clear();
122 Douglas Thrift 203
123 douglas 792 ios::ReadToWriteFully(api::Cin, query, lexical_cast<size_t>(Get(api::TheEnvironment, _B("CONTENT_LENGTH"))));
124 Douglas Thrift 203 }
125    
126 douglas 792 if (query.IsEmpty())
127     return;
128 Douglas Thrift 203
129 douglas 792 _forever
130     try
131     {
132     cse::String name(ios::ReadUntil(query, '='));
133 douglas 908 ext::Buffer value;
134 Douglas Thrift 203
135 douglas 908 try { ios::ReadUntil(query, '&', value); }
136     catch (ext::EosException) {}
137 Douglas Thrift 203
138 douglas 908 cgi[name].InsertLast(value);
139 douglas 792 }
140 douglas 1084 catch (ext::EosException) { break; }*/
141 Douglas Thrift 203 }
142    
143 douglas 792 void FeepingCreaturism::Daily(const cse::String &date)
144 Douglas Thrift 194 {
145     std::time_t when(std::time(NULL));
146 Douglas Thrift 211 std::tm* day(std::localtime(&when));
147 Douglas Thrift 194
148 Douglas Thrift 211 day->tm_sec = 0;
149     day->tm_min = 0;
150     day->tm_hour = 0;
151 Douglas Thrift 194
152 douglas 792 if (!date.IsEmpty())
153     ::strptime(date.NullTerminate(), "%Y-%m-%d", day);
154 Douglas Thrift 211
155     std::time_t difference(mktime(day) / 86400);
156 douglas 792 _L<cse::String> jargon_(jargon.Begin(), jargon.End());
157     cse::String entry(jargon_.GetSize() ? jargon_[difference % jargon_.GetSize()] : cse::EmptyString);
158 Douglas Thrift 194
159 douglas 792 Select(entry);
160 Douglas Thrift 194 }
161    
162 douglas 792 void FeepingCreaturism::Random(const cse::String &number)
163 Douglas Thrift 194 {
164 douglas 792 _L<cse::String> jargon_(jargon.Begin(), jargon.End());
165     size_t random;
166 douglas 906
167 douglas 792 if (number.IsEmpty())
168     api::WeakRandom.Read(reinterpret_cast<byte_t *>(&random), sizeof (size_t));
169     else
170     random = lexical_cast<size_t>(number);
171 Douglas Thrift 194
172 douglas 792 _assert(random >= 0);
173     _assert(random % jargon_.GetSize() < jargon_.GetSize());
174 Douglas Thrift 194
175 douglas 792 cse::String entry(jargon_.GetSize() ? jargon_[random % jargon_.GetSize()] : cse::EmptyString);
176 Douglas Thrift 211
177 douglas 792 Select(entry);
178 Douglas Thrift 194 }
179    
180 douglas 792 void FeepingCreaturism::Select(const cse::String &selection, bool validate)
181 Douglas Thrift 194 {
182 douglas 792 if (!validate || jargon.Contains(selection))
183 Douglas Thrift 194 {
184 douglas 1084 api::Cout << _B("Content-Type: text/html; charset=UTF-8\r\n\r\n") << ios::Flush;
185 Douglas Thrift 196
186 douglas 1084 bool include(false);
187     cse::String relative(cse::EmptyString);
188 Douglas Thrift 196
189 douglas 1084 _foreach (const app::ArgumentList, argument, app::GetArguments())
190     if (*argument == _B("include"))
191     include = true;
192     else if (*argument == _B("relative") && argument + 1 != _end)
193     relative = *++argument;
194    
195     Jargon jargon(path, selection, include/*cgi.Contains(_B("include")) && lexical_cast<bool>(cgi[_B("include")].First())*/, relative/*cgi.Contains(_B("relative")) ? cgi[_B("relative")].First() : cse::EmptyString*/);
196    
197 Douglas Thrift 225 api::Cout << jargon;
198 Douglas Thrift 194 }
199 Douglas Thrift 195 else
200 douglas 792 api::Cout << _B("Status: 404\r\nContent-Type: text/html; charset=ISO-8859-1\r\n\r\n<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n<html><head>\n<title>404 Not Found</title>\n</head><body>\n<h1>Not Found</h1>\n<p>The requested URL ") << Get(api::TheEnvironment, _B("PATH_INFO")) << _B(" was not found on this server.</p>\n<hr />\n") << Get(api::TheEnvironment, _B("SERVER_SIGNATURE")) << _B("</body></html>\n");
201 Douglas Thrift 194 }

Properties

Name Value
svn:eol-style native
svn:keywords Id