Not *that* inventive, but I somehow didn't think of it before:
tail -f log/development.log | grep Rendered
Mostly python-related stuff.
Not *that* inventive, but I somehow didn't think of it before:
tail -f log/development.log | grep Rendered
Autor: Konrad o 05:49 0 komentarze
There IS a simple solution to work conveniently in git-svn with repository that has svn:externals set. You can clone all repositories to seperate trees, and instead of watching svn:externals, make hard links to the trees you need (remember to ignore them in git). The problem is you can't have hard links to directories... unless you're using OS X Leopard (they implemented it in order to get Time Machine to work).
This ability isn't exposed to the command line (ln makes an explicit check to prevent you from doing that), but the code to have it working(scroll down to listing 4) is trivial.
Update: When working with hard-linked directories, remember to be careful when unlinking them: rm wouldn't unlink the directory unless provided with "-r" option, which deletes everything recursively, leaving other hard links to that directory empty.
Autor: Konrad o 00:04 0 komentarze
I finally invested enough time in reading wget's man page to be able to download file hierarchies exposed through http file server. The magic command is:wget -r -np -nH --cut-dirs=2 http://example.com/some/nested/directory
The switches mean:
Autor: Konrad o 01:36 0 komentarze
If you want to find out how to test you GAE apps, check out these two URLs first:
http://groups.google.com/group/google-appengine/msg/9132b44026040498
http://farmdev.com/thoughts/45/testing-google-app-engine-sites/
I want to show you how to clear the datastore quickly (yep, only that :>):
from google.appengine.api import apiproxy_stub_map
def clear_datastore():
datastore = apiproxy_stub_map.apiproxy.GetStub('datastore_v3')
datastore.Clear()
Autor: Konrad o 10:42 1 komentarze
Etykiety: gae, google app engine, testing
It's child easy, but not googleable yet. I used reportlab - a handy, pure-python pdf library. Here are the steps:
svn co http://www.reportlab.co.uk/svn/public/reportlab/trunk \
reportlab
import wsgiref.handlers
from google.appengine.ext import webapp
from reportlab.pdfgen import canvas
class MainPage(webapp.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'application/pdf'
p = canvas.Canvas(self.response.out)
p.drawString(100, 750, "Hey, it's easy!.")
p.showPage()
p.save()
def main():
application = webapp.WSGIApplication([('/', MainPage)], debug=True)
wsgiref.handlers.CGIHandler().run(application)
if __name__ == "__main__":
main()
The key is the canvas instantiation. The constructor takes a file-like object and writes into it. You might have noticed that the code is heavily inspired by this tutorial. The only difference is the creation of canvas.Autor: Konrad o 05:40 8 komentarze
Etykiety: google app engine, pdf, pdf generation, python
Having investigated the new Google D&S forms feature, I decided to create a proof-of-concept blog application (OK - calling it an application is a *bit* an overstatement). It has some basic features, like form for entering entries and a feed. I doesn't have a site and is pretty much crippled. Still, quite good for 0 lines of code.
Here's the feed
And here's the new entry form. Feel free to post.
Autor: Konrad o 11:27 1 komentarze
Hey look! This guy implemented Arc's function-negation operator in Chicken. And he claims to be a Pythoneer, traitor ;-) !
I just investigated the possibilities of doing more or less the same thing in Python. Of course: you can't change the syntax, and you can't change default function's behaviour (which is not having "~" operator implemented). Or can't you?
Let's start with something more explicit for a moment. Nothing prevents us from creating a callable decorator that implements __invert__ something like this:
class invertible:
def __init__(self, foo):
self.foo = foo
def __call__(self, *args, **kwargs):
return self.foo(*args, **kwargs)
def __invert__(self):
def wrapper(*args, **kwargs):
return not self.foo(*args, **kwargs)
return wrapper
Implementing __init__ enables us to call invertible() with an argument, and implementing __call__ makes the instances of our class callable. These two work together in a way that an ordinary decorator works: It's a callable, that takes a callable and returns another callable - easy, huh?truth = invertible(lambda: True)
not_truth = ~truth
assert truth()
assert not not_truth()
This implementation, even though it's easy, is not finished yet. The inverted value is a regular function, which means, that we couldn't invert it again. The easy solution to that is decorating the wrapper:class invertible:
# ...
def __invert__(self):
@invertible
def wrapper(*args, **kwargs):
return not self.foo(*args, **kwargs)
return wrapper
But this would cause the wrappers to accumulate on inverting. We can also check explicitly if we get an invertible on input and set a switch on each instanceclass invertible:
def __init__(self, foo):
self.foo = foo
self.inverted = False
def __call__(self, *args, **kwargs):
if self.inverted:
return not self.foo(*args, **kwargs)
else:
return self.foo(*args, **kwargs)
def __invert__(self):
ret = invertible(self.foo)
ret.inverted = (not self.inverted)
return ret
Now, with the decorator ready, you can do some *evil* magic with frames and namespaces in order to decorate everything in scope, but I'm leaving it as an exercise to readers ;P
Autor: Konrad o 05:00 5 komentarze
The first Cracow Python meetup was a huge success! With over 60 people turning up (some of them having travelled up to 3 hours(!) to get there), four presentations, and plans for next event in mind. What's even better - there are going to be three of us now to organise the next meetings. What's even *more* than better - the lectures from now on will be recorded and streamed live. Unfortunately - most of them will be in polish, but foreign speakers are also very welcome, so don't hesitate and come to Cracow! The following meetup takes place on the 21st of February.
And here are the photos.
Autor: Konrad o 11:45 1 komentarze
Running all the tests for our rails app took around 2 minutes on other machines and over 15 on mine.
Remove all network locations from System Preferences and put them back again.
I reduced the problem to a single test case with a single test method with a single line. Having no idea how exactly Rails Does Stuff, I ended up putting parts of debug output and tracing rails' inner paths this way. I got to before_filters, then spotted the filter that caused the problem - it was the "black-list" check (provided by a plugin). Obviously, it was a single line of the file: the url resolution.
Now, I was scared - it couldn't be ruby's fault! Fortunately, it wasn't: analogous python library was slow as well. Actually they didn't work at all. Even pinging a non-existent url took 7secs, and on ALL other machines (running various OS's) it took an instant. The guys from #ruby channel at freenode were helping me for around 2 hours (thanks a lot!), but still nothing seemed to fix the problem. I got pretty convinced, however, that my problem was caused by a bug in Leopard's TCP/IP implementation. Feeling a bit more firmly in the topic, I started searching in forums. And there it was: on the ruby forum. I followed the most crazy tip and found out why it was the last message in the thread.
Autor: Konrad o 15:16 0 komentarze
Using sick aliases for common methods
irb(main):003:0> def putse *args
irb(main):004:1> puts args
irb(main):005:1> end
=> nil
irb(main):006:0> putse "lol"
lol
=> nil
irb(main):007:0>
Autor: Konrad o 06:00 0 komentarze
Driven mad by insanely active ruby community in Cracow, I decided to take the matter into my own hands and get pythonistas to meet. I was surprised by how easy it seems to be - the room is provided by my university, blogger helped me create something other people could link to (sorry - it's polish only), I found programmers who have something to say and asked couple of news sites and blogs to announce the event. Let's hope everything will go as planned.
Photo by Pete Reed
Autor: Konrad o 14:53 0 komentarze
If you're using Selenium table tests for functional testing of your web app, you could have tried testing for browser specific issues. I used selenium vars for that (here in rsel format).store_eval "if(navigator.userAgent.toLowerCase().indexOf('safari')\
!= -1){'some_locator';} \
else {'some other locator';}",
'specific_part'
assert_element_present '//div//${specific_part}'
*But* most probably, there should be a better way to do this. We used the trick above to look for specific inline style, which is handled differently in safari and firefox ( a space added after a semicolon in safari). We eventually found assert_element_visible.
Autor: Konrad o 05:25 0 komentarze