<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7675371175644526084</id><updated>2011-04-21T16:50:41.548-07:00</updated><title type='text'>everything</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://iqiqi.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7675371175644526084/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://iqiqi.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>零零碎碎</name><uri>http://www.blogger.com/profile/02492426066009661788</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>4</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7675371175644526084.post-8159800315211156085</id><published>2009-03-22T18:06:00.000-07:00</published><updated>2009-03-22T18:10:45.165-07:00</updated><title type='text'>inno setup中 检测 VC2005 运行库</title><content type='html'>&lt;div&gt;使用inno setup 检测vcredist_x86.exe是否已经存在并安装&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;[Files]&lt;/div&gt;&lt;div&gt;Source: ntviewer_xul\vcredist_x86.exe; DestDir: {tmp}; Check: NeedInstallVC8&lt;/div&gt;&lt;div&gt;[Run]&lt;/div&gt;&lt;div&gt;Filename: {tmp}\vcredist_x86.exe; Parameters: /q; WorkingDir: {tmp}; Flags: skipifdoesntexist; StatusMsg: 安装微软 Visual C++ 运行时库 ...; Check: NeedInstallVC8&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;[Code]&lt;/div&gt;&lt;div&gt;function MsiQueryProductState(ProductCode: string): integer;&lt;/div&gt;&lt;div&gt;  external 'MsiQueryProductStateA@msi.dll';&lt;/div&gt;&lt;div&gt;function MsiConfigureProduct(ProductCode: string;&lt;/div&gt;&lt;div&gt;  iInstallLevel: integer; eInstallState: integer): integer;&lt;/div&gt;&lt;div&gt;  external 'MsiConfigureProductA@msi.dll';&lt;/div&gt;&lt;div&gt;const&lt;/div&gt;&lt;div&gt;  INSTALLSTATE_DEFAULT        = 5;&lt;/div&gt;&lt;div&gt;  INSTALLLEVEL_MAXIMUM        = $ffff;&lt;/div&gt;&lt;div&gt;  INSTALLSTATE_ABSENT         = 2;&lt;/div&gt;&lt;div&gt;const&lt;/div&gt;&lt;div&gt;   VCREDIST_X86                ='{7299052b-02a4-4627-81f2-1818da5d550d}';&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;function IsMsiProductInstalled(const ProductId: string): boolean;&lt;/div&gt;&lt;div&gt;begin&lt;/div&gt;&lt;div&gt;  Result := MsiQueryProductState(ProductId) = INSTALLSTATE_DEFAULT;&lt;/div&gt;&lt;div&gt;end;&lt;/div&gt;&lt;div&gt;function UninstallMsiProduct(const ProductId: string): boolean;&lt;/div&gt;&lt;div&gt;begin&lt;/div&gt;&lt;div&gt;  Result := false;&lt;/div&gt;&lt;div&gt;  if not IsMsiProductInstalled(ProductId) then exit;&lt;/div&gt;&lt;div&gt;  Result := MsiConfigureProduct(ProductId, INSTALLLEVEL_MAXIMUM,&lt;/div&gt;&lt;div&gt;    INSTALLSTATE_ABSENT) = 0;&lt;/div&gt;&lt;div&gt;end;&lt;/div&gt;&lt;div&gt;var vc8Missing: Boolean;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;function NeedInstallVC8(): Boolean;&lt;/div&gt;&lt;div&gt;begin&lt;/div&gt;&lt;div&gt;  Result := not vc8Missing;&lt;/div&gt;&lt;div&gt;end;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;function InitializeSetup(): Boolean;&lt;/div&gt;&lt;div&gt;var version: Cardinal;&lt;/div&gt;&lt;div&gt;begin&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;vc8Missing :=IsMsiProductInstalled(VCREDIST_X86);&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;result := true;&lt;/div&gt;&lt;div&gt;end;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7675371175644526084-8159800315211156085?l=iqiqi.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iqiqi.blogspot.com/feeds/8159800315211156085/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7675371175644526084&amp;postID=8159800315211156085' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7675371175644526084/posts/default/8159800315211156085'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7675371175644526084/posts/default/8159800315211156085'/><link rel='alternate' type='text/html' href='http://iqiqi.blogspot.com/2009/03/inno-setup-vc2005.html' title='inno setup中 检测 VC2005 运行库'/><author><name>零零碎碎</name><uri>http://www.blogger.com/profile/02492426066009661788</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7675371175644526084.post-5870290605234447329</id><published>2009-01-07T16:53:00.000-08:00</published><updated>2009-01-07T17:56:39.695-08:00</updated><title type='text'>AppEngine Gallary 项目跟踪--持续更新</title><content type='html'>&lt;ol&gt;&lt;li&gt;开发类&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://gaesql.appspot.com/"&gt;http://gaesql.appspot.com&lt;br /&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div style="text-align: left;"&gt;            The application allows you to&lt;br /&gt;                               1. Draw E-R designs,&lt;br /&gt;                               2. Edit tables and rows,&lt;br /&gt;                               3. Manage          keys,&lt;br /&gt;                               4. Create relations (FK constraints),&lt;br /&gt;                               5. Save &amp;amp; Load designs (in progress),&lt;br /&gt;                               6. Import DB schema.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7675371175644526084-5870290605234447329?l=iqiqi.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iqiqi.blogspot.com/feeds/5870290605234447329/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7675371175644526084&amp;postID=5870290605234447329' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7675371175644526084/posts/default/5870290605234447329'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7675371175644526084/posts/default/5870290605234447329'/><link rel='alternate' type='text/html' href='http://iqiqi.blogspot.com/2009/01/appengine-gallary.html' title='AppEngine Gallary 项目跟踪--持续更新'/><author><name>零零碎碎</name><uri>http://www.blogger.com/profile/02492426066009661788</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7675371175644526084.post-615469590533136829</id><published>2008-12-24T23:55:00.000-08:00</published><updated>2008-12-24T23:57:15.222-08:00</updated><title type='text'>收藏 Using Django with Orbited  http://darkporter.com/?p=7</title><content type='html'>&lt;div id="header"&gt;  &lt;div id="headerimg"&gt;   &lt;h1&gt;&lt;a href="http://luxury.daili.name/842/browse.php?u=Oi8vZGFya3BvcnRlci5jb20v&amp;amp;b=5"&gt;Dark Porter&lt;/a&gt;&lt;/h1&gt;     &lt;/div&gt; &lt;/div&gt; &lt;hr /&gt;         &lt;div class="navigation"&gt;        &lt;div class="alignright"&gt;&lt;a href="http://luxury.daili.name/842/browse.php?u=Oi8vZGFya3BvcnRlci5jb20vP3A9OQ%3D%3D&amp;amp;b=5"&gt;Implementing Scrabble in Python&lt;/a&gt; »&lt;/div&gt;   &lt;/div&gt;        &lt;h2&gt;&lt;a href="http://luxury.daili.name/842/browse.php?u=Oi8vZGFya3BvcnRlci5jb20vP3A9Nw%3D%3D&amp;amp;b=5" rel="bookmark" title="Permanent Link: Using Django with Orbited"&gt;Using Django with Orbited&lt;/a&gt;&lt;/h2&gt;          &lt;p&gt;First off, I have no idea why you want to. For most people there isn’t a reason to do this, but I did. I’ll trust you have your reasons as well.&lt;/p&gt; &lt;p&gt;Here’s our end result: Clients (browsers) connect to our Django-powered site and establish a comet connection. Now we can push messages to the clients, right from our Django code, at any time and with as much frequency as we like. Since it’s real streaming comet, each message goes over a persistent connection with no individual overhead.&lt;/p&gt; &lt;p&gt;Prerequisties: I’m assuming you’re using a real Djanjo setup (in a mod_python instance loaded from Apache).&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Apache &lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The first thing to do is put Apache in Worker MPM mode, limited to a single process.  This gives a single instance of mod_python/Django which is called into by many simulateous threads. Doing this allows us to have all waiting comet connections reference the same variables, and it makes it easy to signal the comet threads to wake up when they have something to send.&lt;/p&gt; &lt;p&gt;Making Apache use Worker MPM means recompiling it. I used these configure options, but I’ll admit I’m unclear what overrides what and what is redundant:&lt;/p&gt; &lt;pre&gt;./configure --with-mpm=worker --enable-modules=all --enable-mods-shared=all&lt;br /&gt;--enable-ssl --enable-proxy --enable-proxy-http --enable-rewrite --enable-deflate&lt;/pre&gt; &lt;p&gt;Then you add this to your apache config file. You may need more than 100 threads depending on your application:&lt;/p&gt; &lt;pre&gt;&lt;ifmodule&gt;&lt;br /&gt; ServerLimit          1&lt;br /&gt; ThreadLimit         100&lt;br /&gt; StartServers         1&lt;br /&gt; MaxClients          100&lt;br /&gt; MinSpareThreads      1&lt;br /&gt; MaxSpareThreads     100&lt;br /&gt; ThreadsPerChild     100&lt;br /&gt; MaxRequestsPerChild  0&lt;br /&gt;&lt;/ifmodule&gt;&lt;/pre&gt; &lt;p&gt;&lt;strong&gt;Django&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Set up Djanjo in the normal fashion,  by installing mod_python then creating a Django project and app. I’m on a Mac so my document root is /Library/WebServer/Documents, and I set up my Django app in /Library/WebServer/darkporter. You should have something like this in your httpd.conf, and a Media symlink in Documents pointing to your django’s Media folder.&lt;/p&gt; &lt;pre&gt;&lt;location&gt;&lt;br /&gt; SetHandler python-program&lt;br /&gt; PythonHandler django.core.handlers.modpython&lt;br /&gt; SetEnv DJANGO_SETTINGS_MODULE darkporter.settings&lt;br /&gt; PythonDebug On&lt;br /&gt; PythonPath "['/Library/WebServer'] + sys.path"&lt;br /&gt;&lt;/location&gt;&lt;/pre&gt; &lt;pre&gt;&lt;location&gt;&lt;br /&gt; SetHandler none&lt;br /&gt;&lt;/location&gt;&lt;/pre&gt; &lt;p&gt;&lt;strong&gt;Orbited&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Download and unzip Orbited (I used 0.6.0), and copy the /orbited subfolder under your django app root.&lt;/p&gt; &lt;p&gt;Here’s the idea: Your django app serves up a page on port 80 which includes all the JavaScript to make a comet connection to Orbited (on port 8000), then Orbited proxies over to your Django app which is also listening on port 9000.&lt;/p&gt; &lt;p&gt;The key here is we’ll be adding code to the top level __init__.py file in your Django app. This code only runs once (because of our single-process Apache), and it can set up not only Orbited and our custom comet handler, but it can also spawn any threads that might generate new messages to the client. Say for example your server is running iTunes, and you want to send a comet message whenever a new song plays. You can start a thread that polls iTunes every second and send updated conditions to the client.&lt;/p&gt; &lt;p&gt;First, starting orbited. That’s the easy part. You just add this to __init__.py:&lt;/p&gt; &lt;pre&gt;import thread&lt;br /&gt;from orbited import start&lt;br /&gt;&lt;br /&gt;thread.start_new_thread(start.main, ())&lt;/pre&gt; &lt;p&gt;There’s no reason we have to start Orbited from here, we could do it from the command line with start.py, but putting it here makes everything self-contained. All you have to do is start Apache and everything runs.&lt;/p&gt; &lt;p&gt;You also have to make one small change to Orbited itself, in start.py at the end, change the “reactor.run()” line to:&lt;/p&gt; &lt;pre&gt;reactor.run(installSignalHandlers=0)&lt;/pre&gt; &lt;p&gt;Now add this to the orbited.cfg in your /etc folder:&lt;/p&gt; &lt;pre&gt;[access]&lt;br /&gt;* -&gt; localhost:9000&lt;/pre&gt; &lt;p&gt;&lt;strong&gt;Comet Handler&lt;/strong&gt;&lt;br /&gt;Now the browser should be able to make a successful comet connection to Orbited, but Orbited proxies over to port 9000 and no one’s listening. So we add more code to __init__.py, like this (sorry the indentation is all messed up):&lt;/p&gt; &lt;pre&gt;def listen():&lt;br /&gt; comet_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)&lt;br /&gt; comet_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)&lt;br /&gt; comet_socket.bind( ('', 9000) )&lt;br /&gt; comet_socket.listen(5)&lt;br /&gt;&lt;br /&gt; while 1:&lt;br /&gt;    thread.start_new_thread(comet.handle_request, comet_socket.accept())&lt;br /&gt;&lt;br /&gt;thread.start_new_thread(listen, ())&lt;/pre&gt; &lt;p&gt;This could and probably should use Twisted, but I don’t know twisted very well. Now you’re going to create a comet.py file also at the root of your django project, this will house your comet handler that deals with comet connections on port 9000 (coming from Orbited). What you do here is up to you, but mine looks like this:&lt;/p&gt; &lt;pre&gt;import threading&lt;br /&gt;&lt;br /&gt;signal = threading.Condition()&lt;br /&gt;messages = []&lt;br /&gt;&lt;br /&gt;def handle_request(incoming_socket, incoming_address):&lt;br /&gt; global signal, messages&lt;br /&gt; while 1:&lt;br /&gt;    signal.acquire()&lt;br /&gt;    signal.wait()&lt;br /&gt;    try:&lt;br /&gt;       # Send something useful here&lt;br /&gt;       incoming_socket.send("Comet!")&lt;br /&gt;    except:&lt;br /&gt;       signal.release()&lt;br /&gt;       incoming_socket.close()&lt;br /&gt;       return&lt;br /&gt;    signal.release()&lt;/pre&gt; &lt;p&gt;The thread just blocks until someone calls notifyAll() on the signal. They could do it from anywhere, from a Django view, from the iTunes polling thread I mentioned, from wherever. They’d just say:&lt;/p&gt; &lt;pre&gt;comet.signal.acquire()&lt;br /&gt;# Mess with shared variables, like comet.messages&lt;br /&gt;comet.signal.notifyAll()&lt;br /&gt;comet.signal.release()&lt;/pre&gt; &lt;p&gt;&lt;strong&gt;Apache Proxy&lt;/strong&gt;&lt;br /&gt;We need a couple more things in the httpd.conf now:&lt;/p&gt; &lt;pre&gt;&lt;location&gt;&lt;br /&gt; SetHandler none&lt;br /&gt;&lt;/location&gt;&lt;br /&gt;&lt;br /&gt;&lt;location&gt;&lt;br /&gt; SetHandler none&lt;br /&gt;&lt;/location&gt;&lt;br /&gt;&lt;br /&gt;ProxyPass /tcp http://localhost:8000/tcp&lt;br /&gt;ProxyPass /orbited/ http://localhost:8000/&lt;/pre&gt; &lt;p&gt;/tcp is the path that the Orbited javascript calls for when it tries to connect to the TCPSocket, and proxying it allows the Orbited javascript to use an xhr stream (since it’s the same port and same domain).&lt;br /&gt;/orbited allows us to fetch the orbited static files like javascript, using only a root path. Instead of having to do this which depends on your particular hostname:&lt;/p&gt; &lt;pre&gt;&lt;script src="http://myserver.org:8000/static/Orbited.js"&gt;&lt;/script&gt;&lt;/pre&gt; &lt;p&gt;We can use a nice absolute path instead:&lt;/p&gt; &lt;pre&gt;&lt;script src="/orbited/static/Orbited.js"&gt;&lt;/script&gt;&lt;/pre&gt; &lt;p&gt;&lt;strong&gt;Clientside&lt;/strong&gt;&lt;br /&gt;The serverside should all be in place now. Use “apachectl start” and go to http://localhost and see what happens. If you get an error it will show up in the browser or in the Apache error logs. Assuming you can view a page, now we need to create a comet-enabled page.&lt;br /&gt;Include the Orbited.js script as shown above, then add this javascript to initiate a comet connection:&lt;/p&gt; &lt;pre&gt;var socket = new Orbited.TCPSocket(); // Orbited.settings.port defaults to 8000&lt;br /&gt;socket.onerror = function() { alert('error'); }&lt;br /&gt;socket.onopen = function() { alert('open'); };&lt;br /&gt;socket.onclose = function() { alert('close'); }&lt;br /&gt;socket.onread = function(s) { alert("Received string through comet -- " + s); }&lt;br /&gt;socket.open("myserver.org", 9000);&lt;/pre&gt; &lt;p&gt;Fill in the onread() function with something useful, and away you go!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7675371175644526084-615469590533136829?l=iqiqi.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iqiqi.blogspot.com/feeds/615469590533136829/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7675371175644526084&amp;postID=615469590533136829' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7675371175644526084/posts/default/615469590533136829'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7675371175644526084/posts/default/615469590533136829'/><link rel='alternate' type='text/html' href='http://iqiqi.blogspot.com/2008/12/blog-post_24.html' title='收藏 Using Django with Orbited  http://darkporter.com/?p=7'/><author><name>零零碎碎</name><uri>http://www.blogger.com/profile/02492426066009661788</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7675371175644526084.post-7708677580592475619</id><published>2008-10-28T19:54:00.001-07:00</published><updated>2008-10-28T19:54:35.495-07:00</updated><title type='text'></title><content type='html'>test&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7675371175644526084-7708677580592475619?l=iqiqi.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iqiqi.blogspot.com/feeds/7708677580592475619/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7675371175644526084&amp;postID=7708677580592475619' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7675371175644526084/posts/default/7708677580592475619'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7675371175644526084/posts/default/7708677580592475619'/><link rel='alternate' type='text/html' href='http://iqiqi.blogspot.com/2008/10/test.html' title=''/><author><name>零零碎碎</name><uri>http://www.blogger.com/profile/02492426066009661788</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
