From fe1667a2e000eea6786ae60579de47e49c89d26e Mon Sep 17 00:00:00 2001 From: Remy Date: Fri, 5 Aug 2011 22:20:36 -0700 Subject: [PATCH] Added artist page and log page, fixed some css, added logline parse to helpers --- data/css/data_table.css | 6 +- data/css/style.css | 56 +++++++++---- data/interfaces/default/artist.html | 68 +++++++++++++++ data/interfaces/default/base.html | 7 +- data/interfaces/default/index.html | 18 +++- data/interfaces/default/logs.html | 56 +++++++++++++ data/js/libs/jquery.dataTables.min.js | 2 +- data/js/script.js | 12 --- headphones/helpers.py | 15 +++- headphones/templates.py | 2 +- headphones/webserve.py | 116 +------------------------- 11 files changed, 210 insertions(+), 148 deletions(-) create mode 100644 data/interfaces/default/artist.html create mode 100644 data/interfaces/default/logs.html diff --git a/data/css/data_table.css b/data/css/data_table.css index 9e9b9320..801352ac 100644 --- a/data/css/data_table.css +++ b/data/css/data_table.css @@ -4,7 +4,7 @@ -moz-border-radius: 20px; width: 88%; margin: 20px auto 0 auto; - padding: 22px; + padding: 25px; background-color: white; position: relative; min-height: 155px; @@ -42,7 +42,7 @@ } .dataTables_info { - width: 40%; + width: 50%; float: left; background-color: white; font-weight: bold; @@ -86,7 +86,7 @@ * DataTables display */ table.display { - margin: 20px auto; + margin: 20px auto; clear: both; /* Note Firefox 3.5 and before have a bug with border-collapse diff --git a/data/css/style.css b/data/css/style.css index d26525d0..3e7b5ba5 100755 --- a/data/css/style.css +++ b/data/css/style.css @@ -66,8 +66,8 @@ input:valid, textarea:valid { } input:invalid, textarea:invalid { border-radius: 1px; -moz-box-shadow: 0px 0px 5px red; -webkit-box-shadow: 0px 0px 5px red; box-shadow: 0px 0px 5px red; } .no-boxshadow input:invalid, .no-boxshadow textarea:invalid { background-color: #f0dddd; } -::-moz-selection{ background: #FF5E99; color:#fff; text-shadow: none; } -::selection { background:#FF5E99; color:#fff; text-shadow: none; } +::-moz-selection{ background: grey; color:#fff; text-shadow: none; } +::selection { background: grey; color:#fff; text-shadow: none; } a:link { -webkit-tap-highlight-color: #FF5E99; } button { width: auto; overflow: visible; } @@ -110,28 +110,56 @@ header { height: 68px; width: 100%; min-width: 907px; padding: 0 10px 0 10px; ba div#logo { float: left; } ul#nav { margin-top: 25px; float: left; list-style-type: none; } -ul#nav li { margin: 40px 5px auto 12px; display: inline; } -ul#nav li a { font-size: 16px; font-weight: bold; color: #330000; text-decoration: none; } +ul#nav li { margin: 40px 0px auto 10px; display: inline; } +ul#nav li a { padding: 5px; font-size: 16px; font-weight: bold; color: #330000; text-decoration: none; } ul#nav li a:hover { background-color: #a3e532; } -div#searchbar { margin: 24px auto auto 30px; float: left; } +div#subhead_container { margin-top: 68px; height: 30px; width:100%; min-width: 907px; background-color:#330000; position: fixed; float: left; list-style-type: none; top: 0; z-index: 999; overflow: hidden; } +ul#subhead_menu { margin-top: 5px; } +ul#subhead_menu li { width: 100%; height: 100%; display: inline; } +ul#subhead_menu li a { padding: 5px 15px 10px 15px; vertical-align: middle; color: white; font-size: 16px; text-decoration: none; } +ul#subhead_menu li a:hover { width: 100%; height: 100%; background-color: #grey; } -div#main { margin: 0; padding: 68px 0 0 0; } +div#searchbar { margin: 24px 30px auto auto; float: right; } + +div#main { margin: 0; padding: 80px 0 0 0; } table#artist_table { background-color: white; } -table#artist_table th#name { text-align: left; min-width: 225px; } -table#artist_table th#album { text-align: center; min-width: 250px; } +table#artist_table th#name { text-align: left; min-width: 200px; } +table#artist_table th#album { text-align: center; min-width: 300px; } table#artist_table th#reldate { width: 175px; text-align: center; min-width: 100px; } -table#artist_table th#center { text-align: center; } -table#artist_table td#name { vertical-align: middle; text-align: left; } -table#artist_table td#album { vertical-align: middle; text-align: center; } -table#artist_table td#reldate { vertical-align: middle; width: 125px; text-align: center; } -table#artist_table td#have { vertical-align: middle; text-align: center; } +table#artist_table th#have { text-align: center; } +table#artist_table td#name { vertical-align: middle; text-align: left; min-width:200px; } +table#artist_table td#album { vertical-align: middle; text-align: center; min-width: 300px; } +table#artist_table td#reldate { vertical-align: middle; text-align: center; min-width: 100px; } +table#artist_table td#have { vertical-align: middle; } + +div#artistheader { padding-top: 48px; font-size: 24px; font-weight: bold; text-align: center; } +table#album_table { background-color: white; } + +table#album_table th#albumart { text-align: left; min-width: 50px; } +table#album_table th#albumname { text-align: center; min-width: 150px; } +table#album_table th#reldate { width: 175px; text-align: center; min-width: 100px; } +table#album_table th#status { width: 175px; text-align: center; min-width: 100px; } +table#album_table th#type { width: 175px; text-align: center; min-width: 100px; } +table#album_table td#albumart { vertical-align: middle; text-align: left; } +table#album_table td#albumname { vertical-align: middle; text-align: center; } +table#album_table td#reldate { vertical-align: middle; text-align: center; } +table#album_table td#status { vertical-align: middle; text-align: center; } +table#album_table td#type { vertical-align: middle; text-align: center; } +table#album_table td#have { vertical-align: middle; } + +table#log_table { background-color: white; } + +table#log_table th#timestamp { text-align: left; min-width: 100px; } +table#log_table th#level { text-align: left; min-width: 100px; } +table#log_table th#thread { text-align: left; min-width: 100px; } +table#log_table th#message { text-align: left; min-width: 200px; } div.progress-container { border: 1px solid #ccc; width: 100px; height: 14px; margin: 2px 5px 2px 0; padding: 1px; float: left; background: white; } div.progress-container > div { background-color: #a3e532; height: 14px; } -.havetracks { font-size: 13px; margin-left: 36px; } +.havetracks { font-size: 13px; margin-left: 36px; padding-bottom: 3px; vertical-align: middle; } footer { margin: 20px auto 20px auto; } div#version { text-align: center; font-weight: bold; } diff --git a/data/interfaces/default/artist.html b/data/interfaces/default/artist.html new file mode 100644 index 00000000..f2f5cb8e --- /dev/null +++ b/data/interfaces/default/artist.html @@ -0,0 +1,68 @@ +<%inherit file="base.html"/> + +<%def name="subhead()"> +
+ +
+ + +<%def name="body()"> +
+ ${artist['ArtistName']} +
+ + + + + + + + + + + + + %for album in albums: + + + + + + + + + %endfor + +
Album NameRelease DateRelease TypeStatusHave
${album['AlbumTitle']}${album['ReleaseDate']}${album['Type']}${album['Status']}
tracks
+ + +<%def name="headerIncludes()"> + + + +<%def name="javascriptIncludes()"> + + + \ No newline at end of file diff --git a/data/interfaces/default/base.html b/data/interfaces/default/base.html index e543c04a..bfc4cd60 100755 --- a/data/interfaces/default/base.html +++ b/data/interfaces/default/base.html @@ -46,7 +46,9 @@ - +
+ ${next.subhead()} +
${next.body()}
@@ -81,4 +83,5 @@ <%def name="javascriptIncludes()"> -<%def name="headerIncludes()"> \ No newline at end of file +<%def name="headerIncludes()"> +<%def name="subhead()"> \ No newline at end of file diff --git a/data/interfaces/default/index.html b/data/interfaces/default/index.html index 8204c1f4..9a2a89bc 100644 --- a/data/interfaces/default/index.html +++ b/data/interfaces/default/index.html @@ -35,8 +35,8 @@ %> - ${artist['ArtistName']} - ${artist['LatestAlbum']} + ${artist['ArtistName']} + ${artist['LatestAlbum']} ${releasedate}
${havetracks}/${totaltracks}
@@ -51,4 +51,18 @@ <%def name="javascriptIncludes()"> + \ No newline at end of file diff --git a/data/interfaces/default/logs.html b/data/interfaces/default/logs.html new file mode 100644 index 00000000..ec79540c --- /dev/null +++ b/data/interfaces/default/logs.html @@ -0,0 +1,56 @@ +<%inherit file="base.html"/> + +<%def name="body()"> + + + + + + + + + + + %for line in lineList: + <% + from headphones import helpers + timestamp, level, thread, message = helpers.extract_logline(line) + %> + %if timestamp and level and thread and message: + + + + + + + %endif + %endfor + +
TimestampLevelThreadMessage
${timestamp}${level}${thread}${message.decode('utf-8')}
+ + +<%def name="headerIncludes()"> + + + +<%def name="javascriptIncludes()"> + + + \ No newline at end of file diff --git a/data/js/libs/jquery.dataTables.min.js b/data/js/libs/jquery.dataTables.min.js index adb45376..e5b480bd 100644 --- a/data/js/libs/jquery.dataTables.min.js +++ b/data/js/libs/jquery.dataTables.min.js @@ -33,7 +33,7 @@ g},"numeric-asc":function(g,l){return(g=="-"||g===""?0:g*1)-(l=="-"||l===""?0:l* if(l!==null&&!isNaN(l)||typeof g=="string"&&g.length===0)return"date";return null},function(g){if(typeof g=="string"&&g.indexOf("<")!=-1&&g.indexOf(">")!=-1)return"html";return null}];o.fnVersionCheck=function(g){var l=function(x,v){for(;x.length=parseInt(w,10)};o._oExternConfig={iNextUnique:0};i.fn.dataTable=function(g){function l(){this.fnRecordsTotal= function(){return this.oFeatures.bServerSide?parseInt(this._iRecordsTotal,10):this.aiDisplayMaster.length};this.fnRecordsDisplay=function(){return this.oFeatures.bServerSide?parseInt(this._iRecordsDisplay,10):this.aiDisplay.length};this.fnDisplayEnd=function(){return this.oFeatures.bServerSide?this.oFeatures.bPaginate===false||this._iDisplayLength==-1?this._iDisplayStart+this.aiDisplay.length:Math.min(this._iDisplayStart+this._iDisplayLength,this._iRecordsDisplay):this._iDisplayEnd};this.sInstance= this.oInstance=null;this.oFeatures={bPaginate:true,bLengthChange:true,bFilter:true,bSort:true,bInfo:true,bAutoWidth:true,bProcessing:false,bSortClasses:true,bStateSave:false,bServerSide:false,bDeferRender:false};this.oScroll={sX:"",sXInner:"",sY:"",bCollapse:false,bInfinite:false,iLoadGap:100,iBarWidth:0,bAutoCss:true};this.aanFeatures=[];this.oLanguage={sProcessing:"Processing...",sLengthMenu:"Show _MENU_ artists per page",sZeroRecords:"No matching records found",sEmptyTable:"", -sLoadingRecords:"Loading...",sInfo:"Showing _START_ to _END_ of _TOTAL_ total artists",sInfoEmpty:"Showing 0 to 0 of 0 artists",sInfoFiltered:"(filtered from _MAX_ total artists)",sInfoPostFix:"",sSearch:"Filter:",sUrl:"",oPaginate:{sFirst:"First",sPrevious:"Previous",sNext:"Next",sLast:"Last"},fnInfoCallback:null};this.aoData=[];this.aiDisplay=[];this.aiDisplayMaster=[];this.aoColumns=[];this.aoHeader=[];this.aoFooter=[];this.iNextId=0;this.asDataSearch=[];this.oPreviousSearch={sSearch:"",bRegex:false, +sLoadingRecords:"Loading...",sInfo:"Showing _START_ to _END_ of _TOTAL_ artists",sInfoEmpty:"Showing 0 to 0 of 0 artists",sInfoFiltered:"(filtered from _MAX_ total artists)",sInfoPostFix:"",sSearch:"Filter:",sUrl:"",oPaginate:{sFirst:"First",sPrevious:"Previous",sNext:"Next",sLast:"Last"},fnInfoCallback:null};this.aoData=[];this.aiDisplay=[];this.aiDisplayMaster=[];this.aoColumns=[];this.aoHeader=[];this.aoFooter=[];this.iNextId=0;this.asDataSearch=[];this.oPreviousSearch={sSearch:"",bRegex:false, bSmart:true};this.aoPreSearchCols=[];this.aaSorting=[[0,"asc",0]];this.aaSortingFixed=null;this.asStripClasses=[];this.asDestoryStrips=[];this.sDestroyWidth=0;this.fnFooterCallback=this.fnHeaderCallback=this.fnRowCallback=null;this.aoDrawCallback=[];this.fnInitComplete=this.fnPreDrawCallback=null;this.sTableId="";this.nTableWrapper=this.nTBody=this.nTFoot=this.nTHead=this.nTable=null;this.bInitialised=this.bDeferLoading=false;this.aoOpenRows=[];this.sDom="lfrtip";this.sPaginationType="two_button"; this.iCookieDuration=7200;this.sCookiePrefix="SpryMedia_DataTables_";this.fnCookieCallback=null;this.aoStateSave=[];this.aoStateLoad=[];this.sAjaxSource=this.oLoadedState=null;this.sAjaxDataProp="aaData";this.bAjaxDataGet=true;this.jqXHR=null;this.fnServerData=function(a,b,c,d){d.jqXHR=i.ajax({url:a,data:b,success:c,dataType:"json",cache:false,error:function(f,e){e=="parsererror"&&alert("DataTables warning: JSON data from server could not be parsed. This is caused by a JSON formatting error.")}})}; this.fnFormatNumber=function(a){if(a<1E3)return a;else{var b=a+"";a=b.split("");var c="";b=b.length;for(var d=0;d.*?)\s\-\s(?P.*?)\s*\:\:\s(?P.*?)\s\:\s(?P.*)', re.VERBOSE) + match = pattern.match(s) + if match: + timestamp = match.group("timestamp") + level = match.group("level") + thread = match.group("thread") + message = match.group("message") + return (timestamp, level, thread, message) + else: + return None \ No newline at end of file diff --git a/headphones/templates.py b/headphones/templates.py index 8f2b3a77..4d399dc2 100644 --- a/headphones/templates.py +++ b/headphones/templates.py @@ -412,7 +412,7 @@ def displayAlbums(ArtistID, Type=None): else: newStatus = '%s' % (results[i][3]) page.append(''' - + %s (link) %s diff --git a/headphones/webserve.py b/headphones/webserve.py index 029805c4..08792d57 100644 --- a/headphones/webserve.py +++ b/headphones/webserve.py @@ -37,110 +37,11 @@ class WebInterface(object): return serve_template(templatename="index.html", title="Home", artists=artists) home.exposed = True - def homeold(self): - page = [templates._header] - if not headphones.CURRENT_VERSION: - page.append('''
You're running an unknown version of Headphones. Click here to update
''') - elif headphones.CURRENT_VERSION != headphones.LATEST_VERSION and headphones.INSTALL_TYPE != 'win': - page.append('''
A - newer version is available. You're %s commits behind. Click here to update
- ''' % (headphones.CURRENT_VERSION, headphones.LATEST_VERSION, headphones.COMMITS_BEHIND)) - page.append(templates._logobar) - page.append(templates._nav) - myDB = db.DBConnection() - results = myDB.select('SELECT ArtistName, ArtistID, Status, LatestAlbum, ReleaseDate, AlbumID, TotalTracks, HaveTracks from artists order by ArtistSortName collate nocase') - if len(results): - page.append('''
- - - - - - ''') - for artist in results: - totaltracks = artist['TotalTracks'] - havetracks = artist['HaveTracks'] - if not havetracks: - havetracks = 0 - try: - percent = (havetracks*100.0)/totaltracks - if percent > 100: - percent = 100 - except (ZeroDivisionError, TypeError): - percent = 0 - totaltracks = '?' - - if artist['LatestAlbum']: - if artist['ReleaseDate'] > helpers.today(): - newalbumName = '%s' % (artist['AlbumID'], artist['LatestAlbum']) - releaseDate = '(%s)' % artist['ReleaseDate'] - else: - newalbumName = '%s' % (artist['AlbumID'], artist['LatestAlbum']) - releaseDate = "" - else: - newalbumName = 'None' - releaseDate = "" - - if artist['Status'] == 'Paused': - newStatus = '''%s(resume)''' % (artist['Status'], artist['ArtistID']) - elif artist['Status'] == 'Loading': - newStatus = '''Loading...''' - else: - newStatus = '''%s(pause)''' % (artist['Status'], artist['ArtistID']) - - page.append(''' - - - - ''' % (artist['ArtistID'], artist['ArtistName'], artist['ArtistID'], - artist['ArtistID'], newStatus, newalbumName, releaseDate, - percent, havetracks, totaltracks)) - - page.append('''
Artist NameStatusUpcoming AlbumsHave
%s - (link) [delete]%s%s %s
%s/%s
''') - page.append(templates._footer % headphones.CURRENT_VERSION) - - else: - have = myDB.select('SELECT ArtistName from have') - if len(have): - page.append("""
Scanning...
""") - else: - page.append("""
Add some artists to the database!
""") - return page - home.exposed = True - - def artistPage(self, ArtistID): - page = [templates._header] - page.append(templates._logobar) - page.append(templates._nav) myDB = db.DBConnection() - - artist = myDB.select('SELECT ArtistName, IncludeExtras, Status from artists WHERE ArtistID=?', [ArtistID]) - while not artist: - time.sleep(1) - page.append('''

%s

- ''' % artist[0][0]) - if artist[0][2] == 'Loading': - page.append('

Loading...

') - - if templates.displayAlbums(ArtistID, 'Album'): - page.append(templates.displayAlbums(ArtistID, 'Album')) - - releasetypes = ['Compilation', 'EP', 'Single', 'Live', 'Remix'] - - for type in releasetypes: - if templates.displayAlbums(ArtistID, type): - page.append(templates.displayAlbums(ArtistID, type)) - - page.append('
') - - if not artist[0][1]: - page.append('''
''' - % (ArtistID, artist[0][0])) - - page.append(templates._footer % headphones.CURRENT_VERSION) - return page + artist = myDB.action('SELECT * FROM artists WHERE ArtistID=?', [ArtistID]).fetchone() + albums = myDB.select('SELECT * from albums WHERE ArtistID=? order by ReleaseDate DESC', [ArtistID]) + return serve_template(templatename="artist.html", title=artist['ArtistName'], artist=artist, albums=albums) artistPage.exposed = True @@ -524,22 +425,13 @@ class WebInterface(object): history.exposed = True def logs(self): - page = [templates._header] - page.append(templates._logobar) - page.append(templates._nav) - page.append('''

''') log_file = os.path.join(headphones.LOG_DIR, 'headphones.log') if os.path.isfile(log_file): fileHandle = open(log_file) lineList = fileHandle.readlines() fileHandle.close() lineList.reverse() - for line in lineList[1:200]: - page.append(line.decode('utf-8') + '

') - page.append('''

''') - page.append(templates._footer % headphones.CURRENT_VERSION) - return page - + return serve_template(templatename="logs.html", title="Log", lineList=lineList[0:1000]) logs.exposed = True def clearhistory(self):