<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[the dtn blog]]></title><description><![CDATA[my thoughts, stories and ideas.]]></description><link>https://blog.ducthinh.net/</link><image><url>https://blog.ducthinh.net/favicon.png</url><title>the dtn blog</title><link>https://blog.ducthinh.net/</link></image><generator>Ghost 3.33</generator><lastBuildDate>Tue, 21 Apr 2026 13:32:15 GMT</lastBuildDate><atom:link href="https://blog.ducthinh.net/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Using GitHub as OpenID IdP with AWS Cognito]]></title><description><![CDATA[Connect GitHub OAuth to your AWS Cognito SSO application as an OpenID Identity Provider (IdP) to login with your GitHub account.]]></description><link>https://blog.ducthinh.net/github-openid-idp-aws-cognito/</link><guid isPermaLink="false">5f170258c054372ea76bfe9b</guid><category><![CDATA[Solved]]></category><category><![CDATA[Python]]></category><category><![CDATA[Issues]]></category><dc:creator><![CDATA[Thinh Nguyen]]></dc:creator><pubDate>Tue, 21 Jul 2020 15:42:36 GMT</pubDate><media:content url="https://blog.ducthinh.net/content/images/2020/07/aws-cognito-github-idp-oauth.png" medium="image"/><content:encoded><![CDATA[<img src="https://blog.ducthinh.net/content/images/2020/07/aws-cognito-github-idp-oauth.png" alt="Using GitHub as OpenID IdP with AWS Cognito"><p>Today I was researching to make AWS Cognito works with GitHub as an identity provider (IdP). I thought it would be easy... until it wasn't.</p><p>The problem is that Cognito only supports integrating third-party authentication system by using SAML or OpenID. SAML is a difficult choice because GitHub only provides SAML SSO (Single Sign-on) support for plans Enterprise+, which is really hard to get for developers. So the only option left is the OpenID, which is an identity layer on top of the OAuth 2.0 protocol.</p><p>Googling for a while, they do give developers ways to create and build an OAuth application on top of GitHub account. You will have to <a href="https://docs.github.com/en/developers/apps/creating-an-oauth-app">create an OAuth application on GitHub first</a>.</p><ul><li>Set your GitHub OAuth Authorization Callback URL to <code>https://&lt;your_cognito_domain&gt;/oauth2/idpresponse</code></li></ul><p>The OAuth endpoints <a href="https://developer.github.com/apps/building-oauth-apps/authorizing-oauth-apps/#2-users-are-redirected-back-to-your-site-by-github">given in GitHub documentation</a> were: </p><ul><li>Request method: GET</li><li>Scopes: user,openid</li><li>Issuer: https://github.com</li><li>Authorize endpoint: <code>https://github.com/login/oauth/authorize</code></li><li>Token endpoint: <code>https://github.com/login/oauth/access_token</code></li><li>User info endpoint: <code>https://api.github.com/user</code></li><li>JWKS endpoint: anything, I put in <code><code>https://github.com/login/oauth/access_token</code></code></li></ul><p>Seems about right? Right? When filled into Cognito OpenID Connect, it just didn't work. I got an error like this:</p><pre><code>Response+from+IdP+token+endpoint+cannot+be+parsed+as+a+JSON.</code></pre><p>Looking back at the documentation, the GitHub implementation of OAuth just didn't match my expectations. For example:</p><ul><li>Requesting data from the token endpoint, it will return the following form: <code>access_token=e72e16c7e42f292c6912e7710c838347ae178b4a&amp;token_type=bearer</code>, which is incorrect. It should be returning a JSON object for OpenID to understand.</li><li>User info endpoint using some weird authorization scheme: <code>Authorization: token OAUTH-TOKEN</code>. That's weird to me. OpenID will send a <code>Bearer</code> scheme so that's why it won't work.</li><li>Playing around in Postman, I noticed that in the user info endpoint, GitHub didn't return <code>sub</code>, a very important field for OpenID Connect and Cognito to map the username.</li></ul><p>So I decided to make a "proxy" in Python and Flask to handle these request and returning the correct payload for Cognito to understand.</p><h3 id="github-token-endpoint-proxy">GitHub Token Endpoint Proxy</h3><p>The idea for this endpoint is to take the form data sent from AWS Cognito, forward it back to GitHub with the header <code>Accept: application/json</code> for GitHub API to return back in JSON form instead of "query" form.</p><pre><code class="language-python">import requests
from flask import request, jsonify

from main import app


@app.route('/oauth/github/access-token', methods=['POST'])
def get_access_token():
    github_request = requests.post(
        url='https://github.com/login/oauth/access_token',
        headers={
            'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
            'Accept': 'application/json'
        },
        data=request.form.to_dict(),
        allow_redirects=False
    )
    response = github_request.json()

    return jsonify(response)</code></pre><h3 id="github-user-info-endpoint-proxy">GitHub User Info Endpoint Proxy</h3><p>With this one, we will do the following things:</p><ul><li>Get the <code>Bearer</code> token given by Cognito and modify the header to send <code>token</code> authorization scheme to GitHub.</li><li>Add a <code>sub</code> field into the response for Cognito to map the username.</li></ul><pre><code>@app.route('/oauth/github/user-info', methods=['GET'])
def get_user_info():
    github_request = requests.get(
        url='https://api.github.com/user',
        headers={
            'Authorization': 'token ' + request.headers.get('Authorization').split('Bearer ')[1],
            'Accept': 'application/json'
        },
        allow_redirects=False
    )
    response = github_request.json()

    return jsonify({
        **response,
        'sub': response['id']
    })</code></pre><hr><p>Deploy these APIs on your server and delete your current OpenID configuration and add a new one with these values:</p><ul><li>Request method: GET</li><li>Scopes: user,openid</li><li>Issuer: https://github.com</li><li>Authorize endpoint: <code>https://github.com/login/oauth/authorize</code></li><li>Token endpoint: <code>https://&lt;your-api-domain&gt;/oauth/github/access-token</code></li><li>User info endpoint: <code>https://&lt;your-api-domain&gt;/oauth/github/user-info</code></li><li>JWKS endpont: anything, I put in the token endpoint <code><code>https://&lt;your-api-domain&gt;/oauth/github/access-token</code></code></li></ul><p>In your App Client settings, remember to config it to:</p><ul><li><strong>Allowed OAuth Flows: </strong>Authorization code grant</li><li><strong>Allowed OAuth Scopes: </strong>tick user, openid</li></ul><hr><p>Hope with my tutorial, you can connect your Cognito app with GitHub as an identity provider using OpenID now. Enjoy!</p>]]></content:encoded></item><item><title><![CDATA[Using Trello as a powerful To-do List with Power-ups and Butler Automation]]></title><description><![CDATA[As a great app for project management and tasks management, Trello can be used as a powerful daily personal To-do List with this easy-to-do setup.]]></description><link>https://blog.ducthinh.net/trello-personal-to-do-list/</link><guid isPermaLink="false">5e8de478c054372ea76bfc5f</guid><category><![CDATA[Productivity]]></category><category><![CDATA[Solved]]></category><dc:creator><![CDATA[Thinh Nguyen]]></dc:creator><pubDate>Wed, 08 Apr 2020 17:13:52 GMT</pubDate><media:content url="https://blog.ducthinh.net/content/images/2020/04/personal-trello-to-do-list-workflow-setup-automation-2.png" medium="image"/><content:encoded><![CDATA[<img src="https://blog.ducthinh.net/content/images/2020/04/personal-trello-to-do-list-workflow-setup-automation-2.png" alt="Using Trello as a powerful To-do List with Power-ups and Butler Automation"><p>Trello is widely used and has long been a great tool for project management and tasks management. Not many other tools have the same easy-to-use user interface like Trello's visual Kanban boards. It is flexible, collaborative, and into each tiny cards you can pack a lot of useful information. </p><p>People mostly use it as a tasks management tool for big projects at work. Trello is more than that – it's not just for work. This piece of software can be turned into anything, you can even use it organize your whole life. To achieve just that, you can  customize your personal board to be a <strong>powerful day-to-day to-do list</strong>. In this article, I'll walk you through my current Trello workflow that I have been using and found effective.</p><h2 id="the-basic-board-setup">The Basic Board Setup</h2><h3 id="lists">Lists</h3><p>With some setups, I have an advice that you should create only 3 - 4 main lists. More lists = less focused.</p><p>My basic lists setup looks like the following, note that you can set up these list or modify as you like and can easily use with free plan without any power-ups or automations applied:</p><ul><li><strong>Projects &amp; Goals</strong>: This is a list that you keep your big goals and big projects in. I often use it as a reference so I can create my tasks later based on my goals and keep things on track.</li><li><strong>Recurring</strong>: Cards that I use on a daily basis. Without automation and powerups then I can just Cmd + C, Cmd + V (yes, you can copy and paste your cards from list to list using keyboard shortcuts) to my today tasks list.</li><li><strong>To-Do</strong>: This list contains things that I'll do in the future, or low priority that can be done later.</li><li><strong>Today Tasks</strong>: I drag cards from To-Do to this list if I have to start working on it today or I will continue doing it today. I try to update this list everyday in the early morning so I get a picture of what I'll do that day.</li><li><strong>Done: </strong>Things are done. </li></ul><h3 id="labels">Labels</h3><p>You can setup labels as you like, but I tend to setup 3 labels:</p><ul><li><strong>Daily</strong>: Daily things that needs to be done, usually things in the Recurring list will have this label.</li><li><strong>Personal</strong>: For personal tasks.</li><li><strong>Work</strong>: For tasks that needs to be done at work.</li></ul><p>With this setup, I can easily scan what needs to be done at work and what are my personal things. </p><h3 id="cards">Cards</h3><p>Card is the most important thing in your board. Try to fill in the shortest &amp; the most detailed way possible. The title should be clear enough for you to know what to do, and put links, attachments, medium in your card description.</p><p>For example, with the tasks <em>"Update morning standup minutes"</em>, I put my labels on as <em>Work</em> and I leave the link to the Google Docs so I can open it immediately when I start working on that task.</p><h3 id="checklists">Checklists</h3><p>Checklists are something people don't take seriously. You should put up checklists for your tasks if you can break it down into smaller tasks or things that need to be done. </p><p>Trust me, it will keep you on track and most of the time you won't have to think about what to do next to complete your tasks when you already had everything planned in advance.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://blog.ducthinh.net/content/images/2020/04/trello-checklists-to-do-list.png" class="kg-image" alt="Using Trello as a powerful To-do List with Power-ups and Butler Automation"><figcaption>Try to make a checklist for your goals, projects and individual tasks.</figcaption></figure><h3 id="background">Background</h3><p>Choose whatever you like, what inspires you, what calms you down. It depends on your taste.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://blog.ducthinh.net/content/images/2020/04/personal-trello-to-do-list-workflow-setup-automation-1.png" class="kg-image" alt="Using Trello as a powerful To-do List with Power-ups and Butler Automation"><figcaption>You should have something like mine now.</figcaption></figure><h2 id="level-up-your-boards-with-butler-automation-and-power-ups">Level Up Your Boards With Butler Automation And Power-ups</h2><p>You might have noticed a new list in my setup, some buttons and strange icons. I'll introduce you with them right away.</p><h3 id="power-ups-1-free-for-basic-plan-">Power-ups (1 Free for Basic Plan)</h3><p>With the basic plan, you have 1 power-up that you can add to your board. These are some free &amp; helpful power-ups you can add:</p><ul><li><a href="https://trello.com/power-ups/57b47fb862d25a30298459b1/card-repeater">Card Repeater</a>: This thing will help you to automatically copy a recurring card to a list of your choice at a specific time. I use it to copy my tasks from <strong>Recurring</strong> list to my <strong>Today Tasks. </strong>⏱</li><li> <a href="https://trello.com/power-ups/5b4765f383dd7c75d8e57be4">Time In List</a>: This powerup will give you a quick overview of how long a card is in your board so you can decide what to do with it. 🔁</li><li><a href="https://trello.com/power-ups/55a5d917446f517774210011">Calendar</a>: This 📅 will give you a quick calendar view of your tasks.</li><li><a href="https://trello.com/power-ups/5a1d81359fcdfd9011c0a698">Cronofy</a>: Helps you to 2-way sync your tasks with your calendar (Google Calendar or iCal). You can even edit your tasks' due on your calendar and it'll be updated on Trello. Pretty easy, right?</li></ul><p>With Gold or Business plan, you can add some more. I'm using Trello Gold and I'm using Card Repeater, Calendar and Cronofy.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://blog.ducthinh.net/content/images/2020/04/recurring-tasks-to-do-list-trello-card-repeater.png" class="kg-image" alt="Using Trello as a powerful To-do List with Power-ups and Butler Automation"><figcaption>I often have my recurring cards added to my <em>Today Tasks </em>in the morning before I wake up. You can choose whatever list you want it to copy to, and which position it will appear in the list.</figcaption></figure><h2 id="automate-with-butler">Automate With Butler</h2><p>Butler is a new feature in Trello. It helps you to automate your boards using easy-to-setup rules. Butler provides you with these features:</p><ul><li><strong>Rules</strong>: You can easily setup rules, for eg. <em>When a card is added to "Done" list, check all the items in checklist and archive it</em>. Sounds pretty cool, right?</li><li><strong>Card Button</strong>: Create a new button on your card to do certain things, like assigning that card to you, make it completed, send to reviewer.</li><li><strong>Board Button</strong>: Create a button that appears at the top of your board and it can do magic to your boards, such as "Monday Setup" - archive all cards in <em>Done</em> and pick some random cards in <em>To-Do</em> to <em>Today Tasks</em>.</li><li><strong>Calendar</strong>: Create commands that will be executed on a specific schedule. For example, I can tell Trello to automatically archive all my cards in <em>Done</em> on Monday.</li></ul><p>In the below paragraphs I'll share with you some of my Butlet setup that I am feeling comfortable with:</p><h3 id="rules-free-feature-">Rules (Free Feature)</h3><blockquote>when a card is moved into list "✅ Done" by anyone, check all the items in all the checklists on the card, mark the due date as complete, and sort the list by time in list descending</blockquote><p>With this one after I drag something to <em>Done </em>it will be automatically sorted by date so I can take a look at it in the following day and fill in my daily standup minutes what I've done yesterday.</p><h3 id="calendar-paid-feature-">Calendar (Paid Feature)</h3><blockquote>every monday at 4:00 am, archive all the cards in list "✅ Done"</blockquote><p>With this rule I, it will automatically archive all the cards in my <em>Done</em> list while I am sleeping so I won't have to worry about archiving myself. And fresh start for new week!</p><blockquote>every day at 5:00 am, move all the cards in list "🚧 Today Tasks (updated at 8AM everyday)" to list "🤔 Unfinished Tasks"</blockquote><p>I love this one as in the morning I can know what I did not finish yesterday, and that I can move it back to my <em>Today Tasks</em> list.</p><h2 id="you-re-powered-up">You're Powered Up</h2><p>I hope that after reading this article, you have learnt something new to boost your personal productivity today 🚀 using Trello as a <strong>day-to-day To-do List</strong>. </p><p>I believe that many people are having a better workflow setups then feel free to share it!</p><p>Cheers!</p>]]></content:encoded></item><item><title><![CDATA[Some words before stepping into the New Year of the Rat]]></title><description><![CDATA[<p>It's 8.30pm now and I just feel like writing some words before saying goodbye to the lovely Pig and welcome the Rat.</p><p>The Pig treated me nicely. Coming into 2019, I actually had low expectations. I just wanted everything to just stay the same as 2018: I was still</p>]]></description><link>https://blog.ducthinh.net/turning-to-year-of-the-rat/</link><guid isPermaLink="false">5e2af11dc054372ea76bfb20</guid><category><![CDATA[Me]]></category><dc:creator><![CDATA[Thinh Nguyen]]></dc:creator><pubDate>Fri, 24 Jan 2020 14:37:19 GMT</pubDate><media:content url="https://blog.ducthinh.net/content/images/2020/01/year-of-the-rat.jpeg" medium="image"/><content:encoded><![CDATA[<img src="https://blog.ducthinh.net/content/images/2020/01/year-of-the-rat.jpeg" alt="Some words before stepping into the New Year of the Rat"><p>It's 8.30pm now and I just feel like writing some words before saying goodbye to the lovely Pig and welcome the Rat.</p><p>The Pig treated me nicely. Coming into 2019, I actually had low expectations. I just wanted everything to just stay the same as 2018: I was still having to finish my Bachelor of Engineering degree, had a somewhat high-paid job that every college students wanted, everything going on really well so I didn't feel the need to change anything...</p><h2 id="a-new-job-as-a-software-engineer-at-got-it">A New Job As A Software Engineer At Got It</h2><p>...Then <em>that</em> happened. </p><p>After celebrating a quiet Tet, I came back to my everyday life: studying and working. Studying is okay, but my work soon became a mess. We parted ways during April. I was stressed, I was mad, I was disappointed.</p><p>When a door is closed, another will open. Being at home for a while, I applied for Got It and after some rounds of interview procedure, I got a job offer. The first time ever in my life – I got a full-time job while still finishing university. I started working on new things I hadn't done before, learnt a new programming language and strengthen my skills. I had fun while building amazing things. I really appreciate the trust my colleagues did give me, and I really am enjoying the working atmosphere there. </p><p>Even when I'm looking back at that period now, I feel so proud. I'm sure that my parents are proud of me too (even though they always pronounce my company's name as "Got I-T" instead of "Got It"). </p><p>During the interview process and while working with Got It, I learnt the most important thing, that is: <strong>you have to put effort to get shit done</strong>. </p><h2 id="finishing-my-bachelor-s-degree">Finishing My Bachelor's Degree</h2><p>I hate to say it but I have to admit that during my years in university, I failed a lot of classes, like 6 - 7 courses. I, at one point, was telling myself that I'd never graduate on time. But after planning to study extra classes during the semesters, I finally made it on time. </p><p>I also successfully defensed my graduation thesis with the topic of "Building a live-streaming website". It was a fun experience even though sometimes I was really exhausted because of having to do it while maintaining my quality of work at Got It.</p><h2 id="financially">Financially</h2><p>After some years of working without saving anything, this year I could finally save some money. I saw it as a big win.</p><p>I like reading financial books. Digging deeper into how money works and transferring it into reality is fun. However, I am a coward so I didn't risk investing or anything last year. I'll find a way to make more money in the next month, and by making more money I mean finding a source of passive income :P.</p><hr><p>So in the new year some of my objectives are trying to learn new things and obtain some certifications, improving myself as a better person and putting more effort into my pet project.. and earning more.</p><p>It's more than one hour passed already and I have nothing else to write so I'm gonna stop here. Hopefully 2020 the Rat will treat me nicer haha. </p><p>Thank you my family, my colleagues, my friends, my exes to have been with me after all this time. I really appreciate. I hope everyone health and wealth.</p>]]></content:encoded></item><item><title><![CDATA[Httpd/ apache2 issue "failed to make connection to backend" on CentOS]]></title><description><![CDATA[<p>Ever came across this issue of "<strong>503 Service Unavailable</strong>" when you trying to setup a <code><strong>ProxyPass</strong></code> to your local (127.0.0.1) with <strong>Apache2/httpd</strong>?</p><pre><code>Service Unavailable
The server is temporarily unable to service your request due to maintenance downtime or capacity problems. Please try again later.</code></pre><figure class="kg-card kg-image-card"><img src="https://blog.ducthinh.net/content/images/2019/12/image.png" class="kg-image"></figure><p>Well now</p>]]></description><link>https://blog.ducthinh.net/fix-httpd-issue-failed-make-connection-backend/</link><guid isPermaLink="false">5dfa3ceec054372ea76bfad3</guid><category><![CDATA[Solved]]></category><category><![CDATA[Linux]]></category><dc:creator><![CDATA[Thinh Nguyen]]></dc:creator><pubDate>Wed, 18 Dec 2019 15:03:21 GMT</pubDate><media:content url="https://blog.ducthinh.net/content/images/2019/12/httpd-failed-to-make-connection-to-backend.png" medium="image"/><content:encoded><![CDATA[<img src="https://blog.ducthinh.net/content/images/2019/12/httpd-failed-to-make-connection-to-backend.png" alt="Httpd/ apache2 issue "failed to make connection to backend" on CentOS"><p>Ever came across this issue of "<strong>503 Service Unavailable</strong>" when you trying to setup a <code><strong>ProxyPass</strong></code> to your local (127.0.0.1) with <strong>Apache2/httpd</strong>?</p><pre><code>Service Unavailable
The server is temporarily unable to service your request due to maintenance downtime or capacity problems. Please try again later.</code></pre><figure class="kg-card kg-image-card"><img src="https://blog.ducthinh.net/content/images/2019/12/image.png" class="kg-image" alt="Httpd/ apache2 issue "failed to make connection to backend" on CentOS"></figure><p>Well now there's a really quick fix for it. Just check your <code>error_log</code> of httpd or apache2:</p><pre><code># for httpd
sudo tail /var/log/httpd/error_log

# for apache2
sudo tail /var/log/apache2/error_log</code></pre><p>If you see something like this:</p><pre><code>[Wed Dec 18 14:45:21.586920 2019] [proxy:error] [pid 15448] (111)Connection refused: AH00957: HTTP: attempt to connect to 127.0.0.1:27447 (127.0.0.1) failed
[Wed Dec 18 14:45:21.586969 2019] [proxy_http:error] [pid 15448] [client 94.102.49.104:45290] AH01114: HTTP: failed to make connection to backend: 127.0.0.1
[Wed Dec 18 14:49:28.842439 2019] [proxy:error] [pid 15450] (111)Connection refused: AH00957: HTTP: attempt to connect to 127.0.0.1:27447 (127.0.0.1) failed
[Wed Dec 18 14:49:28.842492 2019] [proxy_http:error] [pid 15450] [client 162.158.219.94:65190] AH01114: HTTP: failed to make connection to backend: 127.0.0.1</code></pre><p>Then you came to the right place! Just run this command:</p><pre><code>sudo /usr/sbin/setsebool -P httpd_can_network_connect 1</code></pre><p>then restart <strong>httpd/ apache2</strong> and you're good to go!</p><hr><p>In case you get the warning:</p><pre><code>setsebool:  SELinux is disabled.</code></pre><p>Then you have to enable SELinux first by opening the file <code>/etc/selinux/config</code>:</p><pre><code>nano /etc/selinux/config</code></pre><p>Change the <code>SELINUX</code> to <code>enforcing</code> then save it:</p><pre><code>SELINUX=enforcing</code></pre><p>Reboot your computer using <code>sudo reboot</code>. After that you can run the command again:</p><pre><code>sudo /usr/sbin/setsebool -P httpd_can_network_connect 1</code></pre><p></p><p>Ta-da! Now your <strong>httpd</strong> can establish a connection to your local application!</p>]]></content:encoded></item><item><title><![CDATA[Change shell (chsh) for Amazon Linux 2]]></title><description><![CDATA[<p><code>chsh</code> does not come with the EC2 Amazon Linux 2 distro. If you want to install <code>zsh</code> or want to change default shell to your favorite, you might have to do additional step to make it works.</p><p>Run this command on your EC2 instance:</p><pre><code>sudo yum install util-linux-user</code></pre><p>After that,</p>]]></description><link>https://blog.ducthinh.net/change-shell-chsh-ec2-amazon-linux-2/</link><guid isPermaLink="false">5dfa34dcc054372ea76bfaa4</guid><category><![CDATA[Solved]]></category><category><![CDATA[Amazon]]></category><dc:creator><![CDATA[Thinh Nguyen]]></dc:creator><pubDate>Wed, 18 Dec 2019 14:37:07 GMT</pubDate><media:content url="https://blog.ducthinh.net/content/images/2019/12/zsh-shell-chsh-amazon-linux-ec2.png" medium="image"/><content:encoded><![CDATA[<img src="https://blog.ducthinh.net/content/images/2019/12/zsh-shell-chsh-amazon-linux-ec2.png" alt="Change shell (chsh) for Amazon Linux 2"><p><code>chsh</code> does not come with the EC2 Amazon Linux 2 distro. If you want to install <code>zsh</code> or want to change default shell to your favorite, you might have to do additional step to make it works.</p><p>Run this command on your EC2 instance:</p><pre><code>sudo yum install util-linux-user</code></pre><p>After that, you can now change your default shell to <code>zsh</code> using <code>chsh</code>:</p><pre><code>chsh -s $(which zsh)</code></pre><p></p><p>In case you are connecting to your EC2 instance using a key pair and Amazon Linux 2 asking for your password, set your user password using this command:</p><pre><code>sudo passwd ec2-user</code></pre><p>The shell will prompt you to enter the current password, just don't type anything and press Enter. You'll be able to enter your new password and a confirmation of your password.</p><p>After changing, you can now change your default shell again!</p>]]></content:encoded></item><item><title><![CDATA[Solved: GCC cannot find "Python.h"]]></title><description><![CDATA[<p>Ever get these red error messages telling you that GCC compiler could not find its path to <code>Python.h</code>? </p><pre><code>MySQLdb/_mysql.c:38:10: fatal error: Python.h: No such file or directory
 #include "Python.h"
          ^~~~~~~~~~
 compilation terminated.
 error: command 'x86_64-linux-gnu-gcc' failed with exit status 1</code></pre><p>Let's start troubleshooting</p>]]></description><link>https://blog.ducthinh.net/gcc-no-such-file-python-h/</link><guid isPermaLink="false">5dcbdc4ca13e856710c8d4b8</guid><category><![CDATA[Solved]]></category><category><![CDATA[Linux]]></category><category><![CDATA[Python]]></category><category><![CDATA[Issues]]></category><dc:creator><![CDATA[Thinh Nguyen]]></dc:creator><pubDate>Wed, 13 Nov 2019 11:29:51 GMT</pubDate><content:encoded><![CDATA[<p>Ever get these red error messages telling you that GCC compiler could not find its path to <code>Python.h</code>? </p><pre><code>MySQLdb/_mysql.c:38:10: fatal error: Python.h: No such file or directory
 #include "Python.h"
          ^~~~~~~~~~
 compilation terminated.
 error: command 'x86_64-linux-gnu-gcc' failed with exit status 1</code></pre><p>Let's start troubleshooting and fixing it following these simple steps:</p><h2 id="first-attempt">First Attempt</h2><p>Try to locate <code>Python.h</code> file in your system first by typing:</p><pre><code>$ locate Python.m</code></pre><p>In case you get the output like below including the paths to available <code>Python.h</code> file in your system:</p><pre><code>$ locate Python.h
/usr/include/python2.7/Python.h
/usr/include/python3.6m/Python.h</code></pre><p><em>If you get empty result or nothing comes up, proceed to the Second Attempt below.</em></p><p>As you can see, I did install 2 versions of python on my machine so I'd got 2 versions of <code>Python.h</code> in the output - one with the 2.7 and the other with 3.6.</p><p>Let's run the following command to make global symlinks to the corresponding Python version of your choice. </p><p>In this case I'll choose to link <code>python3.6m</code>:</p><pre><code>$ sudo ln -sv /usr/include/python3.6m/* /usr/include/</code></pre><p>After executing it, try whatever you're doing again. It should be working now.</p><h2 id="second-attempt">Second Attempt</h2><p>You should be having <code>python-dev</code> or corresponding dev package of your current Python version, for example:</p><ol><li>If you're using Python 2:</li></ol><pre><code># for Ubuntu
$ sudo apt install python-dev

# for CentOS
sudo yum install python3-devel</code></pre><p>2. If you're using Python 3:</p><pre><code> # for Ubuntu
 $ sudo apt install python3-dev
 
 # for CentOS
 sudo yum install python3-devel</code></pre><p>Or you want to install any dev package of a particular Python version, <em>ex. 3.6</em>:</p><pre><code>$ sudo apt install python3.6-dev</code></pre><p>Hope you guys find these fixes useful. Happy coding!</p>]]></content:encoded></item><item><title><![CDATA[Ned E-learning Cross-platform Mobile Application]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p><strong>Features:</strong></p>
<ul>
<li>User authentication (Students vs teachers.)</li>
<li>Courses management &amp; enrollment, rating system.</li>
<li>Video streaming using AWS/ Live streaming using WebRTC &amp; socket.io.</li>
<li>Courses payment/ payout for teachers &amp; pay to enroll for students.</li>
<li>Integration with Momo payment solution.</li>
</ul>
<p><strong>Technologies Used:</strong> WebRTC, Javascript (ES6), Node.js, Express.js, socket.io,</p>]]></description><link>https://blog.ducthinh.net/ned-e-learning-cross-platform-mobile-application/</link><guid isPermaLink="false">5cdb65ed3eabda3e527e344b</guid><category><![CDATA[Portfolio]]></category><dc:creator><![CDATA[Ghost]]></dc:creator><pubDate>Wed, 15 May 2019 01:19:35 GMT</pubDate><media:content url="https://blog.ducthinh.net/content/images/2019/05/1.Walkthrough-1.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://blog.ducthinh.net/content/images/2019/05/1.Walkthrough-1.jpg" alt="Ned E-learning Cross-platform Mobile Application"><p><strong>Features:</strong></p>
<ul>
<li>User authentication (Students vs teachers.)</li>
<li>Courses management &amp; enrollment, rating system.</li>
<li>Video streaming using AWS/ Live streaming using WebRTC &amp; socket.io.</li>
<li>Courses payment/ payout for teachers &amp; pay to enroll for students.</li>
<li>Integration with Momo payment solution.</li>
</ul>
<p><strong>Technologies Used:</strong> WebRTC, Javascript (ES6), Node.js, Express.js, socket.io, MongoDB, Third-party Payment Solutions Integration, AWS S3.</p>
<p><strong>Source Code:</strong> Not available.</p>
<p><strong>Date:</strong> Late 2018 - present.</p>
<p><strong>Client:</strong> Ned (nedapp.)</p>
<p><img src="https://blog.ducthinh.net/content/images/2019/05/1.Walkthrough.jpg" alt="Ned E-learning Cross-platform Mobile Application"></p>
<p><img src="https://blog.ducthinh.net/content/images/2019/05/3.-a-ng-nha--p.jpg" alt="Ned E-learning Cross-platform Mobile Application"></p>
<p><img src="https://blog.ducthinh.net/content/images/2019/05/5.Cho-n-li-nh-vu--c-2.jpg" alt="Ned E-learning Cross-platform Mobile Application"></p>
<p><img src="https://blog.ducthinh.net/content/images/2019/05/Untitled.png" alt="Ned E-learning Cross-platform Mobile Application"></p>
<p><img src="https://blog.ducthinh.net/content/images/2019/05/Home--ngu-o--i-da-y-.png" alt="Ned E-learning Cross-platform Mobile Application"></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Demo Application for FE Credit]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p><strong>This is a demo application for FE Credit. Includes view contract details, payment reminders and live chat with customer service.</strong></p>
<p><strong>Technologies Used:</strong> React Native, ES6.</p>
<p><strong>Source Code:</strong> Not available.</p>
<p><strong>Date:</strong> May 2018.</p>
<p><img src="https://blog.ducthinh.net/content/images/2019/05/Screenshot_1557882724.png" alt="Screenshot_1557882724"></p>
<p><img src="https://blog.ducthinh.net/content/images/2019/05/Screenshot_1557882745.png" alt="Screenshot_1557882745"></p>
<p><img src="https://blog.ducthinh.net/content/images/2019/05/Screenshot_1557882727.png" alt="Screenshot_1557882727"></p>
<!--kg-card-end: markdown-->]]></description><link>https://blog.ducthinh.net/demo-application-for-fe-credit/</link><guid isPermaLink="false">5cdb66843eabda3e527e3454</guid><category><![CDATA[Portfolio]]></category><dc:creator><![CDATA[Ghost]]></dc:creator><pubDate>Wed, 15 May 2019 01:13:16 GMT</pubDate><media:content url="https://blog.ducthinh.net/content/images/2019/05/Screenshot_1557882724-1.png" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://blog.ducthinh.net/content/images/2019/05/Screenshot_1557882724-1.png" alt="Demo Application for FE Credit"><p><strong>This is a demo application for FE Credit. Includes view contract details, payment reminders and live chat with customer service.</strong></p>
<p><strong>Technologies Used:</strong> React Native, ES6.</p>
<p><strong>Source Code:</strong> Not available.</p>
<p><strong>Date:</strong> May 2018.</p>
<p><img src="https://blog.ducthinh.net/content/images/2019/05/Screenshot_1557882724.png" alt="Demo Application for FE Credit"></p>
<p><img src="https://blog.ducthinh.net/content/images/2019/05/Screenshot_1557882745.png" alt="Demo Application for FE Credit"></p>
<p><img src="https://blog.ducthinh.net/content/images/2019/05/Screenshot_1557882727.png" alt="Demo Application for FE Credit"></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Online Mobile Gaming Portal]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p><strong>This is an online mobile gaming portal that provides user with an unified gaming experience across multiple platforms (Android, iOS, Web).</strong></p>
<p><strong>Technologies Used:</strong> React Native, ES6.</p>
<p><strong>Source Code:</strong> Not available.</p>
<p><strong>Date:</strong> Early 2018.</p>
<p><strong>Client:</strong> Big Fat Team Solutions &amp; Technologies Vietnam Co., Ltd.</p>
<p><img src="https://blog.ducthinh.net/content/images/2019/05/Screenshot_1556125337.png" alt="Screenshot_1556125337"></p>
<p><img src="https://blog.ducthinh.net/content/images/2019/05/Screenshot_1556125649-1.png" alt="Screenshot_1556125649-1"></p>
<p><img src="https://blog.ducthinh.net/content/images/2019/05/Screenshot_1556125378-1.png" alt="Screenshot_1556125378-1"></p>
<!--kg-card-end: markdown-->]]></description><link>https://blog.ducthinh.net/online-mobile-game-portal/</link><guid isPermaLink="false">5cdb633f3eabda3e527e343b</guid><category><![CDATA[Portfolio]]></category><dc:creator><![CDATA[Ghost]]></dc:creator><pubDate>Wed, 15 May 2019 00:57:39 GMT</pubDate><media:content url="https://blog.ducthinh.net/content/images/2019/05/Screenshot_1556125337-1.png" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://blog.ducthinh.net/content/images/2019/05/Screenshot_1556125337-1.png" alt="Online Mobile Gaming Portal"><p><strong>This is an online mobile gaming portal that provides user with an unified gaming experience across multiple platforms (Android, iOS, Web).</strong></p>
<p><strong>Technologies Used:</strong> React Native, ES6.</p>
<p><strong>Source Code:</strong> Not available.</p>
<p><strong>Date:</strong> Early 2018.</p>
<p><strong>Client:</strong> Big Fat Team Solutions &amp; Technologies Vietnam Co., Ltd.</p>
<p><img src="https://blog.ducthinh.net/content/images/2019/05/Screenshot_1556125337.png" alt="Online Mobile Gaming Portal"></p>
<p><img src="https://blog.ducthinh.net/content/images/2019/05/Screenshot_1556125649-1.png" alt="Online Mobile Gaming Portal"></p>
<p><img src="https://blog.ducthinh.net/content/images/2019/05/Screenshot_1556125378-1.png" alt="Online Mobile Gaming Portal"></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Node.js/ Express.js Web Services System for an Education App (Ned)]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p><strong>Features:</strong></p>
<ul>
<li>User authentication (Students vs teachers.)</li>
<li>Courses management &amp; enrollment, rating system.</li>
<li>Video streaming using AWS/ Live streaming using WebRTC &amp; socket.io.</li>
<li>Courses payment/ payout for teachers &amp; pay to enroll for students.</li>
</ul>
<p><strong>Technologies Used:</strong> WebRTC, Javascript (ES6), Node.js, Express.js, socket.io, MongoDB, Third-party Payment Solutions Integration,</p>]]></description><link>https://blog.ducthinh.net/nodejs-express-web-services-for-education-app-ned/</link><guid isPermaLink="false">5c90cf973eabda3e527e3412</guid><category><![CDATA[Portfolio]]></category><dc:creator><![CDATA[Ghost]]></dc:creator><pubDate>Tue, 19 Mar 2019 11:24:20 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p><strong>Features:</strong></p>
<ul>
<li>User authentication (Students vs teachers.)</li>
<li>Courses management &amp; enrollment, rating system.</li>
<li>Video streaming using AWS/ Live streaming using WebRTC &amp; socket.io.</li>
<li>Courses payment/ payout for teachers &amp; pay to enroll for students.</li>
</ul>
<p><strong>Technologies Used:</strong> WebRTC, Javascript (ES6), Node.js, Express.js, socket.io, MongoDB, Third-party Payment Solutions Integration, AWS S3.</p>
<p><strong>Source Code:</strong> Not available.</p>
<p><strong>Date:</strong> Late 2018 - present.</p>
<p><strong>Position:</strong> Freelance Backend Developer.</p>
<p><strong>Client:</strong> Ned (nedapp.)</p>
<p>Demos/ pictures are not available.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Apple đáp trả Spotify về các khiếu nại liên quan đến Apple Music và App Store]]></title><description><![CDATA[<figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://blog.ducthinh.net/content/images/2019/03/apple-music-vs-spotify.png" class="kg-image"><figcaption>Apple Music và Spotify</figcaption></figure><p>Spotify kiếm tiền và hút người dùng chủ yếu nhờ App Store, và khi đã hút đủ rồi thì lại quay ra kiện Apple. </p><p>Không có thương vụ nào chỉ có một bên có lợi hết, nhưng nếu Spotify chơi trò đóng giả nạn nhân ở</p>]]></description><link>https://blog.ducthinh.net/spotify-khieu-nai-apple-tra-loi/</link><guid isPermaLink="false">5c8cdaa63eabda3e527e33fc</guid><category><![CDATA[Apple]]></category><category><![CDATA[Opinions]]></category><dc:creator><![CDATA[Thinh Nguyen]]></dc:creator><pubDate>Sat, 16 Mar 2019 11:24:44 GMT</pubDate><media:content url="https://blog.ducthinh.net/content/images/2019/03/apple-music-vs-spotify-1.png" medium="image"/><content:encoded><![CDATA[<figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://blog.ducthinh.net/content/images/2019/03/apple-music-vs-spotify.png" class="kg-image" alt="Apple đáp trả Spotify về các khiếu nại liên quan đến Apple Music và App Store"><figcaption>Apple Music và Spotify</figcaption></figure><img src="https://blog.ducthinh.net/content/images/2019/03/apple-music-vs-spotify-1.png" alt="Apple đáp trả Spotify về các khiếu nại liên quan đến Apple Music và App Store"><p>Spotify kiếm tiền và hút người dùng chủ yếu nhờ App Store, và khi đã hút đủ rồi thì lại quay ra kiện Apple. </p><p>Không có thương vụ nào chỉ có một bên có lợi hết, nhưng nếu Spotify chơi trò đóng giả nạn nhân ở đây thì người thiệt chỉ là Spotify.</p><p><strong>1,</strong> Apple không thu lợi từ tiền quảng cáo của Spotify. Spotify lại đang cung cấp dịch vụ miễn phí trên App Store đồng nghĩa Apple sẽ không thu được đồng nào của Spotify nếu toàn bộ người dùng đều không trả phí. </p><p>Điều này có thể hiểu là trong số gần 200 triệu người sử dụng Spotify hàng tháng thì toàn bộ 200 triệu người dùng này Apple không thu được đồng nào do Spotify không cho thanh toán qua iTunes Subscription, trong khi người dùng iOS vẫn được sử dụng free, Spotify vẫn thu được tiền quảng cáo cũng như subscriptions.</p><p><strong>2,</strong> Spotify được quyền cho phép người dùng subscribe trên PC/ Web chứ không nhất thiết phải qua App Store (chính Spotify đã tự loại bỏ tính năng này để không phải trả phí 30% cho Apple). Khi bạn sử dụng hệ sinh thái của người khác để kiếm tiền nhưng không trả tiền cho họ, thì bạn được gọi là gì?</p><p>Spotify cũng áp dụng điều này cho ứng dụng trên Google Play. Muốn ăn cả nhưng không muốn cho ai cái gì.</p><p><strong>3,</strong> Apple đang sử dụng business model giống hệt trên Play Store, Apple lấy 30% năm đầu, 15% cho năm thứ hai. Yet Spotify nói rằng 30% là ‘unfair.’</p><p>Đây cũng là lý do mà Spotify đâm đơn kiện Apple. Nhưng 30-15 là chuẩn chung cho các market place lớn (bao gồm Play Store), tại sao chỉ kiện Apple? - Bởi vì Google Play Music không phải là đối thủ lớn, và hầu hết người dùng trả phí là iOS users, trong khi Apple có Apple Music với hơn 56 triệu người dùng trả phí. Bởi vì điều số 2, Spotify muốn nuốt gọn toàn bộ nên người dùng Spotify không có cách nào subscribe thuận tiện trên thiết bị di động.</p><p><strong>4</strong>, Số người dùng iOS sẵn sàng bỏ tiền sử dụng dịch vụ trả phí/ mua ứng dụng gấp đôi so với người dùng Android. Vì thế Spotify được lợi chứ không phải là bị chèn ép gì. Thậm chí Apple còn không thu được đồng lợi tức nào từ userbase mà mình tạo ra cho người khác.</p><p><strong>5</strong>, Trong khi không trả cho Apple bất cứ đồng nào, thu lợi quảng cáo, thu tiền từ subscribers không mất phí, Spotify vẫn trả cho tác giả, nhà soạn nhạc, ca sĩ ÍT HƠN GẦN GẤP ĐÔI so với Apple. Chỉ mới gần đây, khi USCRB yêu cầu các dịch vụ stream nhạc tăng phần chia sẻ cho các nghệ sĩ thì Spotify cũng đã đứng lên kiện ngược lại các nhà viết nhạc.</p><p>Cũng vì điều này mà rất nhiều nghệ sỹ đã quay lưng với Spotify từ rất lâu rồi.</p><p><strong>6</strong>, Về tiêu chuẩn trên App Store, chính những tiêu chuẩn này làm nên một chợ ứng dụng chất lượng. Nhờ điều này mà Apple có hệ sinh thái tốt cho các ứng dụng phát triển, Spotify cũng không ngoại lệ. Quá trình xét duyệt ứng dụng đều có quy trình như nhau, không phân biệt lớn hay bé nên không thể nói Spotify bị phân biệt nên bị làm khó dễ hay bị làm chậm quy trình. </p><p>Vụ kiện này nhìn có vẻ giống một chiêu trò PR hơn nhằm tranh thủ lôi kéo người dùng theo hướng “Apple ăn tham.” Nhưng nếu tôn trọng nghệ sĩ và âm nhạc của họ, chắc hẳn bạn đã biết nên đứng về phe nào.</p><p>Đọc thêm: <em>Addressing Spotify's Claims</em> - <a href="https://www.apple.com/newsroom/2019/03/addressing-spotifys-claims/">https://www.apple.com/newsroom/2019/03/addressing-spotifys-claims/</a></p>]]></content:encoded></item><item><title><![CDATA[Why I chose Starbucks and Apple for the environment]]></title><description><![CDATA[<p>I care about the environment. That’s why I chose Apple and Starbucks over other competitors, including turning my back on local brands. These brands are currently the pioneers in their fields when it comes to reducing environmental footprints.</p><p>These are some of the efforts that have been made by</p>]]></description><link>https://blog.ducthinh.net/starbucks-apple-for-the-environment/</link><guid isPermaLink="false">5c2dc3813eabda3e527e33e2</guid><category><![CDATA[Opinions]]></category><dc:creator><![CDATA[Thinh Nguyen]]></dc:creator><pubDate>Thu, 03 Jan 2019 08:15:16 GMT</pubDate><media:content url="https://blog.ducthinh.net/content/images/2019/01/2019-01-10-15-38-19.236.JPG" medium="image"/><content:encoded><![CDATA[<img src="https://blog.ducthinh.net/content/images/2019/01/2019-01-10-15-38-19.236.JPG" alt="Why I chose Starbucks and Apple for the environment"><p>I care about the environment. That’s why I chose Apple and Starbucks over other competitors, including turning my back on local brands. These brands are currently the pioneers in their fields when it comes to reducing environmental footprints.</p><p>These are some of the efforts that have been made by Starbucks and Apple to reduce their footprints on the environment:</p><p><strong>Starbucks:</strong></p><ul><li>Paper bags, paper napkin, paper cups and even cold cups are all made from post-consumer materials. </li><li>For more specific, the napkin is made with 100% recycled content and a minimum of 40% post-consumer fiber; paper cups consist of an amount of 10% recycled content as the technology is not there yet (aiming to double in 2022); 50% of recycled rPET in cold cups. All these are possible for recycle/ reuse.</li><li>Switching to disposable straws and offer strawless lids at stores. This will have been completed across the globe by 2020 and will help reducing the tide of ocean plastic.</li><li>Encouraging customers to use their own mugs, personal cups or tumblers to help reducing wastes by offering them a discount when doing this. Everyone is happy.</li><li>Owning Renewable Energy Certificates and 62% of all Starbucks stores are powered by renewable energy, aiming for 100% of stores globally in 2020.</li></ul><p><strong>Apple:</strong></p><ul><li>100% of all Apple facilities worldwide including Apple Stores, Apple Park and data centers for services such as iMessage, iCloud... are powered by renewable energy.</li><li>All of Apple products are 100% recyclable. Apple invented Daisy, a robot that can disassemble and recover value materials in devices.</li><li>Apple devices are designed for durability so customers can use devices in a longer period of time. This helps reducing wastes by it being taken advantages of longer without having to switch to a newer device.</li><li>New Apple devices are being made from 100% recycled aluminum that was taken from old devices after recycling process.</li><li>Apple packagings are a lot greener now by using less plastic and their factories and supply chains are Zero Waste-certified.</li></ul><p><strong>References:</strong></p><ul><li><a href="https://www.starbucks.com/responsibility/environment">Starbucks: Environment</a></li><li><a href="https://www.apple.com/environment/pdf/Apple_Environmental_Responsibility_Report_2018.pdf">Apple Environmental Responsibility Report (2018)</a></li></ul>]]></content:encoded></item><item><title><![CDATA[Route TCP 80 to 8080 IPTables]]></title><description><![CDATA[How to route your traffic from any port to port 80 (HTTP) on Linux with iptables.]]></description><link>https://blog.ducthinh.net/route-tcp-80-to-8080-iptables/</link><guid isPermaLink="false">5c05077fff6d390312e7c722</guid><category><![CDATA[Linux]]></category><dc:creator><![CDATA[Thinh Nguyen]]></dc:creator><pubDate>Mon, 03 Dec 2018 10:38:59 GMT</pubDate><media:content url="https://blog.ducthinh.net/content/images/2018/12/70900645936645faa29ea37898fe20b6.png" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><pre><code>sudo sysctl net.ipv4.ip_forward=1
sudo iptables -A PREROUTING -t nat -p tcp --dport 80 -j REDIRECT --to-ports 8080
sudo iptables -t nat -A OUTPUT -o lo -p tcp --dport 80 -j REDIRECT --to-port 8080
</code></pre>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[WWDC18 Keynote Highlights]]></title><description><![CDATA[<h2 id="-wwdc18-keynote-highlights">#WWDC18 Keynote Highlights</h2><h3 id="only-ios-macos">Only iOS &amp; macOS</h3><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://blog.ducthinh.net/content/images/2018/12/apple_WWDC_2018_2325-2.jpg" class="kg-image"><figcaption>WWDC 2018</figcaption></figure><h2 id="-ios12-">#iOS12: </h2><p>1. ARKit 2.<br>2. Smarter Siri + Workflow = Siri Shortcuts.<br>3. Group Notifications, Do not Disturb at Bedtime, Screen Time.<br>4. Memoji.<br>5. Group FaceTime Calls up to 32 people.<br>6. Photos with new ‘For You’ tab and Sharing Suggestions.</p><h2 id="-macosmojave-">#macOSMojave:</h2>]]></description><link>https://blog.ducthinh.net/wwdc18-keynote-highlights/</link><guid isPermaLink="false">5c0506ceff6d390312e7c711</guid><category><![CDATA[WWDC]]></category><category><![CDATA[Apple]]></category><dc:creator><![CDATA[Thinh Nguyen]]></dc:creator><pubDate>Mon, 04 Jun 2018 10:37:00 GMT</pubDate><media:content url="https://blog.ducthinh.net/content/images/2018/12/apple_WWDC_2018_2325-2-1.jpg" medium="image"/><content:encoded><![CDATA[<h2 id="-wwdc18-keynote-highlights">#WWDC18 Keynote Highlights</h2><h3 id="only-ios-macos">Only iOS &amp; macOS</h3><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://blog.ducthinh.net/content/images/2018/12/apple_WWDC_2018_2325-2.jpg" class="kg-image" alt="WWDC18 Keynote Highlights"><figcaption>WWDC 2018</figcaption></figure><h2 id="-ios12-">#iOS12: </h2><img src="https://blog.ducthinh.net/content/images/2018/12/apple_WWDC_2018_2325-2-1.jpg" alt="WWDC18 Keynote Highlights"><p>1. ARKit 2.<br>2. Smarter Siri + Workflow = Siri Shortcuts.<br>3. Group Notifications, Do not Disturb at Bedtime, Screen Time.<br>4. Memoji.<br>5. Group FaceTime Calls up to 32 people.<br>6. Photos with new ‘For You’ tab and Sharing Suggestions.</p><h2 id="-macosmojave-">#macOSMojave:</h2><p>1. System-wide Dark Mode + Xcode in Dark Mode.<br>2. Finder: Dynamic Desktop, Desktop Stacks, new Quick Look and Screenshot Tools.<br>3. Apple News, Home App &amp; Voice Memos.<br>4. Stronger Privacy Control.<br>5. Enhanced Do-not-Tracking in Safari (for both macOS and iOS).<br>6. Completely new, redesigned &amp; rebuilt Mac App Store. (Microsoft and Adobe are bringing their apps to the App Store later this year).<br>7. ‘Create ML’ with Core ML 2 to train ML models on a Mac.<br>8. Better Continuity.</p><p><strong>Not merging iOS &amp; macOS but:</strong><br>- bringing a part of UIKit from iOS to macOS and doing Phase 1 of the integration process: testing the technique. <br>- they’ve made new Apple News, Voice Memos &amp; Home app on macOS based on this technology. <br>- developers are getting this in 2019.</p><p>This year is like Apple finally sat back and did listen to meet their customers' expectations instead of rushing for some big new features that would be buggy. Can't wait for macOS 10.14 and iOS 12 🙏🏻🔥.</p>]]></content:encoded></item><item><title><![CDATA[Starbucks Duy Tân - nước đi "cáo già" của ông lớn ngành cafe]]></title><description><![CDATA[<p>Hôm nay 23/4 là ngày khai trương cửa hàng thứ 10 của Starbucks tại Hà Nội, toạ lạc tại một toà nhà riêng rất đẹp đẽ tại 32 - 34 phố Duy Tân, ngay cạnh The Coffee House.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://blog.ducthinh.net/content/images/2018/12/30171378_2080402175333597_2428334737341563244_o-2-1.jpg" class="kg-image"><figcaption>Starbucks Duy Tân</figcaption></figure><p>Theo trend thì trước đây khi mới có</p>]]></description><link>https://blog.ducthinh.net/starbucks-duy-tan-nuoc-di-cao-gia-cua-ong-lon-nganh-cafe-2/</link><guid isPermaLink="false">5c05018b75aa357eaadbb1d6</guid><category><![CDATA[Opinions]]></category><dc:creator><![CDATA[Thinh Nguyen]]></dc:creator><pubDate>Mon, 23 Apr 2018 10:12:00 GMT</pubDate><media:content url="https://blog.ducthinh.net/content/images/2018/12/30171378_2080402175333597_2428334737341563244_o-2-2.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://blog.ducthinh.net/content/images/2018/12/30171378_2080402175333597_2428334737341563244_o-2-2.jpg" alt="Starbucks Duy Tân - nước đi "cáo già" của ông lớn ngành cafe"><p>Hôm nay 23/4 là ngày khai trương cửa hàng thứ 10 của Starbucks tại Hà Nội, toạ lạc tại một toà nhà riêng rất đẹp đẽ tại 32 - 34 phố Duy Tân, ngay cạnh The Coffee House.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://blog.ducthinh.net/content/images/2018/12/30171378_2080402175333597_2428334737341563244_o-2-1.jpg" class="kg-image" alt="Starbucks Duy Tân - nước đi "cáo già" của ông lớn ngành cafe"><figcaption>Starbucks Duy Tân</figcaption></figure><p>Theo trend thì trước đây khi mới có 9 cửa hàng, thì gần 90% số stores (8 trên tổng số 9) là đều nằm trong khuôn viên của một khách sạn/ tổ hợp nào đó (ví dụ IPH, Somerset, Asia Tower Nha Tho...); duy chỉ có 1 store riêng một building ở ngã tư Bà Triệu; vậy tại sao đến store thứ 10, Starbucks lại chọn xây hẳn một cửa hàng độc lập, mà lại ở phố Duy Tân trong khi cách đó 800m đã có 1 store tại IPH?</p><p><br>1, Phố Duy Tân là phố hội tụ các toà nhà văn phòng của các công ty lớn, như FPT, BIDV, Vietin, Novotel, VPB, Viettel, CMC...; đánh đúng vào đối tượng khách hàng là dân văn phòng, doanh nhân, người nước ngoài... Starbucks mong muốn đây sẽ là nơi lý tưởng cho đối tượng này gặp gỡ đối tác, làm việc,... nơi mà không gian của những chuỗi cafe khác như Highlands hay TCH không thể sánh kịp.</p><p><br>2, Có thể nói đây là Starbucks đầu tư nhất ở Hà Nội hiện giờ, với việc decor cực kì ổn &amp; chuẩn; cạnh tranh trực tiếp với 3 hãng cafe lớn trên cùng trục đường (TCH, HL, TBC), Starbucks đang muốn lôi kéo những khách hàng quen của các hãng khác về thành tập khách hàng của chính mình. Chắc chắn rằng những người muốn đặt chân vào những Twitter, TCH khi nhìn qua chiếc 'dinh tự' Starbucks kia sẽ suy nghĩ lại về quyết định của mình.</p><p><br>3, Có lẽ đây chính là lý do quan trọng nhất: Ngay bên cạnh là The Coffee House, 36 Duy Tân. Tại số 19 ngay gần đó cũng có một Highlands Coffee. Toà TCH cũng mới khai trương vào 31/1/2018 mới đây. Thường thì khi mở sau, các doanh nghiệp rất 'ngại' chạm mặt đối thủ, mà trường hợp này đối thủ lại là 'hàng xóm' ngay cạnh. Tại sao Starbucks dám làm điều này? Đó chính là cái 'cáo già' của 'ông lớn',</p><p><br>Chẳng là, TCH mới đây ra nhánh TCH Signature, có thể nói là 'nhái' y hệt mô hình Reserve của Starbucks. Ông lớn không thể ngồi yên để một thằng oắt con giỡn mặt, việc khai trương store mới này cũng chính là 'signal' để dằn mặt cho thằng bé thấy là 'ông này không dễ chơi thế đâu'.</p>]]></content:encoded></item></channel></rss>