2008年12月8日月曜日

image drag and drop and tipmage



Query UI Draggablesで簡単ドラッグドロップ


src="/javascript/jquery/jquery-1.2.6.min.js"
src="/javascript/Tipmage-1.0.js"

src="/javascript/jquery/jquery.dimensions.js"
src="/javascript/jquery/ui.mouse.js"
src="/javascript/jquery/ui.draggable.js"
src="/javascript/jquery/ui.draggable.ext.js"





http://www.museum-in-cloud.com/index.php?id=1001&option=tipmage&Itemid=1000
http://urlencode.net/result.cgi

2008年12月2日火曜日

urlfetch 403 Error




GAE automatically adds a Referer header and Referer is said to be one of the headers you can't change. That means you can't post to Twitter from GAE.





2008年11月27日木曜日

Picasa Web Albums Data API

Picasa Web Albums Data API

http://code.google.com/apis/picasaweb/developers_guide_protocol.html
アルバムIDの取得

url = "http://picasaweb.google.com/data/feed/api/user/UserName"
result = urlfetch.fetch(url)
dom = minidom.parseString(result.content)
NS  = 'http://search.yahoo.com/mrss/'
a   = range(0,len(dom.getElementsByTagName('title')) )
for x in a:
  title = dom.getElementsByTagName('title')[x].firstChild.data
  id = dom.getElementsByTagName('id')[x].firstChild.data

2008年11月15日土曜日

ReferenceProperty failed to be resolved

ReferenceProperty を利用した場合、データの削除は注意



Traceback (most recent call last):
File "/base/python_lib/versions/1/google/appengine/ext/webapp/__init__.py", line 499, in __call__
handler.get(*groups)
File "/base/data/home/apps/blog-reader/1.329303600108062391/imgurl.py", line 226, in get
ImgList = imgurl_get_cache(site,server,title_lang)
File "/base/data/home/apps/blog-reader/1.329303600108062391/imgurl.py", line 308, in imgurl_get_cache
rssItems += ""
File "/base/python_lib/versions/1/google/appengine/ext/db/__init__.py", line 2421, in __get__
raise Error('ReferenceProperty failed to be resolved')
Error: ReferenceProperty failed to be resolved

2008年11月12日水曜日

it's not found as __builtin__.instancemethod

なぜか memcache でエラーが発生するようになっている。
要観察


File "/base/data/home/apps/blog-editor/1.1280/hw_blog.py", line 1073, in get_blog_menu
if not memcache.add("blogurls", blogurls, 60*60*24*30):
File "/base/python_lib/versions/1/google/appengine/api/memcache/__init__.py", line 557, in add
return self._set_with_policy(MemcacheSetRequest.ADD, key, value, time=time)
File "/base/python_lib/versions/1/google/appengine/api/memcache/__init__.py", line 602, in _set_with_policy
stored_value, flags = _validate_encode_value(value, self._do_pickle)
File "/base/python_lib/versions/1/google/appengine/api/memcache/__init__.py", line 170, in _validate_encode_value
stored_value = do_pickle(value)
File "/base/python_lib/versions/1/google/appengine/api/memcache/__init__.py", line 274, in DoPickle
self._pickler_instance.dump(value)
File "/base/python_dist/lib/python2.5/pickle.py", line 218, in dump
self.save(obj)
File "/base/python_dist/lib/python2.5/pickle.py", line 325, in save
self.save_reduce(obj=obj, *rv)
File "/base/python_dist/lib/python2.5/pickle.py", line 413, in save_reduce
save(state)
File "/base/python_dist/lib/python2.5/pickle.py", line 280, in save
f(self, obj) # Call unbound method with explicit self
File "/base/python_dist/lib/python2.5/pickle.py", line 643, in save_dict
self._batch_setitems(obj.iteritems())
File "/base/python_dist/lib/python2.5/pickle.py", line 675, in _batch_setitems
save(v)
File "/base/python_dist/lib/python2.5/pickle.py", line 325, in save
self.save_reduce(obj=obj, *rv)
File "/base/python_dist/lib/python2.5/pickle.py", line 390, in save_reduce
save(cls)
File "/base/python_dist/lib/python2.5/pickle.py", line 280, in save
f(self, obj) # Call unbound method with explicit self
File "/base/python_dist/lib/python2.5/pickle.py", line 742, in save_global
(obj, module, name))
PicklingError: Can't pickle : it's not found as __builtin__.instancemethod

