Eclectic Magic

I’ve always enjoyed writing. When I was a little kid I would make up stories all the time, and occasionally, with the right pressure, I would write them down. Most of the time it was for assignments in school, but every now and then I would write something small just for me. I have a motivation problem, and a bit of a procrastination problem, but I still love writing when I sit down to do it.

This blog and my daily journal have both been positive for my writing habits. I’m starting to work it into my daily routine and not just do it because I have to, but I honestly sit down and write because I want to. It’s surprising to think that even enjoyable stuff sometimess needs to be exercised a bit for you to start doing it. The more I write things down, the more I want to write things down.

There is a competition going on at a small publisher that one of our H&H friends works for. She’s told both Ashley and I that we need to submit a story for this one and I may have cracked the topic I want to cover. It’s supposed to a tale of “whimsy and adventure” there is some sort of eclectic hook regarding magic. I wrote a short story a while back based on a small writing prompt that Ashley gave me, and I really still love the premise. I wrote the whole thing in less than an hour and it really stuck with me. I’m considering going back and rehashing that into a story for the contest. Not too much has to be done other than lengthening it a bit and adding some real high stakes.

For today, though, it’s time to get my head back in the game and do my job. I have a few ideas for things I want to tackle today. The trick is getting started early so I don’t fall into a slump too early. I was up far too late playing Stardew Valley last night. SURPRISE! So I have to pull myself up by my bootstraps in order to get things going. Maybe this coffee will help.

Do Something

I’m a huge fan of The Art of Manliness website. I don’t always swing in and read it but I do get the weekly digests, and every now and then I’ll search the website for something that I’m curious about. The site is dedicated to reviving “manliness” in young men who seem to have lost how to engage in the next step of life after college. I mean, even after high school we kind of have a hard time figuring out our place. Some of this is due to the leisurely pace that our individual worlds seem to move, and some of it is to just having poor direction from those who came before us.

There was a time when people HAD to grow up because in some ways there wasn’t as much entertainment to be had, and because their survival required it. I think that the previous generation had so much so hard they wanted us to have everything we needed, leading to us having more of a “childhood” than most generations. I don’t think I even worried about having to get a job until I was sixteen, which is probably late in a lot of people’s eyes. Some kids don’t even have to do that.

This is totally not what I set out to write this morning but I guess it’s something that’s been on my mind. I think it comes to mind every now and then when I’m sitting on the couch playing a game or something when Sam is napping or asleep, rather than working on some major project that I should be getting done. In some ways, having the extra “play” time is really good for your brain, but too much of it can have a negative impact on the rest of your life. “No time enjoyed is time wasted,” is often what you’ll hear from people who spend a lot of time on the couch, and that might be true for you as an individual. I just imagine what I could have done in that would have impacted others.

I’m most likely going to write down all these introspective thoughts and then just do the same thing today. It comes in waves though, I suppose. Most of the time I’m doing some pretty impactful stuff. I tend to put a lot of pressure on myself.

I suppose all we can do is wake up every day with the intend to do a little bit of something that impacts someone else in a positive way. If we do that, I suppose it doesn’t matter if we watch movies a bit or play some video games. The main thing is that we get up and accomplish something that makes a difference, even if that’s just repairing the fence that you’ve been putting off, or doing all the laundry that keeps piling up. Have to be responsible sometime, I guess!

Stardew Valley

Stardew Valley is an amazing game. It’s nothing new, and I’ve payed it before, but for whatever reason it really hooked me this time. I picked it up shortly after it initially came out and I was knee deep in new baby stuff and life just wasn’t quite as friendly to video game time as it is now. Sam sleeps for a bit in the afternoons and has a better schedule for giong to bed as well, so I have a little bit more time to game. This thing is stealing all my time.

Part of the reason it hooked me so well this time was because I picked it up on the Nintendo Switch that I got for Christmas. I can play it pretty much anywhere, which means I can play it while I’m hanging out downstairs with Stephanie and she’s watching TV. Stardew Valley really lends itself well to being portable. There are a couple wonky things that are different from the PC version, but all in all it’s still the same game.

There’s plenty of things I should be doing that don’t involve a virtual farm, but I’m having a good time so I regret nothing.

The basic premise of the game is that you are a guy working in corporate America (or whatever made up place this game is in.) Your grandfather writes you a letter leaving his farm to you so you can go out and do something refreshing with your life. The farm is in shambles and it’s up to you to make it a better place before he returns on the dawn of the 3rd year. While you’re making the farm a better place, you also have to juggle a social life with over twenty NPCs, fight monsters, restore a community center, and a bunch of other optional things.

The thing that makes it stick for me is that it’s so CHILL. You don’t have to get in a hurry doing anything. It is totally a clone of a game I played in my early teens called “Harvest Moon.” I played the SNES version of that and later, Lando and I both got hooked on HM64 which we both still believe was the pinnacle of the series. Stardew Valley seems to be based off the SNES version in a lot of ways, but the dev added so much for you to do beyond just farming and building relationships. The whole thing was made by one guy, and it continues to blow my mind the deeper I get into it.

I’m just starting on the 8th day of Fall in the first year. There are a few places where I’ve made mistakes and some spots where I would go back and do things differently, but the game is really about dealing with the mistakes and just moving forward. There is no such thing as a perfect game. It’s taken me some time to figure that out, but now that I have, I’m enjoying myself some more. The pressures is off and I can just do the things that I’m excited to do and be okay with it.

If you haven’t played it, you should. There is something in there for everybody. It’s available on PC, PS4, Xbox One, and Nintendo Switch.

Just Dad Things

Being a dad is a magical thing. You never truly feel rested from anything but at the same time you find some kind of strange energy that keeps you moving and enjoying everything. I woke up this morning to find my son downstairs with him mom putting those little spongy GROW capsules in a bowl of water and being mystified at how they grow. He’s talking up a storm now and listening to him talk about what the animals were, how they were growing, and how the gooey capsule part was still stuck to them. Listening to my 2 1/2 year old talk say “alligator” and “stegasaurus” is still my favorite thing. I’m amazed at how well he does it.

He’s so smart. Everything he does is blowing my mind lately. The only thing I can’t get him to do is build stuff with me, but that’s apparently a normal thing and comes with time. He always wants to knock stuff over, but who could really blame him.

I totally get why people decide not to have kids, but I’m not sure what my life would look like if we had been those people. I always wanted kids, but wasn’t quite sure why other than that’s what you’re supposed to do once you’re married. Now I get it. I totally get it. It’s the most joy I get in a day by miles. All we can hope to do at this point is try to be the best parents we can be. We’ll make mistakes, he’ll goof up here and there, but at the end of the day, we’ll know we did everything we could to raise another good human.

Sitting here, writing in my blog, and listening to him play with toys is really the best thing I could ever hope for when starting my day.

Quality Wordsmithing

Well, now that I have a new blog setup, the journey to something presentable is underway. I like that Ghost is super simple, but I’m finding that any decent themse are hard to come by. I’m probably going to be hunting down something I can edit and then doing my best to make it happen. I have this horribly plain header I dumped up at the top but I’m definitely going to need something at least a little snazzy. This one is minimalist, but pretty darn boring.

I don’t want to be boring. I’m going to need this to be a fun experience, so I’m going to need some art. If you do some art, and have a good idea of what a header should look like for a neato, personal, sometimes tech related blog, then hit me up.

I’m also going to need some content that’s worth reading. As I always do, I’m focusing on the aesthetic first. Who needs quality wordsmithing when you have beautiful graphics everywhere, right? I mean, that’s not true at all but it helps me get going.

Trying Something New

I’m considering a complete departure from social media, but without some sort of outlet in the form of the written word, I’m not sure I’ll be able to handle the escape. The main thing is that I have thoughts that I want to put out there, but I don’t necessarily want to contribute to the dumpster fire that is Twitter. I just recently came to this realization that both Twitter and Facebook will either tell me things I don’t necessarily need to know or something just to get me riled up and angry about something else.

There’s something about people just yelling into the void that is starting to make me nuts. No one is doing anything that is making a difference, but simply shouting into the mass of people that read Twitter makes them feel like they are contributing to the betterment of society. The worst part is that they are often preaching to the choir. We don’t follow people that we don’t have anything in common with, and they don’t follow us, so who are we talking to?

Anyway, this blog might be the place that some of my more long-form ideas go to. Maybe even short form ideas, given that this blog is super easy to put stuff in. I’m kind of intrigued by this software and it’s “no frills” way of allowing me to dump text onto the internet.

We’ll see how this goes and maybe it’ll be useful to me or someone else.

Dragon Con 2017

Every time we come to this convention, we have a good time. Man, this year is no exception. I think yesterday may have been one of the coolest days I’ve ever had at a convention.

Each year I try to meet someone from the Frogpants podcast network, or someone from the Diamond Club and just say, “Hi.” This year, I had a really conversation with Brian Dunaway, and got Justin Robert Young to sign my Contender box. Since I got here, I’ve struggled a bit with what to get into or where to go. For the most part, I’ve just been hunting cool people to see and talk to. For the most part, this is a sci-fi con. There is also quite a bit of SyFy channel stuff here that I have no clue about, but I’ve been pleasantly surprised by how much I’ve enjoyed it anyway.

The Sailor Moon voice actor panel I went to was super fun and I have no idea what any of that show is really about. Stephanie and Ashley were huge fans of it and I’ve watched some of it with them, but I still don’t get it. The cool thing about some of these panels is that none of them necessarily need to be something you’re into as long as the people who are in it are fun to see and listen to. The Sailor Moon ladies were so fun, and they clearly love what they do.

One of the biggest wins so far for me was getting the legendary George Lowe to do the intro for our 400th episode. I was beside myself. I didn’t even know how to breathe after that happened. I have no idea if it’s going to turn out okay because the mic was so hot, but I think I can fix it enough that it sounds like it belongs. He was as genuine and wonderful as ever, and it’s always such a joy to meet him.

Second major win, which is pretty much as good as the first but lists are needed. I got to meet/hang out with Brian Dunaway! He was so cool, man. We really got to hang for a few minutes and spend some real quality time just talking about whatever came to mind. He asked me a bunch of questions as well which felt awesome to me. I asked him about coming on our show sometime and he was totally down for it. I’m hoping that really works out because I’d love to talk to him about all things podcasting and art. He’s such a down to earth, cool dude.

Well, that’s day 1 and 2 for me at Dragon Con. Not even remotely sure what we’ll do today, but I think we can find some stuff to get into. I’m a little crowd exhausted, but I think we can pick it up and make it through another day. I’m refreshed after getting to meet some heroes last night so I’m ready to take on the day. I’m not sure I’m ready for the level of crowds but we’ll see how it goes.

Woo!

Introspective Stephen

This blog has been neglected, then un-neglected, then neglected again for years. Over and over I’ve attempted to bring it back to life and start writing stuff in it again. I haven’t been able to maintain any schedule that I thought I would be able to. That’s really unfortunate.

I’m at a point in my online presence where so much of who I am is out there in the world. So many of the things I started years ago are still around even though I’ve grown into a different person. Every now and then I’ll change a theme or update the look of the art to kind of force my new outlook and new experiences into my old world. That doesn’t seem to scratch the itch like it used to. I am the kind of person that chases change and exciting new developments. It comes out mainly in my hobbies and my shopping habits. Newest. Latest. Best. That’s where I’m at. It’s also the name of a fantastic podcast >_>

I say all that to say that I’m on the verge of considering a full wipe of everything. That’s not to say that all the history I’ve built up is going away, but it might be sat to the side in favor of rebooting. I wasn’t a father a billion years ago when I started this blog. I wasn’t a guy with podcasts. I wasn’t even out of college yet. I don’t even really know if I was in college at the time, I’d have to go back to look. There’s so much that I could do that I’m not doing and I need to start making some changes.

Who knows how far this extends, and what I lose when I move along to something new? Who knows if I’m even going to do it? It’s just one of the many things floating around in my head today. I’ll be giving it some thought over the next few weeks and we’ll see where I end up. H&H is coming up on Episode 400. That’s been weighing on me a bit. It’s Episode 400 and we’re largely at the same listener count we’ve been at for years. Is that okay? Should we be fine with that? Maybe the answer is yes. I don’t know. The market is pretty saturated now and it’s hard to get noticed by people. I guess we’ll see what I decide to do with that as well. BAH! Introspective Stephen is Introspective.

Later!

Europe Bound!

I’m on my first ever trip across the Atlantic Ocean. I’m headed to the Czech Republic for work and I’m both excited and super nervous about the whole ordeal. I’ve only ever traveled to another country one time, and it was just to the Dominican Republic as a big group. This time I’m traveling with a co-worker so I’m still not alone, but more alone than I was the last time. We’re going to be in Prague the first day we’re there and then headed to Brno for a developer conference. I’m excited about being there and seeing the sights, but I’m definitely going to be missing my family a ton. I haven’t been away from them for this long since Sam was born. I went to Boston for a week back then and that was even hard. Sam is older now though, so it’s a bit tougher. He doesn’t know that I’m going to be gone that long, and it was hard to leave him. Not going to lie. I cried a bit.

Anyway, I’m planning on getting a ton of reading done while I’m on the plane and I might watch a movie or two as well. I brought Hellboy and a couple Pixar movies. I try not to watch anything too crazy when I’m on the plane next to people. As much as I love watching Deadpool, it’s probably not the kind of movie I want to watch around other folks. I’m actually super considerate when it comes to sitting next to people and would hate for them to be offended by my entertainment choices. I’m hoping I can finish my star wars book before I have to take it back to the library. I have until Friday and I’m almost 50% of the way through it. I think I can pull it off.

My plane just got to the gate! Yay! I might write some while I’m on the plane as well. I could write a short story about Jim Doogan if I want. That would be pretty awesome and it could help me adjust his tone a bit. If I do write a story about him, it’s going to be an awesome treasure hunt. Maybe not from his perspective either. What if it was a lot like Treasure Island. That could be really fun :D.

Here I go!

Building a Twitch Alert System

I help run a Twitch channel with a fellow group of nerds called 2Dorks. We produce a whole bunch of content on our Twitch Channel and last week we decided that we should put that all to good use. Jacob, a fellow dork and quite the philanthropist, decided that a 12 hour charity stream would be an awesome way to “do some good in the neighborhood.” We all agreed and quickly threw together plans to make this happen.

The meat of this post is on the alert system. We had a few problems:

  • Toys for Tots didn’t have any kind of alerting at all, and no connection to Twitch.
  • They don’t send an email to the donation recipient when someone donates, so no parsing emails for a notification.
  • The only place to get your donations is from either table in your admin panel, or a downloadable csv file.

This doesn’t sound like anything too bad, but it got a little hairy. We didn’t know a few things;

  • Does the list populate by most recent or are donations appended?
  • Does the list paginate, and at what point?
  • How can we grab data from behind the login wall with a script?
  • Is the data unique enough that we won’t trigger duplicates?

Like all good problems, you should always start with the questions. We had plenty of them.

I set to work on planning this thing out. There was no way that we were going to do a donation heavy stream without some way of showing an alert on the screen, or a tracking meter for when someone donated. I can imagine a lot of Twitch streamers would love to donate to something random and maybe this info can help someone. I am NOT a seasoned python dev, but I dabble. So take what you see here and improve on it if you think there’s a better way.

I knew we needed to be able to send alerts to Streamlabs, a common service used by Twitch streamers to display alerts on top of their stream. The good news on that front is that I had worked on a python based alert system utilizing the Streamlabs API, so I had that code already. I just needed to find out how to send the alerts from data I had no idea how to get.

GOOGLE

There’s you answer. I googled a bunch of stuff and finally got pointed to selenium. It’s a python module (oversimplification) that contains a function I need called webdriver. It can not only open webpages, but also click buttons and fill in boxes. I used that to login to the donation administration page, and grab the table. Here’s the code:

# initiate
driver = webdriver.PhantomJS() # initiate a driver, in this case PhatomJS. No Window PopUp
driver.get("https://p2p.charityengine.net/ToysforTotsFoundation/Dashboard/Donations/") # go to the url

# log in
username_field = driver.find_element_by_name('UserName') # get the username field
password_field = driver.find_element_by_name('Password') # get the password field
username_field.send_keys("username") # enter in your username
password_field.send_keys("password") # enter in your password
password_field.submit() # submit it

