<?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: Emily</title>
    <description>The latest articles on DEV Community by Emily (@hphan9).</description>
    <link>https://dev.to/hphan9</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%2F702250%2F46c60ded-4574-4d16-8c3b-1636b0bd769f.jpeg</url>
      <title>DEV Community: Emily</title>
      <link>https://dev.to/hphan9</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hphan9"/>
    <language>en</language>
    <item>
      <title>Flask-Assets</title>
      <dc:creator>Emily</dc:creator>
      <pubDate>Tue, 21 Dec 2021 21:54:21 +0000</pubDate>
      <link>https://dev.to/hphan9/flask-assets-2mpp</link>
      <guid>https://dev.to/hphan9/flask-assets-2mpp</guid>
      <description>&lt;p&gt;This week, I had a task to implement the SCSS with the Python Flask application. The project uses Jinja as a template engine and Flask for web Framework. This is the first time I have used SCSS, so I would love to take some introductory notes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why SCSS
&lt;/h2&gt;

&lt;p&gt;We all know that CSS is Cascading style language using to style webpage. SCSS stands for &lt;code&gt;Sassy CSS&lt;/code&gt;, which is CSS pre-processor that give developer ability to use variables, nested syntax, imports, etc. In the pre-processing stage, SCSS files will be converted to CSS to be ready for the browser. &lt;br&gt;
The biggest advantages of SCSS over CSS is removing code redundant and utilizing code reuse. For example:&lt;br&gt;
CSS Code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.container&lt;/span&gt; &lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.container&lt;/span&gt; &lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;SCSS Code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="nv"&gt;$color-container&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$color-text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nc"&gt;.container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;     &lt;span class="c1"&gt;// Notice here we don't need to repeat .container class&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$color-text&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$color-text&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Install Flask-assets and pyscss
&lt;/h2&gt;

&lt;p&gt;To compile SCSS to CSS, I need &lt;a href="https://flask-assets.readthedocs.io/en/latest/" rel="noopener noreferrer"&gt;Flask-Assets&lt;/a&gt; to manage the assets/static files of my Flask application and Pyscss as CSS compiler to convert SCSS markup to real CSS.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;Flask-Assets
pip &lt;span class="nb"&gt;install &lt;/span&gt;pyscss
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My application structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Folder    
├───App
│   ├───Config
│   │   └───__pycache__
│   ├───Constants
│   │   └───__pycache__
│   ├───flask_session
│   ├───Models
│   │   └───__pycache__
│   ├───static 
│   │   ├───Gen
│   │   ├───SCSS
│   ├───templates
│   │   ├───example.html
|   ├───__init__.py
├───Setup
│   ├───PIP
│   └───QRIOUS
├───application.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;According to the documentation, Environment object is used to hold a collection of bundles and configuration.&lt;br&gt;
A bundle object contains source files, filters _ pyscss in my case, and the output file. It is important to note that all paths in the bundle are relative to my flask application's &lt;code&gt;static&lt;/code&gt; folder. For example: &lt;code&gt;output='Gen/example.css'&lt;/code&gt; , the output CSS file will be in static\Gen folder. &lt;br&gt;
My code:&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;flask&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Flask&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;flask_assets&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Bundle&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;assets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# create an Environment instance
&lt;/span&gt;&lt;span class="n"&gt;bundles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  &lt;span class="c1"&gt;# define nested Bundle
&lt;/span&gt;  &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;example_style&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Bundle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;SCSS/example.scss&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;filters&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;pyscss&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Gen/example.css&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; 
&lt;span class="n"&gt;assets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bundles&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# register name for every bundle in bundles object
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And lately, I can insert my bundle by using its name in the block &lt;code&gt;assets&lt;/code&gt; of jinja template. Flask-Assets will help merge and compress my bundle source files the first time when the template is rendered. Moreover, it also watches the change of the source files and will update the compressed file when necessary.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    {% assets "example_style" %}
    &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/css"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"{{ ASSET_URL }}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    {% endassets %}
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I found that Flask-assets is easy to use, and it becomes convenient for pre-processing files such as SCSS files or JS files.  &lt;/p&gt;

</description>
    </item>
    <item>
      <title>Thinking about Open source</title>
      <dc:creator>Emily</dc:creator>
      <pubDate>Wed, 15 Dec 2021 02:56:11 +0000</pubDate>
      <link>https://dev.to/hphan9/thinking-about-open-source-36om</link>
      <guid>https://dev.to/hphan9/thinking-about-open-source-36om</guid>
      <description>&lt;h2&gt;
  
  
  Open-source
&lt;/h2&gt;

&lt;p&gt;Before OSD600, I saw open-source as an interesting, yet difficult field to get in. I thought that people should have been familiar with open-source projects to be able to join as contributors. However, after working on Telescope and Medusa, I learned that even beginner can start with &lt;code&gt;good first issue&lt;/code&gt; even if they don't have any knowledge on it. The amazing thing about open-sources community is that they can give you opportunity to work on their projects without questioning about your ability. In my eyes, open source is a source code that open for anyone to use, to share and to write. From contributor's point of view, Open source world is like a huge boot-camp where you can learn any topic you like and get practice, get feedback on your code and help resolve real-life challenges. &lt;/p&gt;

&lt;h2&gt;
  
  
  Advices
&lt;/h2&gt;

&lt;p&gt;The advices I would love to give my-self and other new students from day 1 is that you should follow the documentation and ask the right questions. It will save you lots of time when you understand thoroughly the documentation and you know how to ask question. &lt;/p&gt;

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

&lt;p&gt;I learn a lot from the OSD600 course and I am grateful for this opportunity. My point of view about blogging has also changed. Before, this is the scariest part of the course. I was terrified of writing something wrong or scared that maybe I am not good enough. However, as Prof David said from beginning:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A blog gives you a voice, which you can use when and how you want.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, I see blog as as a journal of my learning and working journey. It is a safe place that I can express my thoughts.&lt;/p&gt;

&lt;p&gt;Cover image from MIT News&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>opensource</category>
    </item>
    <item>
      <title>The final result</title>
      <dc:creator>Emily</dc:creator>
      <pubDate>Sun, 12 Dec 2021 20:49:01 +0000</pubDate>
      <link>https://dev.to/hphan9/the-final-result-4ffj</link>
      <guid>https://dev.to/hphan9/the-final-result-4ffj</guid>
      <description>&lt;p&gt;In the last week of OSD600, all my PRs for Telescope were merged.&lt;br&gt;
The summary of them is as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1st: Adding feeds/delayed route to Posts service: &lt;a href="https://github.com/Seneca-CDOT/telescope/pull/2575" rel="noopener noreferrer"&gt;PR&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;2nd: Upgrade Elasticsearch version in docker-compose.yml file: &lt;a href="https://github.com/Seneca-CDOT/telescope/pull/2598" rel="noopener noreferrer"&gt;PR&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In my last two blog posts, I discussed the issues related to the first PR and how I resolved them. For this blog, I would love to write about my experience working on the Telescope project in general and what I learned from my second PR.   &lt;/p&gt;
&lt;h2&gt;
  
  
  Elasticsearch version
&lt;/h2&gt;

&lt;p&gt;Regarding this &lt;a href="https://github.com/Seneca-CDOT/telescope/issues/1897" rel="noopener noreferrer"&gt;issue&lt;/a&gt;, I just need to change the version number of Elasticsearch in the docker-compose.yml file and it is just a 5-min fix:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;// old code&lt;/span&gt;
&lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker.elastic.co/elasticsearch/elasticsearch:7.9.3&lt;/span&gt;
&lt;span class="s"&gt;// my fix&lt;/span&gt;
&lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker.elastic.co/elasticsearch/elasticsearch:7.14.2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, after I sent my PR, Prof. David filed an &lt;a href="https://github.com/Seneca-CDOT/telescope/issues/2597" rel="noopener noreferrer"&gt;issue&lt;/a&gt; about a high severity vulnerability (CVE-2021-44228) which has impacted the Elasticsearch versions 5.0.0+. So the solution is to upgrade to Elasticsearch 7.16.1 once it is released. This experience made me think that we should be aware and keep updated on the third-party engines/tools used in our project. &lt;/p&gt;

&lt;h2&gt;
  
  
  Experience
&lt;/h2&gt;

&lt;p&gt;To put it simply, this is the best open source project I have contributed to. Telescope's Slack channel is always active, and when there is a question, the maintainers and contributors reply instantly. What I love most about it is code review, as I learnt a ton of good practices from Prof. David's comments. &lt;br&gt;
For example:&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%2Fcde843gt9smou8ew3ox7.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%2Fcde843gt9smou8ew3ox7.png" alt="comment" width="800" height="446"&gt;&lt;/a&gt;&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%2F3pvtzp4ww66qcnz4d982.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%2F3pvtzp4ww66qcnz4d982.png" alt="comment" width="800" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I think Telescope's maintainers did a fantastic job in fostering engagement. They are always there to help contributors. They provide excellent and constructive feedbacks, and they value every contribution, even small ones. &lt;/p&gt;

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

&lt;p&gt;This semester, I did not have a chance to work on Front-end issues. However, I am looking forward to taking some React issues in the OSD700 course.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>telescope</category>
    </item>
    <item>
      <title>Progress Report</title>
      <dc:creator>Emily</dc:creator>
      <pubDate>Sat, 11 Dec 2021 05:52:02 +0000</pubDate>
      <link>https://dev.to/hphan9/progress-43na</link>
      <guid>https://dev.to/hphan9/progress-43na</guid>
      <description>&lt;h2&gt;
  
  
  Progress
&lt;/h2&gt;

&lt;p&gt;Until now, my first &lt;a href="https://github.com/Seneca-CDOT/telescope/pull/2520" rel="noopener noreferrer"&gt;PR&lt;/a&gt; for adding route &lt;code&gt;\feeds\invalid&lt;/code&gt; to Posts service merged, and I also sent another &lt;a href="https://github.com/Seneca-CDOT/telescope/pull/2575" rel="noopener noreferrer"&gt;PR&lt;/a&gt; for the issue &lt;a href="https://github.com/Seneca-CDOT/telescope/issues/2413" rel="noopener noreferrer"&gt;#2413&lt;/a&gt;. So everything is going well, and I have not had any significant challenges working on these issues.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding
&lt;/h2&gt;

&lt;p&gt;The hardest part for implementing the route &lt;code&gt;\feeds\delayed&lt;/code&gt; to Posts service is testing my code. When microservices finished downloading feeds and processing them, I checked the Redis server to find the delayed one. And I found nothing. After asking a question on Telescope's Slack channel, I got an answer from prof. David that this case is not usual. The reason is a feed is marked delayed only when the processor receives an &lt;code&gt;HTTP 429&lt;/code&gt; response ("the user has sent too many requests in a given amount of time ("rate limiting")"). This issue made it hard to test my new functions against the real-time database.&lt;br&gt;
The workaround suggested by prof. David is implementing an integration test to create delayed feeds on the fly. Surprisingly, those feeds did not have the time to live when I used &lt;code&gt;ttl&lt;/code&gt; command. I found that the &lt;code&gt;setDelayedFeeds()&lt;/code&gt; function did not set the expire time for the key.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// old code&lt;/span&gt;
&lt;span class="nx"&gt;setDelayedFeed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;seconds&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;createDelayedFeedKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;seconds&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="c1"&gt;// new code&lt;/span&gt;
&lt;span class="nx"&gt;setDelayedFeed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;seconds&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;createDelayedFeedKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;seconds&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;EX&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;seconds&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Take-away
&lt;/h2&gt;

&lt;p&gt;The biggest take-away for me this time is learning about Redis commands and &lt;a href="https://nodejs.org/api/stream.html" rel="noopener noreferrer"&gt;Readable stream&lt;/a&gt; in NodeJs. &lt;br&gt;
Streams is one of the core concepts in NodeJs, and it is often used when we need to work with a large amount of data.&lt;br&gt;
When calling the &lt;code&gt;scanStream()&lt;/code&gt; method on a Redis client, I actually created an object of readable stream.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Scanstream : Convenient class to convert the process of scaning keys to a readable stream&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;My code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getFeedKeysUsingScanStream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;matchPattern&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;keys&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; 
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;scanStream&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;matchPattern&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt; &lt;span class="c1"&gt;//create a readable stream object &lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nx"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error while scanning redis keys&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nf"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error while scanning redis keys&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nx"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;end&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;([...&lt;/span&gt;&lt;span class="nx"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A stream object has many events: 'closed', 'data', 'end', 'error', etc. Because the stream processes data piece by piece, we need to wrap it inside a Promise and only &lt;em&gt;resolve&lt;/em&gt; when there is no more data to consume _ &lt;strong&gt;the end event&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In the end, I was able to make the route work, and I am happy with the progress.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>stream</category>
    </item>
    <item>
      <title>Second PR for Telescope project</title>
      <dc:creator>Emily</dc:creator>
      <pubDate>Thu, 09 Dec 2021 04:02:54 +0000</pubDate>
      <link>https://dev.to/hphan9/second-pr-for-telescope-project-2639</link>
      <guid>https://dev.to/hphan9/second-pr-for-telescope-project-2639</guid>
      <description>&lt;h1&gt;
  
  
  Issue
&lt;/h1&gt;

&lt;p&gt;In the last Release 04 of the OSD600 course, I decided to work on implementing the &lt;code&gt;/feeds/delayed&lt;/code&gt; route for the Telescope project and finishing the &lt;code&gt;/feeds/invalid&lt;/code&gt; route. In general, there are feeds that have been flagged as delayed in the Redis server and the project owners want to see them from new endpoint in the Posts service. So, the new endpoint will return a JSON array of objects containing feeds Id, URL and the time to live of the feed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Planning
&lt;/h2&gt;

&lt;p&gt;The first part is finding the keys with the delayed suffix on the Redis server. This issue is similar to issue 2412 that I have sent a PR. I realized that I could utilize the getFeedKeysUsingScanStream in the old PR to find the delayed keys.&lt;/p&gt;

&lt;p&gt;The second part is retrieving the information of the founded keys. The issue also requires finding the time to leave the delayed feeds. Luckily, prof. David has given detailed instructions about the time to live of delayed feeds on the issue. I will research &lt;code&gt;ttl&lt;/code&gt; command and finish this task soon.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>redis</category>
      <category>javascript</category>
      <category>node</category>
    </item>
    <item>
      <title>Auditting Compiler.md for IPC 144 Project</title>
      <dc:creator>Emily</dc:creator>
      <pubDate>Wed, 01 Dec 2021 05:09:40 +0000</pubDate>
      <link>https://dev.to/hphan9/auditting-compilermd-for-ipc-144-project-42pa</link>
      <guid>https://dev.to/hphan9/auditting-compilermd-for-ipc-144-project-42pa</guid>
      <description>&lt;p&gt;In Release 03 of the Open source course, I had a chance to work on &lt;a href="https://github.com/Seneca-ICTOER/IPC144" rel="noopener noreferrer"&gt;IPC 144&lt;/a&gt; project that helps improve and maintain the IPC144 course's notes. I was working on auditing and editing the Compiler.md page.&lt;/p&gt;

&lt;h2&gt;
  
  
  Issues
&lt;/h2&gt;

&lt;p&gt;Prof. David has listed &lt;a href="https://github.com/Seneca-ICTOER/IPC144/issues/18" rel="noopener noreferrer"&gt;issues&lt;/a&gt; that should be checked and edited to ensure the markdown page looks well. I simply followed the guide, and I improved the page by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fixing typos and Markdown syntax&lt;/li&gt;
&lt;li&gt;Fixing Frontmatter metadata&lt;/li&gt;
&lt;li&gt;Adding inter-site links to other pages that have related info&lt;/li&gt;
&lt;li&gt;Adding alt text on images&lt;/li&gt;
&lt;li&gt;Improving page's Accessibility&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There were some requirements I have not fixed on this page, such as centring images horizontally or making sure images work in dark and light modes. I feel like these requirements/issues should be set up globally instead of locally so the project will have a consistent style throughout all pages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Result
&lt;/h2&gt;

&lt;p&gt;I also got some reviews from my classmate to improve my &lt;a href="https://github.com/Seneca-ICTOER/IPC144/pull/73" rel="noopener noreferrer"&gt;PR&lt;/a&gt;. Thank you, guys, for taking the time to review it. It could not complete without your recommendations. &lt;br&gt;
Finally, my Pr is merged, and this task helps me learn more about Docusaurus, LightHouse tool, and Web accessibility.&lt;/p&gt;

</description>
      <category>seneca</category>
      <category>ipc144</category>
    </item>
    <item>
      <title>Publishing shinny-ssg Nuget Package</title>
      <dc:creator>Emily</dc:creator>
      <pubDate>Mon, 29 Nov 2021 18:45:58 +0000</pubDate>
      <link>https://dev.to/hphan9/publishing-shinny-ssg-nuget-package-13o</link>
      <guid>https://dev.to/hphan9/publishing-shinny-ssg-nuget-package-13o</guid>
      <description>&lt;p&gt;In the last lab of OSD600, I have a chance to publish and release my static site generation application. I chose Nuget.org as my package registry. I have always loved Microsoft documentation as it is clear and easy to follow. This time, I simply followed their &lt;a href="https://docs.microsoft.com/en-us/nuget/nuget-org/publish-a-package" rel="noopener noreferrer"&gt;instructions&lt;/a&gt; and got my package available &lt;a href="https://www.nuget.org/packages/shinny_ssg/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pack
&lt;/h2&gt;

&lt;p&gt;To start, I needed to set the application's PropertyGroup in the project files&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;    &lt;span class="nt"&gt;&amp;lt;PropertyGroup&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;OutputType&amp;gt;&lt;/span&gt;Exe&lt;span class="nt"&gt;&amp;lt;/OutputType&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;TargetFramework&amp;gt;&lt;/span&gt;netcoreapp3.1&lt;span class="nt"&gt;&amp;lt;/TargetFramework&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;RootNamespace&amp;gt;&lt;/span&gt;shinny_ssg&lt;span class="nt"&gt;&amp;lt;/RootNamespace&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;PackAsTool&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/PackAsTool&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;PackageId&amp;gt;&lt;/span&gt;shinny_ssg&lt;span class="nt"&gt;&amp;lt;/PackageId&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;Version&amp;gt;&lt;/span&gt;1.0.1&lt;span class="nt"&gt;&amp;lt;/Version&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;Authors&amp;gt;&lt;/span&gt;Emily Phan&lt;span class="nt"&gt;&amp;lt;/Authors&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;PackageOutputPath&amp;gt;&lt;/span&gt;./bin&lt;span class="nt"&gt;&amp;lt;/PackageOutputPath&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;IsPackable&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/IsPackable&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;RunPostBuildEvent&amp;gt;&lt;/span&gt;Always&lt;span class="nt"&gt;&amp;lt;/RunPostBuildEvent&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/PropertyGroup&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you can use the command  line to pack the package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet pack
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command generated a .nugkp in the &lt;code&gt;/bin&lt;/code&gt; folder. &lt;/p&gt;

&lt;h2&gt;
  
  
  Publish
&lt;/h2&gt;

&lt;p&gt;The next part is publishing the package to nuget.org. &lt;br&gt;
To prepare for that, I created a Nuget account and retrieved the API key. This key is used to identify your account to the Nuget Gallery.&lt;br&gt;
After that, I ran this command to publish Shinny-ssg&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet nuget push shinny_ssg.1.0.1.nupkg &lt;span class="nt"&gt;--api-key&lt;/span&gt; &amp;lt;token&amp;gt; &lt;span class="nt"&gt;--source&lt;/span&gt; https://api.nuget.org/v3/index.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that was it, my tool was ready to use. &lt;/p&gt;

&lt;h2&gt;
  
  
  Testing
&lt;/h2&gt;

&lt;p&gt;I asked one of my friends to test the tools. We have found a bug in my application. When she ran &lt;code&gt;shinny-ssg -v&lt;/code&gt; , she got &lt;code&gt;Multiple options with name "v" found. This is usually due to nested options.&lt;/code&gt; I realized that I did implemented the -v|--version twice and I did not specify it right in my Options class. I will fix this issue and update the version.&lt;/p&gt;

&lt;p&gt;Publishing the package is a happy ending for the project I have worked on the last 2 months. After this, I understand more about a project's lifecycle: developing, testing and publishing. &lt;/p&gt;

</description>
      <category>nuget</category>
      <category>csharp</category>
    </item>
    <item>
      <title>Working on Telescope Project</title>
      <dc:creator>Emily</dc:creator>
      <pubDate>Fri, 26 Nov 2021 22:03:56 +0000</pubDate>
      <link>https://dev.to/hphan9/working-on-telescope-project-40mb</link>
      <guid>https://dev.to/hphan9/working-on-telescope-project-40mb</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://telescope.cdot.systems/" rel="noopener noreferrer"&gt;Telescope&lt;/a&gt; is an open-source project written by Seneca students to aggregate and present a timeline of Seneca's student blogs. Telescope is a fantastic project, and it has a solid impact on to open source community in Seneca. I got a chance to contribute to this project by implementing the route &lt;a href="https://github.com/Seneca-CDOT/telescope/issues/2412" rel="noopener noreferrer"&gt;posts/feeds/invalid&lt;/a&gt; for the posts service. &lt;/p&gt;

&lt;h1&gt;
  
  
  Docker
&lt;/h1&gt;

&lt;p&gt;Contributors to the Telescope project can use Docker to develop and run the application locally. They have provided great &lt;a href="https://github.com/Seneca-CDOT/telescope/blob/master/docs/environment-setup.md#docker-and-docker-compose-setup" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; to set up Docker containers for different operating systems. I always have problems with setting up the environment to work on any projects, but with Docker, this task is a little bit easier this time. &lt;br&gt;
The first challenge I had is error response from Deamon when I first ran &lt;code&gt;npm run service:start&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error response from daemon: Ports are not available: listen tcp 0.0.0.0:80: bind: An attempt was made to access a socket in a way forbidden by its access permissions.
Error starting services with docker-compose: undefined
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I asked a question on the Slack channel, and Prof.David quickly pointed out that my port 80 is being used by an IIS application. I checked, and there was an old application that was running to port 80 all the time. I have closed this application and resolved the problem.&lt;/p&gt;

&lt;h1&gt;
  
  
  Redis
&lt;/h1&gt;

&lt;p&gt;Redis is an in-memory database, a data-structure server and a message broker that stores key-value data. That is a lot of words. But what is in-memory database? It means all data are stored in the main memory of the computer instead of the disk storage, making Redis operations exceptional faster than on-disk databases. &lt;br&gt;
Telescope uses Redis database and &lt;a href="https://www.npmjs.com/package/ioredis" rel="noopener noreferrer"&gt;ioredis&lt;/a&gt; to interact with Redis.&lt;/p&gt;

&lt;h1&gt;
  
  
  Pr
&lt;/h1&gt;

&lt;p&gt;I have added a new route to the Post service and added functions to query the invalid Feeds data to the project. I have sent a &lt;a href="https://github.com/Seneca-CDOT/telescope/pull/2520/files/12c09a6526f7abbb3d983363d0f6c4392e3c6940#diff-385ce74534c40abd35fec7213380832f3dc70f6fde77edc3f1fd2704b688ab51" rel="noopener noreferrer"&gt;draft PR&lt;/a&gt;, and I got some comments from Prof. David to improve it. &lt;/p&gt;

&lt;p&gt;Telescope uses many advanced technology/concepts such as microservices architecture, Redis database, Elasticsearch, Docker, etc. There is so much to learn from it, and I am glad that I can take part in the project.   &lt;/p&gt;

</description>
      <category>redis</category>
      <category>javascript</category>
      <category>opensource</category>
      <category>beginners</category>
    </item>
    <item>
      <title>GitHub Actions</title>
      <dc:creator>Emily</dc:creator>
      <pubDate>Fri, 26 Nov 2021 16:56:28 +0000</pubDate>
      <link>https://dev.to/hphan9/set-up-git-hub-action-546c</link>
      <guid>https://dev.to/hphan9/set-up-git-hub-action-546c</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;What is GitHub Action? According to Github, it is a series of commands that can be executed when a special event (defined by user) occurred. The series of commands is put in the context of &lt;code&gt;workflow&lt;/code&gt; and every steps can be seen as a &lt;code&gt;job&lt;/code&gt;. &lt;br&gt;
This week, I had a chance to explore GitHub Actions for my Shinny-SSG project and it is a great improvement for my application.&lt;/p&gt;
&lt;h1&gt;
  
  
  Define Workflows
&lt;/h1&gt;

&lt;p&gt;I created my first workflow by using Github's default workflow template for .Net project. Github created a YAML file in the &lt;code&gt;.github/workflows&lt;/code&gt; directory inside my git repository. You can read more about it &lt;a href="https://docs.github.com/en/actions/learn-github-actions/understanding-github-actions" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;br&gt;
My dotnet.yml file :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;name: .NET

on:
  push:
    branches: &lt;span class="o"&gt;[&lt;/span&gt; main &lt;span class="o"&gt;]&lt;/span&gt;
  pull_request:
    branches: &lt;span class="o"&gt;[&lt;/span&gt; main &lt;span class="o"&gt;]&lt;/span&gt;

&lt;span class="nb"&gt;jobs&lt;/span&gt;:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2
    - name: Setup .NET Core 3.1 
      uses: actions/setup-dotnet@v1 
      with: 
       dotnet-version: 3.1.x
    - name: Setup .NET Core 5.0
      uses: actions/setup-dotnet@v1
      with:
       dotnet-version: 5.0.x
    - name: dotnet-format
      run: dotnet tool &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; dotnet-format &lt;span class="nt"&gt;--version&lt;/span&gt; 5.1.225507
    - name: Restore dependencies
      run: dotnet restore shinny-ssg/shinny-ssg.sln
    - name: Build
      run: dotnet build shinny-ssg/shinny-ssg.sln &lt;span class="nt"&gt;--no-restore&lt;/span&gt; 
    - name: Test
      run: dotnet &lt;span class="nb"&gt;test &lt;/span&gt;shinny-ssgTests &lt;span class="nt"&gt;--no-build&lt;/span&gt; &lt;span class="nt"&gt;--verbosity&lt;/span&gt; normal
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Testing
&lt;/h1&gt;

&lt;p&gt;Later, I tested my Github Actions by making a pull request to my origin repository. It worked like a charm and it denied merging if my PR did not pass the test. &lt;br&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%2Fcbsvomsrcqq6esn7gie0.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%2Fcbsvomsrcqq6esn7gie0.png" alt="Image description" width="800" height="277"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I also made a &lt;a href="https://github.com/Qiwen-Yu/TextHTMLPress/pull/17" rel="noopener noreferrer"&gt;PR&lt;/a&gt; for my classmate's project. It also worked as expected.  &lt;/p&gt;

</description>
      <category>github</category>
      <category>opensource</category>
      <category>csharp</category>
    </item>
    <item>
      <title>Writing tests for CLI tool</title>
      <dc:creator>Emily</dc:creator>
      <pubDate>Sun, 14 Nov 2021 18:27:00 +0000</pubDate>
      <link>https://dev.to/hphan9/writing-tests-for-cli-tool-3p6b</link>
      <guid>https://dev.to/hphan9/writing-tests-for-cli-tool-3p6b</guid>
      <description>&lt;p&gt;This week, I was working on writing tests for my Shinny-SSG project. It was the most challenging lab in the OSD600 course since I had to modify both my code and my project's folder structure to implement the tests.&lt;/p&gt;

&lt;h2&gt;
  
  
  Set-up
&lt;/h2&gt;

&lt;p&gt;The testing framework that I chose is &lt;a href="https://xunit.net/" rel="noopener noreferrer"&gt;XUnit&lt;/a&gt;. The first reason is that it is trendy compared to another test framework such as NUnits. I created test method stubs from the existing code by &lt;a href="https://docs.microsoft.com/en-us/visualstudio/test/create-unit-tests-menu?view=vs-2022" rel="noopener noreferrer"&gt;Create Unit Tests&lt;/a&gt; command. To use it with Xunit, I have to implement the XUnit.net.TestGenerator extension to my project. &lt;br&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%2Fhx3nbipf2axkmrpzmeh4.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%2Fhx3nbipf2axkmrpzmeh4.png" alt="Image description" width="800" height="331"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Challenges
&lt;/h2&gt;

&lt;p&gt;I want to test how my tools generated files and folders in the destination with different arguments passed to the program. However, in my old code, I put all the logic of working with arguments in the &lt;code&gt;static int main( string[] args)&lt;/code&gt; function. I could not use Interface and Dependency injection to mock the CommandLineApplication because CommandLineUtils does not have an interface for this class. Luckily, I found this &lt;a href="https://github.com/natemcmaster/CommandLineUtils/issues/279" rel="noopener noreferrer"&gt;guidance&lt;/a&gt; from the owner of CommandLineUtils, and he advised that "Split the command-line argument parser and application execution into separate class structures" to test various options programmatically. It is a great suggestion, and I rewrote my program by adding class &lt;a href="https://github.com/hphan9/shinny-ssg/blob/main/shinny-ssg/src/CommandLineOptions.cs" rel="noopener noreferrer"&gt;CommandLineOptions&lt;/a&gt; and adding logic to the constructor of class Generator. I can kill two birds with one stone by this change: code refactoring and writing better tests.&lt;br&gt;&lt;br&gt;
Another problem I had was my folder structure. Before, I put the project's sln file, .git file , and src files in the root of the folder. However, when I added a new test project for Shinny-SSG, I had it outside my git folder, and it would be impossible to commit the change and put it in my remote repository. To resolve that, I had to change my folder structure to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;C:.
├───shinny-ssg
│   ├───bin
│   │   ├───Debug
│   │   │   └───netcoreapp3.1
│   │   │       ├───dist
│   │   │       └───publish
│   │   ├───Destination
│   │   └───Release
│   │       └───netcoreapp3.1
│   ├───obj
│   │   ├───Debug
│   │   │   └───netcoreapp3.1
│   │   └───Release
│   │       └───netcoreapp3.1
│   ├───Properties
│   └───src
└───shinny-ssgTests
    ├───bin
    │   └───Debug
    │       ├───.netcoreapp,version&lt;span class="o"&gt;=&lt;/span&gt;v3.1  
    │       └───netcoreapp3.1
    ├───obj
    │   └───Debug
    │       ├───.netcoreapp,version&lt;span class="o"&gt;=&lt;/span&gt;v3.1
    │       └───netcoreapp3.1
    └───src
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Testing
&lt;/h2&gt;

&lt;p&gt;I wrote 3 test for Generator class &lt;code&gt;run()&lt;/code&gt; function that cover 3 different cases: config file option, input path option and invalid input path option. My tests help uncovering a huge bug in my application. Before, I thought that &lt;code&gt;default&lt;/code&gt; keyword was used to specified the default value of a variable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt; &lt;span class="n"&gt;cssUrl&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cssOption&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;HasValue&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;cssOption&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, the &lt;code&gt;default&lt;/code&gt; literal is for producing the default value of a type that is null in this case ( CssUrl is the &lt;code&gt;string&lt;/code&gt; type).&lt;br&gt;
I also wrote a test that testes the core feature of my application: Given a text and checked if the generated HTML value matched the expected output.&lt;br&gt;
&lt;a href="https://github.com/hphan9/shinny-ssg/commit/23c766a759bc52f1889d78c578da2b29cbb0a248#diff-765ec9ae5392385dc6cb44e7fb9af38ebf78e87a463546cfd86d7d42590341e3" rel="noopener noreferrer"&gt;Pull request&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Throughout this experience, I learn a lot about software testing and why it is essential for software development. In the future, I will implement more tests for my project and explore other test frameworks. &lt;/p&gt;

</description>
      <category>cshap</category>
      <category>testing</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Hackoberfest recap</title>
      <dc:creator>Emily</dc:creator>
      <pubDate>Wed, 10 Nov 2021 03:33:20 +0000</pubDate>
      <link>https://dev.to/hphan9/hackoberfest-recap-56ci</link>
      <guid>https://dev.to/hphan9/hackoberfest-recap-56ci</guid>
      <description>&lt;p&gt;The Hacktobestfest ended last month and, through this journey, I have learned many new things. &lt;/p&gt;

&lt;h2&gt;
  
  
  Challenges
&lt;/h2&gt;

&lt;p&gt;The first challenge I had when working on Hacktoberfest's issues was setting up the project in the local machine. I was a little bit ambitious at the beginning and I chose only the big projects. Obviously, these projects had many packages, test projects, and databases setup processes. In the end, I gave up working on some issues due to the complexity of installation and local development. &lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons
&lt;/h2&gt;

&lt;p&gt;Even thought I have not successfully made four merge pull requests this time, this experience is still worth trying. I have discovered how to write integration tests and what .Net Bot is. Another thing I realize is the way to contribute to an open-source project and git commands. &lt;br&gt;
In addition, I appreciate the project's owners for spending time reviewing my pr. They were patient, they suggested changes and waited for me to fix my code. &lt;br&gt;
I contributed my part to the project, learned a lot in return, and that is the beauty of open source and good karma. &lt;/p&gt;

</description>
      <category>hacktoberfest</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Prettier your C# code with DotNet Format</title>
      <dc:creator>Emily</dc:creator>
      <pubDate>Sat, 06 Nov 2021 16:36:24 +0000</pubDate>
      <link>https://dev.to/hphan9/prettier-your-c-code-with-dotnet-format-75</link>
      <guid>https://dev.to/hphan9/prettier-your-c-code-with-dotnet-format-75</guid>
      <description>&lt;p&gt;This week, I learned about Static Analysis Tool, and I practice applying it to my &lt;a href=""&gt;Shinny-SSG&lt;/a&gt; application. The two tools I used are &lt;a href="https://github.com/dotnet/format" rel="noopener noreferrer"&gt;Dotnet Format&lt;/a&gt; and &lt;a href="https://github.com/DotNetAnalyzers/StyleCopAnalyzers" rel="noopener noreferrer"&gt;StyleCopAnalyzers&lt;/a&gt;. I chose them because they are widely used and they are both analyzing source code based on the &lt;em&gt;.editorconfig&lt;/em&gt; file. &lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  EditorConfig
&lt;/h3&gt;

&lt;p&gt;In the first step, I generated the &lt;em&gt;.editorconfig&lt;/em&gt; file for my project. This &lt;a href="https://docs.microsoft.com/en-us/visualstudio/ide/create-portable-custom-editor-options?view=vs-2019" rel="noopener noreferrer"&gt;Editorconfig&lt;/a&gt; file is where you define your coding style in Visual Studio, such as Indentation and Spacing or Wrapping Preference. &lt;/p&gt;

&lt;h3&gt;
  
  
  DotnetFormat
&lt;/h3&gt;

&lt;p&gt;The second step is installing DotnetFormat tools in my local machine by this command:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dotnet tool install -g dotnet-format&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;This tool will format my code based on the style preferences on the &lt;em&gt;.editorconfig&lt;/em&gt; file. &lt;/p&gt;

&lt;h3&gt;
  
  
  StyleCop.Analyzers
&lt;/h3&gt;

&lt;p&gt;The third step is installing StyleCop Analyzers. As specified in the documentation, I followed the preferable way is to add the NuGet package StyleCop.Analyzers. I also found this &lt;a href="https://dev.to/srmagura/c-linting-and-formatting-tools-in-2021-bna"&gt;blog&lt;/a&gt; is helping, and I followed step by step which the author recommended. In the Project File extension, I added this line to the project so it can trigger StyleCop at the build time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;PackageReference&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"StyleCop.Analyzers"&lt;/span&gt; &lt;span class="na"&gt;Version=&lt;/span&gt;&lt;span class="s"&gt;"1.1.118"&lt;/span&gt; &lt;span class="na"&gt;PrivateAssets=&lt;/span&gt;&lt;span class="s"&gt;"all"&lt;/span&gt; &lt;span class="na"&gt;Condition=&lt;/span&gt;&lt;span class="s"&gt;"$(MSBuildProjectExtension)=='.csproj'"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;PrivateAssets&amp;gt;&lt;/span&gt;all&lt;span class="nt"&gt;&amp;lt;/PrivateAssets&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;IncludeAssets&amp;gt;&lt;/span&gt;runtime; build; native; contentfiles; analyzers; buildtransitive&lt;span class="nt"&gt;&amp;lt;/IncludeAssets&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/PackageReference&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last step is to edit my &lt;em&gt;.editorconfig&lt;/em&gt; file to disable the rule that I don't want to my project, such as: Using directive should appear within a namespace declaration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet_diagnostic.SA1200.severity = None
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, at the build time of my project, it still showed a warning for this rule, so maybe I should research more about it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build Event
&lt;/h2&gt;

&lt;p&gt;I was struggling to find a way to fix the warning from StyleCop for my project automatically. I had 360 warnings, and it will be time-consuming to fix them manually. Luckily, I read the &lt;a href="https://dev.to/mkim219/formatter-linter-for-c-cb0"&gt;blog&lt;/a&gt; of my classmate, Minsu Kim, he mentioned that dotnet format can be used with third-party analyzers. It is a great find, and I can use this command to fix all the warnings from style-cop:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dotnet-format -a warn ./shinny-ssg.sln&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;By using this command, I did not need to modify my Project file extension to trigger StyleCop.Analyzers at the build time and I can leave all the works to dotnet-format.&lt;/p&gt;

&lt;p&gt;Microsoft Visual Studio has &lt;a href="https://docs.microsoft.com/en-us/visualstudio/ide/how-to-specify-build-events-csharp?view=vs-2019" rel="noopener noreferrer"&gt;build events configuration&lt;/a&gt; for projects, and I used it to trigger auto-format code action at the time of building project. I have set up my project as follows:&lt;br&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%2Fr94htcmp2d85roq1rgur.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%2Fr94htcmp2d85roq1rgur.png" alt="Image description" width="800" height="604"&gt;&lt;/a&gt;&lt;br&gt;
After I ran the &lt;em&gt;dotnet build&lt;/em&gt; in my project, two dotnet-format commands have fixed six formatting errors, and 360 warnings.&lt;/p&gt;

&lt;h2&gt;
  
  
  Editor/IDE Integration
&lt;/h2&gt;

&lt;p&gt;Visual Studio provides a great way to replicate the development environment through a &lt;em&gt;vsssetings&lt;/em&gt; file. New contributors to my project can have the same development environment as me by importing the ShinnySSG-2021-11-06.vssettings, which is available in the Project repository. &lt;/p&gt;

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

&lt;p&gt;Formatting code is the first way to improve code quality, and it makes easier for reviewers to spot bugs and give suggestions. I am happy that I have found great tools to make this task much more easier. &lt;/p&gt;

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