Skip to content

Commit

Permalink
Release v0.5.7
Browse files Browse the repository at this point in the history
  • Loading branch information
rembo10 committed Jul 1, 2015
2 parents c5ad7c9 + 624a1d5 commit 84a6c19
Show file tree
Hide file tree
Showing 12 changed files with 211 additions and 87 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
# Changelog

## v0.5.7
Released 01 July 2015

Highlights:
* Improved: Moved pushover to use requests lib
* Improved: Plex tokens with Plex Home
* Improved: Added getLogs & clearLogs to api
* Improved: Cache MetaCritic scores. Added user-agent header to fix 403 errors
* Improved: Specify whether to delete folders when force post-processing
* Improved: Convert target bitrate to vbr preset for what.cd searching
* Improved: Switched Pushover to requests lib

The full list of commits can be found [here](https://github.com/rembo10/headphones/compare/v0.5.6...v0.5.7).

## v0.5.6
Released 08 June 2015

Expand Down
10 changes: 10 additions & 0 deletions data/interfaces/default/config.html
Original file line number Diff line number Diff line change
Expand Up @@ -753,6 +753,12 @@ <h1 class="clearfix"><i class="fa fa-gear"></i> Settings</h1>
<input type="checkbox" name="replace_existing_folders" value="1" ${config['replace_existing_folders']}>
</label>
</div>
<div class="row indent">
<label>
Keep original folder?
<input type="checkbox" name="keep_original_folder" value="1" ${config['keep_original_folder']}>
</label>
</div>
</div>
<label>
Rename files
Expand Down Expand Up @@ -901,6 +907,10 @@ <h3>Plex Media Server</h3>
<label>Plex Password</label><input type="password" name="plex_password" value="${config['plex_password']}" size="30">
<small>Password of your Plex client API (blank for none)</small>
</div>
<div class="row">
<label>Plex Token</label><input type="text" name="plex_token" value="${config['plex_token']}" size="30">
<small>Plex Token (for use with Plex Home)</small>
</div>
<div class="checkbox row">
<input type="checkbox" name="plex_update" value="1" ${config['plex_update']} /><label>Update Plex Library</label>
</div>
Expand Down
91 changes: 69 additions & 22 deletions data/interfaces/default/manage.html
Original file line number Diff line number Diff line change
Expand Up @@ -137,28 +137,27 @@ <h3>The following artists will be deleted:</h3>
No empty artists found.
%endif
</div>
<a href="#" onclick="doAjaxCall('forcePostProcess',$(this))" data-success="Post-Processor is being loaded" data-error="Error during Post-Processing"><i class="fa fa-wrench fa-fw"></i> Force Post-Process Albums in Download Folder</a>
<div id="post_process">
<a href="#" class="btnOpenDialog"><i class="fa fa-wrench fa-fw"></i> Force Post-Process Albums in Download Folder</a>
</div>
</div>
</fieldset>
<form action="forcePostProcess" method="GET">
<fieldset>
<div class="row">
<label>Force Post-Process Albums in Alternate Folder</label>
<input type="text" value="" name="dir" id="dir" size="50" /><input type="submit" />
</div>
</fieldset>

</form>
<form action="forcePostProcess" method="GET">
<fieldset>
<div class="row">
<label>Post-Process Single Folder</label>
<input type="text" value="" name="album_dir" id="album_dir" size="50" /><input type="submit" />
</div>
</fieldset>

</form>

<fieldset>
<div class="row" id="post_process_alternate">
<label>Force Post-Process Albums in Alternate Folder</label>
<input type="text" value="" name="dir" id="dir" size="50" />
<input type="button" class="btnOpenDialog" value="Submit" />
</div>
</fieldset>

<fieldset>
<div class="row" id="post_process_single">
<label>Post-Process Single Folder</label>
<input type="text" value="" name="album_dir" id="album_dir" size="50" />
<input type="button" class="btnOpenDialog" value="Submit" />
</div>
</fieldset>

</div>


Expand All @@ -177,8 +176,7 @@ <h3>The following artists will be deleted:</h3>
</fieldset>

</div>


<div id="dialog-confirm"></div>

</div>
</%def>
Expand All @@ -187,6 +185,55 @@ <h3>The following artists will be deleted:</h3>
function addScanAction() {
$('#autoadd').append('<input type="hidden" name="scan" value=1 />');
};

function fnOpenNormalDialog(id) {
if (id === "post_process"){
var url = "forcePostProcess?"
}
if (id === "post_process_alternate"){
var dir = $('#dir').val();
var url = "forcePostProcess?dir=" + dir + "&"
}
if (id === "post_process_single"){
var dir = $('#album_dir').val();
var url = "forcePostProcess?album_dir=" + dir + "&"
}
var t = $('<a data-success="Post-Processor is being loaded" data-error="Error during Post-Processing">');
$("#dialog-confirm").html("Do you want to keep the original folder(s) after post-processing? If you click no, the folders still might be kept depending on your global settings");

// Define the Dialog and its properties.
$("#dialog-confirm").dialog({
resizable: false,
modal: true,
title: "Keep original folder(s)?",
height: 170,
width: 400,
buttons: {
"Yes": function () {
$(this).dialog('close');
doAjaxCall(url + "keep_original_folder=True", t);
},
"No": function () {
$(this).dialog('close');
doAjaxCall(url + "keep_original_folder=False", t);
}
}
});
}

$('.btnOpenDialog').click(function(e){
e.preventDefault();
var parentId = $(this).closest('div').prop('id');
fnOpenNormalDialog(parentId);
});

function callback(value) {
if (value) {
alert("Confirmed");
} else {
alert("Rejected");
}
}

function initThisPage() {
$('#manage_albums').click(function() {
Expand Down
7 changes: 6 additions & 1 deletion headphones/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ def dbcheck():
conn = sqlite3.connect(DB_FILE)
c = conn.cursor()
c.execute(
'CREATE TABLE IF NOT EXISTS artists (ArtistID TEXT UNIQUE, ArtistName TEXT, ArtistSortName TEXT, DateAdded TEXT, Status TEXT, IncludeExtras INTEGER, LatestAlbum TEXT, ReleaseDate TEXT, AlbumID TEXT, HaveTracks INTEGER, TotalTracks INTEGER, LastUpdated TEXT, ArtworkURL TEXT, ThumbURL TEXT, Extras TEXT, Type TEXT)')
'CREATE TABLE IF NOT EXISTS artists (ArtistID TEXT UNIQUE, ArtistName TEXT, ArtistSortName TEXT, DateAdded TEXT, Status TEXT, IncludeExtras INTEGER, LatestAlbum TEXT, ReleaseDate TEXT, AlbumID TEXT, HaveTracks INTEGER, TotalTracks INTEGER, LastUpdated TEXT, ArtworkURL TEXT, ThumbURL TEXT, Extras TEXT, Type TEXT, MetaCritic TEXT)')
# ReleaseFormat here means CD,Digital,Vinyl, etc. If using the default
# Headphones hybrid release, ReleaseID will equal AlbumID (AlbumID is
# releasegroup id)
Expand Down Expand Up @@ -599,6 +599,11 @@ def dbcheck():
except sqlite3.OperationalError:
c.execute('ALTER TABLE artists ADD COLUMN Type TEXT DEFAULT NULL')

try:
c.execute('SELECT MetaCritic from artists')
except sqlite3.OperationalError:
c.execute('ALTER TABLE artists ADD COLUMN MetaCritic TEXT DEFAULT NULL')

conn.commit()
c.close()

Expand Down
12 changes: 9 additions & 3 deletions headphones/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
cmd_list = ['getIndex', 'getArtist', 'getAlbum', 'getUpcoming', 'getWanted', 'getSnatched', 'getSimilar', 'getHistory', 'getLogs',
'findArtist', 'findAlbum', 'addArtist', 'delArtist', 'pauseArtist', 'resumeArtist', 'refreshArtist',
'addAlbum', 'queueAlbum', 'unqueueAlbum', 'forceSearch', 'forceProcess', 'forceActiveArtistsUpdate',
'getVersion', 'checkGithub','shutdown', 'restart', 'update', 'getArtistArt', 'getAlbumArt',
'getArtistInfo', 'getAlbumInfo', 'getArtistThumb', 'getAlbumThumb',
'getVersion', 'checkGithub', 'shutdown', 'restart', 'update', 'getArtistArt', 'getAlbumArt',
'getArtistInfo', 'getAlbumInfo', 'getArtistThumb', 'getAlbumThumb', 'clearLogs',
'choose_specific_download', 'download_specific_release']


Expand Down Expand Up @@ -176,7 +176,13 @@ def _getSimilar(self, **kwargs):
return

def _getLogs(self, **kwargs):
pass
self.data = headphones.LOG_LIST
return

def _clearLogs(self, **kwargs):
headphones.LOG_LIST = []
self.data = 'Cleared log'
return

def _findArtist(self, **kwargs):
if 'name' not in kwargs:
Expand Down
2 changes: 2 additions & 0 deletions headphones/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ def bool_int(value):
'PLEX_SERVER_HOST': (str, 'Plex', ''),
'PLEX_UPDATE': (int, 'Plex', 0),
'PLEX_USERNAME': (str, 'Plex', ''),
'PLEX_TOKEN': (str, 'Plex', ''),
'PREFERRED_BITRATE': (str, 'General', ''),
'PREFERRED_BITRATE_ALLOW_LOSSLESS': (int, 'General', 0),
'PREFERRED_BITRATE_HIGH_BUFFER': (int, 'General', 0),
Expand All @@ -200,6 +201,7 @@ def bool_int(value):
'PUSHOVER_PRIORITY': (int, 'Pushover', 0),
'RENAME_FILES': (int, 'General', 0),
'REPLACE_EXISTING_FOLDERS': (int, 'General', 0),
'KEEP_ORIGINAL_FOLDER': (int, 'General', 0),
'REQUIRED_WORDS': (str, 'General', ''),
'RUTRACKER': (int, 'Rutracker', 0),
'RUTRACKER_PASSWORD': (str, 'Rutracker', ''),
Expand Down
2 changes: 1 addition & 1 deletion headphones/importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,7 @@ def addArtisttoDB(artistid, extrasonly=False, forcefull=False, type="artist"):
cache.getThumb(ArtistID=artistid)

logger.info(u"Fetching Metacritic reviews for: %s" % artist['artist_name'])
metacritic.update(artist['artist_name'], artist['releasegroups'])
metacritic.update(artistid, artist['artist_name'], artist['releasegroups'])

if errors:
logger.info("[%s] Finished updating artist: %s but with errors, so not marking it as updated in the database" % (artist['artist_name'], artist['artist_name']))
Expand Down
53 changes: 41 additions & 12 deletions headphones/metacritic.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,17 @@
# along with Headphones. If not, see <http://www.gnu.org/licenses/>.

import re
import json
import headphones

from headphones import db, helpers, logger, request
from headphones.common import USER_AGENT

def update(artist_name,release_groups):
def update(artistid, artist_name,release_groups):
""" Pretty simple and crude function to find the artist page on metacritic,
then parse that page to get critic & user scores for albums"""

# First let's modify the artist name to fit the metacritic convention.
# First let's modify the artist name to fit the metacritic convention.
# We could just do a search, then take the top result, but at least this will
# cut down on api calls. If it's ineffective then we'll switch to search

Expand All @@ -31,28 +33,55 @@ def update(artist_name,release_groups):

mc_artist_name = mc_artist_name.replace(" ","-")

headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2243.2 Safari/537.36'}

url = "http://www.metacritic.com/person/" + mc_artist_name + "?filter-options=music&sort_options=date&num_items=100"

res = request.request_soup(url, parser='html.parser')
res = request.request_soup(url, headers=headers, parser='html.parser')

rows = None

try:
rows = res.tbody.find_all('tr')
except:
logger.info("Unable to get metacritic scores for: %s" % artist_name)
return

myDB = db.DBConnection()
artist = myDB.action('SELECT * FROM artists WHERE ArtistID=?', [artistid]).fetchone()

score_list = []

# If we couldn't get anything from MetaCritic for whatever reason,
# let's try to load scores from the db
if not rows:
if artist['MetaCritic']:
score_list = json.loads(artist['MetaCritic'])
else:
return

# If we did get scores, let's update the db with them
else:
for row in rows:
title = row.a.string
scores = row.find_all("span")
critic_score = scores[0].string
user_score = scores[1].string
score_dict = {'title':title,'critic_score':critic_score,'user_score':user_score}
score_list.append(score_dict)

for row in rows:
title = row.a.string
# Save scores to the database
controlValueDict = {"ArtistID": artistid}
newValueDict = {'MetaCritic':json.dumps(score_list)}
myDB.upsert("artists", newValueDict, controlValueDict)

for score in score_list:
title = score['title']
# Iterate through the release groups we got passed to see if we can find
# a match
for rg in release_groups:
if rg['title'].lower() == title.lower():
scores = row.find_all("span")
critic_score = scores[0].string
user_score = scores[1].string
critic_score = score['critic_score']
user_score = score['user_score']
controlValueDict = {"AlbumID": rg['id']}
newValueDict = {'CriticScore':critic_score,'UserScore':user_score}
myDB.upsert("albums", newValueDict, controlValueDict)



Loading

0 comments on commit 84a6c19

Please sign in to comment.