<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Perry Janssen</title>
    <description>The latest articles on DEV Community by Perry Janssen (@perry).</description>
    <link>https://dev.to/perry</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F183439%2Fde739475-9662-42f6-b741-1193c66609f9.png</url>
      <title>DEV Community: Perry Janssen</title>
      <link>https://dev.to/perry</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/perry"/>
    <language>en</language>
    <item>
      <title>Fix slow Docker databases for Apple Silicon M1 chips</title>
      <dc:creator>Perry Janssen</dc:creator>
      <pubDate>Thu, 04 Mar 2021 21:23:26 +0000</pubDate>
      <link>https://dev.to/perry/fix-slow-docker-databases-for-apple-silicon-m1-chips-2ip1</link>
      <guid>https://dev.to/perry/fix-slow-docker-databases-for-apple-silicon-m1-chips-2ip1</guid>
      <description>&lt;p&gt;Reading and writing to databases in Docker on Apple Silicon laptops is currently quite slow. Dealing with large databases can be hard or even impossible to work with. While Docker and Apple are working to fix this issue, we need a temporary solution for our local environments. Luckily, running databases outside of Docker containers isn't slow at all!&lt;/p&gt;

&lt;p&gt;In this little tutorial we'll be creating a database on our localhost and connecting a Drupal installation inside a Docker container to it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Homebrew, MariaDB and another terminal
&lt;/h2&gt;

&lt;p&gt;In this example we'll be setting up a MariaDB database. MariaDB can be installed using Homebrew, but MariaDB isn't compatible with the new M1 chip yet, so we will install it using a Rosetta version of Homebrew.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rosetta Terminal
&lt;/h3&gt;

&lt;p&gt;First, we'll need to create a new terminal application to run our commands using "x86_64 instructions", which emulates the Intel processors of previous Macs. The emulator is called Rosetta 2. You can run programs in this mode, but also create applications that always start up using Rosetta.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In Finder, navigate to your Applications folder.&lt;/li&gt;
&lt;li&gt;Inside the Utilities folder, duplicate the Terminal application and call it something like "Rosetta Terminal".&lt;/li&gt;
&lt;li&gt;Click on "Get Info" on the newly created Application.&lt;/li&gt;
&lt;li&gt;In the General tab, check the box that says "Open using Rosetta".&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;You can change the application icon by copying an image,  clicking on the small icon at the top of the "Get Info" window, and pasting. This way you can tell the two terminal applications apart. Check sites like &lt;a href="http://www.flaticon.com"&gt;www.flaticon.com&lt;/a&gt; for free icons.&lt;/p&gt;

&lt;p&gt;You can also change the background color of the terminal in the application's Preferences &amp;gt; Profiles, so you always know which terminal you've got in front of you.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now all commands executed in this terminal are executed using the Intel architecture. Now let's install Homebrew.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rosetta Brew
&lt;/h3&gt;

&lt;p&gt;Install Homebrew using this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="sr"&gt;/bin/&lt;/span&gt;&lt;span class="nx"&gt;bash&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will install the brew command in &lt;code&gt;/usr/local&lt;/code&gt;, which is a different location than the M1 Homebrew installation. This means we've got two Homebrews, so we need to differentiate between the two by creating an alias command for the new installation.&lt;/p&gt;

&lt;p&gt;You can do this by running: &lt;code&gt;alias ibrew='arch -x86_64 /usr/local/bin/brew'&lt;/code&gt; &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The &lt;code&gt;arch -x86_64&lt;/code&gt; part makes sure the command is run using Rosetta, even if you use it outside of the Rosetta Terminal, but I advise to just always use the Rosetta Terminal when working with x86_64 packages.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you run &lt;code&gt;ibrew&lt;/code&gt;, it will run the Rosetta brew command 🎉&lt;/p&gt;

&lt;p&gt;As you will probably bump into more incompatible brew packages in you developing life, you will get a lot of use out of our &lt;code&gt;ibrew&lt;/code&gt; command.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you don't want to run the alias command every time you want to use the ibrew command, put the line in your terminal profile. For the ZSH shell this is &lt;code&gt;~/.zshrc&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  MariaDB
&lt;/h3&gt;

