Skip to content

Instantly share code, notes, and snippets.

@beddari
Forked from paulmist/trello-to-newsletter.py
Created March 28, 2017 11:38
Show Gist options
  • Save beddari/055f94ee9e2168d06cabdc29e4504b27 to your computer and use it in GitHub Desktop.
Save beddari/055f94ee9e2168d06cabdc29e4504b27 to your computer and use it in GitHub Desktop.
Trello to Newsletter builder
"""
Trello to Newsletter builder
This is heavily inspired by: https://changelog.com/trello-as-a-cms/
To install:
pip install click cached_property markdown py-trello
To run:
export TRELLO_APP_KEY=''
export TRELLO_APP_SECRET=''
export TRELLO_AUTH_TOKEN=''
python trello-to-newsletter.py --board='My Newsletter board'
"""
import click
import markdown
import os
from trello import TrelloClient
from cached_property import cached_property
TRELLO_APP_KEY = os.environ.get('TRELLO_APP_KEY')
TRELLO_APP_SECRET = os.environ.get('TRELLO_APP_SECRET')
TRELLO_AUTH_TOKEN = os.environ.get('TRELLO_AUTH_TOKEN')
# TRELLO_BOARD_ID = os.environ.get('TRELLO_BOARD_ID')
# TRELLO_DEFAULT_LIST = os.environ.get('TRELLO_DEFAULT_LIST', 'Uncategorized')
class Post(object):
def __init__(self, card):
self.card = card
@property
def attached_link(self):
# No supported in py-trello
return False
@cached_property
def body(self):
if self.attached_link:
return self.card.description
else:
if '\n\n' in self.card.description:
return self.card.description.split('\n\n', 1)[1]
else:
return self.card.description
@cached_property
def draft(self):
return 'Draft' in self.labels
@cached_property
def labels(self):
return [label.name for label in self.card.labels]
@cached_property
def link(self):
return self.card.description.split('\n\n', 1)[0]
@cached_property
def sponsored(self):
return 'Sponsored' in self.labels
@cached_property
def title(self):
return self.card.name
class Meta(object):
def __init__(self, list_object):
self.list_object = list_object
def get_card(self, name):
cards = self.list_object.list_cards()
for card in cards:
if card.name == name:
return card
return None
@cached_property
def editors_note(self):
card = self.get_card('editors_note')
if card:
return card.description
return None
@cached_property
def preview_text(self):
card = self.get_card('preview_text')
if card:
return card.description
return None
@cached_property
def published_at(self):
card = self.get_card('published_at')
if card:
return card.description
return None
@click.command()
@click.option('--board')
@click.option('--board-id')
@click.option('--html/--no-html', default=False)
def main(board, board_id, html):
output = []
trello = TrelloClient(
api_key=TRELLO_APP_KEY,
api_secret=TRELLO_APP_SECRET,
token=TRELLO_AUTH_TOKEN
# token_secret=str(trello_config.auth_token),
)
if board:
for obj in trello.list_boards():
if board == obj.name:
board = obj
else:
board = trello.get_board(board_id)
open_lists = board.open_lists()
meta = None
if len(open_lists):
for item in open_lists:
if item.name == 'Meta':
meta = Meta(item)
# click.echo(u'published_at: {0}\n'.format(meta.published_at))
# click.echo(u'preview_text: {0}\n'.format(meta.preview_text))
# click.echo(u'editors_note: {0}\n'.format(meta.editors_note))
output.append(u'published_at: {0}\n'.format(meta.published_at))
output.append(u'preview_text: {0}\n'.format(meta.preview_text))
output.append(u'editors_note: {0}\n'.format(meta.editors_note))
continue
cards = item.list_cards()
if len(cards):
# click.echo(u'## {0}\n'.format(item.name))
output.append(u'## {0}\n'.format(item.name))
for card in cards:
post = Post(card)
if post.draft:
continue
if post.sponsored:
# click.echo(u'#### Sponsored\n')
output.append(u'#### Sponsored\n')
if not post.link:
# click.echo(u'WARNING: {0} does not have a valid link!\n'.format(post.title,))
# click.echo(u'#### Whoops\n')
output.append(u'WARNING: {0} does not have a valid link!\n'.format(post.title,))
output.append(u'#### Whoops\n')
# click.echo(u'### [{0}]({1})\n'.format(post.title, post.link))
# click.echo(u'{0}\n'.format(post.body))
output.append(u'### [{0}]({1})\n'.format(post.title, post.link))
output.append(u'{0}\n'.format(post.body))
text = '\n'.join(output)
if html:
text = markdown.markdown(text)
click.echo(text)
if __name__ == '__main__':
main()

Recent Updates

So far we’ve been able to fund 23 people, including 9 speakers, which is awesome!

Congratulations to all our accepted speakers!

While we’re in the midst of preparations for Austin, it’s also time to think about 2016! Where will we be next year? We need your help in making that decision!

Deciding how to allocate our financial aid budget is something we take very seriously.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment