Re: [Freevo-users] iui based iphone/ipod interface for freevo WAS: Re: Whole house audio and iphone/ipod touch interface for freevo - initial stages started

John Molohan <[email protected]>
Newsgroups gmane.comp.video.freevo.devel
Message-ID <[email protected]>
Jonathan Isom wrote:
> On Tue, Jun 30, 2009 at 5:31 PM, John Molohan<[email protected]> wrote:
>   
>> So that prediction turned out a little ambitious, this is the first chance
>> I've had even just to tar it up and post. There's been absolutely nothing
>> else done to it since I first played around with it, don't expect too much
>> to work but with a bit of time it's realistic that it could be made quite
>> usable. I've tarred up my /usr/share/freevo/htdocs/ folder in it's entirety
>> for simplicity. It's based on a svn checkout from May (details below) so
>> beware if you're replacing your install with this. You'll see I've just hard
>> coded the section for whole house / multi room control as a mock up but I
>> have an idea on how that could work in practice and again it shouldn't be
>> too hard. To test it out browse to
>> http://localhost:8080/iui/samples/freevo.html, substitute in your
>> ip/hostname to browse from your iphone or ipod touch. I've left the old
>> library alone from what I remember so that should still work too. I hope
>> someone finds it useful or at least interesting :)
>>
>>     
> Hi John,
>    Looks like you miised web_types_jm.  Just got around to looking at
> it my self.
> Later
>
> Jonathan
>   File "/usr/lib64/python2.6/site-packages/twisted/protocols/basic.py",
> line 231, in dataReceived
>     why = self.lineReceived(line)
>   File "/usr/lib64/python2.6/site-packages/twisted/web/http.py", line
> 1067, in lineReceived
>     self.allContentReceived()
>   File "/usr/lib64/python2.6/site-packages/twisted/web/http.py", line
> 1108, in allContentReceived
>     req.requestReceived(command, path, version)
>   File "/usr/lib64/python2.6/site-packages/twisted/web/http.py", line
> 626, in requestReceived
>     self.process()
> --- <exception caught here> ---
>   File "/usr/lib64/python2.6/site-packages/twisted/web/server.py",
> line 149, in process
>     resrc = self.site.getResourceFor(self)
>   File "/usr/lib64/python2.6/site-packages/twisted/web/server.py",
> line 567, in getResourceFor
>     return resource.getChildForRequest(self.resource, request)
>   File "/usr/lib64/python2.6/site-packages/twisted/web/resource.py",
> line 50, in getChildForRequest
>     resource = resource.getChildWithDefault(pathElement, request)
>   File "/usr/lib64/python2.6/site-packages/twisted/web/resource.py",
> line 150, in getChildWithDefault
>     return self.getChild(path, request)
>   File "/usr/lib64/python2.6/site-packages/twisted/web/static.py",
> line 277, in getChild
>     return resource.IResource(processor(fpath.path, self.registry))
>   File "/usr/lib64/python2.6/site-packages/twisted/web/script.py",
> line 70, in ResourceScript
>     execfile(path, glob, glob)
>   File "/usr/share/freevo/htdocs/iui/samples/guide.rpy", line 42, in <module>
>     from www.web_types_jm import HTMLResource, FreevoResource,
> RecordClientResource
> exceptions.ImportError: No module named web_types_jm
>   
Here you go. It's so long now since I looked at it I'm not sure if there 
was anything else, hopefully not. I'd love a bit of feedback or even for 
someone to do a bit of work to bring it on as I won't be looking at for 
a few months.

John
>
>   
>> John
>>
>> [john@localhost freevo-1.x]$ svn info
>> Path: .
>> URL: svn://svn.freevo.org/freevo/branches/rel-1
>> Repository Root: svn://svn.freevo.org/freevo
>> Repository UUID: cc3e1ea1-1e01-0410-8d68-8b121e83a9d5
>> Revision: 11482
>> Node Kind: directory
>> Schedule: normal
>> Last Changed Author: duncan
>> Last Changed Rev: 11482
>> Last Changed Date: 2009-05-07 18:39:35 +0100 (Thu, 07 May 2009)
>>
>>
>> ------------------------------------------------------------------------------
>>
>> _______________________________________________
>> Freevo-devel mailing list
>> [email protected]
>> https://lists.sourceforge.net/lists/listinfo/freevo-devel
>>
>>
>>     
>
>
>
>

------------------------------------------------------------------------------
Enter the BlackBerry Developer Challenge  
This is your chance to win up to $100,000 in prizes! For a limited time, 
vendors submitting new applications to BlackBerry App World(TM) will have
the opportunity to enter the BlackBerry Developer Challenge. See full prize  
details at: http://p.sf.net/sfu/Challenge

_______________________________________________
Freevo-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freevo-devel
web_types_jm.py (text/x-python, 19.3 KB)
# -*- coding: iso-8859-1 -*-
# -----------------------------------------------------------------------
# Classes useful for the web interface.
# -----------------------------------------------------------------------
# $Id: web_types.py 11479 2009-05-07 17:34:38Z duncan $
#
# Notes:
# Todo:
#
# -----------------------------------------------------------------------
# Freevo - A Home Theater PC framework
# Copyright (C) 2003 Krister Lagerstrom, et al.
# Please see the file freevo/Docs/CREDITS for a complete list of authors.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MER-
# CHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# -----------------------------------------------------------------------
import base64
import crypt
import re

import os, sys, time

import config
import socket

from twisted.web.woven import page
from twisted.web.resource import Resource
from tv.record_client import RecordClient

TRUE = 1
FALSE = 0


_singleton = None

def RecordClientResource():
    global _singleton

    # One-time init
    if _singleton is None:
        _singleton = RecordClientActions()

    return _singleton



class RecordClientActions:
    """
    """
    def __init__(self):
        import kaa
        self.recordclient = RecordClient()
        kaa.inprogress(self.recordclient.channel).wait()


    def __call__(self):
        return RecordClientResource().recordclient



class FreevoPage(page.Page):
    """
    """
    def __init__(self, model=None, template=None):
        #print 'FreevoPage.__init__(model=%r, template=%r)' % (model, template)

        if not model:
            model = {'foo': 'bar'}
        if not template:
            template = '<html><head><title>ERROR</title></head>' + \
                       '<body>ERROR: no template</body></html>'

        page.Page.__init__(self, model, template=template)

        self.addSlash = 0


class FreevoResource(Resource):
    """
    Base class of webpages which handels the authentication.

    All webpages should be subclasses of this class.
    The subclasses must not have a render method
    but they need a _render method instead.
    When a webpage is opened by the user then first the render method
    of this base class is called and then if the authentication was successfull
    the _render method of the subclass is called.
    Otherwise a error messages is returned and shown to the user.
    """
    def render(self, request):
        """
        render method of this class.

        This method will be called when a user requests this page.
        It only handels the authentication but does not present any
        content.If authentication is successfull this method returns the
        _render method, which does the actuall work.
        """
        # get username and password from the user
        username = request.getUser()
        password = request.getPassword()

        if not self.auth_user(username, password):
            # authentication fails, thus we send 401 error
            request.setResponseCode(401, 'Authentication needed')
            # still we have to create a few things for the header
            request.setHeader('WWW-Authenticate', 'Basic realm="unknown"')
            request.setHeader('Content-Length', str(len('401: = Authorization needed.')))
            request.setHeader('Content-Type', 'text/html')
            # this is for the body of the html document
            return '<h1>401 Authentication required</h1>'
        else:
            # authentication was successfull
            # thus we return the self._render method
            # which hopefully will do something usefull
            self.session = request.getSession()
            return self._render(request)


    def auth_user(self, username, password):
        """
        Check of username and password

        This method validates username and password.
        If authentication is successfull it returns True otherwise False.
        """
        #print 'auth_user(username=%r, password=%r)' % (username, '******')
        cryptpass = config.WWW_USERS.get(username)
        if not cryptpass:
            return False
        m = re.match(r'^(\$1\$[a-zA-Z\d/.]{8}\$)', cryptpass)
        if m:
            # Password is in crypt()ed form.
            return cryptpass == crypt.crypt(password, m.group(1))
        # Assume password is stored as plaintext
        return cryptpass == password



class HTMLResource:
    """
    HTML elements of a freevo webpage

    This class provides many usefull elements which can be used
    in a webpage. It provides a string called res which should be used to
    build up the html string that should form the content of a webpage.
    Usage: Create a instance of this class in the _render method of the
    subclass which represents the webpage, use all this methods to build
    the html string  and return HTMLResource.res in the end.
    """
    def __init__(self):
        # create empty result string which must be filled with life
        self.res =''


    def printContentType(self, content_type='text/html'):
        """Content"""
        # debug print
        #print 'printContentType(content_type=%r)' % (content_type)
        # adding new text
        self.res += 'Content-type: %s\n\n' % content_type


    def printHeader(self, title='unknown page', style=None, script=None, rss=None, selected='Help', prefix=0):
        """
        Header

        This produces the header of a freevo page with the navigation bar.

        @param title:    title of the webpage
        @param style:    style sheet to use for this page
        @param script:   java script to use  for this page
        @param selected: which tab in the tabline should be highlighed
        @param prefix:   how many directory levels is this file below the main level
            this is needed for the links in the navigation bar.
        """

        # debug print
        #print 'printHeader(title=%r, style=%r, script=%r, selected=%r, prefix=%r)' % \
        #    (title, style, script, selected, prefix)

        # we are prefix level below the main directory thus we must go prefix times up,
        # before we are in the same directory than those pages that are in the navigation bar.
        # This is needed for creating the links in the navigation bar.
        strprefix = '../' * prefix

        # now we can start to create the header:

        # doc type
        #self.res += '<?xml version="1.0" encoding="'+ config.encoding +'"?>\n'
##        self.res += '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" '
##        self.res += '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n'

        # <html> and <head> tag
##        self.res += '<html>\n\t<head>\n'
        # <title>
##        self.res += '\t<title>Freevo | '+title+'</title>\n'
        # meta tags, encoding is taken from the users config
##        self.res += '\t<meta http-equiv="Content-Type" content= "text/html; charset='+ config.encoding +'"/>\n'
##        self.res += '\t<link rel="shortcut icon" href="/favicon.ico" />\n'
        # css style sheet
##        if style != None:
##            self.res += '\t<link rel="stylesheet" href="styles/main.css" type="text/css" media="screen" />\n'
        # java script
##        if script != None:
##            self.res += '\t<script language="JavaScript" type="text/JavaScript" src="'+script+'"></script>\n'
        # rss
##        if rss is not None:
##            self.res += '\t<link rel="alternate" href="'+rss+'" type="application/rss+xml" title="" id="gallery" />\n'
        # end of <head>
##        self.res += '</head>\n'
        # here starts the body
##        self.res += '\n\n\n\n<body>\n'
        # header of the page with tab bar
##        self.res += '<!-- Header Logo and Status Line -->\n'
        # headline
##        self.res += '<div id="titlebar"><span class="name">'\
##            +'<a href="http://freevo.sourceforge.net/" target="_blank">Freevo</a></span></div>\n'
        # start the bar, it is build as a list
##        self.res += '<div id="header">\n<ul>'
        # this items should be shown in the tab bar
##        items = []
##        for label, title, link in config.WWW_PAGES:
##            items.append((label, title, os.path.join(str(strprefix), link)))
        # maybe also a personal web pages
##        if hasattr(config, 'WWW_PERSONAL_PAGE'):
##            for page in config.WWW_PERSONAL_PAGE:
##                items.append((page[0], page[1], os.path.join(str(strprefix), page[2])))
##        if hasattr(config, 'WWW_ICECAST_PAGE') and config.WWW_ICECAST_PAGE:
##            items.append((_('Icecast List'),_('Change Icecast List'),'%siceslistchanger.rpy' % (strprefix)))
        # go through the items and create the bar
##        for i in items:
##            if selected == i[0]:
                # this item is selected, thus we highlight the tab
##                self.res += '<li id="current">'
##            else:
##                self.res += '<li>'
##            self.res += "<a href=\"%s\" title=\"%s\">%s</a></li>\n" % (i[2], i[1],i[0])
        # end of the bar list
##        self.res += '</ul>\n</div>'
        # now we are ready for the main content
##        self.res += '\n<!-- Main Content -->\n';


    def tableOpen(self, opts=''):
        """
        Opens a table

        opts are additional parameters for the <table> tag.
        """
        #print 'tableOpen(opts=%r)' % (opts)
        self.res += "<table "+opts+">\n"


    def tableClose(self):
        """
        Close a table
        """
        #print 'tableClose()'
        self.res += "</table>\n"


    def tableHeadOpen(self, opts=''):
        """
        Open a table header line

        opts are additional parameters for the <thead> tag.
        """
        #print 'tableHeadOpen(opts=%r)' % (opts)
        self.res += "  <thead "+opts+">\n"


    def tableHeadClose(self, opts=''):
        """
        Closes a table header line
        """
        #print 'tableHeadClose(opts=%r)' % (opts)
        self.res += "  </thead>\n"


    def tableBodyOpen(self, opts=''):
        """
        Opens a table body

        opts are additional parameter for the <tbody> tag
        """
        #print 'tableBodyOpen(opts=%r)' % (opts)
        self.res += "  <tbody "+opts+">\n"


    def tableBodyClose(self, opts=''):
        """
        Closes a table body
        """
        #print 'tableBodyClose(opts=%r)' % (opts)
        self.res += "  </tbody>\n"


    def tableFootOpen(self, opts=''):
        """
        Opens a table footer

        opts are additional parameters for the <tfoot> tag.
        """
        #print 'tableFootOpen(opts=%r)' % (opts)
        self.res += "  <tfoot "+opts+">\n"


    def tableFootClose(self, opts=''):
        """
        Closes a table footer.
        """
        #print 'tableFootClose(opts=%r)' % (opts)
        self.res += "  </tfoot>\n"


    def tableRowOpen(self, opts=''):
        """
        Opens a table row

        opts are additonal parameters for the <tr> tag
        """
        #print 'tableRowOpen(opts=%r)' % (opts)
        self.res += "     <tr "+opts+">\n"


    def tableRowClose(self):
        """
        Closes a table row
        """
        #print 'tableRowClose()'
        self.res += "     </tr>\n"


    def tableCell(self, data='', opts=''):
        """
        Creates a table cell

        opts are additonal parameters for the <td>.
        data is the content of this table cell.
        """
        #print 'tableCell(data=%r, opts=%r)' % (data, opts)
        self.res += "       <td "+opts+">"+data+"</td>\n"


    def formValue(self, form=None, key=None):
        #print 'formValue(form=%r, key=%r)' % (form, key)
        if not form or not key:
            return None
        try:
            val = form[key][0]
        except:
            val = None

        return val


    def printFooter(self):
        """
        Closes the html document
        """
        #print 'printFooter()'
 ##       self.res += '</body>\n</html>\n'


    def printSearchForm(self):
        """
        Creates the simple search form"""

        #print 'printSearchForm()'