--
回復

Our memcache maintenance was completed at 10:52 PST (GMT-8). During
this period, although calls to the API did in fact return False and
None as expected, memcache API response latency increased
significantly, causing requests with heavy memcache dependence to time
out after 10 seconds due to the request timer, covered in our
documentation here: http://code.google.com/appengine/docs/python/requestsandcgi.html

We're now implementing a fix for this issue, and in the future the
memcache API will return immediately in the event of an outage. We
apologize for any inconvenince this may have caused.

Pete Koomen, App Engine Team

On Nov 12, 6:05 pm, App Engine Team

2008年11月5日水曜日

datastore_errors.BadArgumentError:_app must not be empty.

以前 SDK で動作していた script が動かなくなった。
以下の一行の追加が必要


When I upgraded to 1.1.3 from 1.1.2, my App Engine unit tests (built 
using the scheme described in another post [1]) started failing with 
the following stack trace: 

google.appengine.api.datastore_errors.BadArgumentError: _app must not be empty.

2008年10月27日月曜日

Thumbnail Generation




http://www.zubrag.com/scripts/thumbnail-generator.php

http://localhost/test/webthumb.php?url=http://www.yahoo.co.jp
Thumbnail Generation Error. Thumbnail not created.

http://www.zubrag.com/forum/index.php/topic,33.0.html

C:\xampp\htdocs\test>IECapt.exe http://www.yahoo.com test.png

C:\xampp\htdocs\thumbnail
IECapt.exe
image.class.php
webthumb.php

//$thumbnails_folder = 'Z:/home/localhost/www/thumb/cache/';
$thumbnails_folder = 'C:/work/';


---


Pythonでクリップボードの画像をファイルに保存する
http://d.hatena.ne.jp/himazublog/20080629/1214703203
Python2.5 win32  ( pywin32-212.win32-py2.5.exe   )
http://sourceforge.net/project/showfiles.php?group_id=78018&package_id=79063&release_id=616849

RecIE(IEの操作を記録するツール)とPythonを連携

PILで文字列を画像
 from PIL import Image, ImageDraw, ImageFont
 font = ImageFont.truetype('/usr/local/grass5/fonts/ipagp.ttf',25, encoding='unic')
 image = Image.new('RGBA', (100, 100)) 
 draw = ImageDraw.Draw(image) 
 draw.text((0, 0), u'テスト', font=font, fill='#000000')
 image.save('hoge.png', 'PNG')
http://humming.via-kitchen.com/2007/10/14/string-2-image-using-pil/

PIL Tutorial: How to Create a Button Generator
http://nadiana.com/pil-tutorial-how-create-button-generator

2008年10月13日月曜日

Cooliris と GAE 連携

Cooliris の 3D Wall がすごい。


http://www.cooliris.com/
http://developer.cooliris.com/

crossdomain.xml の設定が必要

http://groups.google.com/group/google-appengine/browse_thread/thread/f064730ead93eedc/4876f0b321b580d0?show_docid=4876f0b321b580d0&fwc=1

ブラウザのキャッシュをクリアしないと、crossdomain エラーが止まらなかった。


ローカルでのテスト
swf ファイルの保存
http://www.browsertools.net/Flash-Saving-Plugin/index.html

ローカルファイルシステムの SWF および信頼されているローカル SWF ファイルのみがローカルリソースにアクセスできます

C:\WINDOWS\system32\Macromed\Flash\FlashPlayerTrust\AcrobatConnect.cfg
に swf の位置を追加
C:\xampp\htdocs\rss\cooliris.swf

2008年10月4日土曜日

Primary Key と Key_name ~MySQLのデータをGAEへ

データの入ったMySQLテーブルの内容を Google App Engine の Cloud に転送することができた。

図のData Viewer の画面であると新たに追加した Model が List に表示されるまでに少しタイムラグがあるため、作業中の動作確認は Logs の画面を監視して行なった。



今回、30個程度のテーブルを対象に作業を行なったが、RDBMS のキー項目とGoogle App Engine の Key_name の対応は以下のようになった。
Key_name は設定したが、parent は設定しなかった。


col = ""
bid = ""
cid = ""
content_id = ""
session_id = ""
menuid = ""
client_id = ""
time = ""
for r in rr:
if r.column_name == 'id' or r.column_name == 'cid':
key_name = 'id' + self.request.get(r.column_name)
j = clazz(key_name = key_name)

if r.column_name == 'cid' : cid = self.request.get(r.column_name)
if r.column_name == 'content_id': content_id = self.request.get(r.column_name)
if r.column_name == 'bid' : bid = self.request.get(r.column_name)
if r.column_name == 'time' : time = self.request.get(r.column_name)
if r.column_name == 'session_id': session_id = self.request.get(r.column_name)
if r.column_name == 'menuid' : menuid = self.request.get(r.column_name)
if r.column_name == 'client_id' : client_id = self.request.get(r.column_name)

if menuid and client_id:
key_name = 'id' + menuid + client_id
j = clazz(key_name = key_name)

if session_id and time:
key_name = 'id' + time + session_id
j = clazz(key_name = key_name)
if content_id:
key_name = 'id' + content_id
j = clazz(key_name = key_name)
if cid and bid:
key_name = 'id' + bid + cid
j = clazz(key_name = key_name)

2008年10月3日金曜日

トランザクションとデータ確認2 ~MySQLのデータをGAEへ

322 レコードのデータを 5 件づつ分けて POST したはずが、件数が合わない。

MySQL からColud へのデータの POST に較べれは、Cloud の一部のキーとなる項目データを取得して、 MySQLに格納するようにするのは工数は少なそうなので、Download 側も作成することに。


Python(Cloud , Google App Engine )
件数とキー項目(key_name)の表示

if self.request.get('cmd') == "columns":
rr = db.GqlQuery("select * from Information_schema_columns")
for r in rr:
self.response.out.write( r.key().name()+"<br>")
self.response.out.write( "count(*) = " + str(rr.count() ))

PHP(MySQL)
Cloud にアクセスし、リストされたデータを取得し、MySQL用のinsert文のSQL を作成し、表示(行末の余計なデータは手動削除)
$req =& new HTTP_Request("http://xxxx/sign?cmd=columns");
if (!PEAR::isError($req->sendRequest())) {
$imgList = $req->getResponseBody();
}
$dd = explode("<br>", $imgList) ;

$sql = "insert into `gae_columns` ( `column` ) values " ;
foreach ($dd as $d) {
$sql_values .= "( '".$d."' )," ;
}


MySQL に gae_column というテーブルを作成し、これに Cloud からの一覧データを挿入。
・MySQL に取得後のデータの確認用SQL
- 一覧

SELECT concat(table_name,'.',column_name) FROM
information_schema.columns i ,
joomlaj.gae_columns g
where i.table_schema ='joomlaj'
and concat('joomlaj_',table_name,'.',column_name) = g.column

- 不足分のリスト

SELECT concat(table_name,'.',column_name)
FROM information_schema.columns i
where i.table_schema ='joomlaj'
and concat('joomlaj_',table_name,'.',column_name) not in
(select g.column from joomlaj.gae_columns g)

やはりこうした作業は RDBMS が格段に優れる。

トランザクションとデータ確認1 ~MySQLのデータをGAEへ

PHP(MySQL) 側で PEAR の HTTP/Request.php を利用し、概略は以下のような流れで1レコードづつ Loop させて POST する。

5回程度のLoop とした。SQL の offset を追加しながら、間隔をあけて実行。
SELECT * FROM information_schema.columns where table_schema ='joomlaj' order by table_name, ordinal_position limit 0,5

SELECT * FROM information_schema.columns where table_schema ='joomlaj' order by table_name, ordinal_position limit 5,5


 require_once "HTTP/Request.php";

$req =& new HTTP_Request($post_url);
$req->setMethod(HTTP_REQUEST_METHOD_POST);

 ・・・

$database->setQuery( $sql2 );
$rows = @$database->loadAssocList();

