From bit to a heart beat

insane innovations from a sane insanity

Mon Jul 19

Create a web service in Clojure without start/stopping the server

This is a cross-post from SocialCaddy

The problem using Jetty (or Netty or Ring) is that after you start the process, your beloved REPL is “binded” to the server thus forcing you to kill the service, make a change, start the process again, refresh and do it again. Not fun at all. It’s easy to run the process “in the background” and have the REPL available to make changes. 

Let’s create a new project (using lein).

> lein new TinyService

Now, we need  a project.clj (so we can do a lein deps and have everything installed automagically)

> lein deps

Edit core.clj with this:

You can run the service in REPL by (boot) and then you’ll still have access to REPL. You can change stuff, C+c C+c, refresh and voila! You can even connect to web server (to a JVM to be more exact) and make changes without the need for compilation. And all this from your local emacs!

Enjoy!

Comments (View)
Wed May 26
Having a developer write his own unit tests is like asking a crazy man if he’s sane. reddit
Comments (View)
Sun Jan 17

Activerecord in Python: Do it like Rails!

I’ve searched around the net for a nice, clean implementation of activerecord in Python but I found none. There are many better libraries for database abstraction out there in Python but I think that Rails’ “activerecord” way is a breeze and a fun way to access a database.

So, my weekend project was to see whether I could hack together a small activerecord for Python.

The first thing I reeeeaally wanted to do, is to create dynamic queries. What dynamic queries are you ask.

Let’s say you have a database and a table with some fruits fields.

Table: People

Fields: id, name, sex

Using ActiveRecord you can do this:

user = People.find_by_name(“Robert”)

and you’ll get all the People with the name Robert. The magic thing is that you haven’t defined anywhere the function find_by_name. Activerecord has only the function find_by and depending on your search it creates automatically a new function called find_by_name (if the ‘name’ field exists on your table). This is all thanks to Ruby’s method_missing function.

Ruby’s method_missing is called automatically from ruby’s VM everytime a function you tried to call was not found. So, when you called find_by_name, ruby couldn’t find the function and after all the search it went to method_missing. From there, activerecord took control and done it’s magic.

That are many different ways to do it in Python but only one comes close to Rails’ implementation.

Behold: __getattr__

Everytime you call a class attribute, this function is called. So, in Python:

user = User.find_by_name(“Robert”)

calls __getatr__ and if the attribute does not exist, it throws an ‘AttributeError’ exception. That’s the place we are going to put our code and create the dynamic queries.

The most difficult part was this: The function __getattr__ gets one parameter (the attribute) so in this example it was the find_by_name. I had to find a way to pass to __getattr__ the query’s argument.

Behold: Lambda

I know a hobby project of mine is awesome when I have to use lambda (old habits from C and Lisp). Using

lambda value: do_smth(value),

you open up the way for another parameter to join the game (hint: value). So, we have this:

dynamic_query = {

“find_by_”: lambda value: self._find(field, value)

}[query]

This is a dictionary emulating a switch/case in Python with lambdas. If you want to add more functions (insert,update) or more logic (find_by_name_and_sex), this is the place to hack.

Check it online at my bitbucket account and push your changes.

Comments (View)
Wed Jan 6

Nimbuzz, Android and Skype: Put your headphones on!

I love Nimbuzz (loving it since I first learn about it when I was at the Erlang Factory in London and spoke with a guy from Nimbuzz) ‘cause it was running smoothly on my Symbian and allowing me to connect with Skype. So when I got my HTC Hero, it was the first app I was going to install. But Skype(to Skype) didn’t seem to work (couldn’t speak, couldn’t hear).

I tried Fring where everything seemed to be working smoothly and I noticed that a headphones icon was appering on my notification bar eventhough I had no headphones connected. So, I connected my slick HTC Hero headphones, fired up Nimbuzz and tadaaaa!

Maybe this solves the muted mic for the Droid on Nimbuzz. I hope for an update and video call!

Comments (View)

Facebook Connect for web2py

Even though web2py has support for building facebook applications, we didn’t have a way to use Facebook Connect.

I’ve studied many ways (like Facebook’s Javascript API) and checked other frameworks (Rails and Django) and after 4 hours I made a patch to facebook.py that enables web2py (and I’m sure that other python frameworks can use - like webpy) to use Facebook Connect by doing this:

def index():
   connected = facebook_connect(request, facebook_settings)
   if connected:
       user = get_facebook_user(request.facebook)
       response.flash = "Hello ", user       
   return dict(api_key=facebook_settings.FACEBOOK_API_KEY)

Just one line of code and you are done!

You can check a live example here and grub the code from github

Comments (View)
Sat Dec 26

Implementing a Rails-like scaffolding in web2py (but better!)

Sometimes I want to create a better administration panel for our clients. With this hack you can create an add/edit/delete panel for every table you like and extend it easily. in order to use it you just go inside the controllers and add:

@scaffold(None)
def authors():
pass

this will create an admin page (authors) that has all the properties from the table “authors”. if you have to “admin” a different table just put it’s name:

@scaffold("other_table")
def authors():
pass

Read the comments for more hacks. PS: I have also a new version that you can pass custom queries (I’ll keep you updated). PS2: Also a version with DataTables (http://datatables.net/)

You can also chain decorators in order to prevent unauthorized access:

@auth.requires_login()
@scaffold("other_table")
def authors():
pass

Now, the installation:

First, put this code inside a module (or in a separate file in models).

def scaffold(tblname=None, fieldid=None): “”” Decorator that exposes show/add/edit/delete for admin purposes

    You can specify a table name else it will use the
name of the function as table name
You can specify a field id that will be displayed for the record
else it will use the first field value
"""

def decorator_outside(func):

def decorator_inside(*args):

db_name = db # we could get the database name from globals
table_name = func.__name__ if tbl_name == None else tbl_name
if table_name not in db_name.tables:
raise Exception("No table with name '%s' found" % table_name)

form = None
if len(request.args) > 1:
action = request.args[0]
record_id = request.args[1]

if action == 'create':
form = crud.create(db_name[table_name])

elif action == 'show':
form = crud.read(db_name[table_name], record_id)

elif action == 'edit':
form = crud.update(db_name[table_name], record_id)

elif request.args[0] == 'delete':
form = crud.delete(db_name[table_name], record_id)

result = db_name(db_name[table_name].id > 0).select()
func()

return dict(rows=result, cntr_name=table_name, form=form, field_id=field_id)
return decorator_inside

return decorator_outside

The do the action in the controller @scaffold(“other_table”) def authors(): pass

Finally create a view file:

{{extend 'layout.html'}}
{{ include 'scaffold.html' }}

and paste this into your views folder:

{{= form if form != None else "" }}
<br />
<table>
{{ i = 0 }}
{{ for row in rows: }}
{{ i += 1 }}
<tr class="{{='even' if i%2 else 'odd'}}">
<td class='main'><a href="{{= URL(r=request, f=cntr_name+'/show',
args=row.id) }}">{{= row.values()[field_id] }}</a></td>
<td><a href="{{= URL(r=request, f=cntr_name+'/edit',
args=row.id) }}">Edit</a></td>
<td><a href="{{= URL(r=request, f=cntr_name+'/delete',
args=row.id) }}">Delete</a></td>
</tr>
{{ pass }}
</table>

{{ if not len(rows): }}
No records found
{{ pass }}

<br />
<a href="{{= URL(r=request, f=cntr_name+'/create/new') }}">Add new</a>
Comments (View)
Fri Dec 18

Uploading files using CKEditor in web2py

This is the second part of integrating CKEditor in web2py. I should warn you that quotes are messed up in the blog so you can check at web2pyslices for the updated (and ready for copy-paste) version.

What it needs to be done in order to have ckeditor uploading works. First, it needs a “file browser” url. That’s just a form with an upload field where we can use to find and upload files. The think is that we must return the path of the uploaded file BACK to the parent form. The most difficult part is activating the Upload button. That is done by specifying the “filebrowserBrowseUrl”. So, here it goes!

Let’s add a new table that will hold our files:

import datetime;
timestamp = datetime.datetime.today()
db.define_table('files',
Field('title', 'string'),
Field('uploaded_data', 'upload'),
Field('created_on','datetime',default=timestamp))

db.files.title.requires = IS_NOT_EMPTY()
db.files.uploaded_data.requires = IS_NOT_EMPTY()

Now, lets add an action the our controller

def upload_file():
url = ""

form = SQLFORM(db.files, showid=False)
if form.accepts(request.vars, session):
response.flash = T('File uploaded successfully!')
url = URL(r=request, f="download",
args = db(db.files.title == request.vars.title).select(orderby=~db.files.created_on)[0].uploaded_data)
return dict(form=form, cknum=request.vars.CKEditorFuncNum, url=url)

and a view upload_file.html:

{{extend 'layout.html'}}

<h2>Upload file</h2>
{{=form}}


{{ if url != "": }}
<script type="text/javascript">
window.opener.CKEDITOR.tools.callFunction({{=cknum}}, '{{=url}}');
</script>
{{ pass }}

Then, lets add the javascript files to our layout AFTER web2py_ajax.html:

 <script type="text/javascript" src="{{=URL(request.application,'static','js/ckeditor/ckeditor.js')}}"></script>

Finally, lets create a test page:

{{extend 'layout.html'}}

{{=form}}

<script type="text/javascript">
var ckeditor = CKEDITOR.replace('page_body', {
filebrowserBrowseUrl : "{{=URL(request.application, c='default', f='upload_file')}}",
//filebrowserUploadUrl : "{{=URL(request.application, c='default', f='upload_file')}}",
});
</script>

We are ready!

Comments (View)
Wed Nov 18

Creating unicode permalinks in Python (even from Greek!)

Optimizing this blog post, which shows you how to create a greek to greeklish “translator”, I’ve created a permalink function that creates urls from greek titles (but you can use your language).

Enjoy!

def create_permalink(s):
“”“
Create greeklish permalinks.
Also works for english.
“”“
import string
import re

input_string = s.lower().decode(‘utf-8’).encode(‘iso-8859-7’, ‘replace’)
from_chars = ‘αβγδεζηθικλμνξοπρσςτυφχψωάήέίόύώϊ’.decode(‘utf-8’).encode(‘iso-8859-7’, ‘replace’)
to_chars = ‘abgdezh8iklmn3oprsstufxywaheiouwi’

translation_table = string.maketrans(from_chars, to_chars)
input_string = string.translate(input_string, translation_table)

return re.compile(“\W+”, re.UNICODE).sub(“_”, input_string)


Comments (View)
Fri Oct 30

Using widgets in web2py (integrating CKEditor)

Although web2py comes with an integrated editor, I really like ckeditor and using it for a text field is trivial using widgets!

First, install ckeditor (put the ckeditor inside a js/ckeditor file in your static folder and include it) :

<script type=”text/javascript” src=”{{=URL(request.application,’static’,’js/ckeditor/ckeditor.js’)}}”></script>

After that, we define a ‘body’ text field (or whatever name you like):

db.define_table(‘page’,
# more Fields …
Field(‘body’, ‘text’))

Then, inside your db.py (or to another file in your models directory) put the widget:

def advanced_editor(field, value):
return TEXTAREA(_id = str(field).replace(‘.’,’_’), _name=field.name, _class=’text ckeditor’, value=value, _cols=80, _rows=10)

and use the widget

db.page.body.widget = advanced_editor

From now, SQLFORM will use ckeditor to show/edit/save data!

CkEditor in web2py

Comments (View)
Wed Oct 7

Creating a dropdown with country names in web2py

There are many ways to create a dropdown that includes all countries in web2py but the most pythonic way goes like this:

Create a module (let’s name it countries.py) and put a list of countries :

COUNTRIES=(‘United States’, ‘Afghanistan’, ‘Albania’, ‘Algeria’, ‘Andorra’, ‘Angola’, ‘Antigua and Barbuda’, ‘Argentina’, ‘Armenia’, ‘Australia’, ‘Austria’, ‘Azerbaijan’, ‘Bahamas’, ‘Bahrain’, ‘Bangladesh’, ‘Barbados’, ‘Belarus’, ‘Belgium’, ‘Belize’, ‘Benin’, ‘Bhutan’, ‘Bolivia’, ‘Bosnia and Herzegovina’, ‘Botswana’, ‘Brazil’, ‘Brunei’, ‘Bulgaria’, ‘Burkina Faso’, ‘Burundi’, ‘Cambodia’, ‘Cameroon’, ‘Canada’, ‘Cape Verde’, ‘Central African Republic’, ‘Chad’, ‘Chile’, ‘China’, ‘Colombia’, ‘Comoros’, ‘Congo’, ‘Costa Rica’, “C&ocirc;te d’Ivoire”, ‘Croatia’, ‘Cuba’, ‘Cyprus’, ‘Czech Republic’, ‘Denmark’, ‘Djibouti’, ‘Dominica’, ‘Dominican Republic’, ‘East Timor’, ‘Ecuador’, ‘Egypt’, ‘El Salvador’, ‘Equatorial Guinea’, ‘Eritrea’, ‘Estonia’, ‘Ethiopia’, ‘Fiji’, ‘Finland’, ‘France’, ‘Gabon’, ‘Gambia’, ‘Georgia’, ‘Germany’, ‘Ghana’, ‘Greece’, ‘Grenada’, ‘Guatemala’, ‘Guinea’, ‘Guinea-Bissau’, ‘Guyana’, ‘Haiti’, ‘Honduras’, ‘Hong Kong’, ‘Hungary’, ‘Iceland’, ‘India’, ‘Indonesia’, ‘Iran’, ‘Iraq’, ‘Ireland’, ‘Israel’, ‘Italy’, ‘Jamaica’, ‘Japan’, ‘Jordan’, ‘Kazakhstan’, ‘Kenya’, ‘Kiribati’, ‘North Korea’,’South Korea’, ‘Kuwait’, ‘Kyrgyzstan’, ‘Laos’, ‘Latvia’, ‘Lebanon’, ‘Lesotho’, ‘Liberia’, ‘Libya’, ‘Liechtenstein’, ‘Lithuania’, ‘Luxembourg’, ‘FYROM’, ‘Madagascar’, ‘Malawi’, ‘Malaysia’, ‘Maldives’, ‘Mali’, ‘Malta’, ‘Marshall Islands’, ‘Mauritania’, ‘Mauritius’, ‘Mexico’, ‘Micronesia’, ‘Moldova’, ‘Monaco’, ‘Mongolia’, ‘Montenegro’, ‘Morocco’, ‘Mozambique’, ‘Myanmar’, ‘Namibia’, ‘Nauru’, ‘Nepal’, ‘Netherlands’, ‘New Zealand’, ‘Nicaragua’, ‘Niger’, ‘Nigeria’, ‘Norway’, ‘Oman’, ‘Pakistan’, ‘Palau’, ‘Palestine’, ‘Panama’, ‘Papua New Guinea’, ‘Paraguay’, ‘Peru’, ‘Philippines’, ‘Poland’, ‘Portugal’, ‘Puerto Rico’, ‘Qatar’, ‘Romania’, ‘Russia’, ‘Rwanda’, ‘Saint Kitts and Nevis’, ‘Saint Lucia’, ‘Saint Vincent and the Grenadines’, ‘Samoa’, ‘San Marino’, ‘Sao Tome and Principe’, ‘Saudi Arabia’, ‘Senegal’, ‘Serbia and Montenegro’, ‘Seychelles’, ‘Sierra Leone’, ‘Singapore’, ‘Slovakia’, ‘Slovenia’, ‘Solomon Islands’, ‘Somalia’, ‘South Africa’, ‘Spain’, ‘Sri Lanka’, ‘Sudan’, ‘Suriname’, ‘Swaziland’, ‘Sweden’, ‘Switzerland’, ‘Syria’, ‘Taiwan’, ‘Tajikistan’, ‘Tanzania’, ‘Thailand’, ‘Togo’, ‘Tonga’, ‘Trinidad and Tobago’, ‘Tunisia’, ‘Turkey’, ‘Turkmenistan’, ‘Tuvalu’, ‘Uganda’, ‘Ukraine’, ‘United Arab Emirates’, ‘United Kingdom’, ‘Uruguay’, ‘Uzbekistan’, ‘Vanuatu’, ‘Vatican City’, ‘Venezuela’, ‘Vietnam’, ‘Yemen’, ‘Zambia’, ‘Zimbabwe’)

then import it to db.py

from applications.yourapplicationname.modules.countries import *

and just “map” the whole list to a database field

db.shipping_info.countries.requires = IS_IN_SET(COUNTRIES)

Now, when you render the field using SQLFORM in your view, a dropdown (select) will be created automatically including all the countries.

Yeap, SQLFORM rocks.

Enjoy!

Comments (View)