##        self.res += """
##    <form id="SearchForm" action="search.rpy" method="get">
##    <div class="searchform"><b>"""+_('Search')+""":</b><input type="text" name="find" size="20" /></div>
##    </form>
##    """


    def printAdvancedSearchForm(self):
        """
        Creates the advanced search form.

        This search form has an additonal checkbox and a go button
        """

        #print 'printAdvancedSearchForm()'
        self.res += """
    <form id="SearchForm" action="search.rpy" method="get">
    <div class="searchform"><b>"""+_('Search')+""":</b><input type="text" name="find" size="20" />
    <input type="checkbox" selected=0 name="movies_only" />"""+_('Movies only')+"""
    <input type="submit" value=" """+_('Go!')+""" " />
    </div>
    </form>
    """


    def printMessages(self, messages):
        """
        Prints a message
        """
        #print 'printMessages(messages=%r)' % (messages)
        self.res += "<h4>"+_("Messages")+":</h4>\n"
        self.res += "<ul>\n"
        for m in messages:
            self.res += "   <li>%s</li>\n" % m
            self.res += "</ul>\n"


    def printMessagesFinish(self, messages):
        """
        Print messages and add the search form, links and footer.
        """
        #print 'printMessagesFinish(messages=%r)' % (messages)
        self.printMessages( messages )
        self.printSearchForm()
        self.printLinks()
        self.printFooter()


    def printLinks(self, prefix=0):
        """
        Print Link
        """
        # seems to do nothing at the moment ????
        #print 'printLinks(prefix=%r)' % (prefix)
        #
        #try:
        #    if config.WWW_ICECAST_PAGE:
        #        self.res += '<a href="%siceslistchanger.rpy">Change Icecast List</a>' % strprefix
        #except AttributeError:
        #    pass
        return


    def printBreadcrumb(self, media, mediadirs, dir):
        """
        ???
        """
        #print 'printBreadcrumb(media=%r, mediadirs=%r, dir=%r)' % (media, mediadirs, dir)
        breadcrumb='<a href="library.rpy">Home: </a><a href="library.rpy?media='+media+'&dir=">'+media+'</a>'
        _url = ""
        url = dir.split("/")
        _mediadir = mediadirs[0][1].split("/")
        for i in url:
            _url += i + "/"
            if i not in _mediadir or i == _mediadir[len(_mediadir)-1]:
                breadcrumb += '/<a href="library.rpy?media='+media+'&dir='+_url+'">'+Unicode(i)+'</a>'

        return breadcrumb


    def printPassword(self, password):
        """
        ???
        """
        #print 'printPassword(password=%r)' % (password)
        self.res += """<script language="JavaScript"> <!--

        var password;

        var pass1=""" + password + """;

        password=prompt('Please enter your password to view this page!',' ');

        if (password!=pass1){
            alert('Password Incorrect, redirected...');
            window.location="library.rpy";
        }
        //-->
        </script>"""


    def printImagePopup(self):
        """
        Opens a Popup to display an image
        """
        #print 'printImagePopup()'
        self.res += """<script language="JavaScript" type="text/javascript" style="display:none;">
        var width = 0;
        var height = 0;
        var max_width = screen.availWidth;
        var max_height = screen.availHeight - 250;
        var client_width = 0;
        var client_height = 0;

        function openfoto(loc,width_img,height_img){
            width = width_img;
            height = height_img;

            if (width >= max_width || height >= max_height) {
                getNewSize();
            }
            var params="toolbar=no,location=no,status=no,menubar=yes,resizable=no,top=0,left=0,width="+width+",height="+height;
            foto = Lightbox.show(''+loc+'', '', 'width='+width+', height='+height+'');
         }

         function getNewSize(){
            // recalculate width / height maintaining aspect
            if (max_width / max_height > width / height) {
                width = Math.round(max_height * width / height);
                height = max_height;
            }
            else {
                height = Math.round(max_width * height / width);
                width = max_width;
            }
        }
        </script> """


    def printWebRemote(self):
        """
        Prints web remote

        If configured to do so,
        then this displays a remote to control freevo
        via the web browser
        """
        #print 'printWebRemote()'
        if not (config.ENABLE_NETWORK_REMOTE == 1 and config.REMOTE_CONTROL_PORT):
            self.res += "no remote enabled"

        self.res += u"""
           <style type="text/css" media="screen">
            table.remote { width: auto; }
            td.remote    { padding: 0px; }
            button.remote { width: 60px; height: 18px; background: #eee; font-size: 12px;
                text-align: center; padding: 0; }
            button.remote:hover { background: #fed; }
           </style>

           <script type="text/javascript">
           <!--
             // AJAX Functions
             var xmlHttp = false;
             var remoteWin = 0;

             function getXMLHttpObject () {
               if (window.XMLHttpRequest) {
                 xmlHttp=new XMLHttpRequest()
               }
               else if (window.ActiveXObject) {
                 xmlHttp=new ActiveXObject("Microsoft.XMLHTTP")
               }
               return xmlHttp
               try {
                 xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");      // Internet Explorer 1st try
               } catch (e) {
                 try {
                   xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); // Internet Explorer 2nd try
                 } catch (e2) {
                   xmlHttp = false;
                 }
               }
               if (!xmlHttp && typeof XMLHttpRequest != 'undefined') {
                 xmlHttp = new XMLHttpRequest();                     // Mozilla, Firefox, Opera
               }
             }

             function send_code( code ) {
               if (! xmlHttp)
                 getXMLHttpObject();
               var url = 'webremote.rpy?code=' + code + '&sid=' + Math.random();
               xmlHttp.open('GET', url, true);
               xmlHttp.send(null);
             }

            function openremote(){
              if(remoteWin) {
                if(!remoteWin.closed) {remoteWin.focus();}
                }
              var params="toolbar=no,location=no,status=no,menubar=no,resizable=no,scrollbars=no,top=0,left=0";
              remoteWin = window.open("webremote.rpy","WebRemote",params);
              remoteWin.focus();
            }
           -->
           </script>
        <br />
        <table border="0" cellspacing="0" cellpadding="0" class="remote">
        <tr><td colspan="3" align="center"><a href="javascript:openremote()">Freevo WebRemote</a></td></tr>
        </table>
        """
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.