|
defmodule Episode do |
|
defstruct id: nil, name: nil, video: nil, markdown: nil, post: nil |
|
|
|
def get_all do |
|
[ |
|
%Episode{id: "001", post: "271", name: "Introduction and Installing Elixir", video: "1366", markdown: "1382"}, |
|
%Episode{id: "002", post: "275", name: "Basic Elixir", video: "1367", markdown: "1357"}, |
|
%Episode{id: "003", post: "280", name: "Pattern Matching", video: "14879", markdown: "1413"}, |
|
%Episode{id: "004", post: "284", name: "Functions", video: "5086", markdown: "1559"}, |
|
%Episode{id: "005", post: "298", name: "Mix and Modules", video: "5087", markdown: "1654"}, |
|
%Episode{id: "006", post: "311", name: "Unit Testing", video: "5090", markdown: "1888"}, |
|
%Episode{id: "007", post: "313", name: "Dynamo, Part 1", video: "5092", markdown: "1927"}, |
|
%Episode{id: "008", post: "317", name: "Dynamo, Part 2", video: "5093", markdown: "2043"}, |
|
%Episode{id: "009", post: "322", name: "Dynamo, Part 3", video: "5094", markdown: "2192"}, |
|
%Episode{id: "010", post: "323", name: "List Comprehensions", video: "12552", markdown: "2247"}, |
|
%Episode{id: "011", post: "324", name: "Records", video: "22098", markdown: "2301"}, |
|
%Episode{id: "012", post: "331", name: "Processes", video: "5097", markdown: "2746"}, |
|
%Episode{id: "013", post: "332", name: "Processes, Part 2", video: "5098", markdown: "2749"}, |
|
%Episode{id: "014", post: "338", name: "OTP Part 1 - Servers", video: "2985", markdown: "2986"}, |
|
%Episode{id: "015", post: "341", name: "OTP Part 2 - Finite State Machines", video: "3064", markdown: "3065"}, |
|
%Episode{id: "016", post: "344", name: "Pipe Operator", video: "3639", markdown: "3637"}, |
|
%Episode{id: "017", post: "348", name: "Enum, Part 1", video: "5068", markdown: "5069"}, |
|
%Episode{id: "018", post: "350", name: "Enum, Part 2", video: "5148", markdown: "5149"}, |
|
%Episode{id: "019", post: "359", name: "Enum, Part 3", video: "5399", markdown: "5400"}, |
|
%Episode{id: "020", post: "361", name: "GenEvent", video: "8379", markdown: "8381"}, |
|
%Episode{id: "021", post: "362", name: "ZeldaCat, Part 2", video: "12321", markdown: "12322"}, |
|
%Episode{id: "022", post: "363", name: "OTP, Part 4 - Supervisors", video: "12346", markdown: "12347"}, |
|
%Episode{id: "023", post: "367", name: "OTP, Part 5 - Supervisors and Persistent State", video: "14512", markdown: "14514"}, |
|
%Episode{id: "024", post: "370", name: "Ecto, Part 1", video: "14801", markdown: "14799"}, |
|
%Episode{id: "025", post: "372", name: "Ecto, Part 2 - Dwitter", video: "14919", markdown: "14920"}, |
|
%Episode{id: "026", post: "376", name: "Dict, Part 1", video: "15379", markdown: "15380"}, |
|
%Episode{id: "027", post: "377", name: "Dict, Part 2", video: "15383", markdown: "15384"}, |
|
%Episode{id: "028", post: "380", name: "Parsing XML", video: "15730", markdown: "15731"}, |
|
%Episode{id: "029", post: "382", name: "HTTP Clients", video: "15819", markdown: "15820"}, |
|
%Episode{id: "030", post: "387", name: "ExActor", video: "16076", markdown: "16077"}, |
|
%Episode{id: "031", post: "389", name: "TCP Servers", video: "16174", markdown: "16175"}, |
|
%Episode{id: "032", post: "392", name: "Command Line Scripts", video: "16426", markdown: "16425"}, |
|
%Episode{id: "033", post: "396", name: "Pry", video: "17312", markdown: "17314"}, |
|
%Episode{id: "034", post: "398", name: "Elixiak", video: "17369", markdown: "17370"}, |
|
%Episode{id: "035", post: "399", name: "Weber", video: "17530", markdown: "17528"}, |
|
%Episode{id: "036", post: "404", name: "Performance", video: "17909", markdown: "17911"}, |
|
%Episode{id: "037", post: "405", name: "ExLager", video: "18020", markdown: "18021"}, |
|
%Episode{id: "038", post: "409", name: "Binaries - Deconstructing and Constructing", video: "18364", markdown: "18365"}, |
|
%Episode{id: "039", post: "411", name: "Binaries - Deconstructing an IP Packet", video: "18433", markdown: "18434"}, |
|
%Episode{id: "040", post: "413", name: "Bitwise", video: "18722", markdown: "18723"}, |
|
%Episode{id: "041", post: "414", name: "File, Part 1", video: "18727", markdown: "18728"}, |
|
%Episode{id: "042", post: "417", name: "File, Part 2", video: "19023", markdown: "19022"}, |
|
%Episode{id: "043", post: "418", name: "Releases With Relex", video: "19102", markdown: "19103"}, |
|
%Episode{id: "044", post: "422", name: "Distribution", video: "19294", markdown: "19295"}, |
|
%Episode{id: "045", post: "424", name: "Distribution, Part 2", video: "19508", markdown: "19507"}, |
|
%Episode{id: "046", post: "428", name: "Markdown Server, Part 1", video: "20035", markdown: "20034"}, |
|
%Episode{id: "047", post: "429", name: "Markdown Server, Part 2", video: "20044", markdown: "20043"}, |
|
%Episode{id: "048", post: "433", name: "Markdown Server, Part 3", video: "20398", markdown: "20400"}, |
|
%Episode{id: "049", post: "434", name: "Markdown Server, Part 4", video: "20484", markdown: "20486"}, |
|
%Episode{id: "050", post: "439", name: "Markdown Server, Part 5", video: "20836", markdown: "20837"}, |
|
%Episode{id: "051", post: "442", name: "BEAM Toolbox, Part 1", video: "21303", markdown: "21304"}, |
|
%Episode{id: "052", post: "444", name: "BEAM Toolbox, Part 2", video: "21529", markdown: "21530"}, |
|
%Episode{id: "053", post: "448", name: "BEAM Toolbox, Part 3", video: "21885", markdown: "21886"}, |
|
%Episode{id: "054", post: "453", name: "Maps, Part 1", video: "22354", markdown: "22455"}, |
|
%Episode{id: "055", post: "454", name: "Maps, Part 2 - Structs", video: "22377", markdown: "22376"}, |
|
%Episode{id: "056", post: "460", name: "Migrating Records To Maps", video: "22875", markdown: "22874"}, |
|
%Episode{id: "057", post: "461", name: "BEAM Toolbox, Part 4", video: "22878", markdown: "22877"}, |
|
%Episode{id: "058", post: "462", name: "BEAM Toolbox, Part 5", video: "23020", markdown: "23019"}, |
|
%Episode{id: "059", post: "465", name: "Custom Mix Tasks", video: "23308", markdown: "23307"}, |
|
%Episode{id: "060", post: "467", name: "New Style Comprehensions", video: "23473", markdown: "23472"}, |
|
%Episode{id: "061", post: "469", name: "Plug", video: "23806", markdown: "23807"}, |
|
%Episode{id: "062", post: "472", name: "Quickie Synth", video: "24016", markdown: "24014"}, |
|
%Episode{id: "063", post: "474", name: "Tracing", video: "24160", markdown: "24161"}, |
|
%Episode{id: "064", post: "481", name: "Digraph", video: "24982", markdown: "24979"}, |
|
%Episode{id: "065", post: "482", name: "SSH", video: "24983", markdown: "24984"}, |
|
%Episode{id: "066", post: "484", name: "Plug.Static", video: "25289", markdown: "25290"}, |
|
%Episode{id: "067", post: "486", name: "Deploying to Heroku", video: "25396", markdown: "25397"}, |
|
%Episode{id: "068", post: "491", name: "Port", video: "25797", markdown: "25798"}, |
|
%Episode{id: "069", post: "492", name: "Observer", video: "25916", markdown: "25917"}, |
|
%Episode{id: "070", post: "495", name: "Hex", video: "26251", markdown: "26252"}, |
|
%Episode{id: "071", post: "497", name: "Wx", video: "26319", markdown: "26321"}, |
|
%Episode{id: "072", post: "501", name: "WxCalc, Part 2", video: "26903", markdown: "26904"}, |
|
%Episode{id: "073", post: "502", name: "Process Dictionaries", video: "26963", markdown: "26964"}, |
|
%Episode{id: "074", post: "506", name: "ETS", video: "27461", markdown: "27462"}, |
|
%Episode{id: "075", post: "508", name: "DETS", video: "28019", markdown: "28021"}, |
|
%Episode{id: "076", post: "510", name: "Streams", video: "28409", markdown: "28410"}, |
|
%Episode{id: "077", post: "511", name: "Exceptions and Errors", video: "28573", markdown: "28574"}, |
|
%Episode{id: "078", post: "514", name: "Agents", video: "28788", markdown: "28789"}, |
|
%Episode{id: "079", post: "516", name: "Tasks", video: "28968", markdown: "28969"}, |
|
%Episode{id: "080", post: "518", name: "erlubi", video: "29197", markdown: "29198"}, |
|
%Episode{id: "081", post: "520", name: "EEx", video: "29634", markdown: "29635"}, |
|
%Episode{id: "082", post: "525", name: "Protocols", video: "29979", markdown: "29978"}, |
|
%Episode{id: "083", post: "526", name: "pg2", video: "30087", markdown: "30088"}, |
|
%Episode{id: "084", post: "529", name: "PCM Audio", video: "30289", markdown: "30291"}, |
|
%Episode{id: "085", post: "532", name: "Apex", video: "30472", markdown: "30473"}, |
|
%Episode{id: "086", post: "534", name: "put_in and get_in", video: "30715", markdown: "30714"}, |
|
%Episode{id: "087", post: "536", name: "WordCloud", video: "30799", markdown: "30798"}, |
|
%Episode{id: "088", post: "540", name: "Porcelain", video: "31006", markdown: "31004"}, |
|
%Episode{id: "089", post: "542", name: "Protocol Buffers", video: "31181", markdown: "31180"}, |
|
%Episode{id: "090", post: "544", name: "Websockets Terminal", video: "31370", markdown: "31368"}, |
|
%Episode{id: "091", post: "546", name: "Test Coverage", video: "31412", markdown: "31411"}, |
|
%Episode{id: "092", post: "549", name: "Link Extractor", video: "31602", markdown: "31601"}, |
|
%Episode{id: "093", post: "551", name: "Link Extractor, Part 2", video: "31755", markdown: "31754"}, |
|
%Episode{id: "094", post: "555", name: "Link Extractor, Part 3", video: "32021", markdown: "32020"}, |
|
%Episode{id: "095", post: "558", name: "Link Extractor, Part 4", video: "32403", markdown: "32404"}, |
|
%Episode{id: "096", post: "560", name: "Arduino Motor Driver", video: "32817"}, |
|
%Episode{id: "097", post: "564", name: "BEAM Toolbox, Part 6", video: "33446", markdown: "33445"}, |
|
%Episode{id: "098", post: "565", name: "Contributing to Open Source", video: "33448"}, |
|
%Episode{id: "099", post: "568", name: "BEAM Toolbox, Part 7", video: "33759", markdown: "33758"}, |
|
%Episode{id: "100", post: "570", name: "BEAM Toolbox, Part 8", video: "33917", markdown: "33918"}, |
|
%Episode{id: "101", post: "573", name: "BEAM Toolbox, Part 9", video: "34074", markdown: "34075"}, |
|
%Episode{id: "102", post: "575", name: "BEAM Toolbox, Episode 10", video: "34186", markdown: "34187"}, |
|
%Episode{id: "103", post: "579", name: "BEAM Toolbox, Episode 11", video: "34583", markdown: "34584"}, |
|
%Episode{id: "104", post: "580", name: "Ruby to Elixir via BERT-RPC", video: "34586", markdown: "34587"}, |
|
%Episode{id: "105", post: "583", name: "Farkov Chain", video: "34807", markdown: "34808"}, |
|
%Episode{id: "106", post: "587", name: "Text Parsing", video: "35165", markdown: "35226"}, |
|
%Episode{id: "107", post: "593", name: "Phoenix Release", video: "36087", markdown: "36086"}, |
|
%Episode{id: "108", post: "597", name: "Release Upgrades", video: "36377", markdown: "36379"}, |
|
%Episode{id: "109", post: "598", name: "Socket", video: "36422", markdown: "36423"}, |
|
%Episode{id: "110", post: "601", name: "ExTwitter", video: "36828", markdown: "36829"}, |
|
%Episode{id: "111", post: "604", name: "ExTwitter, Part 2", video: "37189", markdown: "37188"}, |
|
%Episode{id: "112", post: "608", name: "Benchfella", video: "37589", markdown: "37586"}, |
|
%Episode{id: "113", post: "610", name: "Monitoring Network Traffic", video: "37787", markdown: "37786"}, |
|
%Episode{id: "114", post: "613", name: "Wx Keyboard Events", video: "38022", markdown: "37985"}, |
|
%Episode{id: "115", post: "615", name: "Wx Extris Continued", video: "38248", markdown: "38247"}, |
|
%Episode{id: "116", post: "619", name: "Wx Extris Part 3 - Refactoring", video: "38565", markdown: "38566"}, |
|
%Episode{id: "117", post: "622", name: "Wx Extris Part 4 - Testing", video: "38887", markdown: "38886"}, |
|
%Episode{id: "118", post: "624", name: "WxExtris Part 5", video: "38895", markdown: "38894"}, |
|
%Episode{id: "119", post: "627", name: "WxExtris Part 6", video: "39396", markdown: "39398"}, |
|
%Episode{id: "120", post: "631", name: "WxExtris, Part 7", video: "39929", markdown: "39745"}, |
|
%Episode{id: "121", post: "634", name: "WxExtris, Part 8", video: "40083", markdown: "40082"}, |
|
%Episode{id: "122", post: "637", name: "SDL", video: "40192", markdown: "40191"}, |
|
%Episode{id: "123", post: "638", name: "SDL Extris", video: "40313", markdown: "40312"}, |
|
%Episode{id: "124", post: "643", name: "Typespecs", video: "40620", markdown: "40621"}, |
|
%Episode{id: "125", post: "645", name: "Dialyzer", video: "40788", markdown: "40790"}, |
|
%Episode{id: "126", post: "654", name: "Piping Into Elixir", video: "41110", markdown: "41109"}, |
|
%Episode{id: "127", post: "657", name: "SSH Client Commands", video: "41617", markdown: "41616"}, |
|
%Episode{id: "128", post: "659", name: "Managing Docker", video: "41830", markdown: "41829"}, |
|
%Episode{id: "129", post: "662", name: "egd", video: "42006", markdown: "42008"}, |
|
%Episode{id: "130", post: "663", name: "Extris Web Client", video: "42296", markdown: "42298"}, |
|
%Episode{id: "131", post: "669", name: "ExProf", video: "42734", markdown: "42735"}, |
|
%Episode{id: "132", post: "671", name: "Randomness in the Erlang VM", video: "43108", markdown: "43109"}, |
|
%Episode{id: "133", post: "678", name: "Boltun - Postgres Listen Notify", video: "43373", markdown: "43374"}, |
|
%Episode{id: "134", post: "679", name: "Elastic Search with Tirexs", video: "43510", markdown: "43511"}, |
|
%Episode{id: "135", post: "680", name: "Benchwarmer", video: "43632", markdown: "43633"}, |
|
%Episode{id: "136", post: "688", name: "Interfacing with Asterisk", video: "44016", markdown: "44017"}, |
|
%Episode{id: "137", post: "691", name: "Asterisk AGI with Elixir", video: "44053", markdown: "44054"}, |
|
%Episode{id: "138", post: "692", name: "Monitors and Links", video: "44174", markdown: "44175"}, |
|
%Episode{id: "139", post: "693", name: "hexdocs", video: "44357", markdown: "44358"}, |
|
%Episode{id: "140", post: "695", name: "gopher", video: "44649", markdown: "44650"}, |
|
%Episode{id: "141", post: "696", name: "Set", video: "44740", markdown: "44739"}, |
|
%Episode{id: "142", post: "698", name: "escript", video: "45000", markdown: "45001"}, |
|
%Episode{id: "143", post: "703", name: "phoenix_generator", video: "45267", markdown: "45268"}, |
|
%Episode{id: "144", post: "705", name: "Erlang's `calendar` module", video: "45875", markdown: "45876"}, |
|
%Episode{id: "145", post: "710", name: "Good Times", video: "46019", markdown: "46020"}, |
|
%Episode{id: "146", post: "714", name: "mailman", video: "46199", markdown: "46200"}, |
|
%Episode{id: "147", post: "716", name: "webassembly", video: "46447", markdown: "46446"}, |
|
%Episode{id: "148", post: "718", name: "ejabberd with Elixir", video: "46992", markdown: "46993"}, |
|
%Episode{id: "149", post: "719", name: "ejabberd Packet Filters", video: "47095", markdown: "47096"}, |
|
%Episode{id: "150", post: "720", name: "JInterface", video: "47410", markdown: "47411"}, |
|
%Episode{id: "151", post: "729", name: "System Information", video: "48263", markdown: "48264"}, |
|
%Episode{id: "152", post: "730", name: "erlang_js", video: "48267", markdown: "48268"}, |
|
%Episode{id: "153", post: "732", name: "Phoenix APIs and CORS", video: "48470", markdown: "48471"}, |
|
%Episode{id: "154", post: "733", name: "inet", video: "48507", markdown: "48508"}, |
|
%Episode{id: "155", post: "740", name: "OAuth2 - Code Spelunking", video: "48970", markdown: "48969"}, |
|
%Episode{id: "156", post: "742", name: "Interacting with Amazon's APIs with erlcloud", video: "49056", markdown: "49057"}, |
|
%Episode{id: "157", post: "744", name: "eval_string", video: "49378", markdown: "49379"}, |
|
%Episode{id: "158", post: "746", name: "SOAP with Detergentex", video: "49699", markdown: "49700"}, |
|
%Episode{id: "159", post: "753", name: "Simple One for One Supervisors", video: "49876", markdown: "49877"}, |
|
%Episode{id: "160", post: "754", name: "MultiDef", video: "50045", markdown: "50046"}, |
|
%Episode{id: "161", post: "755", name: "Building a Cron System, Part 1", video: "50111", markdown: "50110"}, |
|
%Episode{id: "162", post: "757", name: "Building a Cron System, Part 2", video: "50492", markdown: "50493"}, |
|
%Episode{id: "163", post: "758", name: "Building a Cron System, Part 3", video: "50763", markdown: "50762"}, |
|
%Episode{id: "164", post: "761", name: "Fractals", video: "51082", markdown: "51083"}, |
|
%Episode{id: "165", post: "774", name: "Accounting 101", video: "51555", markdown: "51556"}, |
|
%Episode{id: "166", post: "776", name: "Implementing Logo, Part 1", video: "51629", markdown: "51630"}, |
|
%Episode{id: "167", post: "777", name: "Implementing Logo, Part 2", video: "51757", markdown: "51758"}, |
|
%Episode{id: "168", post: "784", name: "Continuous Integration", video: "51837", markdown: "51838"}, |
|
%Episode{id: "169", post: "808", name: "Fractals, Part 2", video: "52580", markdown: "52581"}, |
|
%Episode{id: "170", post: "810", name: "Building a Slack Bot", video: "52658", markdown: "52659"}, |
|
%Episode{id: "171", post: "815", name: "Erlang 18 and Time", video: "52879", markdown: "52880"}, |
|
%Episode{id: "172", post: "819", name: "Arc File Uploads", video: "52978", markdown: "52979"}, |
|
%Episode{id: "173", post: "821", name: "Continuous Deployment", video: "53340", markdown: "53341"}, |
|
%Episode{id: "174", post: "822", name: "ElixirFriends - Saving Tweets with Streams and Filters", video: "53597", markdown: "53598"}, |
|
%Episode{id: "175", post: "830", name: "Pagination with Ecto and Phoenix using Scrivener", video: "53862", markdown: "53863"}, |
|
%Episode{id: "176", post: "832", name: "Prettying Up ElixirFriends", video: "54023", markdown: "54024"}, |
|
%Episode{id: "177", post: "847", name: "Audio Visualizer", video: "54655", markdown: "54656"}, |
|
%Episode{id: "178", post: "848", name: "Memory Leaks", video: "54713", markdown: "54714"} |
|
] |
|
end |
|
end |
|
|
|
defmodule ElixirSips do |
|
@download_url "https://elixirsips.dpdcart.com/subscriber/download?file_id=" |
|
@session_cookie "symfony=<put your dpdcart session cookie here>" |
|
|
|
def params(episode, atom) do |
|
["#{@download_url}#{Map.get episode, atom}", "--quiet", "--show-progress", "--cookies=off", "--header", "Cookie: #{@session_cookie}", "-O", "#{episode.id} - #{episode.name}#{extension(atom)}"] |
|
end |
|
|
|
def wget(episode, atom) do |
|
if (episode |> Map.get(atom)) do |
|
System.cmd "wget", params(episode, atom) |
|
else |
|
IO.puts "Download code for '#{atom}' not found, skipping..." |
|
end |
|
end |
|
|
|
def extension(atom) do |
|
case atom do |
|
:video -> ".mp4" |
|
:markdown -> ".md" |
|
_ -> raise "Incorrect Atom" |
|
end |
|
end |
|
|
|
def download(episode) do |
|
IO.puts "Downloading Episode #{episode.id} - #{episode.name}" |
|
|
|
wget(episode, :markdown) |
|
wget(episode, :video) |
|
|
|
IO.puts "\nDone! (#{episode.id})\n\n" |
|
end |
|
end |
|
|
|
Episode.get_all |
|
|> Enum.slice(0..-1) |
|
|> Enum.each(&ElixirSips.download/1) |
|
|