Wednesday, November 21, 2012

RadioTray cp-1251 support in Ubuntu 12.04


  1. sudo gedit /usr/share/pyshared/radiotray/AudioPlayerGStreamer.py
  2. find self.eventManager.notify(EventManager.SONG_CHANGED, metadata)
  3. before it put:

if(metadata['title']):
  metadata['title'] = metadata['title'].encode('latin-1').decode('cp1251').encode('utf8')


Saturday, November 17, 2012

Installing ubuntu 12.04 on SSD OCZ Agility 3

To allow fdisk to properly align partition, use

    fdisk -cu /dev/sda

and use start sector 2048 (it will be default start sector)


Monday, November 12, 2012

jQuery-File-Upload Express.js Middleware

I really like jQuery-File-Upload plugin, but it missed integration with Express.js. I ended up with adapting their node code as a middleware for Express.js. Example Express.js integration:

    var express = require("express"),
        upload = require('jquery-file-upload-middleware');
 
    var app = express();
    app.configure(function () {
        ...
        app.use('/upload', upload({
            uploadDir: __dirname + '/public/uploads',
            uploadUrl: '/uploads/'
        }));
        app.use(express.bodyParser());
        ...
    });



This way upload middleware will be tied to /upload path, in the frontend you use /upload as url to upload files:

   <input id="fileupload" type="file" name="files[]" data-url="/upload" multiple>
   <script>$('#fileupload').fileupload({ dataType: 'json' })</script>
 
 
Other options and their default values:

    tmpDir: '/tmp',
    maxPostSize: 11000000000, // 11 GB
    minFileSize: 1,
    maxFileSize: 10000000000, // 10 GB
    acceptFileTypes: /.+/i,
    // Files not matched by this regular expression force a download dialog,
    // to prevent executing any scripts in the context of the service domain:
    safeFileTypes: /.(gif|jpe?g|png)$/i,
    imageTypes: /.(gif|jpe?g|png)$/i,
    imageVersions: {
        thumbnail: {
            width: 80,
            height: 80
        }
    },
    accessControl: {
        allowOrigin: '*',
        allowMethods: 'OPTIONS, HEAD, GET, POST, PUT, DELETE'
    }
 

IMPORTANT:  jquery-file-upload-middleware should be registered before express.bodyParser(), or else upload progress events will not fire.

Get the code

Friday, September 28, 2012

Sequelize Asynchronous Validation

The most frustrating flaw of the Sequelize is it's validation model - it simply doesn't allow asynchronous validations. If you want to check uniqueness of the email in database, you will end up writing this validation in the controller.

However, here is a solution. It is a fork of sequelize-1.5.0. Instead of calling model.validate() and waiting for error, you register success and error callbacks:
model
    .validate()
    .success(function () {
         model.save();
    })
    .error(function (errors) {
        // errors = { field1: error, field2: error} as 
        // if returned from old .validate() method
    });
 
It breaks the old way of user-defined validations, but brings this missing flexibility to validation. Here is sample model
    var User = sequelize.define("User", {
        name: {
            type: DataTypes.STRING,
            validate: {
                notEmpty: true
            }
        },
        email: {
            type: DataTypes.STRING,
            validate: {
                isEmail: true,
                isUnique: function (value, next) {
                    if (value) {
                        User
                            .find({ where: { email: value }})
                            .success(function (user) {
                                if (user) {
                                    next('Already taken')
                                } else {
                                    next()
                                }
                            })
                            .error(function (err) {
                                next(err.message);
                            });
                    } else {
                        next("String is empty");
                    }
                }
            }
        },
        password: {
            type: DataTypes.STRING,
            validate: {
                len: [4, 10]
            }
        },
        verifyPassword: {
            type: DataTypes.STRING,
            validate: {
                isSame: function (value, next) {
                    if (value == this.values.password)
                        next();
                    else
                        next('Passwords differ');
                }
            }
        },
        confirmed: {
            type: DataTypes.BOOLEAN,
            defaultValue: false
        },
    });
Note email.validate.isUnique function - it gets an extra parameter 'next', which is a callback used to report error back to sequelize. Calling next("error message") will report field validation error, while calling next() without parameters will report success.

Another less significant, but still valuable benefit of this fork is that custom validation functions are called now within model context, so that you can compare current field with another field, see verifyPassword.validate.isSame above.


I'm not sure though whether these changes will ever be accepted back to sequelize, since they break compatibility.