# Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.

#!/usr/bin/env python3
#
import re, base64, logging, pickle, httplib2, time, urlparse, urllib2, urllib, StringIO, gzip, zipfile

from google.appengine.ext import webapp, db

from google.appengine.api import taskqueue, urlfetch, memcache, images, users
from google.appengine.ext.webapp.util import login_required
from google.appengine.ext.webapp import template

from django.utils import simplejson as json
from django.utils.html import strip_tags

from oauth2client.appengine import CredentialsProperty
from oauth2client.client import OAuth2WebServerFlow

import encoder

# TODO(jimhug): Allow client to request desired thumb size.
THUMB_SIZE = (57, 57)
READER_API = 'http://www.google.com/reader/api/0'

MAX_SECTIONS = 5
MAX_ARTICLES = 20


class UserData(db.Model):
    credentials = CredentialsProperty()
    sections = db.ListProperty(db.Key)

    def getEncodedData(self, articleKeys=None):
        enc = encoder.Encoder()
        # TODO(jimhug): Only return initially visible section in first reply.
        maxSections = min(MAX_SECTIONS, len(self.sections))
        enc.writeInt(maxSections)
        for section in db.get(self.sections[:maxSections]):
            section.encode(enc, articleKeys)
        return enc.getRaw()


class Section(db.Model):
    title = db.TextProperty()
    feeds = db.ListProperty(db.Key)

    def fixedTitle(self):
        return self.title.split('_')[0]

    def encode(self, enc, articleKeys=None):
        # TODO(jimhug): Need to optimize format and support incremental updates.
        enc.writeString(self.key().name())
        enc.writeString(self.fixedTitle())
        enc.writeInt(len(self.feeds))
        for feed in db.get(self.feeds):
            feed.ensureEncodedFeed()
            enc.writeRaw(feed.encodedFeed3)
            if articleKeys is not None:
                articleKeys.extend(feed.topArticles)


class Feed(db.Model):
    title = db.TextProperty()
    iconUrl = db.TextProperty()
    lastUpdated = db.IntegerProperty()

    encodedFeed3 = db.TextProperty()
    topArticles = db.ListProperty(db.Key)

    def ensureEncodedFeed(self, force=False):
        if force or self.encodedFeed3 is None:
            enc = encoder.Encoder()
            articleSet = []
            self.encode(enc, MAX_ARTICLES, articleSet)
            logging.info('articleSet length is %s' % len(articleSet))
            self.topArticles = articleSet
            self.encodedFeed3 = enc.getRaw()
            self.put()

    def encode(self, enc, maxArticles, articleSet):
        enc.writeString(self.key().name())
        enc.writeString(self.title)
        enc.writeString(self.iconUrl)

        logging.info('encoding feed: %s' % self.title)
        encodedArts = []

        for article in self.article_set.order('-date').fetch(limit=maxArticles):
            encodedArts.append(article.encodeHeader())
            articleSet.append(article.key())

        enc.writeInt(len(encodedArts))
        enc.writeRaw(''.join(encodedArts))


class Article(db.Model):
    feed = db.ReferenceProperty(Feed)

    title = db.TextProperty()
    author = db.TextProperty()
    content = db.TextProperty()
    snippet = db.TextProperty()
    thumbnail = db.BlobProperty()
    thumbnailSize = db.TextProperty()
    srcurl = db.TextProperty()
    date = db.IntegerProperty()

    def ensureThumbnail(self):
        # If our desired thumbnail size has changed, regenerate it and cache.
        if self.thumbnailSize != str(THUMB_SIZE):
            self.thumbnail = makeThumbnail(self.content)
            self.thumbnailSize = str(THUMB_SIZE)
            self.put()

    def encodeHeader(self):
        # TODO(jmesserly): for now always unescape until the crawler catches up
        enc = encoder.Encoder()
        enc.writeString(self.key().name())
        enc.writeString(unescape(self.title))
        enc.writeString(self.srcurl)
        enc.writeBool(self.thumbnail is not None)
        enc.writeString(self.author)
        enc.writeInt(self.date)
        enc.writeString(unescape(self.snippet))
        return enc.getRaw()


class HtmlFile(db.Model):
    content = db.BlobProperty()
    compressed = db.BooleanProperty()
    filename = db.StringProperty()
    author = db.UserProperty(auto_current_user=True)
    date = db.DateTimeProperty(auto_now_add=True)


class UpdateHtml(webapp.RequestHandler):

    def post(self):
        upload_files = self.request.POST.multi.__dict__['_items']
        version = self.request.get('version')
        logging.info('files: %r' % upload_files)
        for data in upload_files:
            if data[0] != 'files': continue
            file = data[1]
            filename = file.filename
            if version:
                filename = '%s-%s' % (version, filename)
            logging.info('upload: %r' % filename)

            htmlFile = HtmlFile.get_or_insert(filename)
            htmlFile.filename = filename

            # If text > (1MB - 1KB) then gzip text to fit in 1MB space
            text = file.value
            if len(text) > 1024 * 1023:
                data = StringIO.StringIO()
                gz = gzip.GzipFile(str(filename), 'wb', fileobj=data)
                gz.write(text)
                gz.close()
                htmlFile.content = data.getvalue()
                htmlFile.compressed = True
            else:
                htmlFile.content = text
                htmlFile.compressed = False

            htmlFile.put()

        self.redirect('/')


class TopHandler(webapp.RequestHandler):

    @login_required
    def get(self):
        user = users.get_current_user()
        prefs = UserData.get_by_key_name(user.user_id())
        if prefs is None:
            self.redirect('/update/user')
            return

        params = {'files': HtmlFile.all().order('-date').fetch(limit=30)}
        self.response.out.write(template.render('top.html', params))


class MainHandler(webapp.RequestHandler):

    @login_required
    def get(self, name):
        if name == 'dev':
            return self.handleDev()

        elif name == 'login':
            return self.handleLogin()

        elif name == 'upload':
            return self.handleUpload()

        user = users.get_current_user()
        prefs = UserData.get_by_key_name(user.user_id())
        if prefs is None:
            return self.handleLogin()

        html = HtmlFile.get_by_key_name(name)
        if html is None:
            self.error(404)
            return

        self.response.headers['Content-Type'] = 'text/html'

        if html.compressed:
            # TODO(jimhug): This slightly sucks ;-)
            # Can we write directly to the response.out?
            gz = gzip.GzipFile(
                name, 'rb', fileobj=StringIO.StringIO(html.content))
            self.response.out.write(gz.read())
            gz.close()
        else:
            self.response.out.write(html.content)

        # TODO(jimhug): Include first data packet with html.

    def handleLogin(self):
        user = users.get_current_user()
        # TODO(jimhug): Manage secrets for dart.googleplex.com better.
        # TODO(jimhug): Confirm that we need client_secret.
        flow = OAuth2WebServerFlow(
            client_id='267793340506.apps.googleusercontent.com',
            client_secret='5m8H-zyamfTYg5vnpYu1uGMU',
            scope=READER_API,
            user_agent='swarm')

        callback = self.request.relative_url('/oauth2callback')
        authorize_url = flow.step1_get_authorize_url(callback)

        memcache.set(user.user_id(), pickle.dumps(flow))

        content = template.render('login.html', {'authorize': authorize_url})
        self.response.out.write(content)

    def handleDev(self):
        user = users.get_current_user()
        content = template.render('dev.html', {'user': user})
        self.response.out.write(content)

    def handleUpload(self):
        user = users.get_current_user()
        content = template.render('upload.html', {'user': user})
        self.response.out.write(content)


class UploadFeed(webapp.RequestHandler):

    def post(self):
        upload_files = self.request.POST.multi.__dict__['_items']
        version = self.request.get('version')
        logging.info('files: %r' % upload_files)
        for data in upload_files:
            if data[0] != 'files': continue
            file = data[1]
            logging.info('upload feed: %r' % file.filename)

            data = json.loads(file.value)

            feedId = file.filename
            feed = Feed.get_or_insert(feedId)

            # Find the section to add it to.
            sectionTitle = data['section']
            section = findSectionByTitle(sectionTitle)
            if section != None:
                if feed.key() in section.feeds:
                    logging.warn('Already contains feed %s, replacing' % feedId)
                    section.feeds.remove(feed.key())

                # Add the feed to the section.
                section.feeds.insert(0, feed.key())
                section.put()

                # Add the articles.
                collectFeed(feed, data)

            else:
                logging.error('Could not find section %s to add the feed to' %
                              sectionTitle)

        self.redirect('/')


# TODO(jimhug): Batch these up and request them more aggressively.
class DataHandler(webapp.RequestHandler):

    def get(self, name):
        if name.endswith('.jpg'):
            # Must be a thumbnail
            key = urllib2.unquote(name[:-len('.jpg')])
            article = Article.get_by_key_name(key)
            self.response.headers['Content-Type'] = 'image/jpeg'
            # cache images for 10 hours
            self.response.headers['Cache-Control'] = 'public,max-age=36000'
            article.ensureThumbnail()
            self.response.out.write(article.thumbnail)
        elif name.endswith('.html'):
            # Must be article content
            key = urllib2.unquote(name[:-len('.html')])
            article = Article.get_by_key_name(key)
            self.response.headers['Content-Type'] = 'text/html'
            if article is None:
                content = '<h2>Missing article</h2>'
            else:
                content = article.content
            # cache article content for 10 hours
            self.response.headers['Cache-Control'] = 'public,max-age=36000'
            self.response.out.write(content)
        elif name == 'user.data':
            self.response.out.write(self.getUserData())
        elif name == 'CannedData.dart':
            self.canData()
        elif name == 'CannedData.zip':
            self.canDataZip()
        else:
            self.error(404)

    def getUserData(self, articleKeys=None):
        user = users.get_current_user()
        user_id = user.user_id()

        key = 'data_' + user_id
        # need to flush memcache fairly frequently...
        data = memcache.get(key)
        if data is None:
            prefs = UserData.get_or_insert(user_id)
            if prefs is None:
                # TODO(jimhug): Graceful failure for unknown users.
                pass
            data = prefs.getEncodedData(articleKeys)
            # TODO(jimhug): memcache.set(key, data)

        return data

    def canData(self):

        def makeDartSafe(data):
            return repr(unicode(data))[1:].replace('$', '\\$')

        lines = [
            '// TODO(jimhug): Work out correct copyright for this file.',
            'class CannedData {'
        ]

        user = users.get_current_user()
        prefs = UserData.get_by_key_name(user.user_id())
        articleKeys = []
        data = prefs.getEncodedData(articleKeys)
        lines.append('  static const Map<String,String> data = const {')
        for article in db.get(articleKeys):
            key = makeDartSafe(urllib.quote(article.key().name()) + '.html')
            lines.append('    %s:%s, ' % (key, makeDartSafe(article.content)))

        lines.append('    "user.data":%s' % makeDartSafe(data))

        lines.append('  };')

        lines.append('}')
        self.response.headers['Content-Type'] = 'application/dart'
        self.response.out.write('\n'.join(lines))

    # Get canned static data
    def canDataZip(self):
        # We need to zip into an in-memory buffer to get the right string encoding
        # behavior.
        data = StringIO.StringIO()
        result = zipfile.ZipFile(data, 'w')

        articleKeys = []
        result.writestr('data/user.data',
                        self.getUserData(articleKeys).encode('utf-8'))
        logging.info('  adding articles %s' % len(articleKeys))
        images = []
        for article in db.get(articleKeys):
            article.ensureThumbnail()
            path = 'data/' + article.key().name() + '.html'
            result.writestr(
                path.encode('utf-8'), article.content.encode('utf-8'))
            if article.thumbnail:
                path = 'data/' + article.key().name() + '.jpg'
                result.writestr(path.encode('utf-8'), article.thumbnail)

        result.close()
        logging.info('writing CannedData.zip')
        self.response.headers['Content-Type'] = 'multipart/x-zip'
        disposition = 'attachment; filename=CannedData.zip'
        self.response.headers['Content-Disposition'] = disposition
        self.response.out.write(data.getvalue())
        data.close()


