2008年5月24日土曜日

Request







Request Format には3つの書式があり、 REST の場合、URL に記述することだけで
リクエストを送信することができます。
http://api.flickr.com/services/rest/?method=flickr.test.echo&name=value
実際には以下のように必ず取得した api_key を追加しないとエラーとなります。
http://api.flickr.com/services/rest/?method=flickr.test.echo&name=value&api_key=XXXX

http://www.flickr.com/services/api/

2008年5月22日木曜日

A working XML parsing example!

http://groups.google.com/group/google-appengine/browse_thread/thread/85b7d03ff0d4ff2b/9fdfec112a4c051a


SimpleXMLTreeBuilder is no longer supported in the latest SDK. Returns
"object is unsubscriptable" error.


Update: I hope this is still useful for people searching for a working
example!

I can confirm that minidom now works in SDK 1.0.2. As I understand
it, this is because pyexpat is now in the GAE whitelist of C
libraries:

http://code.google.com/appengine/kb/libraries.html

I am using SDK 1.0.2 on Windows XP, therefore for this to work I
needed to patch urlfetch_stub.py because the development server was
discarding my URL parameters.

http://code.google.com/p/googleappengine/issues/detail?id=341

You no longer need to use upload a version of the SimpleXMLTreeBuilder
(although this still works) and the code using minidom now looks like
this:

-----

from google.appengine.api import urlfetch
from xml.dom import minidom

WEATHER_URL = 'http://xml.weather.yahoo.com/forecastrss?p=%s'
WEATHER_NS = 'http://xml.weather.yahoo.com/ns/rss/1.0'

def parse( url ) :
result = urlfetch.fetch(url)
if result.status_code == 200:
return minidom.parseString(result.content)

def weather_for_zip(zip_code):
url = WEATHER_URL % zip_code
dom = parse(url)
forecasts = []
for node in dom.getElementsByTagNameNS(WEATHER_NS, 'forecast'):
forecasts.append({
'date': node.getAttribute('date'),
'low': node.getAttribute('low'),
'high': node.getAttribute('high'),
'condition': node.getAttribute('text')
})
return {
'forecasts': forecasts,
'title': dom.getElementsByTagName('title')[0].firstChild.data
}

print 'Content-Type: text/plain'
print ''
print weather_for_zip('94089')


{'title': u'Yahoo! Weather - Sunnyvale, CA', 'forecasts': [{'date': u'22 May 2008', 'high': u'75', 'low': u'53', 'condition': u'Sunny'}, {'date': u'23 May 2008', 'high': u'73', 'low': u'53', 'condition': u'Partly Cloudy'}]}





http://www.kharakawa.com/kh.log/archives/python/

2008年5月19日月曜日

Broken Datastore

IMProperty での例があったけれども、不正なデータが datatore に登録されて、
削除できなくなる ( fetch も) できなくなってしまう不具合がある。

http://groups.google.com/group/google-appengine/browse_thread/thread/3c3d2da5f7140b18/e80ac633370859db?hl=en&lnk=gst&q=can%27t+delete#e80ac633370859db


%Y ( 2008 ) を省略した日時データを datetime に登録してしまって、削除もできなくなってしまった。
結局 -cleare_datastore してしまったが...

value = datastore_types.FromPropertyPb(prop)
File "C:\Program Files\Google\google_appengine\google\appengine\api\datastore_types.py", line 1102, in FromPropertyPb
'Error converting pb: %s\nException was: %s' % (pb, msg))
BadValueError: Error converting pb: meaning: 7
name: "entry_date"
value <
int64Value: 0xfff831bf8bc87700
>
multiple: false

Exception was: timestamp out of range for platform time_t


http://code.google.com/appengine/docs/thedevwebserver.html
dev_appserver.py --datastore_path=/tmp/myapp_datastore myapp

Default (Windows XP)
C:\Documents and Settings\XXX\Local Settings\Temp\dev_appserver.datastore
C:\Documents and Settings\XXX\Local Settings\Temp\dev_appserver.datastore.history


2008年5月15日木曜日

Entity Groups, Ancestors and Paths

  • Every entity belongs to an entity group, a set of one or more entities that can be manipulated in a single transaction.
    • Entity group relationships tell App Engine to store several entities in the same part of the distributed network.
    • A transaction sets up datastore operations for an entity group, and all of the operations are applied as a group, or not at all if the transaction fails.

  • When the application creates an entity, it can assign another entity as the parent of the new entity.
    • Assigning a parent to a new entity puts the new entity in the same entity group as the parent entity.

  • An entity without a parent is a root entity.
    • An entity that is a parent for another entity can also have a parent.
    • A chain of parent entities from an entity up to the root is the path for the entity, and members of the path are the entity's ancestors.
    • The parent of an entity is defined when the entity is created, and cannot be changed later.

Tips for using entity groups:

  • Only use entity groups when they are needed for transactions. For other relationships between entities, use ReferenceProperty properties and Key values, which can be used in queries.

    グループはトランザクションのため
    データの関連づけには ReferencePropertyKey を使う

class ReferenceProperty(reference_class=None, verbose_name=None, collection_name=None, ...)

A reference to another model instance. For example, a reference may indicate a many-to-one relationship between the model with the property and the model referenced by the property.

reference_class is the model class of the model instance being referenced. If specified, only model instances of the class can be assigned to this property. If None, any model instance can be the value of this property.

collection_name is the name of the property to give to the referenced model class whose value is a Query for all entities that reference the entity. If no collection_name is set, then modelname_set (with the name of the model in lowercase letters and "_set" added) is used.

ReferenceProperty automatically references and dereferences model instances as property values: A model instance can be assigned to a ReferenceProperty directly, and its key will be used. The ReferenceProperty value can be used as if it were a model instance, and the datastore entity will be fetched and the model instance created when it is first used in this way. Untouched reference properties do not query for unneeded data.

class Author(db.Model):
name
= db.StringProperty()

class Story(db.Model):
author
= db.ReferenceProperty(Author)

story
= db.get(story_key)
author_name
= story.author.name

As with a Key value, it is possible for a reference property value to refer to a data entity that does not exist. If a referenced entity is deleted from the datastore, references to the entity are not updated. An application can explicitly db.get() the value of a ReferenceProperty (which is a Key) to test whether the referenced entity exists.

Deleting an entity does not delete entities referred to by a ReferenceProperty.

See also this introduction to reference properties.

Value type: db.Key (see above)


Introduction to reference properties.
http://code.google.com/appengine/docs/datastore/entitiesandmodels.html#References

References

A property value can contain the key of another entity. The value is a Key instance.


# To fetch and iterate over every SecondModel entity that refers to the
# FirstModel instance obj1:
for obj in obj1.firstmodel_set:
# ...

The name of the back-reference property defaults to modelname_set (with the name of the model class in lowercase letters, and "_set" added to the end), and can be adjusted using the collection_name argument to the ReferenceProperty constructor.

Automatic referencing and dereferencing of model instances, type checking and back-references are only available using the ReferenceProperty model property class. Keys stored as values of Expando dynamic properties or ListProperty values do not have these features.

http://groups.google.com/group/google-appengine/browse_thread/thread/e9464ceb131c726f?hl=en
http://blog.arbingersys.com/2008/04/google-app-engine-better-many-to-many.html
http://cluebin.appspot.com/pasted/25


  • The more entity groups your application has―that is, the more root entities there are―the more efficiently the datastore can distribute the entity groups across datastore nodes. Better distribution improves the performance of creating and updating data. Also, multiple users attempting to update entities in the same entity group at the same time will cause some users to retry their transactions, possibly causing some to fail to commit changes. Do not put all of the application's entities under one root.
  • A good rule of thumb for entity groups is that they should be about the size of a single user's worth of data or smaller.
  • Entity groups do not have a significant impact on the speed of queries.

2008年5月14日水曜日

テーブル 分解





a = "abc</tr>efg</tr>aaa"
print a
print a.split('</tr>')[0]
print len(a.split('</tr>'))

imgList = "<table>"
imgList += "<tr>"
imgList += "<td>abc1</td>"
imgList += "<td>abc2</td>"
imgList += "<td>abc3</td>"
imgList += "</tr>"
imgList += "<tr>"
imgList += "<td>2abc1</td>"
imgList += "<td>2abc2</td>"
imgList += "<td>2abc3</td>"
imgList += "</tr>"
imgList += "<tr>"
imgList += "<td>3abc1</td>"
imgList += "<td>3abc2</td>"
imgList += "<td>3abc3</td>"
imgList += "</tr>"

