feat: support YouTube/Dailymotion/SoundCloud embed playback for external content
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 28s

This commit is contained in:
ordinarthur 2026-04-12 22:01:18 +02:00
parent 39e1ed70ee
commit d9e69aa76c
5 changed files with 469 additions and 170 deletions

View File

@ -1,13 +1,65 @@
import { Play, Pause, Volume2, VolumeX, SkipBack, SkipForward } from 'lucide-react' import { useState } from 'react'
import { Play, Pause, Volume2, VolumeX, SkipBack, SkipForward, Maximize2, Minimize2 } from 'lucide-react'
import { usePlayerStore } from '@/stores/player' import { usePlayerStore } from '@/stores/player'
import { formatDuration } from '@/lib/utils' import { formatDuration } from '@/lib/utils'
import { getEmbedInfo } from '@/lib/embed'
import { Avatar } from '@/components/ui/Avatar' import { Avatar } from '@/components/ui/Avatar'
export function PlayerBar() { export function PlayerBar() {
const { current, isPlaying, progress, duration, volume, toggle, seek, setVolume } = usePlayerStore() const { current, isPlaying, isExternal, progress, duration, volume, toggle, seek, setVolume } = usePlayerStore()
const [expanded, setExpanded] = useState(false)
if (!current) return null if (!current) return null
const embedInfo = isExternal ? getEmbedInfo(current.audio_url) : null
// External content: show expandable embed player
if (isExternal && embedInfo && isPlaying) {
return (
<div className={`fixed bottom-0 left-0 right-0 z-50 glass border-t border-border/60 shadow-[0_-4px_30px_rgba(30,27,51,0.08)] transition-all duration-300 ${expanded ? 'h-[70vh]' : 'h-[4.75rem]'}`}>
{expanded && (
<div className="w-full h-[calc(100%-4.75rem)] bg-black/95">
<iframe
src={embedInfo.embedUrl}
className="w-full h-full"
allow="autoplay; encrypted-media; picture-in-picture"
allowFullScreen
title={current.title}
/>
</div>
)}
<div className="max-w-6xl mx-auto px-4 sm:px-6 h-[4.75rem] flex items-center gap-4">
<div className="flex items-center gap-3 min-w-0 flex-1">
<div className="relative shrink-0">
{current.cover_url ? (
<img src={current.cover_url} alt="" className="w-11 h-11 rounded-xl object-cover shadow-organic-sm" />
) : (
<Avatar name={current.title} size="md" className="!rounded-xl" />
)}
<div className="absolute -bottom-0.5 -right-0.5 flex items-end gap-[2px] h-3 p-[2px] bg-surface rounded-md">
<div className="wave-bar" /><div className="wave-bar" /><div className="wave-bar" />
</div>
</div>
<div className="min-w-0">
<p className="text-[13px] font-semibold truncate">{current.title}</p>
<p className="text-[11px] text-text-secondary truncate">
{current.creator?.username} · via {embedInfo.platform === 'youtube' ? 'YouTube' : embedInfo.platform === 'dailymotion' ? 'Dailymotion' : 'SoundCloud'}
</p>
</div>
</div>
<button
onClick={() => setExpanded(!expanded)}
className="w-11 h-11 rounded-full bg-gradient-to-br from-primary to-[#7B6AEF] text-white flex items-center justify-center hover:shadow-[0_2px_20px_rgba(91,76,219,0.4)] transition-all active:scale-95 cursor-pointer"
>
{expanded ? <Minimize2 size={17} /> : <Maximize2 size={17} />}
</button>
</div>
</div>
)
}
// Native audio player
return ( return (
<div className="fixed bottom-0 left-0 right-0 z-50 glass border-t border-border/60 shadow-[0_-4px_30px_rgba(30,27,51,0.08)]"> <div className="fixed bottom-0 left-0 right-0 z-50 glass border-t border-border/60 shadow-[0_-4px_30px_rgba(30,27,51,0.08)]">
{/* Progress bar */} {/* Progress bar */}

46
src/lib/embed.ts Normal file
View File

@ -0,0 +1,46 @@
export type EmbedInfo = {
platform: 'youtube' | 'dailymotion' | 'soundcloud'
id: string
embedUrl: string
}
export function getEmbedInfo(url: string): EmbedInfo | null {
// YouTube
const ytMatch = url.match(
/(?:youtube\.com\/(?:watch\?v=|embed\/|shorts\/)|youtu\.be\/)([a-zA-Z0-9_-]{11})/,
)
if (ytMatch) {
return {
platform: 'youtube',
id: ytMatch[1],
embedUrl: `https://www.youtube.com/embed/${ytMatch[1]}?autoplay=1`,
}
}
// Dailymotion
const dmMatch = url.match(
/(?:dailymotion\.com\/video\/|dai\.ly\/)([a-zA-Z0-9]+)/,
)
if (dmMatch) {
return {
platform: 'dailymotion',
id: dmMatch[1],
embedUrl: `https://www.dailymotion.com/embed/video/${dmMatch[1]}?autoplay=1`,
}
}
// SoundCloud
if (url.includes('soundcloud.com/')) {
return {
platform: 'soundcloud',
id: url,
embedUrl: `https://w.soundcloud.com/player/?url=${encodeURIComponent(url)}&auto_play=true&visual=true`,
}
}
return null
}
export function isExternalUrl(url: string): boolean {
return getEmbedInfo(url) !== null
}

View File

@ -4,6 +4,7 @@ import { Play, Pause, Heart, MessageCircle, Clock, Share2 } from 'lucide-react'
import { supabase } from '@/lib/supabase' import { supabase } from '@/lib/supabase'
import { useAuthStore } from '@/stores/auth' import { useAuthStore } from '@/stores/auth'
import { usePlayerStore } from '@/stores/player' import { usePlayerStore } from '@/stores/player'
import { getEmbedInfo } from '@/lib/embed'
import type { Podcast, Comment } from '@/types' import type { Podcast, Comment } from '@/types'
import { formatDuration, timeAgo } from '@/lib/utils' import { formatDuration, timeAgo } from '@/lib/utils'
import { Avatar } from '@/components/ui/Avatar' import { Avatar } from '@/components/ui/Avatar'
@ -163,6 +164,23 @@ export function PodcastDetail() {
</div> </div>
</div> </div>
{/* Embedded player for external content */}
{(() => {
const embed = getEmbedInfo(podcast.audio_url)
if (!embed) return null
return (
<div className="rounded-2xl overflow-hidden shadow-md border border-border/50 aspect-video">
<iframe
src={embed.embedUrl.replace('autoplay=1', 'autoplay=0')}
className="w-full h-full"
allow="autoplay; encrypted-media; picture-in-picture"
allowFullScreen
title={podcast.title}
/>
</div>
)
})()}
{podcast.description && ( {podcast.description && (
<div> <div>
<h2 className="text-lg font-heading font-bold mb-2">Description</h2> <h2 className="text-lg font-heading font-bold mb-2">Description</h2>

View File

@ -1,9 +1,11 @@
import { create } from 'zustand' import { create } from 'zustand'
import type { Podcast } from '@/types' import type { Podcast } from '@/types'
import { isExternalUrl } from '@/lib/embed'
interface PlayerState { interface PlayerState {
current: Podcast | null current: Podcast | null
isPlaying: boolean isPlaying: boolean
isExternal: boolean
progress: number progress: number
duration: number duration: number
volume: number volume: number
@ -21,6 +23,7 @@ interface PlayerState {
export const usePlayerStore = create<PlayerState>((set, get) => ({ export const usePlayerStore = create<PlayerState>((set, get) => ({
current: null, current: null,
isPlaying: false, isPlaying: false,
isExternal: false,
progress: 0, progress: 0,
duration: 0, duration: 0,
volume: 0.8, volume: 0.8,
@ -28,11 +31,18 @@ export const usePlayerStore = create<PlayerState>((set, get) => ({
play: (podcast) => { play: (podcast) => {
const { audio, current } = get() const { audio, current } = get()
const external = isExternalUrl(podcast.audio_url)
if (current?.id === podcast.id && audio) { if (current?.id === podcast.id) {
audio.play() if (external) {
set({ isPlaying: true }) set({ isPlaying: true })
return return
}
if (audio) {
audio.play()
set({ isPlaying: true })
return
}
} }
if (audio) { if (audio) {
@ -40,6 +50,12 @@ export const usePlayerStore = create<PlayerState>((set, get) => ({
audio.removeAttribute('src') audio.removeAttribute('src')
} }
// External URLs are handled by embed iframe, not HTMLAudioElement
if (external) {
set({ audio: null, current: podcast, isPlaying: true, isExternal: true, progress: 0, duration: podcast.duration_seconds || 0 })
return
}
const newAudio = new Audio(podcast.audio_url) const newAudio = new Audio(podcast.audio_url)
newAudio.volume = get().volume newAudio.volume = get().volume
@ -54,7 +70,7 @@ export const usePlayerStore = create<PlayerState>((set, get) => ({
}) })
newAudio.play() newAudio.play()
set({ audio: newAudio, current: podcast, isPlaying: true, progress: 0 }) set({ audio: newAudio, current: podcast, isPlaying: true, isExternal: false, progress: 0 })
}, },
toggle: () => { toggle: () => {

View File

@ -1,220 +1,387 @@
-- ============================================== -- ==============================================
-- We Talk — Seed Data -- We Talk — Seed Data
-- Podcasts libres de droit (Creative Commons) -- Podcasts from Alice Underground & Small Talk
-- Source: Hacker Public Radio (archive.org) -- Audio from Audiomeans RSS feeds (public)
-- ============================================== -- ==============================================
-- 1. Create demo users in auth.users first (required for FK on profiles) -- 1. Create demo users in auth.users (required for FK on profiles)
-- NOTE: Run this AFTER the migration 001_initial_schema.sql
INSERT INTO auth.users (id, instance_id, email, encrypted_password, email_confirmed_at, aud, role, raw_app_meta_data, raw_user_meta_data, created_at, updated_at, confirmation_token) VALUES INSERT INTO auth.users (id, instance_id, email, encrypted_password, email_confirmed_at, aud, role, raw_app_meta_data, raw_user_meta_data, created_at, updated_at, confirmation_token) VALUES
('a1000000-0000-0000-0000-000000000001', '00000000-0000-0000-0000-000000000000', 'ahuka@demo.wetalk.fr', crypt('demo-password-123', gen_salt('bf')), NOW(), 'authenticated', 'authenticated', '{"provider":"email","providers":["email"]}', '{"username":"ahuka"}', NOW(), NOW(), ''), ('a1000000-0000-0000-0000-000000000001', '00000000-0000-0000-0000-000000000000', 'alice@demo.wetalk.fr', crypt('demo-password-123', gen_salt('bf')), NOW(), 'authenticated', 'authenticated', '{"provider":"email","providers":["email"]}', '{"username":"alice_underground"}', NOW(), NOW(), ''),
('a1000000-0000-0000-0000-000000000002', '00000000-0000-0000-0000-000000000000', 'sgoti@demo.wetalk.fr', crypt('demo-password-123', gen_salt('bf')), NOW(), 'authenticated', 'authenticated', '{"provider":"email","providers":["email"]}', '{"username":"sgoti"}', NOW(), NOW(), ''), ('a1000000-0000-0000-0000-000000000002', '00000000-0000-0000-0000-000000000000', 'david@demo.wetalk.fr', crypt('demo-password-123', gen_salt('bf')), NOW(), 'authenticated', 'authenticated', '{"provider":"email","providers":["email"]}', '{"username":"david_dcl"}', NOW(), NOW(), ''),
('a1000000-0000-0000-0000-000000000003', '00000000-0000-0000-0000-000000000000', 'klaatu@demo.wetalk.fr', crypt('demo-password-123', gen_salt('bf')), NOW(), 'authenticated', 'authenticated', '{"provider":"email","providers":["email"]}', '{"username":"klaatu"}', NOW(), NOW(), ''), ('a1000000-0000-0000-0000-000000000003', '00000000-0000-0000-0000-000000000000', 'sara@demo.wetalk.fr', crypt('demo-password-123', gen_salt('bf')), NOW(), 'authenticated', 'authenticated', '{"provider":"email","providers":["email"]}', '{"username":"sara_f"}', NOW(), NOW(), ''),
('a1000000-0000-0000-0000-000000000004', '00000000-0000-0000-0000-000000000000', 'windigo@demo.wetalk.fr', crypt('demo-password-123', gen_salt('bf')), NOW(), 'authenticated', 'authenticated', '{"provider":"email","providers":["email"]}', '{"username":"windigo"}', NOW(), NOW(), ''), ('a1000000-0000-0000-0000-000000000004', '00000000-0000-0000-0000-000000000000', 'bigflo@demo.wetalk.fr', crypt('demo-password-123', gen_salt('bf')), NOW(), 'authenticated', 'authenticated', '{"provider":"email","providers":["email"]}', '{"username":"bigflo"}', NOW(), NOW(), ''),
('a1000000-0000-0000-0000-000000000005', '00000000-0000-0000-0000-000000000000', 'corydoctorow@demo.wetalk.fr', crypt('demo-password-123', gen_salt('bf')), NOW(), 'authenticated', 'authenticated', '{"provider":"email","providers":["email"]}', '{"username":"corydoctorow"}', NOW(), NOW(), '') ('a1000000-0000-0000-0000-000000000005', '00000000-0000-0000-0000-000000000000', 'mika@demo.wetalk.fr', crypt('demo-password-123', gen_salt('bf')), NOW(), 'authenticated', 'authenticated', '{"provider":"email","providers":["email"]}', '{"username":"mika_music"}', NOW(), NOW(), '')
ON CONFLICT (id) DO NOTHING; ON CONFLICT (id) DO NOTHING;
-- Also insert into auth.identities (required by Supabase Auth)
INSERT INTO auth.identities (id, user_id, provider_id, provider, identity_data, last_sign_in_at, created_at, updated_at) VALUES INSERT INTO auth.identities (id, user_id, provider_id, provider, identity_data, last_sign_in_at, created_at, updated_at) VALUES
('a1000000-0000-0000-0000-000000000001', 'a1000000-0000-0000-0000-000000000001', 'a1000000-0000-0000-0000-000000000001', 'email', '{"sub":"a1000000-0000-0000-0000-000000000001","email":"ahuka@demo.wetalk.fr"}', NOW(), NOW(), NOW()), ('a1000000-0000-0000-0000-000000000001', 'a1000000-0000-0000-0000-000000000001', 'a1000000-0000-0000-0000-000000000001', 'email', '{"sub":"a1000000-0000-0000-0000-000000000001","email":"alice@demo.wetalk.fr"}', NOW(), NOW(), NOW()),
('a1000000-0000-0000-0000-000000000002', 'a1000000-0000-0000-0000-000000000002', 'a1000000-0000-0000-0000-000000000002', 'email', '{"sub":"a1000000-0000-0000-0000-000000000002","email":"sgoti@demo.wetalk.fr"}', NOW(), NOW(), NOW()), ('a1000000-0000-0000-0000-000000000002', 'a1000000-0000-0000-0000-000000000002', 'a1000000-0000-0000-0000-000000000002', 'email', '{"sub":"a1000000-0000-0000-0000-000000000002","email":"david@demo.wetalk.fr"}', NOW(), NOW(), NOW()),
('a1000000-0000-0000-0000-000000000003', 'a1000000-0000-0000-0000-000000000003', 'a1000000-0000-0000-0000-000000000003', 'email', '{"sub":"a1000000-0000-0000-0000-000000000003","email":"klaatu@demo.wetalk.fr"}', NOW(), NOW(), NOW()), ('a1000000-0000-0000-0000-000000000003', 'a1000000-0000-0000-0000-000000000003', 'a1000000-0000-0000-0000-000000000003', 'email', '{"sub":"a1000000-0000-0000-0000-000000000003","email":"sara@demo.wetalk.fr"}', NOW(), NOW(), NOW()),
('a1000000-0000-0000-0000-000000000004', 'a1000000-0000-0000-0000-000000000004', 'a1000000-0000-0000-0000-000000000004', 'email', '{"sub":"a1000000-0000-0000-0000-000000000004","email":"windigo@demo.wetalk.fr"}', NOW(), NOW(), NOW()), ('a1000000-0000-0000-0000-000000000004', 'a1000000-0000-0000-0000-000000000004', 'a1000000-0000-0000-0000-000000000004', 'email', '{"sub":"a1000000-0000-0000-0000-000000000004","email":"bigflo@demo.wetalk.fr"}', NOW(), NOW(), NOW()),
('a1000000-0000-0000-0000-000000000005', 'a1000000-0000-0000-0000-000000000005', 'a1000000-0000-0000-0000-000000000005', 'email', '{"sub":"a1000000-0000-0000-0000-000000000005","email":"corydoctorow@demo.wetalk.fr"}', NOW(), NOW(), NOW()) ('a1000000-0000-0000-0000-000000000005', 'a1000000-0000-0000-0000-000000000005', 'a1000000-0000-0000-0000-000000000005', 'email', '{"sub":"a1000000-0000-0000-0000-000000000005","email":"mika@demo.wetalk.fr"}', NOW(), NOW(), NOW())
ON CONFLICT (id) DO NOTHING; ON CONFLICT (id) DO NOTHING;
-- Now insert profiles (the trigger handle_new_user won't fire on direct auth.users inserts) -- 2. Profiles
INSERT INTO public.profiles (id, username, avatar_url, bio, is_premium, free_listens_count) VALUES INSERT INTO public.profiles (id, username, avatar_url, bio, is_premium, free_listens_count) VALUES
('a1000000-0000-0000-0000-000000000001', 'ahuka', NULL, 'Passionné de technologie et de logiciels libres. Contributeur Hacker Public Radio.', true, 0), ('a1000000-0000-0000-0000-000000000001', 'alice_underground', 'https://static.audiomeans.fr/img/podcast/e113761f-a5db-4bf2-80db-b99fe2448d10.jpg', 'Photographe, realisatrice et creatrice du Trippy Talk Show. Chaque episode est un univers unique.', true, 0),
('a1000000-0000-0000-0000-000000000002', 'sgoti', NULL, 'Podcaster et bricoleur informatique. J''aime parler de tout et de rien.', false, 3), ('a1000000-0000-0000-0000-000000000002', 'david_dcl', 'https://static.audiomeans.fr/img/podcast/279b0aa2-ff30-435e-90e0-5cdfa115ea33.jpg', 'Presentateur de Small Talk chez Konbini. On parle de tout sauf de ce qui vous a rendu celebre.', true, 0),
('a1000000-0000-0000-0000-000000000003', 'klaatu', NULL, 'Explorateur numerique. Voyage, technologie et culture libre.', true, 0), ('a1000000-0000-0000-0000-000000000003', 'sara_f', NULL, 'Actrice et invitee recurrente. J''aime les conversations sans filtre.', false, 5),
('a1000000-0000-0000-0000-000000000004', 'windigo', NULL, 'Administrateur systeme le jour, podcaster la nuit.', false, 7), ('a1000000-0000-0000-0000-000000000004', 'bigflo', NULL, 'Rappeur, entrepreneur, patron. Invitee d''Alice Underground.', false, 2),
('a1000000-0000-0000-0000-000000000005', 'corydoctorow', NULL, 'Auteur, journaliste, activiste. Electronic Frontier Foundation.', true, 0) ('a1000000-0000-0000-0000-000000000005', 'mika_music', NULL, 'Chanteur, conteur, personnage. Invite sur les deux podcasts.', true, 0)
ON CONFLICT (id) DO NOTHING; ON CONFLICT (id) DO NOTHING;
-- 2. Create tags -- 3. Tags
INSERT INTO public.tags (id, name, slug) VALUES INSERT INTO public.tags (id, name, slug) VALUES
('b1000000-0000-0000-0000-000000000001', 'Technologie', 'technologie'), ('b1000000-0000-0000-0000-000000000001', 'Talk Show', 'talk-show'),
('b1000000-0000-0000-0000-000000000002', 'Open Source', 'open-source'), ('b1000000-0000-0000-0000-000000000002', 'Comedie', 'comedie'),
('b1000000-0000-0000-0000-000000000003', 'Jeux Video', 'jeux-video'), ('b1000000-0000-0000-0000-000000000003', 'Culture', 'culture'),
('b1000000-0000-0000-0000-000000000004', 'Tutoriel', 'tutoriel'), ('b1000000-0000-0000-0000-000000000004', 'Musique', 'musique'),
('b1000000-0000-0000-0000-000000000005', 'Culture', 'culture'), ('b1000000-0000-0000-0000-000000000005', 'Cinema', 'cinema'),
('b1000000-0000-0000-0000-000000000006', 'Voyage', 'voyage'), ('b1000000-0000-0000-0000-000000000006', 'Voyage', 'voyage'),
('b1000000-0000-0000-0000-000000000007', 'Productivite', 'productivite'), ('b1000000-0000-0000-0000-000000000007', 'Societe', 'societe'),
('b1000000-0000-0000-0000-000000000008', 'Vie Quotidienne', 'vie-quotidienne'), ('b1000000-0000-0000-0000-000000000008', 'Rap', 'rap'),
('b1000000-0000-0000-0000-000000000009', 'Droit Numerique', 'droit-numerique'), ('b1000000-0000-0000-0000-000000000009', 'Humour', 'humour'),
('b1000000-0000-0000-0000-000000000010', 'Windows', 'windows'), ('b1000000-0000-0000-0000-000000000010', 'Interview', 'interview'),
('b1000000-0000-0000-0000-000000000011', 'Linux', 'linux'), ('b1000000-0000-0000-0000-000000000011', 'French Touch', 'french-touch'),
('b1000000-0000-0000-0000-000000000012', 'Podcasting', 'podcasting') ('b1000000-0000-0000-0000-000000000012', 'Noel', 'noel')
ON CONFLICT (id) DO NOTHING; ON CONFLICT (id) DO NOTHING;
-- 3. Insert podcasts (audio from archive.org, Creative Commons) -- 4. Podcasts — Alice Underground
INSERT INTO public.podcasts (id, creator_id, title, description, audio_url, duration_seconds, cover_url, plays_count, created_at) VALUES INSERT INTO public.podcasts (id, creator_id, title, description, audio_url, duration_seconds, cover_url, plays_count, created_at) VALUES
( (
'c1000000-0000-0000-0000-000000000001', 'c1000000-0000-0000-0000-000000000001',
'a1000000-0000-0000-0000-000000000001', 'a1000000-0000-0000-0000-000000000001',
'Creative Commons Search Engine', 'God Save Stephane Bern',
'Decouvrez Openverse, le nouveau moteur de recherche pour le contenu Creative Commons. Une evolution de l''ancien CC Search developpe par Creative Commons, repris par WordPress, et qui continue d''evoluer.', 'Stephane Bern partage ses anecdotes sur la royaute, les Windsor et Versailles dans le Trippy Talk Show d''Alice.',
'https://archive.org/download/hpr3977/hpr3977.mp3', 'https://audio.audiomeans.fr/file/jxBCsdLAGN/bcd67c67-cae7-481b-9aa6-ebcfa6067969.mp3',
358, 3661,
NULL, 'https://static.audiomeans.fr/img/podcast/e113761f-a5db-4bf2-80db-b99fe2448d10.jpg',
247, 1247,
NOW() - INTERVAL '2 days' '2026-04-08'
), ),
( (
'c1000000-0000-0000-0000-000000000002', 'c1000000-0000-0000-0000-000000000002',
'a1000000-0000-0000-0000-000000000003', 'a1000000-0000-0000-0000-000000000001',
'Playing Alpha Centauri, Part 1', 'Dans notre bulle avec Sara Forestier',
'Premiere partie de nos conseils pour jouer a Alpha Centauri. On commence par regarder comment approcher ce jeu de strategie classique et les bases pour bien demarrer.', 'Sara Forestier parle de desir et de sexualite avec humour et franchise dans un episode sans tabou.',
'https://archive.org/download/hpr3970/hpr3970.mp3', 'https://audio.audiomeans.fr/file/jxBCsdLAGN/4215b52f-8f0b-42d8-9310-55181e3860f1.mp3',
1102, 3254,
NULL, 'https://static.audiomeans.fr/img/podcast/e113761f-a5db-4bf2-80db-b99fe2448d10.jpg',
183, 983,
NOW() - INTERVAL '5 days' '2026-04-01'
), ),
( (
'c1000000-0000-0000-0000-000000000003', 'c1000000-0000-0000-0000-000000000003',
'a1000000-0000-0000-0000-000000000002', 'a1000000-0000-0000-0000-000000000001',
'Comment se faire des amis sur Internet', 'C''est qui le patron ? Avec Bigflo',
'Sgoti et Mugs discutent avec des amis de la facon de creer des liens authentiques en ligne. Un echange decontracte sur les relations humaines a l''ere du numerique.', 'Le rappeur Bigflo se confie sur le business, l''ambition et la vie d''artiste avec son style caracteristique.',
'https://archive.org/download/hpr3971/hpr3971.mp3', 'https://audio.audiomeans.fr/file/jxBCsdLAGN/5497f8c6-0fc3-4393-b77c-2d47627068d8.mp3',
2245, 4189,
NULL, 'https://static.audiomeans.fr/img/podcast/e113761f-a5db-4bf2-80db-b99fe2448d10.jpg',
412, 2134,
NOW() - INTERVAL '3 days' '2026-03-25'
), ),
( (
'c1000000-0000-0000-0000-000000000004', 'c1000000-0000-0000-0000-000000000004',
'a1000000-0000-0000-0000-000000000002', 'a1000000-0000-0000-0000-000000000001',
'Filtrage Thunderbird : garder une boite mail propre', 'Touching grass, avec Berengere Krief',
'Sgoti explique comment filtrer efficacement votre boite de reception Thunderbird pour rester organise et productif au quotidien.', 'Alice et Berengere Krief explorent les relations, l''autonomie du corps et le desir en pleine nature.',
'https://archive.org/download/hpr3972/hpr3972.mp3', 'https://audio.audiomeans.fr/file/jxBCsdLAGN/d4aa4571-6b0a-4f73-9b2d-72aabfeef066.mp3',
743, 3311,
NULL, 'https://static.audiomeans.fr/img/podcast/e113761f-a5db-4bf2-80db-b99fe2448d10.jpg',
156, 756,
NOW() - INTERVAL '7 days' '2026-03-18'
), ),
( (
'c1000000-0000-0000-0000-000000000005', 'c1000000-0000-0000-0000-000000000005',
'a1000000-0000-0000-0000-000000000004', 'a1000000-0000-0000-0000-000000000001',
'Creer un preset d''equalisation pour vos podcasts', 'Un sosie presque parfait avec Laurent Lafitte',
'Une methode pour creer un traitement audio reproductible pour vos episodes de podcast. Apprenez a standardiser la qualite sonore de vos productions.', 'L''acteur tout juste cesairse Laurent Lafitte se prete au jeu avec humour, charme et secrets inattendus.',
'https://archive.org/download/hpr3973/hpr3973.mp3', 'https://audio.audiomeans.fr/file/jxBCsdLAGN/e38e2aaa-4e2d-4581-981f-50423256b801.mp3',
1019, 2233,
NULL, 'https://static.audiomeans.fr/img/podcast/e113761f-a5db-4bf2-80db-b99fe2448d10.jpg',
298, 654,
NOW() - INTERVAL '4 days' '2026-03-04'
), ),
( (
'c1000000-0000-0000-0000-000000000006', 'c1000000-0000-0000-0000-000000000006',
'a1000000-0000-0000-0000-000000000004', 'a1000000-0000-0000-0000-000000000001',
'Decouverte de USBimager', 'Elementaire mon cher Augustin Trapenard',
'Pourquoi vous devriez utiliser USBimager. Introduction a cet outil pratique pour ecrire des images sur des peripheriques de stockage en toute simplicite.', 'Le journaliste Augustin Trapenard et Alice menent l''enquete sur la litterature et la culture en detectives amateurs.',
'https://archive.org/download/hpr3974/hpr3974.mp3', 'https://audio.audiomeans.fr/file/jxBCsdLAGN/4f41d0c9-88b9-4b54-a4e6-2fae3076e74c.mp3',
1019, 4591,
NULL, 'https://static.audiomeans.fr/img/podcast/e113761f-a5db-4bf2-80db-b99fe2448d10.jpg',
89, 1876,
NOW() - INTERVAL '10 days' '2026-02-25'
), ),
( (
'c1000000-0000-0000-0000-000000000007', 'c1000000-0000-0000-0000-000000000007',
'a1000000-0000-0000-0000-000000000003', 'a1000000-0000-0000-0000-000000000001',
'Mesa Verde : journal de voyage Colorado', 'Les baddies font du ski avec Lolo Zouai',
'Notre recit d''une journee de visite a Mesa Verde, Colorado. Nous etions la pour un mariage et avons profite pour explorer ce site remarquable.', 'L''artiste franco-americaine Lolo Zouai et Alice parlent musique, identite et culture sur les pistes de ski.',
'https://archive.org/download/hpr3975/hpr3975.mp3', 'https://audio.audiomeans.fr/file/jxBCsdLAGN/8a2bcffc-f767-4132-9403-b8c4be072be4.mp3',
730, 3161,
NULL, 'https://static.audiomeans.fr/img/podcast/e113761f-a5db-4bf2-80db-b99fe2448d10.jpg',
321, 543,
NOW() - INTERVAL '1 day' '2026-02-18'
), ),
( (
'c1000000-0000-0000-0000-000000000008', 'c1000000-0000-0000-0000-000000000008',
'a1000000-0000-0000-0000-000000000004', 'a1000000-0000-0000-0000-000000000001',
'L''evolution de l''outil Capture d''ecran Windows', 'La cavalerie arrive avec Myd',
'KD retrace l''histoire de l''evolution des outils de capture d''ecran sous Windows, du Print Screen au Snipping Tool moderne.', 'Episode live au festival Spotify RADAR avec le DJ Myd. Musique, fun et bonne humeur au programme.',
'https://archive.org/download/hpr3976/hpr3976.mp3', 'https://audio.audiomeans.fr/file/jxBCsdLAGN/2ce710d2-4b18-41da-b165-1a2b0fdf8041.mp3',
429, 2371,
NULL, 'https://static.audiomeans.fr/img/podcast/e113761f-a5db-4bf2-80db-b99fe2448d10.jpg',
134, 412,
NOW() - INTERVAL '6 days' '2026-02-04'
), ),
( (
'c1000000-0000-0000-0000-000000000009', 'c1000000-0000-0000-0000-000000000009',
'a1000000-0000-0000-0000-000000000005', 'a1000000-0000-0000-0000-000000000001',
'Les trolls du droit d''auteur Creative Commons', 'Elfes in black avec Kiddy Smile',
'Discussion sur Pixsy, un nouveau type de troll du droit d''auteur qui cible les utilisateurs de Creative Commons. Lecture et analyse d''un article de fond sur ce sujet preoccupant.', 'Le DJ et producteur Kiddy Smile se livre avec franchise sur la musique, ses experiences et ses secrets.',
'https://archive.org/download/Cory_Doctorow_Podcast_412/Cory_Doctorow_Podcast_412_-_A_Bug_in_Early_Creative_Commons_Licenses.mp3', 'https://audio.audiomeans.fr/file/jxBCsdLAGN/71e76ea0-64bf-4ff4-81f2-f1aefa1d0519.mp3',
2441, 4411,
NULL, 'https://static.audiomeans.fr/img/podcast/e113761f-a5db-4bf2-80db-b99fe2448d10.jpg',
567, 789,
NOW() - INTERVAL '8 days' '2026-01-28'
),
(
'c1000000-0000-0000-0000-000000000010',
'a1000000-0000-0000-0000-000000000001',
'Dans la foret avec Mika',
'Le chanteur Mika revele des histoires sur sa carriere, ses rencontres celebres et ses secrets de famille.',
'https://audio.audiomeans.fr/file/jxBCsdLAGN/054a325f-9887-4b4d-9982-a76a2ac03c20.mp3',
3180,
'https://static.audiomeans.fr/img/podcast/e113761f-a5db-4bf2-80db-b99fe2448d10.jpg',
1567,
'2026-01-14'
); );
-- 4. Associate tags to podcasts -- 5. Podcasts — Small Talk (Konbini)
INSERT INTO public.podcasts (id, creator_id, title, description, audio_url, duration_seconds, cover_url, plays_count, created_at) VALUES
(
'c2000000-0000-0000-0000-000000000001',
'a1000000-0000-0000-0000-000000000002',
'Clara Morgane et les grands-meres en laisse',
'David explore des sujets inattendus avec Clara Morgane. Revelations sur les poils de corps et introspection personnelle.',
'https://audio.audiomeans.fr/file/jxBCsdLAGN/25cb9c26-6faf-416a-9588-432debd1519d.mp3',
4646,
'https://static.audiomeans.fr/img/episode/f6c68dc9-191e-4565-bb1e-311efac91042.jpg',
3421,
'2026-04-08'
),
(
'c2000000-0000-0000-0000-000000000002',
'a1000000-0000-0000-0000-000000000002',
'Francois Damiens et le complet slip-basket',
'Francois Damiens tente d''esquiver les questions pieges de David dans un episode hilarant et imprevisible.',
'https://audio.audiomeans.fr/file/jxBCsdLAGN/c74aa7df-11f4-4e43-88eb-af5656d9e942.mp3',
3448,
'https://static.audiomeans.fr/img/episode/6ebe8e28-344e-43c3-9aa6-726229e5d441.jpg',
2876,
'2026-03-25'
),
(
'c2000000-0000-0000-0000-000000000003',
'a1000000-0000-0000-0000-000000000002',
'Caballero & JeanJass & la pipeline d''eau minerale',
'Le duo de rappeurs belges se prete au jeu des questions absurdes. Passoire a connards pleinement fonctionnelle.',
'https://audio.audiomeans.fr/file/jxBCsdLAGN/aeb16e4b-9417-485a-9be9-2f3a9ee6191a.mp3',
4906,
'https://static.audiomeans.fr/img/episode/5c363325-7e7d-47f9-9d05-9545f48a14c7.jpg',
1987,
'2026-03-18'
),
(
'c2000000-0000-0000-0000-000000000004',
'a1000000-0000-0000-0000-000000000002',
'Jeremy Ferrari et les vengeances actives',
'On commence deep, on finit deep et on rigole au milieu. Jeremy Ferrari dans toute sa splendeur.',
'https://audio.audiomeans.fr/file/jxBCsdLAGN/0b4967c5-bf51-4006-a9fc-86a2b54b7f48.mp3',
4788,
'https://static.audiomeans.fr/img/episode/126423ee-f543-41d3-a1cb-2432dabe7b0b.jpg',
4532,
'2026-03-04'
),
(
'c2000000-0000-0000-0000-000000000005',
'a1000000-0000-0000-0000-000000000002',
'Tayc et le reculage de dents',
'Le roi de l''afrolove fait des revelations choc. Confessions surprenantes de l''artiste Afrobeats.',
'https://audio.audiomeans.fr/file/jxBCsdLAGN/7c54e552-e242-4dc2-a43d-07c0aa08080b.mp3',
4708,
'https://static.audiomeans.fr/img/episode/df2f2dff-6b32-441b-9f99-8aa13590437a.png',
1654,
'2026-02-26'
),
(
'c2000000-0000-0000-0000-000000000006',
'a1000000-0000-0000-0000-000000000002',
'Cyprien et le palmares des sueurs',
'Deux personnes dont les zones du corps se rejoignent par les poils. Un episode mythique avec le youtubeur.',
'https://audio.audiomeans.fr/file/jxBCsdLAGN/5d21ba37-18a4-43b9-8277-d1b29fcfd421.mp3',
3365,
'https://static.audiomeans.fr/img/episode/1acc2e6c-cf8b-4608-8eb7-a98cd5f81fae.jpg',
5234,
'2026-02-18'
),
(
'c2000000-0000-0000-0000-000000000007',
'a1000000-0000-0000-0000-000000000002',
'Pierre Niney et le reseau tentaculaire de baby-sitting',
'Que Zeus benisse, Pierre Niney est dans Small Talk. L''acteur revele ses reseaux insoupconnes.',
'https://audio.audiomeans.fr/file/jxBCsdLAGN/493d9e44-7f97-4cf3-907a-701a83933e09.mp3',
3663,
'https://static.audiomeans.fr/img/episode/835154f2-adfe-4942-8a40-5f4e6c102b08.jpg',
3876,
'2026-01-21'
),
(
'c2000000-0000-0000-0000-000000000008',
'a1000000-0000-0000-0000-000000000002',
'Julien Dore et la matification cezanesque',
'David decouvre la raison de sa depression vieille de 20 ans. Un episode introspectif et touchant avec Julien Dore.',
'https://audio.audiomeans.fr/file/jxBCsdLAGN/4089b170-240e-4073-bbec-72392abc1075.mp3',
5127,
'https://static.audiomeans.fr/img/episode/8b0163a4-6ecf-498a-b597-8166cde8a1fd.jpg',
6543,
'2026-01-07'
),
(
'c2000000-0000-0000-0000-000000000009',
'a1000000-0000-0000-0000-000000000002',
'Episode de Noel avec Mika',
'Mika a un cousin exorciste et un dealer de Guignols. L''episode special Noel le plus dingue de Small Talk.',
'https://audio.audiomeans.fr/file/jxBCsdLAGN/0385fc90-d888-4776-b4e6-95199cad49d1.mp3',
5096,
'https://static.audiomeans.fr/img/episode/b4ed8cea-4d48-4825-9712-f6315a8b7872.jpg',
7821,
'2025-12-24'
),
(
'c2000000-0000-0000-0000-000000000010',
'a1000000-0000-0000-0000-000000000002',
'Rim''K et le bolossage de la Foire du Trone',
'Caler ou coffrer ? Telle est la question. Rim''K raconte ses aventures de jeunesse et ses choix de vie.',
'https://audio.audiomeans.fr/file/jxBCsdLAGN/f5d1d1dd-ad64-40aa-bab9-270bf0112dd9.mp3',
4833,
'https://static.audiomeans.fr/img/episode/df201cf6-c681-40b5-b3d2-7642233ef830.jpg',
2345,
'2025-12-10'
),
(
'c2000000-0000-0000-0000-000000000011',
'a1000000-0000-0000-0000-000000000002',
'Fabrice Eboue et la guerre du pourboire',
'Fabrice Eboue nous apprend a maitriser l''art du tips. Etiquette, differences culturelles et anecdotes.',
'https://audio.audiomeans.fr/file/jxBCsdLAGN/af20ed5c-c3ff-452d-a92e-77a4c1327eaa.mp3',
4237,
'https://static.audiomeans.fr/img/episode/8fd10e53-385b-4be5-ab1e-919dc0ffef28.jpg',
1987,
'2025-12-03'
);
-- 6. Associate tags to podcasts
INSERT INTO public.podcast_tags (podcast_id, tag_id) VALUES INSERT INTO public.podcast_tags (podcast_id, tag_id) VALUES
-- Creative Commons Search Engine -- Alice Underground
('c1000000-0000-0000-0000-000000000001', 'b1000000-0000-0000-0000-000000000002'), -- Open Source ('c1000000-0000-0000-0000-000000000001', 'b1000000-0000-0000-0000-000000000001'), -- Talk Show
('c1000000-0000-0000-0000-000000000001', 'b1000000-0000-0000-0000-000000000001'), -- Technologie ('c1000000-0000-0000-0000-000000000001', 'b1000000-0000-0000-0000-000000000003'), -- Culture
-- Alpha Centauri ('c1000000-0000-0000-0000-000000000002', 'b1000000-0000-0000-0000-000000000005'), -- Cinema
('c1000000-0000-0000-0000-000000000002', 'b1000000-0000-0000-0000-000000000003'), -- Jeux Video ('c1000000-0000-0000-0000-000000000002', 'b1000000-0000-0000-0000-000000000007'), -- Societe
('c1000000-0000-0000-0000-000000000002', 'b1000000-0000-0000-0000-000000000004'), -- Tutoriel ('c1000000-0000-0000-0000-000000000003', 'b1000000-0000-0000-0000-000000000008'), -- Rap
-- Comment se faire des amis ('c1000000-0000-0000-0000-000000000003', 'b1000000-0000-0000-0000-000000000010'), -- Interview
('c1000000-0000-0000-0000-000000000003', 'b1000000-0000-0000-0000-000000000008'), -- Vie Quotidienne ('c1000000-0000-0000-0000-000000000004', 'b1000000-0000-0000-0000-000000000002'), -- Comedie
('c1000000-0000-0000-0000-000000000003', 'b1000000-0000-0000-0000-000000000005'), -- Culture ('c1000000-0000-0000-0000-000000000004', 'b1000000-0000-0000-0000-000000000007'), -- Societe
-- Thunderbird ('c1000000-0000-0000-0000-000000000005', 'b1000000-0000-0000-0000-000000000005'), -- Cinema
('c1000000-0000-0000-0000-000000000004', 'b1000000-0000-0000-0000-000000000007'), -- Productivite ('c1000000-0000-0000-0000-000000000005', 'b1000000-0000-0000-0000-000000000009'), -- Humour
('c1000000-0000-0000-0000-000000000004', 'b1000000-0000-0000-0000-000000000001'), -- Technologie ('c1000000-0000-0000-0000-000000000006', 'b1000000-0000-0000-0000-000000000003'), -- Culture
-- Equalisation podcast ('c1000000-0000-0000-0000-000000000006', 'b1000000-0000-0000-0000-000000000010'), -- Interview
('c1000000-0000-0000-0000-000000000005', 'b1000000-0000-0000-0000-000000000012'), -- Podcasting ('c1000000-0000-0000-0000-000000000007', 'b1000000-0000-0000-0000-000000000004'), -- Musique
('c1000000-0000-0000-0000-000000000005', 'b1000000-0000-0000-0000-000000000004'), -- Tutoriel ('c1000000-0000-0000-0000-000000000007', 'b1000000-0000-0000-0000-000000000011'), -- French Touch
-- USBimager ('c1000000-0000-0000-0000-000000000008', 'b1000000-0000-0000-0000-000000000004'), -- Musique
('c1000000-0000-0000-0000-000000000006', 'b1000000-0000-0000-0000-000000000011'), -- Linux ('c1000000-0000-0000-0000-000000000008', 'b1000000-0000-0000-0000-000000000011'), -- French Touch
('c1000000-0000-0000-0000-000000000006', 'b1000000-0000-0000-0000-000000000002'), -- Open Source ('c1000000-0000-0000-0000-000000000009', 'b1000000-0000-0000-0000-000000000004'), -- Musique
-- Mesa Verde ('c1000000-0000-0000-0000-000000000009', 'b1000000-0000-0000-0000-000000000001'), -- Talk Show
('c1000000-0000-0000-0000-000000000007', 'b1000000-0000-0000-0000-000000000006'), -- Voyage ('c1000000-0000-0000-0000-000000000010', 'b1000000-0000-0000-0000-000000000004'), -- Musique
('c1000000-0000-0000-0000-000000000007', 'b1000000-0000-0000-0000-000000000005'), -- Culture ('c1000000-0000-0000-0000-000000000010', 'b1000000-0000-0000-0000-000000000010'), -- Interview
-- Snipping Tool -- Small Talk
('c1000000-0000-0000-0000-000000000008', 'b1000000-0000-0000-0000-000000000010'), -- Windows ('c2000000-0000-0000-0000-000000000001', 'b1000000-0000-0000-0000-000000000009'), -- Humour
('c1000000-0000-0000-0000-000000000008', 'b1000000-0000-0000-0000-000000000001'), -- Technologie ('c2000000-0000-0000-0000-000000000001', 'b1000000-0000-0000-0000-000000000010'), -- Interview
-- Cory Doctorow - Copyright trolls ('c2000000-0000-0000-0000-000000000002', 'b1000000-0000-0000-0000-000000000002'), -- Comedie
('c1000000-0000-0000-0000-000000000009', 'b1000000-0000-0000-0000-000000000009'), -- Droit Numerique ('c2000000-0000-0000-0000-000000000002', 'b1000000-0000-0000-0000-000000000009'), -- Humour
('c1000000-0000-0000-0000-000000000009', 'b1000000-0000-0000-0000-000000000002'); -- Open Source ('c2000000-0000-0000-0000-000000000003', 'b1000000-0000-0000-0000-000000000008'), -- Rap
('c2000000-0000-0000-0000-000000000003', 'b1000000-0000-0000-0000-000000000009'), -- Humour
('c2000000-0000-0000-0000-000000000004', 'b1000000-0000-0000-0000-000000000002'), -- Comedie
('c2000000-0000-0000-0000-000000000004', 'b1000000-0000-0000-0000-000000000001'), -- Talk Show
('c2000000-0000-0000-0000-000000000005', 'b1000000-0000-0000-0000-000000000004'), -- Musique
('c2000000-0000-0000-0000-000000000005', 'b1000000-0000-0000-0000-000000000010'), -- Interview
('c2000000-0000-0000-0000-000000000006', 'b1000000-0000-0000-0000-000000000009'), -- Humour
('c2000000-0000-0000-0000-000000000006', 'b1000000-0000-0000-0000-000000000007'), -- Societe
('c2000000-0000-0000-0000-000000000007', 'b1000000-0000-0000-0000-000000000005'), -- Cinema
('c2000000-0000-0000-0000-000000000007', 'b1000000-0000-0000-0000-000000000010'), -- Interview
('c2000000-0000-0000-0000-000000000008', 'b1000000-0000-0000-0000-000000000004'), -- Musique
('c2000000-0000-0000-0000-000000000008', 'b1000000-0000-0000-0000-000000000003'), -- Culture
('c2000000-0000-0000-0000-000000000009', 'b1000000-0000-0000-0000-000000000004'), -- Musique
('c2000000-0000-0000-0000-000000000009', 'b1000000-0000-0000-0000-000000000012'), -- Noel
('c2000000-0000-0000-0000-000000000010', 'b1000000-0000-0000-0000-000000000008'), -- Rap
('c2000000-0000-0000-0000-000000000010', 'b1000000-0000-0000-0000-000000000001'), -- Talk Show
('c2000000-0000-0000-0000-000000000011', 'b1000000-0000-0000-0000-000000000002'), -- Comedie
('c2000000-0000-0000-0000-000000000011', 'b1000000-0000-0000-0000-000000000009'); -- Humour
-- 7. Likes
-- 5. Add some likes
INSERT INTO public.likes (user_id, podcast_id) VALUES INSERT INTO public.likes (user_id, podcast_id) VALUES
('a1000000-0000-0000-0000-000000000001', 'c1000000-0000-0000-0000-000000000003'), -- Alice likes Small Talk episodes
('a1000000-0000-0000-0000-000000000001', 'c1000000-0000-0000-0000-000000000009'), ('a1000000-0000-0000-0000-000000000001', 'c2000000-0000-0000-0000-000000000004'),
('a1000000-0000-0000-0000-000000000001', 'c2000000-0000-0000-0000-000000000008'),
('a1000000-0000-0000-0000-000000000001', 'c2000000-0000-0000-0000-000000000009'),
-- David likes Alice Underground episodes
('a1000000-0000-0000-0000-000000000002', 'c1000000-0000-0000-0000-000000000001'), ('a1000000-0000-0000-0000-000000000002', 'c1000000-0000-0000-0000-000000000001'),
('a1000000-0000-0000-0000-000000000002', 'c1000000-0000-0000-0000-000000000007'), ('a1000000-0000-0000-0000-000000000002', 'c1000000-0000-0000-0000-000000000006'),
('a1000000-0000-0000-0000-000000000002', 'c1000000-0000-0000-0000-000000000009'), ('a1000000-0000-0000-0000-000000000002', 'c1000000-0000-0000-0000-000000000010'),
('a1000000-0000-0000-0000-000000000003', 'c1000000-0000-0000-0000-000000000005'), -- Sara likes various
('a1000000-0000-0000-0000-000000000003', 'c1000000-0000-0000-0000-000000000003'), ('a1000000-0000-0000-0000-000000000003', 'c1000000-0000-0000-0000-000000000002'),
('a1000000-0000-0000-0000-000000000004', 'c1000000-0000-0000-0000-000000000001'), ('a1000000-0000-0000-0000-000000000003', 'c2000000-0000-0000-0000-000000000007'),
('a1000000-0000-0000-0000-000000000003', 'c2000000-0000-0000-0000-000000000006'),
-- Bigflo likes rap episodes
('a1000000-0000-0000-0000-000000000004', 'c2000000-0000-0000-0000-000000000003'),
('a1000000-0000-0000-0000-000000000004', 'c2000000-0000-0000-0000-000000000010'),
('a1000000-0000-0000-0000-000000000004', 'c1000000-0000-0000-0000-000000000003'), ('a1000000-0000-0000-0000-000000000004', 'c1000000-0000-0000-0000-000000000003'),
('a1000000-0000-0000-0000-000000000004', 'c1000000-0000-0000-0000-000000000007'), -- Mika likes his own episodes and others
('a1000000-0000-0000-0000-000000000005', 'c1000000-0000-0000-0000-000000000003'), ('a1000000-0000-0000-0000-000000000005', 'c1000000-0000-0000-0000-000000000006'),
('a1000000-0000-0000-0000-000000000005', 'c1000000-0000-0000-0000-000000000005'), ('a1000000-0000-0000-0000-000000000005', 'c2000000-0000-0000-0000-000000000008'),
('a1000000-0000-0000-0000-000000000005', 'c1000000-0000-0000-0000-000000000007'); ('a1000000-0000-0000-0000-000000000005', 'c2000000-0000-0000-0000-000000000001');
-- 8. Comments
-- 6. Add some comments
INSERT INTO public.comments (id, user_id, podcast_id, content, created_at) VALUES INSERT INTO public.comments (id, user_id, podcast_id, content, created_at) VALUES
('d1000000-0000-0000-0000-000000000001', 'a1000000-0000-0000-0000-000000000002', 'c1000000-0000-0000-0000-000000000001', 'Super episode ! Je ne connaissais pas Openverse, merci pour la decouverte.', NOW() - INTERVAL '1 day'), ('d1000000-0000-0000-0000-000000000001', 'a1000000-0000-0000-0000-000000000003', 'c1000000-0000-0000-0000-000000000002', 'Merci Alice pour cet episode, ca fait du bien d''entendre des conversations aussi libres !', NOW() - INTERVAL '1 day'),
('d1000000-0000-0000-0000-000000000002', 'a1000000-0000-0000-0000-000000000003', 'c1000000-0000-0000-0000-000000000001', 'Tres utile pour trouver du contenu libre. Je recommande aussi ccMixter pour la musique.', NOW() - INTERVAL '12 hours'), ('d1000000-0000-0000-0000-000000000002', 'a1000000-0000-0000-0000-000000000004', 'c1000000-0000-0000-0000-000000000003', 'Le passage sur le business est tellement vrai. Bigflo c''est un vrai patron.', NOW() - INTERVAL '2 days'),
('d1000000-0000-0000-0000-000000000003', 'a1000000-0000-0000-0000-000000000001', 'c1000000-0000-0000-0000-000000000003', 'J''adore ce format de discussion decontractee. On s''y retrouve tous un peu !', NOW() - INTERVAL '2 days'), ('d1000000-0000-0000-0000-000000000003', 'a1000000-0000-0000-0000-000000000002', 'c1000000-0000-0000-0000-000000000006', 'Trapenard en detective amateur c''est exactement le contenu dont on avait besoin.', NOW() - INTERVAL '3 days'),
('d1000000-0000-0000-0000-000000000004', 'a1000000-0000-0000-0000-000000000004', 'c1000000-0000-0000-0000-000000000003', 'Tellement vrai ce qui est dit sur les communautes en ligne. Bel episode.', NOW() - INTERVAL '2 days'), ('d1000000-0000-0000-0000-000000000004', 'a1000000-0000-0000-0000-000000000001', 'c2000000-0000-0000-0000-000000000004', 'Jeremy Ferrari est incroyable dans cet episode. David sait poser les bonnes questions !', NOW() - INTERVAL '1 day'),
('d1000000-0000-0000-0000-000000000005', 'a1000000-0000-0000-0000-000000000005', 'c1000000-0000-0000-0000-000000000009', 'Ce sujet me tient a coeur. Les trolls du copyright sont un vrai probleme pour le libre.', NOW() - INTERVAL '7 days'), ('d1000000-0000-0000-0000-000000000005', 'a1000000-0000-0000-0000-000000000005', 'c2000000-0000-0000-0000-000000000009', 'Mon episode prefere ! Le cousin exorciste m''a tue de rire.', NOW() - INTERVAL '5 days'),
('d1000000-0000-0000-0000-000000000006', 'a1000000-0000-0000-0000-000000000001', 'c1000000-0000-0000-0000-000000000005', 'Exactement ce qu''il me fallait pour ameliorer le son de mon podcast. Merci !', NOW() - INTERVAL '3 days'), ('d1000000-0000-0000-0000-000000000006', 'a1000000-0000-0000-0000-000000000003', 'c2000000-0000-0000-0000-000000000007', 'Pierre Niney est tellement drole quand il parle de baby-sitting. Chef d''oeuvre.', NOW() - INTERVAL '4 days'),
('d1000000-0000-0000-0000-000000000007', 'a1000000-0000-0000-0000-000000000002', 'c1000000-0000-0000-0000-000000000007', 'Mesa Verde a l''air magnifique. Ca donne envie de voyager !', NOW() - INTERVAL '20 hours'), ('d1000000-0000-0000-0000-000000000007', 'a1000000-0000-0000-0000-000000000004', 'c2000000-0000-0000-0000-000000000003', 'Caballero & JeanJass dans Small Talk c''est le crossover qu''on attendait tous.', NOW() - INTERVAL '2 days'),
('d1000000-0000-0000-0000-000000000008', 'a1000000-0000-0000-0000-000000000003', 'c1000000-0000-0000-0000-000000000002', 'Alpha Centauri, quel classique ! J''attends la partie 2 avec impatience.', NOW() - INTERVAL '4 days'); ('d1000000-0000-0000-0000-000000000008', 'a1000000-0000-0000-0000-000000000002', 'c1000000-0000-0000-0000-000000000010', 'Mika est un conteur ne. L''episode dans la foret est magique.', NOW() - INTERVAL '6 days'),
('d1000000-0000-0000-0000-000000000009', 'a1000000-0000-0000-0000-000000000001', 'c2000000-0000-0000-0000-000000000008', 'L''episode avec Julien Dore m''a fait pleurer et rire en meme temps. Bravo David.', NOW() - INTERVAL '3 days'),
('d1000000-0000-0000-0000-000000000010', 'a1000000-0000-0000-0000-000000000005', 'c2000000-0000-0000-0000-000000000006', 'Cyprien dans Small Talk, on en redemande ! Le palmares des sueurs est legendaire.', NOW() - INTERVAL '7 days');
-- 9. Follows
-- 7. Add some follows
INSERT INTO public.follows (follower_id, following_id) VALUES INSERT INTO public.follows (follower_id, following_id) VALUES
('a1000000-0000-0000-0000-000000000001', 'a1000000-0000-0000-0000-000000000005'), ('a1000000-0000-0000-0000-000000000002', 'a1000000-0000-0000-0000-000000000001'), -- David suit Alice
('a1000000-0000-0000-0000-000000000002', 'a1000000-0000-0000-0000-000000000001'), ('a1000000-0000-0000-0000-000000000001', 'a1000000-0000-0000-0000-000000000002'), -- Alice suit David
('a1000000-0000-0000-0000-000000000002', 'a1000000-0000-0000-0000-000000000003'), ('a1000000-0000-0000-0000-000000000003', 'a1000000-0000-0000-0000-000000000001'), -- Sara suit Alice
('a1000000-0000-0000-0000-000000000003', 'a1000000-0000-0000-0000-000000000002'), ('a1000000-0000-0000-0000-000000000003', 'a1000000-0000-0000-0000-000000000002'), -- Sara suit David
('a1000000-0000-0000-0000-000000000003', 'a1000000-0000-0000-0000-000000000005'), ('a1000000-0000-0000-0000-000000000004', 'a1000000-0000-0000-0000-000000000001'), -- Bigflo suit Alice
('a1000000-0000-0000-0000-000000000004', 'a1000000-0000-0000-0000-000000000001'), ('a1000000-0000-0000-0000-000000000004', 'a1000000-0000-0000-0000-000000000002'), -- Bigflo suit David
('a1000000-0000-0000-0000-000000000004', 'a1000000-0000-0000-0000-000000000002'), ('a1000000-0000-0000-0000-000000000005', 'a1000000-0000-0000-0000-000000000001'), -- Mika suit Alice
('a1000000-0000-0000-0000-000000000005', 'a1000000-0000-0000-0000-000000000003'); ('a1000000-0000-0000-0000-000000000005', 'a1000000-0000-0000-0000-000000000002'); -- Mika suit David