")),d=!1,C.$element.trigger("maxReachedGrp"+j)),setTimeout(function(){C.setSelected(r,!1)},10),E[0].classList.add("fadeOut"),setTimeout(function(){E.remove()},1050)}}}else c&&(c.selected=!1),h.selected=!0,C.setSelected(r,!0);!C.multiple||C.multiple&&1===C.options.maxOptions?C.$button.trigger("focus"):C.options.liveSearch&&C.$searchbox.trigger("focus"),d&&(!C.multiple&&a===s.selectedIndex||(A=[h.index,p.prop("selected"),l],C.$element.triggerNative("change")))}}),this.$menu.on("click","li."+V.DISABLED+" a, ."+V.POPOVERHEADER+", ."+V.POPOVERHEADER+" :not(.close)",function(e){e.currentTarget==this&&(e.preventDefault(),e.stopPropagation(),C.options.liveSearch&&!z(e.target).hasClass("close")?C.$searchbox.trigger("focus"):C.$button.trigger("focus"))}),this.$menuInner.on("click",".divider, .dropdown-header",function(e){e.preventDefault(),e.stopPropagation(),C.options.liveSearch?C.$searchbox.trigger("focus"):C.$button.trigger("focus")}),this.$menu.on("click","."+V.POPOVERHEADER+" .close",function(){C.$button.trigger("click")}),this.$searchbox.on("click",function(e){e.stopPropagation()}),this.$menu.on("click",".actions-btn",function(e){C.options.liveSearch?C.$searchbox.trigger("focus"):C.$button.trigger("focus"),e.preventDefault(),e.stopPropagation(),z(this).hasClass("bs-select-all")?C.selectAll():C.deselectAll()}),this.$element.on("change"+j,function(){C.render(),C.$element.trigger("changed"+j,A),A=null}).on("focus"+j,function(){C.options.mobile||C.$button.trigger("focus")})},liveSearchListener:function(){var u=this,f=document.createElement("li");this.$button.on("click.bs.dropdown.data-api",function(){u.$searchbox.val()&&u.$searchbox.val("")}),this.$searchbox.on("click.bs.dropdown.data-api focus.bs.dropdown.data-api touchend.bs.dropdown.data-api",function(e){e.stopPropagation()}),this.$searchbox.on("input propertychange",function(){var e=u.$searchbox.val();if(u.selectpicker.search.elements=[],u.selectpicker.search.data=[],e){var t=[],i=e.toUpperCase(),s={},n=[],o=u._searchStyle(),r=u.options.liveSearchNormalize;r&&(i=w(i));for(var l=0;l=a.selectpicker.view.canHighlight.length&&(t=0),a.selectpicker.view.canHighlight[t+f]||(t=t+1+a.selectpicker.view.canHighlight.slice(t+f+1).indexOf(!0))),e.preventDefault();var m=f+t;e.which===B?0===f&&t===c.length-1?(a.$menuInner[0].scrollTop=a.$menuInner[0].scrollHeight,m=a.selectpicker.current.elements.length-1):d=(o=(n=a.selectpicker.current.data[m]).position-n.height)u+a.sizeInfo.menuInnerHeight),s=a.selectpicker.main.elements[v],a.activeIndex=b[x],a.focusItem(s),s&&s.firstChild.focus(),d&&(a.$menuInner[0].scrollTop=o),r.trigger("focus")}}i&&(e.which===H&&!a.selectpicker.keydown.keyHistory||e.which===D||e.which===W&&a.options.selectOnTab)&&(e.which!==H&&e.preventDefault(),a.options.liveSearch&&e.which===H||(a.$menuInner.find(".active a").trigger("click",!0),r.trigger("focus"),a.options.liveSearch||(e.preventDefault(),z(document).data("spaceSelect",!0))))}},mobile:function(){this.$element[0].classList.add("mobile-device")},refresh:function(){var e=z.extend({},this.options,this.$element.data());this.options=e,this.checkDisabled(),this.setStyle(),this.render(),this.buildData(),this.buildList(),this.setWidth(),this.setSize(!0),this.$element.trigger("refreshed"+j)},hide:function(){this.$newElement.hide()},show:function(){this.$newElement.show()},remove:function(){this.$newElement.remove(),this.$element.remove()},destroy:function(){this.$newElement.before(this.$element).remove(),this.$bsContainer?this.$bsContainer.remove():this.$menu.remove(),this.$element.off(j).removeData("selectpicker").removeClass("bs-select-hidden selectpicker"),z(window).off(j+"."+this.selectId)}};var J=z.fn.selectpicker;z.fn.selectpicker=Z,z.fn.selectpicker.Constructor=Y,z.fn.selectpicker.noConflict=function(){return z.fn.selectpicker=J,this};var Q=z.fn.dropdown.Constructor._dataApiKeydownHandler||z.fn.dropdown.Constructor.prototype.keydown;z(document).off("keydown.bs.dropdown.data-api").on("keydown.bs.dropdown.data-api",':not(.bootstrap-select) > [data-toggle="dropdown"]',Q).on("keydown.bs.dropdown.data-api",":not(.bootstrap-select) > .dropdown-menu",Q).on("keydown"+j,'.bootstrap-select [data-toggle="dropdown"], .bootstrap-select [role="listbox"], .bootstrap-select .bs-searchbox input',Y.prototype.keydown).on("focusin.modal",'.bootstrap-select [data-toggle="dropdown"], .bootstrap-select [role="listbox"], .bootstrap-select .bs-searchbox input',function(e){e.stopPropagation()}),z(window).on("load"+j+".data-api",function(){z(".selectpicker").each(function(){var e=z(this);Z.call(e,e.data())})})}(e)});
+//# sourceMappingURL=bootstrap-select.min.js.map
\ No newline at end of file
diff --git a/plexpy/graphs.py b/plexpy/graphs.py
index 49dfee57..58a199c0 100644
--- a/plexpy/graphs.py
+++ b/plexpy/graphs.py
@@ -51,11 +51,7 @@ class Graphs(object):
time_range = helpers.cast_to_int(time_range) or 30
timestamp = helpers.timestamp() - time_range * 24 * 60 * 60
- user_cond = ''
- if session.get_session_user_id() and user_id and user_id != str(session.get_session_user_id()):
- user_cond = 'AND session_history.user_id = %s ' % session.get_session_user_id()
- elif user_id and user_id.isdigit():
- user_cond = 'AND session_history.user_id = %s ' % user_id
+ user_cond = self._make_user_cond(user_id)
if grouping is None:
grouping = plexpy.CONFIG.GROUP_HISTORY_TABLES
@@ -171,11 +167,7 @@ class Graphs(object):
time_range = helpers.cast_to_int(time_range) or 30
timestamp = helpers.timestamp() - time_range * 24 * 60 * 60
- user_cond = ''
- if session.get_session_user_id() and user_id and user_id != str(session.get_session_user_id()):
- user_cond = "AND session_history.user_id = %s " % session.get_session_user_id()
- elif user_id and user_id.isdigit():
- user_cond = "AND session_history.user_id = %s " % user_id
+ user_cond = self._make_user_cond(user_id)
if grouping is None:
grouping = plexpy.CONFIG.GROUP_HISTORY_TABLES
@@ -308,11 +300,7 @@ class Graphs(object):
time_range = helpers.cast_to_int(time_range) or 30
timestamp = helpers.timestamp() - time_range * 24 * 60 * 60
- user_cond = ''
- if session.get_session_user_id() and user_id and user_id != str(session.get_session_user_id()):
- user_cond = 'AND session_history.user_id = %s ' % session.get_session_user_id()
- elif user_id and user_id.isdigit():
- user_cond = 'AND session_history.user_id = %s ' % user_id
+ user_cond = self._make_user_cond(user_id)
if grouping is None:
grouping = plexpy.CONFIG.GROUP_HISTORY_TABLES
@@ -427,11 +415,7 @@ class Graphs(object):
time_range = helpers.cast_to_int(time_range) or 12
timestamp = arrow.get(helpers.timestamp()).shift(months=-time_range).floor('month').timestamp()
- user_cond = ''
- if session.get_session_user_id() and user_id and user_id != str(session.get_session_user_id()):
- user_cond = 'AND session_history.user_id = %s ' % session.get_session_user_id()
- elif user_id and user_id.isdigit():
- user_cond = 'AND session_history.user_id = %s ' % user_id
+ user_cond = self._make_user_cond(user_id)
if grouping is None:
grouping = plexpy.CONFIG.GROUP_HISTORY_TABLES
@@ -554,11 +538,7 @@ class Graphs(object):
time_range = helpers.cast_to_int(time_range) or 30
timestamp = helpers.timestamp() - time_range * 24 * 60 * 60
- user_cond = ''
- if session.get_session_user_id() and user_id and user_id != str(session.get_session_user_id()):
- user_cond = 'AND session_history.user_id = %s ' % session.get_session_user_id()
- elif user_id and user_id.isdigit():
- user_cond = 'AND session_history.user_id = %s ' % user_id
+ user_cond = self._make_user_cond(user_id)
if grouping is None:
grouping = plexpy.CONFIG.GROUP_HISTORY_TABLES
@@ -653,11 +633,7 @@ class Graphs(object):
time_range = helpers.cast_to_int(time_range) or 30
timestamp = helpers.timestamp() - time_range * 24 * 60 * 60
- user_cond = ''
- if session.get_session_user_id() and user_id and user_id != str(session.get_session_user_id()):
- user_cond = 'AND session_history.user_id = %s ' % session.get_session_user_id()
- elif user_id and user_id.isdigit():
- user_cond = 'AND session_history.user_id = %s ' % user_id
+ user_cond = self._make_user_cond(user_id)
if grouping is None:
grouping = plexpy.CONFIG.GROUP_HISTORY_TABLES
@@ -763,11 +739,7 @@ class Graphs(object):
time_range = helpers.cast_to_int(time_range) or 30
timestamp = helpers.timestamp() - time_range * 24 * 60 * 60
- user_cond = ''
- if session.get_session_user_id() and user_id and user_id != str(session.get_session_user_id()):
- user_cond = 'AND session_history.user_id = %s ' % session.get_session_user_id()
- elif user_id and user_id.isdigit():
- user_cond = 'AND session_history.user_id = %s ' % user_id
+ user_cond = self._make_user_cond(user_id)
if grouping is None:
grouping = plexpy.CONFIG.GROUP_HISTORY_TABLES
@@ -860,11 +832,7 @@ class Graphs(object):
time_range = helpers.cast_to_int(time_range) or 30
timestamp = helpers.timestamp() - time_range * 24 * 60 * 60
- user_cond = ''
- if session.get_session_user_id() and user_id and user_id != str(session.get_session_user_id()):
- user_cond = 'AND session_history.user_id = %s ' % session.get_session_user_id()
- elif user_id and user_id.isdigit():
- user_cond = 'AND session_history.user_id = %s ' % user_id
+ user_cond = self._make_user_cond(user_id)
if grouping is None:
grouping = plexpy.CONFIG.GROUP_HISTORY_TABLES
@@ -941,11 +909,7 @@ class Graphs(object):
time_range = helpers.cast_to_int(time_range) or 30
timestamp = helpers.timestamp() - time_range * 24 * 60 * 60
- user_cond = ''
- if session.get_session_user_id() and user_id and user_id != str(session.get_session_user_id()):
- user_cond = 'AND session_history.user_id = %s ' % session.get_session_user_id()
- elif user_id and user_id.isdigit():
- user_cond = 'AND session_history.user_id = %s ' % user_id
+ user_cond = self._make_user_cond(user_id)
if grouping is None:
grouping = plexpy.CONFIG.GROUP_HISTORY_TABLES
@@ -1048,11 +1012,7 @@ class Graphs(object):
time_range = helpers.cast_to_int(time_range) or 30
timestamp = helpers.timestamp() - time_range * 24 * 60 * 60
- user_cond = ''
- if session.get_session_user_id() and user_id and user_id != str(session.get_session_user_id()):
- user_cond = 'AND session_history.user_id = %s ' % session.get_session_user_id()
- elif user_id and user_id.isdigit():
- user_cond = 'AND session_history.user_id = %s ' % user_id
+ user_cond = self._make_user_cond(user_id)
if grouping is None:
grouping = plexpy.CONFIG.GROUP_HISTORY_TABLES
@@ -1128,11 +1088,7 @@ class Graphs(object):
time_range = helpers.cast_to_int(time_range) or 30
timestamp = helpers.timestamp() - time_range * 24 * 60 * 60
- user_cond = ''
- if session.get_session_user_id() and user_id and user_id != str(session.get_session_user_id()):
- user_cond = 'AND session_history.user_id = %s ' % session.get_session_user_id()
- elif user_id and user_id.isdigit():
- user_cond = 'AND session_history.user_id = %s ' % user_id
+ user_cond = self._make_user_cond(user_id)
if grouping is None:
grouping = plexpy.CONFIG.GROUP_HISTORY_TABLES
@@ -1212,3 +1168,16 @@ class Graphs(object):
'series': [series_1_output, series_2_output, series_3_output]}
return output
+
+ def _make_user_cond(self, user_id):
+ """
+ Expects user_id to be a comma-separated list of ints.
+ """
+ user_cond = ''
+ if session.get_session_user_id() and user_id and user_id != str(session.get_session_user_id()):
+ user_cond = 'AND session_history.user_id = %s ' % session.get_session_user_id()
+ elif user_id:
+ user_ids = helpers.split_strip(user_id)
+ if all(id.isdigit() for id in user_ids):
+ user_cond = 'AND session_history.user_id IN (%s) ' % ','.join(user_ids)
+ return user_cond
diff --git a/plexpy/webserve.py b/plexpy/webserve.py
index 06a9a802..7549aefa 100644
--- a/plexpy/webserve.py
+++ b/plexpy/webserve.py
@@ -2258,7 +2258,7 @@ class WebInterface(object):
Optional parameters:
time_range (str): The number of days of data to return
y_axis (str): "plays" or "duration"
- user_id (str): The user id to filter the data
+ user_id (str): Comma separated list of user id to filter the data
grouping (int): 0 or 1
Returns:
@@ -2302,7 +2302,7 @@ class WebInterface(object):
Optional parameters:
time_range (str): The number of days of data to return
y_axis (str): "plays" or "duration"
- user_id (str): The user id to filter the data
+ user_id (str): Comma separated list of user id to filter the data
grouping (int): 0 or 1
Returns:
@@ -2346,7 +2346,7 @@ class WebInterface(object):
Optional parameters:
time_range (str): The number of days of data to return
y_axis (str): "plays" or "duration"
- user_id (str): The user id to filter the data
+ user_id (str): Comma separated list of user id to filter the data
grouping (int): 0 or 1
Returns:
@@ -2390,7 +2390,7 @@ class WebInterface(object):
Optional parameters:
time_range (str): The number of months of data to return
y_axis (str): "plays" or "duration"
- user_id (str): The user id to filter the data
+ user_id (str): Comma separated list of user id to filter the data
grouping (int): 0 or 1
Returns:
@@ -2434,7 +2434,7 @@ class WebInterface(object):
Optional parameters:
time_range (str): The number of days of data to return
y_axis (str): "plays" or "duration"
- user_id (str): The user id to filter the data
+ user_id (str): Comma separated list of user id to filter the data
grouping (int): 0 or 1
Returns:
@@ -2478,7 +2478,7 @@ class WebInterface(object):
Optional parameters:
time_range (str): The number of days of data to return
y_axis (str): "plays" or "duration"
- user_id (str): The user id to filter the data
+ user_id (str): Comma separated list of user id to filter the data
grouping (int): 0 or 1
Returns:
@@ -2522,7 +2522,7 @@ class WebInterface(object):
Optional parameters:
time_range (str): The number of days of data to return
y_axis (str): "plays" or "duration"
- user_id (str): The user id to filter the data
+ user_id (str): Comma separated list of user id to filter the data
grouping (int): 0 or 1
Returns:
@@ -2565,7 +2565,7 @@ class WebInterface(object):
Optional parameters:
time_range (str): The number of days of data to return
y_axis (str): "plays" or "duration"
- user_id (str): The user id to filter the data
+ user_id (str): Comma separated list of user id to filter the data
grouping (int): 0 or 1
Returns:
@@ -2608,7 +2608,7 @@ class WebInterface(object):
Optional parameters:
time_range (str): The number of days of data to return
y_axis (str): "plays" or "duration"
- user_id (str): The user id to filter the data
+ user_id (str): Comma separated list of user id to filter the data
grouping (int): 0 or 1
Returns:
@@ -2651,7 +2651,7 @@ class WebInterface(object):
Optional parameters:
time_range (str): The number of days of data to return
y_axis (str): "plays" or "duration"
- user_id (str): The user id to filter the data
+ user_id (str): Comma separated list of user id to filter the data
grouping (int): 0 or 1
Returns:
@@ -2694,7 +2694,7 @@ class WebInterface(object):
Optional parameters:
time_range (str): The number of days of data to return
y_axis (str): "plays" or "duration"
- user_id (str): The user id to filter the data
+ user_id (str): Comma separated list of user id to filter the data
grouping (int): 0 or 1
Returns: