#!/usr/bin/env python
#coding: utf-8
#
# File Name: timelined.py
#
# Description: Daemon to parse your timeline.
#
# Creation Date: 2012-01-12
#
# Last Modified: 2012-02-21 18:09
#
# Created By: Daniël Franke <daniel@ams-sec.org>

import sys
import os
import logging
import logging.handlers
import socket
import time

from httplib import IncompleteRead
from ssl import SSLError

from tweepy import Stream, OAuthHandler

from libweetwit.db import DB
from libweetwit.timeline import TimeLineListener
from libweetwit.utils import kill_process


# Very ugly hack to dodge a lot of unicode problems.
reload(sys)
sys.setdefaultencoding('utf-8')



# VERY messy for now.
# TODO: Clean up.
if len(sys.argv) != 2:
    print "No storage directory given."
    sys.exit(2)

storage = sys.argv[1]

if not os.path.isdir(storage):
    print "%s is not a directory." % storage
    sys.exit(3)

status_dir = storage + "/statuses"
if not os.path.exists(status_dir):
    os.mkdir(status_dir)

if not os.path.isdir(status_dir):
    print "%s is not a directory." % status_dir
    sys.exit(4)

# Set up logger
logfile = "%s/timelined.log" % storage
logger = logging.getLogger('timelined')
logger.setLevel(logging.INFO)

fh = logging.handlers.RotatingFileHandler(logfile, maxBytes=1024*1024,
        backupCount=5)
logger.addHandler(fh)

pidfile = "%s/timelined.pid" % storage
if os.path.exists(pidfile):
    with file(pidfile) as f:
        kill_process(int(f.read().rstrip()))
    os.unlink(pidfile)

with file(pidfile, "w") as f:
    f.write(str(os.getpid()))

db = DB(storage)

ck = db.get_config('consumer_key')
cs = db.get_config('consumer_secret')
at = db.get_config('access_token')
ats = db.get_config('access_token_secret')
auth = OAuthHandler(ck, cs)
auth.set_access_token(at, ats)

# We want to stream at least one iteration.
do_stream = True
while do_stream:
    # If it exits normally, we want to quit.
    do_stream = False
    try:
        stream = Stream(auth=auth, listener=TimeLineListener(status_dir))
        stream.userstream()
    except (IncompleteRead, SSLError, socket.error):
        # If the stream quites unexpectedly, try again.
        logger.info("The stream stopped unexpectedly, restarting.")
        do_stream = True
        # Sleep for one second so that we don't hammer the server.
        time.sleep(1)
