<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Software &#8211; Henry Poon&#039;s Blog</title>
	<atom:link href="https://blog.henrypoon.com/blog/tag/software/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.henrypoon.com</link>
	<description></description>
	<lastBuildDate>Sun, 02 Oct 2022 05:08:45 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	
<site xmlns="com-wordpress:feed-additions:1">83044199</site>	<item>
		<title>Running Selenium Webdriver on WSL2</title>
		<link>https://blog.henrypoon.com/blog/2020/09/27/running-selenium-webdriver-on-wsl2/</link>
					<comments>https://blog.henrypoon.com/blog/2020/09/27/running-selenium-webdriver-on-wsl2/#respond</comments>
		
		<dc:creator><![CDATA[hp]]></dc:creator>
		<pubDate>Mon, 28 Sep 2020 00:49:34 +0000</pubDate>
				<category><![CDATA[computer stuff]]></category>
		<category><![CDATA[engineering]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[APT]]></category>
		<category><![CDATA[AWK]]></category>
		<category><![CDATA[Bash]]></category>
		<category><![CDATA[COM]]></category>
		<category><![CDATA[Computer architecture]]></category>
		<category><![CDATA[D]]></category>
		<category><![CDATA[Download]]></category>
		<category><![CDATA[Drive]]></category>
		<category><![CDATA[Error message]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[Firefox version history]]></category>
		<category><![CDATA[Flag]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Graphical user interface testing]]></category>
		<category><![CDATA[IME]]></category>
		<category><![CDATA[IP address]]></category>
		<category><![CDATA[ise]]></category>
		<category><![CDATA[It]]></category>
		<category><![CDATA[Lag]]></category>
		<category><![CDATA[lamb]]></category>
		<category><![CDATA[Language]]></category>
		<category><![CDATA[Lie]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Messages]]></category>
		<category><![CDATA[Net]]></category>
		<category><![CDATA[Operating systems]]></category>
		<category><![CDATA[Parameter]]></category>
		<category><![CDATA[PATH]]></category>
		<category><![CDATA[Port]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Resolv.conf]]></category>
		<category><![CDATA[Rolling]]></category>
		<category><![CDATA[Run]]></category>
		<category><![CDATA[Selenium]]></category>
		<category><![CDATA[Sleep]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[STR]]></category>
		<category><![CDATA[Struct]]></category>
		<category><![CDATA[Time]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[Ubuntu version history]]></category>
		<category><![CDATA[USR]]></category>
		<category><![CDATA[Variable]]></category>
		<category><![CDATA[Web development software]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Z]]></category>
		<guid isPermaLink="false">https://blog.henrypoon.com/?p=6269</guid>

					<description><![CDATA[This is a newer version of the post that I made before on how to run Selenium on WSL, but this one is on doing it in WSL2. The instructions are similar at a high level but there are some additional gotchas. You will need: WSL2 setup with Firefox installed (mine uses Ubuntu 20.04) VcXsrv [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">This is a newer version of the post that I made before on <a href="https://blog.henrypoon.com/blog/2017/06/18/running-selenium-webdriver-on-bash-for-windows/" target="_blank" rel="noreferrer noopener">how to run Selenium on WSL</a>, but this one is on doing it in WSL2.  The instructions are similar at a high level but there are some additional gotchas.</p>



<p class="wp-block-paragraph">You will need:</p>



<ul class="wp-block-list"><li><a rel="noreferrer noopener" href="https://msdn.microsoft.com/en-us/commandline/wsl/install_guide" target="_blank">WSL2 setup</a> with Firefox installed (mine uses Ubuntu 20.04)</li><li><a rel="noreferrer noopener" href="https://sourceforge.net/projects/vcxsrv/" target="_blank">VcXsrv</a></li><li><a rel="noreferrer noopener" href="https://github.com/mozilla/geckodriver/releases" target="_blank">geckodriver</a></li></ul>



<h2 class="wp-block-heading">How it works</h2>



<p class="wp-block-paragraph">VcXsrv starts up an X server on the Windows host machine, and what WSL will do is connect to this server to pass on the details of what programs need to be displayed (in this case, the browser window).  Geckodriver is there purely as a middle layer for Selenium to be able to interact with Firefox.</p>



<h2 class="wp-block-heading">VcXsrv setup</h2>



<p class="wp-block-paragraph">This setups the X server so that Windows can display graphical data coming from the Ubuntu instance.</p>



<ol class="wp-block-list"><li>Download and install</li><li>Start it up with the the command line parameter &#8220;-ac&#8221;.  This flag removes access control restrictions for connecting clients (which is okay as long as this server isn&#8217;t exposed on the open Internet and that the only client connecting is the Ubuntu instance)</li><li>Allow connections to VcXsrv on Windows Firewall</li></ol>



<p class="wp-block-paragraph">The &#8220;-ac&#8221; flag and allowing the program through Windows Firewall is pretty important.  When I didn&#8217;t do this, Ubuntu would give me cryptic error messages like &#8220;Broadway display type not supported&#8221;, but once I set up these access controls, everything was fine.</p>



<h2 class="wp-block-heading">Bash setup</h2>



<p class="wp-block-paragraph">Install firefox</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">sudo apt install firefox</code></pre>



<p class="wp-block-paragraph">Export DISPLAY variable in .bashrc (or for whatever terminal you use, maybe .zshrc, etc.)</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">export DISPLAY=$(ip route | awk '{print $3; exit}'):0</code></pre>



<p class="wp-block-paragraph">This will configure your DISPLAY variable to use the IP address listed in the resolv.conf file.  The IP address listed there is the IP address of the X server that will be used for displaying the browser window.</p>



<p class="wp-block-paragraph">Start up VcXsrv as described in the above and then try to open Firefox.  The Firefox window should open.</p>



<h2 class="wp-block-heading">Geckodriver setup</h2>



<p class="wp-block-paragraph">This acts purely as the API interface that allows Selenium to interact with Firefox.  Selenium looks for this executable when controlling the web browser.</p>



<ol class="wp-block-list"><li>Download geckodriver (make sure to get the Linux one and not the Windows one)</li><li>Put it in /usr/bin (or alternatively some other folder in your PATH)</li></ol>



<h2 class="wp-block-heading">Selenium sample on Python</h2>



<p class="wp-block-paragraph">I tend to use Python when running Selenium code, and I haven&#8217;t tried it on another language (I imagine the principles are similar).  Here is a piece of sample code for starting up the browser and opening up a website, but really any Selenium code can be used.</p>



<pre class="wp-block-code"><code lang="python" class="language-python">import time

from selenium import webdriver
from selenium.webdriver import DesiredCapabilities

def execute_with_retry(method, max_attempts):
    e = None
    for i in range(0, max_attempts):
        try:
            return method()
        except Exception as e:
            print(e)
            time.sleep(1)
    if e is not None:
        raise e

capabilities = DesiredCapabilities.FIREFOX
capabilities["marionette"] = True
firefox_bin = "/usr/bin/firefox"
browser = execute_with_retry(lambda: webdriver.Firefox(
    firefox_binary=firefox_bin, capabilities=capabilities), 10)

browser.get("https://www.google.com")

time.sleep(10)

browser.close()</code></pre>



<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.henrypoon.com/blog/2020/09/27/running-selenium-webdriver-on-wsl2/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">6269</post-id>	</item>
		<item>
		<title>Installing Seafile with Docker and Apache 2</title>
		<link>https://blog.henrypoon.com/blog/2019/06/12/installing-seafile-with-docker-and-apache-2/</link>
					<comments>https://blog.henrypoon.com/blog/2019/06/12/installing-seafile-with-docker-and-apache-2/#respond</comments>
		
		<dc:creator><![CDATA[hp]]></dc:creator>
		<pubDate>Wed, 12 Jun 2019 07:12:42 +0000</pubDate>
				<category><![CDATA[computer stuff]]></category>
		<category><![CDATA[engineering]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[9]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[apache 2]]></category>
		<category><![CDATA[Apache HTTP Server]]></category>
		<category><![CDATA[Bash]]></category>
		<category><![CDATA[Chan]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[cloud storage]]></category>
		<category><![CDATA[COM]]></category>
		<category><![CDATA[D]]></category>
		<category><![CDATA[Dia]]></category>
		<category><![CDATA[Docker]]></category>
		<category><![CDATA[Download]]></category>
		<category><![CDATA[DROPBOX]]></category>
		<category><![CDATA[EAR]]></category>
		<category><![CDATA[Email]]></category>
		<category><![CDATA[File sharing]]></category>
		<category><![CDATA[Free software]]></category>
		<category><![CDATA[Gmail]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Gran]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[IOS]]></category>
		<category><![CDATA[It]]></category>
		<category><![CDATA[Lie]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Matt]]></category>
		<category><![CDATA[Nap]]></category>
		<category><![CDATA[Net]]></category>
		<category><![CDATA[Opera]]></category>
		<category><![CDATA[OS-level virtualisation]]></category>
		<category><![CDATA[Page]]></category>
		<category><![CDATA[Password]]></category>
		<category><![CDATA[PATH]]></category>
		<category><![CDATA[Port]]></category>
		<category><![CDATA[Reference]]></category>
		<category><![CDATA[Run]]></category>
		<category><![CDATA[seafile]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[System software]]></category>
		<category><![CDATA[Systemd]]></category>
		<category><![CDATA[Thou]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[URL]]></category>
		<category><![CDATA[USR]]></category>
		<category><![CDATA[ypres]]></category>
		<category><![CDATA[Z]]></category>
		<guid isPermaLink="false">https://blog.henrypoon.com/?p=3509</guid>

					<description><![CDATA[Seafile is an open source file sharing software that allows its users to setup their own cloud storage at home. Think Dropbox, but self-hosted. This post is about deploying an instance of Seafile using Docker on a non-standard port (i.e. not 80 and 443). The reason to deploy the app on a non-standard port is [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph"><a rel="noreferrer noopener" aria-label="Seafile (opens in a new tab)" href="https://www.seafile.com" target="_blank">Seafile</a> is an open source file sharing software that allows its users to setup their own cloud storage at home.  Think Dropbox, but self-hosted.</p>



<p class="wp-block-paragraph">This post is about deploying an instance of Seafile using Docker on a non-standard port (i.e. not 80 and 443).  The reason to deploy the app on a non-standard port is usually because there is already another webserver running on that port (in my case Apache 2).  In such scenarios, it is necessary to set up a reverse proxy so the Seafile port can be exposed by Apache on ports 80/443.  Under typical circumstances, deploying Seafile on a standard port would mean that the app would host itself without the need for Apache 2 at all.  This post also assumes Ubuntu 16.04 as the operating system, but in theory should apply to other Linux OS&#8217;s.</p>



<p class="has-text-align-left wp-block-paragraph">The process can be split into multiple parts:</p>



<ol class="wp-block-list"><li>Setup Docker</li><li>Deploy Seafile</li><li>Configure Apache 2</li><li>Setup systemd</li><li>Setup e-mail (optional)</li><li>Backing up the image</li><li>Troubleshooting</li></ol>



<h2 class="wp-block-heading">Setup Docker</h2>



<p class="wp-block-paragraph">This guide won&#8217;t go into depth on how to setup Docker, but rather the setup guide and more information about what Docker is can be found here: <a rel="noreferrer noopener" aria-label="https://docs.docker.com/get-started/ (opens in a new tab)" href="https://docs.docker.com/get-started/" target="_blank">https://docs.docker.com/get-started/</a></p>



<h2 class="wp-block-heading">Deploy Seafile</h2>



<p class="wp-block-paragraph">The key page in the Seafile documentation for deploying Seafile within Docker can be found here: <a href="https://github.com/haiwen/seafile-docker" target="_blank" rel="noreferrer noopener">https://github.com/haiwen/seafile-docker</a>.  The command I used is as follows:</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">docker run -d --name seafile \
  -e SEAFILE_SERVER_HOSTNAME=seafile.example.com \
  -e SEAFILE_ADMIN_EMAIL=me@example.com \
  -e SEAFILE_ADMIN_PASSWORD=a_very_secret_password \
  -v /opt/seafile-data:/shared \
  -p 8000:80 \
  seafileltd/seafile:latest</code></pre>



<p class="wp-block-paragraph">I recommend setting up Seafile with an actual secret password because it&#8217;s not easy to change once it&#8217;s set up.</p>



<p class="wp-block-paragraph">Note that the port argument shows 8000:80.  It means that Docker will use the host port 8000 and the container will use port 80 &#8211; meaning that using Docker will interpret requests from my host OS on port 8000 as requests on port 80 in the container.  8000 was used on my setup because port 80 was already used. </p>



<p class="wp-block-paragraph">Once the command is executed, the necessary files will be downloaded and the container will start and will be accessible on port 8000.</p>



<p class="wp-block-paragraph">There is also an option to setup Seafile with an SSL cert from <a rel="noreferrer noopener" aria-label="Let's Encrypt (opens in a new tab)" href="https://letsencrypt.org/" target="_blank">Let&#8217;s Encrypt</a>, but I didn&#8217;t do this because I already had a cert that I wanted to reuse.</p>



<p class="wp-block-paragraph">Once the server is up, navigate to <a href="#">https://seafile.example.com/sys/settings/</a> and change SERVICE_URL and FILE_SERVER_URL to match your domain name.</p>



<h2 class="wp-block-heading">Configure Apache 2</h2>



<p class="wp-block-paragraph">Adding a reverse proxy on Apache 2 will allow Apache 2 to route requests to port 8000, which will go to port 80 in the container.  The main reference for this section is this: <a href="https://manual.seafile.com/deploy/deploy_with_apache/" target="_blank" rel="noreferrer noopener">https://manual.seafile.com/deploy/deploy_with_apache/</a>.  This is done by adding a new site to Apache 2.  The following configuration assumes that a LetsEncrypt SSL certificate is used.</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">cd /etc/apache2/sites-available
sudo nano seafile.conf</code></pre>



<pre class="wp-block-code"><code lang="apacheconf" class="language-apacheconf">&lt;IfModule mod_ssl.c&gt;
&lt;VirtualHost *:443&gt;
    ServerName seafile.example.com
    ServerAdmin me@example.com

    RewriteEngine On

    # ModSecurity does not process requests.  There is a hard limit of 1 GB
    # with ModSecurity.
    SecRuleEngine Off

    # Whitelist internal IPs for mod_evasive
    DOSWhitelist 192.168.1.*

    &lt;Location /media&gt;
        Require all granted
    &lt;/Location&gt;

    # Stuff for seafile server
    ProxyPass /seafhttp http://127.0.0.1:8082
    ProxyPassReverse /seafhttp http://127.0.0.1:8082
    RewriteRule ^/seafhttp - [QSA,L]

    # Stuff for seahub
    SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
    ProxyPreserveHost On
    ProxyPass / http://127.0.0.1:8000/
    ProxyPassReverse / http://127.0.0.1:8000/

    ErrorLog ${APACHE_LOG_DIR}/seafile_error.log
    CustomLog ${APACHE_LOG_DIR}/seafile_access.log combined

    Include /etc/letsencrypt/options-ssl-apache.conf

    SSLCertificateFile /path/to/cert/file.pem
    SSLCertificateKeyFile /path/to/cert/key/file.pem
&lt;/VirtualHost&gt;
&lt;/IfModule&gt;
</code></pre>



<p class="wp-block-paragraph">I&#8217;ve added my local domain to the whitelist so that mod_evasive doesn&#8217;t think my local host is a threat.</p>



<p class="wp-block-paragraph">There are two sets of ProxyPass and ProxyPassReverse lines.  The reason for this is that Seafile is split up into Seahub and Seafile, where one uses port 8082 (by default), while the other uses 8000.  These two lines are essentially what allows Apache to read requests from port 443 and pass them on to the container.</p>



<p class="wp-block-paragraph">Once the file is saved, execute the following</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">sudo a2ensite seafile.conf
sudo service apache2 reload</code></pre>



<p class="wp-block-paragraph">Navigating to the site at the Apache 2 defined port should now load Seafile without having to go to port 8000.</p>



<h2 class="wp-block-heading">Setup systemd</h2>



<p class="wp-block-paragraph">systemd allows the Docker container to be started up on boot, and be controlled like this:</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">sudo service seafile start/stop/restart</code></pre>



<p class="wp-block-paragraph">The configuration is as follows:</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">sudo nano /etc/systemd/system/seafile.service</code></pre>



<pre class="wp-block-code"><code lang="properties" class="language-properties">[Unit]
Description=Seafile Server
After=network.target mysql.service

[Service]
Type=oneshot
ExecStart=/usr/bin/docker container start seafile
ExecStop=/usr/bin/docker container stop seafile
ExecReload=/usr/bin/docker container restart seafile
RemainAfterExit=yes
User=root
Group=root

[Install]
WantedBy=multi-user.target</code></pre>



<p class="wp-block-paragraph">Once the configuration is saved, shut off the existing running instance of Seafile and then let systemd start it up for you.</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">sudo systemctl daemon-reload
sudo service seafile start</code></pre>



<p class="wp-block-paragraph">At this point, Seafile should start automatically on boot, with Apache 2 doing a reverse proxy to the true Seafile port.</p>



<h2 class="wp-block-heading">Setup e-mail (optional)</h2>



<p class="wp-block-paragraph">Optionally, Seafile can be configured to send e-mails.  The reference is here: <a href="https://manual.seafile.com/config/sending_email/" target="_blank" rel="noreferrer noopener">https://manual.seafile.com/config/sending_email/</a>.  The config file should be under:</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">/opt/seafile-data/seafile/conf/seahub_settings.py</code></pre>



<p class="wp-block-paragraph">I happen to be using Gmail SMTP, so at the end of the file I&#8217;ve added</p>



<pre class="wp-block-code"><code lang="properties" class="language-properties">EMAIL_USE_TLS = True
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_HOST_USER = 'me@example.com'
EMAIL_HOST_PASSWORD = 'password'
EMAIL_PORT = 587
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
SERVER_EMAIL = EMAIL_HOST_USER</code></pre>



<h2 class="wp-block-heading">Backing up the image</h2>



<p class="wp-block-paragraph">After setting everything up, you&#8217;ll probably want to backup the Docker image.  First, print out the list of running containers</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">sudo docker ps</code></pre>



<p class="wp-block-paragraph">Then take a snapshot of the current running state:</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">docker commit -p &lt;container ID&gt; &lt;whatever you want to call this snapshot&gt;</code></pre>



<p class="wp-block-paragraph">Running this command lists all the images and should show this newly saved image:</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">sudo docker images</code></pre>



<p class="wp-block-paragraph">I don&#8217;t have a private docker repository, so I saved the image to the disk and backed up the file by doing the below.  Just make sure to actually move the image to an actual backup location.</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">sudo docker save -o &lt;whatever path you want&gt;/&lt;filename&gt;.tar &lt;the name used earlier&gt;</code></pre>



<p class="wp-block-paragraph">The image should be backed up now.  To restore the image, it&#8217;s a matter of running this:</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">sudo docker load -i &lt;path to the backup file&gt;</code></pre>



<p class="wp-block-paragraph">Listing the images as above should show that the image was successfully loaded.  Running this starts it back up again.</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">sudo docker run &lt;container name&gt;</code></pre>



<h2 class="wp-block-heading">Troubleshooting</h2>



<p class="wp-block-paragraph">Seafile logs can be helpful if it doesn&#8217;t start up correctly.  These can be found at:</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">/opt/seafile-data/logs/seafile</code></pre>



<p class="wp-block-paragraph">There may be a need to ssh into the Docker container.  The command for that is:</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">sudo docker exec -it seafile /bin/bash</code></pre>



<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.henrypoon.com/blog/2019/06/12/installing-seafile-with-docker-and-apache-2/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">3509</post-id>	</item>
		<item>
		<title>Copenhagen</title>
		<link>https://blog.henrypoon.com/blog/2017/09/17/copenhagen/</link>
					<comments>https://blog.henrypoon.com/blog/2017/09/17/copenhagen/#respond</comments>
		
		<dc:creator><![CDATA[hp]]></dc:creator>
		<pubDate>Mon, 18 Sep 2017 01:23:54 +0000</pubDate>
				<category><![CDATA[europe]]></category>
		<category><![CDATA[Alley]]></category>
		<category><![CDATA[Amazon]]></category>
		<category><![CDATA[AWK]]></category>
		<category><![CDATA[Beef]]></category>
		<category><![CDATA[Chan]]></category>
		<category><![CDATA[Cities in Europe]]></category>
		<category><![CDATA[COM]]></category>
		<category><![CDATA[Copenhagen]]></category>
		<category><![CDATA[D]]></category>
		<category><![CDATA[Danish cuisine]]></category>
		<category><![CDATA[Delicious]]></category>
		<category><![CDATA[Denmark]]></category>
		<category><![CDATA[EAR]]></category>
		<category><![CDATA[Engineering]]></category>
		<category><![CDATA[Family]]></category>
		<category><![CDATA[Find]]></category>
		<category><![CDATA[fish]]></category>
		<category><![CDATA[food]]></category>
		<category><![CDATA[Force]]></category>
		<category><![CDATA[Fountain]]></category>
		<category><![CDATA[Geography of Denmark]]></category>
		<category><![CDATA[Geography of Europe]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[herring]]></category>
		<category><![CDATA[Icon]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[IME]]></category>
		<category><![CDATA[Installation]]></category>
		<category><![CDATA[ise]]></category>
		<category><![CDATA[It]]></category>
		<category><![CDATA[Lie]]></category>
		<category><![CDATA[Light]]></category>
		<category><![CDATA[Link]]></category>
		<category><![CDATA[Mech]]></category>
		<category><![CDATA[Mecha]]></category>
		<category><![CDATA[Mechanical engineering]]></category>
		<category><![CDATA[Military]]></category>
		<category><![CDATA[Opera]]></category>
		<category><![CDATA[Over]]></category>
		<category><![CDATA[Palace]]></category>
		<category><![CDATA[Parliament]]></category>
		<category><![CDATA[Pho]]></category>
		<category><![CDATA[rice]]></category>
		<category><![CDATA[SMS]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[STR]]></category>
		<category><![CDATA[Thou]]></category>
		<category><![CDATA[Time]]></category>
		<category><![CDATA[Trac]]></category>
		<category><![CDATA[Travel]]></category>
		<category><![CDATA[Urge]]></category>
		<category><![CDATA[Vol]]></category>
		<category><![CDATA[When We]]></category>
		<category><![CDATA[Z]]></category>
		<guid isPermaLink="false">https://blog.henrypoon.com/?p=2750</guid>

					<description><![CDATA[The next destination of this trip was Copenhagen. Someone told me that the pastries were really good, and they were totally correct!! This is the Danish Parliament building. They also allow a small number of people to go up to the top of that tower for free!! We did have to wait for about 20 [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>The next destination of this trip was Copenhagen.</p>
<p>Someone told me that the pastries were really good, and they were totally correct!!</p>
<p><a href="https://photos.google.com/album/AF1QipPXard5bpmDmsFwHXxbYVVWBwoZvMq8M2vhzkze/photo/AF1QipOONAtpq1P4YXvSRFb7sP59tpIEXPaZzgaTMKkO" target="_blank" rel="noopener noreferrer"><img decoding="async" class="aligncenter" src="https://lh3.googleusercontent.com/EQvFque_2ehPLX9PBZeVw2xucsxWCBV_hUrc-blP6oHoJQq6FanGy9USDDE0C87yXE4gEiBusu0YXUTFaE2yFfMU0D06z6odGqBN8ETyl2KlOTssZnPk41FdvrBfxGXcEysiLba_qXMt-twCIyukE89wkqwCvuw-4egmXqH-Jza4J49Nkqp4o1uMKv18ZZj9ZV7mgt5h1jweVbvPBtvM1__TjXa2xAaBQKf7evi3P3GqcwqH8k_QUVOFKb0kGESf_J2OXBaN9EHZfUbiVVfXcIAYZ2ief0KEiGJDA7YwE8bpJyu_G_a2EoUHsOEXObNuO_M_F9_S8lIPo_WK7IzWPcBlO2zdBn6gkHn4AdDSFLdf-gG68AxC_EcIciRG0XM9Qb44jWAMuCsyCcA7DBiTOl8SgP1MiLvNuzuGsfcrhjqcwzEMttQiHIWV6vyZ6fX9t3V0Sxq2XqSq4kHlMBbO_IAXI_FYIdYrFAO6ltFsQNsvV1plBdlHxgoNpsUnyl5Z0f8gfrxcDzCRzbzir6f4SFNMxg5RR7ANZrhj3OSBdvzK1YzhCvqLrhF0W49SeJX3FhpiKS0tGi_vtDaLk-bnP39rceiVYHkMzLD4cIG11jU=w1680-h945-no" alt="" /></a></p>
<p>This is the Danish Parliament building. They also allow a small number of people to go up to the top of that tower for free!! We did have to wait for about 20 minutes though, but I think that was a not so well known destination.</p>
<p><a href="https://photos.google.com/album/AF1QipPXard5bpmDmsFwHXxbYVVWBwoZvMq8M2vhzkze/photo/AF1QipOK1I0MaKd9-gBJpYf51oNsI7o3XlxkLdziPQg5" target="_blank" rel="noopener noreferrer"><img decoding="async" class="aligncenter" src="https://lh3.googleusercontent.com/lN9d82z0tH29_kEFaZe0fUrE_XlTCk0prKjFexMmyoe70CYpXXUVbgYi4bxxl6qCDJReuS0ULg-lRHRNGoj1HInPsLf2X0B1o7CT7ZSaCvTZgd-tRpp7HWT9uXN4iKhW4nMb689Few-8eF2oNetDK0Hp2D_WolhcorLSQbTd64ABxFkzwuy2wvfTcnK0Jc3bmxF-G-OpTwfa9w6LvON7Bc_2Mq1ezKN9oY873GWRlp9EXM4W9rS2XPybSX5xHZ3Bbjg1FhDHunlRkGqBcmDuQOKfmeF0KW9RaFogeCWO0tz5mkYrJETBeMEzhbPNoW3feVm23FCSiB6LVxl21YrxJdqaTxqlmATM5e6RhsHqGl3CN6ny5dRBz1EldruF20AG88P9oOu4YgGAh13FN72zId7B300zF7qMEk6HY0aM4W4Px0rx9TZhIm_6rRRB1vn-bGlf5R7bQSqJVHi5L_0Ky6Fw2bfXjhPFOrWiNk8OPteNDhWCetGkGoUEbTj2H5a2j7VAbH9kpIuEiXnMJ542UnoKlUmxQsrGayWyJn1kd7EKtDtWHxxZ3puJI-zBx-Wkih5Z0MScByUyB2aqLkC8eHBJly_rRz4cW0BXdo-e8es=w1680-h945-no" alt="" /></a></p>
<p><a href="https://photos.google.com/album/AF1QipPXard5bpmDmsFwHXxbYVVWBwoZvMq8M2vhzkze/photo/AF1QipPdY-I2gcEuDSvoHs-gaO58BLhajt_mlG0XMfLa" target="_blank" rel="noopener noreferrer"><img decoding="async" class="aligncenter" src="https://lh3.googleusercontent.com/-AzdPhmZIZBzUlRdgJMkrd38EozqurGNXz5hfUjClTrvsI8dMT8ucEPfrQsFQ1V4gIXqWJp-Y0P5OSaCDN28D_Ae7t5C3t0mjjPppt_Q0_b_io2pW-ieH91xd3aWBQK1gHr8QHeNxlV7VFsgedxuRCIovtIZUq7zHqzbJzjcuymx8tsWj64pqTIrmVTTO461m1ryzNxSZfQoS59G-FYCPkrMYxtlOe4LfKHLlTe5Y4VHjjPxrTpW0nPhpYVV_SlIUCOp79hBi_KXEqfXGZgn0KatOigYIs8qDC2Z6RRVsDfQCrF_O2dzCsZ2niz2oyigKT5yLl9zF5Jpw9L5WI5jNRI4G-yD-tmtziYyTH2hTbQrhGzVSgJi4qQK9I3DP890N9Pj0QVLeVUMPIO9a9I5hx6mLeWhY_kkV32u-bn5gDm6Qtkr9UT7Lq-Fq9Z8dGeHqT8M1wWn2EwTfTQXBJ4rQFE-wNf99VeRMso8N9EoBXVoe4SQW5trSE1XFON9qDoL6x5IQ-Lzw5LN0gOg6-PK8oWrJfV2sxLjSKA5ERQGjg3ELchrSBEuaqn_NZetqpHPPLLy1sCoIklLdhlKA3WzWADVcCl5_KQJopvsyvFVG3U=w1680-h945-no" alt="" /></a></p>
<p>Everybody says that Nyhavn is a must-see destination. It&#8217;s definitely gorgeous, but everything around here is super pricey!!</p>
<p><a href="https://photos.google.com/album/AF1QipPXard5bpmDmsFwHXxbYVVWBwoZvMq8M2vhzkze/photo/AF1QipN-XhlJ_bBTi02tMG8u-YFYhOO_oSVUEmmtTyI7" target="_blank" rel="noopener noreferrer"><img decoding="async" class="aligncenter" src="https://lh3.googleusercontent.com/3dfhiSu379X5lEGqrMlmsDaasHCdoij9V5MOb9r1SRTc5JT_oFwV3wnWC8WHorW-a3gQm8azU5X26wisB8E6CxL29Iuu93EkDKa3xO2JRyO5huCbODAdSDX8AgwZiYAsswIz12ZdzopHtHQqFAe1QF6pgrlJITJ78Gw9t0clklAZK7D95mvU2gt852pahae3OfXkrVxMStfwP-E_ZyP6bd263stHG1eUkcvJl4hHFYRfHL8qxRcUJ7vdoewCc581J_ybAvIre-g3hgqwmbrGanouPwxasMje0CbZHxcujZD6eZpUzrDCBEqnI_9GYDyZjO4arAn8Naj-qVtTDU7Wm3alUlQRRdIItZj3feymnX86g9IQJGnQP42PgbtPEpx3DwnX4Tx4qtPK4HANaNeRTxx1gLAuXBpvmaH7RQhkl3thQtWc8muWVF8WyhLfimFYP2jNPeo-kRAhAiZsEE5qEL4AOIwBu9B2CXEiKWKdER_GIcGug_aFVwRmzZAJyx8j8pV8VIFXwfYRPKmK8jSwJq_Ay5rw2fRf5fqfGExXM30DZMOb-iUFfm1MrtN8bxHYE_xhyYZ_9sqWZ6V-g6jBnk9ZrWqfpqqzBN7IkkUhYSE=w1680-h945-no" alt="" /></a></p>
<p>Amalienborg is the home of the Danish royal family. Sometimes people see the Crown Prince of Denmark going in an out of the palace dressed like a normal person. The building with the dome at the back is the Marble Church.</p>
<p><a href="https://photos.google.com/album/AF1QipPXard5bpmDmsFwHXxbYVVWBwoZvMq8M2vhzkze/photo/AF1QipNNoq8NDIpvEDEpWkxcbo2M64q5eD3X1yK4si2h" target="_blank" rel="noopener noreferrer"><img decoding="async" class="aligncenter" src="https://lh3.googleusercontent.com/vQ4bflCoSFWJ0PKLhjfeiyPneCTVXRXvYXfyZbe5ePoDlDFxUW552OndvN9Ivt08UMIt7GVS3btI-dxjBoWBnN4rwqPEgqO4xZreLiHJG1yc64nHtnzRciiHOlcSOydZmwwTUMIO1Nw-Ot0_Oun8huVPUpr724jJVc8bBey9BsYPL2I5NjugllWsSXzz2MO144PFynxowrl0O6mGAfjli7LBLKl_GjLTuiN-r_YeCxr7Uk09Jp2uTvvqy7jcNW4IyoC2ejQHu8fxYmMZvRI_RTSquA1jyd5opZWasfrYQXS7p7nR5k6fniaYSD7ZsIKzywTpqR2Q9DQJ9OAcz7ILCFSkwLOjAg4e4L44KGUdCVEB9kkJ6UrsQBuT3TlEfaawvVH6sTv6mqW-jEMFpjxD0ZkSsz6Ht_jVAuePfwJkuVobivLFtSWL4DeQbUntrxxgM3I6fnDLaCITyD6Ak1TnGHykfscUCh9exmHPloMrSq0WodJrgel5mhJQYVDxq1X70SAVqslkrR9PtgAAHw7qg7WW7QtYrPFQktkCE1fHUYcHu420pZIDO96RFyjKeAkBcNIEy_GrxnBQ3psYfZUD0hXrJg3F_91lQwLwAZCeKJE=w1680-h945-no" alt="" /></a></p>
<p>These palace guards walked right by me!! Can&#8217;t imagine wearing the full uniform on a blazing hot day&#8230;</p>
<p><a href="https://photos.google.com/album/AF1QipPXard5bpmDmsFwHXxbYVVWBwoZvMq8M2vhzkze/photo/AF1QipPOZovNusCxPS4Kj64gSaprLpPldk7rV7ddKnTi" target="_blank" rel="noopener noreferrer"><img decoding="async" class="aligncenter" src="https://lh3.googleusercontent.com/3SbTC8arRE1d6sK7trgn4ijYl8MBLLkbOZPXR_q2VqmA6dOKYpD3NCb7DKDglT3ZrlM9_Nu2nW179bvZDgOWjX4sdn6s2pzu2BBdb6c5psiSAShpZjIusQOUpr_lPXcV37c9Aq36-wWUwYUQW1lf3KRtKIBxWOIf70O8QmnzWskenbiclnJnvezhpf62XG3sydg8CF4lIfpsUuc7lXj82s7dVoZwnRSsKOIofIwHds9oT6mgG3_13q5F2e-xsIi4qkbAS2y-H07x-IBxnTUfBvsGVmL_iZn1xcQKfEEpWntalc3ZhhZrT4TZiNkmNJ4kWPcvRpMLKxWhcS6FJbeNhcThVcKn0dhoUkhO3rHKD7yu3OjsgP-G1BM8DbOAKRjURJPFsK0GPa-FSmtJiWl7rNW25cw8uUA2OlkQgZ_TQrKrqS3Vghhcyq1yg1w8ReBJINvhU21DaBf7vPEqkqstwL2unZ9cH6fjgXhV5QpDZ9L4FCQHMJqdI-Es_MEtZAWtWzKUksl-Ca-wU1c1NpgMm4DXn2wH3QRCC955YIdHpdHuydBs1fU3yVb3ggOUq3hT_-ipbp6CtE5PyxrSYLrTtTZmSgsbY7YMsE2eCcbyhL8=w1680-h945-no" alt="" /></a></p>
<p>Next up, was a chill bike ride around the city going at a slow 10 km/h. The weather really cooperated with us! It was a weird change going from wearing a full bicycle kit while riding my roadbike to wearing street clothes and riding this commuter with a basket on top&#8230;</p>
<p><a href="https://photos.google.com/album/AF1QipPXard5bpmDmsFwHXxbYVVWBwoZvMq8M2vhzkze/photo/AF1QipNhxZ2GaNW-PGMWruxE2A03kFHechFmfXrIUaYC" target="_blank" rel="noopener noreferrer"><img decoding="async" class="aligncenter" src="https://lh3.googleusercontent.com/E5pmF9Wgknmd0k06tIWsWfW871-Yp99NL_9mb-LWMi4jtTO5cYMeSfqeDq6QKFLkWJqXy0kRyqSRJItFrvosjfeSNWG4XHSbSzWDThROOTqwtTECCso8lg9ogxYLRAjdlLQDScIc0S56-wFEe9Q1haf3H3nLTFx_FtyLt3dXrAnDL8gggBn1F8Iw8h8ahWDYBg2mWRGSm8KdQCxAa16zoZuk-mPW2aSVRucZ6jlUJXtQnGS4mSYr__cLPGTChRAIKnRxM2DP0v5NId1g3iz8czx_uagrXuxskXIWFWTeLqdq-wqh2-hdvD99bZT7i6C4u4CSwakG4psnRZmH6Ezz6R3gZCJs0jDufuRO3JjdYXXRprV5jojaFKcKThv0r5cg-veY5BN9ez25l7OEPXmMT_FIV8INQs2p_bprb9MLaL6PTdp3_7dmljpFoXBymiqQHd3XPMiBEQW9DYPvG1AgYHM-KyMKQFCGdnvw6AGaDWxUhJ0HUrDAqzR9JJ-ZbLGKdqwl5FjSxvKHYW_WPEFJIGIjrayaURY-E6qsen7X1BQ77wrkakUXy4Ywi_pRAP3OEzB_IqOFqlJ8C3Wm0TgdjiICu-YSqoQYmD9BPbUgPgk=w1680-h945-no" alt="" /></a></p>
<p>Randomly stumbled upon this really cool looking fountain, known as Gefionspringvandet.</p>
<p><a href="https://photos.google.com/album/AF1QipPXard5bpmDmsFwHXxbYVVWBwoZvMq8M2vhzkze/photo/AF1QipN-gCWs6MTSRJZTXMZH-HAElDGsbnhEu4wWEBEj" target="_blank" rel="noopener noreferrer"><img decoding="async" class="aligncenter" src="https://lh3.googleusercontent.com/zPEAaChWLasIHd72UAIRs9vk1F-KKbWp8wuZ3LKcUk5K-_mKzLK9dgsN9QXCTngyw4En77Nb-X7ZYv9aqRBy_8I1S95yVGYYcbx2efNOQ-FXEpPvMXy-O4oW-AfnQ-mNiy6eSNbBh69Xo0iN3_jeCU30neN--k9e-W0FbY0gtqKXJAwkUBCGJ_HQ5CSazc4WWRzNp9yPvz73iekR2yMkoOlA4ar1aBOiPFmLoJkHFjXykSXgy9oW3F1rqd2G5X87rN3M3KMxceXW-UoFtyQ8rOOLDU7y8tAGKx-Z2RunhthtdabpRtQgBOzmoGcwP1-4MM2pb_Mk3NLr4okcyX6uhsNHxE4PMyNiTCB9ctvDCJ3tuZYW9sOKD4CwvY3r74GamblvmDY1LkzmtaTXc14Scd5UPVjRlrMOoSiepl8aekU_0MXcTufj37pDFReFgtV8d2LX20PTVazfawiKX6TL1k3gqvhbHFOTIU2x9XA4Hxn657ZjV0o_qyzNWNNOQJ2tv1jZWMcsfv6uWIT0ETEjUW49win6cEjudIpxWrBkzDiq0_wVPkFYM5i26dolVBKHyFFD1OtxNky5iiwAZrOIXCfTmKXxHutxIzzP9CATb7w=w1680-h945-no" alt="" /></a></p>
<p>We rode through this old school star-shaped fortress that has been turned into a nice greenspace!</p>
<p><a href="https://photos.google.com/album/AF1QipPXard5bpmDmsFwHXxbYVVWBwoZvMq8M2vhzkze/photo/AF1QipPNcYRnVjtfpDI_07gVllbaUiMIluq9BKLnSbac" target="_blank" rel="noopener noreferrer"><img decoding="async" class="aligncenter" src="https://lh3.googleusercontent.com/W3bdWRISkv9GHFaNf-fE0BmYxEZZo6pY1XZ2i7gErbdOlNBAXY9RSReqJrzaN6VFcqT-uN8QgMHPZ0ORFLpUroZaz1tCtGZX4yalh7XW5zWhj3hEXmcF5S0jE8RG4XC9yibi2CZZIl6OsZ9Ff6zrRduJJpQCWjuCqSzi2IC8mssXLkhpp8rn7jlUkhXoxuxgCBAcxMYvSApEHC6CN2dS1NMlBmtJ5Eg-VLLur4-hAlgyy20ucLu1fII8hdK6Zq6YFnXLAY92owN9W2YYeZ9Sthccz4x9tOEVsICg5Fb-gfMUnA8YOwjXiuUBz_zBNPEfxr5ki_48tEJUP4IpHNsDe3yy_oiVXBxfgZX3ihN8YCTpIAo55petg2N6qbk_W6s5ngDqnBIZXmQ9cZyUsNRhTTxiwhaoV8GINAnG4-ClKq4uhdhBEOQ7eSX_KiEpoONhPzgXmt1iAcxt4UlQavY5QteL86z9yLlfZxRoAY6-l3KNnFCILD5r_fCuTOxWqT4jx-1zHNcLr8KF7T9YMfAXjq6lHaI6KjGd6vvISiawFMXZ8sOw8JalANji9AdtsIfHl3gN928CI85jANnyeRH3lOd91ocSHO70uMEnTu4qlYw=w1680-h945-no" alt="" /></a></p>
<p>North of there was the Little Mermaid statue that everybody talks about. Everybody says it&#8217;s a must-see attraction, but the most underwhelming. They make it look so big in the pictures but in reality it&#8217;s tiny.</p>
<p><a href="https://photos.google.com/album/AF1QipPXard5bpmDmsFwHXxbYVVWBwoZvMq8M2vhzkze/photo/AF1QipMRMgRQpusWO20s24fpn8kDH8c9Ayy79nOM5vfM" target="_blank" rel="noopener noreferrer"><img decoding="async" class="aligncenter" src="https://lh3.googleusercontent.com/34HqgyV23kORaV0ehyp0gtJgQKx2cPl_4EDB2LHGhnr3vpR9RBq_INOiiNPLxp4F3ilvhrys21zqrYQxy_saTXJVE0FoQfLzxQ3nbEi-Y7c5zvHcBDDDka9z8OOSpEbqjN1j2t7OTnfLNFQlqz3Am1WBWMIBb-XZ_Xq0LBxz5JY-73YCafQtT3argTb73S1BvNW-8hvNSxV717C6ldZOi0VvlJYIO-2XmzIzGngfkq3KN-wlhfQ3-FNCLhNMsbLOXmAHj57ZV8m_vh646lvGxmVQkt5vSsOOM6Eoct2EItGUpXX1CiNydqrSQinnahysBi4NmqR0FQV3WbbhcFRmg9YgokvY9bhtXMmNp-VWcYKVpJiYuGG35GnrsGp4zADvexvLrOe30tPawA-G3SyeuxLyddcqe8c0LYGg6UE-tJO0w61Bt9WBRUdtpp1hO68qe9LyH08mga_vWAolOR7O0HG75_zbZQaCa7Pw-rmKMKI4-MkaFmmkjnx0gXzPvegYL9-QhrNi0VzyUXpzC6A7QotR58C5T4A4Qz_u6K6zkPw44YPzhSpUtqNsbdVY_HorigFumWelOXqxJOFvP7woF8UW_gayj0f-qvbDvlGkzNU=w1680-h945-no" alt="" /></a></p>
<p>We rode past a military installation and saw this interesting sign&#8230; They&#8217;re really up to date with this drone stuff.</p>
<p><a href="https://photos.google.com/album/AF1QipPXard5bpmDmsFwHXxbYVVWBwoZvMq8M2vhzkze/photo/AF1QipMsJc_gexWXNcNy4MwP69tjjfUh2---Lxc2_XBS" target="_blank" rel="noopener noreferrer"><img decoding="async" class="aligncenter" src="https://lh3.googleusercontent.com/1SLXC-L4ROaOPAoTt8SLIEY-sAYk-7b_SIujVRI2i5X3Erp0zN1-PmT0PN7JsKNkVkJyGAWUUh0q2zATCCPb6hrVocxBLxdn1cM27sMwuxkGZ3SsmxClzWV--3OE1zJjGzDxPaF-NhCyCPf0wpg-sQukuRvRUvyZPCQmzcfkvVQVeC118mY1RYhAb28EZTTSUJaG15AlfqLyDchlj692z2MD-XO_HNVvLbu7UEQ4WzEwbEoRiADl7gyNoJk5Q_aGv0SlVDzUJfrnKYVTbcfRYqraYhqvo6k9RSxLx5oat9ZI6r9cUhcIHs8JYkHTy_HueCbgMVxT2pvi8tcz33wpd10Bm_kugLjPjsbgOvFw_IOAt-l2JML3Xl9Ku-6ddBHL_8qh25VYYcXyx9xIOEU6jJdPTAfB7axeGAFtGwTjo14D2WLGUdg1uE66z_h68AX18c6g15cZwmkv0VfodVTSzsprLUdQq0C_XA4ZiTR3wvLKtFaDNEoTfZonAahXkijTTt6GZTV9ou2lYx9bTozLWTEiYkPyg5fgQQGndoVTvNBMnlYKNOFzjZORrppBLTvb-QMAZB60R_ASIofdipYxUQO6bGlOwbHJZBugQkOad34=w1680-h945-no" alt="" /></a></p>
<p>I was in Copenhagen around the same time as Chester Bennington from Linkin Park passed away. He even left a mark on the people in Copenhagen.</p>
<p><a href="https://photos.google.com/album/AF1QipPXard5bpmDmsFwHXxbYVVWBwoZvMq8M2vhzkze/photo/AF1QipOC90c_WEus8v4W29SV8S5tU-f_PzoD1Lp0LtHo" target="_blank" rel="noopener noreferrer"><img decoding="async" class="aligncenter" src="https://lh3.googleusercontent.com/97RkojwfT35SkKtP1jsm8BzWIPWg3Es92pQxsqjzaGOmqjDV41ojbIfnKs2R3v1Jm-x-cMehltvftBDYOx6HmqrdlzpXakVPMYIxEOfNyAwgnIR2gG_Hx9FaXDWRhIO7patmUPCgYt_tMGsBQcXd1nK1fQc8ceyq0jS-g-dDT8EhY_S_Wu3RqV2IzU36vZmejiQXi2YUJsltIxSS7-86sJqgzHeCkO7fnBiWDxH3ihinouSkkiiY5X4SLCxh10BE6w_wN7zHgiU64FDNZNCHDBKSm_0r4rh60LxhddaTTfJBMfmFliV00wUbgIEcG8ioFAK51mqAWEoTpl1wPSG90iOHCumPn1y7hFt0xho9YhPsc9r75uL30y_thUFxr6u-NfG47lV-ZDctX5NsnpmQkPIw3RuoAqeckol6Zx3nlgbwRegVtdod5BdmvwCouHNh9IGfQwWhnenDy0_oT8ChM3s_xdyzc0YykCy1JpNgzyCRoOaF20gPsWwu703fKcKwHw-lh-PO_M4eB-x92kVHoPLbxlBEO98_wh_wGi5E10Ht1BMxaUPLL0EGBKWPwLddTI7OYViMbfLByQKoMi6k0YV7qYn9rMsz5duNrVYXbso=w1680-h945-no" alt="" /></a></p>
<p>There&#8217;s a reason why people say Copenhagen is the bike capital of the world.</p>
<p><a href="https://photos.google.com/album/AF1QipPXard5bpmDmsFwHXxbYVVWBwoZvMq8M2vhzkze/photo/AF1QipPoZLuB9rDnunlbkd5ZivTxiKP_RDvfBmnV3YJE" target="_blank" rel="noopener noreferrer"><img decoding="async" class="aligncenter" src="https://lh3.googleusercontent.com/Lm5-YOwWPbI885d-DtSVunX4kkTF29Ps_gyitzULBMB8BLgHY3RCtzSkCowUCj2J9FdILlcIwMvZFQS-PCP0qk0SD8gUdTfnCGefmiIcDVP7bxxyyCuNtxjFkMH-HoBxiSg1tZF2UWxu8h9Q0A5c7bJJ5NGsICC34Q4YwLR087-_sVyMjUSqzN03-lqbgA9HFNj-O9m0ukMfwZ2rxc2WWwR0aYqwPVr2lN6zjh8DKBjGj0PruiKDuaxWfGq5RF5ElrG1YGRYgov7JhyYSNTp3CxOFqPTR85h7qD1yy1QwQTnDm8IPyoylGDi7CZdAPucFb9_bcMkCqL5VDTo8MP4PqDh4BqcX4HESrPoZWKAELzDGQIn4Nva0aXbyRJVkr1VIHYZFLG0idFgHa1bK18t5LFbA8y6jYb-1vZGVge98mMdsSOvxqqvMowUv9cs59-TtZbkR5KTQchPw210c4N3yAxAjWQ6vBhyzJ_DX-vLYHJdsAX33Rv_0LgEo9q03cbre9O_LIhyhAIZLC3xjvc7N5BLlHEyD7IRu1ez-cntznZ9At-TVbbtKMZNWM6eWmV3JQgNeS3PavP9RgrH_w1kIce7mwIjIEhJ2MoN5diayGs=w1680-h945-no" alt="" /></a></p>
<p>The white buildings in the distance is Paper Island &#8211; a hipster place to hang out and eat food.</p>
<p><a href="https://photos.google.com/album/AF1QipPXard5bpmDmsFwHXxbYVVWBwoZvMq8M2vhzkze/photo/AF1QipMpZYji65sJF4BCh56uJXfsGHTj8YypG76f-Tg7" target="_blank" rel="noopener noreferrer"><img decoding="async" class="aligncenter" src="https://lh3.googleusercontent.com/6ilmptAerh7FVAmQS-HKCingT20ya2_IyF4BCCuj7seexj9hvj1Lin5a-hkpm37ehP_-ygEpQ2ej-d3Kdi3IR1vMvY1R6lDPsBuU6IdTV-S4C8MYl30aufaRkqxUZKXsdvYyPci-e_cGckdMuzKfsLkZA8wFx2nVfhQ9MDt-h-_nIzh4EAnX1gXd-RpFZI-1NsFVEgAcQlAVpQ9IZoN4uZaOknS67tPKfixi8_K30WPBIqW8nCHlGlwQynOBY0J_QPhl3aTWz2ARHrwlPuvjAjZE4eqFzAj2TnUtkpMTB65VW_0Fvs9507BizXO0Psp6KXmKk9FJLkkzeR-jeDLVu2I9jyuc-t64_xFeay_wH3VIhaxzqXki88cppPrPM8exQF5E1eWthOjdvNF7dvk30Ji-Yc4Z6gCX8ylZZX4AMU8ehtd17a1V8Lnpqud490G_iWRA1Yxmn3AcZXfem7YXMKsP2WCj-EyqZxTWOPJ_aF48G1eCrdtw78b5VI_YEuKwEX4OQPNFb1YIrrLFCCo8yk4OEW4mdMNoqlOSvIo7sFsuErdXDpVc7Eu3K9EIHzDGq_BNypctaJwZYu_5WFppWs027Ryb4wImf5qw0Kf_J1U=w1680-h945-no" alt="" /></a></p>
<p>It&#8217;s so busy here&#8230;</p>
<p><a href="https://photos.google.com/album/AF1QipPXard5bpmDmsFwHXxbYVVWBwoZvMq8M2vhzkze/photo/AF1QipOFMStrWQuka4WIq5y3Qm8pIjOFg2jOyPK0pglo" target="_blank" rel="noopener noreferrer"><img decoding="async" class="aligncenter" src="https://lh3.googleusercontent.com/ePfPxjvnGa4TNID2aMLUUkFixzchvkpWl0-FSXWn4AU1167Os4sqPL0r-ISYk3nlEUCuJOro4V8E8N5-U5I8gVp_C1td0kTSl04BelRIc6hvkafkGjpNBzh-SIzvMxMv4ODt7EW1jCQFJ10f3XGbYxrpct4LF5AcuIzCGJiQzEqyiSgoGRlwvWUhVZJkqdGVoV22n6qQstRN3Tx8zaShX2EIaGpT_v502vH2ZkIi4jXR1LjI2iSR1pI-l9YjTy7HPHdhbqZ6zCydedz5XSEOpGhkqffNVBncEH6lWBVRBVNXFZO0ZayU5RGRgE8RmedVNEFH9FWXwufURrMf1J6fEmUsmVijFxBUC6S6ARXXkC7aZ4eCpUQbgIQtbDwGU_UjZ1vbHYEqQt_w8oYwkX3hJcOOImqfp1dTWdP4HR2ogZof2tvV-WbLlymd3kjph4GOrSLi5EnWtbg6cya4AhWQYNxviMun5wwMaFyca0frHeya2bdqsPoq_7wyMDJaUiW05DmQsYwF69j_dY88qCczt69C6fxyjwKyaZiutYgzXQghsXzjUgQh6qspI0eD0scKopYUJcmDfQuPKMe5h4awKslfyttyiBF7etS6llp51ys=w1680-h945-no" alt="" /></a></p>
<p>To my surprise, I found an ostrich burger&#8230; It definitely had a light taste. I&#8217;ve heard it tastes a lot like beef, but I didn&#8217;t get that impression.</p>
<p><a href="https://photos.google.com/album/AF1QipPXard5bpmDmsFwHXxbYVVWBwoZvMq8M2vhzkze/photo/AF1QipP-7GOS2_4XOAZbIPlzZegUYOycQKXthdMzKdZV" target="_blank" rel="noopener noreferrer"><img decoding="async" class="aligncenter" src="https://lh3.googleusercontent.com/aY_5wInZbvF5WGsyCLMvR9_LAIzkvcZrqIS4BMHZawP3IvPwMnz2R_bid4zajiIIFhlP3nHVxusC2JgWL9OX23GcAW8Emu4Qu3tORykE8eEyq0Vg9T9amuunKghXi0_khf6zHPP-79qnQBOOUAb6rNf9WuY_2iC7vwoXRR0NnxxIV0X6a-WyLjctMrOEfXgON4pFDuwQFCA62he-RrhnlMRAKmmTM6qzwznhk6pgl2uXaRZmuPdYbZ31QoAi2vlLGGhYQq3O2bdQDQU2Nvd_6mXNNLuwtEBVNB7abt4r_d0WUdokJtvlwAPBlqVE6uWBy8eLgthoJJYITIxlsMAhqBeITN1-TZqvx6mm_r6Xw_QAf4ZV0JH4z812JJlhayt3FF7scLa2HyNBzVtrnq_76WCcHvlK_8kaHSwtKI8CVm76K9PrmrIaBJsbbkabrvWCKzA0fktz5WNOzdRyjqSR8BFtTRSV1aiNdzrBBRGdjYeZVsHIQOJy6ylD-lnHqO9IS2PCu6btpp9uec7wqEaAJvz-c1ti8ZfjdoGIGHN0PfmgtlKk2iMKjE0eXX7e5l7G8-bhBklf2-EdYRYFYkLRRFCkOlsXhowY5WWnkhcbpVE=w1680-h945-no" alt="" /></a></p>
<p>Next, we went to Freetown Christiania &#8211; an area that the people there self proclaim as autonomous. The area was formed by squatters on land used by the military. Today it is a kind of like area where the police in Copenhagen don&#8217;t really enforce their jurisdiction (although they can), and it is governed by the people who belong to that community who have created their own rules. All the houses have graffiti on them, the paint on the walls is slowly flaking off, and every house has tons of advertisement posters painted on them. The people in the community are either hobos or hippies and sometimes it&#8217;s hard to tell which &#8211; and they&#8217;re probably all high as a kite. If you&#8217;re looking for a wild party, you&#8217;ll probably find it here. It&#8217;s a shame that I wasn&#8217;t allowed to take photos inside.</p>
<p><a href="https://photos.google.com/share/AF1QipNkYfH28ilamlJHJy4FHm0bdyhDF7bAkYfOMsv-fMxoUFp-9BUnvyjjJl2oeogVuQ/photo/AF1QipPVh6tOOqxFYO9XWLuWz_1bhqMhRFbYrLXez7Ot?key=LWRPdlFhSGRSaTJLeXptczdaUlg0OF84SnNub0NB" target="_blank" rel="noopener noreferrer"><img decoding="async" class="aligncenter" src="https://lh3.googleusercontent.com/8iw-t9hkTbqY_8HZQoXXID6C1IVdPibWUGAoMPN7rcaTtMfON04bYAxS3k_sYJEMEpHKCCufvSFa7MspSguhRYMxrzTsdGK9UOiUXJwNLSV5gWyQYS2KV1fuUGK3yWpYubKFoSvgGYx-gHmPV00kOHt0hK7ks9CiVc5BoRgL5cW23g_CW1jXGyAIj_rlBNPcHsCTqicG7cKF2JSKxkzqIB2l_7GoluIQIUqQhcBtTqOyPJx9E2g3zfkm7yfAMh-eNc_O0eIhHsQEG3RG0RvneEXU5NICwPEoTt8-ZQOSqum4gD-0Vkf6h5JO7eg7iXCbVuO3iF-LdGJorMqcyhSXtBfZ9C_ib3dg4RTHNFwCivQVUDLm74TslPwcAqYYbPMVvHy122uhR2ipLubwZAsOD-99DgDnUeoW_vNNII8MZcnwp9X3Rs4leDviz4cE_DNvkk_-yi8aFWmQex8yrDV2K2xZjr9-oYJ-qZkAkFWJhfrBMev7KyfK53fZwiQ2_NqkEn5uzq2WQfP20v273deirAYfNcdaR-HOuNqrVLsDfiNN2ElZm_snWHL_wktSzgwLu6NwQmO5k3biMvr2F5vtn3tQwuCl-EvYc6gKp28eLzygsB7olwk052YH4_uIELNM-sUASzsHpvu4hlvPyPOqoeRJtVKchvOmWBKf=w1285-h951-no" alt="" /></a></p>
<p><a href="https://photos.google.com/share/AF1QipNkYfH28ilamlJHJy4FHm0bdyhDF7bAkYfOMsv-fMxoUFp-9BUnvyjjJl2oeogVuQ/photo/AF1QipOlThscjPIUOdmFdqMYerftGzeAyyKYCxnkXO5a?key=LWRPdlFhSGRSaTJLeXptczdaUlg0OF84SnNub0NB" target="_blank" rel="noopener noreferrer"><img decoding="async" class="aligncenter" src="https://lh3.googleusercontent.com/4gyoLn_4mdyZ3LxA2F5roPtZ2aXMzgU9eIAbuvvou5FCCCOZ8BOWBwWMx1QAfE-CBqDWOGZeHwYEWuLEUt6IpbJt1dKT-BvrFpQPC6pZO49kkEG8EuNMcAX2KCPH02OG4C3un9fW5nHk1o5orovBSt2YyzodKjfEBtQvL-4un7t66JFtRUsHRUqHZD0gf3KqNT3813xi08mcNhiljwztbfI0U_qtW6FO_0z69UFmrVFrrB4W35OD09OlvL_vHtLSs3mqm-ehspgS9ydOWL5Nx1WI4sQSq7td575vbnP3j3Qvdck8cf8COOpFKYSBR9czjIykg8pKO9OUdscWOodDPphg9lZ0D7meIjtNPlBUp6iywD48nO8Cm8BjfNZkjhK5mu-GRB4TNlpV3rQZvltPq-w8un4HEgRXFEyquot4DiNH5s04VDohA3Z67d9uYAgzJnnbXSrnWbsgo4oP328iDzvllHloP5Y0LtnfTkiYL6N8eTlk-mr5wSkeVZM_PaGqkovmotBoxIQlYn7zeE1Tu2nuopAN5Ofmiup_89eZftT4IrK5Vt3-cOTYUqwIY-gB_5edBZ-P5jtVhbz6Qg8J1nfxuCZ0dNMypn67Iadzwk8wsqrKMtEvTPTrEELjla59wOHx1tFvHPe1bogxkQjNa4-OpAOgt9eYfIvV=w1285-h951-no" alt="" /></a></p>
<p>Inside the city hall, there is an astronomical clock. The fastest gear completes a revolution every ten seconds and the slowest every 25,753 years. I have no idea what kind of information it shows, but I can appreciate the mechanisms as someone who studied mechanical engineering!</p>
<p><a href="https://photos.google.com/album/AF1QipPXard5bpmDmsFwHXxbYVVWBwoZvMq8M2vhzkze/photo/AF1QipOyC_xn4_gLXF5kX3zNRnFRrk41f8EH1kj1hgsU" target="_blank" rel="noopener noreferrer"><img decoding="async" class="aligncenter" src="https://lh3.googleusercontent.com/j53tNArDF3I0oC5BkZbI4sawI4j8uNziIcP6VAp6Lxa2cqQdXwbsODRmm0fX4m8TNkJDIBc9v25AnlH3sMMA9jTxcZzQUWtadbhWaFrfWjMghmG6cdHL8qSL3s6lJULb2cDBCzg6G9N-UpAVx7ZAKMCtYRNRS2y9So820bpfAIusp8rTx6HdjOJjb6rh-apt4r29wrmbJh0spuPblwf26Adf_q9BgoudxtdoregFiqHAHSYs2aaNxX9qFqH2w9p65DiIcWbX8ghYLG-7T_bOSdOO-arFXMrhNYwwFS7rpU2X0DGC7ACqBYztbBfYLU0UlFdJzK4a-amvRIIPskhGj8hrHvdLGq7qmgerJ38uNLnwh_S0peVRT4xYgBXDlOgwsQWUws1pX3kJ2FLopflIhGECs5vTXczFJIakM418q1ZsBpf0CAFwSBrfVHbmvIUGrIPuo6sKerlBNfN36_roLax65oBNj9tgkcdk19wIikQSkCOSGVv7Xm4x8QeYWrd5lXwn2Qm0xic07yT5s0TyoLQiSJtjZle9QA96gtrM2mjYpz56r-EsK1oUVx94W_OmNVpBlCqo7edKX5ZcajkcGxDrgs4j9TZzVyXmJkQBt8w=w1680-h945-no" alt="" /></a></p>
<p><a href="https://photos.google.com/album/AF1QipPXard5bpmDmsFwHXxbYVVWBwoZvMq8M2vhzkze/photo/AF1QipO0sao-N9WUzkb9n5oFMjZptpSV0SXUMW0WcvZG" target="_blank" rel="noopener noreferrer"><img decoding="async" class="aligncenter" src="https://lh3.googleusercontent.com/gL573Qb50SZQhuCix8YuYBEBXascCYdnSu3KCM0IWKXd1MZBzUQjg7qpwCFD6pfEFycs_NaIR3bgWy907rZIq9QGIjnx9nI7HjVBDFiasLVSE-YDSjg0aiou92oCriepH57Y1c3QuIAQ2GQoex8ORas0MNH_ZiAS2soTKVBCgAAXNzHjzLAuE2zOZW5VTYSdi4NchzD7Lhj7uwrCzYIV-aQ7VTTYPAW6KqoB9mqBhoVSNo_OkAAqvxLAlCWuTtJ3HQyT_SmUXFIriSQTA5QoyQgO7nKdgi9J8pPuJ9BlfhJkvaJQoKoz2qA5z-5YP4Gba2nduFFc7tI2YHOPVXZPMPLbLyYR9S5lK_dK3vNO4O-MOHizm2gOjFZTKpJSNY8jUnUzBkJUP2m2T2PNvJrAiaqFl8SbBJJrrFhhY8wF1mGUkfLacG2ganxIF30q73DDMicsVHjxbrnuLcM33rdCBqhsrfI0QncfZUoNscP0uD8syXD1CNx9huxHHFeHkBlOxtfNBfjNrKRiF0veaxXtDwJhoGCb_P2Sx3cjTyvIhsQYJN2Sk1c2QPXcz59SGKowTyXuu5xBkVcIg1I91uMZ_TTHpfX5RbsmLKqyVMvdlNU=w1680-h945-no" alt="" /></a></p>
<p>This was probably the best meal on the entire trip. A sampler of the most Danish food ever at Skindbuksen. When we went in, we were the only people inside who looked like tourists and everybody else looked local, which was a good sign, but we stood out. The owner of the restaurant came by with a giant plate of delicious food and loudly said to us, &#8220;this is what we eat in Denmark, you should try this!&#8221;. For a brief moment, our interaction with him gathered the attention of the entire restaurant, while it felt like all the locals were just judging us tourists&#8230; It was a tad awkward. BUT the food was absolutely delicious. There was pickled herring, deep fried fish filet, smoked salmon, roasted pork, and pork filet! The other tables were looking at our food with jealousy.</p>
<p><a href="https://photos.google.com/album/AF1QipPXard5bpmDmsFwHXxbYVVWBwoZvMq8M2vhzkze/photo/AF1QipPheS_2QGyCQRTnfixyyh3G_ic2fsmAJwYoKzAB" target="_blank" rel="noopener noreferrer"><img decoding="async" class="aligncenter" src="https://lh3.googleusercontent.com/Saz9v4GkfYMEGsHb-2VpXVptS8gsSwk6hRSoHt4kO2sZgknN25eWJesomYMeFCY_CI0_rcurgqrevNYxDc36hnd9pTrjVwYSngzPk-eHygk7DQ8ypxjR8d7xOZGvHze5EKKmfq2E6AWlbfWN7kIUnSn91M9FyilGCwT46dE6hlcin6qj-Ql79_ITkIGAky-vRYhLHVUjVDQl5wAG_YSw0kIB2qG1IVsA25gb9hqY5Pwq0MtT37xQRSMSQreU1zFMFXSlUEXlZs4bD9ITrMSJPimARhWq7GafNuuxGN3jj_vKXOOIiYdp6zM33is9bczPcKJ5LKenSfhff7nn3ZkevdtoJaOPqjUcM9-_RpNP0MnuDu38aXX58L8VwpZWqRNvZDGYZQ6JtTgjPalUObHeq5AD9Dd-HXDNKfSl6FLencLJBZZ7zW-iXWZ6d0aDvPNLIn82UeuCFuD30lsYnM4L0HF93Iu1_aY_54jLYnyJbv-MwBJ2lV0DxDxC8jHN65As_5HXV7JdCvRXkrI8FhL57TreM8OwAHFrGcMdjfXujzRcz50lPLuP6yFqq9gMgqBJ-okBGGb8TckHlDMn5KooJDxNmO-Cte67eHokmJK2Ufw=w1680-h945-no" alt="" /></a></p>
<p>At the bar in our hostel, we met someone who was working in Silicon Valley as a software engineer who happened to be working and travelling. She told me she graduated at UC Berkeley and so I asked her if she had seen the Amazon store there (<a href="https://press.aboutamazon.com/news-releases/news-release-details/amazon-opens-new-pickup-location-asuc-student-union-uc-berkeley/" target="_blank" rel="noopener noreferrer">this</a>). She told me how awesome it was to have something like that there and to her surprise, I revealed that I am actually one of the engineers who worked on it!</p>
<p>That&#8217;s it for Copenhagen!</p>
<p>Photo album: <a href="https://photos.app.goo.gl/JjBqpwSzEN6oWdRM2" target="_blank" rel="noopener noreferrer">Copenhagen</a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.henrypoon.com/blog/2017/09/17/copenhagen/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2750</post-id>	</item>
		<item>
		<title>Running Selenium Webdriver on Bash for Windows</title>
		<link>https://blog.henrypoon.com/blog/2017/06/18/running-selenium-webdriver-on-bash-for-windows/</link>
					<comments>https://blog.henrypoon.com/blog/2017/06/18/running-selenium-webdriver-on-bash-for-windows/#comments</comments>
		
		<dc:creator><![CDATA[hp]]></dc:creator>
		<pubDate>Sun, 18 Jun 2017 20:02:23 +0000</pubDate>
				<category><![CDATA[computer stuff]]></category>
		<category><![CDATA[engineering]]></category>
		<category><![CDATA[APT]]></category>
		<category><![CDATA[Bash]]></category>
		<category><![CDATA[COM]]></category>
		<category><![CDATA[D]]></category>
		<category><![CDATA[Download]]></category>
		<category><![CDATA[Drive]]></category>
		<category><![CDATA[EAR]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[Free software]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Graphical user interface testing]]></category>
		<category><![CDATA[IME]]></category>
		<category><![CDATA[ise]]></category>
		<category><![CDATA[It]]></category>
		<category><![CDATA[lamb]]></category>
		<category><![CDATA[Link]]></category>
		<category><![CDATA[Net]]></category>
		<category><![CDATA[Port]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Run]]></category>
		<category><![CDATA[Selenium]]></category>
		<category><![CDATA[Sleep]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Time]]></category>
		<category><![CDATA[USR]]></category>
		<category><![CDATA[Variable]]></category>
		<category><![CDATA[Vol]]></category>
		<category><![CDATA[Web browsers]]></category>
		<category><![CDATA[Web development software]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Xming]]></category>
		<guid isPermaLink="false">https://blog.henrypoon.com/?p=2711</guid>

					<description><![CDATA[NOTE: This article is for WSL1, for WSL2, see this post Bash for Windows has been working pretty great for me until I needed to run Selenium Webdriver on it. I quickly learned that it wouldn&#8217;t work just work right out of the box, and the set up for it is quite convoluted. You will [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">NOTE: This article is for WSL1, for WSL2, see <a href="https://blog.henrypoon.com/blog/2020/09/27/running-selenium-webdriver-on-wsl2/" target="_blank" rel="noreferrer noopener">this post</a></p>



<p class="wp-block-paragraph">Bash for Windows has been working pretty great for me until I needed to run Selenium Webdriver on it. I quickly learned that it wouldn&#8217;t work just work right out of the box, and the set up for it is quite convoluted.</p>



<p class="wp-block-paragraph">You will need</p>



<ul class="wp-block-list"><li><a rel="noreferrer noopener" href="https://msdn.microsoft.com/en-us/commandline/wsl/install_guide" target="_blank">Bash for Windows</a></li><li><a rel="noreferrer noopener" href="https://sourceforge.net/projects/xming/" target="_blank">Xming</a> &#8211; This will actually allow the Window to appear on the screen</li><li><a rel="noreferrer noopener" href="https://github.com/mozilla/geckodriver/releases" target="_blank">geckodriver</a> &#8211; Selenium now needs this to run Firefox</li></ul>



<h2 class="wp-block-heading">Bash setup</h2>



<p class="wp-block-paragraph">Install Firefox:</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">sudo apt-get install firefox</code></pre>



<p class="wp-block-paragraph">Export DISPLAY variable in ~/.bashrc. Just add this to the ~/.bashrc:</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">export DISPLAY=:0</code></pre>



<h2 class="wp-block-heading">Xming setup</h2>



<p class="wp-block-paragraph">Just download it from the link above and run it.</p>



<h2 class="wp-block-heading">Download geckodriver</h2>



<p class="wp-block-paragraph">Download geckodriver from the link above and put in the /usr/bin/ folder in Bash for Windows.</p>



<h2 class="wp-block-heading">Running Selenium</h2>



<p class="wp-block-paragraph">Here is a piece of sample Python code I used to setup the web browser. It will setup the browser, open Google, sit there for 10 seconds and then quit.&nbsp; Make sure to have Xming running otherwise the browser isn&#8217;t going to start.</p>



<pre class="wp-block-code"><code lang="python" class="language-python">import time

from selenium import webdriver
from selenium.webdriver import DesiredCapabilities

def execute_with_retry(method, max_attempts):
    e = None
    for i in range(0, max_attempts):
        try:
            return method()
        except Exception as e:
            print(e)
            time.sleep(1)
    if e is not None:
        raise e

capabilities = DesiredCapabilities.FIREFOX
capabilities["marionette"] = True
firefox_bin = "/usr/bin/firefox"
browser = execute_with_retry(lambda: webdriver.Firefox(
    firefox_binary=firefox_bin, capabilities=capabilities), 10)

browser.get("https://www.google.com")

time.sleep(10)

browser.close()</code></pre>



<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.henrypoon.com/blog/2017/06/18/running-selenium-webdriver-on-bash-for-windows/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2711</post-id>	</item>
		<item>
		<title>Jenkins pipeline for Spring with beta and prod stages and deployment rollback</title>
		<link>https://blog.henrypoon.com/blog/2017/03/09/jenkins-pipeline-for-spring-with-beta-and-prod-stages-and-deployment-rollback/</link>
					<comments>https://blog.henrypoon.com/blog/2017/03/09/jenkins-pipeline-for-spring-with-beta-and-prod-stages-and-deployment-rollback/#respond</comments>
		
		<dc:creator><![CDATA[hp]]></dc:creator>
		<pubDate>Thu, 09 Mar 2017 08:04:51 +0000</pubDate>
				<category><![CDATA[computer stuff]]></category>
		<category><![CDATA[9]]></category>
		<category><![CDATA[Apache Ant]]></category>
		<category><![CDATA[Apache Maven]]></category>
		<category><![CDATA[Build automation]]></category>
		<category><![CDATA[Chan]]></category>
		<category><![CDATA[COM]]></category>
		<category><![CDATA[Compiling tools]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[Const]]></category>
		<category><![CDATA[Continuous integration]]></category>
		<category><![CDATA[D]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[Digital technology]]></category>
		<category><![CDATA[Download]]></category>
		<category><![CDATA[EAR]]></category>
		<category><![CDATA[future]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[Hole]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[IME]]></category>
		<category><![CDATA[It]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Java enterprise platform]]></category>
		<category><![CDATA[Jenkins]]></category>
		<category><![CDATA[Levant]]></category>
		<category><![CDATA[Password]]></category>
		<category><![CDATA[PATH]]></category>
		<category><![CDATA[Plug]]></category>
		<category><![CDATA[Port]]></category>
		<category><![CDATA[Reference]]></category>
		<category><![CDATA[Rolling]]></category>
		<category><![CDATA[Run]]></category>
		<category><![CDATA[Scripting languages]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[STR]]></category>
		<category><![CDATA[Thou]]></category>
		<category><![CDATA[Time]]></category>
		<category><![CDATA[URL]]></category>
		<category><![CDATA[Variable]]></category>
		<category><![CDATA[Z]]></category>
		<category><![CDATA[Zip]]></category>
		<guid isPermaLink="false">https://blog.henrypoon.com/?p=2614</guid>

					<description><![CDATA[In the past couple of days, I&#8217;ve been experimenting a bit with the Jenkins pipeline plugin to create a code deployment pipeline with independent beta and prod stages for a Spring Boot app. I even managed to add rolling back a deployment in case a prod deployment fails! It took me a bit of time [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">In the past couple of days, I&#8217;ve been experimenting a bit with the <a href="https://wiki.jenkins-ci.org/display/JENKINS/Pipeline+Plugin" target="_blank" rel="noopener">Jenkins pipeline plugin</a> to create a code deployment pipeline with independent beta and prod stages for a Spring Boot app. I even managed to add rolling back a deployment in case a prod deployment fails! It took me a bit of time to Google my way through how to do everything, so I figure I just lay it all out here in case it helps other people do the same thing.</p>



<p class="wp-block-paragraph">The nice thing about all of this is that I can push a code change to git, and Jenkins can build it, run through all the tests and then deploy to production automatically.</p>



<h1 class="wp-block-heading">Layout of a pipeline script</h1>



<p class="wp-block-paragraph">Pipeline scripts are written in <a rel="noopener" href="http://www.groovy-lang.org/" target="_blank">Groovy</a>, which is a variant of Java. In general, a pipeline script is laid out like this:</p>



<pre class="wp-block-code"><code lang="python" class="language-python">node {
    def SOME_CONSTANT = "whatever"
    ...

    stage('some stage name like Build') {
        // Stuff to do as a part of this stage
    }

    stage('another stage') {
        // More stuff
    }

    ...
}</code></pre>



<p class="wp-block-paragraph">Each stage represents a stage in the pipeline (e.g. building, beta deployment, prod deployment etc.)</p>



<h1 class="wp-block-heading">Defining some constants</h1>



<p class="wp-block-paragraph">First, a list of constants can be defined that can be used throughout the pipeline so that if the pipeline script gets reused somewhere, only these constants have to be changed. I&#8217;m not aware of anything that lets me reuse a pipeline in Jenkins without copying and pasting the code somewhere else so for now I&#8217;ll have to live with copying and pasting.</p>



<p class="wp-block-paragraph">My project uses Maven so I got Jenkins to download its own copy of Maven that it can use to execute builds and have defined it as a constant. The name I&#8217;ve given it in the Jenkins Global Tool Configuration is &#8220;Maven 3.3.9&#8221; exactly. My project also uses Tomcat so there are some Tomcat specific things in there that may or may not be relevant to your use case.</p>



<pre class="wp-block-code"><code lang="python" class="language-python">def MAVEN_HOME = tool 'Maven 3.3.9'
    def WORKSPACE = pwd()

    def PROJECT_NAME = "name-of-project"
    def WAR_PATH_RELATIVE = "App/target/${PROJECT_NAME}.war"
    def WAR_PATH_FULL = "${WORKSPACE}/${WAR_PATH_RELATIVE}"
    def TOMCAT_CTX_PATH_BETA = "Tomcat-context-path-for-the-beta-stage"
    def TOMCAT_CTX_PATH_PROD = "Tomcat-context-path-for-the-prod-stage"
    def GIT_REPO_URL = "URL-to-git-repo-ending-in-.git"</code></pre>



<h1 class="wp-block-heading">Preparation Stage</h1>



<p class="wp-block-paragraph">First, the code has to be retrieved from the repository before it gets built. Jenkins allows storing username/password pairs so that they can be referenced without having to write out the password in plaintext. Jenkins uses a &#8220;credential ID&#8221; for this.</p>



<pre class="wp-block-code"><code lang="python" class="language-python">    stage('Preparation') {
        git branch: "master",
        credentialsId: "credentials-ID-stored-in-Jenkins-that-can-access-the-git-repo",
        url: "${GIT_REPO_URL}"
    }</code></pre>



<h1 class="wp-block-heading">Build Stage</h1>



<p class="wp-block-paragraph">Next, the code must be built and unit tested. &#8220;mvn clean install&#8221; will do just that (depending on what you want, you can always put in a different maven goal). The junit command is just there to take the resulting XML that gets generated during the build process and posts a graph of how many tests were run for each build.</p>



<pre class="wp-block-code"><code lang="python" class="language-python">    stage('Build') {
        sh "'${MAVEN_HOME}/bin/mvn' clean install"
        junit '**/target/surefire-reports/TEST-*.xml'
    }
</code></pre>



<h1 class="wp-block-heading">Beta Stage</h1>



<p class="wp-block-paragraph">Once the build succeeds, you&#8217;ll want to deploy it to a beta environment, so integration tests can happen. The following happens at this stage:</p>



<ol class="wp-block-list"><li>Get the right credentials to get permissions to Tomcat</li><li>Call the deploy method to deploy the war file in Tomcat (more on that later)</li><li>If the deployment fails for whatever reason, print out the deployment log for debugging and fail the build</li><li>If the deployment succeeds, run the integration tests (the command to do this may differ based on use case)</li></ol>



<pre class="wp-block-code"><code lang="python" class="language-python">    stage('Beta') {
        withCredentials([[$class: 'UsernamePasswordMultiBinding',
            credentialsId: 'credential-id-for-tomcat',
            usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD']]) {
                // Password is available as an env variable, but will be masked 
                // if you try to print it out any which way
                def output = deploy(WAR_PATH_FULL, TOMCAT_CTX_PATH_BETA,
                        env.USERNAME, env.PASSWORD)
                if (output.contains("FAIL - Deployed application at context path " + 
                        "/${TOMCAT_CTX_PATH_BETA} but context failed to start")) {
                    echo "----- Beta deployment log -----"
                    echo output
                    echo "-------------------------------"
                    currentBuild.result = 'FAILURE'
                    error "Beta stage deployment failure"
                }
            }

        echo "Running integration tests"
        sh "'${MAVEN_HOME}/bin/mvn' -Dtest=*IT test"
        junit '**/target/surefire-reports/TEST-*.xml'
    }</code></pre>



<p class="wp-block-paragraph">The deploy method is what takes care of the actual deployment to Tomcat, which is how the Jenkins build tells Tomcat about the newly built war file. The deploy method is below (be sure to change the server IP and port). Alternatively, I could have built my project as an embedded jar file, but that has a different challenge in figuring out how to get Jenkins to tell the OS to execute the newly built jar file as a particular user.</p>



<ol class="wp-block-list"><li>Based on the Tomcat context path, decide whether a beta or production deployment is happening</li><li>Make a copy of the build war file and add .prod or .beta to the end of it so as to keep the original</li><li>Set the Spring profile to use on the newly copied war file (more on that later)</li><li>Call the curl command to do the actual deployment to Tomcat (more on that later)</li></ol>



<pre class="wp-block-code"><code lang="python" class="language-python">def deploy(warPathFull, tomcatCtxPath, username, password) {
    def envSuffix = ""
    def isBeta = tomcatCtxPath.contains("beta")
    if (isBeta) {
        envSuffix = "beta"
    } else {
        envSuffix = "prod"
    }
    sh script: "cp ${warPathFull} ${warPathFull}.${envSuffix}" 
    setSpringProfile(warPathFull, isBeta)
    def output = sh script: "curl --upload-file '${warPathFull}.${envSuffix}' " +
            "'http://${username}:${password}@localhost:8081/manager/text/deploy" + 
            "?path=/${tomcatCtxPath}&amp;update=true'", returnStdout: true
    return output
}</code></pre>



<p class="wp-block-paragraph">In the case of my project, I&#8217;m building a single war file that does not have a Spring profile (beta/prod) defined. This means that I have to manually define this before I deploy the app to Tomcat since there are some things that differ between beta and prod like database URL&#8217;s. To do this, I wrote a method that opens the war file like a zip (jar/war files are zip files) and adds a line to my application.properties to define a Spring profile.</p>



<p class="wp-block-paragraph">Admittedly, doing this zip file manipulation seems kind of hacky. Alternatively, I could have defined my build such that I had a separate beta build and a prod build to avoid modifying the zip file, but the drawback is that I&#8217;d then have to build my code twice.</p>



<pre class="wp-block-code"><code lang="python" class="language-python">def setSpringProfile(warPathFull, isBeta) {
    def zipFileFullPath = warPathFull + "." + (isBeta ? "beta" : "prod")
    def zipIn = new File(zipFileFullPath)
    def zip = new ZipFile(zipIn)
    def zipTemp = File.createTempFile("temp_${System.nanoTime()}", 'zip')
    zipTemp.deleteOnExit()
    def zos = new ZipOutputStream(new FileOutputStream(zipTemp))
    def toModify = "WEB-INF/classes/application.properties"

    for(e in zip.entries()) {
        if(!e.name.equalsIgnoreCase(toModify)) {
            zos.putNextEntry(e)
            zos &lt;&lt; zip.getInputStream(e).bytes
        } else {
            zos.putNextEntry(new ZipEntry(toModify))
            zos &lt;&lt; zip.getInputStream(e).bytes
            zos &lt;&lt; ("\nspring.profiles.active=" + (isBeta ? "beta" : "prod")).bytes
        }
        zos.closeEntry()
    }

    zos.close()
    zipIn.delete()
    zipTemp.renameTo(zipIn)
}</code></pre>



<p class="wp-block-paragraph">A curl command to Tomcat is what actually does the deployment. To deploy a file to Tomcat, do the following below. This will deploy the war file to Tomcat and instantly run it, thus it will be accessible at the given context path.</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">curl --upload-file 'path-to-war-file' http://username:password@server-address:port/manager/text/deploy?path=/tomcat-context-path&amp;update=true</code></pre>



<h1 class="wp-block-heading">Prod Stage</h1>



<p class="wp-block-paragraph">The same kind of stuff happens in the prod stage as in the beta stage with a few exceptions. The following happens at this stage:</p>



<ol class="wp-block-list"><li>Get the right credentials to get permissions to Tomcat</li><li>Call the deploy method to deploy the war file in Tomcat (except this time it is prod)</li><li>If the deployment fails for whatever reason, print out the deployment log for debugging and roll back the deployment</li><li>If the deployment succeeds, save the build files, and then the pipeline is finished. Alternatively, smoke tests can be run at this point, but I did not implement this in my project</li></ol>



<p class="wp-block-paragraph">Rollback is important because if the deployment fails, you don&#8217;t want to be stuck with a broken environment. Since build artifacts are saved on successful deployments, these same artifacts can be brought back if future deployments fail. This means they can be redeployed so that the code can be fixed before another deployment happens.</p>



<pre class="wp-block-code"><code lang="python" class="language-python">    stage('Prod') {
        withCredentials([[$class: 'UsernamePasswordMultiBinding',
            credentialsId: 'credential-id-for-tomcat',
            usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD']]) {
                // Password is available as an env variable, but will be masked 
                // if you try to print it out any which way
                def output = deploy(WAR_PATH_FULL, TOMCAT_CTX_PATH_PROD, env.USERNAME, env.PASSWORD)
                if (output.contains("FAIL - Deployed application at context path " + 
                        "/${TOMCAT_CTX_PATH_PROD} but context failed to start")) {
                    echo "Prod stage deployment failure, rolling back deployment"
                    echo "----- Prod deployment log -----"
                    echo output
                    echo "-------------------------------"
                    step([$class: 'CopyArtifact',
                            filter: "${WAR_PATH_RELATIVE}",
                            fingerprintArtifacts: true,
                            projectName: "${PROJECT_NAME}",
                            target: "${WAR_PATH_RELATIVE}.rollback"])
                    deploy(WAR_PATH_FULL + ".rollback/" + WAR_PATH_RELATIVE,
                            TOMCAT_CTX_PATH_PROD, env.USERNAME, env.PASSWORD)
                    currentBuild.result = 'FAILURE'
                    error "Prod deployment rolled back"
                } else {
                    archiveArtifacts artifacts: "${WAR_PATH_RELATIVE}*", fingerprint: true
                }
            }
    }
</code></pre>



<p class="wp-block-paragraph">At the end you get to have something like this:</p>


<div class="wp-block-image">
<figure class="aligncenter"><img data-recalc-dims="1" fetchpriority="high" decoding="async" width="600" height="882" src="https://i0.wp.com/blog.henrypoon.com/wp-content/uploads/2017/03/JenkinsPipeline.png?resize=600%2C882&#038;ssl=1" alt="" class="wp-image-2638"/></figure>
</div>


<p class="wp-block-paragraph">That pretty much sums up the whole Jenkins pipeline that I&#8217;ve been using lately for Spring projects!</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.henrypoon.com/blog/2017/03/09/jenkins-pipeline-for-spring-with-beta-and-prod-stages-and-deployment-rollback/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2614</post-id>	</item>
		<item>
		<title>Moving an OS to another disk and still have it boot with Linux</title>
		<link>https://blog.henrypoon.com/blog/2016/01/28/moving-an-os-to-another-disk-and-still-have-it-boot-with-linux/</link>
					<comments>https://blog.henrypoon.com/blog/2016/01/28/moving-an-os-to-another-disk-and-still-have-it-boot-with-linux/#respond</comments>
		
		<dc:creator><![CDATA[hp]]></dc:creator>
		<pubDate>Fri, 29 Jan 2016 05:18:36 +0000</pubDate>
				<category><![CDATA[computer stuff]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[Booting]]></category>
		<category><![CDATA[COM]]></category>
		<category><![CDATA[Contents]]></category>
		<category><![CDATA[D]]></category>
		<category><![CDATA[Device file]]></category>
		<category><![CDATA[Disk partitioning]]></category>
		<category><![CDATA[Disk partitions]]></category>
		<category><![CDATA[Drive]]></category>
		<category><![CDATA[Final]]></category>
		<category><![CDATA[GNU GRUB]]></category>
		<category><![CDATA[GNU Parted]]></category>
		<category><![CDATA[GParted]]></category>
		<category><![CDATA[IME]]></category>
		<category><![CDATA[It]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Multi-booting]]></category>
		<category><![CDATA[Net]]></category>
		<category><![CDATA[Operating systems]]></category>
		<category><![CDATA[Plug]]></category>
		<category><![CDATA[Run]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Solid-state drive]]></category>
		<category><![CDATA[System software]]></category>
		<category><![CDATA[Time]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Z]]></category>
		<guid isPermaLink="false">https://blog.henrypoon.com/?p=2194</guid>

					<description><![CDATA[For the longest time, I&#8217;ve had an 80 GB HDD running my Windows partition (dual-boot setup with Ubuntu on a SSD), but now I&#8217;ve finally upgraded the Windows partition to an SSD as well. I looked into how to clone my Windows partition onto the SSD, such that I can still boot the disk. I [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">For the longest time, I&#8217;ve had an 80 GB HDD running my Windows partition (dual-boot setup with Ubuntu on a SSD), but now I&#8217;ve finally upgraded the Windows partition to an SSD as well. I looked into how to clone my Windows partition onto the SSD, such that I can still boot the disk.</p>



<p class="wp-block-paragraph">I already have Ubuntu as my main OS, so copying the disk was easy using <a href="http://linux.die.net/man/1/dd" target="_blank" rel="noopener noreferrer">dd</a>, which allows copying all the contents of one disk to another. This works well when the new hard drive is greater than or the same size as the current hard drive (I upgraded from a 80GB HDD to a 128GB SSD).</p>



<p class="wp-block-paragraph">First I run this to see which disk I am copying from and to</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">fdisk -l</code></pre>



<p class="wp-block-paragraph">Then I run dd. If I am copying from /dev/sda to /dev/sda, then it&#8217;s:</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">dd if=/dev/sda of=/dev/sdb</code></pre>



<p class="wp-block-paragraph">But sometimes the disks don&#8217;t have the same size, so I used gparted to move/resize the partitions to make use of the extra space on the new disk. gparted complained that it might make my disk no bootable, but the disk was still bootable for me nonetheless. I didn&#8217;t even have to mess with any grub bootloader settings either. I simply unplugged the old disk, and left the new disk plugged in and booted into the new disk no problem.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.henrypoon.com/blog/2016/01/28/moving-an-os-to-another-disk-and-still-have-it-boot-with-linux/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2194</post-id>	</item>
		<item>
		<title>Running League of Legends in PlayOnLinux (Ubuntu 14.04)</title>
		<link>https://blog.henrypoon.com/blog/2015/03/08/running-league-of-legends-in-playonlinux-ubuntu-14-04/</link>
					<comments>https://blog.henrypoon.com/blog/2015/03/08/running-league-of-legends-in-playonlinux-ubuntu-14-04/#comments</comments>
		
		<dc:creator><![CDATA[hp]]></dc:creator>
		<pubDate>Mon, 09 Mar 2015 01:45:11 +0000</pubDate>
				<category><![CDATA[computer stuff]]></category>
		<category><![CDATA[gaming]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[9]]></category>
		<category><![CDATA[APT]]></category>
		<category><![CDATA[Chan]]></category>
		<category><![CDATA[Click]]></category>
		<category><![CDATA[COM]]></category>
		<category><![CDATA[Comment]]></category>
		<category><![CDATA[Computer]]></category>
		<category><![CDATA[D]]></category>
		<category><![CDATA[Dia]]></category>
		<category><![CDATA[Directory]]></category>
		<category><![CDATA[Drive]]></category>
		<category><![CDATA[Find]]></category>
		<category><![CDATA[Games]]></category>
		<category><![CDATA[Icon]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[IME]]></category>
		<category><![CDATA[Installation]]></category>
		<category><![CDATA[It]]></category>
		<category><![CDATA[league of legends]]></category>
		<category><![CDATA[Lie]]></category>
		<category><![CDATA[Light]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[lol]]></category>
		<category><![CDATA[Nap]]></category>
		<category><![CDATA[Net]]></category>
		<category><![CDATA[NVIDIA]]></category>
		<category><![CDATA[Object]]></category>
		<category><![CDATA[Over]]></category>
		<category><![CDATA[PATH]]></category>
		<category><![CDATA[Pawn]]></category>
		<category><![CDATA[PlayOnLinux]]></category>
		<category><![CDATA[Radeon HD 5000 Series]]></category>
		<category><![CDATA[Riot Games]]></category>
		<category><![CDATA[Run]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Speed]]></category>
		<category><![CDATA[STR]]></category>
		<category><![CDATA[Struct]]></category>
		<category><![CDATA[System software]]></category>
		<category><![CDATA[Time]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[Video cards]]></category>
		<category><![CDATA[Video gaming]]></category>
		<category><![CDATA[Vol]]></category>
		<category><![CDATA[Volume]]></category>
		<category><![CDATA[WINE]]></category>
		<category><![CDATA[Z]]></category>
		<guid isPermaLink="false">https://www.henrypoon.com/blog/?p=2053</guid>

					<description><![CDATA[There are various guides floating around on the Internet for running League of Legends on Linux, and no single guide worked for me, but after piecing the information together from various places, I managed to get it to work on my system. My computer specifications: Intel Core i5-4570 16 GB Memory Radeon HD 5770 I [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">There are various guides floating around on the Internet for running League of Legends on Linux, and no single guide worked for me, but after piecing the information together from various places, I managed to get it to work on my system.</p>



<p class="wp-block-paragraph">My computer specifications:</p>



<ul class="wp-block-list"><li>Intel Core i5-4570</li><li>16 GB Memory</li><li>Radeon HD 5770</li></ul>



<p class="wp-block-paragraph">I followed the instructions <a href="http://askubuntu.com/questions/459888/shop-and-in-game-item-shop-not-working-in-league-of-legend-lol/461256#461256" target="_blank" rel="noopener noreferrer">here</a>, with these changes:</p>



<ul class="wp-block-list"><li>Using video driver &#8220;fglrx-updates&#8221; (the tutorial talks about NVIDIA cards)</li><li>Did not install TuxLoL</li><li>Did not do anything regarding the &#8220;Maestro error&#8221; since it only applies to Optimus Notebook users</li><li>Did not follow step 6 because I did not run into the problem for big item icon text for the item shop</li><li>EDIT: Thanks to Ingvar&#8217;s comment, the installation progress for the game can be viewed like so: open terminal (Ctrl+Alt+T) and execute: </li></ul>



<pre class="wp-block-code"><code lang="bash" class="language-bash">tail -f ~/.PlayOnLinux/wineprefix/LeagueOfLegends/drive_c/Riot\ Games/League\ of\ Legends/Logs/Patcher\ Logs/*.log</code></pre>



<p class="wp-block-paragraph">There are also other steps that I had to do, which I read from <a href="https://www.playonlinux.com/en/app-1135-League_Of_Legends.html" target="_blank" rel="noopener noreferrer">here</a>:</p>



<ul class="wp-block-list"><li>Click configure for the &#8220;League of Legends&#8221; entry in &#8220;PlayOnLinux&#8221; and find the &#8220;Display&#8221; tab and then choose the following options: <ul><li>Direct Draw Renderer &#8211; gdi</li><li>Video memory size &#8211; 4096 (or something else depending on graphics card)</li><li>Offscreen rendering mode &#8211; fbo\0</li><li>Everything else on default </li></ul></li><li>Create a file called &#8220;game.cfg&#8221; in the directory &#8220;/home/your-username-here/PlayOnLinux&#8217;s virtual drives/LeagueOfLegends/drive_c/Riot Games/League of Legends/Config&#8221;. Below is what I have in my &#8220;game.cfg&#8221;:</li></ul>



<pre class="wp-block-code"><code lang="properties" class="language-properties">[General]
EnableAudio=1
GameMouseSpeed=10
UserSetResolution=1
BindSysKeys=0
SnapCameraOnRespawn=0
OSXMouseAcceleration=1
AutoAcquireTarget=0
EnableLightFx=0
WindowMode=0
ShowTurretRangeIndicators=0
PredictMovement=0
WaitForVerticalSync=0
Colors=32
Height=1080
Width=1920
SystemMouseSpeed=0
CfgVersion=5.3.296
x3d_platform=1</code></pre>



<pre class="wp-block-code"><code lang="properties" class="language-properties">[HUD]
CameraLockMode=0
MiddleClickDragScrollEnabled=0
KeyboardScrollSpeed=0.5000
ChatScale=50
ObjectTooltips=0
AutoDisplayTarget=0
ShowAllChannelChat=1
ShowTimestamps=1
ItemShopPrevY=39
ItemShopPrevX=106
NameTagDisplay=1
ShowChampionIndicator=0
ShowSummonerNames=1
ScrollSmoothingEnabled=0
MiddleMouseScrollSpeed=0.5000
MapScrollSpeed=0.5000
ShowAttackRadius=0
NumericCooldownFormat=1
SmartCastOnKeyRelease=0
EnableLineMissileVis=0
FlipMiniMap=1
ItemShopResizeHeight=0
ItemShopResizeWidth=164
ItemShopPrevResizeHeight=1080
ItemShopPrevResizeWidth=1920
ItemShopItemDisplayMode=1
ItemShopStartPane=1</code></pre>



<pre class="wp-block-code"><code lang="properties" class="language-properties">[Performance]
CharacterInking=1
ShadowsEnabled=1
EnableHUDAnimations=0
PerPixelPointLighting=0
EnableParticleOptimizations=0
BudgetOverdrawAverage=0
BudgetSkinnedVertexCount=0
BudgetSkinnedDrawCallCount=0
BudgetTextureUsage=0
BudgetVertexCount=0
BudgetTriangleCount=0
BudgetDrawCallCount=0
EnableGrassSwaying=0
EnableFXAA=0
AdvancedShader=0
FrameCapType=6
GammaEnabled=0
Full3DModeEnabled=0
AutoPerformanceSettings=0
CharacterQuality=4
EffectsQuality=4
EnvironmentQuality=4
ShadowQuality=4
GraphicsSlider=6
paths=0</code></pre>



<pre class="wp-block-code"><code lang="properties" class="language-properties">[FloatingText]
EnemyTrueDamageCritical_Enabled=1
EnemyMagicalDamageCritical_Enabled=1
EnemyPhysicalDamageCritical_Enabled=1
TrueDamageCritical_Enabled=1
MagicalDamageCritical_Enabled=1
PhysicalDamageCritical_Enabled=1
Countdown_Enabled=0
EnemyTrueDamage_Enabled=0
EnemyMagicalDamage_Enabled=0
EnemyPhysicalDamage_Enabled=0
TrueDamage_Enabled=0
MagicalDamage_Enabled=0
PhysicalDamage_Enabled=0
Score_Enabled=0
QuestComplete_Enabled=0
QuestReceived_Enabled=0
Disable_Enabled=0
Level_Enabled=0
Dodge_Enabled=0
Heal_Enabled=0
Special_Enabled=0
Invulnerable_Enabled=0
Debug_Enabled=0
Absorbed_Enabled=0
OMW_Enabled=0
EnemyCritical_Enabled=0
MagicCritical_Enabled=0
Critical_Enabled=0</code></pre>



<pre class="wp-block-code"><code lang="properties" class="language-properties">[Volume]
SfxVolume=0.5
MasterVolume=0.5</code></pre>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.henrypoon.com/blog/2015/03/08/running-league-of-legends-in-playonlinux-ubuntu-14-04/feed/</wfw:commentRss>
			<slash:comments>27</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2053</post-id>	</item>
		<item>
		<title>Running TurboTax 2014 in PlayOnLinux</title>
		<link>https://blog.henrypoon.com/blog/2015/03/07/running-turbotax-2014-in-playonlinux/</link>
					<comments>https://blog.henrypoon.com/blog/2015/03/07/running-turbotax-2014-in-playonlinux/#comments</comments>
		
		<dc:creator><![CDATA[hp]]></dc:creator>
		<pubDate>Sun, 08 Mar 2015 05:08:28 +0000</pubDate>
				<category><![CDATA[gaming]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[.exe]]></category>
		<category><![CDATA[9]]></category>
		<category><![CDATA[APT]]></category>
		<category><![CDATA[Click]]></category>
		<category><![CDATA[COM]]></category>
		<category><![CDATA[D]]></category>
		<category><![CDATA[Drive]]></category>
		<category><![CDATA[EAR]]></category>
		<category><![CDATA[Find]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[Installation]]></category>
		<category><![CDATA[Installation software]]></category>
		<category><![CDATA[It]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[Net]]></category>
		<category><![CDATA[PlayOnLinux]]></category>
		<category><![CDATA[Run]]></category>
		<category><![CDATA[Shortcut]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[System software]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[TurboTax]]></category>
		<category><![CDATA[UNC]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Windows Installer]]></category>
		<category><![CDATA[WINE]]></category>
		<guid isPermaLink="false">https://www.henrypoon.com/blog/?p=2050</guid>

					<description><![CDATA[This guide describes how to run TurboTax 2014 in PlayOnLinux. &#160;The PlayOnLinux (in combination with WINE) software allows users to install Windows-based software. CAVEAT: NETFILE&#160;did not work for me. &#160;I had to submit my taxes through an installation done on Windows Install&#160;PlayOnLinux and then run it (e.g. starting it through the Terminal) sudo apt-get install [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>This guide describes how to run TurboTax 2014 in <a href="https://www.playonlinux.com/en/" target="_blank" rel="noopener noreferrer">PlayOnLinux</a>. &nbsp;The PlayOnLinux (in combination with <a href="https://www.winehq.org/" target="_blank" rel="noopener noreferrer">WINE</a>) software allows users to install Windows-based software.</p>
<hr />
<p>CAVEAT: NETFILE&nbsp;did not work for me. &nbsp;I had to submit my taxes through an installation done on Windows</p>
<hr />
<ol>
<li>Install&nbsp;PlayOnLinux and then run it (e.g. starting it through the Terminal)</li>
</ol>
<pre>sudo apt-get install playonlinux</pre>
<ol start="2">
<li>Click &#8220;Tools&#8221; &gt; &#8220;Manage wine versions&#8221;</li>
<li>Choose 1.7.27 under &#8220;Available Wine versions&#8221; and then click the right arrow &#8220;&gt;&#8221;</li>
<li>Go through the steps in the installer and let it finish</li>
<li>Back in the PlayOnLinux main screen, click &#8220;Install&#8221; in the menu, and then click &#8220;Install a non-listed program&#8221; on the bottom left</li>
<li>Choose &#8220;Use another version of Wine&#8221;, when asked, and then choose 1.7.27</li>
<li>Choose &#8220;Install a program in a new virtual drive&#8221;, when asked</li>
<li>Choose &#8220;32 bits windows installation&#8221;, when asked</li>
<li>Find the location of setup.exe for the TurboTax installer (I copied the files off of the disc to a place on my hard drive)</li>
<li>Ignore the message &#8220;Error in FS_Check&#8221; if it appears</li>
<li>Let the install complete, but do not launch TurboTax right away</li>
<li>Choose &#8220;tt2014.exe&#8221;, if asked to create a shortcut</li>
<li>Back in the PlayOnLinux main screen, select entry for TurboTax and click &#8220;Configure&#8221; in the menu</li>
<li>Make sure the &#8220;Wine version&#8221; is set to 1.7.27</li>
<li>Under &#8220;Install components&#8221;, install the following in this order (some of these may not be required, but I don&#8217;t know which since this is the configuration that worked for me):
<ul>
<li>vcrun2012</li>
<li>Microsoft Core Fonts</li>
<li>msvc100</li>
<li>RegisterFonts</li>
<li>vcrun2010</li>
<li>dotnet40</li>
<li>d3dx9</li>
<li>mono28</li>
<li>Internet Explorer 8 (click &#8220;Restart&#8221; in the installer)</li>
<li>crypt32</li>
</ul>
</li>
<li>Back in the PlayOnLinux main screen, clicking &#8220;Run&#8221; for TurboTax 2014 should now work!</li>
</ol>
<p>This is what worked for me, so hopefully this will work for others.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.henrypoon.com/blog/2015/03/07/running-turbotax-2014-in-playonlinux/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2050</post-id>	</item>
		<item>
		<title>Deleted IME&#8217;s still appear in the list even though they have been removed in Ubuntu 14.04</title>
		<link>https://blog.henrypoon.com/blog/2015/02/15/deleted-imes-still-appear-in-the-list-even-though-they-have-been-removed-in-ubuntu-14-04/</link>
					<comments>https://blog.henrypoon.com/blog/2015/02/15/deleted-imes-still-appear-in-the-list-even-though-they-have-been-removed-in-ubuntu-14-04/#respond</comments>
		
		<dc:creator><![CDATA[hp]]></dc:creator>
		<pubDate>Mon, 16 Feb 2015 04:30:16 +0000</pubDate>
				<category><![CDATA[computer stuff]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[APT]]></category>
		<category><![CDATA[Chinese input methods for computers]]></category>
		<category><![CDATA[Configuration management]]></category>
		<category><![CDATA[D]]></category>
		<category><![CDATA[Dconf]]></category>
		<category><![CDATA[driving]]></category>
		<category><![CDATA[EAR]]></category>
		<category><![CDATA[Free software]]></category>
		<category><![CDATA[GNOME]]></category>
		<category><![CDATA[IME]]></category>
		<category><![CDATA[It]]></category>
		<category><![CDATA[Japan]]></category>
		<category><![CDATA[Run]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[System software]]></category>
		<category><![CDATA[Thou]]></category>
		<category><![CDATA[ubuntu]]></category>
		<guid isPermaLink="false">https://www.henrypoon.com/blog/?p=2046</guid>

					<description><![CDATA[I had this weird problem when my Japanese and Chinese IME stayed in my IME list even though I had removed them. &#160;It was driving me nuts, but it turns out that they can be disabled through the dconf-editor First, run: Navigate to: Bold options are options that have been modified. &#160;The interesting one is [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">I had this weird problem when my Japanese and Chinese IME stayed in my IME list even though I had removed them. &nbsp;It was driving me nuts, but it turns out that they can be disabled through the dconf-editor</p>



<p class="wp-block-paragraph">First, run:</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">sudo apt-get install dconf-editor</code></pre>



<p class="wp-block-paragraph">Navigate to:</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">org/gnome/desktop/applications/input-sources</code></pre>



<p class="wp-block-paragraph">Bold options are options that have been modified. &nbsp;The interesting one is the row labeled &#8220;sources&#8221;. &nbsp;Clear the entries of the IME&#8217;s that should not appear in the list and that should remove the IME&#8217;s that shouldn&#8217;t be appearing.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.henrypoon.com/blog/2015/02/15/deleted-imes-still-appear-in-the-list-even-though-they-have-been-removed-in-ubuntu-14-04/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2046</post-id>	</item>
		<item>
		<title>Groovy/Grails unable to resolve class &#8211; even if the class is in the same package</title>
		<link>https://blog.henrypoon.com/blog/2015/01/26/groovygrails-unable-to-resolve-class-even-if-the-class-is-in-the-same-package/</link>
					<comments>https://blog.henrypoon.com/blog/2015/01/26/groovygrails-unable-to-resolve-class-even-if-the-class-is-in-the-same-package/#respond</comments>
		
		<dc:creator><![CDATA[hp]]></dc:creator>
		<pubDate>Tue, 27 Jan 2015 06:44:33 +0000</pubDate>
				<category><![CDATA[gaming]]></category>
		<category><![CDATA[Apache Groovy]]></category>
		<category><![CDATA[Chan]]></category>
		<category><![CDATA[COM]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[Cross-platform software]]></category>
		<category><![CDATA[D]]></category>
		<category><![CDATA[Digital technology]]></category>
		<category><![CDATA[EAR]]></category>
		<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[IME]]></category>
		<category><![CDATA[Integrated development environments]]></category>
		<category><![CDATA[ise]]></category>
		<category><![CDATA[It]]></category>
		<category><![CDATA[Java platform]]></category>
		<category><![CDATA[Reference]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Time]]></category>
		<category><![CDATA[Writing]]></category>
		<guid isPermaLink="false">https://www.henrypoon.com/blog/?p=2019</guid>

					<description><![CDATA[The Problem Every now and then I get this annoying problem in GGTS (Grails/Groovy Tool Suite &#8211; Version 3.6.2.RELEASE at the time of this writing), where the IDE just complains about how it can&#8217;t resolve a class. &#160;The weird thing is that the file that the IDE is complaining about is in the same package [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>The Problem</h1>
<p>Every now and then I get this annoying problem in GGTS (Grails/Groovy Tool Suite &#8211; Version 3.6.2.RELEASE at the time of this writing), where the IDE just complains about how it can&#8217;t resolve a class. &nbsp;The weird thing is that the file that the IDE is complaining about is in the same package as the class that I&#8217;m trying to use. &nbsp;It built before, and the source hadn&#8217;t changed &#8211; so clearly this should not be happening.</p>
<h1>The Fix</h1>
<p>Hitting the Clean button on the Eclipse side (Project -&gt; Clean) seems to make the errors go away.</p>
<p>This apparently has been a problem since June 2010 (forum post reference <a href="http://forum.spring.io/forum/spring-projects/springsource-tool-suite/83417-groovy-unable-to-resolve-class-although-same-package-again" target="_blank" rel="noopener noreferrer">here</a>), so I&#8217;m surprised that it is still an issue in the current version.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.henrypoon.com/blog/2015/01/26/groovygrails-unable-to-resolve-class-even-if-the-class-is-in-the-same-package/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2019</post-id>	</item>
	</channel>
</rss>
