Первые проблемы на пути к Вконтакт-iframe приложению

May 22nd, 2010

1. Как создать приложение. Вообще самая первая проблема, как ни странно, была в нахождении кнопки - “Создать приложение”. Для тех кто ещё ничего не пробовал создавать, рассказываю, что в основном вся информация и эта самая кнопка сосредоточена на странице, которая возникает после нажатия на ссылку в самом низу всех страниц и называеться “разработчикам”. Вот её ссылка - http://vkontakte.ru/pages.php?act=developers. И далее на ней сверху, в области на которую почему то никогда не смотриш, стоит синяя кнопка “Создать приложение”.

2. Где искать ответы. Информация, новости, появляеться в обсуждениях одной единственной группы номер которой 1. Внутри обсуждений гдето на сотых-тысячных страницах в большой куче, где мало уже кто что замечает, капошаться людишки, большая половина вопросов, которых, засираються вопросами следующих участников и вот так они процветают. В принципе сначало мне казалось идеальным реализовывать свои идеи через UserAPI, но похоже я был такой один. Её не воспринимали версией Facebook Connect, что правда изменилось через два месяца, когда вышло Open API.

3. Как работает защита информации пользователей. Сначало я не мог понять, можно ли сохранять в базу данных пользователей и делать с ней всё что мне захочеться, для меня это было странно. Вообщем можно и нужно. Схема работает очень просто, типа как приближённые монарха, нравишся власти ты там, ненравишся - нет тебя. Так что ступать надо осторожно и всё время следить за постоянно изменяющимися правилами приложения.

4. Приложение не обязано выдавать надпись “Добавьте приложение на страницу”. Сначало я думал что без согласия, будут недоступны какие то функции, совсем нет, просто все поняли, что раскрутиться можно только заставляя всех ставить приложения. Мой первый шок.

5. Когда начинаеш вызывать функции, они сначало выдают ошибку. Вот что я вам советую сначало проверьте что поставили выпадающий список Состояние в “Приложение включено” и не долбитесь c test_mode. Даже незнаю что это, но когда перестал использовать это всё, стало работать.

6. Кто видит ваше приложение? Тут такая идея что его никто не видит, пока не получите разрешение от администрации. Однако, те кто в группе, которая привязана к приложению, способны его видеть. Однако у меня так и не вышло добавить приложение в группу, пока оно было не авторизованным.

7. Url на ваш сайт. Приложение нужно как-то тестировать пока разрабатываеш, а у урлов есть весьма серьозные ограничения. Не поддерживаеться localhost, хотя могли бы. По IP адресу на собственную машину - работает, но только по 80му порту. Плюс, я всё таки пришёл к тому что выгодней, раз взять тестовый урл, который они посылали и использовать его без самого вконтакта, но конечно не так натурально.

8. Есть очень полезная весчь, как первый результат, пока что мне даже кажеться ни разу не понадобилось вызывать функции во время работы приложения, просто загружаю всё в начале при помощи execute, очень удобно.

Comments inside url(”../img.jpg” /*comment*/)

October 8th, 2009

Found maybe a bug of opera’s CSS engine, also it was in opera 10. Handling of comments inside CSS rules in FF and IE works normal, in opera causes exception.

.class { background: url("..img.jpg" /*comment*/) }

Django logging to a file

August 29th, 2009

For last monthes, part of time I spent on developing own project on django in social area. One of my problem was lack of builtin logging system that I could call in any place with very easy structure like:

log.error(’message’)

I knew python has logging system, so I decided to use it, and reduce to this style.

# common/__init__.py
import logging
import logging.handlers
import os
import settings

LOG_DIR = settings.PROJECT_PATH + '/logging'

if not os.access(LOG_DIR, os.F_OK):
	os.mkdir(LOG_DIR)

# Set up a specific logger with our desired output level

log = logging.getLogger('MyLogger')
log.setLevel(logging.DEBUG)

# Add the log message handler to the logger
handler = logging.handlers.RotatingFileHandler(
	          LOG_DIR + '/log', maxBytes=500000, backupCount=2)

handler.setFormatter(logging.Formatter("%(asctime)s - %(message)s"))

log.addHandler(handler)

settings.PROJECT_PATH - its not standart path, simply absolute directory path to a project. I like to put it in settings like this - “PROJECT_PATH = os.path.abspath(os.path.dirname(__file__))”

Than I create directory if its not exists, and all logging is going to one big file. I am not sure, is it a good idea, or how long is this a good idea, for developing its normal. Latter we can divide them by level, for example.

In my project I have independent app, with all general functionality I use everywhere, this is such as logging, view shortcuts for json and html, utils functions. I called it common, and to use this logging only thing you need is put “from common import log” in the beginning of any module.

Django inheritance + include tag

August 28th, 2009

You remember in asp.net many general things are solved through idea of templates. For example, if you want to return a list of things, you generally generate DataSource and by each element use it for some template. It looks like this:

<asp:Repeater>
     <ItemTemplate> Hi, there <%=Eval('SomeField') %> </ItemTemplate>
</asp:Repeater>

Unfortunatelly when I began developing with django, i didnot find anything similar, besides this “inheritance” something similar to Master/Page idea. There where blocks and extends tags. Also there were include tag and to put inside a bit different context you need to make special tag - like this:

from django import template
register = template.Library()

@register.inclusion_tag('post_short.html')
def post_view(post, isowner):
     return {'post': post, 'isowner': isowner }

Imagine, you have a blog with list of posts, and you wonna reuse post in different situations, know what you should do? You should hard coded it in special templatetag, so small code - thanks to inclusion_tag attribute. There were so many talks about “DRY” principle, and django developers didnot even understood that webapp needs a little reuse in theire blocks. Is this so hard to make syntax like:

{% include "template.html" ctx.param %}

Later, I’ll add this also, but for now I am talking about even uglier stuff - when you need not only change context, but put in it some html. Its stupid to set html through variable, in best case we really need “block” functionality.

So I googled, post a question to stackoverflow “Mix of Inheritance + Inclusion tags” and there were no results. I also tried to put feature to django bug list, they said “its not a place for how-to”.

I dont know what they didnot like in my case. Thats why I decide to put it here. Idea is “if you have template, you wonna include it in your page, but with small changes on 10% for every concrete situation”. I thought it should be something middle between inheritance and include idea. It should look like below:

Inside main.html

{% include "control.html" %}
         {% part one %} put inside {% endpart %}
         {% part two %} put inside one more {% endpart %}
{% endinclude %}

Inside control.html:

<div>
     something in control
     {% part one %}{% endpart %}
     more
     {% part two %}{% endpart %}
      end the footer
</div>

Very early version of this templatetag you can see in my project. Please post any issues and bugs. I know its not ready, its not working with “standart include”, but in concrete case, its doing job.

Url change in JavaScript

May 22nd, 2009

On server when I create urls for my anchors I used several approaches:

If asp.net mvc, I used links generated from action methods, like
Url.Link(c => c.Action(param))

If django, I used url tag in template and resolve in view

But on client, I am not always know real parameters, and I need to put them on client. For example, if you create anchors from javascript array. For that purpose I created small library, that ease life of people, that need to modify some url. You can grab sources from
url-manage-js

Below is use case:

‘http://www.google.com’.url()
.attr(’port’, ‘80′)
.param(’search’, ‘js’)
.string() == ‘http://www.google.com:80?search=js’

kick it on DotNetKicks.com

JQuery Shortcuts: $.showhide(length > 0)

March 5th, 2009

Some time ago, I found, that my code very often include such snippet:

if (length > 0)
{
     $('div').show();
}
else
{
     $('div').hide();
}

Such scenario could exists in case of paging or some data control, when we need hide empty things. In that case code stay: ugly and big, duplicated, and brokes chain. The first what was in mind, to replace it with ternar operation, but that would not solve repeating selector. So I understood, I need small plugin, that could handle boolean operations for me. The plugin interface begin to look like:

$('div').attr('width', '10px').showhide(length > 0)

Take a look on the code of plugin:

jQuery.fn.showhide = function(pf) {
    return this.each(function(i, n) {
        // shows if true, and hides if boolean false
        pf ? $(this).show() : $(this).hide();
    });
}

kick it on DotNetKicks.com

JQuery Shortcuts: $.hoverClass(’over’)

March 4th, 2009

I decided to public some of my, hmm, I cant call this plugin, its more like interesting reusability for jquery chain. 

First would be short implement of hover that very often used as substitude, of not existed css “:hover” support in IE. So to restore beaty of css and js I used such style:

