loginza + django-avatars + facebook + vkontakte

Авторизуємось через loginza, і якщо facebook нам віддає ім'я і аватар юзернейма, зберігаємо у моделі користувачів.

def loginza_auth_handler(sender, user, identity, **kwargs):
    try:
        #loginza_models.UserMap.objects.get(user=user, verified=True)
        map = loginza_models.UserMap.objects.get(user=user)
        data = json.loads(map.identity.data)

        if data['provider'] == "http://www.facebook.com/":
            system_user = User.objects.get(username=user)
            if data['name']['first_name']:
                system_user.first_name = data['name']['first_name']
            if data['name']['last_name']:
                system_user.last_name = data['name']['last_name']
            if data['photo']:
                try:
                    Avatar.objects.get(user=system_user)
                except:
                    (filename, headers) = urllib.urlretrieve(data['photo'])
                    img_name = '%s.jpg' % os.path.basename(filename)
                    copy_path = os.path.join(settings.MEDIA_ROOT, settings.AVATAR_STORAGE_DIR, system_user.username, img_name)
                    copy_dir = os.path.join(settings.MEDIA_ROOT, settings.AVATAR_STORAGE_DIR, system_user.username)
                    if not os.path.isdir(copy_path):
                        os.makedirs(copy_dir)
                    shutil.copy2(filename, copy_path)
                    path_ava = os.path.join(settings.AVATAR_STORAGE_DIR, system_user.username, img_name)

                    avatar = Avatar(
                        user = system_user,
                        primary = True,
                        avatar = path_ava,
                    )
                    avatar.save()
            system_user.save()

        auth.login(sender, user)

Для Вконтактє ситуація аналогічна, лише Вконтактє віддає малюнок з розширенням, а Фейсбук без.

Django pagination

Вбудована пагінація якась надто скромна і не функціональна. Перепробував кілька реалізацій і зупинився на django-paging. Жахливо документована, але запрацювала на "ура" у всіх аппах.

Зміна xml шаблону Sitemap в Django

Захотілось додати CSS в XML-файл Sitemap'у по типу WordPress'івського. Йдемо в /usr/lib/python2.7/site-packages/django/contrib/sitemaps/templates/ (в Fedora такий шлях) і копіюємо sitemap.xml в свій template каталог проекту. Робимо потрібні зміни в ньому і маємо щастя.

авторизація через соціальні мережі в Django

Дуже класний сервіс, який позбавляє головного болю з САБЖом - loginza.ru
Для Django розроблений апп під нього. Все запрацювало з першого разу. Єдине що поправив в обробнику сигналів, то авторизувати неперевірених, а в мануалі вказано що авторизувати лише перевірених

def loginza_auth_handler(sender, user, identity, **kwargs):
    try:
        # it's enough to have single identity verified to treat user as verified
        #loginza_models.UserMap.objects.get(user=user, verified=True)
        loginza_models.UserMap.objects.get(user=user)
        auth.login(sender, user)
    except loginza_models.UserMap.DoesNotExist:
        sender.session['users_complete_reg_id'] = identity.id
        return redirect(reverse('users.views.complete_registration'))

ThreadedComment і TOP10 найкоментованіших об'єктів

Чомусь розробники не написали такої корисної API. Моє рішення, мабуть тимчасове, бо треба буде потестувати на швидкість.

post_type = ContentType.objects.get_for_model(Post)
counts = ThreadedComment.objects.filter(content_type=post_type).values('object_id').annotate(Count('object_id')).order_by()[:10]
counts = [ ( Post.objects.get(pk=cc['object_id']), cc['object_id__count']) for cc in counts ]

а як прикольно це виглядає у одній стрічці :))

counts = [ ( Post.objects.get(pk=cc['object_id']), cc['object_id__count']) for cc in ThreadedComment.objects.filter(content_type=ContentType.objects.get_for_model(Post)).values('object_id').annotate(Count('object_id')).order_by()[:10] ]


No Django support installed in selected interpreter

Давненько не пітонив. Скачав IDE Pycharm і отримав зразу САБЖ-помилку:



Вирішується додаванням потрібного інтерпретатора:

Перевірялка Апача на живучість

#!/bin/bash

PATH=/bin:/usr/bin
THEDIR=/tmp/apache-watchdog
EMAIL=blablabla@gmail.com
mkdir -p $THEDIR

if ( wget --timeout=30 -q -P $THEDIR http://localhost/robots.txt )
then
# we are up
touch ~/.apache-was-up
else
# down! but if it was down already, don't keep spamming
if [[ -f ~/.apache-was-up ]]
then
# write a nice e-mail
echo -n "apache crashed at " > $THEDIR/mail
date >> $THEDIR/mail
echo >> $THEDIR/mail
echo "Access log:" >> $THEDIR/mail
tail -n 30 /var/log/httpd/access_log >> $THEDIR/mail
echo >> $THEDIR/mail
echo "Error log:" >> $THEDIR/mail
tail -n 30 /var/log/httpd/access_log >> $THEDIR/mail
echo >> $THEDIR/mail
# kick apache
echo "Now kicking apache..." >> $THEDIR/mail
/etc/rc.d/init.d/httpd stop >> $THEDIR/mail 2>&1
killall -9 httpd >> $THEDIR/mail 2>&1
/etc/rc.d/init.d/httpd start >> $THEDIR/mail 2>&1
# send the mail
echo >> $THEDIR/mail
echo "Good luck troubleshooting!" >> $THEDIR/mail
mail -s "apache-watchdog: apache crashed" $EMAIL < $THEDIR/mail
rm ~/.apache-was-up
fi
fi
rm -rf $THEDIR


(c) десь нагуглено і допиляно під федору