mirror of
https://github.com/postgres/pgweb.git
synced 2025-08-13 13:12:42 +00:00
Implement automatic tweeting of news
Once a twitter account has been registered (using the twitter_register management command), the twitter_post command wills start posting all new news to twitter, once they are approved. It will only post news from the past 7 days to avoid accidentally flooding with old news.
This commit is contained in:
@ -17,4 +17,4 @@ class NewsArticleForm(forms.ModelForm):
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = NewsArticle
|
model = NewsArticle
|
||||||
exclude = ('submitter', 'approved', )
|
exclude = ('submitter', 'approved', 'tweeted')
|
||||||
|
0
pgweb/news/management/__init__.py
Normal file
0
pgweb/news/management/__init__.py
Normal file
0
pgweb/news/management/commands/__init__.py
Normal file
0
pgweb/news/management/commands/__init__.py
Normal file
48
pgweb/news/management/commands/twitter_post.py
Normal file
48
pgweb/news/management/commands/twitter_post.py
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
#
|
||||||
|
# Script to post previosly unposted news to twitter
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
from django.core.management.base import BaseCommand, CommandError
|
||||||
|
from django.db import connection, transaction
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
import time
|
||||||
|
|
||||||
|
from pgweb.news.models import NewsArticle
|
||||||
|
|
||||||
|
import requests_oauthlib
|
||||||
|
|
||||||
|
class Command(BaseCommand):
|
||||||
|
help = 'Post to twitter'
|
||||||
|
|
||||||
|
def handle(self, *args, **options):
|
||||||
|
curs = connection.cursor()
|
||||||
|
curs.execute("SELECT pg_try_advisory_lock(62387372)")
|
||||||
|
if not curs.fetchall()[0][0]:
|
||||||
|
raise CommandError("Failed to get advisory lock, existing twitter_post process stuck?")
|
||||||
|
|
||||||
|
articles = list(NewsArticle.objects.filter(tweeted=False, approved=True, date__gt=datetime.now()-timedelta(days=7)).order_by('date'))
|
||||||
|
if not len(articles):
|
||||||
|
return
|
||||||
|
|
||||||
|
tw = requests_oauthlib.OAuth1Session(settings.TWITTER_CLIENT,
|
||||||
|
settings.TWITTER_CLIENTSECRET,
|
||||||
|
settings.TWITTER_TOKEN,
|
||||||
|
settings.TWITTER_TOKENSECRET)
|
||||||
|
|
||||||
|
for a in articles:
|
||||||
|
# We hardcode 30 chars for the URL shortener. And then 10 to cover the intro and spacing.
|
||||||
|
statusstr = u"News: {0} - {1}/about/news/{2}/".format(a.title[:140-40], settings.SITE_ROOT, a.id)
|
||||||
|
r = tw.post('https://api.twitter.com/1.1/statuses/update.json', data={
|
||||||
|
'status': statusstr,
|
||||||
|
})
|
||||||
|
if r.status_code != 200:
|
||||||
|
print("Failed to post to twitter: %s " % r)
|
||||||
|
else:
|
||||||
|
a.tweeted = True
|
||||||
|
a.save()
|
||||||
|
# Don't post more often than once / 30 seconds, to not trigger flooding.
|
||||||
|
time.sleep(30)
|
43
pgweb/news/management/commands/twitter_register.py
Normal file
43
pgweb/news/management/commands/twitter_register.py
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
#
|
||||||
|
# Script to register twitter oauth privileges
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
from django.core.management.base import BaseCommand, CommandError
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
|
import requests_oauthlib
|
||||||
|
|
||||||
|
class Command(BaseCommand):
|
||||||
|
help = 'Register with twitter oauth'
|
||||||
|
|
||||||
|
def handle(self, *args, **options):
|
||||||
|
if not hasattr(settings, 'TWITTER_CLIENT'):
|
||||||
|
raise CommandError("TWITTER_CLIENT must be set in settings_local.py")
|
||||||
|
if not hasattr(settings, 'TWITTER_CLIENTSECRET'):
|
||||||
|
raise CommandError("TWITTER_CLIENTSECRET must be set in settings_local.py")
|
||||||
|
if hasattr(settings, 'TWITTER_TOKEN'):
|
||||||
|
raise CommandError("TWITTER_TOKEN is already set in settings_local.py")
|
||||||
|
if hasattr(settings, 'TWITTER_TOKENSECRET'):
|
||||||
|
raise CommandError("TWITTER_TOKENSECRET is already set in settings_local.py")
|
||||||
|
|
||||||
|
# OK, now we're good to go :)
|
||||||
|
oauth = requests_oauthlib.OAuth1Session(settings.TWITTER_CLIENT, settings.TWITTER_CLIENTSECRET)
|
||||||
|
fetch_response = oauth.fetch_request_token('https://api.twitter.com/oauth/request_token')
|
||||||
|
|
||||||
|
authorization_url = oauth.authorization_url('https://api.twitter.com/oauth/authorize')
|
||||||
|
print 'Please go here and authorize: %s' % authorization_url
|
||||||
|
|
||||||
|
pin = raw_input('Paste the PIN here: ')
|
||||||
|
|
||||||
|
oauth = requests_oauthlib.OAuth1Session(settings.TWITTER_CLIENT,
|
||||||
|
settings.TWITTER_CLIENTSECRET,
|
||||||
|
resource_owner_key=fetch_response.get('oauth_token'),
|
||||||
|
resource_owner_secret=fetch_response.get('oauth_token_secret'),
|
||||||
|
verifier=pin)
|
||||||
|
oauth_tokens = oauth.fetch_access_token('https://api.twitter.com/oauth/access_token')
|
||||||
|
|
||||||
|
print("Authorized. Please configure:")
|
||||||
|
print("TWITTER_TOKEN='%s'" % oauth_tokens.get('oauth_token'))
|
||||||
|
print("TWITTER_TOKENSECRET='%s'" % oauth_tokens.get('oauth_token_secret'))
|
19
pgweb/news/migrations/0002_news_tweet.py
Normal file
19
pgweb/news/migrations/0002_news_tweet.py
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('news', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='newsarticle',
|
||||||
|
name='tweeted',
|
||||||
|
field=models.BooleanField(default=True),
|
||||||
|
),
|
||||||
|
]
|
@ -8,6 +8,7 @@ class NewsArticle(models.Model):
|
|||||||
date = models.DateField(null=False, blank=False, default=date.today)
|
date = models.DateField(null=False, blank=False, default=date.today)
|
||||||
title = models.CharField(max_length=200, null=False, blank=False)
|
title = models.CharField(max_length=200, null=False, blank=False)
|
||||||
content = models.TextField(null=False, blank=False)
|
content = models.TextField(null=False, blank=False)
|
||||||
|
tweeted = models.BooleanField(null=False, blank=False, default=False)
|
||||||
|
|
||||||
send_notification = True
|
send_notification = True
|
||||||
markdown_fields = ('content',)
|
markdown_fields = ('content',)
|
||||||
|
Reference in New Issue
Block a user