ul li { color: black }
ul li.over { color: red }

$('ul li').hoverClass('over');

“hoverClass” is our shortcut. Very simple implementation, but code became much clear:

jQuery.fn.hoverClass = function(klass) {
    return this.hover(
        function() { $(this).addClass(klass); },
        function() { $(this).removeClass(klass); }
    );
}

Although, my mind is strikened of strange feeling, that jquery itself could this without help. It would be great if somebody point me.

kick it on DotNetKicks.com

Json [Date -> String -> Date]

December 16th, 2008

Current specification for Date serialize

www.json.org - writes nothing about Dates unfortunatelly. So people mostly use two varients: ‘@timestamp@’ or ‘\/Date(timestamp)\/’. Its a strings inside Json objects. Eval nothing do for both varients, it leaves them as strings.

As I mostly use asp.net mvc as my app layer, I am doing Json manipulation with JavaScriptSerializer, its suitable as not depends on any other libraries and its simply working. JavaScriptSerializer converts DateTime to second varient.

Code to check type, get date and put back

From String -> Date

if (typeof (el) == "string") {
   var dateReg = /\/Date\((\d+)\)\//;
   if (dateReg.test(el))
        return new Date(parseInt(el.match(dateReg)[1]));
   else
        el.toString();
}

From Date -> String

if (x instanceof Date) {
   return '"\\/Date({0})\\/"'.replace('{0}', x.getTime());
}

Note: As there no such type in JavaScript - as Date, we can only use instanceof to find Date inside object

kick it on DotNetKicks.com

Killing using(DataContext){}

December 4th, 2008

Standart way

The standart way of accessing data is putting everywhere code like below constructions:

using(DataClasses1DataContext dataContext = new DataClasses1DataContext())
{
      var users = from user in dataContext.Users
                      where user.UserId == userId;

      users.Single().Pass = "new pass";

      dataContext.SubmitChanges();
}

Singletone way

Firstly, I dont like this using, and in most cases we dont need to create it, as we have only one DataContext! But also we cant put it in a static value, because sql connection will be timeouted in a 30 minutes by default. So the best way is to use one DataContext for one Request.

    public class Ctx
    {
        public static DataClasses1DataContext Model
        {
            get
            {
                if (HttpContext.Current.Items["Data_Context"] == null)
                {
                    HttpContext.Current.Items["Data_Context"] = new DataClasses1DataContext();
                }
                return (MedData)HttpContext.Current.Items["Data_Context"];
            }
        }
    }

If we dont like SubmitChanges also. We can do it once in the end of Request using the same DataContext.

Above sample with Singletone style

      var users = from user in Ctx.Model.Users
                      where user.UserId == userId;

      users.Single().Pass = "new pass";

What we have now in the result is much more simplier, and if we’d like to separate execution in one transaction, we dont need to put everywhere DataContext as an argument, as we have one for request.

kick it on DotNetKicks.com

LinqToSql dbml tuning

December 1st, 2008

Remove “DataContext” prefix

When VisualStudio generates firstly dbml, it creates urly-long prefix DataContext, why I dont know! This very annoying to write everywhere, so I decided to show how to delete prefix:
a) click anywhere on the dbml designer surface, and goto Properties tab
b) change Name, its your DataContext, there you can also change Context Namespace

Linq dbml property - ChangeName

Linq dbml property - ChangeName

Change names of foreign keys.

Its very usefull to change names of ForeignKeys, especially for case like UserCreated, when User table has dozens of keys, with strange names, even numbers. So:
a) click on the arrows that connecting 2 tables and see Properties
b) change Child or Parent property

AutoGeneratedValue

If you dont need to generate Guids on AppServer, to use it further somehow, you could not put id every time you create object, but use default values. Also default values, I used for DateCreated or such kind of fields with (GetUtcDate()). But if you simply dont fill any data inside, it will put null there. So for that, any column has one of the params - AutoGeneratedValue, put it true, and default will work.

Schema unknown

If you use Visual Studio Dbml creator, and create Tables with DragNDrop, than using local database as source to dbml structure, you also copies schema name you used locally “dbo” most likely. So when you dont know schema of your table on the server, you could clean in “Properties of Column -> Source” by simply delete “dbo.”. This is usefull, if you want to have one dbml for different databases, with different schemas.

kick it on DotNetKicks.com