Source

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

Full commit
import pkg
import re
import os
import commands
from urllib import quote_plus, unquote_plus
from glob import glob

from trac.core import Component, implements
from trac.web.chrome import add_stylesheet, add_script

from trac.web import IRequestHandler
from trac.perm import IPermissionRequestor
from trac.web.chrome import ITemplateProvider
from trac.config import PathOption
from trac.util.presentation import Paginator

from quoting import quote4, unquote4

from translate import Translate

PACKAGE = 'dvbcronrecording'
NAV = 'recordings'
URL = 'recording'
SUBURL = 'file'
INTODIR = "/srv/record"

# from core import LIST_VIEW, LIST_APPEND, LIST_DELETE
LIST_VIEW = 'DVBREC_LIST_VIEW'
LIST_APPEND = 'DVBREC_LIST_APPEND'
LIST_DELETE =  'DVBREC_LIST_DELETE'

def ustr(text):
    if type(text) is unicode: return text
    if type(text) is str: return unicode(text)
    return unicode(str(text))
def quote_plus_str(text):
    if type(text) is unicode: return quote_plus(text.encode("utf-8"))
    if type(text) is str: return quote_plus(text)
    return quote_plus(str(text))
def unquote_plus_ustr(text):
    return unicode(unquote_plus(str(text)), "utf-8")    

class FileEntry: pass

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

    #
    # Public methods
    #

    implements(IPermissionRequestor, ITemplateProvider, IRequestHandler)

    intodir = PathOption(PACKAGE, "intodir", INTODIR,
     doc="Where to put the recorder files (mostly videos of course).")
    
    # IPermissionRequestor methods

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

    # 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')]

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

    """
      Handles display, append and delete requests on this plugin.
    """
    def process_request(self, req):
        req.perm.assert_permission('DVBREC_LIST_VIEW')
        translate = Translate("files", req.locale)

        # getting cursor
        db = self.env.get_db_cnx()
        cursor = db.cursor()
        page = req.args['page']
        if not page: page = "list"
        videotype="video/mpeg"
        downloadtype = "application/mpeg2"
        if page.startswith("data/"):
            name = page[len("data/"):]
            if os.path.exists(self.intodir+"/"+name):
                mime_type = downloadtype
                req.send_header('Content-Disposition', '; filename=%s' % name)
                req.send_file(self.intodir+"/"+name, mime_type)
                return
            else:
                page = "showfiles"
        if page.startswith("mplay/"):
            videotype = "application/x-mplayer2"
            page = page[len("m"):]
        if page.startswith("play/") or page.startswith("mplayer"):
            name = page[len("play/"):]
            data = {}
            data['title'] = translate("Show Video")
            data['entries'] = self._file_entries(cursor, req)
            data['videofile'] = name
            data['videoheight'] = 576
            data['videowidth'] = 768
            data['videotype'] = videotype
            data['_'] = translate
            add_stylesheet(req, PACKAGE+'/css/recordinglist.css')
            add_script(req, 'common/js/trac.js')
            return ('recordingfiles.html', data, None)
        message = ""
        if page.startswith('remove'):
            # i.e. delete-file
            name = page[len("remove/"):]
            page = "showfiles"
            filepath = self.intodir+"/"+name
            try:
                os.remove(filepath)
            except Exception, e:
                message = "OOPS, "+str(e)
        # if page in [ 'showfiles', 'data', 'play' ]:
        if not message:
            diskfree = commands.getoutput("df -h "+self.intodir)
            message =  "| \n".join([ item for item in diskfree.split("\n") if "/" in item ])
            # message = diskfree 
        entries = self._file_entries(cursor, req)
        data = {}
        data['title'] = translate("Recorded Files Overview")
        data["_pagenum"] = req.args.get("_pagenum", "0")
        data["_pagesize"] = req.args.get("_pagesize", "10")
        data['datalist'] = Paginator(entries, int(data["_pagenum"]), int(data["_pagesize"]))
        data['message'] = unicode(message)
        data["_"] = translate
        add_stylesheet(req, PACKAGE+'/css/recordinglist.css')
        add_script(req, 'common/js/trac.js')
        return ('recordingfiles.html', data, None)
    def _file_entries(self, cursor, req):
        if False:
            entry = FileEntry()
            entry.name = self.intodir+"/*.mpg"
            entry.path = self.intodir+"/*.mpg"
            entry.file = "*.mpg"
            entry.size = 0
            yield entry
        for path in reversed(sorted(glob(self.intodir+"/*.mpg"))):
            entry = FileEntry()
            entry.path = path
            entry.file = os.path.basename(path)
            entry.size = os.path.getsize(path) 
            name = entry.file
            pref = ""
            m = re.match(r"(\d\d\d\d+-\d\w+-\d\d+)-(.*).mpg", name)
            n = re.match(r"(\d\d\d\d+-\w+)[.](.*).mpg", name)
            if m: name = m.group(2) ; pref = m.group(1)
            elif n: name = n.group(2) ; pref = n.group(1)
            try:
                entry.name = unquote4(name)
            except Exception, e:
                entry.name = ustr(e)
            entry.pref = unquote4(pref)
            yield entry