# gotta wait while the new site loads
time.sleep(3)

html = driver.page_source

#turn the html into ascii so we can iterate over the lines
html = html.encode('ascii','ignore')

#close PhantomJS Instance
driver.quit()

That chunk of awesome logs into the given URL with my admin creds, then pulls down the source code of the page. I had to put a sleep command in there to stop it from pulling down the login page code. Three seconds seemed to do the trick. Just long enough for the page and the actual data I needed to load. I grabbed the HTML because I needed the table where the names and donations lived. Luckily, it was the only table on the page, so I could parse each line one by one and just search for instances of name. The issue there is that I needed to separate actual names from other stuff. ENTER REGEX LAND! More googling plus a regex tester and I ended up with this:

for line in str.splitlines(html):
    if re.search("(
<td>([0-9a-zA-Z]+\s*[0-9a-zA-Z]*)<\/td>)", line)

That little piece of code loops through each line in the HTML and searches for a tag with something like Bob Whatever and considers it a match. Later on, I realized that this was a huge mistake, because it would ONLY match instances of names of either 1 or 2 words. Not 3 or 4. It also wouldn’t work on people like Nikolaj Coster-Waldeau should Jamie Lannister actually desire to donate. It also wouldn’t work on Edith and Archie Bunker or Conan O’Brien. My revised code after the entire thing blew up looks like this:

