diff --git a/scraper/src/youtube2zim/playlists/scraper.py b/scraper/src/youtube2zim/playlists/scraper.py
index 0f5a1dda..c3301bd6 100644
--- a/scraper/src/youtube2zim/playlists/scraper.py
+++ b/scraper/src/youtube2zim/playlists/scraper.py
@@ -91,7 +91,6 @@ def run(self):
(
playlists,
main_channel_id,
- uploads_playlist_id,
user_long_uploads_playlist_id,
user_short_uploads_playlist_id,
user_lives_playlist_id,
@@ -109,10 +108,6 @@ def run(self):
shutil.rmtree(self.build_dir, ignore_errors=True)
for playlist in playlists:
- if playlist.playlist_id == uploads_playlist_id:
- logger.info(f"Skipping playlist {playlist.playlist_id} (uploads one)")
- continue
-
logger.info(f"Executing youtube2zim for playlist {playlist.playlist_id}")
success, process = self.run_playlist_zim(playlist)
if success:
diff --git a/scraper/src/youtube2zim/schemas.py b/scraper/src/youtube2zim/schemas.py
index 89696659..edba89c0 100644
--- a/scraper/src/youtube2zim/schemas.py
+++ b/scraper/src/youtube2zim/schemas.py
@@ -105,7 +105,7 @@ class Channel(CamelModel):
profile_path: str | None = None
banner_path: str | None = None
joined_date: str
- main_playlist: str | None = None
+ first_playlist: str | None = None
user_long_uploads_playlist: str | None = None
user_short_uploads_playlist: str | None = None
user_lives_playlist: str | None = None
diff --git a/scraper/src/youtube2zim/scraper.py b/scraper/src/youtube2zim/scraper.py
index 7307772b..3a036971 100644
--- a/scraper/src/youtube2zim/scraper.py
+++ b/scraper/src/youtube2zim/scraper.py
@@ -170,7 +170,6 @@ def __init__(
# process-related
self.playlists = []
- self.uploads_playlist_id = None
self.user_long_uploads_playlist_id = None
self.user_short_uploads_playlist_id = None
self.user_lives_playlist_id = None
@@ -232,30 +231,6 @@ def banner_path(self):
def is_single_channel(self):
return len({pl.creator_id for pl in self.playlists}) == 1
- @property
- def sorted_playlists(self):
- """sorted list of playlists (by title) but with Uploads one at first if any"""
- if len(self.playlists) <= 1:
- return self.playlists
-
- sorted_playlists = sorted(self.playlists, key=lambda x: x.title)
- index = 0
- # make sure our Uploads, special playlist is first
- if self.uploads_playlist_id:
- try:
- index = [
- index
- for index, p in enumerate(sorted_playlists)
- if p.playlist_id == self.uploads_playlist_id
- ][-1]
- except Exception:
- index = 0
- return (
- [sorted_playlists[index]]
- + sorted_playlists[0:index]
- + sorted_playlists[index + 1 :]
- )
-
def run(self):
"""execute the scraper step by step"""
@@ -555,7 +530,6 @@ def extract_playlists(self):
(
self.playlists,
self.main_channel_id,
- self.uploads_playlist_id,
self.user_long_uploads_playlist_id,
self.user_short_uploads_playlist_id,
self.user_lives_playlist_id,
@@ -1158,10 +1132,9 @@ def get_playlist_slug(playlist) -> str:
)
# write playlists JSON files
- playlist_list = []
- home_playlist_list = []
+ playlist_list: list[PlaylistPreview] = []
+ home_playlist_list: list[Playlist] = []
- main_playlist_slug = None
user_long_uploads_playlist_slug = None
user_short_uploads_playlist_slug = None
user_lives_playlist_slug = None
@@ -1178,18 +1151,6 @@ def get_playlist_slug(playlist) -> str:
if len(self.playlists) == 0:
raise Exception("No playlist succeeded to download")
- main_playlist_slug = get_playlist_slug(
- self.playlists[0]
- ) # set first playlist as main playlist
-
- # Initialize placeholders for special playlists
- special_playlists: dict[str, dict[str, PlaylistPreview | Playlist]] = {
- "user_long_uploads_playlist": {},
- "user_short_uploads_playlist": {},
- "user_lives_playlist": {},
- }
- main_playlist = None
-
for playlist in self.playlists:
playlist_slug = get_playlist_slug(playlist)
playlist_path = f"playlists/{playlist_slug}.json"
@@ -1214,59 +1175,15 @@ def get_playlist_slug(playlist) -> str:
# modify playlist object for preview on homepage
playlist_obj.videos = playlist_obj.videos[:12]
+ home_playlist_list.append(playlist_obj)
if playlist.playlist_id == self.user_long_uploads_playlist_id:
user_long_uploads_playlist_slug = playlist_slug
- special_playlists["user_long_uploads_playlist"] = {
- "preview": generate_playlist_preview_object(playlist),
- "full": playlist_obj,
- }
-
elif playlist.playlist_id == self.user_short_uploads_playlist_id:
user_short_uploads_playlist_slug = playlist_slug
- special_playlists["user_short_uploads_playlist"] = {
- "preview": generate_playlist_preview_object(playlist),
- "full": playlist_obj,
- }
-
elif playlist.playlist_id == self.user_lives_playlist_id:
user_lives_playlist_slug = playlist_slug
- special_playlists["user_lives_playlist"] = {
- "preview": generate_playlist_preview_object(playlist),
- "full": playlist_obj,
- }
-
- elif playlist.playlist_id == self.uploads_playlist_id:
- main_playlist = playlist
- main_playlist_slug = (
- playlist_slug # set uploads playlist as main playlist
- )
- # insert uploads playlist at the beginning of the list
- home_playlist_list.insert(0, playlist_obj)
else:
playlist_list.append(generate_playlist_preview_object(playlist))
- home_playlist_list.append(playlist_obj)
-
- # Check if only one special playlist exists
- special_playlist_count = sum(
- 1 for k in special_playlists if special_playlists[k]
- )
-
- if special_playlist_count == 1:
- if main_playlist is not None:
- self.playlists.remove(main_playlist)
- for key in special_playlists:
- if special_playlists[key]:
- main_playlist_slug = special_playlists[key]["preview"].slug
- home_playlist_list[0] = special_playlists[key]["full"]
- else:
- # Insert special playlists in the desired order
- for key in [
- "user_lives_playlist",
- "user_short_uploads_playlist",
- "user_long_uploads_playlist",
- ]:
- if special_playlists[key]:
- home_playlist_list.insert(1, special_playlists[key]["full"])
# write playlists.json file
self.zim_file.add_item_for(
@@ -1303,7 +1220,7 @@ def get_playlist_slug(playlist) -> str:
channel_description=channel_data["snippet"]["description"],
profile_path="profile.jpg",
banner_path="banner.jpg",
- main_playlist=main_playlist_slug,
+ first_playlist=playlist_list[0].id,
user_long_uploads_playlist=user_long_uploads_playlist_slug,
user_short_uploads_playlist=user_short_uploads_playlist_slug,
user_lives_playlist=user_lives_playlist_slug,
diff --git a/scraper/src/youtube2zim/youtube.py b/scraper/src/youtube2zim/youtube.py
index 33294143..9f7ede30 100644
--- a/scraper/src/youtube2zim/youtube.py
+++ b/scraper/src/youtube2zim/youtube.py
@@ -343,8 +343,9 @@ def skip_outofrange_videos(date_range, item):
def extract_playlists_details_from(youtube_id: str):
"""prepare a list of Playlist from user request"""
- uploads_playlist_id = None
- main_channel_id = None
+ main_channel_id = user_long_uploads_playlist_id = user_short_uploads_playlist_id = (
+ user_lives_playlist_id
+ ) = None
if "," not in youtube_id:
try:
# first try to consider passed ID is a channel ID (or username or handle)
@@ -369,21 +370,21 @@ def extract_playlists_details_from(youtube_id: str):
)
user_lives_playlist_id = user_lives_json["id"] if user_lives_json else None
- # Add special playlists if they exists
- playlist_ids += filter(
- None,
- [
- user_long_uploads_playlist_id,
- user_short_uploads_playlist_id,
- user_lives_playlist_id,
- ],
+ # Add special playlists if they exists, in proper order
+ playlist_ids = (
+ list(
+ filter(
+ None,
+ [
+ user_long_uploads_playlist_id,
+ user_short_uploads_playlist_id,
+ user_lives_playlist_id,
+ ],
+ )
+ )
+ + playlist_ids
)
- # we always include uploads playlist (contains everything)
- playlist_ids += [
- channel_json["contentDetails"]["relatedPlaylists"]["uploads"]
- ]
- uploads_playlist_id = playlist_ids[-1]
is_playlist = False
except ChannelNotFoundError:
# channel not found, then ID should be a playlist
@@ -402,7 +403,6 @@ def extract_playlists_details_from(youtube_id: str):
# dict.fromkeys maintains the order of playlist_ids while removing duplicates
[Playlist.from_id(playlist_id) for playlist_id in dict.fromkeys(playlist_ids)],
main_channel_id,
- uploads_playlist_id,
user_long_uploads_playlist_id,
user_short_uploads_playlist_id,
user_lives_playlist_id,
diff --git a/scraper/tests-integration/integration.py b/scraper/tests-integration/integration.py
index 8241a565..d48be851 100644
--- a/scraper/tests-integration/integration.py
+++ b/scraper/tests-integration/integration.py
@@ -47,7 +47,7 @@ def test_zim_channel_json():
assert channel_json["id"] == "UC8elThf5TGMpQfQc_VE917Q"
assert channel_json["channelName"] == "openZIM_testing"
- assert channel_json["mainPlaylist"] == "uploads_from_openzim_testing-917Q"
+ assert channel_json["firstPlaylist"] == "uploads_from_openzim_testing-917Q"
def test_zim_videos():
diff --git a/zimui/cypress/fixtures/channel/channel.json b/zimui/cypress/fixtures/channel/channel.json
index 19696e8b..eba49a46 100644
--- a/zimui/cypress/fixtures/channel/channel.json
+++ b/zimui/cypress/fixtures/channel/channel.json
@@ -7,5 +7,5 @@
"profilePath": "profile.jpg",
"bannerPath": "banner.jpg",
"joinedDate": "2024-06-04T13:30:16.232286Z",
- "mainPlaylist": "uploads_from_openzim_testing-917Q"
+ "firstPlaylist": "uploads_from_openzim_testing-917Q"
}
diff --git a/zimui/src/components/channel/tabs/ChannelHomeGridTab.vue b/zimui/src/components/channel/tabs/ChannelHomeGridTab.vue
index 87421603..11e4ca55 100644
--- a/zimui/src/components/channel/tabs/ChannelHomeGridTab.vue
+++ b/zimui/src/components/channel/tabs/ChannelHomeGridTab.vue
@@ -15,7 +15,7 @@ const isLoading = ref(true)
// Watch for changes in the main playlist
watch(
- () => main.channel?.mainPlaylist,
+ () => main.channel?.firstPlaylist,
() => {
fetchData()
}
@@ -23,9 +23,9 @@ watch(
// Fetch the videos for the main playlist
const fetchData = async function () {
- if (main.channel?.mainPlaylist) {
+ if (main.channel?.firstPlaylist) {
try {
- const resp = await main.fetchPlaylist(main.channel?.mainPlaylist)
+ const resp = await main.fetchPlaylist(main.channel?.firstPlaylist)
if (resp) {
playlist.value = resp
videos.value = resp.videos
@@ -54,6 +54,6 @@ onMounted(() => {
:count-text="playlist?.videos.length === 1 ? 'video' : 'videos'"
icon="mdi-video-outline"
/>
-
+
diff --git a/zimui/src/components/channel/tabs/ChannelHomeListTab.vue b/zimui/src/components/channel/tabs/ChannelHomeListTab.vue
index b6078cf0..423cd580 100644
--- a/zimui/src/components/channel/tabs/ChannelHomeListTab.vue
+++ b/zimui/src/components/channel/tabs/ChannelHomeListTab.vue
@@ -12,7 +12,7 @@ const isLoading = ref(true)
// Watch for changes in the main playlist
watch(
- () => main.channel?.mainPlaylist,
+ () => main.channel?.id,
() => {
fetchData()
}
@@ -20,7 +20,7 @@ watch(
// Fetch the videos for the main playlist
const fetchData = async function () {
- if (main.channel?.mainPlaylist) {
+ if (main.channel?.id) {
try {
const resp = await main.fetchHomePlaylists()
if (resp) {
diff --git a/zimui/src/components/channel/tabs/GenericTab.vue b/zimui/src/components/channel/tabs/GenericTab.vue
index 4317d476..26ba5c14 100755
--- a/zimui/src/components/channel/tabs/GenericTab.vue
+++ b/zimui/src/components/channel/tabs/GenericTab.vue
@@ -67,10 +67,6 @@ onMounted(() => {
:count-text="playlist?.videos.length === 1 ? 'video' : 'videos'"
icon="mdi-video-outline"
/>
-
+
diff --git a/zimui/src/components/channel/tabs/PlaylistsTab.vue b/zimui/src/components/channel/tabs/PlaylistsTab.vue
index a06c7039..a97a602a 100644
--- a/zimui/src/components/channel/tabs/PlaylistsTab.vue
+++ b/zimui/src/components/channel/tabs/PlaylistsTab.vue
@@ -13,7 +13,7 @@ const isLoading = ref(true)
// Watch for changes in the main playlist
watch(
- () => main.channel?.mainPlaylist,
+ () => main.channel?.id,
() => {
fetchData()
}
@@ -21,7 +21,7 @@ watch(
// Fetch the playlists for the playlist tab
const fetchData = async function () {
- if (main.channel?.mainPlaylist) {
+ if (main.channel?.id) {
try {
const resp = await main.fetchPlaylists()
if (resp) {
diff --git a/zimui/src/types/Channel.ts b/zimui/src/types/Channel.ts
index 967d9e3d..f243a077 100644
--- a/zimui/src/types/Channel.ts
+++ b/zimui/src/types/Channel.ts
@@ -7,10 +7,10 @@ export interface Channel {
profilePath?: string
bannerPath?: string
joinedDate: string
- mainPlaylist?: string
- userLongUploadsPlaylist?:string
- userShortUploadsPlaylist?:string
- userLivesPlaylist?:string
+ firstPlaylist?: string
+ userLongUploadsPlaylist?: string
+ userShortUploadsPlaylist?: string
+ userLivesPlaylist?: string
playlistCount: number
}