<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: CodingVibe</title>
    <description>The latest articles on DEV Community by CodingVibe (@codingvibe).</description>
    <link>https://dev.to/codingvibe</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F783853%2F493def92-e907-4c3b-9227-89cd9d33ca18.jpg</url>
      <title>DEV Community: CodingVibe</title>
      <link>https://dev.to/codingvibe</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/codingvibe"/>
    <language>en</language>
    <item>
      <title>Programming As A Hobby -- Let's Make Coding Like Knitting</title>
      <dc:creator>CodingVibe</dc:creator>
      <pubDate>Tue, 22 Mar 2022 02:53:55 +0000</pubDate>
      <link>https://dev.to/codingvibe/programming-as-a-hobby-lets-make-coding-like-knitting-4dem</link>
      <guid>https://dev.to/codingvibe/programming-as-a-hobby-lets-make-coding-like-knitting-4dem</guid>
      <description>&lt;p&gt;Recently, I've been having tons of fun &lt;a href="https://twitch.tv/codingvibe"&gt;programming on stream&lt;/a&gt; and realized it was because the pressure was low and the goal was simple and relevant. I decided to distill those feelings in to a relatively short talk showing off projects, tossing out potential ideas, and trying to open the minds of a non-technical audience to the the world of software without self-imposed barriers or self conscious feelings of ineptitude. I showed off such ridiculous things as an offline LoFi Girl-inspired music visualization site, a Twitter bot for tweeting Cheesecake Factory menu changes, and a tool to send Instagram photos to my relatives who refuse to use Instagram.&lt;/p&gt;

&lt;p&gt;This talk's also available on YouTube here &lt;a href="https://www.youtube.com/watch?v=S82LorEHeNg"&gt;https://www.youtube.com/watch?v=S82LorEHeNg&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Talk given March 18th, 2022 for OJO Labs as part of a Beer Friday talk series. &lt;/p&gt;

</description>
    </item>
    <item>
      <title>This Script is Only Useful to Me (Probably)</title>
      <dc:creator>CodingVibe</dc:creator>
      <pubDate>Thu, 03 Mar 2022 02:26:34 +0000</pubDate>
      <link>https://dev.to/codingvibe/this-script-is-only-useful-to-me-probably-2pg7</link>
      <guid>https://dev.to/codingvibe/this-script-is-only-useful-to-me-probably-2pg7</guid>
      <description>&lt;p&gt;I have a podcast with a friend and we were interested in uploading our episodes in full to YouTube. Unfortunately, he doesn't know how to video edit and I'm busy with my job, streaming, the podcast, and writing articles like this, so it seemed like YouTube as a podcast platform was dead to us. I did a bit of research and it turns out both our podcast platform Buzzsprout and YouTube have APIs available for uploading, which meant if I invested the time, I could bundle up the uploading work in to one script and have it done even faster.&lt;/p&gt;

&lt;p&gt;Then the classic dilemma hit me -- do I really want to sink the time in to doing this? There's so many factors that go in to that like how much time it'll save me, how much time it'll take, will anyone else find it useful. Ultimately, I hit upon the piece of logic I often hit on when deciding what personal projects to do -- it sounds fun so why not?&lt;/p&gt;

&lt;h2&gt;
  
  
  Three Scripts
&lt;/h2&gt;

&lt;p&gt;First off, I decided to write three separate scripts to do the following operations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Upload the podcast to Buzzsprout&lt;/li&gt;
&lt;li&gt;Create a visualization video for the podcast. Essentially a static image with audio visualization on top with the podcast as the audio&lt;/li&gt;
&lt;li&gt;Upload a video to YouTube&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All three on their own are small, atomic operations that can be stitched together with an overarching script or CI/CD platform to form a complete workflow, but can also be used individually. Since the upload data required for both Buzzsprout and YouTube are similar (time to publish, title, description, and episode number), it makes sense to streamline the input of data in to both upload scripts and call the script just once.&lt;/p&gt;

&lt;h2&gt;
  
  
  Podcast Workflow Automator
&lt;/h2&gt;

&lt;p&gt;Copying and pasting the code from all three scripts and making one super script does future me a disservice. By smashing them together, but also having them separate, any changes in one code base needs to also be copy/pasted in to the other code base and if I don't remember that, I'll end up fixing bugs or coding enhancements twice. As mentioned earlier, I could have one base script and call these individual scripts on their own via Bash, Powershell, or a CI/CD platform, but since Python also allows you to import code from other &lt;code&gt;.py&lt;/code&gt; files, I decided to keep it consistent and go for that option.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prepping individual scripts for import
&lt;/h2&gt;

&lt;p&gt;Unfortunately, the way in which I usually write standalone scripts isn't compatible with import, so a few changes had to be made. Upon initially writing the scripts, my code looked like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
  &lt;span class="n"&gt;parser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;argparse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ArgumentParser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_argument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--foo&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;# script logic
&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This structure doesn't allow us to use the meat and potatoes of the script without grabbing arguments from &lt;code&gt;argparse&lt;/code&gt;. To fix this, we pull all the &lt;code&gt;argparse&lt;/code&gt; logic in to its own function, then call the main function from that. The &lt;code&gt;main&lt;/code&gt; function is also renamed to something more logical so when we're importing it in other functions, we're not scratching our heads wondering what &lt;code&gt;main&lt;/code&gt; does.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;call_with_args&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
  &lt;span class="n"&gt;parser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;argparse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ArgumentParser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_argument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--foo&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse_known_args&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nf"&gt;upload_podcast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;upload_podcast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="c1"&gt;# upload logic
&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;call_with_args&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now that our relevant functions have been renamed, we can move on to exposing and importing them in to our new script. First off, the base script needed to be moved to a directory with the name I wanted to use for the package. Next an &lt;code&gt;__init__.py&lt;/code&gt; file had to be created alongside the script that imported and exposed the primary function as part of being a module. Then a &lt;code&gt;setup.py&lt;/code&gt; file detailing the package and its dependencies had to be created in the base directory. All of that is to enable importing in the &lt;code&gt;requirements.txt&lt;/code&gt; like this:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git+https://github.com/codingvibe/audio-to-vizualization@main#egg=audio_to_visualization
git+https://github.com/codingvibe/buzzsprout-uploader@main#egg=buzzsprout_uploader
git+https://github.com/codingvibe/youtube-uploader@main#egg=youtube_uploader
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now we can import the relevant functions in to our combined script like any normal package this:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;buzzsprout_uploader&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;upload_podcast&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;audio_to_visualization&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;create_vizualization&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;youtube_uploader&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;upload_video&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Was this a non-trivial amount of work to do for something nobody is likely going to use? Yes. Are there easier, dirtier ways to do this? Absolutely. Since I have the repos locally, I could have just done this:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;../&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;buzzsprout_uploader.buzzsprout_uploader&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;upload_podcast&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;audio_to_visualization.audio_to_visualization&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;create_vizualization&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;youtube_uploader.youtube_uploader&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;upload_video&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Had I done this, I wouldn't have had to bother with the &lt;code&gt;script.py&lt;/code&gt; or package directory. I decided to go with the pip-importable way just to get some experience doing it and on the off chance anyone else would use this. Had I not intended to upload it to Github, I definitely would have done it the lazy way (and in fact I did on my &lt;a href="https://www.twitch.tv/codingvibe" rel="noopener noreferrer"&gt;Twitch stream&lt;/a&gt; and only made it importable when I wrote this article). Doing it the "right" way took quite a while and lead to this fun experience:&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1498493630411157507-456" src="https://platform.twitter.com/embed/Tweet.html?id=1498493630411157507"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1498493630411157507-456');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1498493630411157507&amp;amp;theme=dark"
  }



&lt;/p&gt;
&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Is this a project more people can use than just me? Maybe, but honestly it doesn't matter -- it's going to make my life marginally easier and was fun to write. I spent probably 20 hours taking my time to upload an episode to Buzzsprout and YouTube from 20 minutes to 5, which means it'll be worth the time investment once we have 80+ episodes. As the saying goes, "why spend 10 minutes doing a task when I can spend 3 hours automating it?"&lt;/p&gt;

