Skip to content

Instantly share code, notes, and snippets.

@jefftriplett
Last active June 5, 2021 17:00
Show Gist options
  • Save jefftriplett/9d2470a97ab57d2cec6d to your computer and use it in GitHub Desktop.
Save jefftriplett/9d2470a97ab57d2cec6d 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.

@myusuf3
Copy link

myusuf3 commented Jun 30, 2015

This is super cool. I unfortunately don't use trello for anything but would be super cool way to organize a newsletter visually! I wish I had this.

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