imgList += "</table>"

print "imgList",imgList
imgData = imgList[:-8][7:]

print "imgData",imgData

rr = range(0, len(imgData.split('</tr>'))-1 )

for r in rr:
imgRow = imgData.split('</tr>')[r][8:][:-5]

print "r,imgRow:", r,imgRow

imgRow = imgRow.split('</td><td>')

print "imgRow,len(imgRow)",imgRow,len(imgRow)




abc</tr>efg</tr>aaa

abc

3

imgList <table><tr><td>abc1</td><td>abc2</td><td>abc3</td></tr><tr><td>2abc1</td><td>2abc2</td><td>2abc3</td></tr><tr><td>3abc1</td><td>3abc2</td><td>3abc3</td></tr></table>

imgData <tr><td>abc1</td><td>abc2</td><td>abc3</td></tr><tr><td>2abc1</td><td>2abc2</td><td>2abc3</td></tr><tr><td>3abc1</td><td>3abc2</td><td>3abc3</td></tr>

r,imgRow: 0 abc1</td><td>abc2</td><td>abc3

imgRow,len(imgRow) ['abc1', 'abc2', 'abc3'] 3

r,imgRow: 1 2abc1</td><td>2abc2</td><td>2abc3

imgRow,len(imgRow) ['2abc1', '2abc2', '2abc3'] 3

r,imgRow: 2 3abc1</td><td>3abc2</td><td>3abc3

imgRow,len(imgRow) ['3abc1', '3abc2', '3abc3'] 3


削除、一括登録

一括削除
http://code.google.com/appengine/docs/datastore/creatinggettinganddeletingdata.html
class editBlog(BaseRequestHandler):
def get(self):
cmd = self.request.get('cmd')
if cmd == 'delete':
q = db.GqlQuery("SELECT * FROM Blog" )
results = q.fetch(100)
# db.delete(results)
for result in results:
result.delete()
self.redirect('/_ah/admin/datastore?kind=Blog')

# self.redirect('/helloworld/')

Deleting an entity does not change any Key values in the datastore that may have referred to the entity. If your application may attempt to de-reference a Key value for a deleted entity, the application should do so using db.get(), then test the return value before accessing properties.


get(keys)
Gets the entity or entities for the given key or keys, of any Model.
Arguments:
keys
A Key object or a list of Key objects.

If one Key is provided, the return value is an instance of the appropriate Model class, or None if no entity exists with the given Key. If a list of Keys is provided, the return value is a corresponding list of model instances, with None values when no entity exists for a corresponding Key.                    See also Model.get().


Deleting an entity that is an ancestor for other entities does not affect the other entities. As long as the application does not depend on the existence of the ancestor to build keys for the descendant entities, the application can still access the descendants.



ループによる登録が思うように動作しない
トランザクションの問題ではないようなのだが。
http://code.google.com/appengine/docs/datastore/transactions.html

データストア Property

http://code.google.com/appengine/docs/datastore/typesandpropertyclasses.html
http://code.google.com/appengine/docs/datastore/typesandpropertyclasses.html#StringProperty

class StringProperty(verbose_name=None, multiline=False, ...)

A short string property. Takes a Python str or unicode (basestring) value of 500 bytes or less.

500バイト以下

StringProperty property values are indexed, and can be used in filters and sort orders.

インデックスによるフィルタ、並び替え可能

If multiline is False, then the value cannot include linefeed characters. The djangoforms library uses this to enforce a difference between text fields and textarea fields in the data model, and others can use it for a similar purpose.

multiline=True にすると LF(Line Feed)を含めることができる

Value type: str or unicode

class TextProperty()

A long string.

Unlike StringProperty, a TextProperty value can be more than 500 bytes long. However, TextProperty values are not indexed, and cannot be used in filters or sort orders.

500 バイト以上対応

フィルタはつかえない
検索条件にするものには向かない

TextProperty values store text with a text encoding. For binary data, use BlobProperty.

Value type: Text


class DateTimeProperty(verbose_name=None, auto_now=False, auto_now_add=False, ...)

A date and time property.

