Last active
September 3, 2019 16:34
-
-
Save Kefta/b1d058b3420e4bd41164729d06da1c20 to your computer and use it in GitHub Desktop.
Lua program for planning my radio show
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--[=[ | |
// 2019-09-03 - 2:48:49 // | |
[1] Ghettotech/Juke/Footwork - 24:18 | |
1.Feelin - DJ Rashad feat. DJ Spinn & Taso - Double Cup - 4:31 | |
2.Feelin' - DJ Rashad - TEKLIFE Vol. 1: Welcome to the Chi - 4:02 | |
3.Move Da Booty - D.J. Funk - Booty House Anthems 2 - 0:28 | |
4.Have'n Sex ???? Hell Yea!!!!! - D.J. Funk - Booty House Anthems 2 - 1:15 | |
5.Footworkin on Air - Traxman - Da Mind of Traxman - 4:01 | |
6.Itz Crack - Traxman - Da Mind of Traxman - 3:02 | |
7.Sound Filed - Traxman - Da Mind of Traxman - 2:51 | |
8.Double Cup - DJ Rashad feat. DJ Spinn - Double Cup - 4:08 | |
[2] Ambient Techno - 35:10 | |
1.Session Add - Skee Mask - Compro - 6:20 | |
2.Quadrant Dub I - Basic Channel - Quadrant Dub I - 15:36 | |
3.Phylyps Trak Ii/Ii - Basic Channel - Phylyps Trak II - 13:14 | |
[3] Nu Disco/Future Funk/Synth Funk - 23:13 | |
1.A Different Feeling - The Avalanches - Since I Left You - 4:23 | |
2.Black Hole - Kelley Polar - Love Songs of the Hanging Gardens - 4:50 | |
3.Vocalise (From Here To Polarity - Kelley Polar - Love Songs of the Hanging Gardens - 3:55 | |
4.Feelings of Sentimentality Due to Getting Curved - Flamingosis - Bright Moments - 3:16 | |
5.Strange - DJ Screw & Cameo - Chapter 214: Old School - 6:49 | |
[4] UK Garage/Future Garage - 25:45 | |
1.Raver - Burial - Untrue - 5:00 | |
2.White Noise - Disclosure feat. AlunaGeorge - Seattle - 4:38 | |
3.Sincere - Re-Cue'D - MJ Cole feat. Nova Casper & Jay Dee - Sincere - 5:39 | |
4.Right Thing to Do - SBTRKT feat. Jessie Ware - SBTRKT - 3:23 | |
5.Unluck - James Blake - James Blake - 3:00 | |
6.Flatline - Vacant - Origins - 4:05 | |
[5] Instrumental Hip Hop/Lo-fi Hip Hop/Glitch Hop - 25:58 | |
1.Falling 4 U - SwuM & Jinsang - Blossoms - 2:05 | |
2.chief. - who knows - 2:16 | |
3.HORIZONTAL - YAYAYI - YAYAYI - 11:19 | |
4.Ice $ Cold $ Ocean - NxxxxxS - Fujita Scale - 5:09 | |
5.[][][][][][][][][]][[][][][][][[]?[[[][]][[][][][][]][]][][][][][]][][][][][][][][]][]][[][][]. 333% - ATIVAN COREA - 5:09 | |
[6] Industrial Techno/Breaks/EBM - 34:25 | |
1.Fuck Da Police - Anne KGB - 15:00 | |
2.Hidden Power (Phase d) - Machine Girl - WLFGRL - 8:39 | |
3.Splitter - Fixmer / McCarthy - Between the Devil - 6:01 | |
4.Meat Beat Manifesto - Psyche-Out - 99% - 4:45 | |
]=] | |
local Show = (dofile or include)("show_planner.lua").Show | |
print(Show("2019-09-03", {{ | |
Title = "Ghettotech/Juke/Footwork", | |
Tracks = { | |
{"Feelin", "DJ Rashad feat. DJ Spinn & Taso", "Double Cup", "4:31"}, | |
{"Feelin'", "DJ Rashad", "TEKLIFE Vol. 1: Welcome to the Chi", "4:02"}, | |
{"Move Da Booty", "D.J. Funk", "Booty House Anthems 2", "0:28"}, | |
{"Have'n Sex ???? Hell Yea!!!!!", "D.J. Funk", "Booty House Anthems 2", "1:15"}, | |
{"Footworkin on Air", "Traxman", "Da Mind of Traxman", "4:01"}, | |
{"Itz Crack", "Traxman", "Da Mind of Traxman", "3:02"}, | |
{"Sound Filed", "Traxman", "Da Mind of Traxman", "2:51"}, | |
{"Double Cup", "DJ Rashad feat. DJ Spinn", "Double Cup", "4:08"} | |
} | |
},{ | |
Title = "Ambient Techno", | |
Tracks = { | |
{"Session Add", "Skee Mask", "Compro", "6:20"}, | |
{"Quadrant Dub I", "Basic Channel", "Quadrant Dub I", "15:36"}, | |
{"Phylyps Trak Ii/Ii", "Basic Channel", "Phylyps Trak II", "13:14"} | |
} | |
},{ | |
Title = "Nu Disco/Future Funk/Synth Funk", | |
Tracks = { | |
{"A Different Feeling", "The Avalanches", "Since I Left You", "4:23"}, | |
{"Black Hole", "Kelley Polar", "Love Songs of the Hanging Gardens", "4:50"}, | |
{"Vocalise (From Here To Polarity", "Kelley Polar", "Love Songs of the Hanging Gardens", "3:55"}, | |
{"Feelings of Sentimentality Due to Getting Curved", "Flamingosis", "Bright Moments", "3:16"}, | |
{"Strange", "DJ Screw & Cameo", "Chapter 214: Old School", "6:49"} | |
} | |
},{ | |
Title = "UK Garage/Future Garage", | |
Tracks = { | |
{"Raver", "Burial", "Untrue", "5:00"}, | |
{"White Noise", "Disclosure feat. AlunaGeorge", "Seattle", "4:38"}, | |
{"Sincere - Re-Cue'D", "MJ Cole feat. Nova Casper & Jay Dee", "Sincere", "5:39"}, | |
{"Right Thing to Do", "SBTRKT feat. Jessie Ware", "SBTRKT", "3:23"}, | |
{"Unluck", "James Blake", "James Blake", "3:00"}, | |
{"Flatline", "Vacant", "Origins", "4:05"} | |
} | |
},{ | |
Title = "Instrumental Hip Hop/Lo-fi Hip Hop/Glitch Hop", | |
Tracks = { | |
{"Falling 4 U", "SwuM & Jinsang", "Blossoms", "2:05"}, | |
{"chief.", "who knows", nil, "2:16"}, | |
{"HORIZONTAL", "YAYAYI", "YAYAYI", "11:19"}, | |
{"Ice $ Cold $ Ocean", "NxxxxxS", "Fujita Scale", "5:09"}, | |
{"[][][][][][][][][]][[][][][][][[][[[][]][[][][][][]][]][][][][][]][][][][][][][][]][]][[][][]. 333%", "ATIVAN COREA", nil, "5:09"} | |
} | |
},{ | |
Title = "Industrial Techno/Breaks/EBM", | |
Tracks = { | |
{"Fuck Da Police", "Anne KGB", nil, "15:00"}, | |
{"Hidden Power (Phase d)", "Machine Girl", "WLFGRL", "8:39"}, | |
{"Splitter", "Fixmer / McCarthy", "Between the Devil", "6:01"}, | |
{"Meat Beat Manifesto", "Psyche-Out", "99%", "4:45"} | |
} | |
}})) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local planner = {} | |
local function FormatSubTime(uSeconds) | |
return uSeconds < 10 and "0" .. uSeconds or uSeconds | |
end | |
local function Time(uHours, uMinutes, uSeconds) | |
if (uSeconds == nil) then | |
if (uMinutes == nil) then | |
return "00:" .. FormatSubTime(uHours) | |
end | |
return uHours .. ":" .. FormatSubTime(uMinutes) | |
end | |
if (uHours == 0) then | |
return uMinutes .. ":" .. FormatSubTime(uSeconds) | |
end | |
return uHours .. ":" .. FormatSubTime(uMinutes) .. ":" .. FormatSubTime(uSeconds) | |
end | |
local function AddTime(uHours, uMinutes, uSeconds, uTotalHours, uTotalMinutes, uTotalSeconds) | |
uTotalSeconds = uTotalSeconds + uSeconds | |
if (uTotalSeconds > 60) then | |
uTotalMinutes = uTotalMinutes + 1 | |
uTotalSeconds = uTotalSeconds - 60 | |
end | |
uTotalMinutes = uTotalMinutes + uMinutes | |
if (uTotalMinutes > 60) then | |
uTotalHours = uTotalHours + 1 | |
uTotalMinutes = uTotalMinutes - 60 | |
end | |
return uTotalHours + uHours, uTotalMinutes, uTotalSeconds | |
end | |
local function GetTime(sTime) | |
local uSep = string.find(sTime, ":") | |
if (uSep == nil) then | |
local uSeconds = tonumber(sTime) | |
if (uSeconds == nil) then | |
return nil, nil, nil | |
end | |
local uHours = math.floor(uSeconds / 3600) | |
uSeconds = uSeconds % 3600 | |
return uHours, math.floor(uSeconds / 60), uSeconds % 60 | |
end | |
local uSep2 = string.find(sTime, ":", uSep + 1) | |
local uHours, uMinutes, uSeconds | |
if (uSep2 == nil) then | |
uMinutes = tonumber(string.sub(sTime, 1, uSep - 1)) | |
if (uMinutes == nil) then | |
return nil, nil, nil | |
end | |
uSeconds = tonumber(string.sub(sTime, uSep + 1)) | |
if (uSeconds == nil) then | |
return nil, nil, nil | |
end | |
uHours = 0 | |
else | |
uHours = tonumber(string.sub(sTime, 1, uSep - 1)) | |
if (uHours == nil) then | |
return nil, nil, nil | |
end | |
uMinutes = tonumber(string.sub(sTime, uSep + 1, uSep2 - 1)) | |
if (uMinutes == nil) then | |
return nil, nil, nil | |
end | |
uSeconds = tonumber(string.sub(sTime, uSep2 + 1)) | |
if (uSeconds == nil) then | |
return nil, nil, nil | |
end | |
end | |
uHours = uHours + math.floor(uSeconds / 3600) | |
uSeconds = uSeconds % 3600 | |
return uHours + math.floor(uMinutes / 60), uMinutes % 60 + math.floor(uSeconds / 60), uSeconds % 60 | |
end | |
local SHOW = {__newindex = function() end, __tostring = function(self) return self:ToString() end} | |
function planner.Show(sTitle --[[= "Show"]], tBlockConstructors --[[= {}]]) | |
if (sTitle == nil) then | |
sTitle = "Show" | |
end | |
local tShow = {} | |
local tBlocks = {} | |
local uBlocks | |
if (tBlockConstructors == nil) then | |
uBlocks = 0 | |
else | |
uBlocks = #tBlockConstructors | |
for i = 1, uBlocks do | |
local tBlock = tBlockConstructors[i] | |
tBlocks[i] = planner.Block(tBlock.Title, tBlock.Tracks) | |
end | |
end | |
function tShow:GetTitle() | |
return sTitle | |
end | |
function tShow:SetTitle(sNewTitle) | |
sTitle = sNewTitle | |
end | |
function tShow:GetBlock(uBlockPos) | |
return tBlocks[uBlockPos] | |
end | |
function tShow:SetBlock(uBlockPos, block) | |
for i = uBlocks + 1, uBlockPos - 1 do | |
uBlocks = uBlocks + 1 | |
tBlocks[i] = planner.Block() | |
end | |
uBlocks = uBlocks + 1 | |
tBlocks[uBlockPos] = block | |
end | |
-- function tShow:AddBlock(block) - also supported where uBlockPos will default to tShow:GetBlockCount() | |
function tShow:AddBlock(uBlockPos, block) | |
uBlocks = uBlocks + 1 | |
if (block == nil) then | |
block = uBlockPos | |
uBlockPos = uBlocks | |
end | |
tBlocks[uBlockPos] = block | |
end | |
function tShow:RemoveBlock(uBlockPos --[[= tShow:GetBlockCount()]]) | |
if (uBlocks > 0) then | |
if (uBlockPos == nil) then | |
uBlockPos = uBlocks | |
end | |
uBlocks = uBlocks - 1 | |
tBlocks[uBlocks] = nil | |
end | |
end | |
function tShow:GetBlockCount() | |
return uBlocks | |
end | |
function tShow:GetTime() | |
local uTotalHours, uTotalMinutes, uTotalSeconds = 0, 0, 0 | |
for i = 1, uBlocks do | |
local uHours, uMinutes, uSeconds = tBlocks[i]:GetTime() | |
uTotalHours, uTotalMinutes, uTotalSeconds = AddTime(uHours, uMinutes, uSeconds, uTotalHours, uTotalMinutes, uTotalSeconds) | |
end | |
return uTotalHours, uTotalMinutes, uTotalSeconds | |
end | |
function tShow:ToString() | |
local tStringBuffer = {string.format("// %s - %s //\n", sTitle, Time(self:GetTime()))} | |
for i = 2, uBlocks + 1 do | |
tStringBuffer[i] = string.format("\n[%u] %s", i - 1, tBlocks[i - 1]:ToString()) | |
end | |
return table.concat(tStringBuffer) | |
end | |
return setmetatable(tShow, SHOW) | |
end | |
function planner.IsShow(v) | |
return getmetatable(v) == SHOW | |
end | |
local BLOCK = {__newindex = function() end, __tostring = function(self) return self:ToString() end} | |
function planner.Block(sTitle --[["Block"]], tTrackConstructors --[[{}]]) | |
local tBlock = {} | |
local tTracks = {} | |
local uTracks | |
if (tTrackConstructors == nil) then | |
uTracks = 0 | |
else | |
uTracks = #tTrackConstructors | |
for i = 1, uTracks do | |
local tTrack = tTrackConstructors[i] | |
tTracks[i] = planner.Track(tTrack.Title or tTrack[1], tTrack.Artist or tTrack[2], tTrack.Album or tTrack[3], tTrack.Time or tTrack[4]) | |
end | |
end | |
function tBlock:GetTitle() | |
return sTitle | |
end | |
function tBlock:SetTitle(sNewTitle) | |
sTitle = sNewTitle | |
end | |
function tBlock:GetTrack(uTrackPos) | |
return tTracks[uTrackPos] | |
end | |
function tBlock:SetTrack(uTrackPos, track) | |
for i = uTracks + 1, uTrackPos - 1 do | |
uTracks = uTracks + 1 | |
tTracks[i] = planner.Track() | |
end | |
uTracks = uTracks + 1 | |
tTracks[uTrackPos] = track | |
end | |
-- function tBlock:AddTrack(track) - also supported where uTrackPos will default to tBlock:GetTrackCount() | |
function tBlock:AddTrack(uTrackPos, track) | |
uTracks = uTracks + 1 | |
if (track == nil) then | |
track = uTrackPos | |
uTrackPos = uTracks | |
end | |
tTracks[uTrackPos] = track | |
end | |
function tBlock:RemoveTrack(uTrackPos --[[= tBlock:GetTrackCount()]]) | |
if (uTracks > 0) then | |
if (uTrackPos == nil) then | |
uTrackPos = uTracks | |
end | |
uTracks = uTracks - 1 | |
tTracks[uTracks] = nil | |
end | |
end | |
function tBlock:GetTrackCount() | |
return uTracks | |
end | |
function tBlock:GetTime() | |
local uTotalHours, uTotalMinutes, uTotalSeconds = 0, 0, 0 | |
for i = 1, uTracks do | |
local uHours, uMinutes, uSeconds = tTracks[i]:GetTime() | |
uTotalHours, uTotalMinutes, uTotalSeconds = AddTime(uHours, uMinutes, uSeconds, uTotalHours, uTotalMinutes, uTotalSeconds) | |
end | |
return uTotalHours, uTotalMinutes, uTotalSeconds | |
end | |
function tBlock:ToString() | |
local tStringBuffer = {sTitle .. " - " .. Time(self:GetTime()) .. "\n"} | |
for i = 2, uTracks + 1 do | |
tStringBuffer[i] = string.format("\t%u.%s\n", i - 1, tTracks[i - 1]:ToString()) | |
end | |
return table.concat(tStringBuffer) | |
end | |
return setmetatable(tBlock, BLOCK) | |
end | |
function planner.IsBlock(v) | |
return getmetatable(v) == BLOCK | |
end | |
local TRACK = {__newindex = function() end, __tostring = function(self) return self:ToString() end} | |
function planner.Track(sTitle --[[= ""]], sArtist --[[= ""]], sAlbum --[[= ""]], sTime --[[= ""]]) | |
if (sTitle == nil) then | |
sTitle = "" | |
end | |
if (sArtist == nil) then | |
sArtist = "" | |
end | |
if (sAlbum == nil) then | |
sAlbum = "" | |
end | |
if (sTime == nil) then | |
sTime = "" | |
end | |
local tTrack = {} | |
local uHours, uMinutes, uSeconds = GetTime(sTime) | |
function tTrack:GetTitle() | |
return sTitle | |
end | |
function tTrack:SetTitle(sNewTitle) | |
sTitle = sNewTitle | |
end | |
function tTrack:GetArtist() | |
return sArtist | |
end | |
function tTrack:SetArtist(sNewArtist) | |
sArtist = sNewArtist | |
end | |
function tTrack:GetAlbum() | |
return sAlbum | |
end | |
function tTrack:SetAlbum(sNewAlbum) | |
sAlbum = sNewAlbum | |
end | |
function tTrack:GetTime() | |
return uHours or 0, uMinutes or 0, uSeconds or 0 | |
end | |
function tTrack:ToString() | |
local tStringBuffer = {sTitle} | |
local uBufferPos = 2 | |
if (sArtist ~= "") then | |
tStringBuffer[uBufferPos] = " - " .. sArtist | |
uBufferPos = uBufferPos + 1 | |
end | |
if (sAlbum ~= "") then | |
tStringBuffer[uBufferPos] = " - " .. sAlbum | |
uBufferPos = uBufferPos + 1 | |
end | |
if (uHours ~= nil) then | |
tStringBuffer[uBufferPos] = " - " .. Time(uHours, uMinutes, uSeconds) | |
uBufferPos = uBufferPos + 1 | |
end | |
return table.concat(tStringBuffer) | |
end | |
return setmetatable(tTrack, TRACK) | |
end | |
function planner.IsTrack(v) | |
return getmetatable(v) == TRACK | |
end | |
return planner |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment