Source

trac-dvbcronrecording-plugin / src / dvbcronrecording / programguide.py

Full commit
Guido Draheim 019bae0 










































































































































































































































# -*- coding: utf-8 -*-
import pkg
import re
import os.path
import sys
import datetime

from trac.core import Component, implements
# from trac.db import *
#from trac.wiki import wiki_to_html, wiki_to_oneliner
from trac.web.chrome import add_stylesheet, add_script
#from trac.util import Markup, format_datetime

from trac.web import IRequestHandler
from trac.perm import IPermissionRequestor
from trac.web.chrome import  ITemplateProvider # INavigationContributor,
from trac.util.presentation import Paginator
from translate import Translate #@UnresolvedImport

from dvbcronrecording.db.session import db_cnx, commit
from dvbcronrecording.db.schema import RecordingList #@UnresolvedImport
from dvbcronrecording.db.schema import RecordingChanges #@UnresolvedImport

def intnull(value, default = None):
    if value is None: return default
    try: return int(value)
    except Exception: return default
def lookup(lists, entry, default = None):
    if entry is None: return default
    idx = intnull(entry)
    if idx is None or idx >= len(lists): return default
    return lists[idx]
def ustr(text):
    if type(text) is unicode: return text
    if type(text) is str: return unicode(text)
    return unicode(str(text))

PACKAGE = u'dvbcronrecording'
NAV = 'recordings'
URL = 'recording'
SUBURL = 'programguide'

LIST_APPEND = 'DVBREC_LIST_APPEND'

"""
  here we are.
"""
class DvbCronRecordingProgramguidePlugin(Component):

    #
    # Public methods
    #

    implements(IPermissionRequestor, ITemplateProvider,  IRequestHandler)

    # IPermissionRequestor methods

    """
      Returns list of permitions privided by this plugin.
    """
    def get_permission_actions(self):
        return [ LIST_APPEND ]

    # ITemplateProvider methods

    """
      Returns additional path where stylesheets are placed.
    """
    def get_htdocs_dirs(self):
        return [(PACKAGE, pkg.resource_filename(__name__, 'htdocs'))]

    """
      Returns additional path where templates are placed.
    """
    def get_templates_dirs(self):
        return [pkg.resource_filename(__name__, 'templates')]

    # IRequestHandler methods

    """
      Determines if request should be handled by this plugin.
    """
    def match_request(self, req):
        m = re.match(r"/%s/%ss?(?:/(.*))?$" % (URL, SUBURL), req.path_info)
        if m:
            page = m.group(1)
            req.args['page'] = page 
            return True
        return False

    """
      Handles display and download requests on this plugin.
    """
    def process_request(self, req):
        req.perm.assert_permission(LIST_APPEND)
        # ------------------------------------------------
        translate = Translate(PACKAGE, req.locale)
        userscripts_dir = self.get_scripts_dir()

        page = req.args['page']
        message = "[%s]" % page

        if page and page.startswith("install/"):
            name = page[len("install/"):]
            filepath = os.path.join(userscripts_dir, name)
            if os.path.exists(filepath):
                try:
                    f = open(filepath)
                    text = f.read()
                    f.close()
                    text = text.replace("http://SERVER", ustr(req.base_url).encode("utf-8"))
                    req.send_header("Content-Disposition:", 'inline; filename="%s"' % name)
                    req.send(text, "application/octet-stream")
                    return
                except Exception, e:
                    # req.send_error(sys.exc_info(), status=500, env=self.env, data = { "page" : page})
                    # return
                    message = "OOPS %s" % (e,)
            else:
                message = translate("userscript not found:")
                message += " %s" % name
        elif page and page.startswith("tvspielfilm"):
            # decode the strings from the remote page
            date = req.args["date"]
            time = req.args["time"]
            channel = req.args["channel"]
            title = req.args["title"]
            on_date = re.compile(r"\w\w\s+(\d+)[.](\d+)[.]\s*")
            on_time = re.compile(r"(\d+:\d+)\s+-\s+(\d+:\d+)")
            newdate = None
            newtime = None
            endtime = None
            m = on_date.match(date)
            if m:
                day = m.group(1)
                month = m.group(2)
                current = datetime.datetime.now()
                year = current.year
                if int(month) < current.month:
                    year += 1  
                newdate = datetime.datetime(year, int(month), int(day))
            m = on_time.match(time)
            if m:
                newtime = m.group(1)
                endtime = m.group(2)
            channel = self.map_channel(channel)
            message = self.save(req, newdate, newtime, endtime, channel, title, page)

        userscripts = []
        for filename in os.listdir(userscripts_dir):
            if filename.endswith(".user.js"):
                userscripts += [ filename ]

        add_stylesheet(req, 'common/css/wiki.css')
        add_stylesheet(req, PACKAGE+'/css/dvbcronrecording.css')
        add_script(req, 'common/js/trac.js')
        add_script(req, 'common/js/wikitoolbar.js')

        # passing variables to template
        data = {}
        data['message'] = message
        data['title'] = translate('Userscript List')
        data['scripts_url'] = self.get_scripts_url("")
        data['install_url'] = self.get_install_url("")
        data["_pagenum"] = req.args.get("_pagenum", "0")
        data["_pagesize"] = req.args.get("_pagesize", "10")
        data['datalist'] = Paginator(userscripts, int(data["_pagenum"]), int(data["_pagesize"]))
        data['author'] = req.authname or ""
        data['_'] = translate

        return ('programguidescripts.html', data, None)

    def get_scripts_dir(self):
        htdocsdir = self.get_htdocs_dirs()[0][1]
        return os.path.join(str(htdocsdir), "js")
    def get_install_url(self, name):
        return "%s/%s/install/%s" % (URL, SUBURL, name)
    def get_scripts_url(self, name):
        return ("/chrome/"+PACKAGE+"/js/"+name)

    def save(self, req, newdate, newtime, endtime, channel, title, source):
        onlydate = newdate.strftime("%d.%m.")
        weekday = newdate.weekday()
        session = db_cnx(self.env)
        q = session.query(RecordingList).filter_by(title = title, onlydate = onlydate)
        existing = q.count()
        if existing > 0:
            return "EXISTS"
        item = RecordingList()
        item.channelname = channel
        item.newtime = newtime
        item.endtime = endtime
        item.extratime = 9
        item.weekday = weekday
        item.onlydate = onlydate
        item.status = "ok"
        item.priority = "3"
        item.title = title
        session.add(item)
        datespec = "[%s-%s%s]" % (item.newtime, 
                                item.endtime, 
                                item.onlydate 
                               ) 
        changed = "new recording on %s %s %s (from %s)" % (item.channelname,
                                                 datespec,
                                                 item.title,
                                                 source)
        session.add(RecordingChanges(tablename="RecordingList",
                                  username=req.authname,
                                  modified=datetime.datetime.now(),
                                  changed=changed))
        session.flush()
        return u"OK %s" % item.id
    def map_channel(self, channel):
        """ FIXME: hardcoded """
        if channel in ["Das Erste"]:
            return "1ard"
        if channel in ["ZDF"]:
            return "2zdf"
        if channel in [ "RTL" ]:
            return "rtl"
        if channel in [ "SAT.1" ]:
            return "sat1"
        if channel in [ "ProSieben" ]:
            return "pro7"
        if channel in [ "kabel eins" ]:
            return "kabel1"
        if channel in [ "RTL II" ]:
            return "rtl2"
        if channel in [ "VOX" ]:
            return "vox"
        if channel in [ "ARTE" ]:
            return "arte"
        if channel in [ "TELE 5" ]:
            return "tele5"
        return channel