&lt;p&gt;The three individual scripts you can find here:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/codingvibe" rel="noopener noreferrer"&gt;
        codingvibe
      &lt;/a&gt; / &lt;a href="https://github.com/codingvibe/audio-to-vizualization" rel="noopener noreferrer"&gt;
        audio-to-vizualization
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Given an audio file and background image, make an audio visualization on the image to the audio
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Audio to Visualization&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;The purpose of this small Python script is to transform an audio file in to a video using a background image and an audio visualizer. This tool was written leveraging ffmpeg and requires it be installed and accessible via the &lt;code&gt;ffmpeg&lt;/code&gt; command on the command line.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;FFMPEG&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;Download &lt;code&gt;ffmpeg&lt;/code&gt; and get access to the documentation at &lt;a href="https://www.ffmpeg.org/" rel="nofollow noopener noreferrer"&gt;https://www.ffmpeg.org/&lt;/a&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Requirements&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;Install via pip:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pip install -r requirements.txt&lt;/code&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Run the script&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;python audio_to_visualization/audio_to_visualization.py &amp;lt;arguments&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Command line arguments&lt;/h3&gt;

&lt;/div&gt;

&lt;p&gt;&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;br&gt;
&lt;thead&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;th&gt;Argument&lt;/th&gt;
&lt;br&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;br&gt;
&lt;th&gt;Required&lt;/th&gt;
&lt;br&gt;
&lt;th&gt;Default&lt;/th&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;/thead&gt;
&lt;br&gt;
&lt;tbody&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;--audio&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;path to audio file to visualize&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;--background&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;path to image to use for background&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;--output&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;path and name of output file. Must end in .mp4&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;N/a&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;--vis-background-to-vid-ratio&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;ratio of visualization background height to input image height (0.0-1.0)&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;0.2&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;--vis-waves-to-vid-ratio&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;ratio of visualization waves height to input image height (0.0-1.0)&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;0.15&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;--vis-color&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;color for visualization waveforms. can be used multiple times&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;/tbody&gt;
&lt;br&gt;
&lt;/table&gt;&lt;/div&gt;…&lt;/p&gt;
&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/codingvibe/audio-to-vizualization" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;

&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/codingvibe" rel="noopener noreferrer"&gt;
        codingvibe
      &lt;/a&gt; / &lt;a href="https://github.com/codingvibe/buzzsprout-uploader" rel="noopener noreferrer"&gt;
        buzzsprout-uploader
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Simple script to upload a podcast to Buzzsprout
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;buzzsprout-uploader&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;Simple script to upload a podcast to Buzzsprout.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Requirements&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;Install via pip:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pip install -r requirements.txt&lt;/code&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Run the script&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;&lt;code&gt;python buzzsprout_uploader/buzzsprout_uploader.py &amp;lt;arguments&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;API Key and Podcast ID&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;A Buzzsprout API key and the ID of your podcast are both required to run this script. You can obtain both by logging in to Buzzsprout and navigating to &lt;a href="https://www.buzzsprout.com/my/profile/api" rel="nofollow noopener noreferrer"&gt;https://www.buzzsprout.com/my/profile/api&lt;/a&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Command line arguments&lt;/h3&gt;

&lt;/div&gt;

&lt;p&gt;&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;br&gt;
&lt;thead&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;th&gt;Argument&lt;/th&gt;
&lt;br&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;br&gt;
&lt;th&gt;Required&lt;/th&gt;
&lt;br&gt;
&lt;th&gt;Default&lt;/th&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;/thead&gt;
&lt;br&gt;
&lt;tbody&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;--audio&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;path to audio file to upload&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;--title&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;title of the podcast&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;--description&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;description of the podcast&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;--tags&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;space separated list of tags for the podcast&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;[]&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;--publish-at-date&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;date to publish video (format is YYYY-MM-DD)&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;false&lt;/td&gt;


&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;--publish-at-time&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;time to publish video (iso format)&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;false&lt;/td&gt;


&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;--episode-number&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;episode number of this upload&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;If not supplied, most recent episode number + 1&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;--season-number&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;season number for this upload&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;If not supplied, most recent episode number&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;--private&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;whether or not&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;/tbody&gt;
&lt;br&gt;
&lt;/table&gt;&lt;/div&gt;…&lt;/p&gt;
&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/codingvibe/buzzsprout-uploader" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;

