Index: tools/telemetry/third_party/gsutil/third_party/protorpc/demos/tunes_db/server/tunes_db.py |
diff --git a/tools/telemetry/third_party/gsutil/third_party/protorpc/demos/tunes_db/server/tunes_db.py b/tools/telemetry/third_party/gsutil/third_party/protorpc/demos/tunes_db/server/tunes_db.py |
deleted file mode 100644 |
index 0d62cb7ce9a7bdbc69bc629b946168854b6713de..0000000000000000000000000000000000000000 |
--- a/tools/telemetry/third_party/gsutil/third_party/protorpc/demos/tunes_db/server/tunes_db.py |
+++ /dev/null |
@@ -1,539 +0,0 @@ |
-#!/usr/bin/env python |
-# |
-# Copyright 2010 Google Inc. |
-# |
-# Licensed under the Apache License, Version 2.0 (the "License"); |
-# you may not use this file except in compliance with the License. |
-# You may obtain a copy of the License at |
-# |
-# http://www.apache.org/licenses/LICENSE-2.0 |
-# |
-# Unless required by applicable law or agreed to in writing, software |
-# distributed under the License is distributed on an "AS IS" BASIS, |
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
-# See the License for the specific language governing permissions and |
-# limitations under the License. |
-# |
- |
-"""Tunes DB service implementation. |
- |
-This module contains all the protocol buffer and service definitions |
-necessary for the Tunes DB service. |
-""" |
- |
-import base64 |
-import sys |
- |
-from google.appengine.ext import db |
- |
-from protorpc import descriptor |
-from protorpc import message_types |
-from protorpc import messages |
-from protorpc import protobuf |
-from protorpc import remote |
- |
-import model |
- |
- |
-class Artist(messages.Message): |
- """Musician or music group responsible for music production. |
- |
- Fields: |
- artist_id: Unique opaque identifier for artist. |
- name: User friendly name of artist. |
- album_count: Number of albums produced by artist. |
- """ |
- |
- artist_id = messages.StringField(1, required=True) |
- name = messages.StringField(2, required=True) |
- |
- album_count = messages.IntegerField(3) |
- |
- |
-class Album(messages.Message): |
- """Album produced by a musician or music group. |
- |
- Fields: |
- album_id: Unique opaque identifier for artist. |
- artist_id: Artist id of musician or music group that produced album. |
- name: Name of album. |
- released: Year when album was released. |
- """ |
- |
- album_id = messages.StringField(1, required=True) |
- artist_id = messages.StringField(2, required=True) |
- name = messages.StringField(3, required=True) |
- released = messages.IntegerField(4) |
- |
- |
-class AddArtistRequest(messages.Message): |
- """Request to add a new Artist to library. |
- |
- Fields: |
- name: User friendly name of artist. |
- """ |
- |
- name = messages.StringField(1, required=True) |
- |
- |
-class AddArtistResponse(messages.Message): |
- """Response sent after creation of new artist in library. |
- |
- Fields: |
- artist_id: Unique opaque ID of new artist. |
- """ |
- |
- artist_id = messages.StringField(1, required=True) |
- |
- |
-class UpdateArtistRequest(messages.Message): |
- """Update an existing artist. |
- |
- Fields: |
- artist: Complete information about artist to update. |
- """ |
- |
- artist = messages.MessageField(Artist, 1, required=True) |
- |
- |
-class UpdateArtistResponse(messages.Message): |
- """Artist update response. |
- |
- Fields: |
- artist_updated: Artist was found and updated. |
- """ |
- |
- artist_updated = messages.BooleanField(1, required=True) |
- |
- |
-class DeleteArtistRequest(messages.Message): |
- """Delete artist from library. |
- |
- Fields: |
- artist_id: Unique opaque ID of artist to delete. |
- """ |
- |
- artist_id = messages.StringField(1, required=True) |
- |
- |
-class DeleteArtistResponse(messages.Message): |
- """Artist deletion response. |
- |
- Fields: |
- artist_deleted: Artist was found and deleted. |
- """ |
- |
- artist_deleted = messages.BooleanField(1, default=True) |
- |
- |
-class FetchArtistRequest(messages.Message): |
- """Fetch an artist from the library. |
- |
- Fields: |
- artist_id: Unique opaque ID of artist to fetch. |
- """ |
- |
- artist_id = messages.StringField(1, required=True) |
- |
- |
-class FetchArtistResponse(messages.Message): |
- """Fetched artist from library. |
- |
- Fields: |
- artist: Artist found in library. |
- """ |
- |
- artist = messages.MessageField(Artist, 1) |
- |
- |
-class SearchArtistsRequest(messages.Message): |
- """Artist search request. |
- |
- Fields: |
- continuation: Continuation from the response of a previous call to |
- search_artists remote method. |
- fetch_size: Maximum number of records to retrieve. |
- name_prefix: Name prefix of artists to search. If none provided and |
- no continuation provided, search will be of all artists in library. |
- If continuation is provided, name_prefix should be empty, if not, value |
- is ignored. |
- """ |
- |
- continuation = messages.StringField(1) |
- fetch_size = messages.IntegerField(2, default=10) |
- name_prefix = messages.StringField(3, default=u'') |
- |
- |
-class SearchArtistsResponse(messages.Message): |
- """Response from searching artists. |
- |
- Fields: |
- artists: Artists found from search up to fetch_size. |
- continuation: Opaque string that can be used with a new search request |
- that will continue finding new artists where this response left off. |
- Will not be set if there were no results from the search or fewer |
- artists were returned in the response than requested, indicating the end |
- of the query. |
- """ |
- |
- artists = messages.MessageField(Artist, 1, repeated=True) |
- continuation = messages.StringField(2) |
- |
- |
-class AddAlbumRequest(messages.Message): |
- """Request to add a new album to library. |
- |
- Fields: |
- name: User friendly name of album. |
- artist_id: Artist id of artist that produced record. |
- released: Year album was released. |
- """ |
- |
- name = messages.StringField(1, required=True) |
- artist_id = messages.StringField(2, required=True) |
- released = messages.IntegerField(3) |
- |
- |
-class AddAlbumResponse(messages.Message): |
- """Response sent after creation of new album in library. |
- |
- Fields: |
- album_id: Unique opaque ID of new album. |
- """ |
- |
- album_id = messages.StringField(1, required=True) |
- |
- |
-class UpdateAlbumRequest(messages.Message): |
- """Update an existing album. |
- |
- Fields: |
- album: Complete information about album to update. |
- """ |
- |
- album = messages.MessageField(Album, 1, required=True) |
- |
- |
-class UpdateAlbumResponse(messages.Message): |
- """Album update response. |
- |
- Fields: |
- album_updated: Album was found and updated. |
- """ |
- |
- album_updated = messages.BooleanField(1, required=True) |
- |
- |
-class DeleteAlbumRequest(messages.Message): |
- """Delete album from library. |
- |
- Fields: |
- album_id: Unique opaque ID of album to delete. |
- """ |
- |
- album_id = messages.StringField(1, required=True) |
- |
- |
-class DeleteAlbumResponse(messages.Message): |
- """Album deletion response. |
- |
- Fields: |
- album_deleted: Album was found and deleted. |
- """ |
- |
- album_deleted = messages.BooleanField(1, default=True) |
- |
- |
-class FetchAlbumRequest(messages.Message): |
- """Fetch an album from the library. |
- |
- Fields: |
- album_id: Unique opaque ID of album to fetch. |
- """ |
- |
- album_id = messages.StringField(1, required=True) |
- |
- |
-class FetchAlbumResponse(messages.Message): |
- """Fetched album from library. |
- |
- Fields: |
- album: Album found in library. |
- """ |
- |
- album = messages.MessageField(Album, 1) |
- |
- |
-class SearchAlbumsRequest(messages.Message): |
- """Album search request. |
- |
- Fields: |
- continuation: Continuation from the response of a previous call to |
- search_albums remote method. |
- fetch_size: Maximum number of records to retrieve. |
- name_prefix: Name prefix of albms to search. If none provided and |
- no continuation provided, search will be of all albums in library. |
- If continuation is provided, name_prefix should be empty, if not, value |
- is ignored. |
- artist_id: Restrict search to albums of single artist. |
- """ |
- |
- continuation = messages.StringField(1) |
- fetch_size = messages.IntegerField(2, default=10) |
- name_prefix = messages.StringField(3, default=u'') |
- artist_id = messages.StringField(4) |
- |
- |
-class SearchAlbumsResponse(messages.Message): |
- """Response from searching artists. |
- |
- Fields: |
- albums: Albums found from search up to fetch_size. |
- continuation: Opaque string that can be used with a new search request |
- that will continue finding new albums where this response left off. |
- Will not be set if there were no results from the search or fewer |
- albums were returned in the response than requested, indicating the end |
- of the query. |
- """ |
- |
- albums = messages.MessageField(Album, 1, repeated=True) |
- continuation = messages.StringField(2) |
- |
- |
-class MusicLibraryService(remote.Service): |
- """Music library service.""" |
- |
- __file_set = None |
- |
- def __artist_from_model(self, artist_model): |
- """Helper that copies an Artist model to an Artist message. |
- |
- Args: |
- artist_model: model.ArtistInfo instance to convert in to an Artist |
- message. |
- |
- Returns: |
- New Artist message with contents of artist_model copied in to it. |
- """ |
- return Artist(artist_id=unicode(artist_model.key()), |
- name=artist_model.name, |
- album_count=artist_model.album_count) |
- |
- def __album_from_model(self, album_model): |
- """Helper that copies an Album model to an Album message. |
- |
- Args: |
- album_model: model.AlbumInfo instance to convert in to an Album |
- message. |
- |
- Returns: |
- New Album message with contents of album_model copied in to it. |
- """ |
- artist_id = model.AlbumInfo.artist.get_value_for_datastore(album_model) |
- |
- return Album(album_id=unicode(album_model.key()), |
- artist_id=unicode(artist_id), |
- name=album_model.name, |
- released=album_model.released or None) |
- |
- @classmethod |
- def __search_info(cls, |
- request, |
- info_class, |
- model_to_message, |
- customize_query=None): |
- """Search over an Info subclass. |
- |
- Since all search request classes are very similar, it's possible to |
- generalize how to do searches over them. |
- |
- Args: |
- request: Search request received from client. |
- info_class: The model.Info subclass to search. |
- model_to_method: Function (model) -> message that transforms an instance |
- of info_class in to the appropriate messages.Message subclass. |
- customize_query: Function (request, query) -> None that adds additional |
- filters to Datastore query based on specifics of that search message. |
- |
- Returns: |
- Tuple (results, continuation): |
- results: A list of messages satisfying the parameters of the request. |
- None if there are no results. |
- continuation: Continuation string for response if there are more |
- results available. None if there are no more results available. |
- """ |
- # TODO(rafek): fetch_size from this request should take priority |
- # over what is stored in continuation. |
- if request.continuation: |
- encoded_search, continuation = request.continuation.split(':', 1) |
- decoded_search = base64.urlsafe_b64decode(encoded_search.encode('utf-8')) |
- request = protobuf.decode_message(type(request), decoded_search) |
- else: |
- continuation = None |
- encoded_search = unicode(base64.urlsafe_b64encode( |
- protobuf.encode_message(request))) |
- |
- name_prefix = request.name_prefix |
- |
- query = info_class.search(name_prefix) |
- query.order('name') |
- if customize_query: |
- customize_query(request, query) |
- |
- if continuation: |
- # TODO(rafek): Pure query cursors are not safe for model with |
- # query restrictions. Would technically need to be encrypted. |
- query.with_cursor(continuation) |
- |
- fetch_size = request.fetch_size |
- |
- model_instance = query.fetch(fetch_size) |
- results = None |
- continuation = None |
- if model_instance: |
- results = [model_to_message(i) for i in model_instance] |
- if len(model_instance) == fetch_size: |
- cursor = query.cursor() |
- continuation = u'%s:%s' % (encoded_search, query.cursor()) |
- |
- return results, continuation |
- |
- |
- @remote.method(AddArtistRequest, AddArtistResponse) |
- def add_artist(self, request): |
- """Add artist to library.""" |
- artist_name = request.name |
- def do_add(): |
- artist = model.ArtistInfo(name=artist_name) |
- artist.put() |
- return artist |
- artist = db.run_in_transaction(do_add) |
- |
- return AddArtistResponse(artist_id = unicode(artist.key())) |
- |
- @remote.method(UpdateArtistRequest, UpdateArtistResponse) |
- def update_artist(self, request): |
- """Update artist from library.""" |
- def do_deletion(): |
- artist = model.ArtistInfo.get(request.artist.artist_id) |
- if artist: |
- artist.name = request.artist.name |
- artist.put() |
- return True |
- else: |
- return False |
- return UpdateArtistResponse( |
- artist_updated=db.run_in_transaction(do_deletion)) |
- |
- @remote.method(DeleteArtistRequest, DeleteArtistResponse) |
- def delete_artist(self, request): |
- """Delete artist from library.""" |
- def do_deletion(): |
- artist = model.ArtistInfo.get(request.artist_id) |
- if artist: |
- db.delete(model.Info.all(keys_only=True).ancestor(artist)) |
- return True |
- else: |
- return False |
- return DeleteArtistResponse( |
- artist_deleted = db.run_in_transaction(do_deletion)) |
- |
- @remote.method(FetchArtistRequest, FetchArtistResponse) |
- def fetch_artist(self, request): |
- """Fetch artist from library.""" |
- artist_model = model.ArtistInfo.get(request.artist_id) |
- if isinstance(artist_model, model.ArtistInfo): |
- artist = self.__artist_from_model(artist_model) |
- else: |
- artist = None |
- return FetchArtistResponse(artist=artist) |
- |
- |
- @remote.method(SearchArtistsRequest, SearchArtistsResponse) |
- def search_artists(self, request): |
- """Search library for artists.""" |
- results, continuation = self.__search_info(request, |
- model.ArtistInfo, |
- self.__artist_from_model) |
- return SearchArtistsResponse(artists=results or [], |
- continuation=continuation or None) |
- |
- @remote.method(AddAlbumRequest, AddAlbumResponse) |
- def add_album(self, request): |
- """Add album to library.""" |
- def create_album(): |
- if not request.artist_id: |
- raise ValueError('Request does not have artist-id.') |
- artist = model.ArtistInfo.get(request.artist_id) |
- if not artist: |
- raise ValueError('No artist found for %s.' % request.artist_id) |
- artist.album_count += 1 |
- artist.put() |
- |
- album = model.AlbumInfo(name=request.name, |
- released=request.released, |
- artist=artist, |
- parent=artist) |
- album.put() |
- |
- return album |
- album = db.run_in_transaction(create_album) |
- |
- return AddAlbumResponse(album_id=unicode(album.key())) |
- |
- @remote.method(UpdateAlbumRequest, UpdateAlbumResponse) |
- def update_album(self, request): |
- """Update album from library.""" |
- def do_deletion(): |
- album = model.AlbumInfo.get(request.album.album_id) |
- if album: |
- album.name = request.album.name |
- album.released = request.album.released |
- album.put() |
- return True |
- else: |
- return False |
- return UpdateAlbumResponse(album_updated=db.run_in_transaction(do_deletion)) |
- |
- @remote.method(DeleteAlbumRequest, DeleteAlbumResponse) |
- def delete_album(self, request): |
- """Delete album from library.""" |
- def do_deletion(): |
- album = model.AlbumInfo.get(request.album_id) |
- |
- artist = album.artist |
- artist.album_count -= 1 |
- artist.put() |
- |
- if album: |
- db.delete(model.Info.all(keys_only=True).ancestor(album)) |
- return True |
- else: |
- return False |
- |
- return DeleteAlbumResponse(album_deleted=db.run_in_transaction(do_deletion)) |
- |
- @remote.method(FetchAlbumRequest, FetchAlbumResponse) |
- def fetch_album(self, request): |
- """Fetch album from library.""" |
- album_model = model.AlbumInfo.get(request.album_id) |
- if isinstance(album_model, model.AlbumInfo): |
- album = self.__album_from_model(album_model) |
- else: |
- album = None |
- return FetchAlbumResponse(album=album) |
- |
- @remote.method(SearchAlbumsRequest, SearchAlbumsResponse) |
- def search_albums(self, request): |
- """Search library for albums.""" |
- def customize_query(request, query): |
- if request.artist_id: |
- query.filter('artist', db.Key(request.artist_id)) |
- |
- response = SearchAlbumsResponse() |
- results, continuation = self.__search_info(request, |
- model.AlbumInfo, |
- self.__album_from_model, |
- customize_query) |
- return SearchAlbumsResponse(albums=results or [], |
- continuation=continuation or None) |