<?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>Forem: Dan Han</title>
    <description>The latest articles on Forem by Dan Han (@danhan01010).</description>
    <link>https://forem.com/danhan01010</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%2F129292%2Fba270ea5-001f-467b-91e9-c3410990b844.png</url>
      <title>Forem: Dan Han</title>
      <link>https://forem.com/danhan01010</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/danhan01010"/>
    <language>en</language>
    <item>
      <title>Mastodon Backup</title>
      <dc:creator>Dan Han</dc:creator>
      <pubDate>Sun, 20 Nov 2022 00:00:00 +0000</pubDate>
      <link>https://forem.com/danhan01010/mastodon-backup-bcc</link>
      <guid>https://forem.com/danhan01010/mastodon-backup-bcc</guid>
      <description>&lt;p&gt;I have been active on Mastodon, posting one reactive, misguided, opinion per day. In this blog post, I’ll describe my mastodon backup process.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why backup posts/toots?
&lt;/h2&gt;

&lt;p&gt;The things I am posting to mastodon are important to me. I do my best to post thoughts and opinions that I think are worthwhile. I hope that they’ll be useful to others, which is why I’m not just posting to a local text file. But even if they don’t have value to others, I hope these old posts can be valuable to me. Maybe they can remind “future me” of something I forgot, or maybe they can help “future me” realize how far I have come. It’s really hard to remember how dumb I used to be. So, I want to have access to all my ramblings for all eternity.&lt;/p&gt;

&lt;p&gt;I trust that the amazing folks maintaining my mastodon instance, fosstodon, want to provide a service that gives gives me full access to all of my toots. They surely want to preserve data and have it available for me. With that said, issues can arise. Stuff can happen that may block me from my own toots. Maybe there’s some bad actors that wipe out data. Maybe the instance runs out of funds, I miss all the warning messages, and it’s shut down before I get a chance to get my data. Maybe I turn on some setting that auto deletes my toots.&lt;/p&gt;

&lt;p&gt;So, backup is important to me.&lt;/p&gt;

&lt;h2&gt;
  
  
  My backup process
&lt;/h2&gt;

&lt;p&gt;My backup process depends on a few tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/kensanata/mastodon-archive" rel="noopener noreferrer"&gt;mastodon-archive&lt;/a&gt; provides the scripts to fetch the backup and render it nicely in html.&lt;/li&gt;
&lt;li&gt;Docker provides a nice environment for running the script.&lt;/li&gt;
&lt;li&gt;Synology NAS provides a task scheduler where I run Docker and stores the backup files for me.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The backup script
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/kensanata/mastodon-archive" rel="noopener noreferrer"&gt;mastodon-archive&lt;/a&gt; has a thorough README and help documentation, so you will learn more by reading the docs there. I read them, skimmed them at least, and I found two commands to be particularly useful.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mastodon-archive archive danhan01010@fosstodon.org

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create a file like &lt;code&gt;fosstodon.org.user.danhan01010.json&lt;/code&gt; that contains all of your data. The first time you run it, it will ask you to go through a couple of extra steps to create a “secret” file. This gives the script the information needed to fetch your archive. It’s a one time thing, and the same secret file can be reused in the future.&lt;/p&gt;

&lt;p&gt;The json file can be difficult to read. It can be rendered into a nice html format by running&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mastodon-archive html danhan01010@fosstodon.org

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;which gives you a file like &lt;code&gt;fosstodon.org.user.danhan01010.statuses.0.html&lt;/code&gt;, which you can open with your web browser. here’s an image of what I see after my latest backup.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs66mxunvj5u1krmxjht2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs66mxunvj5u1krmxjht2.png" alt="Image of recent nicely rendered by mastodon archive html tool" width="800" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Docker and Synology NAS
&lt;/h2&gt;

&lt;p&gt;I wanted to automatically and periodically run the backup scripts, so I defaulted to tools I’m familiar with and have access to. Here’s my super simple Dockerfile.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM python:3.9-slim-buster
WORKDIR /app
COPY . /app
RUN python3.9 -m pip install mastodon_archive

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It does two things. It copies secret files over to Docker, and installs the mastodon_archive package. Note, installing from pip will ensure we are using the latest published version of the package. You could pin the install to a particular version or create the package from source files if you worry that a broken change could mess things up. I just went with a simple install for now.&lt;/p&gt;

&lt;p&gt;Then, I use docker compose to make things easy to run. Here’s my docker-compose.yaml.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: "3.9"
services:
  archive:
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - .:/app
    command:
      - /usr/local/bin/mastodon-archive
      - archive
      - danhan01010@fosstodon.org
  html:
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - .:/app
    command:
      - /usr/local/bin/mastodon-archive
      - html
      - danhan01010@fosstodon.org

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It’s a bit longer, but doesn’t really do too much either. It sets up two services: one to fetch a backup file and another to create an html file to view the backup. With all these docker files ready, you can run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker-compose build &amp;amp;&amp;amp; docker-compose run archive &amp;amp;&amp;amp; docker-compose run html

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I added that command to a scheduled task in my local Synology NAS. It runs once a week, and my backup process is complete. Of course, I have synology also running backups of all my files, so these files are backed up as well. Redundancy is good!&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;If you put any thought or energy into your Mastodon posts, you will want to back them up. I posted how I do it, but I’m open to hearing about any other better strategies.&lt;/p&gt;