&lt;p&gt;Install MariaDB in your Rosetta Terminal.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run &lt;code&gt;brew install mariadb&lt;/code&gt; and let the installation complete.&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;brew services start mariadb&lt;/code&gt; to start the MySQL database.&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;sudo mysql&lt;/code&gt; to log into MySQL as the root user.&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;CREATE DATABASE db_name;&lt;/code&gt; to create a database.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now we have a database service and created a database which we can connect to. But before we can connect to it outside of our terminal, we have to create a user.&lt;/p&gt;

&lt;p&gt;When still in the MySQL command line:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run &lt;code&gt;CREATE USER 'username'@'%' IDENTIFIED BY 'password';&lt;/code&gt; to create a user with username "username" and password "password" for all hosts. Replace username and password with you desired credentials.&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;GRANT ALL PRIVILEGES ON *.* TO 'username'@'%' IDENTIFIED BY 'password';&lt;/code&gt; to grant all permissions to the user, so it can read and write to the database.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;The percent sign '%' after the username makes sure the user can log in from any host. Setting this to 'localhost' will only make the databases accessible from the localhost domain, for that user. You want to specify this host in production environments for security reasons, but locally I advise using the % wildcard, especially because we want to connect to it from out Docker container.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now we have set up everything to connect to our database, so let's do that now!&lt;/p&gt;

&lt;h2&gt;
  
  
  Connecting to an "external" database
&lt;/h2&gt;

&lt;p&gt;When inside a Docker container, you cannot reach the localhost of you machine by just using localhost or 127.0.0.1 as the host. Luckily Docker has made a couple of hosts we can use that proxy to our localhost 😄&lt;/p&gt;

&lt;p&gt;There are multiple hosts for some reason. One or all might work for you, just try them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;host.docker.internal&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gateway.docker.internal&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;docker.for.mac.host.internal&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In Drupal 8/9 the database config looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$databases&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="s1"&gt;'driver'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'mysql'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'database'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'db_name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'username'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'username'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'password'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'password'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'host'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'host.docker.internal'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'port'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3306&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You &lt;em&gt;should&lt;/em&gt; be able to connect to your external database now!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Download &lt;a href="https://sequelpro.com/download"&gt;Sequel Pro&lt;/a&gt; to make creating and maintaining databases a little more visual.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;While this isn't a perfect solution, it actually works better than I expected, at least for the project I'm working on now! For small databases you can still use database services inside Docker, but if you're talking huge, content-filled Drupal or Wordpress databases, you will have a hard time not using an external database like this. Let's hope Docker and/or Apple will fix this very soon!&lt;/p&gt;

</description>
      <category>docker</category>
      <category>m1</category>
      <category>database</category>
      <category>rosetta</category>
    </item>
    <item>
      <title>Getting random tracks using the Spotify API</title>
      <dc:creator>Perry Janssen</dc:creator>
      <pubDate>Thu, 20 Jun 2019 14:05:21 +0000</pubDate>
      <link>https://dev.to/perry/getting-random-tracks-using-the-spotify-api-403i</link>
      <guid>https://dev.to/perry/getting-random-tracks-using-the-spotify-api-403i</guid>
      <description>&lt;p&gt;While the Spotify API offers quite a lot of ways to interact with one of the most used streaming services, it lacks the ability of accessing all Spotify tracks as a whole. This might be because of the enormous amount of available songs. Grabbing a list of all wouldn’t be very efficient. While I was creating an application with which a user can discover new music, I wanted to show the user seemingly random tracks using Spotify. In this article, I’ll go over a couple of ways I tried to achieve this.&lt;/p&gt;

&lt;p&gt;This is not a tutorial on the basics of the Spotify API, but on kind of a obscure, specific issue. Check out the ‘Get Started’ guide: &lt;a href="https://developer.spotify.com/documentation/web-api/quick-start/"&gt;https://developer.spotify.com/documentation/web-api/quick-start/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Developing using (Node)JS? This module really made connecting with Spotify and especially oAuth, a lot easier: &lt;a href="https://www.npmjs.com/package/spotify-web-api-js"&gt;https://www.npmjs.com/package/spotify-web-api-js&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Genres
&lt;/h3&gt;

