#!/usr/bin/python

"""

AudioBrowse

Qt application for browsing audiobooks

author: Maxime Cogney

"""

import sys
import json
import time
import requests
from PyQt4.QtGui import *
from PyQt4.QtCore import *
from ADBLParser import *

class ABFeed(QThread):

    def __init__(self):
        QThread.__init__(self)

        self.urls=[]
        self.quitting = False
        self.parser = ADBLParser()

    def __del__(self):
        self.quitting = True
        self.wait()

    def addUrl(self,url):
        self.urls.append(url)

    def run(self):
        for url in self.urls:
            if(self.quitting):
                break
            self.feedUrl(url)

    def feedUrl(self,url):
        data = requests.get(url).text
        self.parser.feed(data)

        for item in self.parser.res:
            item=self.cacheImage(item)
            self.emit(SIGNAL('feed(PyQt_PyObject)'), item)
        self.parser.reset()

    def cacheImage(self,item):
        if 'img' not in item:
            return item

        url=item['img'] 
        filename=url.split('/')[-1]
        filelocation='img_cache/'+filename
        req=requests.get(url, stream=True)

        if req.status_code == 200:
            with open(filelocation,'wb') as f:
                for ch in req.iter_content(1024):
                    f.write(ch)
        else:
            print 'Bad requests ({})'.format(req.status_code)
            return item

        item['img']=filelocation
        return item



class ABMain(QMainWindow):

    def __init__(self, *args):
        QMainWindow.__init__(self, *args)

        self.initUI()

        # Setting up our worker to scrape the first 10 pages of new Audible releases
        self.feed = ABFeed()
        for x in range(10):
            self.feed.addUrl(page_url.format(x+1))
        self.connect(self.feed, SIGNAL('feed(PyQt_PyObject)'), self.table.addEntry)
        self.feed.start()

    def initUI(self):
        self.setWindowTitle("AudioBrowse")
        self.resize(800,600)

        # File menu
        exit_action = QAction('&Exit', self)
        exit_action.setShortcut('Ctrl+Q')
        exit_action.triggered.connect(qApp.quit)
        file_menu = self.menuBar().addMenu('&File')
        file_menu.addAction(exit_action)

        # Option menu
        switch_url_action = QAction('Hide &links', self)
        switch_url_action.setShortcut('Ctrl+L')
        switch_url_action.setCheckable(True)
        switch_url_action.triggered.connect(self.switchUrl)
        option_menu = self.menuBar().addMenu('&Option')
        option_menu.addAction(switch_url_action)
        
        # Main table
        self.table = ABTable(self)
        self.setCentralWidget(self.table)
        self.table.show()

    def switchUrl(self):
        if self.sender().isChecked():
            self.table.hideColumn(1)
        else:
            self.table.showColumn(1)
            self.table.setColumnWidth(0,self.table.columnWidth(0)-200)

class ABTable(QTableWidget):

    # Horizontal header labels
    labels=('Title','Link')

    def __init__(self, *args):
        QTableWidget.__init__(self, *args)

        self.initUI()

    # UI Setup
    def initUI(self):

        # Setting up headers
        self.setColumnCount(len(self.labels))
        self.setHorizontalHeaderLabels(self.labels)
        self.horizontalHeader().setStretchLastSection(True)
        self.setColumnWidth(0,600)
        self.verticalHeader().setVisible(False)

        # Setting up selection/edition behavior
        self.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.setSelectionMode(QAbstractItemView.NoSelection)
        self.setEditTriggers(QAbstractItemView.NoEditTriggers)

        # Allow sorting
        self.setSortingEnabled(True)

    # Add entry (row) to table from a dictionnary
    def addEntry(self, data):

        # Verify item validity
        if any(x not in data for x in ('title','img','href')):
            print 'Invalid item'
            return

        # Setting up items
        title = QTableWidgetItem(data['title'])
        title.setData(Qt.DecorationRole,QPixmap('img_cache/'+data['img'].split('/')[-1]))
        href = QTableWidgetItem(data['href'])

        # Qt sorts at item insertion, which means we gotta hold auto sort calls until the
        # whole row is filled up if we don't want a mess or overwritten cells.
        self.setSortingEnabled(False)

        # Creating new row
        new_size = self.rowCount()
        self.insertRow(new_size)
        self.setItem(new_size,0,title)
        self.setItem(new_size,1,href)

        # Reenabling sorting
        self.setSortingEnabled(True)

def main():
    
    app = QApplication(sys.argv)
    main = ABMain()
    main.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()