Browse Source

Added support for ratings and integration with OZnzb.

pull/127/head
oznzb-dev 12 years ago
parent
commit
c211969a81
  1. BIN
      interfaces/Plush/templates/static/stylesheets/colorschemes/gold/images/sound16.png
  2. BIN
      interfaces/Plush/templates/static/stylesheets/colorschemes/gold/images/thumbdown20.png
  3. BIN
      interfaces/Plush/templates/static/stylesheets/colorschemes/gold/images/thumbup20.png
  4. BIN
      interfaces/Plush/templates/static/stylesheets/colorschemes/gold/images/vision16.png
  5. BIN
      interfaces/Plush/templates/static/stylesheets/rateit/delete.gif
  6. 98
      interfaces/Plush/templates/static/stylesheets/rateit/rateit.css
  7. BIN
      interfaces/Plush/templates/static/stylesheets/rateit/star.gif
  8. 34
      interfaces/wizard/four.html
  9. 43
      sabnzbd/api.py
  10. 39
      sabnzbd/interface.py
  11. 261
      sabnzbd/rating.py

BIN
interfaces/Plush/templates/static/stylesheets/colorschemes/gold/images/sound16.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 319 B

BIN
interfaces/Plush/templates/static/stylesheets/colorschemes/gold/images/thumbdown20.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 286 B

BIN
interfaces/Plush/templates/static/stylesheets/colorschemes/gold/images/thumbup20.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 347 B

BIN
interfaces/Plush/templates/static/stylesheets/colorschemes/gold/images/vision16.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 341 B

BIN
interfaces/Plush/templates/static/stylesheets/rateit/delete.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 752 B

98
interfaces/Plush/templates/static/stylesheets/rateit/rateit.css

@ -0,0 +1,98 @@
.rateit {
display: -moz-inline-box;
display: inline-block;
position: relative;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-o-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-touch-callout: none;
}
.rateit .rateit-range
{
position: relative;
display: -moz-inline-box;
display: inline-block;
background: url(star.gif);
height: 16px;
outline: none;
}
.rateit .rateit-range * {
display:block;
}
/* for IE 6 */
* html .rateit, * html .rateit .rateit-range
{
display: inline;
}
/* for IE 7 */
* + html .rateit, * + html .rateit .rateit-range
{
display: inline;
}
.rateit .rateit-hover, .rateit .rateit-selected
{
position: absolute;
left: 0px;
}
.rateit .rateit-hover-rtl, .rateit .rateit-selected-rtl
{
left: auto;
right: 0px;
}
.rateit .rateit-hover
{
background: url(star.gif) left -32px;
}
.rateit .rateit-hover-rtl
{
background-position: right -32px;
}
.rateit .rateit-selected
{
background: url(star.gif) left -48px;
}
.rateit .rateit-selected-rtl
{
background-position: right -48px;
}
.rateit .rateit-preset
{
background: url(star.gif) left -16px;
}
.rateit .rateit-preset-rtl
{
background: url(star.gif) left -16px;
}
.rateit button.rateit-reset
{
background: url(delete.gif) 0 0;
width: 16px;
height: 16px;
display: -moz-inline-box;
display: inline-block;
float: left;
outline: none;
border:none;
padding: 0;
}
.rateit button.rateit-reset:hover, .rateit button.rateit-reset:focus
{
background-position: 0 -16px;
}

BIN
interfaces/Plush/templates/static/stylesheets/rateit/star.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

34
interfaces/wizard/four.html

