Skip to content

Instantly share code, notes, and snippets.

@dicene
Created August 8, 2019 02:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dicene/509b9c8d6b48ce060ccc9315148f0cc1 to your computer and use it in GitHub Desktop.
Save dicene/509b9c8d6b48ce060ccc9315148f0cc1 to your computer and use it in GitHub Desktop.
Mudlet Spell Scraper
function downloadSpell()
print("Downloading...")
--downloadFile(getMudletHomeDir().."/spell.html", [[https://www.dndbeyond.com/spells?filter-class=0&filter-search=acid+splash&filter-verbal=&filter-somatic=&filter-%20material=&filter-concentration=&filter-ritual=&filter-sub-class=]])
downloadFile(getMudletHomeDir().."/spell.html", [[http://regalgoblins.com/spells-5e.php]])
end
function trim(s)
return (s:gsub("^%s*(.-)%s*$", "%1"))
end
function magiclines(s)
if s:sub(-1)~="\n" then s=s.."\n" end
return s:gmatch("(.-)\n")
end
function scrapeSpell(_, filename)
-- is the file that downloaded ours?
if not filename:match("spell", 1, true) then return end
-- parse our downloaded file for the player count
io.input(filename)
local s = io.read("*all")
spellList = {}
--display(s)
local currentSpell = {}
for line in magiclines(s) do
--display(line)
if descriptionNext then
currentSpell.description = line:trim()
end
descriptionNext = false
if line:match([[<header class="clearfix">]]) then
--echo("start of spell")
if currentSpell and currentSpell.name then
spellList[currentSpell.name] = currentSpell
end
currentSpell = {}
elseif line:match([[<div id="level">%d+</div>]]) then
currentSpell.level = line:match([[<div id="level">(%d+)</div>]])
elseif line:match([[<div id="level"><img src="/images/star.png" class="star"/></div>]]) then
currentSpell.level = "cantrip"
elseif line:match([[<div id="basics">(.+)</div>]]) then
currentSpell.name = line:match([[<div id="basics">(.+)</div>]])
elseif line:match([[<div id="components" class=" (.+)">]]) then
local list = line:match([[<div id="components" class=" (.+)">]])
if list:match("somatic") then currentSpell.somatic = true end
if list:match("verbal") then currentSpell.verbal = true end
if list:match("material") then currentSpell.material = true end
elseif line:match([[<dt>Casting Time</dt><dd>(.+)&nbsp;</dd>]]) then
currentSpell.castingTime = line:match([[<dt>Casting Time</dt><dd>(.+)&nbsp;</dd>]])
elseif line:match([[<dt>Casting Time</dt><dd>(.+)&nbsp;</dd>]]) then
currentSpell.range = line:match([[<dt>Range</dt><dd>(.+)&nbsp;</dd>]])
elseif line:match([[<dt>Duration</dt><dd>(.+)&nbsp;</dd>]]) then
currentSpell.duration = line:match([[<dt>Duration</dt><dd>(.+)&nbsp;</dd>]])
elseif line:match([[<dt>Materials</dt><dd>(.+)</dd>]]) then
currentSpell.materials = line:match([[<dt>Materials</dt><dd>(.+)&nbsp;</dd>]])
elseif line:match([[<div id="description%-content">]]) then
descriptionNext = true
--echo("Starting description!\n")
elseif line:match([[<dt>School</dt><dd>(.+)&nbsp;</dd>]]) then
currentSpell.school = line:match([[<dt>School</dt><dd>(.+)&nbsp;</dd>]])
elseif line:match([[<dt>Book</dt><dd>(.+)&nbsp;</dd>]]) then
currentSpell.book = line:match([[<dt>Book</dt><dd>(.+)&nbsp;</dd>]])
end
end
for name, spell in pairs(spellList) do
echo(name .. " -> " .. spell.level .. "\n")
end
end
registerAnonymousEventHandler("sysDownloadDone", "scrapeSpell")
@dicene
Copy link
Author

dicene commented Aug 8, 2019

{
  castingTime = "1 action",
  duration = "instantaneous or 1 hour",
  verbal = true,
  name = "Shape Water",
  description = "<p>You choose an area of water that you can see within range and that fits within 
a 5-foot cube. You manipulate it in one of the following ways:</p><p></p><p>* You instantaneously 
move or otherwise change the flow of the water as you direct, up to 5 feet in any direction. This 
movement doesn&#039;t have enough force to cause damage.</p><p>* You cause the water to form into 
simple shapes and animate at your direction. This change lasts for 1 hour.</p><p>* You change the 
water&#039;s color or opacity. The water must be changed in the same way throughout. This change 
lasts for 1 hour.</p><p>* You freeze the water, provided that there are no creatures in it. The 
water unfreezes in 1 hour.</p><p></p><p>If you cast this spell multiple times, you can have no more 
than two of its non-instantaneous effects active at a time, and you can dismiss such an effect as 
an action.</p>",
  school = "Alteration",
  level = "cantrip",
  somatic = true,
  material = true
}

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