/dev/blog/ID10T

Advertisement

Using the Spotify Web player on Android

• Android and Web • Comments

A friend of mine asked me if it was possible to use the Spotify Web Player on his Android smartphone.

Spotify Android App

If you are like me and don’t use Spotify on mobile very often, you might not know that the free version of the Spotify app is heavily castrated. I’m not using it a lot, but if I understood correctly, you can’t properly play a playlist or one song, you get force fed “matching” songs. Also you can’t constantly skip songs. To push their Premium Account to you, Spotify additionally prevents mobile browsers from using their less limited Web player.

While I understand that Spotify wants to earn money, I heavily dislike the artificial limitations to push people to a paying account. If you can’t sell your Premium Account with a feature list, you should probably work on the list instead of artificially limiting the features on different devices. Especially the differentiation between PC and mobile browsers triggered me. Therefore I welcomed the challenge of convincing Spotifys Web player to work on Android.

Ansible: Extend variable values in Jinja 2 templates

• ansible • Comments

In a Jinja 2 Template for one of my Ansible playbooks I wanted to construct a string containing several potentially filled variables to eventually append it to a command execution.

I tried this:

{% set additional_opts = '' %}
{% for opt_arg, opt_name in [
  (item.exclusive_labels|default(''), '--exclusive_labels'),
  (item.ignore_labels|default(''), '--ignore_labels'),
  (item.exclusive_prefixes|default(''), '--exclusive_prefixes'),
  (item.ignore_prefixes|default(''), '--ignore_prefixes')
] %}
{% if opt_arg %}
{% set additional_opts %}{{ additional_opts }} {{ opt_name }}="{{ opt_arg }}"
{%- endset %}
{% endif %}
{% endfor %}

runme.py {{ additional_opts }}

But that didn’t work. The additional_opts variable never contained any value outside of the loop. After some research, I found out, that this is working as intended. This is even mentioned in Jinjas (excellent) Template Designer Documentation:

Please keep in mind that it is not possible to set variables inside a block and have them show up outside of it. This also applies to loops.

And there’s even a proposal how to achieve this use case properly:

As of version 2.10 more complex use cases can be handled using namespace objects which allow propagating of changes across scopes

After reading that, correcting my template didn’t take long. It ended up looking like this:

{% set ns=namespace(additional_opts='') %}
{% for opt_arg, opt_name in [
  (item.exclusive_labels|default(''), '--exclusive_labels'),
  (item.ignore_labels|default(''), '--ignore_labels'),
  (item.exclusive_prefixes|default(''), '--exclusive_prefixes'),
  (item.ignore_prefixes|default(''), '--ignore_prefixes')
] %}
{% if opt_arg %}
{% set ns.additional_opts %}{{ ns.additional_opts }} {{ opt_name }}="{{ opt_arg }}"
{%- endset %}
{% endif %}
{% endfor %}

runme.py {{ ns.additional_opts }}

While this way is a bit less intuitive, it works like a charm.

How I miraculously fixed my Windows 10 startup DNS problems

• windows • Comments

I once again had a great experience with Windows 10. For some reason my DNS resolution stopped working for roughly two minutes after every startup. Of course there was neither an update around that time, nor were there any unusual messages in the Event Viewer. Therefore I had no idea where to look. I tried a couple of things, manually setting different DNS servers, configuring a static IP, and of course doing the classic ipconfig /flushdns and ipconfig /registerdns. To no avail. I still did not have DNS directly after startup. The DNS issues even occured in the first two minutes of Safe Boot Mode.
So, how did I fix it?

Using Custom executables in Steam applications

• steam and gaming • Comments

Nearly 10 years ago, on the 30th December of 2009, I bought League of Legends on Steam. Back in this time, DOTA 2 wasn’t released yet and there was a Digital Collectors Edition for League available on Steam. Therefore, I’m one of the very few users who are playing League of Legends via Steam. But while the League of Legends client was further developed, the game version in Steam did not. Luckily, the small Steam League of Legends community found workarounds, so the tracking of ingame time still works. A couple of months ago, Riot Games, the company behind League of Legends did a major overhaul of the client, renaming the game launcher in the process. This, in connection with the workaround install of League of Legends in Steam lead to an popup message every time the game was started via Steam shortcut:

League of Legends Launcher Shortcut Popup

League of Legends will now update your desktop shortcuts. Your operating system may ask for Administrator permissions.

While I’m not playing League frequently anymore, this popup still annoyed me. As other players also encountered this problem and simply renaming the executables didn’t work, I did some tinkering and incidentally found a solution which probably enables the easy usage of custom executables for every Steam game.

Understanding multi line strings in YAML and Ansible (Part II - Ansible)

• YAML and Ansible • Comments

In Part I of this series we examined the two block styles of YAML, literal and folded, as well as the three block chomping methods, strip, clip and keep. In this post we want to investigate how these styles and methods interact with different Ansible use cases.

Multi line strings in Modules

The classic usage of a multi line string in Ansible is in the command or shell module. This example is directly taken from the Ansible docs:

# You can use shell to run other executables to perform actions inline
- name: Run expect to wait for a successful PXE boot via out-of-band CIMC
  shell: |
    set timeout 300
    spawn ssh [email protected]

    expect "password:"
    send "\n"

    expect "\n"
    send "connect host\n"

    expect "pxeboot.n12"
    send "\n"

    exit 0
  args:
    executable: /usr/bin/expect
  delegate_to: localhost

A literal style block with clip chomping is used to send several commands. Folded style would not make any sense here, except if you wanted to either pipe the commands or chain them with && or ||.

Advertisement