From 7fe8ebf1002b1893be5d4f21d9fa6f02fb95cccb Mon Sep 17 00:00:00 2001 From: "amyu@google.com" Date: Sun, 26 Aug 2012 23:05:38 +0000 Subject: [PATCH] README update for latest SDK; misc small cleanup git-svn-id: http://google-app-engine-samples.googlecode.com/svn/trunk@160 99225164-8649-0410-878b-2ba91e509939 --- search/product_search_python/README | 33 +++++++------ search/product_search_python/admin_handlers.py | 7 +-- search/product_search_python/app.yaml | 2 +- search/product_search_python/docs.py | 9 ++-- search/product_search_python/handlers.py | 8 ++-- search/product_search_python/static/instrs.html | 55 ++++++++++++---------- .../product_search_python/templates/product.html | 6 +-- 7 files changed, 66 insertions(+), 54 deletions(-) diff --git a/search/product_search_python/README b/search/product_search_python/README index b0d2a80..19a1996 100644 --- a/search/product_search_python/README +++ b/search/product_search_python/README @@ -23,6 +23,20 @@ A user does not need to be logged in to search the products, or to add reviews. A user must be logged in **as an admin of the app to add or modify product data**. The sidebar admin links are not displayed for non-admin users. +## Configuration + +Before you deploy the application, edit `app.yaml` to specify your own app id and version. + +In `templates/product.html`, the Google Maps API is accessed. It does not require an API key, but you are encouraged to use one to monitor your maps usage. In the element, look for: + + src="https://maps.googleapis.com/maps/api/js?sensor=false" + +and replace it with something like the following, where `replaceWithYourAPIKey` is your own API key: + + src="https://maps.googleapis.com/maps/api/js?sensor=false&key=replaceWithYourAPIKey" + +as described [here](https://developers.google.com/maps/documentation/javascript/tutorial#api_key). + ## Information About Running the App Locally Log in as an app admin to add and modify the app's product data. @@ -38,15 +52,9 @@ The app is configured to use Python 2.7. On some platforms, it may also be necessary to have Python 2.7 installed locally when running the dev_appserver. The app's unit tests also require Python 2.7. -**Locally, the documents index is not preserved across restarts of the dev app -server**. So, when running locally, you may want to re-initialize the sample -app data upon each restart, as described below. - When running the app locally, not all features of the search API are supported. -So, not all search queries will give the same results during local testing as -when run with the deployed app. As one example, numeric comparison queries are -not currently supported with the dev_appserver. This means that filtering on -product ratings is not supported locally. +So, not all search queries may give the same results during local testing as +when run with the deployed app. Be sure to test on a deployed version of your app as well as locally. ## Administering the deployed app @@ -60,16 +68,11 @@ remove this restriction, you can edit the `login: admin` specification in ## Loading Sample Data When you first start up your app, you will want to add sample data to it. -Because the `dev_appserver` does not preserve indexed document data between -restarts, you will probably want to do this **each time you launch the app -locally**. (This is not necessary for the deployed app, which will retain data -between deployments). Sample product data can be added in two ways. First, sample product data in CSV format can be added in batch via a link on the app's admin page. Batch indexing -of documents is more efficient than adding the documents one at a time. Note -that because the `dev_appserver` does not preserve indexed document data between -restarts, for consistency **the batch addition of sample data first removes all +of documents is more efficient than adding the documents one at a time. For consistency, +**the batch addition of sample data first removes all existing index and datastore product data**. The second way to add sample data is via the admin's "Create new product" link diff --git a/search/product_search_python/admin_handlers.py b/search/product_search_python/admin_handlers.py index 10d542d..86024da 100644 --- a/search/product_search_python/admin_handlers.py +++ b/search/product_search_python/admin_handlers.py @@ -44,6 +44,7 @@ def reinitAll(sample_data=True): Deletes all product entities and documents, essentially resetting the app state, then loads in static sample data if requested. Hardwired for the expected product types in the sample data. + (Re)loads store location data from stores.py as well. This function is intended to be run 'offline' (e.g., via a Task Queue task). As an extension to this functionality, the channel ID could be used to notify when done.""" @@ -93,9 +94,9 @@ def loadStoreLocationData(): for s in slocs: logging.info("s: %s", s) geopoint = search.GeoPoint(s[3][0], s[3][1]) - fields = [search.TextField(name='storename', value=s[1]), - search.TextField(name='address', value=s[2]), - search.GeoField(name='store_location', value=geopoint) + fields = [search.TextField(name=docs.Store.STORE_NAME, value=s[1]), + search.TextField(name=docs.Store.STORE_ADDRESS, value=s[2]), + search.GeoField(name=docs.Store.STORE_LOCATION, value=geopoint) ] d = search.Document(doc_id=s[0], fields=fields) try: diff --git a/search/product_search_python/app.yaml b/search/product_search_python/app.yaml index 66bdd1f..1d705be 100644 --- a/search/product_search_python/app.yaml +++ b/search/product_search_python/app.yaml @@ -10,7 +10,7 @@ handlers: - url: /admin/.* script: admin.application - login: admin + login: required secure: always - url: .* diff --git a/search/product_search_python/docs.py b/search/product_search_python/docs.py index ae0ce01..a10a2ef 100644 --- a/search/product_search_python/docs.py +++ b/search/product_search_python/docs.py @@ -142,6 +142,9 @@ class BaseDocumentManager(object): class Store(BaseDocumentManager): _INDEX_NAME = config.STORE_INDEX_NAME + STORE_NAME = 'store_name' + STORE_LOCATION = 'store_location' + STORE_ADDRESS = 'store_address' class Product(BaseDocumentManager): @@ -168,7 +171,7 @@ class Product(BaseDocumentManager): _SORT_OPTIONS = [ [AVG_RATING, 'average rating', search.SortExpression( expression=AVG_RATING, - direction=search.SortExpression.DESCENDING, default_value=1)], + direction=search.SortExpression.DESCENDING, default_value=0)], [PRICE, 'price', search.SortExpression( # other examples: # expression='max(price, 14.99)' @@ -178,7 +181,7 @@ class Product(BaseDocumentManager): # Then, you can access the score to build expressions like: # expression='price * _score' expression=PRICE, - direction=search.SortExpression.ASCENDING, default_value=1)], + direction=search.SortExpression.ASCENDING, default_value=9999)], [UPDATED, 'modified', search.SortExpression( expression=UPDATED, direction=search.SortExpression.DESCENDING, default_value=1)], @@ -187,7 +190,7 @@ class Product(BaseDocumentManager): direction=search.SortExpression.ASCENDING, default_value='')], [PRODUCT_NAME, 'product name', search.SortExpression( expression=PRODUCT_NAME, - direction=search.SortExpression.ASCENDING, default_value='')] + direction=search.SortExpression.ASCENDING, default_value='zzz')] ] _SORT_MENU = None diff --git a/search/product_search_python/handlers.py b/search/product_search_python/handlers.py index bae0664..e808310 100644 --- a/search/product_search_python/handlers.py +++ b/search/product_search_python/handlers.py @@ -529,10 +529,10 @@ class StoreLocationHandler(BaseHandler): # logging.info("geo search results: %s", results) response_obj2 = [] for res in results: - gdoc = docs.BaseDocumentManager(res) - geopoint = gdoc.getFirstFieldVal('store_location') - resp = {'addr': gdoc.getFirstFieldVal('address'), - 'storename': gdoc.getFirstFieldVal('storename'), + gdoc = docs.Store(res) + geopoint = gdoc.getFirstFieldVal(gdoc.STORE_LOCATION) + resp = {'addr': gdoc.getFirstFieldVal(gdoc.STORE_ADDRESS), + 'storename': gdoc.getFirstFieldVal(gdoc.STORE_NAME), 'lat': geopoint.latitude, 'lon': geopoint.longitude} response_obj2.append(resp) logging.info("resp: %s", response_obj2) diff --git a/search/product_search_python/static/instrs.html b/search/product_search_python/static/instrs.html index a94a77f..be3e898 100644 --- a/search/product_search_python/static/instrs.html +++ b/search/product_search_python/static/instrs.html @@ -12,9 +12,9 @@
-

Full-Text Search Demo App: Product Search

+

Full-Text Search Demo App: Product Search

-

Introduction

+

Introduction

This Python App Engine application illustrates the use of the Full-Text Search API in a “Product @@ -35,7 +35,23 @@ reviews yet, its rating will be 0).

A user must be logged in as an admin of the app to add or modify product data. The sidebar admin links are not displayed for non-admin users.

-

Information About Running the App Locally

+

Configuration

+ +

Before you deploy the application, edit app.yaml to specify your own app id and version.

+ +

In templates/product.html, the Google Maps API is accessed. It does not require an API key, but you are encouraged to use one to monitor your maps usage. In the element, look for:

+ +
src="https://maps.googleapis.com/maps/api/js?sensor=false"
+
+ +

and replace it with something like the following, where replaceWithYourAPIKey is your own API key:

+ +
  src="https://maps.googleapis.com/maps/api/js?sensor=false&key=replaceWithYourAPIKey"
+
+ +

as described here.

+ +

Information About Running the App Locally

Log in as an app admin to add and modify the app’s product data.

@@ -51,18 +67,12 @@ GAE SDK is in your path, do:

necessary to have Python 2.7 installed locally when running the dev_appserver. The app’s unit tests also require Python 2.7.

-

Locally, the documents index is not preserved across restarts of the dev app -server. So, when running locally, you may want to re-initialize the sample -app data upon each restart, as described below.

-

When running the app locally, not all features of the search API are supported. -So, not all search queries will give the same results during local testing as -when run with the deployed app. As one example, numeric comparison queries are -not currently supported with the dev_appserver. This means that filtering on -product ratings is not supported locally. +So, not all search queries may give the same results during local testing as +when run with the deployed app. Be sure to test on a deployed version of your app as well as locally.

-

Administering the deployed app

+

Administering the deployed app

You will need to be logged in as an administrator of the app to add and modify product data, though not to search products or add reviews. If you want to @@ -70,26 +80,22 @@ remove this restriction, you can edit the login: admin specificatio app.yaml, and remove the @BaseHandler.admin decorators in admin_handlers.py.

-

Loading Sample Data

+

Loading Sample Data

When you first start up your app, you will want to add sample data to it. -Because the dev_appserver does not preserve indexed document data between -restarts, you will probably want to do this each time you launch the app -locally. (This is not necessary for the deployed app, which will retain data -between deployments).

+

Sample product data can be added in two ways. First, sample product data in CSV format can be added in batch via a link on the app’s admin page. Batch indexing -of documents is more efficient than adding the documents one at a time. Note -that because the dev_appserver does not preserve indexed document data between -restarts, for consistency the batch addition of sample data first removes all +of documents is more efficient than adding the documents one at a time. For consistency, +the batch addition of sample data first removes all existing index and datastore product data.

The second way to add sample data is via the admin’s “Create new product” link in the sidebar, which lets an admin add sample products (either “books” or “hd televisions”) one at a time.

-

Updating product documents with a new average rating

+

Updating product documents with a new average rating

When a user creates a new review, the average rating for that product is updated in the datastore. The app may be configured to update the associated @@ -97,7 +103,7 @@ product search.Document at the same time (the default), or do this later time in batch (which is more efficient). See cron.yaml for an example of how to do this update periodically in batch.

-

Searches

+

Searches

Any valid queries can be typed into the search box. This includes simple word and phrase queries, but you may also submit queries that include references to @@ -114,7 +120,7 @@ query string used for the query is displayed with the search results.

Only product information is searched; product review text is not included in the search.

-

Some example searches

+

Some example searches

Below are some example product queries, which assume the sample data has been loaded. As discussed above, not all of these queries are supported by the dev_appserver.

@@ -126,14 +132,13 @@ As discussed above, not all of these queries are supported by the dev_appserver. name:tv1
size > 30

-

Geosearch

+

Geosearch

This application includes an example of using the Search API to perform location-based queries. Sample store location data is defined in stores.py, and is loaded along with the product data. The product details page for a product allows a search for stores within a given radius of the user’s current location. The user’s location is obtained from the browser.

-
diff --git a/search/product_search_python/templates/product.html b/search/product_search_python/templates/product.html index 7e47ede..9309ba5 100644 --- a/search/product_search_python/templates/product.html +++ b/search/product_search_python/templates/product.html @@ -4,7 +4,7 @@ @@ -79,11 +79,11 @@ function findLocation() { alert ('Timeout'); break; case error.POSITION_UNAVAILABLE: - alert ('Position unavailable; using fake data (37.60, -122)'); + alert ('Position unavailable; using fake data (37.60, -122). If you are running from localhost, note that geosearch is not currently fully supported on the dev app server.'); mapLocations(37.60, -122); break; case error.PERMISSION_DENIED: - alert ('Permission denied; using fake data.(-33.873038, 151.20563'); + alert ('Permission denied; using fake data.(-33.873038, 151.20563). If you are running from localhost, note that geosearch is not currently fully supported on the dev app server.'); mapLocations(-33.873038, 151.20563); break; case error.UNKNOWN_ERROR: -- 2.11.4.GIT