for line in str.splitlines(html):
    # Find the username line in the table
    if re.search("(
<td>
Opted out of communications<\/td>)", line):
        continue
    if re.search("(
<td>([0-9a-zA-Z'*-*]+\s*)*<\/td>)", line):

That part with the Opted out of communications line also had to be added so that the looper would skip instances of that. There is a hilarious moment where Mr. Opted out of communcations donated a bunch of money. Had to kill the script in a bad way. Lesson learned!

Onward to Redis!

Not only did I need to find the names and the amount they donated, I also needed to keep that data somewhere. What could I use to define two simple values that I could reference easily? REDIS!

I have never worked with Redis, but I knew enough to know it was a simple key/value store that I could use to store stuff like donator_name: value. It was perfect! I also knew how to access it with python since I had goofed around with another idea from before.

So I stored each line discovered with the loop in a dictionary that looked like this: {'Hulk Hogan': '$7000.00'}. That was in a list so it was a bunch of those over time. After I had the list of key/values, I looped over that list and ONLY stored values in redis that weren’t already there. I would check to see if name = donation, and if it didn’t, I’d add it. I figured people might donate twice. NOTE: The big issue with this is if someone donated twice the same amount, I wouldn’t alert nor include it. I took a risk and I knew it.

# iterate over the result list, load each dict into the redis db as a keypair
for i in result:
    if r.get(i.get('name')) != i.get('donation'):
        f.write(i.get('name') + ': ' + i.get('donation') + '
' + '\n')
        r.set(i.get('name'), i.get('donation'))

That’s the code that does the storing of the value. You can kind of see what I’m doing there. I also stored the donation into a donations.txt file. That file would be used for a bunch of stuff. I needed that one to load into a webpage so we could feed it to Open Broadcaster Software which is what we used to make all the ovelays.

Alert. Alert.

So now we havea all the data in a file and we are currently holding it in result list. That result list is handy because I could use it inside the loop to call my alert function. By the way, the alert function looks like this:

#Twitchalerts API
url = 'http://www.twitchalerts.com/api/v1.0/alerts'

# Payload. Still need to add a gif and a sound
payload = {
"access_token": "no_you_can't_see_this",
"duration": "5",
"type": "subscription",
"special_text_color": "#ff0000",
}

# Define the alert function that will be used to actually fire to streamlabs
def alert(name, donation):
    payload['message'] = '*' + str(name) + '* has donated *' + str(donation) + '* to Toys For Tots!'
    session = requests.Session()
    response = session.post(url, data=payload)

So I would do something like alert(i.get('name'), i.get('donation')) at the end of the result loop. I threw a time.sleep(15) in there because I don’t know how streamlabs handles a ton of alerts coming in at once. I wanted to avoid any missed alerts.

Meter Time

Okay, so we have our data alerting. GOOD! Job done, right?

WRONG!

Our good buddy, Drest, from our WoW streams surprised us with a meter for keeping track of donations. “All you have to do is plugin your data,” he says. Sounds great!

It was so much trickier than I thought and required more of that good ol’ Google. I figured out after a lot of trial and error that I could take the text from files and load it between <div> tags using jQuery. That way, I could define the data on demand rather than having to statically put it in the webpage. This was important because data was going to change and I wanted to make sure the website, AKA meter, got all the data.

So, I decided to just write out all the info into files that the jQuery could load from. Here’s what that looks like. **IT’S UGLY**

with open('/foo/bar/donations.txt', 'r') as content_file:
content = content_file.read()

f = open('/foo/bar/total.txt', 'w+')
total = 0
for line in content.splitlines():
    dollar = re.search("[0-9]+\.[0-9]{2}", line)
    dollar = dollar.group()
    total = total + float(dollar)
f.write('${:,.2f}'.format(total) + '\n')
f.close()

f = open('/foo/bar/percent.txt', 'w+')
percentage = float(total) / 500
f.write("{:.0%}".format(percentage) + ' \n')
f.close()

num_lines = sum(1 for line in open('/foo/bar/donations.txt'))
f = open('/foo/bar/lines.txt', 'w+')
f.write(str(num_lines) + '\n')
f.close

I would have done this smarter, but I didn’t have enough time and I don’t know HTML or PHP. I knew how to load the text from a file, but not how to separate it. The jQuery that actually pulls in the data looks like this:

$(document).ready(function () {
function callAjax() {
$("#amount").load("total.txt");
}
setInterval(callAjax, 10000);
});

That `setInterval` deal came a lot later. I learned that I needed to not only dynamically update stuff on page load, I also needed to do it in increments! That became apparent when we realized that the OBS plugin we used to display web content didn’t actually refresh or even have a refresh interval.

The good part about all this is that Drest was awesome and programmed div id’s around all the spots where I needed to put the text. So all I had to do is load the text file into whatever div I needed it to go to and everything was fine.

Lessons Learned

Double check your REGEX and consider alternates.
This one burned pretty bad. When a four name person came in, it totally broke the entire engine. Since a name wasn’t found, the next value of a dollar amount didn’t have anywhere to go and the script broke. It broke again later when a person with an apostrophe in their name donated, but by then I had gone to bed and nothing could be done at the time.

Stuff is gonna break. Roll with it.
We were troubleshooting bugs for an hour while LIVE. Though not ideal, it happens. Stuff is going to break. The key to this is knowing enough about the code you wrote to know where the issue is. This is where copy/paste can really burn you. If you just pull from websites and don’t **understand** your code, then you’re going to get hurt.

PHP/HTML/jQuery
I need to know more of this. That’s all.

If you can draw it, you can build it
A network teacher told me that a long time ago. I envisioned how I would hold the data early on in the project. Once I had that vision, I was able to put the pieces together. The blank page was terrifying. THe first thing I did was paste in my alert code I wrote a long time ago, because I knew how it worked. After that, some of the intimidation went away and I just started plowing away at it.

Charity streams are awesome
We were able to raise over $500 for Toys for Tots just by sitting down and playing video games all night. Granted a lot of effort went in to promoting it and getting people on board with us, but at the end of the day we just hung out and played. It was amazing. We definitely want to do it again, but we’ll pick a charity early next time and hopefully have the bugs worked out.

Code

Yep. I did the thing. I wrote an app that alerts a service by pulling data from another service. I wrote my first python script in July of this year, and now I wrote something on my own because I could. I would have never imagined this even a year ago, and now here I am. Once you know how to code, the possibilities are endless. I’m no expert, but I made a thing that did a job for me that otherwise would have been impossible. I think that counts for something.

Hopefully this post provides some info for other folks who want to send alerts for charities that don’t necessarily have a great system for weird off-shoot stuff like a Twitch stream. Extra-Life and Child’s Play cater to this kind of audience but there are plenty who don’t.

Questions

Got anything you want to know about this stuff? Just leave a comment on the post. I’ll try to answer them. I hope to put my code for this up on Github once I sanitize it a bit and add some comments. I also need to get Drest’s permission since the meter site was his minus the jQuery statements.