Merge in changes from trunk
This commit is contained in:
commit
24abdc076e
5 changed files with 62 additions and 14 deletions
|
@ -2,13 +2,12 @@ from . import extensions
|
||||||
from .views import views
|
from .views import views
|
||||||
from .api import api
|
from .api import api
|
||||||
from .push import push
|
from .push import push
|
||||||
from config import Config
|
|
||||||
import flask
|
import flask
|
||||||
|
|
||||||
|
|
||||||
def create_app():
|
def create_app(config_path='../woodwind.cfg'):
|
||||||
app = flask.Flask('woodwind')
|
app = flask.Flask('woodwind')
|
||||||
app.config.from_object(Config)
|
app.config.from_pyfile(config_path)
|
||||||
if not app.debug:
|
if not app.debug:
|
||||||
import logging
|
import logging
|
||||||
import sys
|
import sys
|
||||||
|
|
30
woodwind/sse_server.py
Normal file
30
woodwind/sse_server.py
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
from aiohttp import web
|
||||||
|
import asyncio
|
||||||
|
import asyncio_redis
|
||||||
|
|
||||||
|
|
||||||
|
@asyncio.coroutine
|
||||||
|
def handle_subscription(request):
|
||||||
|
topic = request.GET['topic']
|
||||||
|
response = web.StreamResponse()
|
||||||
|
response.headers['Content-Type'] = 'text/event-stream'
|
||||||
|
response.start(request)
|
||||||
|
redis = yield from asyncio_redis.Connection.create()
|
||||||
|
try:
|
||||||
|
ps = yield from redis.start_subscribe()
|
||||||
|
yield from ps.subscribe(['woodwind_notify:' + topic])
|
||||||
|
while True:
|
||||||
|
message = yield from ps.next_published()
|
||||||
|
response.write(
|
||||||
|
'data: {}\n\n'.format(message.value).encode('utf-8'))
|
||||||
|
finally:
|
||||||
|
redis.close()
|
||||||
|
|
||||||
|
|
||||||
|
app = web.Application()
|
||||||
|
app.router.add_route('GET', '/', handle_subscription)
|
||||||
|
|
||||||
|
loop = asyncio.get_event_loop()
|
||||||
|
srv = loop.run_until_complete(
|
||||||
|
loop.create_server(app.make_handler(), '0.0.0.0', 8077))
|
||||||
|
loop.run_forever()
|
|
@ -1,8 +1,8 @@
|
||||||
from config import Config
|
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from redis import StrictRedis
|
from redis import StrictRedis
|
||||||
from woodwind.models import Feed, Entry
|
from woodwind.models import Feed, Entry
|
||||||
from woodwind import util
|
from woodwind import util
|
||||||
|
from flask import Config as FlaskConfig
|
||||||
import bs4
|
import bs4
|
||||||
import datetime
|
import datetime
|
||||||
import feedparser
|
import feedparser
|
||||||
|
@ -19,6 +19,8 @@ import sys
|
||||||
import time
|
import time
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
|
|
||||||
|
config = FlaskConfig('/home/kmahan/projects/woodwind')
|
||||||
|
config.from_pyfile('/home/kmahan/projects/woodwind.cfg')
|
||||||
|
|
||||||
# normal update interval for polling feeds
|
# normal update interval for polling feeds
|
||||||
UPDATE_INTERVAL = datetime.timedelta(hours=1)
|
UPDATE_INTERVAL = datetime.timedelta(hours=1)
|
||||||
|
@ -30,10 +32,17 @@ TWITTER_RE = re.compile(
|
||||||
TAG_RE = re.compile(r'</?\w+[^>]*?>')
|
TAG_RE = re.compile(r'</?\w+[^>]*?>')
|
||||||
COMMENT_RE = re.compile(r'<!--[^>]*?-->')
|
COMMENT_RE = re.compile(r'<!--[^>]*?-->')
|
||||||
|
|
||||||
|
AUDIO_ENCLOSURE_TMPL = '<p><audio class="u-audio" src="{href}" controls '\
|
||||||
|
'preload=none ><a href="{href}">audio</a></audio></p>'
|
||||||
|
VIDEO_ENCLOSURE_TMPL = '<p><video class="u-video" src="{href}" controls '\
|
||||||
|
'preload=none ><a href="{href}">video</a></video></p>'
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
#logger.setLevel(logging.DEBUG)
|
logger.setLevel(logging.DEBUG)
|
||||||
#logger.addHandler(logging.StreamHandler(sys.stdout))
|
logger.addHandler(logging.StreamHandler(sys.stdout))
|
||||||
engine = sqlalchemy.create_engine(Config.SQLALCHEMY_DATABASE_URI)
|
|
||||||
|
engine = sqlalchemy.create_engine(config['SQLALCHEMY_DATABASE_URI'])
|
||||||
|
|
||||||
Session = sqlalchemy.orm.sessionmaker(bind=engine)
|
Session = sqlalchemy.orm.sessionmaker(bind=engine)
|
||||||
redis = StrictRedis()
|
redis = StrictRedis()
|
||||||
|
|
||||||
|
@ -148,8 +157,8 @@ def update_feed(feed_id, content=None, is_polling=True):
|
||||||
def check_push_subscription(session, feed, response):
|
def check_push_subscription(session, feed, response):
|
||||||
def build_callback_url():
|
def build_callback_url():
|
||||||
return '{}://{}/_notify/{}'.format(
|
return '{}://{}/_notify/{}'.format(
|
||||||
getattr(Config, 'PREFERRED_URL_SCHEME', 'http'),
|
getattr(config, 'PREFERRED_URL_SCHEME', 'http'),
|
||||||
Config.SERVER_NAME,
|
config['SERVER_NAME'],
|
||||||
feed.id)
|
feed.id)
|
||||||
|
|
||||||
def send_request(mode, hub, topic):
|
def send_request(mode, hub, topic):
|
||||||
|
@ -312,6 +321,16 @@ def process_xml_feed_for_new_entries(session, feed, content, backfill, now):
|
||||||
if content.startswith(title_trimmed):
|
if content.startswith(title_trimmed):
|
||||||
title = None
|
title = None
|
||||||
|
|
||||||
|
for link in p_entry.get('links', []):
|
||||||
|
if link.type == 'audio/mpeg':
|
||||||
|
audio = AUDIO_ENCLOSURE_TMPL.format(href=link.get('href'))
|
||||||
|
content = audio + (content or '')
|
||||||
|
if (link.type == 'video/x-m4v'
|
||||||
|
or link.type == 'video/x-mp4'
|
||||||
|
or link.type == 'video/mp4'):
|
||||||
|
video = VIDEO_ENCLOSURE_TMPL.format(href=link.get('href'))
|
||||||
|
content = video + (content or '')
|
||||||
|
|
||||||
entry = Entry(
|
entry = Entry(
|
||||||
published=published,
|
published=published,
|
||||||
updated=updated,
|
updated=updated,
|
||||||
|
@ -408,7 +427,7 @@ def fetch_reply_context(entry_id, in_reply_to, now):
|
||||||
|
|
||||||
|
|
||||||
def proxy_url(url):
|
def proxy_url(url):
|
||||||
if Config.TWITTER_AU_KEY and Config.TWITTER_AU_SECRET:
|
if config['TWITTER_AU_KEY'] and config['TWITTER_AU_SECRET']:
|
||||||
# swap out the a-u url for twitter urls
|
# swap out the a-u url for twitter urls
|
||||||
match = TWITTER_RE.match(url)
|
match = TWITTER_RE.match(url)
|
||||||
if match:
|
if match:
|
||||||
|
@ -416,8 +435,8 @@ def proxy_url(url):
|
||||||
'https://twitter-activitystreams.appspot.com/@me/@all/@app/{}?'
|
'https://twitter-activitystreams.appspot.com/@me/@all/@app/{}?'
|
||||||
.format(match.group(2)) + urllib.parse.urlencode({
|
.format(match.group(2)) + urllib.parse.urlencode({
|
||||||
'format': 'html',
|
'format': 'html',
|
||||||
'access_token_key': Config.TWITTER_AU_KEY,
|
'access_token_key': config['TWITTER_AU_KEY'],
|
||||||
'access_token_secret': Config.TWITTER_AU_SECRET,
|
'access_token_secret': config['TWITTER_AU_SECRET'],
|
||||||
}))
|
}))
|
||||||
logger.debug('proxied twitter url %s', proxy_url)
|
logger.debug('proxied twitter url %s', proxy_url)
|
||||||
return proxy_url
|
return proxy_url
|
||||||
|
|
|
@ -299,7 +299,7 @@ def add_subscription(origin, feed_url, type):
|
||||||
flask_login.current_user.feeds.append(feed)
|
flask_login.current_user.feeds.append(feed)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
# go ahead and update the fed
|
# go ahead and update the fed
|
||||||
tasks.q.enqueue(update_feed, feed.id)
|
tasks.q.enqueue(tasks.update_feed, feed.id)
|
||||||
return feed
|
return feed
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
from . import create_app
|
from . import create_app
|
||||||
|
|
||||||
application = create_app()
|
application = create_app('../woodwind.cfg')
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue