Add support for total YouTube views (#123144)
* Add support for retrieving the total views of a channel. * Add missing tests * Re-order imports * Another run on code format * Add missing translation * Update YouTube test snapshots
This commit is contained in:
parent
8255728f53
commit
00533bae4b
7 changed files with 61 additions and 1 deletions
|
@ -15,6 +15,7 @@ AUTH = "auth"
|
|||
LOGGER = logging.getLogger(__package__)
|
||||
|
||||
ATTR_TITLE = "title"
|
||||
ATTR_TOTAL_VIEWS = "total_views"
|
||||
ATTR_LATEST_VIDEO = "latest_video"
|
||||
ATTR_SUBSCRIBER_COUNT = "subscriber_count"
|
||||
ATTR_DESCRIPTION = "description"
|
||||
|
|
|
@ -22,6 +22,7 @@ from .const import (
|
|||
ATTR_SUBSCRIBER_COUNT,
|
||||
ATTR_THUMBNAIL,
|
||||
ATTR_TITLE,
|
||||
ATTR_TOTAL_VIEWS,
|
||||
ATTR_VIDEO_ID,
|
||||
CONF_CHANNELS,
|
||||
DOMAIN,
|
||||
|
@ -68,6 +69,7 @@ class YouTubeDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
|||
ATTR_ICON: channel.snippet.thumbnails.get_highest_quality().url,
|
||||
ATTR_LATEST_VIDEO: latest_video,
|
||||
ATTR_SUBSCRIBER_COUNT: channel.statistics.subscriber_count,
|
||||
ATTR_TOTAL_VIEWS: channel.statistics.view_count,
|
||||
}
|
||||
except UnauthorizedError as err:
|
||||
raise ConfigEntryAuthFailed from err
|
||||
|
|
|
@ -20,6 +20,7 @@ from .const import (
|
|||
ATTR_SUBSCRIBER_COUNT,
|
||||
ATTR_THUMBNAIL,
|
||||
ATTR_TITLE,
|
||||
ATTR_TOTAL_VIEWS,
|
||||
ATTR_VIDEO_ID,
|
||||
COORDINATOR,
|
||||
DOMAIN,
|
||||
|
@ -58,6 +59,15 @@ SENSOR_TYPES = [
|
|||
entity_picture_fn=lambda channel: channel[ATTR_ICON],
|
||||
attributes_fn=None,
|
||||
),
|
||||
YouTubeSensorEntityDescription(
|
||||
key="views",
|
||||
translation_key="views",
|
||||
native_unit_of_measurement="views",
|
||||
available_fn=lambda _: True,
|
||||
value_fn=lambda channel: channel[ATTR_TOTAL_VIEWS],
|
||||
entity_picture_fn=lambda channel: channel[ATTR_ICON],
|
||||
attributes_fn=None,
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -46,7 +46,8 @@
|
|||
"published_at": { "name": "Published at" }
|
||||
}
|
||||
},
|
||||
"subscribers": { "name": "Subscribers" }
|
||||
"subscribers": { "name": "Subscribers" },
|
||||
"views": { "name": "Views" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
}),
|
||||
'subscriber_count': 2290000,
|
||||
'title': 'Google for Developers',
|
||||
'total_views': 214141263,
|
||||
}),
|
||||
})
|
||||
# ---
|
||||
|
|
|
@ -30,6 +30,21 @@
|
|||
'state': '2290000',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor.2
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'entity_picture': 'https://yt3.ggpht.com/fca_HuJ99xUxflWdex0XViC3NfctBFreIl8y4i9z411asnGTWY-Ql3MeH_ybA4kNaOjY7kyA=s800-c-k-c0x00ffffff-no-rj',
|
||||
'friendly_name': 'Google for Developers Views',
|
||||
'unit_of_measurement': 'views',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.google_for_developers_views',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '214141263',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor_without_uploaded_video
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
|
@ -58,3 +73,18 @@
|
|||
'state': '2290000',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor_without_uploaded_video.2
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'entity_picture': 'https://yt3.ggpht.com/fca_HuJ99xUxflWdex0XViC3NfctBFreIl8y4i9z411asnGTWY-Ql3MeH_ybA4kNaOjY7kyA=s800-c-k-c0x00ffffff-no-rj',
|
||||
'friendly_name': 'Google for Developers Views',
|
||||
'unit_of_measurement': 'views',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.google_for_developers_views',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '214141263',
|
||||
})
|
||||
# ---
|
||||
|
|
|
@ -29,6 +29,9 @@ async def test_sensor(
|
|||
state = hass.states.get("sensor.google_for_developers_subscribers")
|
||||
assert state == snapshot
|
||||
|
||||
state = hass.states.get("sensor.google_for_developers_views")
|
||||
assert state == snapshot
|
||||
|
||||
|
||||
async def test_sensor_without_uploaded_video(
|
||||
hass: HomeAssistant, snapshot: SnapshotAssertion, setup_integration: ComponentSetup
|
||||
|
@ -52,6 +55,9 @@ async def test_sensor_without_uploaded_video(
|
|||
state = hass.states.get("sensor.google_for_developers_subscribers")
|
||||
assert state == snapshot
|
||||
|
||||
state = hass.states.get("sensor.google_for_developers_views")
|
||||
assert state == snapshot
|
||||
|
||||
|
||||
async def test_sensor_updating(
|
||||
hass: HomeAssistant, setup_integration: ComponentSetup
|
||||
|
@ -95,6 +101,9 @@ async def test_sensor_reauth_trigger(
|
|||
state = hass.states.get("sensor.google_for_developers_subscribers")
|
||||
assert state.state == "2290000"
|
||||
|
||||
state = hass.states.get("sensor.google_for_developers_views")
|
||||
assert state.state == "214141263"
|
||||
|
||||
mock.set_thrown_exception(UnauthorizedError())
|
||||
future = dt_util.utcnow() + timedelta(minutes=15)
|
||||
async_fire_time_changed(hass, future)
|
||||
|
@ -121,6 +130,9 @@ async def test_sensor_unavailable(
|
|||
state = hass.states.get("sensor.google_for_developers_subscribers")
|
||||
assert state.state == "2290000"
|
||||
|
||||
state = hass.states.get("sensor.google_for_developers_views")
|
||||
assert state.state == "214141263"
|
||||
|
||||
mock.set_thrown_exception(YouTubeBackendError())
|
||||
future = dt_util.utcnow() + timedelta(minutes=15)
|
||||
async_fire_time_changed(hass, future)
|
||||
|
@ -131,3 +143,6 @@ async def test_sensor_unavailable(
|
|||
|
||||
state = hass.states.get("sensor.google_for_developers_subscribers")
|
||||
assert state.state == "unavailable"
|
||||
|
||||
state = hass.states.get("sensor.google_for_developers_views")
|
||||
assert state.state == "unavailable"
|
||||
|
|
Loading…
Add table
Reference in a new issue