class SetDefaultFeeds(webapp.RequestHandler):

    @login_required
    def get(self):
        user = users.get_current_user()
        prefs = UserData.get_or_insert(user.user_id())

        prefs.sections = [
            db.Key.from_path('Section', 'user/17857667084667353155/label/Top'),
            db.Key.from_path('Section',
                             'user/17857667084667353155/label/Design'),
            db.Key.from_path('Section', 'user/17857667084667353155/label/Eco'),
            db.Key.from_path('Section', 'user/17857667084667353155/label/Geek'),
            db.Key.from_path('Section',
                             'user/17857667084667353155/label/Google'),
            db.Key.from_path('Section',
                             'user/17857667084667353155/label/Seattle'),
            db.Key.from_path('Section', 'user/17857667084667353155/label/Tech'),
            db.Key.from_path('Section', 'user/17857667084667353155/label/Web')
        ]

        prefs.put()

        self.redirect('/')


class SetTestFeeds(webapp.RequestHandler):

    @login_required
    def get(self):
        user = users.get_current_user()
        prefs = UserData.get_or_insert(user.user_id())

        sections = []
        for i in range(3):
            s1 = Section.get_or_insert('Test%d' % i)
            s1.title = 'Section %d' % (i + 1)

            feeds = []
            for j in range(4):
                label = '%d_%d' % (i, j)
                f1 = Feed.get_or_insert('Test%s' % label)
                f1.title = 'Feed %s' % label
                f1.iconUrl = getFeedIcon('http://google.com')
                f1.lastUpdated = 0
                f1.put()
                feeds.append(f1.key())

                for k in range(8):
                    label = '%d_%d_%d' % (i, j, k)
                    a1 = Article.get_or_insert('Test%s' % label)
                    if a1.title is None:
                        a1.feed = f1
                        a1.title = 'Article %s' % label
                        a1.author = 'anon'
                        a1.content = 'Lorem ipsum something or other...'
                        a1.snippet = 'Lorem ipsum something or other...'
                        a1.thumbnail = None
                        a1.srcurl = ''
                        a1.date = 0

            s1.feeds = feeds
            s1.put()
            sections.append(s1.key())

        prefs.sections = sections
        prefs.put()

        self.redirect('/')


class UserLoginHandler(webapp.RequestHandler):

    @login_required
    def get(self):
        user = users.get_current_user()
        prefs = UserData.get_or_insert(user.user_id())
        if prefs.credentials:
            http = prefs.credentials.authorize(httplib2.Http())

            response, content = http.request(
                '%s/subscription/list?output=json' % READER_API)
            self.collectFeeds(prefs, content)
            self.redirect('/')
        else:
            self.redirect('/login')

    def collectFeeds(self, prefs, content):
        data = json.loads(content)

        queue_name = self.request.get('queue_name', 'priority-queue')
        sections = {}
        for feedData in data['subscriptions']:
            feed = Feed.get_or_insert(feedData['id'])
            feed.put()
            category = feedData['categories'][0]
            categoryId = category['id']
            if not sections.has_key(categoryId):
                sections[categoryId] = (category['label'], [])

            # TODO(jimhug): Use Reader preferences to sort feeds in a section.
            sections[categoryId][1].append(feed.key())

            # Kick off a high priority feed update
            taskqueue.add(
                url='/update/feed',
                queue_name=queue_name,
                params={'id': feed.key().name()})

        sectionKeys = []
        for name, (title, feeds) in sections.items():
            section = Section.get_or_insert(name)
            section.feeds = feeds
            section.title = title
            section.put()
            # Forces Top to be the first section
            if title == 'Top': title = '0Top'
            sectionKeys.append((title, section.key()))

        # TODO(jimhug): Use Reader preferences API to get users true sort order.
        prefs.sections = [key for t, key in sorted(sectionKeys)]
        prefs.put()