</description>
      <category>coding</category>
      <category>docker</category>
      <category>mastodon</category>
      <category>synology</category>
    </item>
    <item>
      <title>Revisiting Your Technology Past</title>
      <dc:creator>Dan Han</dc:creator>
      <pubDate>Sun, 20 Nov 2022 00:00:00 +0000</pubDate>
      <link>https://forem.com/danhan01010/revisiting-your-technology-past-480i</link>
      <guid>https://forem.com/danhan01010/revisiting-your-technology-past-480i</guid>
      <description>&lt;p&gt;A couple of years ago, I was regularly developing with &lt;a href="https://flask.palletsprojects.com/"&gt;Flask&lt;/a&gt;. Since then, I’ve moved onto other projects and technologies. Today, I decided to revisit this “old” tech stack; it was a fun and interesting experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  A little background
&lt;/h2&gt;

&lt;p&gt;When I first used Flask, I was trying to build a personal website. It would be a simple site, containing a blog, a list of projects, and other static content. I built something and used it for a while. But eventually, I decided to shut my custom project down, and began &lt;a href="https://programmerdays.com/2020/04/12/Blogging.With.Github.Pages/"&gt;hosting my site with github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Since shutting my site down, I hadn’t done any programming with Flask. Today, I was thinking of building a new website/app. I read through some introductory texts on a few existing solutions: Django, Ghost, Wordpress, etc… And then, I came across my old friend Flask.&lt;/p&gt;

&lt;p&gt;For probably the same reasons as before, Flask appealed to me. It uses python, which I like. It feels relatively lightweight, at least moreso than Django. So, here I am again, after a couple of years, trying to build my Flask application, again for the second time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Familiar faces and places
&lt;/h2&gt;

&lt;p&gt;As I began building a new Flask app, things felt very familiar. The code was really easy to understand, because well, I had seen it before.&lt;/p&gt;

&lt;p&gt;Google searches led me to &lt;a href="https://blog.miguelgrinberg.com/"&gt;Miguel Grinberg’s site&lt;/a&gt;. His site contains lots of great tutorials related to Flask. I used it a couple of years ago, so I was sure the content would be good.&lt;/p&gt;

&lt;p&gt;When you go through introductory tutorials, it is easy to be overwhelmed. There is just so much to learn: domain specific jargon, new concepts, and other technical difficulties. Good tutorials try to explain the bare minimum to keep you moving, while introducing a whole new world. Tutorial authors must maintain a fine line to push forward without losing the reader.&lt;/p&gt;

&lt;p&gt;But for experienced developers, who are revisiting a topic, there is a lot more room for error. Instead of trying to focus in and just get through the tutorial, you breeze through the easy steps and can absorb extra nuggets of information. When I went through the Flask tutorial, I diverged from the tutorial and experimented with different implementations. If things went wrong, it was easy to get back on track.&lt;/p&gt;

&lt;p&gt;Revisitng Flask today, felt like a pleasant warm up. The muscle memory of how Flask works faded, but I’m waking them up and was able to get coding right away.&lt;/p&gt;

&lt;h2&gt;
  
  
  New bells and whistles
&lt;/h2&gt;

&lt;p&gt;Coming back to Flask, I found that the landscape has changed a little. I’m sure the platform has improved internally, but I haven’t gotten deep enough into it to notice. I did however notice that tutorials provide instructions for building with Docker and putting a React frontend UI in front of the Flask server.&lt;/p&gt;

&lt;p&gt;Finding that Flask is ready to work with these technologies is a nice surprise. I use Docker a lot these days, so I’m comfortable in that development workflow. I have been meaning to learn React, so this project gives me a good reason to learn.&lt;/p&gt;

&lt;h2&gt;
  
  
  What did I build?
&lt;/h2&gt;

&lt;p&gt;Nothing much. I have a super simple app consisting of a flask backend server and a react frontend UI. It is ready to work and build with Docker. If you are curious about it, I posted the project here &lt;a href="https://github.com/dan-han-101/simple-flask-react-docker"&gt;simple-flask-reack-docker&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions and Recommendations
&lt;/h2&gt;

&lt;p&gt;I highly recommend trying out technologies that you used in the past. Maybe some of the things you hated about it have improved? So, you’ll find it more pleasant than before. Even if things haven’t changed a lot, you will still have some memory of how things used to work, so you should be able to get started without a painful learning curve.&lt;/p&gt;

&lt;p&gt;And as a more experienced developer, you will bring a new perspective to technologies you used before. You may be able to understand more of how things work, which feels good. You may also be able to incorporate some of your new knowledge so that you can get more out of that old tech stack.&lt;/p&gt;

&lt;p&gt;We all start as coding newbs. Blindly pointing and clicking, hoping to just get those “hello world” applications to run. Before you realize it, you have learned and forgotten plenty of tech stacks. Instead of jumping into the new trendy toolset, I recommend revisiting some old stuff and see what things looks like there. I think you’ll find it to be a rewarding experience.&lt;/p&gt;

</description>
      <category>coding</category>
      <category>docker</category>
      <category>flask</category>
      <category>react</category>
    </item>
    <item>
      <title>Thoughts on Mastodon After 1 Week</title>
      <dc:creator>Dan Han</dc:creator>
      <pubDate>Sun, 13 Nov 2022 00:00:00 +0000</pubDate>
      <link>https://forem.com/danhan01010/thoughts-on-mastodon-after-1-week-3je4</link>
      <guid>https://forem.com/danhan01010/thoughts-on-mastodon-after-1-week-3je4</guid>
      <description>&lt;p&gt;Last week, I noted that I &lt;a href="https://programmerdays.com/2022/11/06/Joined-Mastodon/"&gt;joined Mastodon&lt;/a&gt;. My overall recommendation is to join and give it a try. The rest of this post provides some other notes on mastodon after 1 week of usage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Moved to Fosstodon instance
&lt;/h2&gt;

&lt;p&gt;I originally joined a large “general” instance called “mas.to”. It seemed OK enough, but I wanted a more tech-centric focus, so I switched to “fosstodon”. You can now find me here&lt;/p&gt;

&lt;p&gt;&lt;a href="https://fosstodon.org/@danhan01010"&gt;https://fosstodon.org/@danhan01010&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want to switch instances, I’d recommend doing it early. It’s easy to transfer your follows and followers over, but migrating posts over isn’t done automagically for you. So, it’s better to re-home early on, when you are OK letting your few posts remain in your old instance.&lt;/p&gt;

&lt;p&gt;If you find the idea of instances intimidating and confusing, I hear you. My advice is to spend a very small amount of time reading about it. I’d read one or two of the top Google hits on the subject. Then, just dive in and pick one. After a bit, you will find that your instance is fine, or that you may want to switch. In either case, you learn more by doing than being stuck in decision paralysis.&lt;/p&gt;

&lt;h2&gt;
  
  
  Decorated my new home
&lt;/h2&gt;

&lt;p&gt;I added a avatar, banner, bio and a link to &lt;a href="https://programmerdays.com"&gt;my website&lt;/a&gt; to my mastodon profile. I created the avatar from some free web tool and used google drawing to create a simple banner. Personalizing the default stuff is fun. It’s also more inviting and engaging for others than the default stuff you get.&lt;/p&gt;

&lt;p&gt;It’s customary to create and pin an introduction post, but I haven’t done that yet. For now, I’ve only been posting about programming/coding. I’m not sure if I will expand my posts to other parts of my life. I’ll wait until I establish my identity on this platform before setting the introduction.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tools
&lt;/h2&gt;

&lt;p&gt;I’ve used the web UI, the metatext phone app and even the toot command line tool. I found that all of it worked well. Some things were a little bit confusing, but I blame my own user error and misunderstandings.&lt;/p&gt;

&lt;p&gt;I’ve also tried the &lt;a href="https://github.com/kensanata/mastodon-backup"&gt;mastodon-backup&lt;/a&gt; tool. It worked out of the box. I’ve still got to figure out how to automate it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Content
&lt;/h2&gt;

&lt;p&gt;By design, mastodon gives you exactly what you ask for. Your personal timeline will only contain stuff from those you follow or stuff they boost. For newcomers, who are not following anyone, things can feel empty. You can jump to other timelines that have bigger scope, ie within your instance or beyond, but the information may not target your interests.&lt;/p&gt;

&lt;p&gt;I could try to search for people to follow and curate the perfect timeline to start, but instead, I’ve decided to focus on posting regularly. I’m aiming to post one toot per day. I’d like to be more of a producer than a passive consumer. If anyone follows me, I’ll follow them back. If you are interested in me, I’m probably interested in your thoughts. It’s simple to unfollow, so there is little cost.&lt;/p&gt;

&lt;p&gt;As I run into interesting posts, I’ll follow the posters. Over time, I’m sure I can evolve my follower list to create a rich timeline for me to browse.&lt;/p&gt;

&lt;h2&gt;
  
  
  Future plans
&lt;/h2&gt;

&lt;p&gt;My plan is the following. Post a thought once per day to mastodon. I think this will force me to publish ideas, even if they are half baked. The goal is to post things without worrying if they are perfect or not. Waiting for perfection has been a blocker for me in the past.&lt;/p&gt;

&lt;p&gt;Then, once a week, write a blog post. I can use my recent mastodon posts as inspiration for writing ideas. Hopefully these blog posts are slightly more “baked” than my short mastodon toots.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hope and dreams
&lt;/h2&gt;

&lt;p&gt;The things I noted above are things I’ve done or will do. The last reason for using Mastodon is for the hope that it can connect me with others. I hope that I engage with some interesting folks and ideas and that we’re all better off for it.&lt;/p&gt;

</description>
      <category>writing</category>
    </item>
    <item>
      <title>Joined Mastodon</title>
      <dc:creator>Dan Han</dc:creator>
      <pubDate>Sun, 06 Nov 2022 00:00:00 +0000</pubDate>
      <link>https://forem.com/danhan01010/joined-mastodon-1ame</link>
      <guid>https://forem.com/danhan01010/joined-mastodon-1ame</guid>
      <description>&lt;p&gt;I just joined &lt;a href="https://joinmastodon.org/"&gt;Mastodon&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Twitter is in a point of transition. It got bought, lots of folks were laid off, and major changes were announced. Most people are predicting doom and gloom. And as people worried about the end of twitter, I heard about the app “Mastodon” a bunch of times. So, I decided to try it out. After some pointing and clicking I created a new account.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://mas.to/@danhan01010"&gt;https://mas.to/@danhan01010&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My tentative plan is to just post to it regularly. I will try to get out of my way and just post things. In my bio, I said I’ll be posting “half-baked ideas”. I could then look through old posts and expand on them as more fully baked blog posts.&lt;/p&gt;

