Skip to content

Instantly share code, notes, and snippets.

@sheharyarn
Last active December 22, 2021 08:42
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save sheharyarn/99a3300d767cba176c4a to your computer and use it in GitHub Desktop.
Save sheharyarn/99a3300d767cba176c4a to your computer and use it in GitHub Desktop.
Download videos from ElixirSips.com

ElixirSips Video Downloads

  1. Download the Script

  2. Login to your ElixirSips account

  3. Get the Session Cookie (use Firebug or Chrome Inspector)

  4. Put it in the @session_cookie on line 189:

    @session_cookie   "symfony=weirdsessioncookiehere"
  5. Specify the video range on line 223

    |> Enum.slice(9..19)    # Downloads episodes 10 through 20
  6. Run the script!

    $ elixir elixir_sips.exs

I'm still a Elixir Newbie, would appreciate pointers on how to make this code better.

defmodule Episode do
defstruct id: nil, name: nil, video: nil, markdown: nil, post: nil
def list 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 - Tweets with Streams and Filters", video: "53597", markdown: "53598" },
%Episode{id: "175", post: "830", name: "Pagination with Ecto & 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" },
%Episode{id: "179", post: "853", name: "Rules Engine", video: "55597", markdown: "55445" },
%Episode{id: "180", post: "854", name: "Collectable", video: "55601", markdown: "55602" },
%Episode{id: "181", post: "861", name: "Native Compilation with HiPE", video: "56123", markdown: "56124" },
%Episode{id: "182", post: "867", name: "Phoenix API", video: "56640", markdown: "56641" },
%Episode{id: "183", post: "872", name: "React with Phoenix", video: "56770", markdown: "56771" },
%Episode{id: "184", post: "878", name: "React with Phoenix Channels", video: "56891", markdown: "56892" },
%Episode{id: "185", post: "881", name: "Mix Archives", video: "57000", markdown: "57001" },
%Episode{id: "186", post: "892", name: "Automatically Connecting Nodes", video: "57291", markdown: "57292" },
%Episode{id: "187", post: "897", name: "Compiling a Custom AST Into Elixir Functions", video: "57467", markdown: "57466" },
%Episode{id: "188", post: "910", name: "ElixirScript", video: "57779", markdown: "57778" },
%Episode{id: "189", post: "912", name: "iex.exs", video: "57821", markdown: "57822" },
%Episode{id: "190", post: "918", name: "Testing Phoenix Channels", video: "58050", markdown: "58051" },
%Episode{id: "191", post: "951", name: "Interesting IO", video: "58314", markdown: "58315" },
%Episode{id: "192", post: "952", name: "Interesting IO - Part 2", video: "58423", markdown: "58424" },
%Episode{id: "193", post: "955", name: "Linting with Dogma", video: "58565", markdown: "58566" },
%Episode{id: "194", post: "962", name: "Interoperability - Ports", video: "58824", markdown: "58825" }
]
end
end
defmodule ElixirSips do
@download_url "https://elixirsips.dpdcart.com/subscriber/download?file_id="
@session_cookie "symfony=put_your_token_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.list
|> Enum.slice(0..-1)
|> Enum.each(&ElixirSips.download/1)
@knewter
Copy link

knewter commented Jul 20, 2015

This makes me so happy :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment