diff --git a/data/css/style.css b/data/css/style.css
index 91bf7b7f..9bd44217 100755
--- a/data/css/style.css
+++ b/data/css/style.css
@@ -136,11 +136,11 @@ table#artist_table { background-color: white; width: 100%; padding: 20px; }
table#artist_table th#name { text-align: left; min-width: 200px; }
table#artist_table th#status { text-align: left; min-width: 50px; }
-table#artist_table th#album { text-align: center; min-width: 300px; }
+table#artist_table th#album { text-align: left; min-width: 300px; }
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#status { vertical-align: middle; text-align: left; min-width: 50px; }
-table#artist_table td#album { vertical-align: middle; text-align: center; min-width: 300px; }
+table#artist_table td#album { vertical-align: middle; text-align: left; min-width: 300px; }
table#artist_table td#have { vertical-align: middle; }
div#paddingheader { padding-top: 48px; font-size: 24px; font-weight: bold; text-align: center; }
@@ -190,6 +190,25 @@ footer { margin: 20px auto 20px auto; }
div#version { text-align: center; font-weight: bold; }
div#donate { text-align: center; margin: 20px auto 20px auto; }
+.cloudtag { padding-top: 30px; font-size:16px; }
+#cloud a.tag1 { font-size: 0.7em; font-weight: 100; }
+#cloud a.tag2 { font-size: 0.8em; font-weight: 200; }
+#cloud a.tag3 { font-size: 0.9em; font-weight: 300; }
+#cloud a.tag4 { font-size: 1.0em; font-weight: 400; }
+#cloud a.tag5 { font-size: 1.2em; font-weight: 500; }
+#cloud a.tag6 { font-size: 1.4em; font-weight: 600; }
+#cloud a.tag7 { font-size: 1.6em; font-weight: 700; }
+#cloud a.tag8 { font-size: 1.8em; font-weight: 800; }
+#cloud a.tag9 { font-size: 2.2em; font-weight: 900; }
+#cloud a.tag10 { font-size: 2.5em; font-weight: 900; }
+
+#cloud { padding: 2px; line-height: 1.5em; text-align: center; }
+#cloud a { padding: 0px; }
+#cloud { margin: 0; }
+#cloud li { display: inline; }
+
+
+
.ir { display: block; text-indent: -999em; overflow: hidden; background-repeat: no-repeat; text-align: left; direction: ltr; }
.hidden { display: none; visibility: hidden; }
.visuallyhidden { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; }
diff --git a/data/interfaces/default/album.html b/data/interfaces/default/album.html
new file mode 100644
index 00000000..e242556d
--- /dev/null
+++ b/data/interfaces/default/album.html
@@ -0,0 +1,82 @@
+<%inherit file="base.html" />
+<%!
+ from headphones import db, helpers
+ myDB = db.DBConnection()
+%>
+
+<%def name="headerIncludes()">
+
+
+
+%def>
+
+<%def name="body()">
+
+
+
+
+
+
+ | # |
+ Track Title |
+ Duration |
+ Have |
+
+
+
+ %for track in tracks:
+ <%
+ trackmatch = 'asd'
+ if len(trackmatch):
+ grade = 'A'
+ check = '
'
+ else:
+ grade = 'Z'
+ check = ''
+ %>
+
+ | # |
+ ${track['TrackTitle']} |
+ ${track['TrackDuration']} |
+ ${check} |
+
+ %endfor
+
+
+
+
+%def>
+
+<%def name="headIncludes()">
+
+%def>
+
+<%def name="javascriptIncludes()">
+
+
+%def>
\ No newline at end of file
diff --git a/data/interfaces/default/base.html b/data/interfaces/default/base.html
index f3a38847..f9cea722 100755
--- a/data/interfaces/default/base.html
+++ b/data/interfaces/default/base.html
@@ -27,9 +27,17 @@
+
+<%inherit file="base.html" />
\ No newline at end of file
diff --git a/data/interfaces/default/extras.html b/data/interfaces/default/extras.html
new file mode 100644
index 00000000..d9dbbe2f
--- /dev/null
+++ b/data/interfaces/default/extras.html
@@ -0,0 +1,13 @@
+<%inherit file="base.html" />
+<%def name="body()">
+
+
Artists You Might Like
+
+
+%def>
diff --git a/data/interfaces/default/history.html b/data/interfaces/default/history.html
index 5db80fc3..f1002609 100644
--- a/data/interfaces/default/history.html
+++ b/data/interfaces/default/history.html
@@ -4,9 +4,9 @@
%def>
diff --git a/data/interfaces/default/index.html b/data/interfaces/default/index.html
index 595aae3d..83a594b6 100644
--- a/data/interfaces/default/index.html
+++ b/data/interfaces/default/index.html
@@ -30,7 +30,7 @@
if artist['ReleaseDate'] and artist['LatestAlbum']:
releasedate = artist['ReleaseDate']
- albumdisplay = '%s (%s)' % (artist['LatestAlbum'], artist['ReleaseDate'])
+ albumdisplay = '%s (%s)' % (artist['LatestAlbum'], artist['ReleaseDate'])
if releasedate > helpers.today():
grade = 'A'
else:
@@ -38,21 +38,21 @@
elif artist['LatestAlbum']:
releasedate = ''
grade = 'Z'
- albumdisplay = artist['LatestAlbum']
+ albumdisplay = '%s' % artist['LatestAlbum']
else:
releasedate = ''
grade = 'Z'
- albumdisplay = 'None'
+ albumdisplay = 'None'
if artist['Status'] == 'Paused':
grade = 'X'
%>
- | ${artist['ArtistName']} |
+ ${artist['ArtistName']} |
${artist['Status']} |
- ${albumdisplay} |
- ${havetracks}/${totaltracks} |
+ ${albumdisplay} |
+ ${havetracks}/${totaltracks} |
%endfor
diff --git a/data/interfaces/default/manage.html b/data/interfaces/default/manage.html
new file mode 100644
index 00000000..0d91e773
--- /dev/null
+++ b/data/interfaces/default/manage.html
@@ -0,0 +1,33 @@
+<%inherit file="base.html" />
+<%def name="body()">
+
+
Scan Music Library
+ Where do you keep your music?
+ You can put in any directory, and it will scan for audio files in that folder
+ (including all subdirectories)
For example: '/Users/name/Music'
+
+ It may take a while depending on how many files you have. You can navigate away from the page
+ as soon as you click 'Submit'
+
+
+
+
+
Import Last.FM Artists
+ Enter the username whose artists you want to import:
+
+
+ ''' % (music_dir_input, lastfm_user_text))
+%def>
\ No newline at end of file
diff --git a/data/interfaces/default/upcoming.html b/data/interfaces/default/upcoming.html
new file mode 100644
index 00000000..3bdd64f8
--- /dev/null
+++ b/data/interfaces/default/upcoming.html
@@ -0,0 +1,14 @@
+<%inherit file="base.html" />
+<%def name="body()">
+
+
Upcoming Albums
+ %for album in wanted:
+
+ %endfor
+
+
+
+
Wanted Albums
+
+
+%def>
diff --git a/headphones/webserve.py b/headphones/webserve.py
index 768d9fd1..73cb42bc 100644
--- a/headphones/webserve.py
+++ b/headphones/webserve.py
@@ -10,10 +10,11 @@ import threading
import headphones
-from headphones.mb import getReleaseGroup
-from headphones import templates, logger, searcher, db, importer, helpers, mb, lastfm
+from headphones import logger, searcher, db, importer, lastfm
from headphones.helpers import checked, radio
+
+
def serve_template(templatename, **kwargs):
template_dir = os.path.join(str(headphones.PROG_DIR), 'data/interfaces/default/')
@@ -181,18 +182,14 @@ class WebInterface(object):
def queueAlbum(self, AlbumID, ArtistID, new=False):
-
logger.info(u"Marking album: " + AlbumID + "as wanted...")
myDB = db.DBConnection()
controlValueDict = {'AlbumID': AlbumID}
newValueDict = {'Status': 'Wanted'}
myDB.upsert("albums", newValueDict, controlValueDict)
-
import searcher
searcher.searchNZB(AlbumID, new)
-
raise cherrypy.HTTPRedirect("artistPage?ArtistID=%s" % ArtistID)
-
queueAlbum.exposed = True
def unqueueAlbum(self, AlbumID, ArtistID):
@@ -208,112 +205,14 @@ class WebInterface(object):
unqueueAlbum.exposed = True
def upcoming(self):
- page = [templates._header]
- page.append(templates._logobar)
- page.append(templates._nav)
myDB = db.DBConnection()
- albums = myDB.select("SELECT AlbumTitle, ReleaseDate, DateAdded, AlbumASIN, AlbumID, ArtistName, ArtistID from albums WHERE ReleaseDate > date('now') order by ReleaseDate DESC")
-
+ upcoming = myDB.select("SELECT AlbumTitle, ReleaseDate, DateAdded, AlbumASIN, AlbumID, ArtistName, ArtistID from albums WHERE ReleaseDate > date('now') order by ReleaseDate DESC")
wanted = myDB.select("SELECT AlbumTitle, ReleaseDate, DateAdded, AlbumASIN, AlbumID, ArtistName, ArtistID from albums WHERE Status='Wanted'")
-
- page.append('''
-
- |
- Upcoming Albums
|
- |
- |
-
''')
- if len(albums) == 0:
- page.append("""
No albums are coming out soon :(
- (try adding some more artists!)
""")
-
- i = 0
- while i < len(albums):
-
- if albums[i][3]:
- albumart = '''

''' % (albums[i][3], albums[i][3])
- else:
- albumart = 'No Album Art... yet.'
-
- page.append('''| %s |
- %s |
- %s (%s) |
- ''' % (albumart, albums[i][6], albums[i][5], albums[i][4], albums[i][0], albums[i][1]))
- i += 1
- page.append('''
''')
- if len(wanted):
- page.append('''
-
- |
- Wanted Albums
|
- |
- |
-
''')
- i = 0
- while i < len(wanted):
-
- if wanted[i][3]:
- albumart = '''

''' % (wanted[i][3], wanted[i][3])
- else:
- albumart = 'No Album Art... yet.'
-
- page.append('''| %s |
- %s |
- %s (%s) |
- ''' % (albumart, wanted[i][6], wanted[i][5], wanted[i][4], wanted[i][0], wanted[i][1]))
- i += 1
- page.append('''
''')
- if len(albums):
- page.append(templates._footer % headphones.CURRENT_VERSION)
-
- return page
+ return serve_template(templatename="upcoming.html", title="Upcoming", upcoming=upcoming, wanted=wanted)
upcoming.exposed = True
def manage(self):
- if headphones.LASTFM_USERNAME:
- lastfm_user_text = headphones.LASTFM_USERNAME
- else:
- lastfm_user_text = 'Last.FM Username'
- if headphones.MUSIC_DIR:
- music_dir_input = '''''' % headphones.MUSIC_DIR
- else:
- music_dir_input = ''''''
- page = [templates._header]
- page.append(templates._logobar)
- page.append(templates._nav)
- page.append('''
- Scan Music Library
- Where do you keep your music?
- You can put in any directory, and it will scan for audio files in that folder
- (including all subdirectories)
For example: '/Users/name/Music'
-
- It may take a while depending on how many files you have. You can navigate away from the page
- as soon as you click 'Submit'
-
-
-
- Import Last.FM Artists
- Enter the username whose artists you want to import:
-
-
- ''' % (music_dir_input, lastfm_user_text))
- page.append(templates._footer % headphones.CURRENT_VERSION)
- return page
+ return serve_template(templatename="manage.html", title="Manage")
manage.exposed = True
def importLastFM(self, username):
@@ -387,67 +286,57 @@ class WebInterface(object):
return serve_template(templatename="logs.html", title="Log", lineList=lineList[0:500])
logs.exposed = True
- def clearhistory(self):
-
- logger.info(u"Clearing history")
+ def clearhistory(self, type=None):
+ logger.info(u"Clearing history where status is %s" % type)
myDB = db.DBConnection()
- myDB.action('''DELETE from snatched''')
-
+ myDB.action('DELETE from snatched WHERE Status=?', [type])
raise cherrypy.HTTPRedirect("history")
clearhistory.exposed = True
def config(self):
- page = [templates._header]
- page.append(templates._logobar)
- page.append(templates._nav)
- page.append(templates.configform % (
- headphones.HTTP_HOST,
- headphones.HTTP_USERNAME,
- headphones.HTTP_PORT,
- headphones.HTTP_PASSWORD,
- checked(headphones.LAUNCH_BROWSER),
- headphones.SAB_HOST,
- headphones.SAB_USERNAME,
- headphones.SAB_APIKEY,
- headphones.SAB_PASSWORD,
- headphones.SAB_CATEGORY,
- headphones.DOWNLOAD_DIR,
- checked(headphones.BLACKHOLE),
- headphones.BLACKHOLE_DIR,
- headphones.USENET_RETENTION,
- checked(headphones.NZBMATRIX),
- headphones.NZBMATRIX_USERNAME,
- headphones.NZBMATRIX_APIKEY,
- checked(headphones.NEWZNAB),
- headphones.NEWZNAB_HOST,
- headphones.NEWZNAB_APIKEY,
- checked(headphones.NZBSORG),
- headphones.NZBSORG_UID,
- headphones.NZBSORG_HASH,
- checked(headphones.NEWZBIN),
- headphones.NEWZBIN_UID,
- headphones.NEWZBIN_PASSWORD,
- radio(headphones.PREFERRED_QUALITY, 0),
- radio(headphones.PREFERRED_QUALITY, 1),
- radio(headphones.PREFERRED_QUALITY, 3),
- radio(headphones.PREFERRED_QUALITY, 2),
- headphones.PREFERRED_BITRATE,
- checked(headphones.DETECT_BITRATE),
- checked(headphones.MOVE_FILES),
- checked(headphones.RENAME_FILES),
- checked(headphones.CORRECT_METADATA),
- checked(headphones.CLEANUP_FILES),
- checked(headphones.ADD_ALBUM_ART),
- checked(headphones.EMBED_ALBUM_ART),
- headphones.DESTINATION_DIR,
- headphones.FOLDER_FORMAT,
- headphones.FILE_FORMAT,
- checked(headphones.INCLUDE_EXTRAS),
- headphones.LOG_DIR
- ))
- page.append(templates._footer % headphones.CURRENT_VERSION)
- return page
-
+ config = {
+ "http_host" : headphones.HTTP_HOST,
+ "http_user" : headphones.HTTP_USERNAME,
+ "http_port" : headphones.HTTP_PORT,
+ "http_pass" : headphones.HTTP_PASSWORD,
+ "launch_browser" : checked(headphones.LAUNCH_BROWSER),
+ "sab_host" : headphones.SAB_HOST,
+ "sab_user" : headphones.SAB_USERNAME,
+ "sab_api" : headphones.SAB_APIKEY,
+ "sab_pass" : headphones.SAB_PASSWORD,
+ "sab_cat" : headphones.SAB_CATEGORY,
+ "download_dir" : headphones.DOWNLOAD_DIR,
+ "use_blackhole" : checked(headphones.BLACKHOLE),
+ "blackhole_dir" : headphones.BLACKHOLE_DIR,
+ "usenet_retention" : headphones.USENET_RETENTION,
+ "use_nzbmatrix" : checked(headphones.NZBMATRIX),
+ "nzbmatrix_user" : headphones.NZBMATRIX_USERNAME,
+ "nzbmatrix_api" : headphones.NZBMATRIX_APIKEY,
+ "use_newznab" : checked(headphones.NEWZNAB),
+ "newznab_host" : headphones.NEWZNAB_HOST,
+ "newznab_api" : headphones.NEWZNAB_APIKEY,
+ "use_nzbsorg" : checked(headphones.NZBSORG),
+ "nzbsorg_uid" : headphones.NZBSORG_UID,
+ "nzbsorg_hash" : headphones.NZBSORG_HASH,
+ "pref_qual_0" : radio(headphones.PREFERRED_QUALITY, 0),
+ "pref_qual_1" : radio(headphones.PREFERRED_QUALITY, 1),
+ "pref_qual_2" : radio(headphones.PREFERRED_QUALITY, 3),
+ "pref_qual_3" : radio(headphones.PREFERRED_QUALITY, 2),
+ "pref_bitrate" : headphones.PREFERRED_BITRATE,
+ "detect_bitrate" : checked(headphones.DETECT_BITRATE),
+ "move_files" : checked(headphones.MOVE_FILES),
+ "rename_files" : checked(headphones.RENAME_FILES),
+ "correct_metadata" : checked(headphones.CORRECT_METADATA),
+ "cleanup_files" : checked(headphones.CLEANUP_FILES),
+ "add_album_art" : checked(headphones.ADD_ALBUM_ART),
+ "embed_album_art" : checked(headphones.EMBED_ALBUM_ART),
+ "dest_dir" : headphones.DESTINATION_DIR,
+ "folder_format" : headphones.FOLDER_FORMAT,
+ "file_format" : headphones.FILE_FORMAT,
+ "include_extras" : checked(headphones.INCLUDE_EXTRAS),
+ "log_dir" : headphones.LOG_DIR
+ }
+ return serve_template(templatename="config.html", title="Settings", config=config)
config.exposed = True