Friday, December 30, 2011

Flask-Jasmine: Execute Jasmine tests within Flask

Just finished Flask-Jasmine extension to execute beautiful Behavior Driven tests for Jasmine in JavaScript.

Such extensions already exists for Django and for Rails. Now it's available for Flask too.

Install with pip:

pip install Flask-Jasmine

Detailed instruction about configuration and usage

Friday, December 9, 2011

Update: JsLint Checker for Sublime Text 2 with jslint4java

Very important update of JsLint Checker Plugin for Sublime Text 2: I've moved execution of jslint4java (the tool which make lint checks) into separate thread so now plugin becoming usable for production/daily usage.

Execution in separate thread is important difference from other *-lint plugins – you don't need to wait with blocked editor area until jslint finish the work. Now all of it will be done separately from main editor thread and you can continue to work.

Next steps for this plugin are:
  1. Add support of Sublime Package Control
  2. I want to add support of PyLint, PEP8 and PyFlakes support
Check it out on GitHub

Tuesday, December 6, 2011

JsLint Checker for Sublime Text 2 with jslint4java

Just finished small JsLint Checker for Sublime Text 2. Configuration of two found on github packages was quite non-trivial from my point of view.

I think that clean code is great improvement of development process and speed of development. Also JsLint is very good tool to avoid stupid errors like variables global scope leaks and so on.

Check it out on github

Sunday, September 11, 2011

How to discover unit tests from your project

Within code snippet below implemented very primitive way to collect your unit tests within your project.  This is not for real project - I know at least two of fancy discovering tools - it's nose and discover , which do same thing in more convenient and accurate way.

I was curious and I did it.


# -*- coding: utf-8 -*-
import os
import sys
import unittest


FILE_ABSPATH = lambda p: os.path.dirname(os.path.abspath(p))
COMPARE_DIRS = lambda a, b: FILE_ABSPATH(a) == FILE_ABSPATH(b)


def collect_tests():
    """
    Function to collect tests from whole project
    """

    basedir = os.path.abspath(os.path.dirname(__file__))
    main_module = os.path.basename(basedir)

    test_file = "tests.py"
    test_dir = "tests"
    tests = []
    new_locals = {}

    for root, dirs, files in os.walk(basedir):
        if test_file in files and \
            os.path.join(root, test_file) != os.path.abspath(__file__):
            tests.append(os.path.join(root, test_file))

        if os.path.dirname(root) == test_dir:
            tests.append(root)

    for test in tests:
        test_path = test.replace(basedir, '').replace('.py', '')
        module_name = "%s%s" % (main_module, test_path.replace('/', '.'))
        __import__(module_name)

        module = sys.modules[module_name]

        for cls in dir(module):
            attr = getattr(module, cls)
            try:
                attr.__module__
            except AttributeError:
                continue

            # we don't want to import anything from current file
            if COMPARE_DIRS(sys.modules[attr.__module__].__file__, __file__):
                continue

            try:
                if issubclass(attr, unittest.TestCase):
                    new_locals[cls] = attr
            except TypeError:
                pass

    return new_locals

# execute tests
if __name__ == '__main__':
    locals().update(collect_tests())
    unittest.main()

Wednesday, June 15, 2011

django-dtpanel-htmltidy: Custom Django Debug Toolbar panel to validate your HTML

Custom panel form Django Debug Toolbar which display HTML Validation errors and warnings.

Install with PIP:

pip install django-dtpanel-htmltidy

Configuration instructions on github


Compatible with Django 1.1.1 and higher and Django Debug Toolbar 0.8.2 and higher.


Preview:



App on:
Thanks to Rob Hudson and Enrique Bastos for the tip about custom panel.

Thursday, May 26, 2011

Two useful enhancements for Django Debug Toolbar

Sometimes on my work I experience two typical issues: first one is that on unknown projects I don't know what objects was changes, how much objects was changed and what is deleted. To find out what's going on the current page(s) I have to study code of views, internal methods etc. Sometimes it's really pain in the ass, for example if I work on satchmo-based projects.

Another typical issue is hard way to keep valid HTML during long-term development. I don't want to add plugins to my browser which will validate my html. But I still need to develop clean and transparent HTML code. So I made decision to develop additional HTML Validator panel for Django Debug Toolbar.


Past month I've done two panels (screenshots below):

  1. State Debug Panel – debug_toolbar.panels.state.StateDebugPanel
  2. HTML Validator Debug Panel – debug_toolbar.panels.htmlvalidator.HTMLValidationDebugPanel
All of the code was merged with current master of django-debug-panel and available on github



Tuesday, May 3, 2011

Three easy rules about parts of code of apps within django project

Very easy convention about parts of code of apps within django project:

  • Any functions which aren't views shouldn't be placed in views.py
  • Any functions related to work with forms should be in forms.py and be method of the form class
  • Any function which used by more than one view/form/function should be saved in utils.py

Sunday, March 27, 2011

Issues using django-compress and django.contrib.staticfiles from django 1.3

There is no way to use both django-compress and django.contrib.staticilfes from new django 1.3. MEDIA_URL and MEDIA_ROOT hardcoded into django-compress utility functions so here is
my fork of django-compress on github with fix.

I've added two new settings COMPRESS_URL and COMPRESS_ROOT which points by default to MEDIA_URL and MEDIA_ROOT respectively for backward compatibility.

django-compress is extremely useful tool which provide possibility to organize your JavaScript and CSS files around your project. Also there is a couple of useful features like support of YUI compressor and building of bunch of JavaScript or CSS files into one.

Read more about django-compress

direct_to_template generic view class-based replacement for django 1.3

I was in love with direct_to_template shortcut from django.views.generic.simple

Update: It was my lack of attention to the docs. new render shortcut do the same thing as code below

It's extremely useful to use direct_to_template instead of render_to_response because there is no necessary to put RequestContext to direct_to_template shourcut. But now it's deprecated so I decided to replace it with small class-based view which do same thing as old direct_to_template but – without restriction of new TemplateView where is no way to put extra context.

from django.views.generic.base import TemplateResponseMixin
from django.template import RequestContext


class RenderTemplate(TemplateResponseMixin):
    """django 1.3+ Class-Based replacement for
       django.views.generic.simple.direct_to_template
       Usage:
        context = {}
        return RenderTemplate.view(context, \
            request=request, template_name="main.html")
    """
    @classmethod
    def view(cls, context, render_args={}, **initkwargs):
        obj = cls()
        for key, val in initkwargs.iteritems():
            setattr(obj, key, val)

        return obj.render_to_response(context, **render_args)

    def render_to_response(self, context, **kwargs):
        return super(RenderTemplate, self)\
                    .render_to_response(RequestContext(self.request, \
                        context), **kwargs)

Wednesday, March 2, 2011

Disqus experience - cache of model's related fields

Very interesting tricks from Disqus: Scaling The World’s Largest Django Application

The main idea to retrieve related fields by two requests instead of 1 + 25 sql requests using post.user

Such situation caused in several projects simultaneously so I working on optimization things right now.

# cache
posts = Post.objects.all()[0:25]

users = dict(
    (u.pk, u) for u in \
    User.objects.filter(pk__in=set(p.user_id for p in posts))
)

for p in posts:
    p.__user_cache = users.get(p.user_id)


And don't forget about SQL indexes - in all cases when field used in ORDER or WHERE sql statements it will increase performance a lot

Friday, January 7, 2011

LinkShare Pixel Tracking template tag for usage with Satchmo

I've implemented LinkShare Pixel Tracking for Satchmo-based stores — Django Snippet #2314. Very simple template tag which use info from current order and generate Pixel Tracking image link.