&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/codingvibe" rel="noopener noreferrer"&gt;
        codingvibe
      &lt;/a&gt; / &lt;a href="https://github.com/codingvibe/youtube-uploader" rel="noopener noreferrer"&gt;
        youtube-uploader
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Updated version of the Python YouTube upload example from Google with extra command line arguments
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;youtube-uploader&lt;/h1&gt;

&lt;/div&gt;

&lt;p&gt;Updated version of the Python YouTube upload example from Google with extra command line arguments.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Install Requirements&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;pip install&lt;/code&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Run the script&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;python youtube_uploader.py &amp;lt;arguments&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Command line arguments&lt;/h3&gt;

&lt;/div&gt;

&lt;p&gt;&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;br&gt;
&lt;thead&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;th&gt;Argument&lt;/th&gt;
&lt;br&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;br&gt;
&lt;th&gt;Required&lt;/th&gt;
&lt;br&gt;
&lt;th&gt;Default&lt;/th&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;/thead&gt;
&lt;br&gt;
&lt;tbody&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;--file&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;path to video file to upload&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;--title&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;title of the uploaded video&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;Test Title&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;--description&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;description of the video&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;Test Description&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;--category&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;YouTube category of video (&lt;a href="https://developers.google.com/youtube/v3/docs/videoCategories/list" rel="nofollow noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://developers.google.com/youtube/v3/docs/videoCategories/list" rel="noopener noreferrer"&gt;https://developers.google.com/youtube/v3/docs/videoCategories/list&lt;/a&gt;)&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;22&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;--keywords&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;comma separated list of tags&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;false&lt;/td&gt;


&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;--privacy-status&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;privacy status of video&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;public&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;--publish-at-date&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;date to publish video (format is YYYY-MM-DD)&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;false&lt;/td&gt;


&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;--publish-at-time&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;time to publish video (iso format)&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;false&lt;/td&gt;


&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;--client-secrets-file&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;path to client secrets json file&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;&lt;code&gt;youtube-uploader-client-credentials.json&lt;/code&gt;&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;/tbody&gt;
&lt;br&gt;
&lt;/table&gt;&lt;/div&gt;&lt;br&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/codingvibe/youtube-uploader" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;And the final workflow script is here:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/codingvibe" rel="noopener noreferrer"&gt;
        codingvibe
      &lt;/a&gt; / &lt;a href="https://github.com/codingvibe/podcast-workflow-automator" rel="noopener noreferrer"&gt;
        podcast-workflow-automator
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A script that uploads a podcast to Buzzsprout, creates an audio visualization of your podcast, then uploads to YouTube
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;podcast-workflow-automator&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;A script that uploads a podcast to Buzzsprout, creates an audio visualization of your podcast, then uploads to YouTube&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Command line arguments&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;I know there are a lot. I'm sorry.&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Argument&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Required&lt;/th&gt;
&lt;th&gt;Default&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;--audio&lt;/td&gt;
&lt;td&gt;path to audio file to upload&lt;/td&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;--title&lt;/td&gt;
&lt;td&gt;title of the uploaded podcast and video&lt;/td&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;--description&lt;/td&gt;
&lt;td&gt;description of the podcast and video&lt;/td&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;--api-key&lt;/td&gt;
&lt;td&gt;Buzzsprout API key to use to upload&lt;/td&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;--podcast-id&lt;/td&gt;
&lt;td&gt;ID of the podcast to upload to&lt;/td&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;--background-image&lt;/td&gt;
&lt;td&gt;path to image to use for background in video&lt;/td&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;--tags&lt;/td&gt;
&lt;td&gt;space separated list of tags for the podcast and video&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;--episode-number&lt;/td&gt;
&lt;td&gt;episode number of this upload&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;td&gt;If not supplied, most recent episode number + 1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;--season-number&lt;/td&gt;
&lt;td&gt;season number for this upload&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;td&gt;If not supplied, most recent episode number&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;--private&lt;/td&gt;
&lt;td&gt;whether or not this upload should be private&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;--publish-at-date&lt;/td&gt;
&lt;td&gt;date&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;…&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/codingvibe/podcast-workflow-automator" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>python</category>
      <category>showdev</category>
      <category>discuss</category>
      <category>motivation</category>
    </item>
  </channel>
</rss>
