예제 #1
0
파일: tautulli.py 프로젝트: tkuennen/Varken
    def get_activity(self):
        self.now = datetime.now(timezone.utc).astimezone().isoformat()
        influx_payload = []

        req = self.session.prepare_request(Request('GET', self.server.url + self.endpoint))
        g = connection_handler(self.session, req, self.server.verify_ssl)

        if not g:
            return

        get = g['response']['data']

        try:
            sessions = [TautulliStream(**session) for session in get['sessions']]
        except TypeError as e:
            self.logger.error('TypeError has occurred : %s while creating TautulliStream structure', e)
            return

        for session in sessions:
            try:
                geodata = geo_lookup(session.ip_address_public)
            except (ValueError, AddressNotFoundError):
                if self.server.fallback_ip:
                    geodata = geo_lookup(self.server.fallback_ip)
                else:
                    my_ip = self.session.get('http://ip.42.pl/raw').text
                    geodata = geo_lookup(my_ip)

            if not all([geodata.location.latitude, geodata.location.longitude]):
                latitude = 37.234332396
                longitude = -115.80666344
            else:
                latitude = geodata.location.latitude
                longitude = geodata.location.longitude

            decision = session.transcode_decision
            if decision == 'copy':
                decision = 'direct stream'

            video_decision = session.stream_video_decision
            if video_decision == 'copy':
                video_decision = 'direct stream'
            elif video_decision == '':
                video_decision = 'Music'

            quality = session.stream_video_resolution
            if not quality:
                quality = session.container.upper()
            elif quality in ('SD', 'sd', '4k'):
                quality = session.stream_video_resolution.upper()
            else:
                quality = session.stream_video_resolution + 'p'

            player_state = session.state.lower()
            if player_state == 'playing':
                player_state = 0
            elif player_state == 'paused':
                player_state = 1
            elif player_state == 'buffering':
                player_state = 3

            product_version = session.product_version
            if session.platform == 'Roku':
                product_version = session.product_version.split('-')[0]

            hash_id = hashit('{}{}{}{}'.format(session.session_id, session.session_key, session.username,
                                               session.full_title))
            influx_payload.append(
                {
                    "measurement": "Tautulli",
                    "tags": {
                        "type": "Session",
                        "session_id": session.session_id,
                        "friendly_name": session.friendly_name,
                        "username": session.username,
                        "title": session.full_title,
                        "platform": session.platform,
                        "product_version": product_version,
                        "quality": quality,
                        "video_decision": video_decision.title(),
                        "transcode_decision": decision.title(),
                        "media_type": session.media_type.title(),
                        "audio_codec": session.audio_codec.upper(),
                        "audio_profile": session.audio_profile.upper(),
                        "stream_audio_codec": session.stream_audio_codec.upper(),
                        "quality_profile": session.quality_profile,
                        "progress_percent": session.progress_percent,
                        "region_code": geodata.subdivisions.most_specific.iso_code,
                        "location": geodata.city.name,
                        "full_location": '{} - {}'.format(geodata.subdivisions.most_specific.name,
                                                          geodata.city.name),
                        "latitude": latitude,
                        "longitude": longitude,
                        "player_state": player_state,
                        "device_type": session.platform,
                        "server": self.server.id
                    },
                    "time": self.now,
                    "fields": {
                        "hash": hash_id
                    }
                }
            )

        influx_payload.append(
            {
                "measurement": "Tautulli",
                "tags": {
                    "type": "current_stream_stats",
                    "server": self.server.id
                },
                "time": self.now,
                "fields": {
                    "stream_count": int(get['stream_count']),
                    "total_bandwidth": int(get['total_bandwidth']),
                    "wan_bandwidth": int(get['wan_bandwidth']),
                    "lan_bandwidth": int(get['lan_bandwidth']),
                    "transcode_streams": int(get['stream_count_transcode']),
                    "direct_play_streams": int(get['stream_count_direct_play']),
                    "direct_streams": int(get['stream_count_direct_stream'])
                }
            }
        )

        self.dbmanager.write_points(influx_payload)
예제 #2
0
파일: tautulli.py 프로젝트: arnesweb/Varken
    def get_activity(self):
        now = datetime.now(timezone.utc).astimezone().isoformat()
        influx_payload = []
        params = {'cmd': 'get_activity'}

        req = self.session.prepare_request(
            Request('GET', self.server.url + self.endpoint, params=params))
        g = connection_handler(self.session, req, self.server.verify_ssl)

        if not g:
            return

        get = g['response']['data']

        # Remove erroneous key from sessions
        for session in get['sessions']:
            if session.get('_cache_time'):
                del session['_cache_time']

        try:
            sessions = [
                TautulliStream(**session) for session in get['sessions']
            ]
        except TypeError as e:
            self.logger.error(
                'TypeError has occurred : %s while creating TautulliStream structure',
                e)
            return

        for session in sessions:
            # Check to see if ip_address_public attribute exists as it was introduced in v2
            try:
                getattr(session, 'ip_address_public')
            except AttributeError:
                self.logger.error(
                    'Public IP attribute missing!!! Do you have an old version of Tautulli (v1)?'
                )
                exit(1)

            try:
                geodata = self.geoiphandler.lookup(session.ip_address_public)
            except (ValueError, AddressNotFoundError):
                self.logger.debug('Public IP missing for Tautulli session...')
                if not self.my_ip:
                    # Try the fallback ip in the config file
                    try:
                        self.logger.debug(
                            'Atempting to use the failback IP...')
                        geodata = self.geoiphandler.lookup(
                            self.server.fallback_ip)
                    except AddressNotFoundError as e:
                        self.logger.error('%s', e)

                        self.my_ip = self.session.get(
                            'http://ip.42.pl/raw').text
                        self.logger.debug(
                            'Looked the public IP and set it to %s',
                            self.my_ip)

                        geodata = self.geoiphandler.lookup(self.my_ip)

                else:
                    geodata = self.geoiphandler.lookup(self.my_ip)

            if not all([geodata.location.latitude, geodata.location.longitude
                        ]):
                latitude = 37.234332396
                longitude = -115.80666344
            else:
                latitude = geodata.location.latitude
                longitude = geodata.location.longitude

            decision = session.transcode_decision
            if decision == 'copy':
                decision = 'direct stream'

            video_decision = session.stream_video_decision
            if video_decision == 'copy':
                video_decision = 'direct stream'
            elif video_decision == '':
                video_decision = 'Music'

            quality = session.stream_video_resolution
            if not quality:
                quality = session.container.upper()
            elif quality in ('SD', 'sd', '4k'):
                quality = session.stream_video_resolution.upper()
            else:
                quality = session.stream_video_resolution + 'p'

            player_state = session.state.lower()
            if player_state == 'playing':
                player_state = 0
            elif player_state == 'paused':
                player_state = 1
            elif player_state == 'buffering':
                player_state = 3

            product_version = session.product_version
            if session.platform == 'Roku':
                product_version = session.product_version.split('-')[0]

            hash_id = hashit(
                f'{session.session_id}{session.session_key}{session.username}{session.full_title}'
            )
            influx_payload.append({
                "measurement": "Tautulli",
                "tags": {
                    "type": "Session",
                    "session_id": session.session_id,
                    "friendly_name": session.friendly_name,
                    "username": session.username,
                    "title": session.full_title,
                    "platform": session.platform,
                    "product_version": product_version,
                    "quality": quality,
                    "video_decision": video_decision.title(),
                    "transcode_decision": decision.title(),
                    "transcode_hw_decoding": session.transcode_hw_decoding,
                    "transcode_hw_encoding": session.transcode_hw_encoding,
                    "media_type": session.media_type.title(),
                    "audio_codec": session.audio_codec.upper(),
                    "audio_profile": session.audio_profile.upper(),
                    "stream_audio_codec": session.stream_audio_codec.upper(),
                    "quality_profile": session.quality_profile,
                    "progress_percent": session.progress_percent,
                    "region_code": geodata.subdivisions.most_specific.iso_code,
                    "location": geodata.city.name,
                    "full_location":
                    f'{geodata.subdivisions.most_specific.name} - {geodata.city.name}',
                    "latitude": latitude,
                    "longitude": longitude,
                    "player_state": player_state,
                    "device_type": session.platform,
                    "server": self.server.id
                },
                "time": now,
                "fields": {
                    "hash": hash_id
                }
            })

        influx_payload.append({
            "measurement": "Tautulli",
            "tags": {
                "type": "current_stream_stats",
                "server": self.server.id
            },
            "time": now,
            "fields": {
                "stream_count": int(get['stream_count']),
                "total_bandwidth": int(get['total_bandwidth']),
                "wan_bandwidth": int(get['wan_bandwidth']),
                "lan_bandwidth": int(get['lan_bandwidth']),
                "transcode_streams": int(get['stream_count_transcode']),
                "direct_play_streams": int(get['stream_count_direct_play']),
                "direct_streams": int(get['stream_count_direct_stream'])
            }
        })

        self.dbmanager.write_points(influx_payload)
