From 1ecfae71fe7dc9c069089f8d6d75b7978fbb94e1 Mon Sep 17 00:00:00 2001
From: Britney Fransen <brfransen@gmail.com>
Date: Fri, 30 Dec 2022 16:06:31 -0500
Subject: linhes-web: initial inclusion

---
 linhes/linhes-web/.gitignore                       |   1 +
 linhes/linhes-web/PKGBUILD                         |  17 +
 linhes/linhes-web/mp_preflight                     |   3 +
 .../linhes-web/website/contents/ajaxloader.min.js  |   1 +
 linhes/linhes-web/website/contents/back.png        | Bin 0 -> 3133 bytes
 linhes/linhes-web/website/contents/calllog.py      |  66 +++
 linhes/linhes-web/website/contents/calllog.shtml   |  19 +
 linhes/linhes-web/website/contents/cardmap.shtml   |  13 +
 linhes/linhes-web/website/contents/count.py        | 100 +++++
 linhes/linhes-web/website/contents/docs.html       |  58 +++
 .../linhes-web/website/contents/error-handler.html |   9 +
 .../website/contents/error/call_log.html           |  11 +
 .../linhes-web/website/contents/error/hobbit.html  |  11 +
 .../website/contents/error/mythbackend.html        |  11 +
 .../website/contents/error/mythexport.html         |  22 +
 .../website/contents/error/mythexpress.html        |  20 +
 .../linhes-web/website/contents/error/mythweb.html |  16 +
 .../website/contents/error/phpadmin.html           |  26 ++
 .../linhes-web/website/contents/error/remyth.html  |  22 +
 .../website/contents/error/status-404.html         |   9 +
 .../website/contents/error/zoneminder.html         |  20 +
 linhes/linhes-web/website/contents/exports.shtml   |  14 +
 linhes/linhes-web/website/contents/favicon.ico     | Bin 0 -> 1150 bytes
 linhes/linhes-web/website/contents/fe_status.py    | 144 +++++++
 linhes/linhes-web/website/contents/fe_status.shtml |  18 +
 .../website/contents/fe_status_load.shtml          |  41 ++
 linhes/linhes-web/website/contents/frame.css       | 229 +++++++++++
 linhes/linhes-web/website/contents/go.png          | Bin 0 -> 2471 bytes
 linhes/linhes-web/website/contents/header.html     |  97 +++++
 linhes/linhes-web/website/contents/home.shtml      |  17 +
 .../website/contents/images/classic-menugraph.png  | Bin 0 -> 144106 bytes
 .../website/contents/images/dvr_menugraph.png      | Bin 0 -> 207288 bytes
 .../website/contents/images/menu_diagram_color.png | Bin 0 -> 193264 bytes
 linhes/linhes-web/website/contents/index.html      |  16 +
 .../linhes-web/website/contents/linhes_header.png  | Bin 0 -> 57259 bytes
 linhes/linhes-web/website/contents/links.html      |  27 ++
 linhes/linhes-web/website/contents/list_cardmap.py | 156 +++++++
 linhes/linhes-web/website/contents/list_exports.py |  85 ++++
 linhes/linhes-web/website/contents/mv.css          | 100 +++++
 linhes/linhes-web/website/contents/mvp_process.py  | 195 +++++++++
 linhes/linhes-web/website/contents/mvp_select.py   | 146 +++++++
 linhes/linhes-web/website/contents/mvpmc.shtml     |  21 +
 linhes/linhes-web/website/contents/mythweb.html    |  16 +
 .../website/contents/page_background.jpg           | Bin 0 -> 740 bytes
 linhes/linhes-web/website/contents/process.py      | 447 +++++++++++++++++++++
 linhes/linhes-web/website/contents/skeleton.css    | 105 +++++
 46 files changed, 2329 insertions(+)
 create mode 100644 linhes/linhes-web/.gitignore
 create mode 100644 linhes/linhes-web/PKGBUILD
 create mode 100755 linhes/linhes-web/mp_preflight
 create mode 100755 linhes/linhes-web/website/contents/ajaxloader.min.js
 create mode 100644 linhes/linhes-web/website/contents/back.png
 create mode 100644 linhes/linhes-web/website/contents/calllog.py
 create mode 100644 linhes/linhes-web/website/contents/calllog.shtml
 create mode 100755 linhes/linhes-web/website/contents/cardmap.shtml
 create mode 100644 linhes/linhes-web/website/contents/count.py
 create mode 100644 linhes/linhes-web/website/contents/docs.html
 create mode 100644 linhes/linhes-web/website/contents/error-handler.html
 create mode 100644 linhes/linhes-web/website/contents/error/call_log.html
 create mode 100644 linhes/linhes-web/website/contents/error/hobbit.html
 create mode 100644 linhes/linhes-web/website/contents/error/mythbackend.html
 create mode 100644 linhes/linhes-web/website/contents/error/mythexport.html
 create mode 100644 linhes/linhes-web/website/contents/error/mythexpress.html
 create mode 100644 linhes/linhes-web/website/contents/error/mythweb.html
 create mode 100644 linhes/linhes-web/website/contents/error/phpadmin.html
 create mode 100644 linhes/linhes-web/website/contents/error/remyth.html
 create mode 100644 linhes/linhes-web/website/contents/error/status-404.html
 create mode 100644 linhes/linhes-web/website/contents/error/zoneminder.html
 create mode 100755 linhes/linhes-web/website/contents/exports.shtml
 create mode 100644 linhes/linhes-web/website/contents/favicon.ico
 create mode 100644 linhes/linhes-web/website/contents/fe_status.py
 create mode 100644 linhes/linhes-web/website/contents/fe_status.shtml
 create mode 100755 linhes/linhes-web/website/contents/fe_status_load.shtml
 create mode 100644 linhes/linhes-web/website/contents/frame.css
 create mode 100644 linhes/linhes-web/website/contents/go.png
 create mode 100644 linhes/linhes-web/website/contents/header.html
 create mode 100644 linhes/linhes-web/website/contents/home.shtml
 create mode 100644 linhes/linhes-web/website/contents/images/classic-menugraph.png
 create mode 100644 linhes/linhes-web/website/contents/images/dvr_menugraph.png
 create mode 100644 linhes/linhes-web/website/contents/images/menu_diagram_color.png
 create mode 100644 linhes/linhes-web/website/contents/index.html
 create mode 100644 linhes/linhes-web/website/contents/linhes_header.png
 create mode 100644 linhes/linhes-web/website/contents/links.html
 create mode 100755 linhes/linhes-web/website/contents/list_cardmap.py
 create mode 100755 linhes/linhes-web/website/contents/list_exports.py
 create mode 100644 linhes/linhes-web/website/contents/mv.css
 create mode 100644 linhes/linhes-web/website/contents/mvp_process.py
 create mode 100644 linhes/linhes-web/website/contents/mvp_select.py
 create mode 100644 linhes/linhes-web/website/contents/mvpmc.shtml
 create mode 100644 linhes/linhes-web/website/contents/mythweb.html
 create mode 100644 linhes/linhes-web/website/contents/page_background.jpg
 create mode 100755 linhes/linhes-web/website/contents/process.py
 create mode 100644 linhes/linhes-web/website/contents/skeleton.css

diff --git a/linhes/linhes-web/.gitignore b/linhes/linhes-web/.gitignore
new file mode 100644
index 0000000..073b364
--- /dev/null
+++ b/linhes/linhes-web/.gitignore
@@ -0,0 +1 @@
+website.tar.gz
diff --git a/linhes/linhes-web/PKGBUILD b/linhes/linhes-web/PKGBUILD
new file mode 100644
index 0000000..7cde68f
--- /dev/null
+++ b/linhes/linhes-web/PKGBUILD
@@ -0,0 +1,17 @@
+pkgname=linhes-web
+pkgver=9.0.0
+pkgrel=1
+conflicts=()
+pkgdesc="LinHES local website"
+depends=()
+makedepends=()
+arch=('x86_64')
+license=('GPL')
+source=(website.tar.gz)
+sha256sums=('6ff99589d225826d86bd1911aa0223f3c9668c02ff15e7bc607e52d90cca20ae')
+
+package() {
+    mkdir -p $pkgdir/data/srv/httpd/htdocs/
+    cp -rp $srcdir/website/contents/* $pkgdir/data/srv/httpd/htdocs
+    chmod -R 755 $pkgdir/data/srv/httpd/htdocs
+}
diff --git a/linhes/linhes-web/mp_preflight b/linhes/linhes-web/mp_preflight
new file mode 100755
index 0000000..037054f
--- /dev/null
+++ b/linhes/linhes-web/mp_preflight
@@ -0,0 +1,3 @@
+#!/usr/bin/bash
+echo "    Starting mp_preflight"
+tar -czvf website.tar.gz ./website
diff --git a/linhes/linhes-web/website/contents/ajaxloader.min.js b/linhes/linhes-web/website/contents/ajaxloader.min.js
new file mode 100755
index 0000000..11c14ba
--- /dev/null
+++ b/linhes/linhes-web/website/contents/ajaxloader.min.js
@@ -0,0 +1 @@
+﻿function AjaxLoader(e,t){function n(e){var t=/^#?([a-f\d])([a-f\d])([a-f\d])$/i;e=e.replace(t,function(e,t,n,r){return t+t+n+n+r+r});var n=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);return n?{r:parseInt(n[1],16),g:parseInt(n[2],16),b:parseInt(n[3],16)}:null}function r(e,t,n){return"#"+((1<<24)+(e<<16)+(t<<8)+n).toString(16).slice(1)}function b(){p=s>=32?s>=128?72:36:18,d=.5*s*o,v=2*Math.PI/p;h=a/m;if(f){h=-h}g.width=s;g.height=s}function w(e){var t=2*Math.PI*e;var n=Math.cos(t),r=Math.sin(t),i=.5*s*(1+n),o=.5*s*(1-r),a=i-d*n,l=o+d*r;y.clearRect(0,0,s,s);for(var c=0;c<p;c++){y.beginPath();if(f){y.fillStyle="rgba("+u.r+","+u.g+","+u.b+","+(p-1-c)/(p-1)+")"}else{y.fillStyle="rgba("+u.r+","+u.g+","+u.b+","+c/(p-1)+")"}y.moveTo(i,o);y.lineTo(a,l);t+=v,n=Math.cos(t);r=Math.sin(t);i=.5*s*(1+n);o=.5*s*(1-r);a=i-d*n;l=o+d*r;y.lineTo(a,l);y.lineTo(i,o);y.closePath();y.fill()}}var i={size:32,factor:.25,speed:1,color:"#000",clockwise:true};var s,o,u,a,f,l,c=0,h,p,d,v,m=30;if(t!=null){s="size"in t?t.size:i.size;o="factor"in t?t.factor:i.factor;u=n("color"in t?t.color:i.color);a="speed"in t?t.speed:i.speed;f="clockwise"in t?t.clockwise:i.clockwise}else{s=i.size;o=i.factor;u=n(i.color);a=i.speed;f=i.clockwise}var g=document.getElementById(e);if(g==null){console.log("AjaxLoader Error! Cannot find canvas element by id '"+e+"'");return null}var y=g.getContext("2d");b();this.show=function(){g.removeAttribute("style");clearInterval(l);l=setInterval(function(){w(c);c+=h;c=c-Math.floor(c)},1e3/m)};this.hide=function(){clearInterval(l);g.style.display="none"};this.getSize=function(){return s};this.setSize=function(e){s=e;b()};this.getFactor=function(){return o};this.setFactor=function(e){o=e;b()};this.getSpeed=function(){return a};this.setSpeed=function(e){a=e;b()};this.getColor=function(){return r(u.r,u.g,u.b)};this.setColor=function(e){u=n(e)};this.getClockwise=function(){return f};this.setClockwise=function(e){f=e;b()}}
\ No newline at end of file
diff --git a/linhes/linhes-web/website/contents/back.png b/linhes/linhes-web/website/contents/back.png
new file mode 100644
index 0000000..6b5da48
Binary files /dev/null and b/linhes/linhes-web/website/contents/back.png differ
diff --git a/linhes/linhes-web/website/contents/calllog.py b/linhes/linhes-web/website/contents/calllog.py
new file mode 100644
index 0000000..0b2fb22
--- /dev/null
+++ b/linhes/linhes-web/website/contents/calllog.py
@@ -0,0 +1,66 @@
+#!/usr/bin/python2
+# import MySQL module
+
+import MySQLdb
+import sys
+import getopt
+import socket
+
+
+def main(argv):
+    grandtotal=0
+    grandtotal_current=0
+    db = MySQLdb.connect(host="localhost", user="mythtv", passwd="[REDACTED] db="ncid")
+    # create a cursor
+    cursor = db.cursor()
+   # execute SQL statement
+   # cursor.execute("select  name,number,count(number) as '# calls'  from cid group by number,name  order by '# calls' DESC  limit 20;")
+   # result = cursor.fetchall()
+
+
+    #Top 20 callers
+    #print '<div id="content"> <p></p>'
+    print '<div> <p></p>'
+    print '<table class="calllog">'
+    print "Top 20 callers"
+    searchstring='''<td> <a href="http://www.google.com/search?q=%s" target="_blank" >  %s  </a> </td> '''
+    cursor.execute("select  name,number,count(number)  from cid group by number,name  order by count(number) DESC  limit 20;")
+    result = cursor.fetchall()
+    for row in result:
+        print "	<tr>"
+        #print "		<td>",row[0],"</td>"
+        print  searchstring  % (row[0], row [0])
+        print "		<td>",row[2],"</td>"
+        #print "		<td>",row[1],"</td>"
+        print  searchstring  % (row[1], row [1])
+        print "	</tr>"
+        #print "%40s %26s %10s" %(row[0],row[2],row[1])
+    print "</table>"
+    print "</div>"
+
+
+    #last 20 calls
+    print '<br>'
+    print '<br>'
+    #print '<div id="content"> <p></p>'
+    print '<div>  <p></p>'
+    print '<table class="calllog">'
+    print "Last 20 calls"
+    print '<br>'
+    cursor.execute("select date,time,name,number from cid order by date(ts) DESC ,time DESC  limit 20 ;" )
+    result = cursor.fetchall()
+    for row in result:
+        print "	<tr>"
+        print "		<td>  %s  </td>" %(row[0])
+        print "		<td>",row[1],"</td>"
+        #print "		<td>",row[2],"</td>"
+        print  searchstring  % (row[2], row [2])
+        #print "		<td>",row[3],"</td>"
+        print  searchstring  % (row[3], row [3])
+        print "	</tr>"
+#        print "%26s %26s %26s %26s " %(row[0],row[1],row[2],row[3])
+    print "</table>"
+    print "</div>"
+
+if __name__ == "__main__":
+    main(sys.argv[1:])
diff --git a/linhes/linhes-web/website/contents/calllog.shtml b/linhes/linhes-web/website/contents/calllog.shtml
new file mode 100644
index 0000000..5b64dc3
--- /dev/null
+++ b/linhes/linhes-web/website/contents/calllog.shtml
@@ -0,0 +1,19 @@
+<html>
+<head>
+<style type="text/css">@import "/frame.css";</style>
+</head>
+
+<body>
+        <div id="header">
+                <h1>Phone Call Log</h1>
+                <br>
+        </div>
+
+	<!--#exec cmd="/data/srv/httpd/htdocs/calllog.py" -->
+
+</br>
+</br>
+
+</body>
+</html>
+
diff --git a/linhes/linhes-web/website/contents/cardmap.shtml b/linhes/linhes-web/website/contents/cardmap.shtml
new file mode 100755
index 0000000..d98a4e9
--- /dev/null
+++ b/linhes/linhes-web/website/contents/cardmap.shtml
@@ -0,0 +1,13 @@
+<html>
+    <head>
+        <style type="text/css">@import "/frame.css";</style>
+    </head>
+    <body>
+        <div id="header">
+		    <h1>Tuners</h1>
+		    <h2>Detected Cards and Static Device Paths</h2>
+        </div>
+        <!--#exec cmd=" MYTHCONFDIR=/usr/share/mythtv /data/srv/httpd/htdocs/list_cardmap.py" -->
+    </body>
+</html>
+
diff --git a/linhes/linhes-web/website/contents/count.py b/linhes/linhes-web/website/contents/count.py
new file mode 100644
index 0000000..76d18e8
--- /dev/null
+++ b/linhes/linhes-web/website/contents/count.py
@@ -0,0 +1,100 @@
+#!/usr/bin/python2
+# import MySQL module
+
+import MySQLdb
+import sys
+import getopt
+import socket
+
+
+def main(argv):
+    #get LinHES version
+    verfile = open('/etc/LinHES-release', 'r')
+    verLH = verfile.read()
+    verfile.close()
+
+    grandtotal=0
+    grandtotal_current=0
+    db = MySQLdb.connect(host="localhost", user="mythtv", passwd="[REDACTED] db="mythconverg")
+    # create a cursor
+    cursor = db.cursor()
+   # execute SQL statement
+    cursor.execute("SELECT unix_timestamp(starttime),unix_timestamp(endtime),title FROM oldrecorded where oldrecorded.recstatus = -3  ORDER by starttime;")
+    result = cursor.fetchall()
+
+    for row in result:
+      #  print row[0], row[1] ,row [2]
+        start=row[0]
+        end=row[1]
+        if ( end  > start ):
+            total = (end - start) /60
+            grandtotal+=total
+    hours = grandtotal / 60.0
+    days = hours / 24.0
+
+    cursor.execute("SELECT unix_timestamp(starttime),unix_timestamp(endtime),title FROM recorded where not (recgroup=(%s))  ORDER by starttime",("LiveTV"))
+    result_current = cursor.fetchall()
+    for row in result_current:
+        start=row[0]
+        end=row[1]
+        if ( end  > start ):
+            total = (end - start) /60
+            grandtotal_current+=total
+    hours_current = grandtotal_current / 60.0
+    days_current = hours_current / 24.0
+
+    print '<div id="header">'
+    print "<h3>Welcome to</h3>"
+    print "<h1>" , verLH , "</h1>"
+    print "<h3>on " , socket.gethostname() , "</h3>"
+    print "</br>"
+    print "<table>"
+    print "    <tr>"
+    print "	  <td>Currently there are " , len(result_current) , " recorded programs, with a viewing time of %.2f days or %.2f hours.</td>" %(days_current,hours_current)
+    print "    </tr>"
+    print "</table>"
+    print "</br> "
+
+    print "<table>"
+    print "	<tr>"
+    print "  		<td>Overall there have been " , len(result) , "shows recorded, with a viewing time of %.2f days or %.2f hours.</td>"%(days,hours)
+    print "	</tr>"
+    print "</table>"
+    print '</div>'
+    print "</br> </br> "
+#Top shows
+    print '<div id="content"> <p></p>'
+    print '<table class="sample">'
+    print "Top 20 Shows"
+    cursor.execute("select title,count(title),category as numtitle from oldrecorded where oldrecorded.recstatus = -3 group by title having (COUNT(title) > 0 ) order by (COUNT(title)) DESC  limit 20;" )
+    result = cursor.fetchall()
+    for row in result:
+        print "	<tr>"
+        print "		<td>",row[0],"</td>"
+        print "		<td>",row[2],"</td>"
+        print "		<td>",row[1],"</td>"
+        print "	</tr>"
+       # print "%40s %26s %10s" %(row[0],row[2],row[1])
+    print "</table>"
+    print "</div>"
+#Top categories
+
+    print '<div id="column">'
+    print '<table class="sample">'
+    print "Top 20 Categories"
+    cursor.execute("select category,count(category) as numtitle from oldrecorded where oldrecorded.recstatus = -3 group by category having (COUNT(category) > 0 ) order by (COUNT(category)) DESC  limit 20; " )
+    result = cursor.fetchall()
+    for row in result:
+        category = row[0]
+        if category == "":
+            category = "Unknown"
+        print "	<tr>"
+        print "		<td>",category,"</td>"
+        print "		<td>",row[1],"</td>"
+        print "	</tr>"
+        #print "%16s %16s" %(row[0],row[1])
+    print "</table>"
+    print "</div>"
+
+if __name__ == "__main__":
+    main(sys.argv[1:])
diff --git a/linhes/linhes-web/website/contents/docs.html b/linhes/linhes-web/website/contents/docs.html
new file mode 100644
index 0000000..dc3a936
--- /dev/null
+++ b/linhes/linhes-web/website/contents/docs.html
@@ -0,0 +1,58 @@
+<html>
+<head>
+<style type="text/css">@import "frame.css";</style>
+</head>
+
+<body>
+<div id="header">
+<h1>Documentation</h1>
+<br>
+</div>
+
+<h3>Package Management</h3>
+<div id="navcontainer">
+<ul id="navlist">
+        <li>pacman -Sy = to refresh pkg database</li>
+        <li>pacman -Ss $keyword = to search pkg database</li>
+        <li>pacman -Su = to update all install packages</li>
+        <li>pacman -S $pkg = to update one pkg</li>
+        <li>pacman -h = for a list of pacman operations</li>
+        <li>pacman -S --help = for a full list of options associated with the -S command</li>
+</ul>
+</div>
+<br>
+
+<h3>Starting and Stopping Services</h3>
+<div id="navcontainer">
+<ul id="navlist">
+    <li>sv {stop,start,restart} frontend = This will start/stop the entire X proccess that runs mythfrontend</li>
+    <li>sv {stop,start,restart} mysql</li>
+    <li>sv {stop,start,restart} mythbackend</li>
+    <li>sv {stop,start,restart} remotes</li>
+</ul>
+<br>
+</div>
+
+<h3>Other Notes</h3>
+<div id="navcontainer">
+<ul id="navlist">
+    <li>To keep a host from showing up in the network map, add it to:
+        /home/xymon/server/ext/ignoreclient.py
+    </li>
+    <li>To stop xymon from running a check on a function remove "func" from bb-hosts</li>
+    <li>remove  "func" from bb-hosts to stop hobbit from running a func check on it </li>
+    <li>If /tmp/nomfe is present then mythfrontend will not restart</li>
+    <li>Adding pkg names to /etc/pkgname.blacklist will stop MythVantage from auto installing a package</li>
+</div>
+<br>
+
+<h3>MythFrontend Menu Navigation</h3>
+<div id="navcontainer">
+<ul id="navlist">
+    <li> <A HREF="images/classic-menugraph.png">Classic Menu</A> </li>
+    <li> <A HREF="images/menu_diagram_color.png">Standard Menu</A> </li>
+    <li> <A HREF="images/dvr_menugraph.png">DVR Menu</A> </li>
+
+</body>
+</html>
+
diff --git a/linhes/linhes-web/website/contents/error-handler.html b/linhes/linhes-web/website/contents/error-handler.html
new file mode 100644
index 0000000..49e406f
--- /dev/null
+++ b/linhes/linhes-web/website/contents/error-handler.html
@@ -0,0 +1,9 @@
+<html>
+<head>
+<style type="text/css">@import "/frame.css";</style>
+</head>
+
+<body>
+Module or page not found
+</body>
+</html>
\ No newline at end of file
diff --git a/linhes/linhes-web/website/contents/error/call_log.html b/linhes/linhes-web/website/contents/error/call_log.html
new file mode 100644
index 0000000..d4d6333
--- /dev/null
+++ b/linhes/linhes-web/website/contents/error/call_log.html
@@ -0,0 +1,11 @@
+<html>
+<head>
+<style type="text/css">@import "/frame.css";</style>
+</head>
+
+<body>
+Call logging is not enabled, or no calls logs
+</br>
+To enable logging of incoming phone calls please visit the advanced section of the service menu
+</body>
+</html>
diff --git a/linhes/linhes-web/website/contents/error/hobbit.html b/linhes/linhes-web/website/contents/error/hobbit.html
new file mode 100644
index 0000000..4c65716
--- /dev/null
+++ b/linhes/linhes-web/website/contents/error/hobbit.html
@@ -0,0 +1,11 @@
+<html>
+<head>
+<style type="text/css">@import "/frame.css";</style>
+</head>
+
+<body>
+Xymon does not appear to be installed.
+</br>
+If Xymon was just installed/started it will take a few minutes before this page populates.
+</body>
+</html>
diff --git a/linhes/linhes-web/website/contents/error/mythbackend.html b/linhes/linhes-web/website/contents/error/mythbackend.html
new file mode 100644
index 0000000..9c3a362
--- /dev/null
+++ b/linhes/linhes-web/website/contents/error/mythbackend.html
@@ -0,0 +1,11 @@
+<html>
+<head>
+<style type="text/css">@import "/frame.css";</style>
+</head>
+
+<body>
+MythBackend status is currently unavailable.
+</br>
+
+</body>
+</html>
diff --git a/linhes/linhes-web/website/contents/error/mythexport.html b/linhes/linhes-web/website/contents/error/mythexport.html
new file mode 100644
index 0000000..f0d6b9d
--- /dev/null
+++ b/linhes/linhes-web/website/contents/error/mythexport.html
@@ -0,0 +1,22 @@
+<html>
+<head>
+<style type="text/css">@import "/frame.css";</style>
+</head>
+
+<body>
+<h2>MythExport does not appear to be installed</h2>
+</br>
+</br>
+<h4>Export MythTV recordings to portable media players.</h4>
+</br>
+<div id="navcontainer">
+    <ul id="navlist">
+To enable MythExport run these commands in a terminal:
+    </br>
+    <li>     pacman -Syyu mythexport </li>
+    <li>     add_service.sh mythexport </li>
+</ul>
+
+</body>
+</html>
+
diff --git a/linhes/linhes-web/website/contents/error/mythexpress.html b/linhes/linhes-web/website/contents/error/mythexpress.html
new file mode 100644
index 0000000..0525dfc
--- /dev/null
+++ b/linhes/linhes-web/website/contents/error/mythexpress.html
@@ -0,0 +1,20 @@
+<html>
+<head>
+<style type="text/css">@import "/frame.css";</style>
+</head>
+
+<body>
+<h2>MythExpress is not enabled or installed</h2>
+</br>
+</br>
+<h4>MythExpress is a browser-based interface to MythTV's HTTP streaming capability.</h4>
+</br>
+<div id="navcontainer">
+    <ul id="navlist">
+To enable MythExpress run these commands in a terminal:
+    </br>
+    <li>     pacman -Syyu mythexpress </li>
+    <li>     add_service.sh mythexpress </li>
+</ul>
+</body>
+</html>
diff --git a/linhes/linhes-web/website/contents/error/mythweb.html b/linhes/linhes-web/website/contents/error/mythweb.html
new file mode 100644
index 0000000..fe76a9a
--- /dev/null
+++ b/linhes/linhes-web/website/contents/error/mythweb.html
@@ -0,0 +1,16 @@
+<html>
+<head>
+<style type="text/css">@import "/frame.css";</style>
+</head>
+
+<body>
+MythWeb does not appear to be installed.
+</br>
+To install MythWeb either
+</br>
+1) Visit the MythVantage advanced screen to enable mythweb. </br>
+2) type "pacman -S mythweb-release-fixes" at the console.
+
+
+</body>
+</html>
diff --git a/linhes/linhes-web/website/contents/error/phpadmin.html b/linhes/linhes-web/website/contents/error/phpadmin.html
new file mode 100644
index 0000000..39b2f48
--- /dev/null
+++ b/linhes/linhes-web/website/contents/error/phpadmin.html
@@ -0,0 +1,26 @@
+<html>
+<head>
+<style type="text/css">@import "/frame.css";</style>
+</head>
+
+<body>
+phpMyAdmin is a tool written in PHP intended to handle the administration of MySQL over the Web. 
+</br>
+Currently it's not installed,but if you wish to install phpmyadmin, type the following at a command prompt
+</br>
+</br>
+
+pacman -S phpmyadmin
+
+</br>
+</br>
+PHP must be enabled for phpMyAdmin.
+</br>
+</br>
+</br>
+
+Please be carefull, phpMyAdmin is a powerful tool and can easily mess with your settings.
+		
+
+</body>
+</html>
diff --git a/linhes/linhes-web/website/contents/error/remyth.html b/linhes/linhes-web/website/contents/error/remyth.html
new file mode 100644
index 0000000..36661d2
--- /dev/null
+++ b/linhes/linhes-web/website/contents/error/remyth.html
@@ -0,0 +1,22 @@
+<html>
+<head>
+<style type="text/css">@import "/frame.css";</style>
+</head>
+
+<body>
+<h2>ReMyth is not enabled or installed</h2>
+</br>
+</br>
+<h4>ReMyth provides a nice remote for your MythTV Frontends.</h4>
+<h4>You will be able to view your recordings, as well as send actions to a frontend of your choosing.</h4>
+</br>
+
+<div id="navcontainer">
+    <ul id="navlist">
+To enable ReMyth run these commands in a terminal:
+    </br>
+    <li>     pacman -Syyu remyth </li>
+    <li>     add_service.sh remyth </li>
+</ul>
+</body>
+</html>
diff --git a/linhes/linhes-web/website/contents/error/status-404.html b/linhes/linhes-web/website/contents/error/status-404.html
new file mode 100644
index 0000000..49e406f
--- /dev/null
+++ b/linhes/linhes-web/website/contents/error/status-404.html
@@ -0,0 +1,9 @@
+<html>
+<head>
+<style type="text/css">@import "/frame.css";</style>
+</head>
+
+<body>
+Module or page not found
+</body>
+</html>
\ No newline at end of file
diff --git a/linhes/linhes-web/website/contents/error/zoneminder.html b/linhes/linhes-web/website/contents/error/zoneminder.html
new file mode 100644
index 0000000..25ecc9b
--- /dev/null
+++ b/linhes/linhes-web/website/contents/error/zoneminder.html
@@ -0,0 +1,20 @@
+<html>
+<head>
+<style type="text/css">@import "/frame.css";</style>
+</head>
+
+<body>
+Zoneminder is not enabled or installed.
+</br>
+</br>
+</br>
+<div id="navcontainer">
+    <ul id="navlist">
+
+To enable zoneminder run these commands in a terminal:
+    </br>
+    <li>     pacman -Syyu zoneminder </li>
+    <li>     add_service.sh zoneminder </li>
+</ul>
+</body>
+</html>
diff --git a/linhes/linhes-web/website/contents/exports.shtml b/linhes/linhes-web/website/contents/exports.shtml
new file mode 100755
index 0000000..12e079c
--- /dev/null
+++ b/linhes/linhes-web/website/contents/exports.shtml
@@ -0,0 +1,14 @@
+<html>
+    <head>
+        <style type="text/css">@import "/frame.css";</style>
+    </head>
+    <body>
+        <div id="header">
+            <h1>File Shares</h1>
+        </div>
+        <div id="navcontainer">
+            <!--#exec cmd="/data/srv/httpd/htdocs/list_exports.py" -->
+        </div>
+    </body>
+</html>
+
diff --git a/linhes/linhes-web/website/contents/favicon.ico b/linhes/linhes-web/website/contents/favicon.ico
new file mode 100644
index 0000000..6a99443
Binary files /dev/null and b/linhes/linhes-web/website/contents/favicon.ico differ
diff --git a/linhes/linhes-web/website/contents/fe_status.py b/linhes/linhes-web/website/contents/fe_status.py
new file mode 100644
index 0000000..c66d8f9
--- /dev/null
+++ b/linhes/linhes-web/website/contents/fe_status.py
@@ -0,0 +1,144 @@
+#!/usr/bin/python2
+
+import urllib2
+import xml.etree.ElementTree as ET
+import socket
+from  MythTV import Frontend
+import sys
+#socket.setdefaulttimeout(1)
+#socket.setdefaulttimeout(.00001)
+
+def msg(msg):
+    #if cmdargs.silent is False:
+    print "%s" %msg
+
+
+def parse_xml(frontend):
+    temp_dict = {'state':" --- ",
+                 'title':" --- ",
+                 'subtitle':" --- ",
+                 'location':" --- "}
+    url = "http://%s:6547/Frontend/GetStatus" %frontend
+    try:
+        request = urllib2.Request(url)
+        xml = urllib2.urlopen(request,timeout=1)
+        tree = ET.parse(xml)
+        root = tree.getroot()
+    except:
+        #msg("   Couldn't connect to %s" %frontend)
+        temp_dict['state'] = "offline"
+        return temp_dict
+
+    lst = root.find("State")
+    for item in lst:
+            try:
+                keyitem = (item.find('Key').text).strip()
+                valueitem  = (item.find('Value').text).strip()
+            except:
+                continue
+            if keyitem == "state":
+                temp_dict['state'] = valueitem
+
+            elif keyitem == "title":
+                temp_dict['title'] = valueitem
+
+            elif keyitem == "subtitle":
+                temp_dict['subtitle'] = valueitem
+
+            elif keyitem == "currentlocation":
+                temp_dict['location'] = valueitem
+
+    return temp_dict
+
+
+def mythfe_status(cursor,mythDB):
+    status_dict={}
+    try:
+        #frontends = mythDB.getFrontends() #use cursor instead so it doesn't test connection
+        cursor.execute("select distinct hostname from settings where hostname is not null;")
+        frontends=cursor.fetchall()
+    except:
+        #msg("Exceptions")
+        return
+
+    for i in frontends:
+        i=''.join(i)
+        try:
+            fe_hostname = socket.gethostbyaddr(i)[0]
+        except:
+            #print "DNS lookup failed for %s" %i
+            fe_hostname = i
+        try:
+            ip_addr = socket.gethostbyname(i)
+            fe_hostname = "%s (%s)" %(fe_hostname,ip_addr)
+            status_dict[fe_hostname] = parse_xml(ip_addr)
+        except:
+            fe_hostname = "%s" %fe_hostname
+            status_dict[fe_hostname] = parse_xml(fe_hostname)
+    return status_dict
+
+
+def print_html(status_dict):
+    print '<div> <p></p>'
+    print '</br> </br> '
+    print '<table class="calllog">'
+
+    #print "Current state of all online frontends"
+    #print '</br> </br> '
+
+    #print status_dict
+    row = '''
+<tr>
+    <td> %s  </td>
+    <td> %s  </td>
+    <td> %s  </td>
+    <td> %s  </td>
+    <td> %s  </td>
+</tr>
+'''
+    print row %("  MythFrontend Host  ","  State  ","  Title  ","  Subtitle  ","  MythFrontend Location  ")
+    for fe in status_dict.keys():
+        temp_dict = status_dict[fe]
+        print row %(fe,
+                    temp_dict['state'],
+                    temp_dict['title'],
+                    temp_dict['subtitle'],
+                    temp_dict['location'])
+
+    print "</table>"
+    print '</div>'
+
+#    print '''
+#    <div id="footer">
+#       </br>
+#       <p>Offline systems are not listed</p>
+#    </div>
+#'''
+
+
+def main():
+    try:
+        from MythTV import MythDB
+        mythDB = MythDB()
+        cursor = mythDB.cursor()
+        db_conn=True
+    except:
+        msg("Couldn't connect to MythTV database.")
+        db_conn=False
+
+    try:
+        from MythTV import MythBE
+        mythBE = MythBE()
+        be_conn=True
+    except:
+        msg("Couldn't connect to MythTV backend.")
+        be_conn=False
+
+    if (db_conn):
+        status_dict = mythfe_status(cursor,mythDB)
+        print_html(status_dict)
+
+
+
+if __name__ == "__main__":
+    main()
diff --git a/linhes/linhes-web/website/contents/fe_status.shtml b/linhes/linhes-web/website/contents/fe_status.shtml
new file mode 100644
index 0000000..8fda3df
--- /dev/null
+++ b/linhes/linhes-web/website/contents/fe_status.shtml
@@ -0,0 +1,18 @@
+<html>
+    <head>
+        <style type="text/css">@import "/frame.css";</style>
+        <meta http-equiv="cache-control" content="max-age=0" />
+        <meta http-equiv="cache-control" content="no-cache" />
+        <meta http-equiv="expires" content="0" />
+        <meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT" />
+        <meta http-equiv="pragma" content="no-cache" />
+        <meta http-equiv="refresh" content="30">
+    </head>
+
+    <body>
+        <div id="header">
+            <h1>MythFrontend Status</h1>
+        </div>
+        <!--#exec cmd="MYTHCONFDIR=/usr/share/mythtv /data/srv/httpd/htdocs/fe_status.py" -->
+    </body>
+</html>
diff --git a/linhes/linhes-web/website/contents/fe_status_load.shtml b/linhes/linhes-web/website/contents/fe_status_load.shtml
new file mode 100755
index 0000000..b83c13f
--- /dev/null
+++ b/linhes/linhes-web/website/contents/fe_status_load.shtml
@@ -0,0 +1,41 @@
+<html>
+    <head>
+        <style type="text/css">@import "/frame.css";</style>
+        <script src="/ajaxloader.min.js"></script>
+        <meta http-equiv="cache-control" content="max-age=0">
+        <meta http-equiv="cache-control" content="no-cache">
+        <meta http-equiv="expires" content="0">
+        <meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT">
+        <meta http-equiv="pragma" content="no-cache">
+        <meta http-equiv="refresh" content="0; url=/fe_status.shtml">
+        <script language="javascript">
+            function redirect() {
+            window.location.replace("/fe_status.shtml");}
+        </script>
+    </head>
+
+    <body onload="redirect()">
+        <div id="header">
+            <h1>MythFrontend Status</h1>
+        </div>
+        <br> <br> 
+        <h3>Querying MythFrontends...</h3>
+        <br>
+        <div id="container">
+            <div>
+                <canvas id="spinner"></canvas>
+            </div>
+        </div>
+        <script type="text/javascript">
+            var opts = {
+                size: 72,           // Width and height of the spinner
+                factor: 0.25,       // Factor of thickness, density, etc.
+                color: "#ebb81c",      // Color #rgb or #rrggbb
+                speed: 1.0,         // Number of turns per second
+                clockwise: true     // Direction of rotation
+            };
+            var ajaxLoader = new AjaxLoader("spinner", opts);
+            ajaxLoader.show();
+        </script>
+    </body>
+</html>
diff --git a/linhes/linhes-web/website/contents/frame.css b/linhes/linhes-web/website/contents/frame.css
new file mode 100644
index 0000000..0008aec
--- /dev/null
+++ b/linhes/linhes-web/website/contents/frame.css
@@ -0,0 +1,229 @@
+* /* Our "universal rule" */
+{
+    padding: 0px;
+    margin: 0px;
+    border: 0px;
+}
+body {
+/*    background: url("page_background.jpg") repeat-y #9FA9B3; */
+    background-color: #191c26;
+
+//background-color: #ebb81c;
+//background-image: -webkit-gradient(linear, left top, left bottom, from(#ebb81c), to(#0072bc)); /* Saf4+, Chrome */
+//background-image: -webkit-linear-gradient(top, #ebb81c, #0072bc); /* Chrome 10+, Saf5.1+, iOS 5+ */
+//background-image:    -moz-linear-gradient(top, #ebb81c, #0072bc) ; /* FF3.6 */
+//background-image:    -moz-linear-gradient(top, #0072bc,#ebb81c) ; /* FF3.6 */
+//background-image:     -ms-linear-gradient(top, #ebb81c, #0072bc); /* IE10 */
+//background-image:      -o-linear-gradient(top, #ebb81c, #0072bc); /* Opera 11.10+ */
+//background-image:         linear-gradient(top, #ebb81c, #0072bc);
+/filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#ebb81c', EndColorStr='#0072bc'); /* IE6-IE9 */
+
+
+//background-size: 1000px 1000px, 500px 500px;
+//-o-background-size: 1000px 10000px;
+//-moz-background-size: 1000px 10000px, 500px, 500px;
+//-webkit-background-size: 1000px 10000px, 500px 500px;
+
+    margin: 10px;
+    padding: 10px;
+    border: 10px;
+    min-width: 770px;
+    font-family: Arial, Tahoma, Helvetica, sans-serif;
+    font-size: 11px;
+    color: #FFFFFF;
+    text-align: center;
+    font-size: 18px;
+    font-family: tahoma, verdana, geneva, arial, helvetica, sans-serif;
+}
+
+#mainContainer {
+    clear: both;
+    width: 770px;
+    margin: 10px auto;
+    text-align: left; /* Since we used text-align: center in the body to be sure some older IE versions are going to center our design, we now align the text left */
+    display: block;
+}
+#header {
+    color: #fff;
+    text-align: center;
+}
+#content {
+    float: left; /* Our content is going to be left aligned */
+    width: 320px; /* And it's going to have a 320px width */
+    /*background: #D9D9D9;*/
+    margin-left:60px;
+}
+
+#column {
+    float: right; /* Our column is going to be right aligned */
+    width: 320px; /* And it's going to have a 320px width */
+    /*background: #8A8AE6;*/
+    margin-right:60px;
+}
+
+#resultbox {
+    width: 700px ;
+    margin-left: auto ;
+    margin-right: auto ;
+    border-width: .2em;
+    border-style: dotted;
+    border-color: #900;
+    text-align: left;
+    padding-left: 30;
+    padding-right: 30;
+    padding-top: 10;
+    padding-bottom: 10;
+
+}
+
+#netContainer {
+    clear: both;
+    width: 770px;
+    margin: 10px auto;
+    display: block;
+}
+
+img.center {
+    display: block;
+    padding-top: 10px;
+    padding-bottom: 10px;
+    margin-left: auto;
+    margin-right: auto;
+    max-width: 100%;
+}
+
+#footer {
+    clear: both; /* We have to clear our floats */
+    width: 770px; /* We need to set the width on the footer since it's outside the mainContainer, and therefor isn't controlled by it */
+    margin: 0px auto; /* We need to center the footer also */
+    color: gold;
+    text-align: center;
+    font-size: 10px;
+}
+
+#navlist {
+    clear: both;
+    width: 770px;
+    margin: 10px auto;
+    display: block;
+    text-align: left;
+    list-style-type: square;
+}
+
+#navlist li {
+
+}
+#navlist a:link
+{
+    color: #fff;
+#	background-color: #FDB14F;
+    text-decoration: underline;
+
+
+}
+
+#navlist a:visited
+{
+#	color: #FDB14F;
+    color: gold;
+    text-decoration: underline;
+}
+
+table.sample {
+    border-width: 4px;
+    border-spacing: 2px;
+    border-style: outset;
+    border-color: #808080;
+    border-collapse: separate;
+    width:300px;
+}
+
+table.sample td {
+    border-width: 1px;
+    padding: 1px;
+    border-style: inset;
+    border-color: #808080;
+    /*width:300px;*/
+    -moz-border-radius: ;
+}
+
+
+table.calllog {
+    border-width: 4px;
+    border-spacing: 2px;
+    border-style: outset;
+    border-color: #808080;
+    border-collapse: separate;
+    width:85%;
+    margin-left:auto;
+    margin-right:auto;
+    body {text-align:center;}
+}
+
+table.calllog td {
+    border-width: 1px;
+    padding: 1px;
+    border-style: inset;
+    border-color: #808080;
+    /*width:300px;*/
+    -moz-border-radius: ;
+}
+
+
+.n {
+    font-weight: normal;
+    text-align: left;
+    width: 250px;
+    color: white;
+}
+
+.s {
+    font-weight: normal;
+    text-align: left;
+    width: 150px;
+    color: white;
+    text-decoration: none;
+}
+
+.m {
+    font-weight: normal;
+    text-align: left;
+    width: 350px;
+    color: white;
+    text-decoration: none;
+}
+
+.t {
+    font-weight: normal;
+    text-align: left;
+    width: 350px;
+    color: white;
+    text-decoration: none;
+    visibility:hidden
+}
+
+
+a:link
+{
+    color: #fff;
+#	background-color: #FDB14F;
+    text-decoration: underline;
+
+#    	 margin-left:10px;
+
+}
+
+a:visited
+{
+#	color: #FDB14F;
+    color: gold;
+    text-decoration: underline;
+        margin-left:10px;
+}
+
+#submitbutton {
+    background-color: #010101;
+    font-size: 100%;
+    color: gold;
+    text-decoration: underline;margin-left:150px;
+    padding: 10px; font-weight: bold; }
diff --git a/linhes/linhes-web/website/contents/go.png b/linhes/linhes-web/website/contents/go.png
new file mode 100644
index 0000000..c70bf2a
Binary files /dev/null and b/linhes/linhes-web/website/contents/go.png differ
diff --git a/linhes/linhes-web/website/contents/header.html b/linhes/linhes-web/website/contents/header.html
new file mode 100644
index 0000000..831a9d5
--- /dev/null
+++ b/linhes/linhes-web/website/contents/header.html
@@ -0,0 +1,97 @@
+<html>
+<!--<style type="text/css">@import "mv.css";</style>-->
+<link rel="stylesheet" type="text/css" href="skeleton.css" />
+<head>
+
+<script type="text/javascript">
+function r()
+{
+    current_hostname=parent.location.hostname
+    top.frames["content"].location.href = ( "http://" + current_hostname + ":6544" ) ;
+}
+
+function express()
+{
+    current_hostname=parent.location.hostname
+    top.frames["content"].location.href = ( "http://" + current_hostname + ":6565" ) ;
+}
+
+function remyth()
+{
+    current_hostname=parent.location.hostname
+    top.frames["content"].location.href = ( "http://" + current_hostname + ":8088" ) ;
+}
+
+function beStatus()
+{
+    document.getElementById('modify-me').href = "http://" + window.location.hostname + ":6544";
+}
+
+</script>
+</head>
+
+<BODY BGCOLOR=#ebb81c onload="beStatus()">
+
+<div id='header'></div>
+<img id='header_img' src="linhes_header.png" alt="LinHES" title="LinHES"/>
+
+<base target="content" />
+<ul id="nav">
+<li><a href="home.shtml" TARGET="content" id="current">Home</a></li>
+
+<li><a href="mythweb/">MythWeb &#187;</a>
+    <ul>
+        <li><a href="mythweb/tv/list"  >Listings</a></li>
+        <li><a href="mythweb/tv/recorded"  >Recorded</a></li>
+        <li><a href="mythweb/tv/schedules"  >Schedules</a></li>
+        <li><a href="mythweb/tv/searches"  >Searches</a></li>
+        <li><a href="mythweb/status"  >Status</a></li>
+        <li><a href="mythweb/tv/upcoming"  >Upcoming</a></li>
+        <li><a href="mythweb/music"  >Music</a></li>
+        <li><a href="mythweb/video"  >Video</a></li>
+    </ul>
+</li>
+
+<li><a href="fe_status_load.shtml">MythFrontend Status</a></li>
+
+<li><a href="" id="modify-me" target="_blank">MythTV WebFrontend</a></li>
+
+<li><a href="xymon/">Health & Maintenance</a></li>
+
+<li><a href="/logs/" >System &#187;</a>
+    <ul>
+    <!--    <li><a href="/xymon"  >Health</a></li>-->
+        <li><a href="/logs/"  >Logs</a></li>
+        <li><a href="/exports.shtml"  >File Shares</a></li>
+        <li><a href="/cardmap.shtml"  >Tuners</a></li>
+        <li><a href="/shell/"  >Terminal</a></li>
+    </ul>
+</li>
+
+<li><a href="calllog.shtml">Utilities &#187;</a>
+    <ul>
+<!--        <li><a onClick=r() >MythBackend Status</a></li> -->
+        <li><a href="calllog.shtml">Call Log</a></li>
+        <li><a href="mythexport/setup.cgi">MythExport</a></li>
+        <li><a href="mythexpress.html" target="_blank">MythExpress</a></li>
+<!--    <li><a href="remyth.html" >ReMyth</a></li> -->
+        <li><a href="zm">ZoneMinder</a></li>
+    </ul>
+</li>
+
+<li><a href="docs.html"  >Documentation</a></li>
+
+<li><a href="links.html"  >Links &#187;</a>
+    <ul>
+        <li><a href="http://linhes.org/wiki"  >LinHES Wiki</a></li>
+        <li><a href="http://forums.linhes.org"  >LinHES Forums</a></li>
+        <li><a href="http://linhes.org/projects/linhes/issues"  >LinHES Bug Tracker </a></li>
+        <li><a href="http://linhes.org/projects/linhes/wiki/Official_and_3rd_party_add-ons" >LinHES Add-Ons</a></li>
+        <li><a href="http://www.mythtv.org"  >MythTV</a></li>
+        <li><a href="http://smolt.mythtv.org"  >MythTV Smolt Server</a></li>
+        <li><a href="http://www.schedulesdirect.org"  >Schedules Direct</a></li>
+    </ul>
+</li>
+
+</body>
+</html>
diff --git a/linhes/linhes-web/website/contents/home.shtml b/linhes/linhes-web/website/contents/home.shtml
new file mode 100644
index 0000000..a2c817e
--- /dev/null
+++ b/linhes/linhes-web/website/contents/home.shtml
@@ -0,0 +1,17 @@
+<html>
+    <head>
+        <style type="text/css">@import "frame.css";</style>
+    </head>
+    <body>
+        <div id="mainContainer">
+            <!--#exec cmd="/data/srv/httpd/htdocs/count.py" -->
+        </div>
+        <div id="netContainer">
+            <img src="/xymon/gifs/network.png" class="center">
+        </div>
+        <div id="footer">
+            <p>Thank you for choosing LinHES</p>
+        </div>
+    </body>
+</html>
+
diff --git a/linhes/linhes-web/website/contents/images/classic-menugraph.png b/linhes/linhes-web/website/contents/images/classic-menugraph.png
new file mode 100644
index 0000000..bedbd93
Binary files /dev/null and b/linhes/linhes-web/website/contents/images/classic-menugraph.png differ
diff --git a/linhes/linhes-web/website/contents/images/dvr_menugraph.png b/linhes/linhes-web/website/contents/images/dvr_menugraph.png
new file mode 100644
index 0000000..712ab36
Binary files /dev/null and b/linhes/linhes-web/website/contents/images/dvr_menugraph.png differ
diff --git a/linhes/linhes-web/website/contents/images/menu_diagram_color.png b/linhes/linhes-web/website/contents/images/menu_diagram_color.png
new file mode 100644
index 0000000..d364d94
Binary files /dev/null and b/linhes/linhes-web/website/contents/images/menu_diagram_color.png differ
diff --git a/linhes/linhes-web/website/contents/index.html b/linhes/linhes-web/website/contents/index.html
new file mode 100644
index 0000000..1168c4a
--- /dev/null
+++ b/linhes/linhes-web/website/contents/index.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
+<html>
+	<head>
+        <link rel="shortcut icon" href="/favicon.ico">
+        <title>LinHES: The Linux Home Entertainment System</title>
+	</head>
+	<frameset cols="205, 100%" frameborder="no" border="0" bordercolor="#000000">
+	<frame src="header.html" scrolling=no  name="menuframe" />
+		      <frame src="home.shtml" name="content" />
+		      <noframes>
+			      <body>
+				      There is no frame support on your browser.
+			      </body>
+		      </noframes>
+	      </frameset>
+      </html>
diff --git a/linhes/linhes-web/website/contents/linhes_header.png b/linhes/linhes-web/website/contents/linhes_header.png
new file mode 100644
index 0000000..fd50187
Binary files /dev/null and b/linhes/linhes-web/website/contents/linhes_header.png differ
diff --git a/linhes/linhes-web/website/contents/links.html b/linhes/linhes-web/website/contents/links.html
new file mode 100644
index 0000000..65b5231
--- /dev/null
+++ b/linhes/linhes-web/website/contents/links.html
@@ -0,0 +1,27 @@
+<html>
+<head>
+<style type="text/css">@import "frame.css";</style>
+</head>
+
+<body>
+<h1>Links</h1>
+</br>
+
+<div id="navcontainer">
+<ul id="navlist">
+	<!--        <li><a href="/mvpmc.shtml"  >Media MVP setup</a> (dhcp server must be enabled) </li> -->
+        <li><a href="http://linhes.org/wiki"  >LinHES Wiki</a></li>
+        <li><a href="http://forums.linhes.org"  >LinHES Forums</a></li>
+        <li><a href="http://linhes.org/projects/linhes/issues"  >LinHES Bug Tracker </a></li>
+        <li><a href="http://linhes.org/projects/linhes/wiki/Official_and_3rd_party_add-ons" >LinHES Add-Ons</a></li>
+        <li><a href="http://www.mythtv.org"  >MythTV</a></li>
+        <li><a href="http://smolt.mythtv.org"  >MythTV Smolt Server</a></li>
+        <li><a href="http://www.schedulesdirect.org"  >Schedules Direct</a></li>
+
+
+
+</ul>
+</div>
+
+</body>
+</html>
diff --git a/linhes/linhes-web/website/contents/list_cardmap.py b/linhes/linhes-web/website/contents/list_cardmap.py
new file mode 100755
index 0000000..c77ed83
--- /dev/null
+++ b/linhes/linhes-web/website/contents/list_cardmap.py
@@ -0,0 +1,156 @@
+#!/usr/bin/python2
+import subprocess
+import socket,sys
+import urllib2
+from MythTV import MythBE,MythDB,MythLog
+
+def find_slave_hosts():
+    slave_hosts=[]
+    try:
+        be=MythBE()
+        db = MythDB()
+        cursor = db.cursor()
+    except:
+        return slave_hosts
+
+    try:
+        cmd="select hostname from settings where data='Slave_backend';"
+        cursor.execute(cmd)
+        results=cursor.fetchall()
+        for i in results:
+            slave_hosts.append(i[0])
+    except:
+        return slave_hosts
+    return slave_hosts
+
+def read_local_tuner():
+    tuner_list = []
+    exportfile = '/etc/udev/mv-persistent-video.description'
+    try:
+        f = open(exportfile,"r")
+        for line in f.readlines():
+            if line.startswith("#"):
+                continue
+            item = line.split(":")
+            if len(item) <= 1 :
+                continue
+            tuner_list.append(item)
+    except :
+        tuner_list.append(["notfound","notfound","notfound"])
+    return tuner_list
+
+def parse_remote_tuners(the_page):
+    tuner_list=[]
+    the_page = the_page.split("\n")
+    try:
+        for line in the_page:
+            if line.startswith("#"):
+                continue
+            item = line.split(":")
+            if len(item) <= 1 :
+                continue
+            tuner_list.append(item)
+    except :
+        tuner_list.append(["notfound","notfound","notfound"])
+    return tuner_list
+
+
+def remote_tuners(slave_host):
+    default_timeout = 3
+    socket.setdefaulttimeout(default_timeout)
+    slaveurl="http://%s:1337/cardlist.cgi" %slave_host
+    req = urllib2.Request(slaveurl)
+    response = urllib2.urlopen(req)
+    the_page = response.read()
+    #the_page="abc\nadef\na"
+    if the_page :
+        tuner_list = parse_remote_tuners(the_page)
+        print "</br>"
+        for statictuner in tuner_list:
+            if statictuner[1].find("notfound") > -1 :
+                print "Couldn't open tuner map"
+                print "</br>"
+            else:
+                print "<li> %s&nbsp;&nbsp;&nbsp%s" %(statictuner[1] ,statictuner[0])
+                print "</br>"
+                print "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;static device node: %s"  %statictuner[2]
+                print "</br>"
+                print "</br>"
+    else:
+        print "<li> no tuners found &nbsp;&nbsp;&nbsp"
+
+    return
+
+
+
+mbelist = read_local_tuner()
+slave_hosts = find_slave_hosts()
+
+#--------------MBE-------------
+hostname = socket.gethostname()
+print "</br>"
+print "<h2>"
+print "__________ %s __________" %(hostname)
+print "</h2>"
+print "</br>"
+print '''
+<div id="navcontainer">
+<ul id="navlist">
+'''
+
+for statictuner in mbelist:
+    hdhr_url = None
+    if statictuner[1].find("notfound") > -1 :
+        print "Couldn't open tuner map"
+        print "</br>"
+    else:
+        ceton_url = None
+        hdhr_url = None
+        if statictuner[0] == "hdhr":
+            hdhr_url = statictuner[1].split("-")[-1]
+        elif statictuner[0] == "infinitv":
+            ceton_port = statictuner[3].strip()
+            #Services/1/Status.html
+            #print statictuner
+            ceton_tuner=statictuner[2].strip()[-1]
+            ceton_tuner = int(ceton_tuner) + 1
+            ceton_url = "http://%s:%s/Services/%s/Status.html" %(hostname,
+                                                                 ceton_port,
+                                                                 ceton_tuner)
+
+        #print "<li> %s&nbsp;&nbsp;&nbsp%s" %(statictuner[1] ,statictuner[0])
+        print "<li> %s&nbsp;&nbsp;&nbsp" %(statictuner[1])
+        print "</br>"
+        print "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;static device node: %s"  %statictuner[2]
+
+        if hdhr_url:
+            print "</br>"
+            print '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;device webpage: <a href="http://%s">http://%s</a> '  %(hdhr_url.strip(),hdhr_url.strip())
+        if ceton_url:
+            print "</br>"
+            print '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;device webpage: <a href="%s">%s</a> '  %(ceton_url.strip(),ceton_url.strip())
+        print "</br>"
+        print "</br>"
+
+print '''</ul> </div>'''
+
+#---------Slave tuners
+for i in slave_hosts:
+    print "<h2>"
+    print "__________ %s __________" %(i)
+    print "</h2>"
+    print "</br>"
+    print '''
+    <div id="navcontainer">
+    <ul id="navlist" '''
+    #remote_tuners(i)
+    try:
+        remote_tuners(i)
+        pass
+    except:
+        print "</br>"
+        print "<li> Problem reading list from %s" %i
+        pass
+    print ''' </ul> </div>'''
+
+
diff --git a/linhes/linhes-web/website/contents/list_exports.py b/linhes/linhes-web/website/contents/list_exports.py
new file mode 100755
index 0000000..79c2c38
--- /dev/null
+++ b/linhes/linhes-web/website/contents/list_exports.py
@@ -0,0 +1,85 @@
+#!/usr/bin/python2
+import subprocess
+
+def  nfs_export_list():
+    nfslist = []
+    exportfile = "/etc/exports"
+    proc = subprocess.Popen(["showmount", "-a"] , stdout=subprocess.PIPE,stderr=subprocess.PIPE)
+    stdout,stderr = proc.communicate()
+    rc = proc.returncode
+    if rc == 0:
+        try:
+            f = open(exportfile,"r")
+            for line in f.readlines():
+                if line.startswith("#"):
+                    continue
+                item = line.split()
+                if len(item) <= 1 :
+                    continue
+                nfslist.append(item)
+        except :
+            pass
+    else:
+        nfslist.append(["NFS server  is not running",'NFS server is not running'])
+    return nfslist
+
+
+def smb_share_list():
+    smblist=[]
+
+    proc = subprocess.Popen(["smbclient", "-L", "\\localhost" , "-N"], stdout=subprocess.PIPE,stderr=subprocess.PIPE)
+    stdout,stderr = proc.communicate()
+    outstuff = stderr.split("\n")
+    for line in outstuff:
+        try:
+            heading1 = line.split()[0]
+        except:
+            continue
+        #print heading1
+        #print heading1.find("Domain")
+        if heading1.find("Domain") > -1  :
+            #smblist.append('')
+            smblist.append(heading1)
+            break
+
+    outstuff = stdout.split("\n")
+    for line in outstuff:
+        try:
+            heading1,heading2 = line.split()
+        except:
+            continue
+        if heading1 == "Server" and heading2 == "Comment":
+            break
+        smblist.append(line)
+
+    return smblist
+
+
+nfslist = nfs_export_list()
+smblist = smb_share_list()
+
+
+print "</br>"
+print "<h2>__________ NFS Shares __________</h2>"
+print "</br>"
+print '<ul id="navlist">'
+for sharename in nfslist:
+    if sharename[1].find("noaccess") > -1 :
+        print "<h3>%s \t no access</h3>" %sharename[0]
+    else:
+        print "<li>%s</li>" %sharename[0]
+
+print '</ul>'
+
+print "</br>"
+print "<h2>__________ SMB Shares __________</h2>"
+print "</br>"
+print '<ul id="navlist">'
+if len(smblist)  == 0:
+    print "<h3>Samba is not running or no shares are listed</h3>"
+    print "</br>"
+else:
+    for sharename in smblist:
+        print "<li>%s</li>" %(sharename.split()[0])
+
+print '</ul>'
diff --git a/linhes/linhes-web/website/contents/mv.css b/linhes/linhes-web/website/contents/mv.css
new file mode 100644
index 0000000..54e70b0
--- /dev/null
+++ b/linhes/linhes-web/website/contents/mv.css
@@ -0,0 +1,100 @@
+#header {
+       // width: 820px;
+        position: relative;
+        height: 182px;
+        #background: #000011 url(linhes_header.png) no-repeat center top;
+        background: #ebb81c url(linhes_header.png) no-repeat center bottom ;
+        padding: 0;
+	padding-top: 1px;
+        font-size: 14px;
+        color: #FFF;
+}
+
+#header h1#logo-text {
+      //  position: absolute;
+        margin: 0; padding: 0;
+        font: bolder 3.3em 'Trebuchet MS', Arial, Sans-serif;
+        letter-spacing: -2px;
+        color: #FFFFFF;
+        text-transform: none;
+	text-align: center;
+        /* change the values of top and left to adjust the position of the logo*/
+        top: 0px; left: 150px;
+}
+
+#content
+{
+        color: #FFFFFF;
+        text-transform: none;
+	text-align: center;
+}
+
+#navcontainer
+{
+	width: 100%;
+	float: left;
+	background-color:#0072bc;
+}
+
+#navcontainer ul { padding: 0; }
+#navcontainer ul li { display: inline; }
+
+#navcontainer ul
+{
+	margin: 0;
+	padding: 0 0 0 7%;
+	color: #FFFFFF;
+	font-family: tahoma, verdana, geneva, arial, helvetica, sans-serif;
+	//font-size: .65em;
+	letter-spacing: 2px;
+	font-weight: bold;
+        float: right;
+        //background:#ebb81c;
+	background-color: #0072bc;
+
+}
+
+
+#navcontainer ul li a
+{
+	padding: 0.2em 12px;//	background-color: #ebb81c;
+	background-color: #0072bc;
+	color: #FFFFFF;
+	text-decoration: none;
+	float: left;
+	//border-right: 1px solid #94B473;
+
+	border-top-right-radius: 15px;
+	-moz-border-top-right-radius: 15px;
+
+	border-top-left-radius: 15px;
+	-moz-border-top-left-radius: 15px;
+}
+
+
+#navcontainer a:active
+{
+	background-color: #ECECEC;
+        color: #333;
+	border-top-right-radius: 25px;
+	-moz-border-top-right-radius: 25px;
+	border-top-left-radius: 25px;
+	-moz-border-top-left-radius: 22px;
+}
+
+#navcontainer ul li a:hover
+{
+	background-color: #ECECEC;
+        color: #333;
+}
+
+#navlist li a:hover, #navlist li a:active li:active
+{
+	color: #FFFFFF;
+	text-decoration: none;
+	background:black;
+	text-align: right;
+        font-family: tahoma, verdana, geneva, arial, helvetica, sans-serif;
+}
+
+
diff --git a/linhes/linhes-web/website/contents/mvp_process.py b/linhes/linhes-web/website/contents/mvp_process.py
new file mode 100644
index 0000000..b01ed8b
--- /dev/null
+++ b/linhes/linhes-web/website/contents/mvp_process.py
@@ -0,0 +1,195 @@
+#!/usr/bin/python
+import sys
+import cgi
+import os
+import socket
+import time
+import shutil
+try:
+    import cgitb
+    cgitb.enable()
+except ImportError:
+    sys.stderr = sys.stdout
+def cgiprint(inline=''):
+    sys.stdout.write(inline)
+    sys.stdout.write('\r\n')
+    sys.stdout.flush()
+contentheader = 'Content-Type: text/html'
+
+thepage = '''<html><head>
+<title>%s</title>
+</head><body>
+%s
+</body></html>
+'''
+h1 = '<h1>%s</h1>'
+
+def getform(theform, valuelist, notpresent='', nolist=False):
+    """
+    This function, given a CGI form as a
+    FieldStorage instance, extracts the
+    data from it, based on valuelist
+    passed in. Any non-present values are
+    set to '' - although this can be
+    changed. (e.g. to return None so you
+    can test for missing keywords - where
+    '' is a valid answer but to have the
+    field missing isn't.) It also takes a
+    keyword argument 'nolist'. If this is
+    True list values only return their
+    first value.
+    """
+    data = {}
+    for field in valuelist:
+
+
+        if not theform.has_key(field):
+        #  if the field is not present (or was empty)
+            data[field] = notpresent
+        else:
+        # the field is present
+            data[field] = theform.getlist(field)
+
+#	    print type(theform[field])
+    return data
+
+def getall(theform, nolist=False):
+    """
+    Passed a form (cgi.FieldStorage
+    instance) return *all* the values.
+    This doesn't take into account
+    multipart form data (file uploads).
+    It also takes a keyword argument
+    'nolist'. If this is True list values
+    only return their first value.
+    """
+    data = {}
+    for field in theform.keys():
+    # we can't just iterate over it, but must use the keys() method
+        if type(theform[field]) ==  type([]):
+            if not nolist:
+                data[field] = theform.getlist(field)
+
+            else:
+                data[field] = theform.getfirst(field)
+        else:
+            data[field] = theform[field].value
+
+
+    return data
+
+def isblank(indict):
+    """
+    Passed an indict of values it checks
+    if any of the values are set. Returns
+    True if the indict is empty, else
+    returns False. I use it on the a form
+    processed with getform to tell if my
+    CGI has been activated without any
+    form values.
+    """
+    for key in indict.keys():
+        if indict[key]:
+            return False
+    return True
+
+
+def update_mvp_list(maclist):
+    outfile = open("/etc/dnsmasq.mvpmc.conf","w")
+    mvpline="dhcp-boot=net:mvp,dongle.bin"
+    mvpmacline='dhcp-host=net:mvp,%s'
+    results="The following media mvp devices have been added:"
+    results+='</br>'
+    havemvp = "false"
+    #print maclist
+    for i in range(len(maclist)):
+        if maclist[i] != '':
+#             print mvpmacline % maclist[i]
+    	     outfile.write(mvpmacline % maclist[i] + '\n' )
+             havemvp="true"
+             results+=maclist[i]
+             results+='</br>'
+    if havemvp == "true":
+#        print mvpline
+    	outfile.write(mvpline + '\n' )
+        outfile.flush
+    	outfile.close
+        #time.sleep(5)
+
+    else:
+        outfile.close
+    return  results
+
+
+mainpage = '''
+ <html><head>
+ <style type="text/css">@import "/frame.css";</style>
+ <!--<meta http-equiv="refresh" content="6">-->
+ <title>Receiving a Form</title>
+ </head><body>%s</body></html>'''
+
+error = '''
+
+    <h2>Removed all media mvp devices</h2>'''
+
+result = '''
+    <h1>%s</h1>
+'''
+possible_parameters = ['activemvp', 'othermac','hiddenparam']
+
+if __name__ == '__main__':
+    cgiprint(contentheader)   # content header
+    cgiprint()                # finish headers with blank line
+
+    theform = cgi.FieldStorage()
+    #print theform
+    formdict = getform(theform, possible_parameters)
+    #print possible_parameters
+    #print formdict
+    oldurl = '/mvpmc.shtml'
+    if isblank(formdict):
+        body = error
+        all_active=[]
+    else:
+        all_active=[]
+        activemac_checkbox = formdict['activemvp']
+        for i in range(len(activemac_checkbox)):
+             active_string=activemac_checkbox[i]
+             active_string=active_string.strip()
+             all_active.append(active_string)
+        body = result % ("MVP mac address")
+
+
+
+    print mainpage % body
+ #   mylogfile=update_mvp_list(all_active)
+
+
+    box='''
+     <div style="border: 1px solid #aaa; width:600px; height:500px; overflow:auto; color:#FFF;text-align:left;">
+         <code id="box" style="display: block; height: 500px; width: 600px; overflow: auto;">
+    '''
+
+    endbox='''
+         </code>
+     </div>
+    '''
+    javascript='''
+    <script type="text/javascript">
+        var objDiv = document.getElementById("box");
+        objDiv.scrollTop = objDiv.scrollHeight;
+    </script>
+     '''
+    if all_active != []:
+        mylogfile=update_mvp_list(all_active)
+        command="sudo /sbin/sv stop dnsmasq"
+        os.system(command)
+        command="sudo /sbin/sv start dnsmasq"
+        os.system(command)
+        print box
+        print mylogfile
+        print endbox
+    print '<a href=',  oldurl,     '  > Back </a> '
+    #print oldurl
+    print javascript
+
diff --git a/linhes/linhes-web/website/contents/mvp_select.py b/linhes/linhes-web/website/contents/mvp_select.py
new file mode 100644
index 0000000..8283d68
--- /dev/null
+++ b/linhes/linhes-web/website/contents/mvp_select.py
@@ -0,0 +1,146 @@
+#!/usr/bin/python
+#
+
+import urllib2
+import string
+import sys
+import time
+import datetime
+import socket
+
+def read_accepted():
+
+    global dhcp_accepted
+    dhcp_accepted = []
+    try:
+        infile = open('/tmp/dhcp.leases', 'r')
+    except(IOError), e:
+        print "couldn't open accepted"
+    else:
+        filelist = infile.readlines()
+        infile.close()
+        for item in filelist:
+            item=item.strip()
+            macaddress=item.split(" ")[1]
+            if macaddress not in dhcp_accepted:
+                    dhcp_accepted.append(macaddress)
+                    #print macaddress
+
+def read_offered():
+    global dhcp_offered
+    dhcp_offered = []
+    try:
+        today = datetime.date.today()
+
+        host = socket.gethostname()
+        filename='/var/log/'
+        filename+=str(today)
+        filename+='/'
+        filename+=host
+        filename+='/dnsmasq'
+        infile = open(filename, 'r')
+    except(IOError), e:
+        print "couldn't open offered"
+    else:
+        filelist = infile.readlines()
+        infile.close()
+        for item in filelist:
+            item=item.strip()
+            if item.find("DHCPOFFER") != -1 :
+                macaddress=item.rpartition(" ")[2]
+                if macaddress not in dhcp_offered:
+                    dhcp_offered.append(macaddress)
+                    #print macaddress
+
+
+
+def read_current():
+    global dhcp_current
+    dhcp_current = []
+    try:
+        infile = open('/etc/dnsmasq.mvpmc.conf', 'r')
+    except(IOError), e:
+        print "couldn't open current"
+    else:
+        filelist = infile.readlines()
+        infile.close()
+        for item in filelist:
+            item=item.strip()
+            if item.find("dhcp-host") != -1 :
+                macaddress=item.partition(",")[2]
+
+                if macaddress not in dhcp_current :
+                    dhcp_current.append(macaddress)
+                   # print macaddress
+
+
+
+
+
+
+
+def make_html():
+    global dhcp_accepted
+    global dhcp_offered
+    buttonform_top='''
+        <div class="content" style="solid #aaa; width:500px; height:300px; overflow:auto; color:#FFF;text-align:left;">
+         <form action="/mvp_process.py" method="get">
+         '''
+
+
+    buttonform_bottom='''
+            Mac Address:
+            <input type="text" name="activemvp">
+
+            </br>
+            <input id="submitbutton" type="submit" />
+        </form>
+        </div>
+        '''
+    checkboxline = '''
+     <input type="checkbox"  name="activemvp" value="%s"  %s  />  %s <br />
+    '''
+    print '<br />'
+    da = set(dhcp_accepted)
+    dof = set(dhcp_offered)
+    dc = set(dhcp_current)
+    possible_mac= dof  -dc
+    #possible_mac= dof  -da - dc
+
+    print buttonform_top
+    for mac in dhcp_current:
+        print checkboxline % (mac ,' checked="yes"' , mac)
+    for mac in possible_mac:
+        print checkboxline % (mac , " " ,mac)
+    print buttonform_bottom
+
+
+#-------------------
+global dhcp_accepted
+global dhcp_offered
+global dhcp_current
+
+
+
+
+read_offered()
+#print "--"
+#print '</br>'
+read_accepted()
+#print "--"
+#print '</br>'
+read_current()
+#print "--"
+#print '</br>'
+
+
+
+#possible_mac= (dof - da)
+#possible_mac = dof
+#print "should be unchecked:"
+#print possible_mac
+
+
+make_html()
+
+
diff --git a/linhes/linhes-web/website/contents/mvpmc.shtml b/linhes/linhes-web/website/contents/mvpmc.shtml
new file mode 100644
index 0000000..edc27d4
--- /dev/null
+++ b/linhes/linhes-web/website/contents/mvpmc.shtml
@@ -0,0 +1,21 @@
+<html>
+<head>
+<style type="text/css">@import "/frame.css";</style>
+</head>
+<h1>Media MVP page</h1>
+<body>
+<div id="mainContainer">
+<!--		<div id="header"><p></p></div>
+		<div id="content">
+		<p></p>-->
+
+	<!--#exec cmd="/data/srv/httpd/htdocs/mvp_select.py" -->
+
+
+</br>
+</br>
+<div id="footer"><p>Thank you for choosing MythVantage</p></div>
+
+</body>
+</html>
+
diff --git a/linhes/linhes-web/website/contents/mythweb.html b/linhes/linhes-web/website/contents/mythweb.html
new file mode 100644
index 0000000..fe76a9a
--- /dev/null
+++ b/linhes/linhes-web/website/contents/mythweb.html
@@ -0,0 +1,16 @@
+<html>
+<head>
+<style type="text/css">@import "/frame.css";</style>
+</head>
+
+<body>
+MythWeb does not appear to be installed.
+</br>
+To install MythWeb either
+</br>
+1) Visit the MythVantage advanced screen to enable mythweb. </br>
+2) type "pacman -S mythweb-release-fixes" at the console.
+
+
+</body>
+</html>
diff --git a/linhes/linhes-web/website/contents/page_background.jpg b/linhes/linhes-web/website/contents/page_background.jpg
new file mode 100644
index 0000000..4819c9a
Binary files /dev/null and b/linhes/linhes-web/website/contents/page_background.jpg differ
diff --git a/linhes/linhes-web/website/contents/process.py b/linhes/linhes-web/website/contents/process.py
new file mode 100755
index 0000000..60714ee
--- /dev/null
+++ b/linhes/linhes-web/website/contents/process.py
@@ -0,0 +1,447 @@
+#!/usr/bin/python2
+import sys
+import cgi
+import os
+import socket
+import time
+import StringIO
+
+try:
+    import cgitb
+    cgitb.enable()
+except ImportError:
+    sys.stderr = sys.stdout
+def cgiprint(inline=''):
+    sys.stdout.write(inline)
+    sys.stdout.write('\r\n')
+    sys.stdout.flush()
+contentheader = 'Content-Type: text/html'
+
+def getform(theform, valuelist, notpresent='', nolist=False):
+    """
+    This function, given a CGI form as a
+    FieldStorage instance, extracts the
+    data from it, based on valuelist
+    passed in. Any non-present values are
+    set to '' - although this can be
+    changed. (e.g. to return None so you
+    can test for missing keywords - where
+    '' is a valid answer but to have the
+    field missing isn't.) It also takes a
+    keyword argument 'nolist'. If this is
+    True list values only return their
+    first value.
+    """
+    data = {}
+    for field in valuelist:
+        if not theform.has_key(field):
+        #  if the field is not present (or was empty)
+            data[field] = notpresent
+        else:
+        # the field is present
+            #print type(theform[field])
+            if  type(theform[field]) != type([]):
+            # is it a list or a single item
+                #print type(theform[field])
+                data[field] = theform[field].value
+            else:
+                if not nolist:
+                # do we want a list ?
+                    data[field] = theform.getlist(field)
+                else:
+                    data[field] = theform.getfirst(field)
+                    # just fetch the first item
+    return data
+
+def getall(theform, nolist=False):
+    """
+    Passed a form (cgi.FieldStorage
+    instance) return *all* the values.
+    This doesn't take into account
+    multipart form data (file uploads).
+    It also takes a keyword argument
+    'nolist'. If this is True list values
+    only return their first value.
+    """
+    data = {}
+    for field in theform.keys():
+    # we can't just iterate over it, but must use the keys() method
+        if type(theform[field]) ==  type([]):
+            if not nolist:
+                data[field] = theform.getlist(field)
+            else:
+                data[field] = theform.getfirst(field)
+        else:
+            data[field] = theform[field].value
+    return data
+
+def isblank(indict):
+    """
+    Passed an indict of values it checks
+    if any of the values are set. Returns
+    True if the indict is empty, else
+    returns False. I use it on the a form
+    processed with getform to tell if my
+    CGI has been activated without any
+    form values.
+    """
+    for key in indict.keys():
+        if indict[key]:
+            return False
+    return True
+
+def go_backup(myhost):
+    myhostname = socket.gethostname()
+    results="Nothing happened"
+    command= "sudo /usr/LH/bin/lh_system_backup_job"
+    #print command
+
+    command2="sleep 1; sudo -u nobody /home/xymon/server/ext/hbnotes.py"
+    results=os.popen(command,'r')
+    os.popen(command2,'r')
+
+    return  results
+
+def go_download_backup(dl_file):
+    # Actual File Content will go hear.
+    dlf = "/data/storage/disk0/backup/system_backups/%s" %dl_file
+    fo = open(dlf, "rb")
+
+    str = fo.read()
+    fo.close()
+
+    # HTTP Header
+    print "Content-Type:application/octet-stream; name=\"%s\"\r\n;" %(dl_file)
+    print "Content-Disposition: attachment; filename=\"%s\"\r\n;" %(dl_file)
+    print "Content-Length: %d" % len(str)
+    print ""
+
+    print str
+    return results
+
+def go_restore(restorefile,myhost,prestore):
+    myhostname = socket.gethostname()
+    psc = ''
+    if prestore == "on":
+        psc = "partial"
+
+    if myhostname.strip() == myhost.strip():
+        command="sudo /usr/LH/bin/lh_system_restore_job %s  %s" %(restorefile , psc)
+    else:
+        #this should never execute
+        sshcmd="ssh -o StrictHostKeyChecking=no -o ConnectTimeout=1 -i /data/srv/.nobody_ssh/id_dsa mythtv@"
+        sshcmd+=myhost.strip()
+        cmd=' "sudo /usr/bin/restore_job.sh   "   '
+        command=sshcmd + cmd + restorefile + " 2>&1 "
+    #print command
+    results=os.popen(command,'r')
+    return  results
+
+def go_upload(up_file):
+    saveDir = "/data/storage/disk0/backup/system_backups/"
+    fPath = "%s/%s" % (saveDir, up_file.filename)
+    buf = up_file.file.read()
+    bytes = len(buf)
+    sFile = open(fPath, 'wb')
+    sFile.write(buf)
+    sFile.close()
+    results=["<b>%s</b> uploaded (%d bytes)." %(up_file.filename, bytes)]
+    line = '''The backup has been uploaded and is now available for restore.
+    To restore from the file, check "Restore database" then select the file from the drop down menu'''
+
+    results.append(line)
+
+    command2="sleep 1; sudo -u nobody /home/xymon/server/ext/hbnotes.py"
+    os.popen(command2,'r')
+
+    return results
+
+def go_optimize(myhost):
+    #myhostname = socket.gethostname()
+    #if myhostname.strip() == myhost.strip():
+    command="/usr/LH/bin/optimize_mythdb.py"
+    #print command
+    results=os.popen(command,'r')
+    #else:
+        #results='This host does not run a database'
+    return  results
+
+def go_update(myhost,update_type):
+    cmd=" call pacman update_system "
+    cmd+=update_type
+    command="/usr/bin/func \"" + myhost.strip() + "*\"  " + cmd
+    #print command
+    results=os.popen(command,'r')
+    return  results
+
+def go_updateall(allupdate_type):
+    cmd=" sudo /usr/bin/update_system_all "
+    cmd+=allupdate_type
+    command= cmd + " 2>&1 "
+    results=os.popen(command,'r')
+    return  results
+
+def go_shutdown(myhost):
+    myhostname = socket.gethostname()
+    message="Shutdown from MBE"
+    command="/usr/bin/func \"" + myhost.strip() +  "*\" call msg display \"%s\" " %message
+    results=os.popen(command,'r')
+    time.sleep(3)
+    command="/usr/bin/func \"" + myhost.strip() +  "*\" call power poweroff "
+    results=os.popen(command,'r')
+    return  results
+
+def go_shutdownall():
+    import MySQLdb
+    #import mysql
+    #find all hosts(minus myself)
+    #loop through results shutdown as we go.
+    db = MySQLdb.connect(host="localhost", user="mythtv", passwd="[REDACTED] db="mythconverg")
+    # create a cursor
+    cursor = db.cursor()
+    # execute SQL statement
+    myhostname = socket.gethostname()
+    results=["Sent shutdown command to: \n "]
+    cursor.execute("SELECT distinct(hostname) from settings where not  hostname = %s ; ",(myhostname))
+    result = cursor.fetchall()
+
+    for row in result:
+         go_shutdown(row[0])
+         results.append(row[0])
+
+    #shutdown myself.
+    #go_shutdown(myhostname)
+    #results.append(myhostname)
+    return  results
+
+def go_reboot(myhost):
+    myhostname = socket.gethostname()
+    message="Reboot from MBE"
+    command="/usr/bin/func \"" + myhost.strip() +  "*\" call msg display \"%s\" " %message
+    results=os.popen(command,'r')
+    time.sleep(3)
+
+    command="/usr/bin/func \"" + myhost.strip() +  "*\" call power reboot "
+    results=os.popen(command,'r')
+    return  results
+
+def go_wake(myhost):
+    command="/usr/MythVantage/bin/wakeonlan.sh " + myhost.strip()
+    results=os.popen(command,'r')
+    return  results
+
+def go_kill(myhost,kill_type):
+    myhostname = socket.gethostname()
+    cmd=" call fe_restart "
+    cmd+=kill_type
+    command="/usr/bin/func \"" + myhost.strip() + "*\"  " + cmd
+
+    results=os.popen(command,'r')
+    return  results
+
+def go_restart_mbe_local():
+    cmd = "/usr/LH/bin/lh_backend_control.sh restart &"
+    #results=os.popen(cmd,'r')
+    os.popen(cmd,'r')
+    results = ["Attempting restart of backend service"]
+    return  results
+
+
+mainpage = '''
+<html>
+    <head>
+        <style type="text/css">@import "/frame.css";</style>
+        <meta http-equiv="cache-control" content="max-age=0">
+        <meta http-equiv="cache-control" content="no-cache">
+        <meta http-equiv="expires" content="0">
+        <meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT">
+        <meta http-equiv="pragma" content="no-cache">
+        <title>LinHES</title>
+    </head>
+    <body>
+    %s
+    </body>
+</html>
+'''
+
+
+loadingpage = '''
+<html>
+    <head>
+        <style type="text/css">@import "/frame.css";</style>
+        <script src="/ajaxloader.min.js"></script>
+        <meta http-equiv="cache-control" content="max-age=0">
+        <meta http-equiv="cache-control" content="no-cache">
+        <meta http-equiv="expires" content="0">
+        <meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT">
+        <meta http-equiv="pragma" content="no-cache">
+        <title>LinHES</title>
+    </head>
+    <body>
+        <div id="header">
+            %s
+        </div>
+        <div id="container">
+            <br><br>
+            <h3>Working. Please Wait...</h3>
+            <br><br>
+            <div>
+                <canvas id="spinner"></canvas>
+            </div>
+        </div>
+        <script type="text/javascript">
+            var opts = {
+                size: 72,           // Width and height of the spinner
+                factor: 0.25,       // Factor of thickness, density, etc.
+                color: "#ebb81c",      // Color #rgb or #rrggbb
+                speed: 1.0,         // Number of turns per second
+                clockwise: true     // Direction of rotation
+            };
+            var ajaxLoader = new AjaxLoader("spinner", opts);
+            ajaxLoader.show();
+        </script>
+'''
+
+
+error = '''
+    <h1>Error</h1>
+    <h2>No Form Submission Was Received</h2>'''
+
+
+result = '''
+    <h1>%s of %s</h1>
+'''
+
+possible_parameters = ['param1', 'param2', 'param3', 'param4','hiddenparam','param5','param6','param7','uFile','param8']
+
+if __name__ == '__main__':
+
+    theform = cgi.FieldStorage()
+    #print theform
+    formdict = getform(theform, possible_parameters)
+    #print possible_parameters
+
+    if isblank(formdict):
+        body = error
+    else:
+        name = formdict['param1']
+        radio = formdict['param2']  # should be 'this' or 'that'
+        if radio != 'Restore' :
+            name = ""
+        update_type = formdict['param3']
+        oldurl = formdict['param4']
+        hidden = formdict['hiddenparam']
+        all_update_type=formdict['param5']
+        kill_type = formdict['param6']
+        dl_file = formdict['param7']
+        try:
+            up_file = theform['uFile']
+        except:
+            pass
+        try:
+            prestore = theform['param8'].value
+        except:
+            prestore = "off"
+        body = result % (radio, hidden)
+
+    selection=radio
+    myhost=hidden.lower()
+
+    if selection == "Restore":
+        mylogfile=go_restore(name,myhost,prestore)
+        cgiprint(contentheader)   # content header
+        cgiprint()                # finish headers with blank line
+        print mainpage % body
+    elif selection == "Backup":
+        cgiprint(contentheader)   # content header
+        cgiprint()                # finish headers with blank line
+        print loadingpage % body
+        mylogfile=go_backup(myhost)
+    elif selection == "Dbackup":
+        mylogfile=go_download_backup(dl_file)
+        cgiprint(contentheader)   # content header
+        cgiprint()                # finish headers with blank line
+        print mainpage % body
+    elif selection == "Update":
+        cgiprint(contentheader)   # content header
+        cgiprint()                # finish headers with blank line
+        print loadingpage % body
+        mylogfile=go_update(myhost,update_type)
+    elif selection == "Shutdown":
+        mylogfile=go_shutdown(myhost)
+        cgiprint(contentheader)   # content header
+        cgiprint()                # finish headers with blank line
+        print mainpage % body
+    elif selection == "Reboot":
+        mylogfile=go_reboot(myhost)
+        cgiprint(contentheader)   # content header
+        cgiprint()                # finish headers with blank line
+        print mainpage % body
+    elif selection == "Optimize":
+        cgiprint(contentheader)   # content header
+        cgiprint()                # finish headers with blank line
+        print loadingpage % body
+        mylogfile=go_optimize(myhost)
+    elif selection == "WOL":
+        cgiprint(contentheader)   # content header
+        cgiprint()                # finish headers with blank line
+        print loadingpage % body
+        mylogfile=go_wake(myhost)
+    elif selection == "UpdateAll":
+        mylogfile=go_updateall(all_update_type)
+        cgiprint(contentheader)   # content header
+        cgiprint()                # finish headers with blank line
+        print mainpage % body
+    elif selection == "ShutdownAll":
+        mylogfile=go_shutdownall()
+        cgiprint(contentheader)   # content header
+        cgiprint()                # finish headers with blank line
+        print mainpage % body
+    elif selection == "Kill":
+        mylogfile=go_kill(myhost,kill_type)
+        cgiprint(contentheader)   # content header
+        cgiprint()                # finish headers with blank line
+        print mainpage % body
+    elif selection == "Upload":
+        mylogfile = go_upload(up_file)
+        cgiprint(contentheader)   # content header
+        cgiprint()                # finish headers with blank line
+        print mainpage % body
+    elif selection == "RestartMBE":
+        mylogfile = go_restart_mbe_local()
+        cgiprint(contentheader)   # content header
+        cgiprint()                # finish headers with blank line
+        print mainpage % body
+
+    cgiprint()                # finish headers with blank line
+
+    box='''<br><br>
+    <div id="resultbox" >
+
+    '''
+
+    endbox='''
+
+     </div>
+    '''
+    javascript='''
+    <script type="text/javascript">
+        document.getElementById("container").style.display = 'none';
+        ajaxLoader.hide();
+        var objDiv = document.getElementById("resultbox");
+        objDiv.scrollTop = objDiv.scrollHeight;
+    </script>
+    '''
+
+    print box
+    for line in mylogfile:
+        print line + '<br> \r\n'
+
+    print endbox
+    print "<br><br>"
+    #print '<a href=',  oldurl,     '  > Back </a> '
+    s='<a href="%s"><img src="back.png"></a>' %oldurl
+    print s
+    #<a href="myfile.htm"><img src="rainbow.gif"></a>
+    #print oldurl
+    print javascript
diff --git a/linhes/linhes-web/website/contents/skeleton.css b/linhes/linhes-web/website/contents/skeleton.css
new file mode 100644
index 0000000..6a6b107
--- /dev/null
+++ b/linhes/linhes-web/website/contents/skeleton.css
@@ -0,0 +1,105 @@
+/* ================================================================
+This copyright notice must be untouched at all times.
+
+The original version of this stylesheet and the associated (x)html
+is available at http://www.stunicholls.com/menu/skeleton_up.html
+Copyright (c) 2005-2007 Stu Nicholls. All rights reserved.
+This stylesheet and the associated (x)html may be modified in any
+way to fit your requirements.
+=================================================================== */
+#header_img {margin:5px auto;display:block;width:100%}
+
+#nav,
+#nav ul {padding:0 0 5px 0; margin:0; list-style:none;
+         font: 14px helvetica, sans-serif;
+         /*font: 14px verdana, sans-serif;*/
+         border:1px solid #000;
+         border-color:#ace #79b #68a #bde;
+         border-width:1px 2px 2px 1px; background:#fff;
+         position:relative; z-index:200;}
+
+#nav {height:auto; width:calc(100% - 2px);
+      padding:0; background-color:#0072bc;
+      display: inline-block;}
+
+#nav li {float:left; width:100%;}
+#nav li li {float:none; background:#fff;}
+/* a hack for IE5.x and IE6 */
+* html #nav li li {float:left;}
+
+
+
+
+#nav li a {display:block; float:left;
+           color:#FFFFFF; margin:0 25px 0 10px;
+           height:auto; line-height:25px;
+           text-decoration:none; white-space:normal;
+}
+
+/*item in white box*/
+#nav li li a {height:auto; line-height:20px; float:none;
+              background-color:#0072bc;
+              margin:0 0 0 0;
+              border:1px solid #000;
+              /*border-color:#ace #79b #68a #bde;*/
+              border-color:#0072bc;
+              border-width:3px 3px 3px 3px; background:#0072bc;
+    }
+
+#nav li:hover {position:relative; z-index:300; }
+
+/*white box*/
+#nav li:hover ul {left:4em; top:0px; right:-10px; background-color:#0072bc;}
+
+/* another hack for IE5.5 and IE6 */
+* html #nav li:hover ul {left:10px;}
+
+
+#nav ul {position:absolute;
+        left:-9999px;
+        top:-9999px;
+}
+/* yet another hack for IE5.x and IE6 */
+* html #nav ul {width:1px;}
+
+/* it could have been this simple if all browsers understood */
+/* show next level */
+#nav li:hover li:hover > ul {left:-15px; margin-left:100%; bottom:-7px; top:auto;}
+/* keep further levels hidden */
+#nav li:hover > ul ul {position:absolute; left:-9999px; top:-9999px; width:auto;}
+/* show path followed */
+
+#nav li:hover > a {text-decoration:underline; }
+
+
+/* but IE5.x and IE6 need this lot to style the flyouts and path followed */
+/* show next level */
+#nav li:hover li:hover ul,
+#nav li:hover li:hover li:hover ul,
+#nav li:hover li:hover li:hover li:hover ul,
+#nav li:hover li:hover li:hover li:hover li:hover ul
+{left:-15px; margin-left:100%; bottom:-7px; top:auto;}
+
+/* keep further levels hidden */
+#nav li:hover ul ul,
+#nav li:hover li:hover ul ul,
+#nav li:hover li:hover li:hover ul ul,
+#nav li:hover li:hover li:hover li:hover ul ul
+{position:absolute; left:-9999px; top:-9999px;}
+
+/* show path followed */
+#nav li:hover a,
+#nav li:hover li:hover a,
+#nav li:hover li:hover li:hover a,
+#nav li:hover li:hover li:hover li:hover a,
+#nav li:hover li:hover li:hover li:hover li:hover a,
+#nav li:hover li:hover li:hover li:hover li:hover li:hover a
+{text-decoration:underline; color:#ebb81c;}
+
+/* hide futher possible paths */
+#nav li:hover li a,
+#nav li:hover li:hover li a,
+#nav li:hover li:hover li:hover li a,
+#nav li:hover li:hover li:hover li:hover li a,
+#nav li:hover li:hover li:hover li:hover li:hover li a
+{text-decoration:none; color:#FFFFFF;}
-- 
cgit v0.12