class AllFeedsCollector(webapp.RequestHandler):
    '''Ensures that a given feed object is locally up to date.'''

    def post(self):
        return self.get()

    def get(self):
        queue_name = self.request.get('queue_name', 'background')
        for feed in Feed.all():
            taskqueue.add(
                url='/update/feed',
                queue_name=queue_name,
                params={'id': feed.key().name()})


UPDATE_COUNT = 4  # The number of articles to request on periodic updates.
INITIAL_COUNT = 40  # The number of articles to get first for a new queue.
SNIPPET_SIZE = 180  # The length of plain-text snippet to extract.


class FeedCollector(webapp.RequestHandler):

    def post(self):
        return self.get()

    def get(self):
        feedId = self.request.get('id')
        feed = Feed.get_or_insert(feedId)

        if feed.lastUpdated is None:
            self.fetchn(feed, feedId, INITIAL_COUNT)
        else:
            self.fetchn(feed, feedId, UPDATE_COUNT)

        self.response.headers['Content-Type'] = "text/plain"

    def fetchn(self, feed, feedId, n, continuation=None):
        # basic pattern is to read by ARTICLE_COUNT until we hit existing.
        if continuation is None:
            apiUrl = '%s/stream/contents/%s?n=%d' % (READER_API, feedId, n)
        else:
            apiUrl = '%s/stream/contents/%s?n=%d&c=%s' % (READER_API, feedId, n,
                                                          continuation)

        logging.info('fetching: %s' % apiUrl)
        result = urlfetch.fetch(apiUrl)

        if result.status_code == 200:
            data = json.loads(result.content)
            collectFeed(feed, data, continuation)
        elif result.status_code == 401:
            self.response.out.write('<pre>%s</pre>' % result.content)
        else:
            self.response.out.write(result.status_code)


def findSectionByTitle(title):
    for section in Section.all():
        if section.fixedTitle() == title:
            return section
    return None


def collectFeed(feed, data, continuation=None):
    '''
  Reads a feed from the given JSON object and populates the given feed object
  in the datastore with its data.
  '''
    if continuation is None:
        if 'alternate' in data:
            feed.iconUrl = getFeedIcon(data['alternate'][0]['href'])
        feed.title = data['title']
        feed.lastUpdated = data['updated']

    articles = data['items']
    logging.info('%d new articles for %s' % (len(articles), feed.title))

    for articleData in articles:
        if not collectArticle(feed, articleData):
            feed.put()
            return False

    if len(articles) > 0 and data.has_key('continuation'):
        logging.info('would have looked for more articles')
        # TODO(jimhug): Enable this continuation check when more robust
        #self.fetchn(feed, feedId, data['continuation'])

    feed.ensureEncodedFeed(force=True)
    feed.put()
    return True


def collectArticle(feed, data):
    '''
  Reads an article from the given JSON object and populates the datastore with
  it.
  '''
    if not 'title' in data:
        # Skip this articles without titles
        return True

    articleId = data['id']
    article = Article.get_or_insert(articleId)
    # TODO(jimhug): This aborts too early - at lease for one adafruit case.
    if article.date == data['published']:
        logging.info(
            'found existing, aborting: %r, %r' % (articleId, article.date))
        return False

    if data.has_key('content'):
        content = data['content']['content']
    elif data.has_key('summary'):
        content = data['summary']['content']
    else:
        content = ''
    #TODO(jimhug): better summary?
    article.content = content
    article.date = data['published']
    article.title = unescape(data['title'])
    article.snippet = unescape(strip_tags(content)[:SNIPPET_SIZE])

    article.feed = feed

    # TODO(jimhug): make this canonical so UX can change for this state
    article.author = data.get('author', 'anonymous')

    article.ensureThumbnail()

    article.srcurl = ''
    if data.has_key('alternate'):
        for alt in data['alternate']:
            if alt.has_key('href'):
                article.srcurl = alt['href']
    return True