예제 #3
0
    def get_historical(self, days=30):
        influx_payload = []
        start_date = date.today() - timedelta(days=days)
        params = {'cmd': 'get_history', 'grouping': 1, 'length': 1000000}
        req = self.session.prepare_request(
            Request('GET', self.server.url + self.endpoint, params=params))
        g = connection_handler(self.session, req, self.server.verify_ssl)

        if not g:
            return

        get = g['response']['data']['data']

        params = {'cmd': 'get_stream_data', 'row_id': 0}
        sessions = []
        for history_item in get:
            if not history_item['id']:
                self.logger.debug('Skipping entry with no ID. (%s)',
                                  history_item['full_title'])
                continue
            if date.fromtimestamp(history_item['started']) < start_date:
                continue
            params['row_id'] = history_item['id']
            req = self.session.prepare_request(
                Request('GET', self.server.url + self.endpoint, params=params))
            g = connection_handler(self.session, req, self.server.verify_ssl)
            if not g:
                self.logger.debug(
                    'Could not get historical stream data for %s. Skipping.',
                    history_item['full_title'])
            try:
                self.logger.debug('Adding %s to history',
                                  history_item['full_title'])
                history_item.update(g['response']['data'])
                sessions.append(TautulliStream(**history_item))
            except TypeError as e:
                self.logger.error(
                    'TypeError has occurred : %s while creating TautulliStream structure',
                    e)
                continue

        for session in sessions:
            try:
                geodata = self.geoiphandler.lookup(session.ip_address)
            except (ValueError, AddressNotFoundError):
                self.logger.debug('Public IP missing for Tautulli session...')
                if not self.my_ip:
                    # Try the fallback ip in the config file
                    try:
                        self.logger.debug(
                            'Attempting to use the fallback IP...')
                        geodata = self.geoiphandler.lookup(
                            self.server.fallback_ip)
                    except AddressNotFoundError as e:
                        self.logger.error('%s', e)

                        self.my_ip = self.session.get(
                            'http://ip.42.pl/raw').text
                        self.logger.debug(
                            'Looked the public IP and set it to %s',
                            self.my_ip)

                        geodata = self.geoiphandler.lookup(self.my_ip)

                else:
                    geodata = self.geoiphandler.lookup(self.my_ip)

            if not all([geodata.location.latitude, geodata.location.longitude
                        ]):
                latitude = 37.234332396
                longitude = -115.80666344
            else:
                latitude = geodata.location.latitude
                longitude = geodata.location.longitude

            if not geodata.city.name:
                location = '👽'
            else:
                location = geodata.city.name

            decision = session.transcode_decision
            if decision == 'copy':
                decision = 'direct stream'

            video_decision = session.stream_video_decision
            if video_decision == 'copy':
                video_decision = 'direct stream'
            elif video_decision == '':
                video_decision = 'Music'

            quality = session.stream_video_resolution
            if not quality:
                quality = session.container.upper()
            elif quality in ('SD', 'sd', '4k'):
                quality = session.stream_video_resolution.upper()
            elif session.stream_video_full_resolution:
                quality = session.stream_video_full_resolution
            else:
                quality = session.stream_video_resolution + 'p'

            # Platform Overrides
            platform_name = session.platform
            if platform_name in 'osx':
                platform_name = 'Plex Mac OS'
            if platform_name in 'windows':
                platform_name = 'Plex Windows'

            player_state = 100

            hash_id = hashit(
                f'{session.id}{session.session_key}{session.user}{session.full_title}'
            )
            influx_payload.append({
                "measurement":
                "Tautulli",
                "tags": {
                    "type": "Session",
                    "session_id": session.session_id,
                    "friendly_name": session.friendly_name,
                    "username": session.user,
                    "title": session.full_title,
                    "product": session.product,
                    "platform": platform_name,
                    "quality": quality,
                    "video_decision": video_decision.title(),
                    "transcode_decision": decision.title(),
                    "transcode_hw_decoding": session.transcode_hw_decoding,
                    "transcode_hw_encoding": session.transcode_hw_encoding,
                    "media_type": session.media_type.title(),
                    "audio_codec": session.audio_codec.upper(),
                    "stream_audio_codec": session.stream_audio_codec.upper(),
                    "quality_profile": session.quality_profile,
                    "progress_percent": session.progress_percent,
                    "region_code": geodata.subdivisions.most_specific.iso_code,
                    "location": location,
                    "full_location":
                    f'{geodata.subdivisions.most_specific.name} - {geodata.city.name}',
                    "latitude": latitude,
                    "longitude": longitude,
                    "player_state": player_state,
                    "device_type": platform_name,
                    "relayed": session.relayed,
                    "secure": session.secure,
                    "server": self.server.id
                },
                "time":
                datetime.fromtimestamp(
                    session.stopped).astimezone().isoformat(),
                "fields": {
                    "hash": hash_id
                }
            })
            try:
                self.dbmanager.write_points(influx_payload)
            except InfluxDBClientError as e:
                if "beyond retention policy" in str(e):
                    self.logger.debug(
                        'Only imported 30 days of data per retention policy')
                else:
                    self.logger.error(
                        'Something went wrong... post this output in discord: %s',
                        e)