@ -0,0 +1,34 @@
<!--#include $webdir + "/inc_top.tmpl"#-->
<script type="text/javascript" src="static/javascript/jquery.js"></script>
<script type="text/javascript" src="static/javascript/restart.js"></script>
<br/><br/>
<h4 id="restarting" class="align-center">$T('wizard-restarting')</h4>
<h4 id="complete" class="align-center success hidden">$T('wizard-complete')</h4>
<br />
<br/>
<div id="tips" class="hidden">
$T('wizard-tip1') <span class="bold">$T('wizard-tip2')</span><br/>
<!--#set $tip3 = $T('wizard-tip3') % ''#-->
$tip3<br/><br/>
<div class="quoteBlock">
<!--#set $i = 0#-->
<!--#for $url in $urls#-->
<!--#set $i = $i+1#-->
<a href="$url">$url</a><!--#if $i != len($urls)#--><br /><!--#end if#-->
<!--#end for#-->
</div><br/>
$T('wizard-tip4')
<br/><br/>
$T('wizard-tip-wiki') <a href="$helpuri">wiki</a>
</div>
</div>
<hr /><br/>
<div class="full-width">
<table class="full-width">
<tr class="align-center">
<td><input type="hidden" name="session" id="apikey" value="$session"><input class="bigbutton disabled" type="button" onclick="document.location ='$access_url'" value="$T('wizard-goto')" disabled="disabled"/></td>
</tr>
</table>
</div>
<!--#include $webdir + "/inc_bottom.tmpl"#-->

43
sabnzbd/api.py

@ -58,6 +58,7 @@ from sabnzbd.postproc import PostProcessor
from sabnzbd.articlecache import ArticleCache from sabnzbd.articlecache import ArticleCache
from sabnzbd.utils.servertests import test_nntp_server_dict from sabnzbd.utils.servertests import test_nntp_server_dict
from sabnzbd.newzbin import Bookmarks from sabnzbd.newzbin import Bookmarks
from sabnzbd.rating import Rating
from sabnzbd.bpsmeter import BPSMeter from sabnzbd.bpsmeter import BPSMeter
from sabnzbd.database import build_history_info, unpack_history_info, get_history_handle from sabnzbd.database import build_history_info, unpack_history_info, get_history_handle
import sabnzbd.growler import sabnzbd.growler
@ -270,6 +271,24 @@ def _api_queue_default(output, value, kwargs):
else: else:
return report(output, _MSG_NOT_IMPLEMENTED) return report(output, _MSG_NOT_IMPLEMENTED)
def _api_queue_rating(output, value, kwargs):
""" API: accepts output, value(=nzo_id), type, setting, detail """
vote_map = {'up': Rating.VOTE_UP, 'down': Rating.VOTE_DOWN}
flag_map = {'spam': Rating.FLAG_SPAM, 'encrypted': Rating.FLAG_ENCRYPTED, 'expired': Rating.FLAG_EXPIRED, 'other': Rating.FLAG_OTHER, 'comment': Rating.FLAG_COMMENT}
type = kwargs.get('type')
setting = kwargs.get('setting')
if value:
try:
video = setting if type == 'video' and setting != "-" else None
audio = setting if type == 'audio' and setting != "-" else None
vote = vote_map[setting] if type == 'vote' else None
flag = flag_map[setting] if type == 'flag' else None
Rating.do.update_user_rating(value, video, audio, vote, flag, kwargs.get('detail'))
return report(output)
except:
return report(output, _MSG_BAD_SERVER_PARMS)
else:
return report(output, _MSG_NO_VALUE)
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
def _api_options(name, output, kwargs): def _api_options(name, output, kwargs):
@ -819,7 +838,8 @@ _api_queue_table = {
'pause' : _api_queue_pause, 'pause' : _api_queue_pause,
'resume' : _api_queue_resume, 'resume' : _api_queue_resume,
'priority' : _api_queue_priority, 'priority' : _api_queue_priority,
'sort' : _api_queue_sort 'sort' : _api_queue_sort,
'rating' : _api_queue_rating
} }
_api_config_table = { _api_config_table = {
@ -1044,6 +1064,7 @@ def build_queue(web_dir=None, root=None, verbose=False, prim=True, webdir='', ve
info['script_list'] = list_scripts() info['script_list'] = list_scripts()
info['cat_list'] = list_cats(output is None) info['cat_list'] = list_cats(output is None)
info['rating_enable'] = bool(cfg.rating_enable())
n = 0 n = 0
found_active = False found_active = False
@ -1213,8 +1234,13 @@ def build_queue(web_dir=None, root=None, verbose=False, prim=True, webdir='', ve
slot['finished'] = finished slot['finished'] = finished
slot['active'] = active slot['active'] = active
slot['queued'] = queued slot['queued'] = queued
rating = Rating.do.get_rating_by_nzo(nzo_id)
slot['has_rating'] = rating is not None
if rating:
slot['rating_avg_video'] = rating.avg_video
slot['rating_avg_audio'] = rating.avg_audio
if (start <= n and n < start + limit) or not limit: if (start <= n and n < start + limit) or not limit:
slotinfo.append(slot) slotinfo.append(slot)
n += 1 n += 1
@ -1762,6 +1788,17 @@ def build_history(start=None, limit=None, verbose=False, verbose_list=None, sear
if item['retry']: if item['retry']:
retry_folders.append(path) retry_folders.append(path)
rating = Rating.do.get_rating_by_nzo(item['nzo_id'])
item['has_rating'] = rating is not None
if rating:
item['rating_avg_video'] = rating.avg_video
item['rating_avg_audio'] = rating.avg_audio
item['rating_avg_vote_up'] = rating.avg_vote_up
item['rating_avg_vote_down'] = rating.avg_vote_down
item['rating_user_video'] = rating.user_video
item['rating_user_audio'] = rating.user_audio
item['rating_user_vote'] = rating.user_vote
total_items += full_queue_size total_items += full_queue_size
fetched_items = len(items) fetched_items = len(items)

39
sabnzbd/interface.py

@ -39,6 +39,7 @@ from sabnzbd.misc import real_path, to_units, \
from sabnzbd.panic import panic_old_queue from sabnzbd.panic import panic_old_queue
from sabnzbd.newswrapper import GetServerParms from sabnzbd.newswrapper import GetServerParms
from sabnzbd.newzbin import Bookmarks from sabnzbd.newzbin import Bookmarks
from sabnzbd.rating import Rating
from sabnzbd.bpsmeter import BPSMeter from sabnzbd.bpsmeter import BPSMeter
from sabnzbd.encoding import TRANS, xml_name, LatinFilter, unicoder, special_fixer, \ from sabnzbd.encoding import TRANS, xml_name, LatinFilter, unicoder, special_fixer, \
platform_encode, latin1, encode_for_xml platform_encode, latin1, encode_for_xml
@ -878,7 +879,8 @@ class HistoryPage(object):
self.__verbose_list = [] self.__verbose_list = []
self.__failed_only = False self.__failed_only = False
self.__prim = prim self.__prim = prim
self.__edit_rating = None
@cherrypy.expose @cherrypy.expose
def index(self, **kwargs): def index(self, **kwargs):
if not check_access(): return Protected() if not check_access(): return Protected()
@ -894,6 +896,8 @@ class HistoryPage(object):
history['isverbose'] = self.__verbose history['isverbose'] = self.__verbose
history['failed_only'] = failed_only history['failed_only'] = failed_only
history['rating_enable'] = bool(cfg.rating_enable())
if cfg.newzbin_username() and cfg.newzbin_password(): if cfg.newzbin_username() and cfg.newzbin_password():
history['newzbinDetails'] = True history['newzbinDetails'] = True
@ -908,6 +912,12 @@ class HistoryPage(object):
history['lines'], history['fetched'], history['noofslots'] = build_history(limit=limit, start=start, verbose=self.__verbose, verbose_list=self.__verbose_list, search=search, failed_only=failed_only) history['lines'], history['fetched'], history['noofslots'] = build_history(limit=limit, start=start, verbose=self.__verbose, verbose_list=self.__verbose_list, search=search, failed_only=failed_only)
for line in history['lines']:
if self.__edit_rating is not None and line.get('nzo_id') == self.__edit_rating:
line['edit_rating'] = True
else:
line['edit_rating'] = ''
if search: if search:
history['search'] = escape(search) history['search'] = escape(search)
else: else:
@ -1026,6 +1036,29 @@ class HistoryPage(object):
del_hist_job(job, del_files=True) del_hist_job(job, del_files=True)
raise dcRaiser(self.__root, kwargs) raise dcRaiser(self.__root, kwargs)
@cherrypy.expose
def show_edit_rating(self, **kwargs):
msg = check_session(kwargs)
if msg: return msg
self.__edit_rating = kwargs.get('job');
raise queueRaiser(self.__root, kwargs)
@cherrypy.expose
def action_edit_rating(self, **kwargs):
flag_map = {'spam': Rating.FLAG_SPAM, 'encrypted': Rating.FLAG_ENCRYPTED, 'expired': Rating.FLAG_EXPIRED}
msg = check_session(kwargs)
if msg: return msg
try:
if kwargs.get('send'):
video = kwargs.get('video') if kwargs.get('video') != "-" else None
audio = kwargs.get('audio') if kwargs.get('audio') != "-" else None
flag = flag_map.get(kwargs.get('rating_flag'))
detail = kwargs.get('expired_host') if kwargs.get('expired_host') != '<Host>' else None
Rating.do.update_user_rating(kwargs.get('job'), video, audio, flag, detail)
except:
pass
self.__edit_rating = None;
raise queueRaiser(self.__root, kwargs)
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
class ConfigPage(object): class ConfigPage(object):
@ -1176,7 +1209,8 @@ SWITCH_LIST = \
'ignore_samples', 'pause_on_post_processing', 'quick_check', 'nice', 'ionice', 'ignore_samples', 'pause_on_post_processing', 'quick_check', 'nice', 'ionice',
'ssl_type', 'pre_script', 'pause_on_pwrar', 'ampm', 'sfv_check', 'folder_rename', 'ssl_type', 'pre_script', 'pause_on_pwrar', 'ampm', 'sfv_check', 'folder_rename',
'unpack_check', 'quota_size', 'quota_day', 'quota_resume', 'quota_period', 'unpack_check', 'quota_size', 'quota_day', 'quota_resume', 'quota_period',
'pre_check', 'max_art_tries', 'max_art_opt', 'fail_hopeless' 'pre_check', 'max_art_tries', 'max_art_opt', 'fail_hopeless',
'rating_enable', 'rating_api_key', 'rating_host', 'rating_feedback'
) )
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
@ -1233,6 +1267,7 @@ SPECIAL_BOOL_LIST = \
'randomize_server_ip', 'no_ipv6', 'keep_awake', 'overwrite_files', 'empty_postproc', 'randomize_server_ip', 'no_ipv6', 'keep_awake', 'overwrite_files', 'empty_postproc',
'web_watchdog', 'wait_for_dfolder', 'warn_empty_nzb', 'enable_recursive', 'sanitize_safe', 'web_watchdog', 'wait_for_dfolder', 'warn_empty_nzb', 'enable_recursive', 'sanitize_safe',
'enable_meta' 'enable_meta'
) )
SPECIAL_VALUE_LIST = \ SPECIAL_VALUE_LIST = \
( 'size_limit', 'folder_max_length', 'fsys_type', 'movie_rename_limit', 'nomedia_marker', ( 'size_limit', 'folder_max_length', 'fsys_type', 'movie_rename_limit', 'nomedia_marker',

261
sabnzbd/rating.py

@ -0,0 +1,261 @@
#!/usr/bin/python -OO
# Copyright 2008-2012 The SABnzbd-Team <team@sabnzbd.org>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
"""
sabnzbd.rating - Rating support functions
"""
import httplib
import urllib
import time
import logging
import copy
import socket
import random
try:
socket.ssl
_HAVE_SSL = True
except:
_HAVE_SSL = False
from threading import *
import sabnzbd
from sabnzbd.decorators import synchronized
from sabnzbd.misc import OrderedSetQueue
import sabnzbd.cfg as cfg
RATING_URL = "/releaseRatings/releaseRatings.php"
RATING_LOCK = RLock()
_g_warnings = 0
def _warn(msg):
global _g_warnings
_g_warnings += 1
if _g_warnings < 3:
logging.warning(msg)
def _reset_warn():
global _g_warnings
_g_warnings = 0
class NzbRating(object):
def __init__(self):
self.avg_video = 0
self.avg_video_cnt = 0
self.avg_audio = 0
self.avg_audio_cnt = 0
self.avg_vote_up = 0
self.avg_vote_down = 0
self.user_video = None
self.user_audio = None
self.user_vote = None
self.user_flag = {}
self.auto_flag = {}
self.changed = 0
class Rating(Thread):
VERSION = 1
VOTE_UP = 1
VOTE_DOWN = 2
FLAG_OK = 0
FLAG_SPAM = 1
FLAG_ENCRYPTED = 2
FLAG_EXPIRED = 3
FLAG_OTHER = 4
FLAG_COMMENT = 5
CHANGED_USER_VIDEO = 0x01
CHANGED_USER_AUDIO = 0x02
CHANGED_USER_VOTE = 0x04
CHANGED_USER_FLAG = 0x08
CHANGED_AUTO_FLAG = 0x10
do = None
def __init__(self):
Rating.do = self
self.shutdown = False
self.queue = OrderedSetQueue()
try:
(self.version, self.ratings, self.nzo_indexer_map) = sabnzbd.load_admin("Rating.sab")
if (self.version != Rating.VERSION):
raise Exception()
except:
self.version = Rating.VERSION
self.ratings = {}
self.nzo_indexer_map = {}
Thread.__init__(self)
if not _HAVE_SSL:
logging.warning('Ratings server requires secure connection')
self.stop()
def stop(self):
self.shutdown = True
self.queue.put(None) # Unblock queue
def run(self):
self.shutdown = False
while not self.shutdown:
time.sleep(0.5)
indexer_id = self.queue.get()
try:
if indexer_id and not self._send_rating(indexer_id):
for i in range(0, 60):
if self.shutdown: break
time.sleep(1)
self.queue.put(indexer_id)
except:
pass
logging.debug('Stopping ratings')
@synchronized(RATING_LOCK)
def save(self):
if self.ratings and self.nzo_indexer_map:
sabnzbd.save_admin((self.version, self.ratings, self.nzo_indexer_map), "Rating.sab")
# The same file may be uploaded multiple times creating a new nzo_id each time
@synchronized(RATING_LOCK)
def add_rating(self, indexer_id, nzo_id, video, video_cnt, audio, audio_cnt, vote_up, vote_down):
if indexer_id and nzo_id and (video or audio or vote_up or vote_down):
logging.debug('Add rating (%s, %s: %s, %s, %s, %s)', indexer_id, nzo_id, video, audio, vote_up, vote_down)
try:
rating = self.ratings.get(indexer_id, NzbRating())
if video and video_cnt:
rating.avg_video = int(float(video))
rating.avg_video_cnt = int(float(video_cnt))
if audio and audio_cnt:
rating.avg_audio = int(float(audio))
rating.avg_audio_cnt = int(float(audio_cnt))
if vote_up: rating.avg_vote_up = int(float(vote_up))
if vote_down: rating.avg_vote_down = int(float(vote_down))
self.ratings[indexer_id] = rating
self.nzo_indexer_map[nzo_id] = indexer_id
except:
pass
@synchronized(RATING_LOCK)
def update_user_rating(self, nzo_id, video, audio, vote, flag, flag_detail = None):
logging.debug('Updating user rating (%s: %s, %s, %s, %s)', nzo_id, video, audio, vote, flag)
if nzo_id not in self.nzo_indexer_map:
logging.warning('indexer id (%s) not found for ratings file', nzo_id)
return
indexer_id = self.nzo_indexer_map[nzo_id]
rating = self.ratings[indexer_id]
if video:
rating.user_video = int(video)
rating.avg_video = int((rating.avg_video_cnt * rating.avg_video + rating.user_video) / (rating.avg_video_cnt + 1))
rating.changed = rating.changed | Rating.CHANGED_USER_VIDEO
if audio:
rating.user_audio = int(audio)
rating.avg_audio = int((rating.avg_audio_cnt * rating.avg_audio + rating.user_audio) / (rating.avg_audio_cnt + 1))
rating.changed = rating.changed | Rating.CHANGED_USER_AUDIO
if flag:
rating.user_flag = { 'val': int(flag), 'detail': flag_detail }
rating.changed = rating.changed | Rating.CHANGED_USER_FLAG
if vote and not rating.user_vote:
rating.user_vote = int(vote)
rating.changed = rating.changed | Rating.CHANGED_USER_VOTE
if rating.user_vote == Rating.VOTE_UP:
rating.avg_vote_up += 1
else:
rating.avg_vote_down += 1
self.queue.put(indexer_id)
@synchronized(RATING_LOCK)
def update_auto_flag(self, nzo_id, flag, flag_detail = None):
if not flag or not cfg.rating_feeback():
return
logging.debug('Updating auto flag (%s: %s)', nzo_id, flag)
if nzo_id not in self.nzo_indexer_map:
logging.warning('indexer id (%s) not found for ratings file', nzo_id)
return
indexer_id = self.nzo_indexer_map[nzo_id]
rating = self.ratings[indexer_id]
rating.auto_flag = { 'val': int(flag), 'detail': flag_detail }
rating.changed = rating.changed | Rating.CHANGED_AUTO_FLAG
self.queue.put(indexer_id)
@synchronized(RATING_LOCK)
def get_rating_by_nzo(self, nzo_id):
if nzo_id not in self.nzo_indexer_map:
return None
return copy.copy(self.ratings[self.nzo_indexer_map[nzo_id]])
@synchronized(RATING_LOCK)
def _get_rating_by_indexer(self, indexer_id):
return copy.copy(self.ratings[indexer_id])
def _flag_request(self, val, flag_detail, auto):
if val == Rating.FLAG_SPAM:
return {'m': 'rs', 'auto': auto}
if val == Rating.FLAG_ENCRYPTED:
return {'m': 'rp', 'auto': auto}
if val == Rating.FLAG_EXPIRED:
expired_host = flag_detail if flag_detail and len(flag_detail) > 0 else 'Other'
return {'m': 'rpr', 'pr': expired_host, 'auto': auto};
if (val == Rating.FLAG_OTHER) and flag_detail and len(flag_detail) > 0:
return {'m': 'o', 'r': flag_detail};
if (val == Rating.FLAG_COMMENT) and flag_detail and len(flag_detail) > 0:
return {'m': 'rc', 'r': flag_detail};
def _send_rating(self, indexer_id):
logging.debug('Updating indexer rating (%s)', indexer_id)
api_key = cfg.rating_api_key()
rating_host = cfg.rating_host()
if not api_key or not rating_host:
return False
requests = []
_headers = {'User-agent' : 'SABnzbd+/%s' % sabnzbd.version.__version__, 'Content-type': 'application/x-www-form-urlencoded'}
rating = self._get_rating_by_indexer(indexer_id) # Requesting info here ensures always have latest information even on retry
if rating.changed & Rating.CHANGED_USER_VIDEO:
requests.append({'m': 'r', 'r': 'videoQuality', 'rn': rating.user_video})
if rating.changed & Rating.CHANGED_USER_AUDIO:
requests.append({'m': 'r', 'r': 'audioQuality', 'rn': rating.user_audio})
if rating.changed & Rating.CHANGED_USER_VOTE:
up_down = 'up' if rating.user_vote == Rating.VOTE_UP else 'down'
requests.append({'m': 'v', 'v': up_down, 'r': 'overall'})
if rating.changed & Rating.CHANGED_USER_FLAG:
requests.append(self._flag_request(rating.user_flag.get('val'), rating.user_flag.get('detail'), 0))
if rating.changed & Rating.CHANGED_AUTO_FLAG:
requests.append(self._flag_request(rating.auto_flag.get('val'), rating.auto_flag.get('detail'), 1))
try:
conn = httplib.HTTPSConnection(rating_host)
for request in filter(lambda r: r is not None, requests):
request['apikey'] = api_key
request['i'] = indexer_id
conn.request('POST', RATING_URL, urllib.urlencode(request), headers = _headers)
response = conn.getresponse()
response.read()
if response.status == httplib.UNAUTHORIZED:
_warn('Ratings server unauthorized user')
return False
elif response.status != httplib.OK:
_warn('Ratings server failed to process request (%s, %s)' % response.status, response.reason)
return False
rating.changed = 0
_reset_warn()
return True
except:
_warn('Problem accessing ratings server: %s' % rating_host)
return False
Loading…
Cancel
Save