def unescape(html):
    "Inverse of Django's utils.html.escape function"
    if not isinstance(html, basestring):
        html = str(html)
    html = html.replace('&#39;', "'").replace('&quot;', '"')
    return html.replace('&gt;', '>').replace('&lt;', '<').replace('&amp;', '&')


def getFeedIcon(url):
    url = urlparse.urlparse(url).netloc
    return 'http://s2.googleusercontent.com/s2/favicons?domain=%s&alt=feed' % url


def findImage(text):
    img = findImgTag(text, 'jpg|jpeg|png')
    if img is not None:
        return img

    img = findVideoTag(text)
    if img is not None:
        return img

    img = findImgTag(text, 'gif')
    return img


def findImgTag(text, extensions):
    m = re.search(r'src="(http://\S+\.(%s))(\?.*)?"' % extensions, text)
    if m is None:
        return None
    return m.group(1)


def findVideoTag(text):
    # TODO(jimhug): Add other videos beyond youtube.
    m = re.search(r'src="http://www.youtube.com/(\S+)/(\S+)[/|"]', text)
    if m is None:
        return None

    return 'http://img.youtube.com/vi/%s/0.jpg' % m.group(2)


def makeThumbnail(text):
    url = None
    try:
        url = findImage(text)
        if url is None:
            return None
        return generateThumbnail(url)
    except:
        logging.info('error decoding: %s' % (url or text))
        return None


def generateThumbnail(url):
    logging.info('generating thumbnail: %s' % url)
    thumbWidth, thumbHeight = THUMB_SIZE

    result = urlfetch.fetch(url)
    img = images.Image(result.content)

    w, h = img.width, img.height

    aspect = float(w) / h
    thumbAspect = float(thumbWidth) / thumbHeight

    if aspect > thumbAspect:
        # Too wide, so crop on the sides.
        normalizedCrop = (w - h * thumbAspect) / (2.0 * w)
        img.crop(normalizedCrop, 0., 1. - normalizedCrop, 1.)
    elif aspect < thumbAspect:
        # Too tall, so crop out the bottom.
        normalizedCrop = (h - w / thumbAspect) / h
        img.crop(0., 0., 1., 1. - normalizedCrop)

    img.resize(thumbWidth, thumbHeight)

    # Chose JPEG encoding because informal experiments showed it generated
    # the best size to quality ratio for thumbnail images.
    nimg = img.execute_transforms(output_encoding=images.JPEG)
    logging.info('  finished thumbnail: %s' % url)

    return nimg


class OAuthHandler(webapp.RequestHandler):

    @login_required
    def get(self):
        user = users.get_current_user()
        flow = pickle.loads(memcache.get(user.user_id()))
        if flow:
            prefs = UserData.get_or_insert(user.user_id())
            prefs.credentials = flow.step2_exchange(self.request.params)
            prefs.put()
            self.redirect('/update/user')
        else:
            pass


def main():
    application = webapp.WSGIApplication(
        [
            ('/data/(.*)', DataHandler),

            # This is called periodically from cron.yaml.
            ('/update/allFeeds', AllFeedsCollector),
            ('/update/feed', FeedCollector),
            ('/update/user', UserLoginHandler),
            ('/update/defaultFeeds', SetDefaultFeeds),
            ('/update/testFeeds', SetTestFeeds),
            ('/update/html', UpdateHtml),
            ('/update/upload', UploadFeed),
            ('/oauth2callback', OAuthHandler),
            ('/', TopHandler),
            ('/(.*)', MainHandler),
        ],
        debug=True)
    webapp.util.run_wsgi_app(application)


if __name__ == '__main__':
    main()