&lt;p&gt;The first method I tried made use of Spotify’s genre system. By fetching a list of all genres, picking a random genre and getting a track by that genre would result in a random track, or so I thought. First, Spotify doesn’t assign a genre to each track. A genre is linked to an artist, instead. Secondly, the list of available genres does not match the genres linked to the artists.&lt;/p&gt;

&lt;p&gt;According to the list of ‘available genre seeds’ only contain about one- or two hundred genres. These genres are all very general. The genres linked to artist accounts are usually more specific. This makes it impossible to search all artists, and therefore all tracks, by using genres.&lt;/p&gt;

&lt;p&gt;This problem has already been noticed by other developers. You can check out the issue on GitHub: &lt;a href="https://github.com/spotify/web-api/issues/868"&gt;https://github.com/spotify/web-api/issues/868&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Search
&lt;/h3&gt;

&lt;p&gt;The second method I tried made use of a simple search query. Using Spotify’s Search API, you can search through all available tracks, artists, playlist and more. This method worked best for me. According to Spotify’s documentation, a wildcard character can be used to search. A wildcard is a character that can be anything. For instance, a search query like this: &lt;code&gt;My %&lt;/code&gt; will return all tracks that begin with the word &lt;code&gt;My&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now I had to think of a way of creating random searches, and getting a random track from that search. The best way I could think of was having a random character prefixing the wildcard character, like this: &lt;code&gt;d%&lt;/code&gt;. This would return all tracks that start with a &lt;code&gt;d&lt;/code&gt;. You could also put the wildcard at the beginning, or at both the beginning or end.&lt;/p&gt;

&lt;p&gt;Because Spotify shows the more famous artists and tracks at the top of the search results, I also had to randomize an offset. According to documentation, a maximum limit of 10.000 can be applied. The offset will be the index of the first returned item, or the first returned page if a limit is set.&lt;/p&gt;

&lt;p&gt;Check out the Spotify Search documentation: &lt;a href="https://developer.spotify.com/documentation/web-api/reference/search/search/"&gt;https://developer.spotify.com/documentation/web-api/reference/search/search/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting a random search query
&lt;/h3&gt;

&lt;p&gt;To get a random search query, you’ll need to grab a random character from a list of characters and add the wildcard character to the string. I created a simple function that would do just that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getRandomSearch&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// A list of all characters that can be chosen.&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;characters&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;abcdefghijklmnopqrstuvwxyz&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Gets a random character from the characters string.&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;randomCharacter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;characters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;charAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;characters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;randomSearch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Places the wildcard character at the beginning, or both beginning and end, randomly.&lt;/span&gt;
  &lt;span class="k"&gt;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="nx"&gt;randomSearch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;randomCharacter&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;%&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="nx"&gt;randomSearch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;%&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;randomCharacter&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;%&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;randomSearch&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To create a random offset, just generate a random number between 0–10.000:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const randomOffset = Math.floor(Math.random() * 10000);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The Spotify Search endpoint allows you to filter on different types. To get tracks, just add type=track to the request.&lt;/p&gt;

&lt;p&gt;Now that we have all the required parameters, we can make a GET request to the Spotify Search endpoint, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET https://api.spotify.com/v1/search
type=track
q=getRandomSearch()
offset=randomOffset
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Locality issue
&lt;/h3&gt;

&lt;p&gt;To use the Spotify API, Spotify requires the user to be logged in. A logged in user is linked to a certain location. This means that searching, even through the API, can be a little biased towards tracks originating from the user’s country. There isn’t really a way around this, but it is possible to define a &lt;code&gt;market&lt;/code&gt;. A market is, kind of, the country the user is from. You can set the market the same way as any other parameter, but setting a market means you’ll only get results from artists from that specific country. Of course, you could randomize this as well.&lt;/p&gt;

</description>
      <category>spotify</category>
      <category>api</category>
    </item>
  </channel>
</rss>
