Трендец всем

Делаем mash-up приложение на трэндах

Разделы

понедельник, 13 августа 2012 г.

Знакомство с Facebook

Вообщем Фэйсбук не такой уж и страшный и с ним даже можно и нужно работать. А начал я своё знакомство с ним сразу с приложения. Приложение пишется очень быстро, но долго дорабатывается, т.к. удалось въехать совсем не с первого раза в механизмы авторизации и шаманство с куками - иначе это не назовёшь, т.к. приложение работает во фрейме.

Как я уже сказал приложение пишетс достаточно быстро - ровно столько же сколько происходило изучение доков, прежде чем приступить. И поэтому что бы обезопасить от набития шишек кое что расскажу из предварительных настроек. Как создаётся приложение?

Приложение начинается с этого адреса, в котором при его создании, самое сложное было в Basic - меню выбрать какой какой тип приложения я хочу использовать. Так как я делаю серверные приложения (пока ещё) то мой выбор пал на два: App on Facebook и Page Tab. И я долго долго ковырялся на просторах фэйсбука пока не нашёл (потерял) доходичвую документацию - что они отличаются тем, как будут встраиваться на страницу. В первом случае приложение будет работать в указанном канвасе, а со страницей пользователя общаться через апи, а во втором случае, после встраивания в таб приложение выдаёт индивидульную информацию прямо в таб, при этом поддерживается разные языки-макросы FBML, FQL, FBJS... Очевидно я остановился на приложение в канвасе которое общается через АПИ и чего-то там делает в стандартных фэйсбучных объектах - коих предостаточно.

Проблема номер два, устаревающая авторизация. Здесь я буду краток, хотя уже написав приложение пришлось его перелопачивать из-за ткой мелочи как short-time lived token. В новых версиях (новых потому что их две с сентября и октября 2012) откзались от оффлайн авторизации при этом предложили "длинный" токен, который можно получить через запрос сервера. Но он не обновляется! Обновлять можно только короткий токен, который получается на клиенте. Короче что бы приложение могло работать лайфтайм надо брать короткий токен при каждой новой возможности, и обновлять его на длинный. Кстати длинный живёт 60 дней короткий 24 часа. Примеры не выкладываю, т.к. есть отличный пример Run with Friends, написанный прямо на питоне и прямо для ГАЕ. Чуть критики: мне немного не понравилась его логика, но может я просто не привычный к Джанго, но пример сам по себе достаточно полный, включает все необходимое для того что бы начать писать под Facebook. На этом всё, и да кстати пользуйтесь приложением, если есть свои фанпаги - можно зарабатывать с Амазон в фэйсбуке. Удачи!

понедельник, 30 июля 2012 г.

Amazon - продолжение

Амазон гад, не даёт всё инфу о таварах, приходиться запрашивать и немного парсить, гы. Но в целом, технические вопросы с ним рашаются за неделю. Вопрос что дальше, что с этим делать? Ну конечно магазин, но как где и т.д. Вообщем как делать серьёзный магазин, я к этому ещё вернусь, ибо в первоочередных планах. Расскажу как делать простой магазин.

Для этого выбираем один из популярных блог движков, например блоггер, формируем из полученного товара приемлемую HTML-страницу, и отправляем на секретный адрес. Проще простого.

На самом деле надо сделать так: товар в базе у нас уже есть, надо его как-то оформить. Для этого надо найти подходящий Landing Page или даже Landing Email, (неплохие варианты по приемлемым ценам), и на базе этого подготовить дизайн в формате стандартного фрэймворка или Bottle, которым я обычно пользуюсь. Дальше как уже было сказано можно захостить товар на блоггере отправляя письма, но при этом не будут учитываться тэги (ярлыки на местном диаллате) сообщений, для таких случаев у блоггера есть API. Но при первом знакомстве выяснилось что оно просто так не даётся, для этого надо слать запрос, с описанием цели использования. У меня лично никаких проблем с этим не возникло и лимит на API был выдан в полном объёме. Я очень доволен этим, т.к. блоггер в последнее время меня радует своим динамическим дизайном, у которого есть кстати свои фичи, но об этом не сейчас.

Есть другой вариант WP. Там на первый взгляд всё ещё удобней. Ага, не тут-то было. Да у него есть XML-RPC, но т.к. я им до этого ни разу не пользовался да PHP знаю не очень я просто ужаснулся от его кривизны после использования скажем JSON. Но это пол беды, т.к. кривизну отчасти можно списать на кривизну рук. Основная беда в том что Вордпресс режет несчадно HTML-код, причём очень очень грубо. В итогое дизайн к нему разрабатывался методом тыка, порежет/не порежет. Это было занудно и мучительно долго, и желаемого результата добиться не удалось. Что ж дарёному коню (хостинг) в зубы не смотрят. И на последок одну приятную мелоч.

Что бы постить на фриблоги надо где-то хранить картинки, я не сразу догадался но на то есть два замечательных варианта, кому какой будет удобней: это Google Storage и Picasa. Плюсы первого: простой интерфейс и универсальность в плане типов файлов. Второй это всё таки больше для альбомов фотографий, но насколько я понял трафик там бесплатный совсем, а цена на хранение та же.

пятница, 29 июня 2012 г.

Amazon - партнёрский магазин

Вообщем, простое решение привело меня к Amazon. Вопрос стоял так: чем наполнять сайт, пока нет авторского материала, и не совсем прямым путём пришёл к Амазон. Конечно же брать оттуда контент как дополнительный не стоит, а стоит взять его за основной, а всё что удалось добыть иным путём разместить вместе с ним. Amazon он большой, поэтому здесь сейчас будет краткий обзор, скорей так сказать букмарки с коментами.

Итак с чего начать:
Партнёрская программа
Доступ к API
Полезные доки (из множетсва других)
И наконец песочница, поигратся с запросами

Ещё есть библиотека для питон, но не факт что она заработает в GAE - причём у неё вид страшноватый (огромное количество файлов непонято для чего). Имя всё это и принимая во внимание последнее, решил на написать свою библитеку доступа к их базе.
Сначала думал что убдет всё просто, но по факту что-то сразу не пошло, а загвоздка сводилась к тому что они импользуют какой что старый интерфейс OAuth, верней он у них свой, похож просто. Отличие в том сообщение формируют несколько иначе и подписывают не SHA1 а SHA256. Ниже код
#!/usr/bin/env python
# encoding: utf-8

from google.appengine.api import urlfetch
from urllib import quote, unquote, urlencode
from hmac import new as hmac
from hashlib import sha256
from datetime import datetime
from urlparse import urlparse


import logging
from settings import AMAZON_TAG, AMAZON_KEY, AMAZON_SECRET

try:
    import json
except ImportError:
    import simplejson as json

def amazon_request(url="", additional_params=None, method=urlfetch.GET):
    def _quote(text):
        return quote(str(text), "~")
    
    url = url if url else "http://ecs.amazonaws.com/onca/xml" 
    
    consumer_key = AMAZON_KEY
    consumer_secret = AMAZON_SECRET
    
    params = {"Service": "AWSECommerceService",
                        "AssociateTag": "AMAZON_TAG",
                        "AWSAccessKeyId": consumer_key,
                        "Timestamp": datetime.now().strftime("%Y-%m-%dT%H:%M:%S.000Z")
                        }

    if additional_params:
        params.update(additional_params)
    
    for k,v in params.items():
        if isinstance(v, unicode):
            params[k] = v.encode('utf8')

    params_str = "&".join(["%s=%s" % (_quote(k), _quote(params[k])) for k in sorted(params)])
    parse_url = urlparse(url)
    message = "\n".join(["GET" if method == urlfetch.GET else "POST", parse_url.netloc, parse_url.path, params_str])
    params["Signature"] = hmac(consumer_secret, message, sha256).digest().encode("base64").strip()

    payload = urlencode(params)

    if method == urlfetch.GET:
        url = "%s?%s" % (url, payload)
        payload = None

    rpc = urlfetch.create_rpc(deadline=12.0)
    urlfetch.make_fetch_call(rpc, url, method=method, payload=payload)
    
    try:
        res = rpc.get_result()
    except urlfetch.DownloadError, msg:
        logging.error(msg)
        logging.error(repr(additional_params))
        return None

    if res.status_code != 200:
        logging.error("amazon_request: status_code")
        logging.error(repr(additional_params))
        if res.content:
            logging.error(res.content)
            logging.error("token is %s" % token)
        return None
    
    return res.content
P.S.: Если прокатит одна штука, будет статейка про блоггер - уж очень мне их новый дизайн приглянулся, к тому же не надо забывать что это хостинг и притом бесплатный.

суббота, 16 июня 2012 г.

Краткий план

Пока особо серьёзное откладываю на потом,  есть как я говорил уже идея для твиттер, очень классная идея для Google+, но это всё отнимет уйму времени. Гораздо эффективней по горячим следам из того что уже есть сделать что-то интересное. И это интересное - лёгкий двиг на питоне для блога. Никаких наворотов не планируется, кое-какие социальные фичи, и вместе с авторскими публикациями, кое что из автонаполнения актуальными новостями - ну как же без этого. Естественно всё это под GAE. При освоении новых технологий буду держать в курсе.

Побочный продукт

Из того что было использовано в первом проекте удалось создать некий сервис по работе с Twitter. Сервис сам так себе и служит скорей для того что бы пощупать скрипт, который содержит расширенный функционал. Вообщем об этом всё есть на сайте. На этом изучение Twitter API для себя я считаю закрытым.

суббота, 5 мая 2012 г.

Сокращённые урлы

Вообщем последние штрихи (ну конечно не считая дизайна, который оставляет желать лучшего). Прикрутил обновления на твиттер, не совсем кроспостинг, а самое интересное, с твитами и ретвитами. Ну с ретвитами всё более мене обычно (см предыдущий пост), а в твитах длинные урлы не очень как-то смотрятся. Хорошо полазив в самом Twitter Api обнаружил что t.co твиттер оставил для внутреннего пользования. Поэтому пришлось поискать сторонние сервисы. Т.к. я попробовал не один попробую представить краткий обзор.

BitLy: Где-то здесь можно зарегистрироваться прямо через твиттер. И для того что бы сокращать урлы, надо получить ключ и логин. Внимательно: логин - это не имя в твиттере, а там где сcылки 'Public Timeline' вида: http://bitly.com/u/o_xxxxxxxxx.rss, можно определить свой логин, который начинается с 'o_'. Как им пользоваться без OAuth (c OAuth - курить я не стал) см. ниже:

from google.appengine.api import urlfetch
from urllib import quote, unquote, urlencode
import logging

try:
    import json
except ImportError:
    import simplejson as json

def bit_shorten(uri):
    params = {'login' : BITLY_LOGIN,
                                'apiKey' : BITLY_KEY,
                                'domain' : "bit.ly", 
                                'uri' : uri.encode('utf8'), 
                    }
    bit_url = "http://api.bit.ly/v3/shorten?%s" % urlencode(params, doseq=True)

    try:
        res = urlfetch.fetch(bit_url)
    except urlfetch.DownloadError, msg:
        logging.error(str(msg))
        return ""
            
    if res.status_code != 200:
        logging.error(res.status_code)
        return ""
        
    try:
        jj = json.loads(res.content)
    except Exception, msg:
        logging.error(msg)
        return ""
    
    if jj["status_txt"] != "OK":
        logging.error(jj["status_txt"])
        return ""
    else:
        return jj["data"]["url"]

Вообщем оно работало но не долго... Спустя сутки перестало, причины в чём же дело я выяснять не стал, толи лимит исчерпался, толи OAuth не подключён. Ждать когда это само собой рассосётся я не стал.

Google: Набрал в поиске кто ещё умеет сокращать урлы и на удивление наткнулся на гугл (Кто в твиттере сидит наверное видел ссылки вида goo.gl). Решил попробовать прикрутить его. Для начала идём сюда. Там можно выбрать любой API который предоставляет гугл. Я ограничился только 'Shorten URL'. Честно скажу я хотел сначала использовать OAuth с ключами от серверного приложения,  но "что-то пошло не так". И  быстро нашёл оправдание что мне не потоком же эти урлы сокращать (лимит в сутки там 1 000 000 запросов), и решил сделать без авторизации но с ключём (без ключа можно тоже слать, но лимит не известен). Выглядит это так:

from google.appengine.api import urlfetch
from urllib import quote, unquote, urlencode
import logging

try:
    import json
except ImportError:
    import simplejson as json

def gog_shorten(uri):
    params = {"key" : GOOGLE_KEY, "longUrl" : uri.encode('utf8')}
    gog_url = "https://www.googleapis.com/urlshortener/v1/url"
    headers = {"Content-Type" : "application/json"}
    payload = json.dumps(params)
    
    try:
        res = urlfetch.fetch(gog_url, method=urlfetch.POST, headers=headers, payload=payload)
    except urlfetch.DownloadError, msg:
        logging.error(str(msg))
        return ""
            
    if res.status_code != 200:
        logging.error(res.status_code)
        return ""
        
    try:
        jj = json.loads(res.content)
    except Exception, msg:
        logging.error(msg)
        return ""
    
    return jj["id"]
И это пока пашет... тьфу-тьфу-тьфу.

вторник, 17 апреля 2012 г.

С возвращением.

Вообщем прошёл почти год, и я был занят в другой области - не связанной с программированием, и вот решил вернутся. За это время квоты... тут вообще жёсткий сюрприз, урезали по самые яйца, так что дальше не куда. Приложение тоже придётся немного переориентировать - сделать ещё проще. Да! А почему бы нет, лучше доделать самое простое и посмотреть как оно будет. Пришлось переименовать из 'uptweetter' в 'trendstat' (в блоге уже всё исправил задним числом). Вообщем, "убрал" весь интерактив, оставил только выдачу из БД в разном формате, и немного остаётся задумать над дизайном. А весь интерактив будет в следующем проекте, очень скоро (правда скоро) на русском языке, но и вообще под рунет и с твиттером. Идею пока палить не буду.

Постоянные читатели

Copyright © trendec. Технологии Blogger.