&lt;p&gt;Let’s see how this goes.&lt;/p&gt;

</description>
      <category>writing</category>
    </item>
    <item>
      <title>Zen of Every Day Things</title>
      <dc:creator>Dan Han</dc:creator>
      <pubDate>Sun, 14 Mar 2021 00:00:00 +0000</pubDate>
      <link>https://forem.com/danhan01010/zen-of-every-day-things-2jc3</link>
      <guid>https://forem.com/danhan01010/zen-of-every-day-things-2jc3</guid>
      <description>&lt;p&gt;This month, I read most of &lt;a href="https://www.amazon.com/Zen-Art-Motorcycle-Maintenance-Inquiry-dp-0688002307/dp/0688002307"&gt;Zen and the Art of Motorcycle Maintenance&lt;/a&gt; and some of the &lt;a href="https://www.amazon.com/Design-Everyday-Things-Revised-Expanded/dp/0465050654"&gt;Design of Everyday Things&lt;/a&gt;. I couldn’t quite finish either of them before time ran out and they were due back to the library. With that said, I think I got a good feel for what each author was saying overall.&lt;/p&gt;

&lt;p&gt;Both books delve into the relationship between objects and people. In Zen of Motorocycle Maintenance, the author views objects with reverence. For him, a motorcycle is a dynamic being. He observes and responds to it. As it strains from overuse, he reduces the speed of the bike so it can recover. He is attuned to any signs of failure and promptly works to correct issues. The limitations of a motorcyle, such as overheating, are not strictly design flaws. They are bounds in which the object can work well. If you place the object out of bounds, you can not blame the bike for coming up short.&lt;/p&gt;

&lt;p&gt;In the Design of Everyday things, the author was much less forgiving of the object. Objects provide some utility and give some hints as to how a user may access that utility. For example, a door provides the utility of transit into a building. Its door handle will have a certain shape that indicates to the user whether you should push, pull, turn or slide to open the door. If the user of a door cannot easily deduce how the door should be used, the blame is on the door, or the designer of the door. It should have been made in a way that would make things easier for the user.&lt;/p&gt;

&lt;p&gt;I wonder how the authors of these books would feel about the other book.&lt;/p&gt;

&lt;p&gt;I sympathize with both camps. As a software developer, it’s good to think like the author of Design of Everyday Things. You want to make things that are generally easy to use. Any confusion can lead to user errors and overall dissatisfaction. So, you have to put yourself in the mind of the new user and guess how they might feel about your product or API. Is the most natural way to use your product also the correct way and also the easiest thing to do? Telling people to read the manual is a signal that the design can be improved.&lt;/p&gt;

&lt;p&gt;As a software developer, it’s also good to think like the author of Zen of Motorcycle Maintenance. You need to observe and be attuned to your code. If it misbehaves with bugs or bad performance, you can’t just blame the original authors and say the design is poor. You have to foresee or at least react to issues. Each bug is an opportunity to understand your system a little bit more and improve your system to be a little more robust.&lt;/p&gt;

&lt;p&gt;In total, while I see the merits of both, I think I lean towards the Zen of Motorcycle philosophy. What about you?&lt;/p&gt;

</description>
      <category>reading</category>
    </item>
    <item>
      <title>One Win for a Team Lead</title>
      <dc:creator>Dan Han</dc:creator>
      <pubDate>Thu, 01 Oct 2020 00:00:00 +0000</pubDate>
      <link>https://forem.com/danhan01010/one-win-for-a-team-lead-9ko</link>
      <guid>https://forem.com/danhan01010/one-win-for-a-team-lead-9ko</guid>
      <description>&lt;p&gt;Being a manager is challenging. On any given day, I can look back on so many things that I could’ve done better. I could have brought more energy to a meeting. I could have spotted something that was bothering a team member a little earlier. I could have prioritized work differently or reduced the scope of a project. And on and on and on…&lt;/p&gt;

&lt;p&gt;And the wins can feel quite sparse. When I was a developer, each day had some level of success. I got the code to compile. I was able to reproduce and fix a bug. I helped a colleague debug an issue with one of our libraries. Even when our team has a big successful release, it’s not as easy to spot what the team lead actually contributed.&lt;/p&gt;

&lt;p&gt;So when I come across a clear win, I make a special note of it. Last week, I had one of those wins.&lt;/p&gt;

&lt;p&gt;One of my team members was falling behind. He was working on a bunch of items: a bug fix, some research work, some admin work. He happily volunteered for the work, but they weren’t getting done. Prior to our weekly 1-1, I wondered what was the best way I could help him course correct.&lt;/p&gt;

&lt;p&gt;I eventually approached him with a couple of questions instead of demands. I asked him how he was doing? I said that I noticed he had a lot of things pending, and asked him if this was his preferred working style.&lt;/p&gt;

&lt;p&gt;Luckily, he said he didn’t like what was going on. This was fortunate. Instead of me making demands, such as “Get focused and start finishing work”, he came up with some modifications. He’d try to wrap things up, post updates more regularly, and ask the team for help earlier. I said I understood his current situation and offered my help. I told him that I would help prioritize items for him so that we could spend more time on the things he really enjoyed. After some discussion, I felt we were in a good trusting space. At that point, I was able to say the higher level things I really wanted. I wanted him to get things done and to be transparent with updates. I think this discussion went well. His goals were now aligned with the team’s goals.&lt;/p&gt;

&lt;p&gt;I don’t know what will happen next. Maybe things will improve. Maybe he will continue his bad habits. No matter what, we had a conversation that lays the groundwork for building trust and partnership.&lt;/p&gt;

</description>
      <category>management</category>
    </item>
    <item>
      <title>Setting up NextCloud on My Raspberry Pi</title>
      <dc:creator>Dan Han</dc:creator>
      <pubDate>Sat, 01 Aug 2020 00:00:00 +0000</pubDate>
      <link>https://forem.com/danhan01010/setting-up-nextcloud-on-my-raspberry-pi-38l</link>
      <guid>https://forem.com/danhan01010/setting-up-nextcloud-on-my-raspberry-pi-38l</guid>
      <description>&lt;p&gt;Over the last week or two, I set up our raspberry pi to work as a Nextcloud server. I wanted an easy way to back up photos from my phone.&lt;/p&gt;

&lt;p&gt;I read through and followed lots of guides to get it working.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://opensource.com/article/18/7/network-attached-storage-Raspberry-Pi"&gt;https://opensource.com/article/18/7/network-attached-storage-Raspberry-Pi&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pimylifeup.com/raspberry-pi-exfat/"&gt;https://pimylifeup.com/raspberry-pi-exfat/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.raspberrypi.org/documentation/configuration/external-storage.md"&gt;https://www.raspberrypi.org/documentation/configuration/external-storage.md&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://baddotrobot.com/blog/2017/10/26/upgrade-raspian-jessie-to-stretch/"&gt;http://baddotrobot.com/blog/2017/10/26/upgrade-raspian-jessie-to-stretch/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pimylifeup.com/upgrade-raspbian-stretch-to-raspbian-buster/"&gt;https://pimylifeup.com/upgrade-raspbian-stretch-to-raspbian-buster/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pimylifeup.com/raspberry-pi-nextcloud-server/"&gt;https://pimylifeup.com/raspberry-pi-nextcloud-server/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://unixetc.co.uk/2016/11/20/simple-nextcloud-installation-on-raspberry-pi/"&gt;http://unixetc.co.uk/2016/11/20/simple-nextcloud-installation-on-raspberry-pi/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now that it’s up and working, I can say that it alls works pretty well without too much trouble. With some time and perserverence, I’m sure you can set it up as well. But as a reminder to myself, I wanted to notes some things that tripped me or slowed me down. No matter how trivial the project, we should all remember, these things take some time.&lt;/p&gt;

&lt;p&gt;Even before I really got started at all, I found out that my Raspberry Pi operating system was a bit behind. So, I spent a bit of time upgrading. First, I had to upgrade from “Jessie” to “Stretch”. Then, I upgraded from “Stretch” to “Buster”. This was completely straightforward, but it took a while (hours?) to complete. It probably went quicker than that, but it was so long that I stepped away and just periodically checked on it. I think this sort of “rot” happens on any project. You go to fix one thing, but you discover you have to do a lot of other clean up before you can even get started.&lt;/p&gt;

&lt;p&gt;The next big time consuming thing was permissions. In Unix, every file and folder associated permissions. Who owns a file? Who can read, write or run a file? Setting tight permissions prevents bad-guys from messing with your stuff and keeps you from shooting yourself in the foot. But it can also be a pain. You “workaround” this problem by just relaxing all restrictions and making every file readable and writeable by everyone in the world. It’s simpler to get things done when there is no security. In contrast, doing the right thing takes longer, and the benefits are often unsatisfyingly delayed, but it’s usually worth it, right? So, I fiddled around until permissions and user ownership were just enough to get things working, and not any more than necessary.&lt;/p&gt;

&lt;p&gt;Finally, the last big time suck was figuring out how to adjust the power settings on my hard drive. I expect the NextCloud server to sporadically need to read and write to the my hard drive. It would be a couple of times per day max, and many days, no reading or writing would be needed. So, I wanted my hard drive to spin down to save on wear and tear. A lot of suggestions on using one tool or another sounded like they would work, if your hard drive was compatible. In the end, I got to a happy solution, but it took a decent amount of trial and error.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I’m glad that I completed this project and that I’m putting my raspberry pi to good use. It didn’t take too much to set up the Nextcloud server, but yet, it took longer than I expected. I’ll try to remember this whenever I estimate work. If I don’t know exactly what I’m doing, it’ll probably take a little longer than I’d guess.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Custom Domain For Github Pages</title>
      <dc:creator>Dan Han</dc:creator>
      <pubDate>Sat, 23 May 2020 00:00:00 +0000</pubDate>
      <link>https://forem.com/danhan01010/custom-domain-for-github-pages-4mg3</link>
      <guid>https://forem.com/danhan01010/custom-domain-for-github-pages-4mg3</guid>
      <description>&lt;p&gt;I recently set up &lt;a href="//2020-04-12-Blogging.With.Github.Pages"&gt;github pages to use as my blogging platform&lt;/a&gt;. And I have had no major complaints so far. I already added lots of bells and whistles: commenting, analytics, rss feed etc… Today, I’ve set up custom domain for my github pages.&lt;/p&gt;

&lt;p&gt;I already had a domain with Google Domains, so I just had to point it to my github pages site. To get it working, I followed this &lt;a href="https://medium.com/@hossainkhan/using-custom-domain-for-github-pages-86b303d3918a"&gt;medium post&lt;/a&gt; and the &lt;a href="https://help.github.com/en/github/working-with-github-pages/managing-a-custom-domain-for-your-github-pages-site"&gt;documentation from github&lt;/a&gt;. Now that it’s all done, going to any of these urls, &lt;a href="//programmerdays.com"&gt;programmerdays.com&lt;/a&gt;, &lt;a href="//wwww.programmerdays.com"&gt;wwww.programmerdays.com&lt;/a&gt;, &lt;a href="//dannyhan12.github.io"&gt;dannyhan12.github.io&lt;/a&gt; should all take you to “programmerdays.com” which shows my github pages site.&lt;/p&gt;

&lt;p&gt;The process involves just 3 steps, but I found it a little confusing at first. Here’s some notes that explains what is going on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1
&lt;/h2&gt;

&lt;p&gt;First, update Google Domains or your DNS provider to send your apex domain, such as &lt;code&gt;"&amp;lt;my-awesome-custom-domain&amp;gt;.com"&lt;/code&gt; to the IP addresses owned by github. This is pretty straightforward. You need to tell the "internet" where to find the server that will process your requests.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2
&lt;/h2&gt;

&lt;p&gt;Next, update the settings of your github project to use your custom domain. Now, when Github servers get requests for &lt;code&gt;“my-awesome-custom-domain&amp;gt;.com"&lt;/code&gt;, they'll be able to properly map it to your github pages, &lt;code&gt;"&amp;lt;username&amp;gt;.github.io"&lt;/code&gt;. Conversely, if you make a request to the original github pages, the url is auto-magically updated to your custom domain.&lt;/p&gt;

&lt;p&gt;I used this curl command to review requests&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -v -L -D - https://programmerdays.com -o /dev/null 2&amp;gt;&amp;amp;1 | egrep '&amp;gt;|&amp;lt;|\*' | less , 

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and I could see that the request is sent to one of the github IP addresses and that it immediately returns with a successful code, 200. If I run the same curl command with the url of my github pages, &lt;code&gt;“&amp;lt;username&amp;gt;.github.io"&lt;/code&gt;, I get a 301 redirect rcode. Then another request is sent to my custom domain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3
&lt;/h2&gt;

&lt;p&gt;Finally, update Google Domains again. Add a CNAME for the subdomain, “www”, to your &lt;code&gt;"&amp;lt;username&amp;gt;.github.io."&lt;/code&gt; page. Now, requests going to “www.&lt;code&gt;&amp;lt;my-awesome-custom-domain&amp;gt;&lt;/code&gt;.com" will also get your github pages page. The github docs mention that the proper redirects work between a subdomain and an apex domain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Setting up a custom domain was pretty straightforward. I got it working without too much trouble, or even understanding. I then took a little time to learn about DNS records and HTTP redirects. Getting something working and learning something is a nice double win for me.&lt;/p&gt;

</description>
      <category>programming</category>
    </item>
    <item>
      <title>Tips for Writing Pull Requests</title>
      <dc:creator>Dan Han</dc:creator>
      <pubDate>Wed, 29 Apr 2020 00:00:00 +0000</pubDate>
      <link>https://forem.com/danhan01010/tips-for-writing-pull-requests-38mo</link>
      <guid>https://forem.com/danhan01010/tips-for-writing-pull-requests-38mo</guid>
      <description>&lt;p&gt;These days, when you update code, you often do it via a &lt;a href="https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests"&gt;pull request&lt;/a&gt;. You write code, create a pull request, and hope that your changes are accepted.&lt;/p&gt;

&lt;p&gt;Pull requests and code reviews are scary. Posting your code for someone to critique is nerve-wracking. Doing it in public is terrifying. Here are some tips to make it all a bit less scary.&lt;/p&gt;

&lt;h2&gt;
  
  
  Communicate
&lt;/h2&gt;

&lt;p&gt;A pull request should start with communication. The person reviewing the code should confirm that the update you want to make will be welcomed. You should confirm what you will be doing and even how you will do it. A pull request shouldn’t be a pop quiz. It should be a take home exam, where you can ask the teacher how to answer the questions before you go home. And then you can ask follow up questions as you are working on the test. Communication ensures that you are coding a fix that everybody wants.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stay Focused
&lt;/h2&gt;

&lt;p&gt;Now that you know what you want to do, deliver what you promised, but not much more or less. Don’t add extra “drive-by” fixes. If you spot a bug somewhere else in the code, don’t fix it in this Pull Request. Create an &lt;a href="https://help.github.com/en/github/managing-your-work-on-github/about-issues"&gt;issue&lt;/a&gt; so that it can be fixed later on, and stay focused on the purpose of your pull request. Don’t try to do more than one thing in this pull request. Pull requests targetting one item are easier to read and review. Getting a single pull request merged is hard. Don’t make it harder by adding in some extra things that stir up more questions and discussions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test
&lt;/h2&gt;

&lt;p&gt;Demonstrate your pull request works with tests. Add new tests to show that your update works. Or note which failing tests are restored. Code reviewers don’t have to rely on your word or their mental debugging skills to be sure everything works. The tests in the pull request prove that the code works and document the normal and edge cases that you’ve considered. If the repository isn’t easily testable, at least describe what tests you manually did to prove things work. Including some screen shots or standard output may be the best you can do, but it’s better than nothing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fit in
&lt;/h2&gt;

&lt;p&gt;Make your code look like the rest of the existing code. Whatever style conventions exist, mimic them. No matter how much you dislike the conventions used in the code base, just go with the flow. If you add code that doesn’t fit in, it’s harder to read. It’s also somewhat insulting to the original authors.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cheat
&lt;/h2&gt;

&lt;p&gt;If you’re nervous about submitting a pull request, look at other pull requests that have already been closed or are being reviewed in the repository. You can see what sort of reasons other pull requests were rejected or accepted. You can see what sort of questions people ask. This will help you avoid common mistakes.&lt;/p&gt;

&lt;h2&gt;
  
  
  What else?
&lt;/h2&gt;

&lt;p&gt;If you’ve done all of the above, you’re in a good position to get your pull request accepted. Do your best to write good code with &lt;a href="https://chris.beams.io/posts/git-commit/"&gt;good commit messages&lt;/a&gt;. Then, go ahead and submit with confidence.&lt;/p&gt;

</description>
      <category>programming</category>
    </item>
    <item>
      <title>Being Nice</title>
      <dc:creator>Dan Han</dc:creator>
      <pubDate>Sat, 18 Apr 2020 00:00:00 +0000</pubDate>
      <link>https://forem.com/danhan01010/being-nice-4aek</link>
      <guid>https://forem.com/danhan01010/being-nice-4aek</guid>
      <description>&lt;p&gt;I have always been a nice person.&lt;/p&gt;

&lt;p&gt;I am polite; please and thank yous all the time. If you ask for help, I give you some. If you make a mistake, you'll get the benefit of the doubt from me.&lt;/p&gt;

&lt;p&gt;It was always easy for me to maintain this level of aggreeability. But it's getting harder. On a personal level, I've become a parent. Kids are exhausting. They consume my patience with their unrelenting need for attention. I love showering them with love, but it's still exhausting.&lt;/p&gt;

&lt;p&gt;On a professional level, I've shifted my role from individual software developer to team lead. Being a manager is depleting my reserves of nice-ness. It takes boatloads of empathy to be an effective manager. There are so many relationships and interactions to navigate. Being consistently nice to everyone (team members, your manager, other teams, your clients, etc...) is tricky.&lt;/p&gt;

&lt;p&gt;So, I'm finding it harder to be nice. That's a big problem, because being nice is part of the job. &lt;/p&gt;

&lt;p&gt;What do I mean by being "nice"? It's a subjective thing. I think it is one of those things that &lt;a href="https://en.wikipedia.org/wiki/I_know_it_when_I_see_it"&gt;"You know it, when you see it"&lt;/a&gt;. The key question may be, how welcoming are you? When people are looking for help or advice, would they seek you or would they dread having to go to you? If you are nice enough that people like to interact with you, then that's probably nice enough.&lt;/p&gt;

&lt;p&gt;There are so many things that make a software project and software team successful. Being nice is one of them. Sure, jerks write code, their stuff gets used, and they can be successful. But people also write shoddy, untested, slow and buggy code that succeeds as well.&lt;/p&gt;

&lt;p&gt;Nice isn't necessary or sufficient for success. Steve Jobs and Linus Torvalds were infamously not nice and also super successful. Although, linus has admitted his need to &lt;a href="https://lore.kernel.org/lkml/CA+55aFy+Hv9O5citAawS+mVZO+ywCKd9NQ2wxUmGsz9ZJzqgJQ@mail.gmail.com/"&gt;increase his empathy&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;But for most of us, being nice is an important ingredient for long term success. Just as bad code slowly cripples projects with technical debt, not being nice (being a jerk) will poison a team. You will be left with code that no one wants to touch and a bunch of people who dread talking to each other.&lt;/p&gt;

&lt;p&gt;Being nice enables communication. Your team can raise concerns to you earlier and you can start addressing them before they get out of control. Instead of a teammate telling you they are leaving unexpectedly, you would be aware they were unhappy and help them shift them focus or at least make a smooth transition to another team. &lt;/p&gt;

&lt;p&gt;If you're known as a jerk, you'll miss out. Other teams won't collaborate with you. You'll miss out on building things together or waste time addressing the same issues as someone else. &lt;/p&gt;

&lt;p&gt;And on the positive side of things, being nice is contagious. Your team will pick up on this attitude and it will be part of your team's culture. We are all nice to each other. Isn't that nice?&lt;/p&gt;

&lt;p&gt;So, I want to be nicer. Here are a couple of things I have been telling myself to do more, so that I could be a nicer person/manager/teammate.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get healthy. If you are tired, hungry or otherwise unhealthy, it's harder to be nice.
&lt;/li&gt;
&lt;li&gt;When people speak, listen and don't do anything else (taking notes is OK). If you are reading or thinking about something else, it's impossible to show any real empathy.
&lt;/li&gt;
&lt;li&gt;When people send you email, read the whole thing, don't just skim.&lt;/li&gt;
&lt;li&gt;Do something. Being a passive bystander, is not the same as being nice. Take initiative. RSVP immediately, Reach out and respond to people.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Most of that boils down to being less self-centered and more interested in whoever I am trying to be nice to.&lt;/p&gt;

&lt;p&gt;Being nice isn't easy, but it's part of the job. As coders, we all spend trying to level up our development skills. As team members, are you working on being nicer?&lt;/p&gt;

</description>
      <category>management</category>
    </item>
    <item>
      <title>Blogging with Github Pages</title>
      <dc:creator>Dan Han</dc:creator>
      <pubDate>Sun, 12 Apr 2020 00:00:00 +0000</pubDate>
      <link>https://forem.com/danhan01010/blogging-with-github-pages-57n2</link>
      <guid>https://forem.com/danhan01010/blogging-with-github-pages-57n2</guid>
      <description>&lt;p&gt;I’ve tried a bunch of different blogging platforms in my day. I used out-of-the-box tools like Blogger and Wordpress for a while. I also wrote a completely home-made application based on Python/Flask for some time. There’s plusses and minuses to everything, so it’s hard to say what tool is the best for you. For me, my interests keep on changing, so, the right tool seems to change as well.&lt;/p&gt;

&lt;p&gt;In the end, the blogging software doesn’t matter nearly as much as the person writing the blog. I’ve had long periods where I stopped writing and publishing. None of the above blogging platforms could’ve helped me there. If you want to be a successful blogger, just start writing.&lt;/p&gt;

&lt;p&gt;With that said, I’m now giving &lt;a href="https://pages.github.com/"&gt;github pages&lt;/a&gt; a try.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why github pages?
&lt;/h2&gt;

&lt;p&gt;It’s free. Before, I was paying $5/month to self host. I can afford $5/month, but free is even more affordable.&lt;/p&gt;

&lt;p&gt;It’s easy. I write in markdown and save my posts to github already. So switching my blogging/publishing to github pages doesn’t involve any extra work. It’s actually less work.&lt;/p&gt;

&lt;p&gt;It seems like the right choice today. Github recently became part of Microsoft and Microsoft seems to be very developer friendly. If I’m wrong, and things aren’t so friendly here, I can always move this blob of text somewhere else.&lt;/p&gt;

&lt;h2&gt;
  
  
  Initial Impressions
&lt;/h2&gt;

&lt;p&gt;I was able to get something up and working in a few minutes. But then, I found &lt;a href="https://www.smashingmagazine.com/2014/08/build-blog-jekyll-github-pages/"&gt;this guide&lt;/a&gt; which helped me transform my barebones site into a more fully featured blog.&lt;/p&gt;

&lt;p&gt;I forked &lt;a href="https://github.com/barryclark/jekyll-now"&gt;the repository&lt;/a&gt;, renamed it, and then dropped my old blog posts into the _posts directory. And everything just worked. Voila, I had a pretty functional blog. I then updated a couple fields in _config.xml to unlock some sweet blogging features.&lt;/p&gt;

&lt;p&gt;RSS feed. You get this for free with github pages. Setting a value in the &lt;a href="https://github.com/dannyhan12/dannyhan12.github.io/blob/986e9de0efb7a774ee75f42bbc92f0af716d3bf8/_config.yml#L28"&gt;_config.yml&lt;/a&gt; will add a link to your RSS feed on the page. I still use RSS feeds, so this was convenient. Even better, I plan to register the rss feed to my &lt;a href="https://dev.to/"&gt;dev.to&lt;/a&gt; account. I hope cross posting to dev.to should give me some readers.&lt;/p&gt;

&lt;p&gt;For comments, I set up a new &lt;a href="https://disqus.com/"&gt;disqus site&lt;/a&gt;. Once you set that up, you need add it to &lt;a href="https://github.com/dannyhan12/dannyhan12.github.io/blob/986e9de0efb7a774ee75f42bbc92f0af716d3bf8/_config.yml#L37"&gt;the config&lt;/a&gt;. Then, you need to add &lt;code&gt;comments: true&lt;/code&gt; to the front matter of each post.&lt;/p&gt;

&lt;p&gt;To know how my blog is doing, I set up Google Analytics. I set up a new tracking ID and added it to the config. There’s obviously nothing much to see so far, but who knows, over time, maybe there will be something to smile about.&lt;/p&gt;

&lt;h2&gt;
  
  
  Parting thoughts
&lt;/h2&gt;

&lt;p&gt;This post is mostly meant as a reminder to myself of when I switched blogging platforms, and what I was thinking and feeling today. New tools are fun. If this entices me to write a bit more, than it is worth the time.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