If auto_now is True, the property value is set to the current time whenever the model instance is stored in the datastore, overwriting the property's previous value. This is useful for tracking a "last modified" date and time for a model instance.

If auto_now_add is True, the property value is set to the current time the first time the model instance is stored in the datastore, unless the property has already been assigned a value. This is useful for storing a "created" date and time for a model instance.

BadValueError: Property entry_date must be a datetime

Date-time values are stored as and returned using the UTC time zone. See datetime.datetime for a discussion of how to manage time zones.

Value type: datetime.datetime

datetime に文字列の日時をいきなり代入しようとすると以下のエラーとなる。
BadValueError: Property entry_date must be a datetime
strptime での対応が必要。

yymm = '2008-05-10 22:22:22'
ydate = datetime.datetime.strptime(yymm, '%Y-%m-%d %H:%M:%S')
print ydate

フォーマット文字 説明 出力例
a 'a.m.' または 'p.m.' (Associated Press に合わせるため,'.' が入っている点が PHP と違います). 'a.m.'
A 'AM' または 'PM' です. 'AM'
B 実装されていません.
d 月の中の日. 2 桁のゼロ詰めです. '01' から '31'
D 週の中の日. 3 文字のテキスト形式です. 'Fri'
f 12 時間表記の時と分.ただし,ゼロ分の場合には表示しません.独自の拡張です. '1', '1:30'
F 月名を長いテキスト形式で表したものです. 'January'
g 12 時間表記の時.ゼロ詰めはしません. '1' から '12'
G 24 時間表記の時.ゼロ詰めはしません. '0' から '23'
h 12 時間表記の時です. '01' から '12'
H 24 時間表記の時です. '00' から '23'
i 分です. '00' から '59'
I 実装されていません.
j 月の中の日.ゼロ詰めしません. '1' から '31'
l 週の中の曜日.長いテキスト形式です. 'Friday'
L 閏年かどうかを表すブール値です. True``または``False
m 月です.2 桁でゼロ詰めしたものです. '01' から '12'
M 月です.3 文字のテキスト形式です. 'Jan'
n 月です.ゼロ詰めしません. '1' から '12'
N Associated Press スタイルの月の省略表記です.独自の拡張です. 'Jan.', 'Feb.', 'March', 'May'
O グリニッジ標準時からの時差です. '+0200'
P 時刻です.12 時間表記の時,分,そして 'a.m.'/'p.m.' です.分がゼロの場合には省略され,必要に応じて'midnight' または 'noon' になります.独自の拡張です. '1 a.m.', '1:30 p.m.', 'midnight', 'noon', '12:30 p.m.'
r RFC 822 に従ったフォーマットの日時です. 'Thu, 21 Dec 2000 16:01:07 +0200'
s 秒です. 2 桁のゼロ詰めです. '00' から '59'
S 月の中の日につける 2 文字の序数接尾辞です. 'st', 'nd', 'rd' or 'th'
t 月の日数です. 28 から 31
T 計算機のタイムゾーン設定です. 'EST', 'MDT'
U 実装されていません.
w 週の中の曜日です.ゼロ詰めしません. '0' (Sunday) to '6' (Saturday)
W ISO-8601 に従った年の中の週番号です.週は月曜日から始まります. 1, 23
y 2 桁の年です. '99'
Y 4 桁の年です. '1999'
z 年の中の日 0 から 365
Z タイムゾーンオフセットを秒であらわしたものです.UTC よりも西側のタイムゾーン値は全て負の値になり,東側の値は常に正になります. -43200 から 43200

例:

It is {% now "jS F Y H:i" %}

フォーマット文字列中で普通の文字列を使いたければ,バックスラッシュでエスケープできます.下の例では,"f" が時刻を表すフォーマット指定子として解釈されないようにエスケープしています. "o" はフォーマット指定子ではないのでエスケープしていません:

It is the {% now "jS o\f F" %}

このテンプレートは "It is the 4th of September" になります.


Swift UI チュートリアル Loading watchOS が終わらない?

Loading watchOS が終わらない? ディスク容量の残量が少ないので不要なシュミレーターを削除したとこころ watchOSのものが全部なくなってしまっていた。 WatchOS を削除して再度インストールしても復活せず。 Create a new simulator で ...