diff --git a/modules/SampleData/SampleData.php b/modules/SampleData/SampleData.php new file mode 100644 index 00000000..f546f2b9 --- /dev/null +++ b/modules/SampleData/SampleData.php @@ -0,0 +1,39 @@ +permission_enable('administration', 'import_sample_data', 'import sample data profiles into Observer'); + + return true; + } + + public function uninstall() + { + $this->permission_disable('import_sample_data'); + + return true; + } + + public function purge() + { + $this->permission_delete('import_sample_data'); + + return true; + } +} diff --git a/modules/SampleData/controllers/SampleData.php b/modules/SampleData/controllers/SampleData.php new file mode 100644 index 00000000..4c72c199 --- /dev/null +++ b/modules/SampleData/controllers/SampleData.php @@ -0,0 +1,42 @@ +user->require_permission('import_sample_data'); + $this->SampleDataModel = $this->load->model('SampleData', 'SampleData'); + } + + public function listProfiles() + { + $profiles = $this->SampleDataModel('listProfiles'); + return [true, 'Sample data profiles.', $profiles]; + } + + public function runProfile() + { + $profile = trim((string) $this->data('profile')); + + if ($profile === '' || !preg_match('/^[a-z0-9_]+$/', $profile)) { + return [false, 'Invalid profile name.']; + } + + $result = $this->SampleDataModel('runProfile', $profile); + + if (!$result['success']) { + return [false, $result['error'], ['log' => $result['log']]]; + } + + return [true, 'Sample data imported.', ['log' => $result['log']]]; + } +} diff --git a/modules/SampleData/html/sampledata.html b/modules/SampleData/html/sampledata.html new file mode 100644 index 00000000..93a3a235 --- /dev/null +++ b/modules/SampleData/html/sampledata.html @@ -0,0 +1,23 @@ + + +

Import Sample Data

+ +

Pick a sample data profile and click "Import" to seed your installation. The action is idempotent — items that already exist are skipped, never overwritten.

+ + + + + + + + + + + + +

+ + diff --git a/modules/SampleData/js/sampledata.js b/modules/SampleData/js/sampledata.js new file mode 100644 index 00000000..eb227dca --- /dev/null +++ b/modules/SampleData/js/sampledata.js @@ -0,0 +1,101 @@ +// Copyright 2012-2026 OpenBroadcaster, Inc. +// SPDX-License-Identifier: AGPL-3.0-or-later + +OBModules.SampleData = new Object(); + +OBModules.SampleData.init = function () { + OB.Callbacks.add('ready', 0, OBModules.SampleData.initMenu); +}; + +OBModules.SampleData.initMenu = function () { + OB.UI.addSubMenuItem( + 'admin', + 'Import Sample Data', + 'import_sample_data', + OBModules.SampleData.importPage, + 110, + 'import_sample_data' + ); +}; + +OBModules.SampleData.importPage = function () { + OB.UI.replaceMain('modules/sampledata/sampledata.html'); + + OBModules.SampleData.profiles = {}; + $('#sampledata_module-profile').html(''); + $('#sampledata_module-import').prop('disabled', true); + $('#sampledata_module-log').hide().text(''); + + OB.API.post('sampledata', 'listProfiles', {}, function (response) { + if (!response.status) { + $('#sampledata_module-info').text('Error loading sample data profiles.'); + return; + } + + var profiles = response.data || []; + var $select = $('#sampledata_module-profile'); + $select.empty(); + + if (profiles.length === 0) { + $select.append(''); + $('#sampledata_module-import').prop('disabled', true); + return; + } + + $.each(profiles, function (_, profile) { + OBModules.SampleData.profiles[profile.directory] = profile; + $select.append( + $('').val(profile.directory).text(profile.name) + ); + }); + + OBModules.SampleData.updateDescription(); + $('#sampledata_module-import').prop('disabled', false); + }); + + $('#sampledata_module-profile').off('change').on('change', OBModules.SampleData.updateDescription); + $('#sampledata_module-import').off('click').on('click', function () { + OBModules.SampleData.runImport(false); + }); +}; + +OBModules.SampleData.updateDescription = function () { + var dir = $('#sampledata_module-profile').val(); + var profile = OBModules.SampleData.profiles[dir]; + $('#sampledata_module-description').text(profile ? (profile.description || '') : ''); +}; + +OBModules.SampleData.runImport = function (confirmed) { + var dir = $('#sampledata_module-profile').val(); + if (!dir) { + return; + } + + if (!confirmed) { + OB.UI.confirm( + 'Import sample data profile "' + dir + '"?\n\nThis will create permission groups, users, playlists, a sample player and schedule, and apply settings. The action is idempotent — existing items are skipped — but it cannot be undone.', + function () { OBModules.SampleData.runImport(true); }, + 'Yes, Import', + 'No, Cancel', + 'delete' + ); + return; + } + + $('#sampledata_module-info').text('Importing…'); + $('#sampledata_module-import').prop('disabled', true); + $('#sampledata_module-log').show().text(''); + + OB.API.post('sampledata', 'runProfile', { profile: dir }, function (response) { + var log = (response.data && response.data.log) ? response.data.log.join('\n') : ''; + $('#sampledata_module-log').text(log); + + if (response.status) { + $('#sampledata_module-info').text('Sample data imported.'); + } else { + $('#sampledata_module-info').text('Import failed: ' + (response.msg || 'unknown error')); + } + + $('#sampledata_module-import').prop('disabled', false); + }); +}; diff --git a/modules/SampleData/profiles/en_community_radio/categories.json b/modules/SampleData/profiles/en_community_radio/categories.json new file mode 100644 index 00000000..f535ebdc --- /dev/null +++ b/modules/SampleData/profiles/en_community_radio/categories.json @@ -0,0 +1,22 @@ +[ + "Commercial Ad", + "Community Events", + "Documents", + "Images", + "Interviews", + "Lecture Talk or Discussion", + "Music", + "News", + "Pop Vox", + "Priority Broadcast", + "PSA Audio", + "PSA Image", + "PSA Video", + "SFX", + "Show Promotion", + "Show Sponsor", + "Shows Complete", + "Station ID", + "Video", + "VoiceTrack" +] diff --git a/modules/SampleData/profiles/en_community_radio/genres.json b/modules/SampleData/profiles/en_community_radio/genres.json new file mode 100644 index 00000000..d9774f9f --- /dev/null +++ b/modules/SampleData/profiles/en_community_radio/genres.json @@ -0,0 +1,307 @@ +{ + "Music": [ + {"name": "Blues", "description": "Blues"}, + {"name": "Classic Rock", "description": "Classic Rock"}, + {"name": "Country", "description": "Country"}, + {"name": "Dance", "description": "Dance"}, + {"name": "Disco", "description": "Disco"}, + {"name": "Funk", "description": "Funk"}, + {"name": "Grunge", "description": "Grunge"}, + {"name": "Hip Hop", "description": "Hip Hop"}, + {"name": "Jazz", "description": "Jazz"}, + {"name": "Metal", "description": "Metal"}, + {"name": "New Age", "description": "New Age"}, + {"name": "Oldies", "description": "Oldies"}, + {"name": "Other", "description": "Other"}, + {"name": "Pop", "description": "Pop"}, + {"name": "R&B", "description": "R&B"}, + {"name": "Rap", "description": "Rap"}, + {"name": "Reggae", "description": "Reggae"}, + {"name": "Rock", "description": "Rock"}, + {"name": "Techno", "description": "Techno"}, + {"name": "Industrial", "description": "Industrial"}, + {"name": "Alternative", "description": "Alternative"}, + {"name": "Ska", "description": "Ska"}, + {"name": "Death Metal", "description": "Death Metal"}, + {"name": "Pranks", "description": "Pranks"}, + {"name": "Soundtrack", "description": "Soundtrack"}, + {"name": "Euro-Techno", "description": "Euro-Techno"}, + {"name": "Ambient", "description": "Ambient"}, + {"name": "Trip Hop", "description": "Trip Hop"}, + {"name": "Vocal", "description": "Vocal"}, + {"name": "Jazz+Funk", "description": "Jazz+Funk"}, + {"name": "Fusion", "description": "Fusion"}, + {"name": "Trance", "description": "Trance"}, + {"name": "Classical", "description": "Classical"}, + {"name": "Instrumental", "description": "Instrumental"}, + {"name": "Acid", "description": "Acid"}, + {"name": "House", "description": "House"}, + {"name": "Game", "description": "Game"}, + {"name": "Sound Clip", "description": "Sound Clip"}, + {"name": "Gospel", "description": "Gospel"}, + {"name": "Noise", "description": "Noise"}, + {"name": "AlternRock", "description": "Alternative Rock"}, + {"name": "Bass", "description": "Bass"}, + {"name": "Soul", "description": "Soul"}, + {"name": "Punk", "description": "Punk"}, + {"name": "Space", "description": "Space"}, + {"name": "Meditative", "description": "Meditative"}, + {"name": "Instrumental Pop", "description": "Instrumental Pop"}, + {"name": "Instrumental Rock", "description": "Instrumental Rock"}, + {"name": "Ethnic", "description": "Ethnic"}, + {"name": "Gothic", "description": "Gothic"}, + {"name": "Darkwave", "description": "Darkwave"}, + {"name": "Techno-Industrial", "description": "Techno-Industrial"}, + {"name": "Electronic", "description": "Electronic"}, + {"name": "Pop-Folk", "description": "Pop-Folk"}, + {"name": "Eurodance", "description": "Eurodance"}, + {"name": "Dream", "description": "Dream"}, + {"name": "Southern Rock", "description": "Southern Rock"}, + {"name": "Comedy", "description": "Comedy"}, + {"name": "Cult", "description": "Cult"}, + {"name": "Gangsta", "description": "Gangsta"}, + {"name": "Top 40", "description": "Top 40"}, + {"name": "Christian Rap", "description": "Christian Rap"}, + {"name": "Pop/Funk", "description": "Pop/Funk"}, + {"name": "Jungle", "description": "Jungle"}, + {"name": "Native American", "description": "Native American"}, + {"name": "Cabaret", "description": "Cabaret"}, + {"name": "New Wave", "description": "New Wave"}, + {"name": "Psychedelic", "description": "Psychedelic"}, + {"name": "Rave", "description": "Rave"}, + {"name": "Showtunes", "description": "Showtunes"}, + {"name": "Trailer", "description": "Trailer"}, + {"name": "Lo-Fi", "description": "Lo-Fi"}, + {"name": "Tribal", "description": "Tribal"}, + {"name": "Acid Punk", "description": "Acid Punk"}, + {"name": "Acid Jazz", "description": "Acid Jazz"}, + {"name": "Polka", "description": "Polka"}, + {"name": "Retro", "description": "Retro"}, + {"name": "Musical", "description": "Musical"}, + {"name": "Rock & Roll", "description": "Rock & Roll"}, + {"name": "Hard Rock", "description": "Hard Rock"}, + {"name": "Folk", "description": "Folk"}, + {"name": "Folk-Rock", "description": "Folk-Rock"}, + {"name": "National Folk", "description": "National Folk"}, + {"name": "Swing", "description": "Swing"}, + {"name": "Fast Fusion", "description": "Fast Fusion"}, + {"name": "Bebop", "description": "Bebop"}, + {"name": "Latin", "description": "Latin"}, + {"name": "Revival", "description": "Revival"}, + {"name": "Celtic", "description": "Celtic"}, + {"name": "Bluegrass", "description": "Bluegrass"}, + {"name": "Avantgarde", "description": "Avantgarde"}, + {"name": "Gothic Rock", "description": "Gothic Rock"}, + {"name": "Progressive Rock", "description": "Progressive Rock"}, + {"name": "Psychedelic Rock", "description": "Psychedelic Rock"}, + {"name": "Symphonic Rock", "description": "Symphonic Rock"}, + {"name": "Slow Rock", "description": "Slow Rock"}, + {"name": "Big Band", "description": "Big Band"}, + {"name": "Chorus", "description": "Chorus"}, + {"name": "Easy Listening", "description": "Easy Listening"}, + {"name": "Acoustic", "description": "Acoustic"}, + {"name": "Humour", "description": "Humour"}, + {"name": "Speech", "description": "Speech"}, + {"name": "Chanson", "description": "Chanson"}, + {"name": "Opera", "description": "Opera"}, + {"name": "Chamber Music", "description": "Chamber Music"}, + {"name": "Sonata", "description": "Sonata"}, + {"name": "Symphony", "description": "Symphony"}, + {"name": "Booty Bass", "description": "Booty Bass"}, + {"name": "Primus", "description": "Primus"}, + {"name": "Porn Groove", "description": "Porn Groove"}, + {"name": "Satire", "description": "Satire"}, + {"name": "Slow Jam", "description": "Slow Jam"}, + {"name": "Club", "description": "Club"}, + {"name": "Tango", "description": "Tango"}, + {"name": "Samba", "description": "Samba"}, + {"name": "Folklore", "description": "Folklore"}, + {"name": "Ballad", "description": "Ballad"}, + {"name": "Power Ballad", "description": "Power Ballad"}, + {"name": "Rhythmic Soul", "description": "Rhythmic Soul"}, + {"name": "Freestyle", "description": "Freestyle"}, + {"name": "Duet", "description": "Duet"}, + {"name": "Punk Rock", "description": "Punk Rock"}, + {"name": "Drum Solo", "description": "Drum Solo"}, + {"name": "A capella", "description": "A capella"}, + {"name": "Euro-House", "description": "Euro-House"}, + {"name": "Dance Hall", "description": "Dance Hall"}, + {"name": "Goa", "description": "Goa"}, + {"name": "Drum & Bass", "description": "Drum & Bass"}, + {"name": "Club-House", "description": "Club-House"}, + {"name": "Hardcore", "description": "Hardcore"}, + {"name": "Terror", "description": "Terror"}, + {"name": "Indie", "description": "Indie"}, + {"name": "BritPop", "description": "BritPop"}, + {"name": "Negerpunk", "description": "Negerpunk"}, + {"name": "Polsk Punk", "description": "Polsk Punk"}, + {"name": "Beat", "description": "Beat"}, + {"name": "Christian Gangsta", "description": "Christian Gangsta"}, + {"name": "Heavy Metal", "description": "Heavy Metal"}, + {"name": "Black Metal", "description": "Black Metal"}, + {"name": "Crossover", "description": "Crossover"}, + {"name": "Contemporary Christian", "description": "Contemporary Christian"}, + {"name": "Christian Rock", "description": "Christian Rock"}, + {"name": "Merengue", "description": "Merengue"}, + {"name": "Salsa", "description": "Salsa"}, + {"name": "Trash Metal", "description": "Trash Metal"}, + {"name": "Anime", "description": "Anime"}, + {"name": "JPop", "description": "JPop"}, + {"name": "Synthpop", "description": "Synthpop"}, + {"name": "World Music", "description": "World Music"}, + {"name": "Yukon", "description": "Local Yukon musicians"} + ], + + "Images": [ + {"name": "Abstract", "description": "Abstract"}, + {"name": "Adults", "description": "Adults"}, + {"name": "Agriculture", "description": "Agriculture"}, + {"name": "Animal", "description": "Animal"}, + {"name": "Architecture", "description": "Architecture"}, + {"name": "Arctic", "description": "Arctic"}, + {"name": "Arts", "description": "Arts"}, + {"name": "Astro Photography", "description": "Astro Photography"}, + {"name": "Baby", "description": "Baby"}, + {"name": "Backgrounds", "description": "Backgrounds"}, + {"name": "Business", "description": "Business"}, + {"name": "Celebrations", "description": "Celebrations"}, + {"name": "Children", "description": "Children"}, + {"name": "City", "description": "City"}, + {"name": "Comedy Funny", "description": "Comedy Funny"}, + {"name": "Communications", "description": "Communications"}, + {"name": "Computers", "description": "Computers"}, + {"name": "Culture", "description": "Culture"}, + {"name": "Documentary", "description": "Documentary"}, + {"name": "Domestic", "description": "Domestic"}, + {"name": "Earth Photos", "description": "Earth Photos"}, + {"name": "Education", "description": "Education"}, + {"name": "Entertainment", "description": "Entertainment"}, + {"name": "Environmental", "description": "Environmental"}, + {"name": "Families", "description": "Families"}, + {"name": "Fantasy", "description": "Fantasy"}, + {"name": "Fine Art", "description": "Fine Art"}, + {"name": "Flowers", "description": "Flowers"}, + {"name": "Food", "description": "Food"}, + {"name": "General", "description": "General"}, + {"name": "Glamour", "description": "Glamour"}, + {"name": "Government", "description": "Government"}, + {"name": "Health", "description": "Health"}, + {"name": "Historic", "description": "Historic"}, + {"name": "Holidays", "description": "Holidays"}, + {"name": "Homes", "description": "Homes"}, + {"name": "Industrial", "description": "Industrial"}, + {"name": "International", "description": "International"}, + {"name": "Landscape", "description": "Landscape"}, + {"name": "Landscapes", "description": "Landscapes"}, + {"name": "Leisure", "description": "Leisure"}, + {"name": "Lifestyles", "description": "Lifestyles"}, + {"name": "Logo", "description": "Logo"}, + {"name": "Love Romance", "description": "Love Romance"}, + {"name": "Manufacturing", "description": "Manufacturing"}, + {"name": "Medical", "description": "Medical"}, + {"name": "Meetings", "description": "Meetings"}, + {"name": "Men", "description": "Men"}, + {"name": "Military", "description": "Military"}, + {"name": "Models", "description": "Models"}, + {"name": "Money", "description": "Money"}, + {"name": "Music", "description": "Music"}, + {"name": "Nature", "description": "Nature"}, + {"name": "Nautical", "description": "Nautical"}, + {"name": "Newspaper", "description": "Newspaper"}, + {"name": "Northern", "description": "Northern"}, + {"name": "Nostalgia", "description": "Nostalgia"}, + {"name": "Office", "description": "Office"}, + {"name": "Other Images", "description": "Other Images"}, + {"name": "Outdoors", "description": "Outdoors"}, + {"name": "Patriotic", "description": "Patriotic"}, + {"name": "Patterns", "description": "Patterns"}, + {"name": "People", "description": "People"}, + {"name": "Personality", "description": "Personality"}, + {"name": "Pets", "description": "Pets"}, + {"name": "Photo Essay", "description": "Photo Essay"}, + {"name": "Political", "description": "Political"}, + {"name": "Portrait", "description": "Portrait"}, + {"name": "Recreation", "description": "Recreation"}, + {"name": "Religion", "description": "Religion"}, + {"name": "Science", "description": "Science"}, + {"name": "Shopping", "description": "Shopping"}, + {"name": "Signs", "description": "Signs"}, + {"name": "Space", "description": "Space"}, + {"name": "Sports", "description": "Sports"}, + {"name": "Still Life", "description": "Still Life"}, + {"name": "Symbols", "description": "Symbols"}, + {"name": "Teamwork", "description": "Teamwork"}, + {"name": "Technology", "description": "Technology"}, + {"name": "Tourism", "description": "Tourism"}, + {"name": "Traditional", "description": "Traditional"}, + {"name": "Trains", "description": "Trains"}, + {"name": "Transportation", "description": "Transportation"}, + {"name": "Travel", "description": "Travel"}, + {"name": "Underwater", "description": "Underwater"}, + {"name": "Vintage", "description": "Vintage"}, + {"name": "Weather", "description": "Weather"}, + {"name": "Weird Animals", "description": "Weird Animals"}, + {"name": "Wildlife", "description": "Wildlife"}, + {"name": "Women", "description": "Women"}, + {"name": "Workplace", "description": "Workplace"} + ], + + "Video": [ + {"name": "Action", "description": "Action"}, + {"name": "Adventure", "description": "Adventure"}, + {"name": "Amateur", "description": "Amateur"}, + {"name": "Animation", "description": "Animation"}, + {"name": "Aviation", "description": "Aviation"}, + {"name": "Biography", "description": "Biography"}, + {"name": "Chick Flicks", "description": "Chick Flicks"}, + {"name": "Christmas Video", "description": "Christmas Video"}, + {"name": "Classic Hollywood", "description": "Classic Hollywood"}, + {"name": "Comedy Funny", "description": "Comedy Funny"}, + {"name": "Crime", "description": "Crime"}, + {"name": "Cult Movies", "description": "Cult Movies"}, + {"name": "Detective Mystery", "description": "Detective Mystery"}, + {"name": "Disaster Films", "description": "Disaster Films"}, + {"name": "Documentary", "description": "Documentary"}, + {"name": "Drama", "description": "Drama"}, + {"name": "Experimental", "description": "Experimental"}, + {"name": "Family", "description": "Family"}, + {"name": "Fantasy", "description": "Fantasy"}, + {"name": "History", "description": "History"}, + {"name": "Horror", "description": "Horror"}, + {"name": "Mockumentary", "description": "Mockumentary"}, + {"name": "Music Concerts", "description": "Music Concerts"}, + {"name": "Musical", "description": "Musical"}, + {"name": "News", "description": "News"}, + {"name": "Northern", "description": "Northern"}, + {"name": "Organized Crime", "description": "Organized Crime"}, + {"name": "Other Video", "description": "Other Video"}, + {"name": "Road Films", "description": "Road Films"}, + {"name": "Satire", "description": "Satire"}, + {"name": "SciFi", "description": "SciFi"}, + {"name": "Short", "description": "Short"}, + {"name": "Silent Movies", "description": "Silent Movies"}, + {"name": "Sport", "description": "Sport"}, + {"name": "Supernatural", "description": "Supernatural"}, + {"name": "Thrillers Suspense", "description": "Thrillers Suspense"}, + {"name": "Trailers", "description": "Trailers"}, + {"name": "War", "description": "War"}, + {"name": "Western", "description": "Western"} + ], + + "SFX": [ + {"name": "Animal Sounds", "description": "Animal Sounds"}, + {"name": "Beatle Bits", "description": "Beatle Bits"}, + {"name": "Christmas", "description": "Christmas"}, + {"name": "Halloween", "description": "Halloween"}, + {"name": "Machine Recordings", "description": "Machine Recordings"}, + {"name": "Movie Bits", "description": "Movie Bits"}, + {"name": "Star Trek", "description": "Star Trek"}, + {"name": "TTS", "description": "Text to Speech"} + ], + + "PSA Audio": [ + {"name": "Disabled", "description": "Disabled"}, + {"name": "Enabled", "description": "Enabled"}, + {"name": "PSA Audio Regular", "description": "PSA Audio Regular"} + ] +} diff --git a/modules/SampleData/profiles/en_community_radio/groups.json b/modules/SampleData/profiles/en_community_radio/groups.json new file mode 100644 index 00000000..8e47f8c9 --- /dev/null +++ b/modules/SampleData/profiles/en_community_radio/groups.json @@ -0,0 +1,22 @@ +[ + { + "name": "Basic", + "permissions": [ + "create_own_media", + "create_own_playlists" + ] + }, + { + "name": "Manager", + "permissions": [ + "create_own_media", + "approve_own_media", + "manage_media", + "create_own_playlists", + "manage_playlists", + "manage_timeslots", + "view_player_monitor", + "download_media" + ] + } +] diff --git a/modules/SampleData/profiles/en_community_radio/manifest.json b/modules/SampleData/profiles/en_community_radio/manifest.json new file mode 100644 index 00000000..d0f0e1f0 --- /dev/null +++ b/modules/SampleData/profiles/en_community_radio/manifest.json @@ -0,0 +1,8 @@ +{ + "name": "English Community Radio Station", + "description": "Sample data profile for an English-language community radio station. Populates categories, genres, users, permission groups, settings, custom metadata fields, playlists, and a sample schedule.", + "version": "1.0.0", + "author": "OpenBroadcaster", + "locale": "en", + "created": "2026-04-01" +} diff --git a/modules/SampleData/profiles/en_community_radio/metadata_fields.json b/modules/SampleData/profiles/en_community_radio/metadata_fields.json new file mode 100644 index 00000000..1111a450 --- /dev/null +++ b/modules/SampleData/profiles/en_community_radio/metadata_fields.json @@ -0,0 +1,38 @@ +[ + { + "name": "internal_memo", + "description": "Internal Memo (Private)", + "type": "textarea", + "visibility": "visible", + "mode": "optional", + "default": "", + "id3_key": "" + }, + { + "name": "physical_tags", + "description": "Physical Tags", + "type": "tags", + "visibility": "public", + "mode": "optional", + "default": "", + "id3_key": "", + "tag_suggestions": [ + "CD", + "Vinyl", + "Cassette", + "Digital", + "Donated", + "Library" + ] + }, + { + "name": "day_parting", + "description": "Day Parting Tags", + "type": "select", + "visibility": "public", + "mode": "optional", + "default": "Anytime", + "id3_key": "", + "select_options": "Morning\nMidday\nAfternoon\nEvening\nOvernight\nAnytime" + } +] diff --git a/modules/SampleData/profiles/en_community_radio/playlists.json b/modules/SampleData/profiles/en_community_radio/playlists.json new file mode 100644 index 00000000..2d3be17f --- /dev/null +++ b/modules/SampleData/profiles/en_community_radio/playlists.json @@ -0,0 +1,26 @@ +[ + { + "name": "Default Playlist", + "description": "Default playlist for the station. Add your most-played content here.", + "type": "standard", + "status": "public" + }, + { + "name": "Sample Music Mix", + "description": "A sample music playlist. Replace with your own music selections.", + "type": "standard", + "status": "public" + }, + { + "name": "Station IDs", + "description": "Station identification audio clips for broadcast compliance.", + "type": "standard", + "status": "public" + }, + { + "name": "Live Assist Board", + "description": "Live assist playlist with quick-access buttons for on-air use.", + "type": "live_assist", + "status": "public" + } +] diff --git a/modules/SampleData/profiles/en_community_radio/schedule.json b/modules/SampleData/profiles/en_community_radio/schedule.json new file mode 100644 index 00000000..8057b15d --- /dev/null +++ b/modules/SampleData/profiles/en_community_radio/schedule.json @@ -0,0 +1,76 @@ +{ + "player": { + "name": "Sample Player", + "timezone": "America/Toronto", + "support_audio": true, + "support_video": true, + "support_images": true + }, + + "shows": [ + { + "title": "Morning Melodies", + "description": "Kickstart your day with the best mix of classic and contemporary tunes.", + "start_time": "06:00", + "duration": 120, + "mode": "daily", + "recurring_days": 180 + }, + { + "title": "News Hour", + "description": "Stay informed with the latest local, national, and international news stories.", + "start_time": "08:00", + "duration": 60, + "mode": "daily", + "recurring_days": 180 + }, + { + "title": "Community Spotlight", + "description": "Highlighting local events, organizations, and people making a difference.", + "start_time": "09:00", + "duration": 120, + "mode": "daily", + "recurring_days": 180 + }, + { + "title": "Lunchtime Jazz", + "description": "Enjoy a selection of smooth jazz tracks during your lunch break.", + "start_time": "11:00", + "duration": 60, + "mode": "daily", + "recurring_days": 180 + }, + { + "title": "Indie Hour", + "description": "Discover emerging indie artists and bands from around the world.", + "start_time": "12:00", + "duration": 60, + "mode": "daily", + "recurring_days": 180 + }, + { + "title": "Drive Time", + "description": "Get the latest traffic updates and upbeat tunes for your drive home.", + "start_time": "15:00", + "duration": 180, + "mode": "daily", + "recurring_days": 180 + }, + { + "title": "Evening Chill", + "description": "Wind down with a mix of calming tracks and ambient sounds.", + "start_time": "18:00", + "duration": 120, + "mode": "daily", + "recurring_days": 180 + }, + { + "title": "Late Night Talk", + "description": "Join the conversation on various topics with expert guests and callers.", + "start_time": "20:00", + "duration": 240, + "mode": "daily", + "recurring_days": 180 + } + ] +} diff --git a/modules/SampleData/profiles/en_community_radio/settings.json b/modules/SampleData/profiles/en_community_radio/settings.json new file mode 100644 index 00000000..1bb2615e --- /dev/null +++ b/modules/SampleData/profiles/en_community_radio/settings.json @@ -0,0 +1,13 @@ +{ + "settings": { + "audio_formats": "flac,mp3,ogg,wav", + "video_formats": "avi,mpg,ogg", + "image_formats": "jpg,png", + "document_formats": "pdf", + "core_metadata": "{\"artist\":\"required\",\"album\":\"required\",\"year\":\"required\",\"category_id\":\"required\",\"country_id\":\"enabled\",\"language_id\":\"enabled\",\"comments\":\"enabled\"}" + }, + + "client_login_message": "Welcome to your Community Radio Station powered by OpenBroadcaster. Please log in to manage your station content, playlists, and schedules.", + + "client_welcome_page": "

Welcome to OpenBroadcaster

Your community radio station is ready to go! Here are some things you can do:

This station has been pre-configured with sample categories, genres, and playlists to help you get started. Feel free to modify or remove them as needed.

Need help? Visit openbroadcaster.com for documentation and support.

" +} diff --git a/modules/SampleData/profiles/en_community_radio/users.json b/modules/SampleData/profiles/en_community_radio/users.json new file mode 100644 index 00000000..0df12eb0 --- /dev/null +++ b/modules/SampleData/profiles/en_community_radio/users.json @@ -0,0 +1,30 @@ +[ + { + "name": "Admin", + "username": "admin", + "email": "admin@example.com", + "display_name": "Admin", + "password": "changeme", + "enabled": true, + "group": "Administrator", + "skip_if_exists": true + }, + { + "name": "Basic User", + "username": "basic_user", + "email": "basic@example.com", + "display_name": "Basic User", + "password": "changeme", + "enabled": true, + "group": "Basic" + }, + { + "name": "Manager", + "username": "manager", + "email": "manager@example.com", + "display_name": "Manager", + "password": "changeme", + "enabled": true, + "group": "Manager" + } +]