Compare commits
12 Commits
v2.1.2-bet
...
v2.1.4
Author | SHA1 | Date | |
---|---|---|---|
![]() |
b1dc5816a4 | ||
![]() |
476011a783 | ||
![]() |
e038c57c4c | ||
![]() |
a989a53750 | ||
![]() |
d8cfdea704 | ||
![]() |
ed4722c4ce | ||
![]() |
17ab5f05ed | ||
![]() |
71ab2248d7 | ||
![]() |
4fb4410552 | ||
![]() |
a915d2333f | ||
![]() |
aaf5a18251 | ||
![]() |
b90026801b |
18
CHANGELOG.md
18
CHANGELOG.md
@@ -1,5 +1,23 @@
|
||||
# Changelog
|
||||
|
||||
## v2.1.4 (2018-05-05)
|
||||
|
||||
* Newsletters:
|
||||
* Fix: Newsletter URL without an HTTP root.
|
||||
|
||||
|
||||
## v2.1.3-beta (2018-05-04)
|
||||
|
||||
* Newsletters:
|
||||
* Fix: HTTP root doubled in newsletter URL.
|
||||
* Fix: Configuration would not open with failed hostname resolution.
|
||||
* Fix: Schedule one day off when using weekday names in cron.
|
||||
* Fix: Images not refreshing when changed in Plex.
|
||||
* Fix: Cloudinary upload with non-ASCII image titles.
|
||||
* Other:
|
||||
* Fix: Potential XSS vulnerability in search.
|
||||
|
||||
|
||||
## v2.1.2-beta (2018-05-01)
|
||||
|
||||
* Newsletters:
|
||||
|
@@ -28,15 +28,17 @@
|
||||
|
||||
<%def name="javascriptIncludes()">
|
||||
<script>
|
||||
var query_string = "${query.replace('"','\\"').replace('/','\\/') | n}";
|
||||
|
||||
$('#search_button').removeClass('btn-inactive');
|
||||
$('#query').val("${query.replace('"','\\"') | n}").css({ right: '0', width: '250px' }).addClass('active');
|
||||
$('#query').val(query_string).css({ right: '0', width: '250px' }).addClass('active');
|
||||
|
||||
$.ajax({
|
||||
url: 'get_search_results_children',
|
||||
type: "GET",
|
||||
type: "POST",
|
||||
async: true,
|
||||
data: {
|
||||
query: "${query.replace('"','\\"') | n}",
|
||||
query: query_string,
|
||||
limit: 30
|
||||
},
|
||||
complete: function (xhr, status) {
|
||||
|
@@ -188,7 +188,7 @@ DOCUMENTATION :: END
|
||||
},
|
||||
complete: function (xhr, status) {
|
||||
$('#search-results-list').html(xhr.responseText);
|
||||
$('#update_query_title').html(query_string)
|
||||
$('#update_query_title').text(query_string)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@@ -9,7 +9,7 @@ __all__ = ('AllExpression', 'RangeExpression', 'WeekdayRangeExpression',
|
||||
'WeekdayPositionExpression', 'LastDayOfMonthExpression')
|
||||
|
||||
|
||||
WEEKDAYS = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']
|
||||
WEEKDAYS = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat']
|
||||
MONTHS = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec']
|
||||
|
||||
|
||||
|
@@ -792,8 +792,8 @@ def upload_to_cloudinary(img_data, img_title='', rating_key='', fallback=''):
|
||||
try:
|
||||
response = upload('data:image/png;base64,{}'.format(base64.b64encode(img_data)),
|
||||
public_id='{}_{}'.format(fallback, rating_key),
|
||||
tags=[fallback, rating_key],
|
||||
context={'title': img_title, 'rating_key': rating_key, 'fallback': fallback})
|
||||
tags=[fallback, str(rating_key)],
|
||||
context={'title': img_title.encode('utf-8'), 'rating_key': str(rating_key), 'fallback': fallback})
|
||||
logger.debug(u"Tautulli Helpers :: Image '{}' ({}) uploaded to Cloudinary.".format(img_title, fallback))
|
||||
img_url = response.get('url', '')
|
||||
except Exception as e:
|
||||
@@ -837,10 +837,10 @@ def cloudinary_transform(rating_key=None, width=1000, height=1500, opacity=100,
|
||||
img_options = {}
|
||||
|
||||
if width != 1000:
|
||||
img_options['width'] = width
|
||||
img_options['width'] = str(width)
|
||||
img_options['crop'] = 'fill'
|
||||
if height != 1500:
|
||||
img_options['height'] = height
|
||||
img_options['height'] = str(height)
|
||||
img_options['crop'] = 'fill'
|
||||
if opacity != 100:
|
||||
img_options['opacity'] = opacity
|
||||
@@ -1072,7 +1072,10 @@ def get_plexpy_url(hostname=None):
|
||||
s.connect(('<broadcast>', 0))
|
||||
hostname = s.getsockname()[0]
|
||||
except socket.error:
|
||||
hostname = socket.gethostbyname(socket.gethostname())
|
||||
try:
|
||||
hostname = socket.gethostbyname(socket.gethostname())
|
||||
except socket.gaierror:
|
||||
pass
|
||||
|
||||
if not hostname:
|
||||
hostname = 'localhost'
|
||||
|
@@ -475,7 +475,10 @@ class Newsletter(object):
|
||||
def _build_params(self):
|
||||
date_format = helpers.momentjs_to_arrow(plexpy.CONFIG.DATE_FORMAT)
|
||||
|
||||
base_url = plexpy.CONFIG.HTTP_BASE_URL or helpers.get_plexpy_url()
|
||||
if plexpy.CONFIG.NEWSLETTER_SELF_HOSTED and plexpy.CONFIG.HTTP_BASE_URL:
|
||||
base_url = plexpy.CONFIG.HTTP_BASE_URL + plexpy.HTTP_ROOT
|
||||
else:
|
||||
base_url = helpers.get_plexpy_url() + '/'
|
||||
|
||||
parameters = {
|
||||
'server_name': plexpy.CONFIG.PMS_NAME,
|
||||
@@ -484,7 +487,7 @@ class Newsletter(object):
|
||||
'week_number': self.start_date.isocalendar()[1],
|
||||
'newsletter_time_frame': self.config['time_frame'],
|
||||
'newsletter_time_frame_units': self.config['time_frame_units'],
|
||||
'newsletter_url': base_url.rstrip('/') + plexpy.HTTP_ROOT + 'newsletter/' + self.uuid,
|
||||
'newsletter_url': base_url + 'newsletter/' + self.uuid,
|
||||
'newsletter_uuid': self.uuid
|
||||
}
|
||||
|
||||
|
@@ -256,7 +256,7 @@ def notify_custom_conditions(notifier_id=None, parameters=None):
|
||||
|
||||
elif parameter_type == 'float':
|
||||
values = [helpers.cast_to_float(v) for v in values]
|
||||
|
||||
|
||||
except ValueError as e:
|
||||
logger.error(u"Tautulli NotificationHandler :: Unable to cast condition '%s', values '%s', to type '%s'."
|
||||
% (parameter, values, parameter_type))
|
||||
@@ -317,7 +317,9 @@ def notify_custom_conditions(notifier_id=None, parameters=None):
|
||||
else:
|
||||
evaluated_logic = all(evaluated_conditions[1:])
|
||||
|
||||
logger.debug(u"Tautulli NotificationHandler :: Custom condition evaluated to '%s'." % str(evaluated_logic))
|
||||
logger.debug(u"Tautulli NotificationHandler :: Custom condition evaluated to '{}'. Conditions: {}.".format(
|
||||
evaluated_logic, evaluated_conditions[1:]))
|
||||
|
||||
return evaluated_logic
|
||||
|
||||
return True
|
||||
|
@@ -2436,7 +2436,7 @@ class PmsConnect(object):
|
||||
return labels_list
|
||||
|
||||
def get_image(self, img=None, width=1000, height=1500, opacity=None, background=None, blur=None,
|
||||
img_format='png', clip=False, **kwargs):
|
||||
img_format='png', clip=False, refresh=False, **kwargs):
|
||||
"""
|
||||
Return image data as array.
|
||||
Array contains the image content type and image binary
|
||||
@@ -2454,6 +2454,9 @@ class PmsConnect(object):
|
||||
height = height or 1500
|
||||
|
||||
if img:
|
||||
if refresh:
|
||||
img = '{}/{}'.format(img.rstrip('/'), int(time.time()))
|
||||
|
||||
if clip:
|
||||
params = {'url': '%s&%s' % (img, urllib.urlencode({'X-Plex-Token': self.token}))}
|
||||
else:
|
||||
@@ -2544,7 +2547,7 @@ class PmsConnect(object):
|
||||
metadata = self.get_metadata_details(rating_key=rating_key)
|
||||
search_results_list[metadata['media_type']].append(metadata)
|
||||
|
||||
output = {'results_count': sum(len(s) for s in search_results_list.items()),
|
||||
output = {'results_count': sum(len(s) for s in search_results_list.values()),
|
||||
'results_list': search_results_list
|
||||
}
|
||||
|
||||
|
@@ -1,2 +1,2 @@
|
||||
PLEXPY_BRANCH = "beta"
|
||||
PLEXPY_RELEASE_VERSION = "v2.1.2-beta"
|
||||
PLEXPY_RELEASE_VERSION = "v2.1.4"
|
||||
|
@@ -3962,13 +3962,20 @@ class WebInterface(object):
|
||||
return
|
||||
|
||||
if rating_key and not img:
|
||||
img = '/library/metadata/%s/thumb/1337' % rating_key
|
||||
if fallback == 'art':
|
||||
img = '/library/metadata/{}/art'.format(rating_key)
|
||||
else:
|
||||
img = '/library/metadata/{}/thumb'.format(rating_key)
|
||||
|
||||
img_string = img.rsplit('/', 1)[0] if '/library/metadata' in img else img
|
||||
img_string = '{}{}{}{}{}{}'.format(img_string, width, height, opacity, background, blur)
|
||||
img_split = img.split('/')
|
||||
img = '/'.join(img_split[:5])
|
||||
rating_key = rating_key or img_split[3]
|
||||
|
||||
fp = hashlib.md5(img_string).hexdigest()
|
||||
fp += '.%s' % img_format # we want to be able to preview the thumbs
|
||||
img_string = '{}.{}.{}.{}.{}.{}.{}.{}'.format(
|
||||
plexpy.CONFIG.PMS_UUID, img, rating_key, width, height, opacity, background, blur, fallback)
|
||||
img_hash = hashlib.sha256(img_string).hexdigest()
|
||||
|
||||
fp = '{}.{}'.format(img_hash, img_format) # we want to be able to preview the thumbs
|
||||
c_dir = os.path.join(plexpy.CONFIG.CACHE_DIR, 'images')
|
||||
ffp = os.path.join(c_dir, fp)
|
||||
|
||||
@@ -3994,7 +4001,8 @@ class WebInterface(object):
|
||||
background=background,
|
||||
blur=blur,
|
||||
img_format=img_format,
|
||||
clip=clip)
|
||||
clip=clip,
|
||||
refresh=refresh)
|
||||
|
||||
if result and result[0]:
|
||||
cherrypy.response.headers['Content-type'] = result[1]
|
||||
|
Reference in New Issue
Block a user