<?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: 1Link.Fun</title>
    <description>The latest articles on Forem by 1Link.Fun (@1link).</description>
    <link>https://forem.com/1link</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%2F351674%2Fbbab86af-62a1-4205-a488-ff98a4cba1d6.png</url>
      <title>Forem: 1Link.Fun</title>
      <link>https://forem.com/1link</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/1link"/>
    <language>en</language>
    <item>
      <title>Github Copilot prefer to give man more salary than woman</title>
      <dc:creator>1Link.Fun</dc:creator>
      <pubDate>Wed, 27 Nov 2024 06:02:08 +0000</pubDate>
      <link>https://forem.com/1link/github-copilot-prefer-to-give-man-more-salary-than-woman-43bp</link>
      <guid>https://forem.com/1link/github-copilot-prefer-to-give-man-more-salary-than-woman-43bp</guid>
      <description>&lt;p&gt;I ask Github Copilot to create a function to calculate woman's salary based on a integer as base salary, here is how it response:&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%2F8hqevm8svwv1qjwahaj2.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%2F8hqevm8svwv1qjwahaj2.png" alt="Image description" width="784" height="535"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;10% increment, good~&lt;/p&gt;

&lt;p&gt;I then ask it to create a function to calculate man's salary, and it responded below:&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%2Fzaw4e8ztop70a3njxbk3.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%2Fzaw4e8ztop70a3njxbk3.png" alt="Image description" width="783" height="519"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;15% of increment!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to get timestamp of all Kubernetes nodes without SSH to them</title>
      <dc:creator>1Link.Fun</dc:creator>
      <pubDate>Mon, 29 Jul 2024 09:44:25 +0000</pubDate>
      <link>https://forem.com/1link/how-to-get-timestamp-of-all-kubernetes-nodes-without-ssh-to-them-4m18</link>
      <guid>https://forem.com/1link/how-to-get-timestamp-of-all-kubernetes-nodes-without-ssh-to-them-4m18</guid>
      <description>&lt;p&gt;In some cases, you may need to get latest timestamp of &lt;code&gt;ALL&lt;/code&gt; kubernetes nodes, instead of SSH to every one of them and issue &lt;code&gt;date&lt;/code&gt; command, you can do this by &lt;code&gt;kubectl&lt;/code&gt; and below script.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="c"&gt;# Get the name of the first DaemonSet in the kube-system namespace&lt;/span&gt;
&lt;span class="nv"&gt;first_daemonset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;kubectl get daemonsets &lt;span class="nt"&gt;-n&lt;/span&gt; kube-system &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;jsonpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'{.items[0].metadata.name}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;echo &lt;/span&gt;Collecting timestamp across the cluster nodes by using DaemonSet &lt;span class="nv"&gt;$first_daemonset&lt;/span&gt;

&lt;span class="c"&gt;# Get the list of pod names and their corresponding node names controlled by the first DaemonSet&lt;/span&gt;
&lt;span class="nv"&gt;pods_info&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; kube-system &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;jsonpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'{range .items[?(@.metadata.ownerReferences[0].name=="'&lt;/span&gt;&lt;span class="nv"&gt;$first_daemonset&lt;/span&gt;&lt;span class="s1"&gt;'")]}{.metadata.name}{"\t"}{.spec.nodeName}{"\n"}{end}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# Loop through each pod and execute the date command&lt;/span&gt;
&lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nv"&gt;IFS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;$'&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt; &lt;span class="nb"&gt;read&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; pod node&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="c"&gt;# Get the name of the first container in the pod&lt;/span&gt;
    &lt;span class="nv"&gt;container_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;kubectl get pod &lt;span class="nt"&gt;-n&lt;/span&gt; kube-system &lt;span class="nv"&gt;$pod&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;jsonpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'{.spec.containers[0].name}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$container_name&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"No containers found in pod &lt;/span&gt;&lt;span class="nv"&gt;$pod&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
        &lt;span class="k"&gt;continue
    fi&lt;/span&gt;

    &lt;span class="c"&gt;# Execute the date command inside the selected container&lt;/span&gt;
    &lt;span class="nv"&gt;pod_date&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; kube-system &lt;span class="nv"&gt;$pod&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="nv"&gt;$container_name&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nb"&gt;date&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"node: &lt;/span&gt;&lt;span class="nv"&gt;$node&lt;/span&gt;&lt;span class="s2"&gt;, date: &lt;/span&gt;&lt;span class="nv"&gt;$pod_date&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$pods_info&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is how it works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;I get the first &lt;code&gt;daemonset&lt;/code&gt; name in &lt;code&gt;kube-system&lt;/code&gt; namespace, normally, it should be the CNI plugin, but it doesn't matter if it's not, as long as it's a daemonset, its pods should runs on every nodes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I then get the pod info list of the daemonset, for each of them I got &lt;code&gt;{pod name} {node name}&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Then I iterate the pod info list, for each of them, I firstly get the first container name of the pod (to execute &lt;code&gt;date&lt;/code&gt; command in), then I use &lt;code&gt;kubectl exec&lt;/code&gt; to run the &lt;code&gt;date&lt;/code&gt; command in it&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;So finally, I got everything, and print the result in &lt;code&gt;node: &amp;lt;node name&amp;gt;, date: &amp;lt;date command output&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The result be like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Collecting timestamp across the cluster nodes by using DaemonSet rke2-canal
node: test-worker-2, date: Mon Jul 29 08:44:30 UTC 2024
node: test-worker-3, date: Mon Jul 29 08:44:28 UTC 2024
node: test-worker-1, date: Mon Jul 29 08:44:32 UTC 2024
node: test-master, date: Mon Jul 29 08:44:31 UTC 2024
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Problem solved!&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>linux</category>
      <category>bash</category>
      <category>devops</category>
    </item>
    <item>
      <title>2 short key you will need &amp; love as a developer</title>
      <dc:creator>1Link.Fun</dc:creator>
      <pubDate>Tue, 06 Jun 2023 07:27:36 +0000</pubDate>
      <link>https://forem.com/1link/2-short-key-you-will-need-love-as-a-developer-3hmn</link>
      <guid>https://forem.com/1link/2-short-key-you-will-need-love-as-a-developer-3hmn</guid>
      <description>&lt;p&gt;Every developer should and must know this 2 short keys to boost your productivity or even make your code better.&lt;/p&gt;

&lt;p&gt;Note: Replace &lt;code&gt;Ctrl&lt;/code&gt; to &lt;code&gt;Command&lt;/code&gt; if you are using Mac OS.&lt;/p&gt;




&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Ctrl - C&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ctrl - V&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You are welcome &lt;/p&gt;

</description>
    </item>
    <item>
      <title>A gallery of homeless toys built with VueJS</title>
      <dc:creator>1Link.Fun</dc:creator>
      <pubDate>Sun, 16 Aug 2020 08:18:05 +0000</pubDate>
      <link>https://forem.com/1link/a-gallery-of-homeless-toys-built-with-vuejs-2npb</link>
      <guid>https://forem.com/1link/a-gallery-of-homeless-toys-built-with-vuejs-2npb</guid>
      <description>&lt;p&gt;Hello every one, long time no see!&lt;/p&gt;

&lt;p&gt;Today I want introduce my new created website: &lt;a href="https://homeless-toys.netlify.app" rel="noopener noreferrer"&gt;Homeless Toys&lt;/a&gt; to you.&lt;/p&gt;

&lt;p&gt;Yesterday, I was exploring the Sina Weibo and found a post showing 9 images of homeless toys, every one of them is adorable and cute and also pitiful.&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%2Fketd805abypgod7qed6b.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%2Fketd805abypgod7qed6b.png" width="800" height="666"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We all have some toys from childhood to nowadays, they brought us so many happy times, we should always not abandon them.&lt;/p&gt;

&lt;p&gt;So I create a website to collect all(hopefully, as much as possible) homeless toys to remind each of us how adorable they are and we should not abandon them like a trash :-(&lt;/p&gt;

&lt;p&gt;The gallery image style is based on &lt;a href="https://codepen.io/kathykato/pen/KRQOKY" rel="noopener noreferrer"&gt;this one at codepen&lt;/a&gt;, thanks about that.&lt;/p&gt;

&lt;p&gt;And I use &lt;a href="https://github.com/ElemeFE/vue-infinite-scroll" rel="noopener noreferrer"&gt;vue-infinite-scroll&lt;/a&gt; to do a pagination loading of images for better user experience.&lt;/p&gt;

&lt;p&gt;All the images are collected from internet, I'd like to invite you to submit such images you found or took to make this website great.&lt;/p&gt;

&lt;p&gt;You can visit &lt;a href="https://homeless-toys.netlify.app" rel="noopener noreferrer"&gt;Homeless Toys&lt;/a&gt; to see the website and &lt;a href="https://homeless-toys.netlify.app/#/thanks-for-submit" rel="noopener noreferrer"&gt;this page&lt;/a&gt; to submit a new image.&lt;/p&gt;

&lt;p&gt;Hope you love your toys than this website ❤️。&lt;/p&gt;

&lt;p&gt;See you in my next post.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>A PWA app to view all EXIF data of your .jpeg or even .heic files!</title>
      <dc:creator>1Link.Fun</dc:creator>
      <pubDate>Sun, 19 Jul 2020 01:53:03 +0000</pubDate>
      <link>https://forem.com/1link/a-pwa-app-to-view-all-exif-data-of-your-jpeg-or-even-heic-files-155k</link>
      <guid>https://forem.com/1link/a-pwa-app-to-view-all-exif-data-of-your-jpeg-or-even-heic-files-155k</guid>
      <description>&lt;p&gt;Hi everyone!&lt;/p&gt;

&lt;p&gt;In this post, I will introduce you my new created website, &lt;a href="https://exifviewer.netlify.app" rel="noopener noreferrer"&gt;EXIF Viewer&lt;/a&gt;, it's a PWA app to let you view all EXIF data of your &lt;code&gt;.jpeg&lt;/code&gt; or even &lt;code&gt;.heic&lt;/code&gt; image files.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is EXIF
&lt;/h2&gt;

&lt;p&gt;EXIF i.e. Exchangeable image file format, is a standard that specifies the formats for images, sound, and ancillary tags used by digital cameras (including smartphones), scanners and other systems handling image and sound files recorded by digital cameras.&lt;/p&gt;

&lt;p&gt;It will include some informations when your camera take photos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make, like: Apple for iOS&lt;/li&gt;
&lt;li&gt;Model, like: iPhone 8&lt;/li&gt;
&lt;li&gt;GPS*, will include the latitude and longitude&lt;/li&gt;
&lt;li&gt;Date time, like: 2020:06:25&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why to build this website
&lt;/h2&gt;

&lt;p&gt;Privacy is becoming more and more important in our daily life, as we see in above, an image may(or may not) include many EXIF data that may expose your mobile model, your GPS location etc.&lt;/p&gt;

&lt;p&gt;One can know from an image that WHEN the time you use WHAT camera(mobile) at WHERE location took this image.&lt;/p&gt;

&lt;p&gt;It's not good for privacy.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use this website
&lt;/h2&gt;

&lt;p&gt;It's simple enough and I just put 2 screenshots in here and sure you will know.&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%2Fi%2F9dg7eh7rgmj0h7vu9esq.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%2Fi%2F9dg7eh7rgmj0h7vu9esq.png" alt="Before you select an image" width="800" height="522"&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%2Fi%2Fi2krmr8sonl4h0825rmr.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%2Fi%2Fi2krmr8sonl4h0825rmr.png" alt="After you select an image" width="800" height="522"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Easy, right?&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;In the next few releases, I will provide the EXIF data striping so you can download the image with no EXIF data, for privacy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Another words
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The website will not upload your image to anywhere, it's just in your computer and in your browser&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Not all the images include EXIF data and even an image does, it may not include all the EXIF data, that's another reason you will need this website.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It's on GitHub.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/jwenjian" rel="noopener noreferrer"&gt;
        jwenjian
      &lt;/a&gt; / &lt;a href="https://github.com/jwenjian/exif-viewer" rel="noopener noreferrer"&gt;
        exif-viewer
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A free online tool to read all the EXIF data of your .jpg, .jpeg, .heic image file.
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;If you found this useful, just give it a ✨ or &lt;a href="https://www.buymeacoffee.com/jwenjian" rel="noopener noreferrer"&gt;buy me a coffee&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;OK, see you in my next post.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>vue</category>
      <category>webdev</category>
      <category>showdev</category>
    </item>
    <item>
      <title>The story of visitor-badge</title>
      <dc:creator>1Link.Fun</dc:creator>
      <pubDate>Tue, 14 Jul 2020 04:40:46 +0000</pubDate>
      <link>https://forem.com/1link/the-story-of-visitor-badge-46mm</link>
      <guid>https://forem.com/1link/the-story-of-visitor-badge-46mm</guid>
      <description>&lt;p&gt;Hello every one!&lt;/p&gt;

&lt;p&gt;In this post, I will tell you the story of me to creating the &lt;code&gt;visitor-badge&lt;/code&gt;, it's a svg image that can count your visitors for your GitHub README.md, issues, PRs in just one line markdown code.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Since the GitHub profile README feature, it can also count the visitors for your GitHub profile page(✌️). See &lt;a href="https://github.com/jwenjian" rel="noopener noreferrer"&gt;my profile page&lt;/a&gt; for a demo&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Why
&lt;/h3&gt;

&lt;p&gt;All the story starting from I migrate all my blog posts from Hexo GitHub Pages to a GitHub issue based repository. After a painful migration, I found that there is no visitor tracking for the repository, though basically I myself am the only one visitor in most time :(, I still want a visitor counting service for my every GitHub Issue and the README.&lt;/p&gt;

&lt;h3&gt;
  
  
  How
&lt;/h3&gt;

&lt;p&gt;After a lot of searching, brainstorming, prototyping, I put my eye on the little &lt;code&gt;badge&lt;/code&gt; in many other repository. Those badges can show us:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How much stars of the repository&lt;/li&gt;
&lt;li&gt;How much opened issues&lt;/li&gt;
&lt;li&gt;How much PRs&lt;/li&gt;
&lt;li&gt;Latest version of npm package&lt;/li&gt;
&lt;li&gt;CI status&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and all the badges is just a svg image file with a dynamic content in it.&lt;/p&gt;

&lt;p&gt;After more searching, I found the &lt;code&gt;pybadge&lt;/code&gt; library which will generate a GitHub badge style dynamically with a very simple api.&lt;/p&gt;

&lt;p&gt;So I can setup a python server, receive a svg file request, generate a dynamic svg file, return it, so it will display on the README.md.&lt;/p&gt;

&lt;p&gt;What else? A database to store the previous count of each page so that in the next time the same request from the page received, I can increment 1 based on the previous count.&lt;/p&gt;

&lt;p&gt;Here it is: &lt;code&gt;https://countapi.xyz/&lt;/code&gt;, a free counting API allows you to create simple numeric counters. IaaS, Integer as a Service. 🎉&lt;/p&gt;

&lt;p&gt;CountAPI is a perfect chosen for this use case, and it's easy to use, I don't need to prepare a database(SQLite, MySQL, etc.), I just send a http request to the API, and can get the incremented number.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Also can avoid concurrent updating issue if too many visitors to your page in the same time, it will count them correctly, because the CountAPI is based on Redis.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, for now, we have all we needed, just coding:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/jwenjian" rel="noopener noreferrer"&gt;
        jwenjian
      &lt;/a&gt; / &lt;a href="https://github.com/jwenjian/visitor-badge" rel="noopener noreferrer"&gt;
        visitor-badge
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      [Service is DOWN now] A badge generator service to count visitors of your markdown file.
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;h4&gt;
  
  
  Some tricks
&lt;/h4&gt;

&lt;h5&gt;
  
  
  Why you have to pass a &lt;code&gt;page_id&lt;/code&gt; as a query parameter?
&lt;/h5&gt;

&lt;p&gt;For the first version, I plan to use the &lt;code&gt;Referrer&lt;/code&gt; header in http request which is more convenient but GitHub proxy all the image request via its camo image server:&lt;/p&gt;

&lt;p&gt;Your browser -&amp;gt; Github Camo -&amp;gt; My server&lt;/p&gt;

&lt;p&gt;But Camo does not pass the &lt;code&gt;Referrer&lt;/code&gt; header to my server for some reason, so I change to the query parameter solution.&lt;/p&gt;

&lt;h4&gt;
  
  
  How to deal with the image cache?
&lt;/h4&gt;

&lt;p&gt;As you know, browser often caches images and in our case GitHub Camo also caches images.&lt;/p&gt;

&lt;p&gt;Cache is good for us in most time, but for a badge to count visitor, it is a disaster because if the previous badge image are cached, there is no new request to my server and the count will not have chance the increment until the cache is invalid, that's not what we want.&lt;/p&gt;

&lt;p&gt;We want every time every one visitor our README.md the count will increment 1, so I did a trick thing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Disable cache by adding a response header: &lt;code&gt;'Cache-Control': 'no-cache,max-age=0'&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set a passed expire time to 10 minutes AGO of current time: &lt;code&gt;'Expires': &amp;lt;10 minutes ago&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's it, after this little tricks every time you visitor the README.md, the browser(and camo) will know that the cached image is invalidated then send a request to my server to get the latest count.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;So many words, hope my not very good English make things clear. :)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Also I launched Visistor Badge on ProductHunt too, so If you found this useful, you can consider give it a vote.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.producthunt.com/posts/visitor-count-badge-for-your-github-repo?utm_source=badge-featured&amp;amp;utm_medium=badge&amp;amp;utm_souce=badge-visitor-count-badge-for-your-github-repo" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fapi.producthunt.com%2Fwidgets%2Fembed-image%2Fv1%2Ffeatured.svg%3Fpost_id%3D195146%26theme%3Dlight" alt="Visitor count badge for your Github Repo - A github badge to count visitor to your repository | Product Hunt Embed" width="250" height="54"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Also you can use &lt;a href="https://github.com/dwyl/hits" rel="noopener noreferrer"&gt;Hits&lt;/a&gt;, which is a similar visitor badge with a more stable service I think, because my service is now deployed under a free version of glitch.com, so your choice.&lt;/p&gt;




&lt;p&gt;I will see you in my next post.&lt;/p&gt;

</description>
      <category>github</category>
      <category>python</category>
      <category>glitch</category>
    </item>
    <item>
      <title>Lucky You - a cross-platform app built on tauri</title>
      <dc:creator>1Link.Fun</dc:creator>
      <pubDate>Sun, 28 Jun 2020 14:13:46 +0000</pubDate>
      <link>https://forem.com/1link/lucky-you-a-cross-platform-app-built-on-tauri-49jf</link>
      <guid>https://forem.com/1link/lucky-you-a-cross-platform-app-built-on-tauri-49jf</guid>
      <description>&lt;p&gt;Hello there, good to see you!&lt;/p&gt;

&lt;p&gt;In this post. I will introduce my latest open source project &lt;a href="https://github.com/jwenjian/lucky-you" rel="noopener noreferrer"&gt;lucky-you&lt;/a&gt; to you.&lt;/p&gt;

&lt;p&gt;It'a a cross platform app build on tauri framework and helps you doing a lucky draw or making a rolling all or similar use cases.&lt;/p&gt;

&lt;p&gt;Screenshots in below:&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%2Fi%2Fnwbd2fkne1mgoqs6lgl5.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%2Fi%2Fnwbd2fkne1mgoqs6lgl5.png" alt="Screenshot of LuckyYou" width="800" height="643"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It's tiny&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's tiny thanks to tauri, the latest version install file of Mac OS file is only 4.1Mb, 3.4Mb for Linux, 5.4Mb for Windows&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It's simple&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's simple, you just select a folder contains image files and click start then click stop, biu~  a chosen one!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It's safe&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's safe because the code is open source, and because no network access needed. Also, the native part of tauri is written in Rust, it's safe.&lt;/p&gt;

&lt;p&gt;Github repo is here: &lt;a href="https://github.com/jwenjian/lucky-you" rel="noopener noreferrer"&gt;lucky-you&lt;/a&gt; , hopes you like it!&lt;/p&gt;




&lt;p&gt;For windows user that failed to use the app, I build a PWA app in &lt;a href="https://luckyyou.netlify.app" rel="noopener noreferrer"&gt;here&lt;/a&gt;(&lt;a href="https://github.com/jwenjian/lucky-you/wiki/PWA-App" rel="noopener noreferrer"&gt;How to use?&lt;/a&gt;), you can use it instead.&lt;/p&gt;







&lt;p&gt;&lt;a href="https://www.producthunt.com/posts/lucky-you?utm_source=badge-featured&amp;amp;utm_medium=badge&amp;amp;utm_souce=badge-lucky-you" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fapi.producthunt.com%2Fwidgets%2Fembed-image%2Fv1%2Ffeatured.svg%3Fpost_id%3D219757%26theme%3Dlight" alt="Lucky You - A free, simple, beautiful PWA app to do a lucky draw. | Product Hunt Embed" width="250" height="54"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;See you in next post! 😁&lt;/p&gt;

</description>
      <category>tauri</category>
      <category>vue</category>
      <category>crossplatform</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
