#!/usr/bin/env python
# -*- coding: utf-8 -*- 

from sqlalchemy import desc
from base import Base
from schema import Session, Feed, Post
from datetime import datetime as dt
from datetime import timedelta
from time import mktime, sleep
try:
    from multiprocessing import Process, Lock
except ImportError:
    print('multiprocessing not found: fallback to threading')
    from threading import Thread as Process, Lock

from config import max_post_age

from parser import parse_one

class Index(Base):
    def get(self):
        posts = Session.query(Post).filter_by(read=False).order_by(desc(
                    Post.published))
        return self.render('index.html', posts=posts)

class FeedDelete(Base):
    # TODO: rewrite to post or better: delete (if that is possible?)
    def get(self, id):
        # sqlite won't cascade-delete the posts
        Session.query(Post).filter_by(feed_id=id).delete()
        Session.query(Feed).filter_by(id=id).delete()
        Session.commit()
        Session.close()
        return self.redirect('/')

class FeedEdit(Base):
    def get(self, id):
        feed = Session.query(Feed).filter_by(id=id).one()
        return self.render('feed_edit.html', feed=feed)

    def post(self, id):
        feed = Session.query(Feed).filter_by(id=id).one()
        feed.title = self.get_argument('name')
        feed.url = self.get_argument('url')
        Session.commit()
        Session.close()
        return self.redirect('/')

class FeedAdd(Base):
    def get(self):
        return self.render('feed_add.html')

    def post(self):
        name = self.get_argument('name')
        url = self.get_argument('url')
        feed = Feed()
        feed.title = name
        feed.url = url
        Session.add(feed)
        Session.commit()
        return self.render('index.html')

class MarkAsRead(Base):
    def get(self):
        for post in Session.query(Post).filter_by(read=False):
            post.read = True
        Session.commit()
        Session.close()
        return self.redirect('/')

class Refresh(Base):
    def get(self):
        Session.query(Post).filter(Post.updated <=
                dt.now() - timedelta(days=max_post_age) ).delete()
        feeds = Session.query(Feed.id).all()
        Session.close()
        procs = []
        for feed in feeds:
            p = Process(target=parse_one, args=(feed.id,))
            p.start()
            if not hasattr(p, 'is_alive'):
                p.is_alive = p.isAlive
            procs.append(p)
        while any( p.is_alive() for p in procs):
            sleep(0.05)
        return self.redirect('/')

@@ -38,17 +38,16 @@
 tf-8 -*-
- 
 %0A%0Afrom s
@@ -205,216 +205,33 @@
 rom 
-time import mktime, sleep%0Atry:%0A    from multiprocessing import Process, Lock%0Aexcept ImportError:%0A    print('multiprocessing not found: fallback to threading')%0A    from threading import Thread as Process, Lock
+concurrent import futures
 %0A%0Afr
@@ -291,16 +291,17 @@
 se_one%0A%0A
+%0A
 class In
@@ -401,13 +401,8 @@
 _by(
-desc(
 %0A   
@@ -410,24 +410,21 @@
         
-        
+desc(
 Post.pub
@@ -487,16 +487,17 @@
 posts)%0A%0A
+%0A
 class Fe
@@ -841,32 +841,33 @@
 .redirect('/')%0A%0A
+%0A
 class FeedEdit(B
@@ -1263,24 +1263,25 @@
 irect('/')%0A%0A
+%0A
 class FeedAd
@@ -1613,24 +1613,25 @@
 dex.html')%0A%0A
+%0A
 class MarkAs
@@ -1837,16 +1837,17 @@
 t('/')%0A%0A
+%0A
 class Re
@@ -1913,16 +1913,29 @@
 .filter(
+%0A            
 Post.upd
@@ -1941,32 +1941,16 @@
 dated %3C=
-%0A               
  dt.now(
@@ -1981,17 +1981,16 @@
 ost_age)
- 
 ).delete
@@ -2073,308 +2073,113 @@
     
-procs = %5B%5D%0A        for feed in feeds:%0A            p = Process(target=parse_one, args=(feed.id,))%0A            p.start()%0A            if not hasattr(p, 'is_alive'):%0A                p.is_alive = p.isAlive%0A            procs.append(p)%0A        while any( p.is_alive()
+with futures.ProcessPoolExecutor() as executor:%0A            executor.map(parse_one, (f.id
  for 
-p
+f
  in 
-procs):%0A            sleep(0.05
+feeds)
 )%0A  

use concurrent.futures instead of the threading module to refresh feeds