mirror of
https://github.com/home-assistant/core.git
synced 2025-07-13 08:17:08 +00:00
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
@ -15,6 +15,7 @@ AUTH = "auth"
|
|||||||
LOGGER = logging.getLogger(__package__)
|
LOGGER = logging.getLogger(__package__)
|
||||||
|
|
||||||
ATTR_TITLE = "title"
|
ATTR_TITLE = "title"
|
||||||
|
ATTR_TOTAL_VIEWS = "total_views"
|
||||||
ATTR_LATEST_VIDEO = "latest_video"
|
ATTR_LATEST_VIDEO = "latest_video"
|
||||||
ATTR_SUBSCRIBER_COUNT = "subscriber_count"
|
ATTR_SUBSCRIBER_COUNT = "subscriber_count"
|
||||||
ATTR_DESCRIPTION = "description"
|
ATTR_DESCRIPTION = "description"
|
||||||
|
@ -22,6 +22,7 @@ from .const import (
|
|||||||
ATTR_SUBSCRIBER_COUNT,
|
ATTR_SUBSCRIBER_COUNT,
|
||||||
ATTR_THUMBNAIL,
|
ATTR_THUMBNAIL,
|
||||||
ATTR_TITLE,
|
ATTR_TITLE,
|
||||||
|
ATTR_TOTAL_VIEWS,
|
||||||
ATTR_VIDEO_ID,
|
ATTR_VIDEO_ID,
|
||||||
CONF_CHANNELS,
|
CONF_CHANNELS,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
@ -68,6 +69,7 @@ class YouTubeDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
|||||||
ATTR_ICON: channel.snippet.thumbnails.get_highest_quality().url,
|
ATTR_ICON: channel.snippet.thumbnails.get_highest_quality().url,
|
||||||
ATTR_LATEST_VIDEO: latest_video,
|
ATTR_LATEST_VIDEO: latest_video,
|
||||||
ATTR_SUBSCRIBER_COUNT: channel.statistics.subscriber_count,
|
ATTR_SUBSCRIBER_COUNT: channel.statistics.subscriber_count,
|
||||||
|
ATTR_TOTAL_VIEWS: channel.statistics.view_count,
|
||||||
}
|
}
|
||||||
except UnauthorizedError as err:
|
except UnauthorizedError as err:
|
||||||
raise ConfigEntryAuthFailed from err
|
raise ConfigEntryAuthFailed from err
|
||||||
|
@ -20,6 +20,7 @@ from .const import (
|
|||||||
ATTR_SUBSCRIBER_COUNT,
|
ATTR_SUBSCRIBER_COUNT,
|
||||||
ATTR_THUMBNAIL,
|
ATTR_THUMBNAIL,
|
||||||
ATTR_TITLE,
|
ATTR_TITLE,
|
||||||
|
ATTR_TOTAL_VIEWS,
|
||||||
ATTR_VIDEO_ID,
|
ATTR_VIDEO_ID,
|
||||||
COORDINATOR,
|
COORDINATOR,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
@ -58,6 +59,15 @@ SENSOR_TYPES = [
|
|||||||
entity_picture_fn=lambda channel: channel[ATTR_ICON],
|
entity_picture_fn=lambda channel: channel[ATTR_ICON],
|
||||||
attributes_fn=None,
|
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" }
|
"published_at": { "name": "Published at" }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"subscribers": { "name": "Subscribers" }
|
"subscribers": { "name": "Subscribers" },
|
||||||
|
"views": { "name": "Views" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
}),
|
}),
|
||||||
'subscriber_count': 2290000,
|
'subscriber_count': 2290000,
|
||||||
'title': 'Google for Developers',
|
'title': 'Google for Developers',
|
||||||
|
'total_views': 214141263,
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
# ---
|
# ---
|
||||||
|
@ -30,6 +30,21 @@
|
|||||||
'state': '2290000',
|
'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
|
# name: test_sensor_without_uploaded_video
|
||||||
StateSnapshot({
|
StateSnapshot({
|
||||||
'attributes': ReadOnlyDict({
|
'attributes': ReadOnlyDict({
|
||||||
@ -58,3 +73,18 @@
|
|||||||
'state': '2290000',
|
'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")
|
state = hass.states.get("sensor.google_for_developers_subscribers")
|
||||||
assert state == snapshot
|
assert state == snapshot
|
||||||
|
|
||||||
|
state = hass.states.get("sensor.google_for_developers_views")
|
||||||
|
assert state == snapshot
|
||||||
|
|
||||||
|
|
||||||
async def test_sensor_without_uploaded_video(
|
async def test_sensor_without_uploaded_video(
|
||||||
hass: HomeAssistant, snapshot: SnapshotAssertion, setup_integration: ComponentSetup
|
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")
|
state = hass.states.get("sensor.google_for_developers_subscribers")
|
||||||
assert state == snapshot
|
assert state == snapshot
|
||||||
|
|
||||||
|
state = hass.states.get("sensor.google_for_developers_views")
|
||||||
|
assert state == snapshot
|
||||||
|
|
||||||
|
|
||||||
async def test_sensor_updating(
|
async def test_sensor_updating(
|
||||||
hass: HomeAssistant, setup_integration: ComponentSetup
|
hass: HomeAssistant, setup_integration: ComponentSetup
|
||||||
@ -95,6 +101,9 @@ async def test_sensor_reauth_trigger(
|
|||||||
state = hass.states.get("sensor.google_for_developers_subscribers")
|
state = hass.states.get("sensor.google_for_developers_subscribers")
|
||||||
assert state.state == "2290000"
|
assert state.state == "2290000"
|
||||||
|
|
||||||
|
state = hass.states.get("sensor.google_for_developers_views")
|
||||||
|
assert state.state == "214141263"
|
||||||
|
|
||||||
mock.set_thrown_exception(UnauthorizedError())
|
mock.set_thrown_exception(UnauthorizedError())
|
||||||
future = dt_util.utcnow() + timedelta(minutes=15)
|
future = dt_util.utcnow() + timedelta(minutes=15)
|
||||||
async_fire_time_changed(hass, future)
|
async_fire_time_changed(hass, future)
|
||||||
@ -121,6 +130,9 @@ async def test_sensor_unavailable(
|
|||||||
state = hass.states.get("sensor.google_for_developers_subscribers")
|
state = hass.states.get("sensor.google_for_developers_subscribers")
|
||||||
assert state.state == "2290000"
|
assert state.state == "2290000"
|
||||||
|
|
||||||
|
state = hass.states.get("sensor.google_for_developers_views")
|
||||||
|
assert state.state == "214141263"
|
||||||
|
|
||||||
mock.set_thrown_exception(YouTubeBackendError())
|
mock.set_thrown_exception(YouTubeBackendError())
|
||||||
future = dt_util.utcnow() + timedelta(minutes=15)
|
future = dt_util.utcnow() + timedelta(minutes=15)
|
||||||
async_fire_time_changed(hass, future)
|
async_fire_time_changed(hass, future)
|
||||||
@ -131,3 +143,6 @@ async def test_sensor_unavailable(
|
|||||||
|
|
||||||
state = hass.states.get("sensor.google_for_developers_subscribers")
|
state = hass.states.get("sensor.google_for_developers_subscribers")
|
||||||
assert state.state == "unavailable"
|
assert state.state == "unavailable"
|
||||||
|
|
||||||
|
state = hass.states.get("sensor.google_for_developers_views")
|
||||||
|
assert state.state == "unavailable"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user