th_trello/my_trello.py
# coding: utf-8
# django classes
from django.conf import settings
from django.core.cache import caches
from django.utils.translation import ugettext as _
# django_th classes
from django_th.apps import DjangoThConfig
from django_th.models import update_result, UserService
from django_th.services.services import ServicesMgr
from logging import getLogger
from th_trello.models import Trello
# Trello API
from trello import TrelloClient, ResourceUnavailable
"""
handle process with Trello
put the following in settings.py
TH_TRELLO = {
'consumer_key': 'abcdefghijklmnopqrstuvwxyz',
'consumer_secret': 'abcdefghijklmnopqrstuvwxyz',
}
TH_SERVICES = (
...
'th_trello.my_trello.ServiceTrello',
...
)
"""
logger = getLogger('django_th.trigger_happy')
cache = caches['django_th']
class ServiceTrello(ServicesMgr):
"""
Serivce Trello
"""
# Boards own Lists own Cards
def __init__(self, token=None, **kwargs):
super(ServiceTrello, self).__init__(token, **kwargs)
# app name
self.app_name = DjangoThConfig.verbose_name
# expiration
self.expiry = "30days"
# scope define the rights access
self.scope = 'read,write'
self.oauth = 'oauth1'
self.service = 'ServiceTrello'
base = 'https://www.trello.com'
self.AUTH_URL = '{}/1/OAuthAuthorizeToken'.format(base)
self.REQ_TOKEN = '{}/1/OAuthGetRequestToken'.format(base)
self.ACC_TOKEN = '{}/1/OAuthGetAccessToken'.format(base)
self.consumer_key = settings.TH_TRELLO_KEY['consumer_key']
self.consumer_secret = settings.TH_TRELLO_KEY['consumer_secret']
if token:
token_key, token_secret = token.split('#TH#')
try:
self.trello_instance = TrelloClient(self.consumer_key,
self.consumer_secret,
token_key,
token_secret)
except ResourceUnavailable as e:
us = UserService.objects.get(token=token)
logger.error(e.msg, e.error_code)
update_result(us.trigger_id, msg=e.msg, status=False)
def read_data(self, **kwargs):
"""
get the data from the service
:param kwargs: contain keyword args : trigger_id at least
:type kwargs: dict
"""
trigger_id = kwargs.get('trigger_id')
data = list()
kwargs['model_name'] = 'Trello'
kwargs['app_label'] = 'th_trello'
super(ServiceTrello, self).read_data(**kwargs)
cache.set('th_trello_' + str(trigger_id), data)
return data
def save_data(self, trigger_id, **data):
"""
let's save the data
:param trigger_id: trigger ID from which to save data
:param data: the data to check to be used and save
:type trigger_id: int
:type data: dict
:return: the status of the save statement
:rtype: boolean
"""
data['output_format'] = 'md'
title, content = super(ServiceTrello, self).save_data(trigger_id, **data)
if len(title):
# get the data of this trigger
t = Trello.objects.get(trigger_id=trigger_id)
# footer of the card
footer = self.set_card_footer(data, t)
content += footer
# 1 - we need to search the list and board where we will
# store the card so ...
# 1.a search the board_id by its name
# by retrieving all the boards
boards = self.trello_instance.list_boards()
board_id = ''
my_list = ''
for board in boards:
if t.board_name == board.name:
board_id = board.id
break
if board_id:
# 1.b search the list_id by its name
my_board = self.trello_instance.get_board(board_id)
lists = my_board.open_lists()
# just get the open list ; not all the archive ones
for list_in_board in lists:
# search the name of the list we set in the form
if t.list_name == list_in_board.name:
# return the (trello) list object to be able to add card at step 3
my_list = my_board.get_list(list_in_board.id)
break
# we didnt find the list in that board -> create it
if my_list == '':
my_list = my_board.add_list(t.list_name)
else:
# 2 if board_id and/or list_id does not exist, create it/them
my_board = self.trello_instance.add_board(t.board_name)
# add the list that didn't exists and return a (trello) list object
my_list = my_board.add_list(t.list_name)
# 3 create the card
my_list.add_card(title, content)
logger.debug(str('trello {} created').format(data['link']))
status = True
else:
sentence = "no token or link provided for trigger ID {}".format(trigger_id)
update_result(trigger_id, msg=sentence, status=False)
status = False
return status
@staticmethod
def set_card_footer(data, trigger):
"""
handle the footer of the note
"""
footer = ''
if data.get('link'):
provided_by = _('Provided by')
provided_from = _('from')
footer_from = "<br/><br/>{} <em>{}</em> {} <a href='{}'>{}</a>"
description = trigger.trigger.description
footer = footer_from.format(provided_by, description, provided_from, data.get('link'), data.get('link'))
import pypandoc
footer = pypandoc.convert(footer, 'md', format='html')
return footer
def auth(self, request):
"""
let's auth the user to the Service
:param request: request object
:return: callback url
:rtype: string that contains the url to redirect after auth
"""
request_token = super(ServiceTrello, self).auth(request)
callback_url = self.callback_url(request)
# URL to redirect user to, to authorize your app
auth_url_str = '{auth_url}?oauth_token={token}'
auth_url_str += '&scope={scope}&name={name}'
auth_url_str += '&expiration={expiry}&oauth_callback={callback_url}'
auth_url = auth_url_str.format(auth_url=self.AUTH_URL,
token=request_token['oauth_token'],
scope=self.scope,
name=self.app_name,
expiry=self.expiry,
callback_url=callback_url)
return auth_url
def callback(self, request, **kwargs):
"""
Called from the Service when the user accept to activate it
:param request: request object
:return: callback url
:rtype: string , path to the template
"""
return super(ServiceTrello, self).callback(request, **kwargs)