foreach($fields[$table] as $field=>$type) { ?>
eval($get_fld_value);
$req->addPostData(strtolower($field), $value);


$request .= '&table='.$table ;
$request .= '&table_name='.$table_name ;
$req->addPostData('table', $table);
$req->addPostData('table_name', $table_name);

if (!PEAR::isError($req->sendRequest())) {
$response1 = $req->getResponseBody();
} else {
$response1 = "";
}



POST されたものを受ける、Python(Google App Engine の Cloud )側での概要はこちら

*1 PHP の fsockopen ではGAEのSDKでは動作しても cloud への POST はうまくかないようなので注意

2008年10月2日木曜日

Dynamic Datastore MySQLのデータをGAEへ

information_schema スキーマのcolumns テーブルについては以下のように決め打ちで対応した。
Datastore 側の key_name にはスキーマ、テーブル、カラム名を結合したものを設定した。

key = information_schema_columns.table_schema + "_"
key += information_schema_columns.table_name+ "."
key += information_schema_columns.column_name

Information_schema_columns.get_or_insert(key,
table_catalog = self.request.get('table_catalog'),
table_schema = self.request.get('table_schema'),
table_name = self.request.get('table_name'),
column_name = self.request.get('column_name'),
ordinal_position = ordinal_position,
column_default = column_default,
is_nullable = self.request.get('is_nullable'),
data_type = self.request.get('data_type'),
character_maximum_length = character_maximum_length,
character_octet_length = character_octet_length,
numeric_precision = numeric_precision,
numeric_scale = numeric_scale,
character_set_name = self.request.get('character_set_name'),
collation_name = self.request.get('collation_name'),
column_type = self.request.get('column_type'),
column_key = self.request.get('column_key') ,
extra = self.request.get('extra'),
privileges = self.request.get('privileges'),
column_comment = self.request.get('column_comment'))

けれども、この情報を利用してデータを転送する汎用的なものを作成しなければならない。
RDBMSには動的SQLという仕組みがあるが、 Datastore ではどのように対応したらいいのであろうか。

Pythonでリフレクションする」*1 などと参考にいろいろと試行錯誤、ようやくそれらしいものができた。
苦労したのはまず、

1.  動的に Class を作成するには ?

clazz = globals()[cls.capitalize()]
obj = clazz()

 
2.  動的に作成できた Class の Attribute を動的に作成するには ?

setattr


3. get_or_insert() でなくて、単純に put() するときの key_name の指定方法 ?

4. key_name にはなにを設定するか ?

Joomla! では id あるいは cid 列を設定しているようなので、まずはこれらを利用することに。


def post_mysql_data(self,cls):
clazz = globals()[cls.capitalize()]
obj = clazz()
table = cls
rr = db.GqlQuery("select * from Information_schema_columns where table_name = :1", table )

col = ""
for r in rr:
if r.column_name == 'id' or r.column_name == 'cid':
column_value = self.request.get(r.column_name)
key_name = 'id' + column_value
j = clazz(key_name = key_name)

if j:
for r in rr:
column_value = self.request.get(r.column_name)
if r.data_type == 'varchar' or r.data_type == 'text' or r.data_type == 'longtext' :
if column_value : setattr(j,r.column_name,column_value)
if r.data_type == 'bigint' or r.data_type == 'tinyint' or r.data_type == 'int' :
if column_value : setattr(j,r.column_name,int(column_value))
if r.data_type == 'datetime':
if column_value :
if column_value == '0000-00-00 00:00:00':column_value = '1901-01-01 00:00:00'
column_value = datetime.datetime.strptime(column_value,'%Y-%m-%d %H:%M:%S')
setattr(j,r.column_name,column_value)
col = j.put()


*1  shisashiの開発日記 http://shisashi.blogspot.com/

information.schema.columns MySQLのデータをGAEへ

拡張機能のライブラリ Joomla! Extensions Directory の
Administration - Database Management の中の
を使うと、 Joomla! というCMSの Administration 画面で phpMyAdmin ライクの操作を行なうことができる。
テーブル構造から class の定義の変換についてはオリジナルの components を作成してみたが、以降はこの Extention Components をベースにすることにした。

PHP 側から MySQL のデータを Google App Engine の Cloud に POST して、それを Python側で受けて datastore に put()  するフローとなる。

事前に各model の定義は作成しておいたとしても、datastore に put する際に column ごとにデータの型が intger なのか text なのか、わかっている必要がある。

Cloud 側のデータの型は数字もすべてテキストとし保存してしまってもよいのかもしれないが、いずれにしろまず、列情報を持つ MySQL のテーブルを Cloud に転送する第1ターゲットとすることにした。


SELECT * FROM information_schema.columns where table_schema ='joomlaj' order by table_name, ordinal_position limit 0,10

MySQLのデータをGAEへ

テンプレートの良し悪しで画面の感じがまったくかわってしまう。
PHP で書かれている Joomla とういうCMSのテンプレートの質が高い。また拡張ライブラリが充実している。

GAE にこれらのテンプレートを応用しようとした場合、 やはり Joomla 側のキーとなるいくつかのテーブルと同様のものを Cloud に作成する必要がある。

Joomla! の components の作成手順を参考にまずテーブルに対応する class の定義を作成するようにした。 以下がまず作成した対応一覧。

if ($data_type == "bigint" ) { $datastore_type = " = db.IntegerProperty()" ;}
if ($data_type == "tinyint") { $datastore_type = " = db.IntegerProperty()" ;}
if ($data_type == "int" ) { $datastore_type = " = db.IntegerProperty()" ;}
if ($data_type == "varchar") { $datastore_type = " = db.StringProperty()" ; }
if ($data_type == "text") { $datastore_type = " = db.TextProperty()" ; }
if ($data_type == "longtext"){ $datastore_type = " = db.TextProperty()" ; }
if ($data_type == "datetime"){ $datastore_type = " = db.DateTimeProperty()" ; }
views/auto/tmpl/defaul.php



2008年10月1日水曜日

fsock でcloud にPOSTしても値が届かない

php の fsockopen にて データを POST する、
local の Google App Engine の SDK 環境では動作しても、本番環境の Cloud では
501 エラーなども発生。

チェックが厳しいためか。
http://code.google.com/p/gears/wiki/ContentRangePostProposal


結局 PEAR を利用したところ、無事 cloud に対してでも POST できるようになった。
http://pear.php.net/manual/ja/package.http.http-request.headers.php

2008年9月22日月曜日

Joomla

・ 管理メニューで Top Menu が表示されない
->   モジュール管理 にて Top Menu を有効にする

- インストール時に サンプル を選択しないと、 jos_menu_types  に seed data が登録されないことが原因
joomlaj\installation_\sql\mysql\sample_data_sql
INSERT INTO `#__menu_types` VALUES
(2, 'usermenu', 'User Menu', 'A Menu for logged in Users'),
(3, 'topmenu', 'Top Menu', 'Top level navigation'),
(4, 'othermenu', 'Resources', 'Additional links'),
(5, 'ExamplePages', 'Example Pages', 'Example Pages'),
(6, 'keyconcepts', 'Key Concepts', 'This describes some critical information for new Users.');


・ 最終更新 の日付の日の部分が %d のまま表示される。
/language/ja-JP/ja-JP.ini の以下を変更(結局スペースを追加)
DATE_FORMAT_LC2=%Y年  %B %d日(%A) %H:%M
#DATE_FORMAT_LC2=%Y年%B%d日(%A) %H:%M


無料Joomla!テンプレー          http://www.joomlashack.jp/content/view/4/9/
Joomla ジャパン                    http://www.joomla.jp/
Joomla Template Tutorial    http://dev.joomla.org/content/view/1136/79/


Joomla! 1.5 変更部分
・ メニューの構築手順
  外部ファイルの取り込みがエクステンションに一元化
・ テンプレートではtemplateDetails.xml の役割
  モジュールポディションの設定、テンプレートパラメータの設定が可能
  テンプレート側にポディション

・ 特定のメニューから呼び出されたページに対し、テンプレートを指定することができる
  セクションと、その配下にカテゴリーの2層構造でしかコンテンツを管理することができない
  --->  メニューと組み合わせが必要
  Assign 対応していない template もある。



・ Joomla! 1.5.3 でタイトルタグにサイト名を表示させるための変更

・  機能拡張     http://extensions.joomla.org/
    Joomla! 1.5 Template Tutorials Project


・ Zend Framework の動作


・phpフレームワーク・オブジェクト指向入門 http://phpc2.seesaa.net/
PHP5の新機能(クラス関係) http://www.atmarkit.co.jp/fcoding/articles/php5/02/php502a.html
・引数の値渡しと参照渡し http://ww7.tiki.ne.jp/~inabah/php/004_002.htm

Home Developer Manual 11. API Reference [REVIEW] database->loadAssocList

Tutorial:Developing a Model-View-Controller Component - Part 1

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

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