Skip to content
This repository was archived by the owner on Jun 19, 2022. It is now read-only.

Commit 807736f

Browse files
committed
Initial commit
0 parents  commit 807736f

11 files changed

+533
-0
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*.pyc
2+
.DS_Store

app.yaml

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
application: billkatz-test
2+
version: 1
3+
runtime: python
4+
api_version: 1
5+
6+
handlers:
7+
- url: .*/favicon\.ico
8+
static_files: static/favicon.ico
9+
upload: static/favicon.ico
10+
11+
- url: /robots\.txt
12+
static_files: static/robots.txt
13+
upload: static/robots.txt
14+
15+
- url: /static
16+
static_dir: static
17+
18+
- url: .*
19+
script: main.py

index.yaml

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
indexes:
2+
- kind: SearchIndex
3+
properties:
4+
- name: parent_kind
5+
- name: keywords
6+
7+
# AUTOGENERATED
8+
9+
# This index.yaml is automatically updated whenever the dev_appserver
10+
# detects that a new type of query is run. If you want to manage the
11+
# index.yaml file manually, remove the above marker line (the line
12+
# saying "# AUTOGENERATED"). If you want to manage some indexes
13+
# manually, move them above the marker line. The index.yaml file is
14+
# automatically uploaded to the admin console when you next deploy
15+
# your application using appcfg.py.

main.py

+132
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
#!/usr/bin/env python
2+
#
3+
# The MIT License
4+
#
5+
# Copyright (c) 2009 William T. Katz
6+
#
7+
# Permission is hereby granted, free of charge, to any person obtaining a copy
8+
# of this software and associated documentation files (the "Software"), to
9+
# deal in the Software without restriction, including without limitation
10+
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
11+
# and/or sell copies of the Software, and to permit persons to whom the
12+
# Software is furnished to do so, subject to the following conditions:
13+
#
14+
# The above copyright notice and this permission notice shall be included in
15+
# all copies or substantial portions of the Software.
16+
#
17+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22+
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23+
# DEALINGS IN THE SOFTWARE.
24+
25+
"""A super simple Google App Engine text posting app.
26+
27+
Logged in visitors can add some test and search for keywords across all
28+
added pages. It demos a simple full text search module.
29+
"""
30+
__author__ = 'William T. Katz'
31+
32+
import cgi
33+
import logging
34+
35+
from google.appengine.api import users
36+
from google.appengine.ext import db
37+
from google.appengine.ext import webapp
38+
from google.appengine.ext.webapp.util import run_wsgi_app
39+
40+
# The following are necessary for full-text search demo
41+
import search
42+
INDEXING_URL = '/tasks/searchindexing'
43+
44+
class Page(search.Searchable, db.Model):
45+
content = db.TextProperty()
46+
user = db.UserProperty()
47+
created = db.DateTimeProperty(auto_now=True)
48+
49+
class SimplePage(webapp.RequestHandler):
50+
def render(self, html):
51+
user = users.get_current_user()
52+
page = '<html><body><div><a href="/">Add Page</a> | '
53+
if user:
54+
page += 'Logged in as %s ' % (user.nickname())
55+
logout_url = users.create_logout_url(self.request.uri)
56+
page += '| <a href="%s">Logout</a></div>' % (logout_url)
57+
else:
58+
login_url = users.create_login_url(self.request.uri)
59+
page += '<a href="%s">Google login</a></div>' % (login_url)
60+
page += """
61+
<hr>
62+
<h3>Full Text Search Test</h3>
63+
<p>This app tests a simple full text search module for Google App Engine.
64+
The search module uses the Task Queue API to schedule full text indexing and
65+
creates relation index entities (as described in
66+
<a href="http://code.google.com/events/io/sessions/BuildingScalableComplexApps.html">
67+
Brett Slatkin's 'Building Scalable, Complex Apps on App Engine' talk</a>
68+
at Google I/O, 2009).
69+
</p>
70+
<p>See <a href="http://www.billkatz.com/">my blog</a> for more information.</p>
71+
<form action="/search" method="get">
72+
Search for phrase (e.g., 'lorem ipsum'):
73+
"""
74+
page += '<input name="phrase"'
75+
phrase = self.request.get('phrase')
76+
if phrase:
77+
page += ' value="%s"' % (phrase)
78+
page += '><input type="submit" value="Search"><em>&nbsp;minimum 4 letters long</em></form>'
79+
page += html
80+
page += '</body></html>'
81+
self.response.out.write(page)
82+
83+
class MainPage(SimplePage):
84+
def get(self):
85+
user = users.get_current_user()
86+
if not user:
87+
html = '<h4>Please login to add a page.</h4>'
88+
else:
89+
html = """
90+
<h4>Add a text page below:</h4>
91+
<form action="/" method="post">
92+
<div><textarea name="content" rows="10" cols="60"></textarea></div>
93+
<div><input type="submit" value="Add Page"></div>
94+
</form>
95+
"""
96+
self.render(html)
97+
98+
def post(self):
99+
user = users.get_current_user()
100+
content = self.request.get('content')
101+
if not user:
102+
self.redirect('/?msg=You+must+be+logged+in')
103+
elif not content:
104+
self.redirect('/')
105+
else:
106+
page = Page(content=content, user=user)
107+
page.put()
108+
page.queue_indexing(url=INDEXING_URL, only_index=['content'])
109+
html = "<div>Thanks for entering the following text:</div>"
110+
html += "<pre>%s</pre>" % (cgi.escape(content))
111+
self.render(html)
112+
113+
class SearchPage(SimplePage):
114+
def get(self):
115+
phrase = self.request.get('phrase')
116+
pages = Page.search(phrase)
117+
html = "<h4>'" + phrase + "' was found on these pages:</h4>"
118+
for page in pages:
119+
html += "<div><p>User: %s, Created: %s</p><pre>%s</pre></div>" \
120+
% (str(page.user), str(page.created), cgi.escape(page.content))
121+
self.render(html)
122+
123+
application = webapp.WSGIApplication([
124+
('/', MainPage),
125+
('/search', SearchPage),
126+
(INDEXING_URL, search.SearchIndexing)], debug=True)
127+
128+
def main():
129+
run_wsgi_app(application)
130+
131+
if __name__ == '__main__':
132+
main()

0 commit comments

Comments
 (0)