<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Posts on Dev notes</title>
    <link>https://blog.michal.pawlik.dev/posts/</link>
    <description>Recent content in Posts on Dev notes</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <lastBuildDate>Wed, 01 Oct 2025 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://blog.michal.pawlik.dev/posts/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>How to run sbt tasks with custom settings</title>
      <link>https://blog.michal.pawlik.dev/posts/til/sbt-task-with-custom-settings/</link>
      <pubDate>Wed, 01 Oct 2025 00:00:00 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/til/sbt-task-with-custom-settings/</guid>
      <description>&lt;p&gt;When preparing build configuration in sbt, you might want to write custom sbt task. Task in sbt is like a function that can depend on other tasks and project settings.&lt;/p&gt;&#xA;&lt;h2 id=&#34;custom-sbt-tasks&#34;&gt;Custom sbt tasks&lt;/h2&gt;&#xA;&lt;p&gt;To illustrate it, let&amp;rsquo;s write a simple task that validates environment, runs tests and builds an app&lt;/p&gt;&#xA;&lt;div class=&#34;cyber-terminal&#34;&gt;&#xA;  &lt;div class=&#34;cyber-terminal__header&#34;&gt;&#xA;    &lt;span class=&#34;cyber-terminal__dot cyber-terminal__dot--red&#34;&gt;&lt;/span&gt;&#xA;    &lt;span class=&#34;cyber-terminal__dot cyber-terminal__dot--yellow&#34;&gt;&lt;/span&gt;&#xA;    &lt;span class=&#34;cyber-terminal__dot cyber-terminal__dot--green&#34;&gt;&lt;/span&gt;&#xA;    &lt;span class=&#34;cyber-terminal__title&#34;&gt;scala&lt;/span&gt;&#xA;    &lt;button class=&#34;cyber-terminal__copy&#34; type=&#34;button&#34; aria-label=&#34;Copy code&#34; data-copy&gt;&#xA;      &lt;i class=&#34;fa-regular fa-copy&#34;&gt;&lt;/i&gt;&#xA;    &lt;/button&gt;&#xA;  &lt;/div&gt;&#xA;  &lt;div class=&#34;cyber-terminal__body&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code class=&#34;language-scala&#34; data-lang=&#34;scala&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; sbt.&lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;lazy&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;val&lt;/span&gt; validateAndBuild &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; taskKey&lt;span style=&#34;color:#ff79c6&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#8be9fd&#34;&gt;Unit&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;](&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Validates env, runs tests and builds the app&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;val&lt;/span&gt; root &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; project&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;in&lt;span style=&#34;color:#ff79c6&#34;&gt;(&lt;/span&gt;file&lt;span style=&#34;color:#ff79c6&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;.&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;)).&lt;/span&gt;settings&lt;span style=&#34;color:#ff79c6&#34;&gt;(&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  validateAndBuild &lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    validateEnvVars&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    test&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    assembly&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#ff79c6&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&lt;h2 id=&#34;tasks-vs-immutable-settings&#34;&gt;Tasks vs immutable settings&lt;/h2&gt;&#xA;&lt;p&gt;This can be handy when the project grows in complexity. One problem with this approach is that we don&amp;rsquo;t control the inputs to the sub-tasks that we run.&#xA;In sbt, settings are initialized when the project is loaded and are not mutable.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Scala Tooling Spree #1 recap</title>
      <link>https://blog.michal.pawlik.dev/posts/scala/tooling-spree-recap/</link>
      <pubDate>Fri, 31 Jan 2025 00:00:00 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/scala/tooling-spree-recap/</guid>
      <description>&lt;p&gt;On January 30, 2025, the first Scala Tooling Spree took place, and I had the pleasure of being part of it. Here’s a recap of the event. Spoiler alert: it was awesome!&lt;/p&gt;&#xA;&lt;h2 id=&#34;event-details&#34;&gt;Event details&lt;/h2&gt;&#xA;&lt;p&gt;The first Scala Tooling Spree was announced on &lt;a href=&#34;https://discord.com/channels/632642981228314653/632652693013528589/1331562385978429491&#34;&gt;Discord&lt;/a&gt; and &lt;a href=&#34;https://bsky.app/profile/michal.pawlik.dev/post/3lgq2kx7d6s2d&#34;&gt;Bluesky&lt;/a&gt;.&#xA;The event brought together 9 participants who formed 4 teams. Over the course of a 2-hour call, we tackled 4 issues, resulting in 3 pull requests. We had participants with diverse backgrounds, ranging from business application developers to tooling and compiler engineers. Each team had at least one experienced tooling maintainer, ensuring we were never short on expertise!&lt;/p&gt;</description>
    </item>
    <item>
      <title>Understand your build structure and performance</title>
      <link>https://blog.michal.pawlik.dev/posts/til/bloop-performance-tracing/</link>
      <pubDate>Wed, 29 Jan 2025 00:00:00 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/til/bloop-performance-tracing/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;: Today I learned that you can &lt;a href=&#34;https://scalacenter.github.io/bloop/docs/performance-guide&#34;&gt;trace your build performance with bloop&lt;/a&gt;, and it&amp;rsquo;s especially easy when using Metals. The setup might not be obvious for some.&lt;/p&gt;&#xA;&lt;p&gt;When working with &lt;a href=&#34;https://www.scala-sbt.org/1.x/docs/Multi-Project.html&#34;&gt;multi-module&lt;/a&gt; projects, build times can sometimes increase unexpectedly. There are a few ways to analyze that statically, but you can always see the live data from your bloop compilation. Let&amp;rsquo;s explore those options.&lt;/p&gt;&#xA;&lt;h2 id=&#34;static-analysis&#34;&gt;Static analysis&lt;/h2&gt;&#xA;&lt;p&gt;When your &lt;code&gt;build.sbt&lt;/code&gt; file grows complex it&amp;rsquo;s easy to lose track of which depends on which. This not only creates confusion and complicates onboarding, but also to slower builds and frustration in consequence.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Your own Bluesky feed</title>
      <link>https://blog.michal.pawlik.dev/posts/bluesky-feed/</link>
      <pubDate>Wed, 27 Nov 2024 00:00:00 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/bluesky-feed/</guid>
      <description>&lt;p&gt;In this post we&amp;rsquo;ll learn how to build and deploy your own feed on Bluesky. We&amp;rsquo;ll start with some background info on Bluesky and how feeds work. Then we&amp;rsquo;ll code and deploy our own feed. Don&amp;rsquo;t worry about the complexity, it&amp;rsquo;s mostly filling the gaps in the template.&lt;/p&gt;&#xA;&lt;h2 id=&#34;whats-bluesky&#34;&gt;What&amp;rsquo;s Bluesky&lt;/h2&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://bsky.app/&#34;&gt;Bluesky&lt;/a&gt; is a decentralized social network. From the end user perspective, it&amp;rsquo;s very similar to 𝕏 (formerly Twitter).&#xA;It&amp;rsquo;s built with &lt;a href=&#34;https://atproto.com/&#34;&gt;AT Protocol&lt;/a&gt; which allows programmers to interact with the platform.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Useful commands for inspecting sbt build</title>
      <link>https://blog.michal.pawlik.dev/posts/til/inspecting-sbt/</link>
      <pubDate>Wed, 29 May 2024 00:00:00 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/til/inspecting-sbt/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; Today I learned a few useful commands to help you understand complex sbt builds.&lt;/p&gt;&#xA;&lt;h2 id=&#34;task-timing&#34;&gt;task timing&lt;/h2&gt;&#xA;&lt;p&gt;JAVA_OPTS=-Dsbt.task.timings=true sbt&lt;/p&gt;&#xA;&lt;h2 id=&#34;inspecting-task&#34;&gt;inspecting task&lt;/h2&gt;&#xA;&lt;p&gt;inspect module/taskName&lt;/p&gt;&#xA;&lt;h2 id=&#34;inspecting-task-tree&#34;&gt;inspecting task tree&lt;/h2&gt;&#xA;&lt;p&gt;inspect tree module/taskName&lt;/p&gt;</description>
    </item>
    <item>
      <title>Hide irrelevant data in your PRs</title>
      <link>https://blog.michal.pawlik.dev/posts/til/cleaner-pr-diffs/</link>
      <pubDate>Fri, 05 Jan 2024 00:00:00 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/til/cleaner-pr-diffs/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; Today I learned that you can &lt;a href=&#34;https://docs.github.com/en/repositories/working-with-files/managing-files/customizing-how-changed-files-appear-on-github&#34;&gt;hide irrelevant changes from Github PRs&lt;/a&gt;. The syntax for &lt;code&gt;.gitattributes&lt;/code&gt; can be tricky though.&lt;/p&gt;&#xA;&lt;p&gt;In my current project, it&amp;rsquo;s sometimes necessary to re-generate and commit a bunch of files to the repository. This can happen when you store some &lt;a href=&#34;https://en.wikipedia.org/wiki/Infrastructure_as_code&#34;&gt;IaC&lt;/a&gt; or test data in the repository.&lt;/p&gt;&#xA;&lt;h2 id=&#34;sample-repository&#34;&gt;Sample repository&lt;/h2&gt;&#xA;&lt;p&gt;To demonstrate the problem, here&amp;rsquo;s an example repository: &lt;a href=&#34;https://github.com/majk-p/nice-pr-diffs&#34;&gt;https://github.com/majk-p/nice-pr-diffs&lt;/a&gt; that features two PRs:&lt;/p&gt;&#xA;&lt;p&gt;The first one is hard to read &lt;a href=&#34;https://github.com/majk-p/nice-pr-diffs/pull/1/files&#34;&gt;https://github.com/majk-p/nice-pr-diffs/pull/1/files&lt;/a&gt; because it features a wall of text - new testing data that has been added.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Integration testing with Weaver and Localstack</title>
      <link>https://blog.michal.pawlik.dev/posts/scala/weaver-localstack/</link>
      <pubDate>Fri, 29 Dec 2023 00:00:00 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/scala/weaver-localstack/</guid>
      <description>&lt;p&gt;When creating software that makes heavy use of cloud infrastructure, it is wise to test the integration in the end-to-end fashion. Doing so in cloud environment is one option, but it may not be viable for all cases. It can be pricy and you cannot do it in an local environment.&lt;/p&gt;&#xA;&lt;p&gt;A popular solution to this problem is to run &lt;a href=&#34;https://www.localstack.cloud/&#34;&gt;Localstack&lt;/a&gt; and test your code against it. In this post we&amp;rsquo;ll explore how to manage your Localstack resources for E2E tests using &lt;a href=&#34;https://testcontainers.com/&#34;&gt;Testcontainers&lt;/a&gt;, &lt;a href=&#34;https://typelevel.org/cats-effect/docs/std/resource&#34;&gt;Cats-effect &lt;code&gt;Resource&lt;/code&gt;&lt;/a&gt; and &lt;a href=&#34;https://disneystreaming.github.io/weaver-test/&#34;&gt;Weaver&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Type safety with Iron</title>
      <link>https://blog.michal.pawlik.dev/posts/scala/iron/</link>
      <pubDate>Fri, 25 Aug 2023 00:00:00 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/scala/iron/</guid>
      <description>&lt;p&gt;This article is a follow up to &lt;a href=&#34;https://blog.michal.pawlik.dev/posts/scala/refined&#34;&gt;Type safety with refined&lt;/a&gt;, make sure to check it out if you haven&amp;rsquo;t.&lt;/p&gt;&#xA;&lt;p&gt;In this one we&amp;rsquo;ll repeat the same thing but this time using &lt;a href=&#34;https://blog.michal.pawlik.dev/posts/scala/refined/&#34;&gt;iron&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;unsafe-approach&#34;&gt;Unsafe approach&lt;/h2&gt;&#xA;&lt;p&gt;Similarly to the previous post, we&amp;rsquo;ll try to refactor the code below to eliminate the handwritten value checks. The goal is to express our business requirements using the type-system.&lt;/p&gt;&#xA;&lt;div class=&#34;cyber-terminal&#34;&gt;&#xA;  &lt;div class=&#34;cyber-terminal__header&#34;&gt;&#xA;    &lt;span class=&#34;cyber-terminal__dot cyber-terminal__dot--red&#34;&gt;&lt;/span&gt;&#xA;    &lt;span class=&#34;cyber-terminal__dot cyber-terminal__dot--yellow&#34;&gt;&lt;/span&gt;&#xA;    &lt;span class=&#34;cyber-terminal__dot cyber-terminal__dot--green&#34;&gt;&lt;/span&gt;&#xA;    &lt;span class=&#34;cyber-terminal__title&#34;&gt;scala&lt;/span&gt;&#xA;    &lt;button class=&#34;cyber-terminal__copy&#34; type=&#34;button&#34; aria-label=&#34;Copy code&#34; data-copy&gt;&#xA;      &lt;i class=&#34;fa-regular fa-copy&#34;&gt;&lt;/i&gt;&#xA;    &lt;/button&gt;&#xA;  &lt;/div&gt;&#xA;  &lt;div class=&#34;cyber-terminal__body&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code class=&#34;language-scala&#34; data-lang=&#34;scala&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//&amp;gt; using scala &amp;#34;2&amp;#34;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;UnsafeOrderLine&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;(&lt;/span&gt;product&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd&#34;&gt;String&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;,&lt;/span&gt; quantity&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd&#34;&gt;Int&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;object&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;UnsafeOrderLine&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#ff79c6&#34;&gt;def&lt;/span&gt; safeApply&lt;span style=&#34;color:#ff79c6&#34;&gt;(&lt;/span&gt;product&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd&#34;&gt;String&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;,&lt;/span&gt; quantity&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd&#34;&gt;Int&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd&#34;&gt;UnsafeOrderLine&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;(&lt;/span&gt;product&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;isEmpty&lt;span style=&#34;color:#ff79c6&#34;&gt;())&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#ff79c6&#34;&gt;throw&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;RuntimeException&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Product is empty&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#ff79c6&#34;&gt;else&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;(&lt;/span&gt;quantity &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#ff79c6&#34;&gt;throw&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;RuntimeException&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Quantity lower than 1&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#ff79c6&#34;&gt;else&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#50fa7b&#34;&gt;UnsafeOrderLine&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;(&lt;/span&gt;product&lt;span style=&#34;color:#ff79c6&#34;&gt;,&lt;/span&gt; quantity&lt;span style=&#34;color:#ff79c6&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#ff79c6&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;// Works fine!&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;println&lt;span style=&#34;color:#ff79c6&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#50fa7b&#34;&gt;UnsafeOrderLine&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;safeApply&lt;span style=&#34;color:#ff79c6&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;123&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;10&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;// Throws runtime exception 👇&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#50fa7b&#34;&gt;UnsafeOrderLine&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;safeApply&lt;span style=&#34;color:#ff79c6&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;10&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&lt;h2 id=&#34;iron&#34;&gt;Iron&lt;/h2&gt;&#xA;&lt;p&gt;Iron is a library for refined types developed in Scala 3. To use it in your project simply add the dependency to sbt/scala-cli&lt;/p&gt;</description>
    </item>
    <item>
      <title>Introduction to optics in Scala</title>
      <link>https://blog.michal.pawlik.dev/posts/scala/optics/</link>
      <pubDate>Tue, 11 Jul 2023 00:00:00 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/scala/optics/</guid>
      <description>&lt;p&gt;Throughout this blog I&amp;rsquo;ve mentioned the benefits of having a strong type system a multiple times. I&amp;rsquo;ve covered &lt;a href=&#34;https://blog.michal.pawlik.dev/posts/scala/refined/&#34;&gt;type refinement for value validation&lt;/a&gt;, &lt;a href=&#34;https://blog.michal.pawlik.dev/posts/scala/scala-derivations/&#34;&gt;beginner friendly&lt;/a&gt; and &lt;a href=&#34;https://blog.michal.pawlik.dev/posts/scala/scala-derivations-show/&#34;&gt;advanced approach&lt;/a&gt; to type-class derivation or type-safe approach to &lt;a href=&#34;https://blog.michal.pawlik.dev/posts/scala/pass4s-basics/&#34;&gt;messaging with pass4s&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;The possibilities are endless though, so today I want to introduce another topic, that beginners in languages like Scala or Haskell might not be aware of.&lt;/p&gt;&#xA;&lt;p&gt;In this post I&amp;rsquo;ll talk about &lt;strong&gt;Optics&lt;/strong&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;meet-optics&#34;&gt;Meet Optics&lt;/h2&gt;&#xA;&lt;p&gt;Optics is an umbrella term for accessing and transforming immutable data. We&amp;rsquo;ll explore the world of optics with the great library &lt;a href=&#34;https://www.optics.dev/Monocle/&#34;&gt;Monocle&lt;/a&gt;. Before we get started, let&amp;rsquo;s set the stage and with some problem we can refer to.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Intermediate&#39;s guide to derivations in Scala: Magnolia</title>
      <link>https://blog.michal.pawlik.dev/posts/scala/scala-derivations-show/</link>
      <pubDate>Sun, 07 May 2023 00:00:00 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/scala/scala-derivations-show/</guid>
      <description>&lt;p&gt;In the &lt;a href=&#34;https://blog.michal.pawlik.dev/posts/scala/scala-derivations/&#34;&gt;previous post&lt;/a&gt; about Scala derivation I&amp;rsquo;ve explained the idea of derivation and showed how we can benefit from it by using library-provided derivations. This time let&amp;rsquo;s dig deeper and implement our own derviation with &lt;a href=&#34;https://github.com/softwaremill/magnolia&#34;&gt;Magnolia&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; This post is intended for intermediate Scala users, if you are not familiar with the topic I recommend starting with the &lt;a href=&#34;https://blog.michal.pawlik.dev/posts/scala/scala-derivations/&#34;&gt;beginner introduction&lt;/a&gt; first&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;h2 id=&#34;-recap&#34;&gt;♻️ Recap&lt;/h2&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; you can skip this section if you remember the previous post, it&amp;rsquo;s just a recap&lt;/p&gt;</description>
    </item>
    <item>
      <title>Beginner&#39;s guide to derivations in Scala</title>
      <link>https://blog.michal.pawlik.dev/posts/scala/scala-derivations/</link>
      <pubDate>Sun, 23 Apr 2023 00:00:00 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/scala/scala-derivations/</guid>
      <description>&lt;p&gt;When learning about Scala, there are a few things that might be surprising. One of such mechanisms is code derivation. With this post I want to demystify the term for those of you who are learning Scala and functional programming in general.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; This post is intended for Scala beginners and does not go into the details of building your own derivation. Instead, it shows the client side of things, aiming to show the impact on the code simplification.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Tech bytes #5 in Kraków recap</title>
      <link>https://blog.michal.pawlik.dev/posts/tech-bytes-5-krakow-recap/</link>
      <pubDate>Thu, 16 Mar 2023 00:00:00 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/tech-bytes-5-krakow-recap/</guid>
      <description>&lt;p&gt;Last Thursday (13.04.2023) I had the pleasure to speak at the 5th edition of &lt;a href=&#34;https://www.meetup.com/pl-PL/tech-bytes-ocado-technology-krakow/events/292412394/&#34;&gt;Tech Bytes&lt;/a&gt; in Kraków.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; This post is a short recap of the event&lt;/p&gt;&#xA;&lt;h1 id=&#34;-the-right-tools-for-the-right-job&#34;&gt;🔧 The right tools for the right job&lt;/h1&gt;&#xA;&lt;p&gt;This edition had two talks scheduled, both focused on programming languages, specifically Scala and Elixir. &amp;ldquo;The right tools for the right job&amp;rdquo; was the topic of the meeting.&lt;/p&gt;&#xA;&lt;p&gt;The talks were:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;em&gt;Get rid of boilerplate with Scala&lt;/em&gt; by myself&lt;/li&gt;&#xA;&lt;li&gt;&lt;em&gt;What is Elixir and what it can do with concurrency challenges? - sharing Elixirator insights&lt;/em&gt; by Józef Pawlikowski and Alexander Sosnovskiy&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Sadly Alexander wasn&amp;rsquo;t able to join us but Józef did his best to present his peer&amp;rsquo;s part.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Beginner&#39;s guide to toolkits in Scala</title>
      <link>https://blog.michal.pawlik.dev/posts/scala/scala-toolkits/</link>
      <pubDate>Sat, 11 Mar 2023 00:00:00 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/scala/scala-toolkits/</guid>
      <description>&lt;p&gt;So you are learning Scala and see all the news about &lt;a href=&#34;https://scala-cli.virtuslab.org/&#34;&gt;scala-cli&lt;/a&gt; and it becoming the new &lt;a href=&#34;https://github.com/scala/improvement-proposals/pull/46&#34;&gt;scala runner&lt;/a&gt;, &lt;a href=&#34;https://github.com/scala/toolkit&#34;&gt;Scala Toolkit&lt;/a&gt;, &lt;a href=&#34;https://github.com/typelevel/toolkit&#34;&gt;Typelevel Toolkit&lt;/a&gt; and things become a little confusing?&lt;/p&gt;&#xA;&lt;p&gt;This post is here to help you understand what&amp;rsquo;s going on. To make some sense of it, let&amp;rsquo;s tell a bit of a story.&lt;/p&gt;&#xA;&lt;h2 id=&#34;-scala-runner-and-scala-cli&#34;&gt;💻 Scala runner and scala-cli&lt;/h2&gt;&#xA;&lt;p&gt;First of all, what&amp;rsquo;s Scala runner? basically it&amp;rsquo;s the program that you launch by typing &lt;code&gt;scala&lt;/code&gt; in your terminal. It can launch a basic REPL or run provided Scala file, but not much more.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Proxy large messages via S3 with pass4s</title>
      <link>https://blog.michal.pawlik.dev/posts/scala/pass4s-s3-proxy/</link>
      <pubDate>Sun, 05 Mar 2023 00:00:00 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/scala/pass4s-s3-proxy/</guid>
      <description>&lt;p&gt;In the &lt;a href=&#34;https://blog.michal.pawlik.dev/posts/scala/pass4s-codecs/&#34;&gt;previous post&lt;/a&gt; we have learned how pass JSON and XML messages via the SNS/SQS using &lt;a href=&#34;https://github.com/ocadotechnology/pass4s&#34;&gt;pass4s&lt;/a&gt;. This time we&amp;rsquo;ll focus on another problem, often faced when implementing messaging in backend systems. We&amp;rsquo;ll learn how to handle large messages.&lt;/p&gt;&#xA;&lt;p&gt;As with previous posts, you&amp;rsquo;ll find all code examples in the companion repository &lt;a href=&#34;https://github.com/majk-p/pass4s-playground&#34;&gt;https://github.com/majk-p/pass4s-playground&lt;/a&gt;. Along the way I also might refer to the code in that repo.&lt;/p&gt;&#xA;&lt;h1 id=&#34;the-problem&#34;&gt;The problem&lt;/h1&gt;&#xA;&lt;p&gt;Let&amp;rsquo;s begin with how a typical SNS-SQS setup looks like. A simple diagram might look like this:&lt;/p&gt;</description>
    </item>
    <item>
      <title>JSON and XML messaging with pass4s</title>
      <link>https://blog.michal.pawlik.dev/posts/scala/pass4s-codecs/</link>
      <pubDate>Mon, 27 Feb 2023 00:00:00 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/scala/pass4s-codecs/</guid>
      <description>&lt;p&gt;In the &lt;a href=&#34;https://blog.michal.pawlik.dev/posts/scala/pass4s-basics/&#34;&gt;previous post&lt;/a&gt; we have learned how implement the SNS/SQS based message flow using &lt;a href=&#34;https://github.com/ocadotechnology/pass4s&#34;&gt;pass4s&lt;/a&gt;. The examples only shown how to exchange basic string messages. In this one I&amp;rsquo;ll show you how to exchange more complex types and serialize them in transport. Examples shown in this post are also available in &lt;a href=&#34;https://github.com/majk-p/pass4s-playground/&#34;&gt;https://github.com/majk-p/pass4s-playground/&lt;/a&gt; so feel free to clone and play around.&lt;/p&gt;&#xA;&lt;p&gt;Pass4s is elastic in terms of message encoding, it provides JSON and XML serialization mechanisms out of the box.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Functional messaging in Scala with pass4s</title>
      <link>https://blog.michal.pawlik.dev/posts/scala/pass4s-basics/</link>
      <pubDate>Sat, 25 Feb 2023 00:00:00 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/scala/pass4s-basics/</guid>
      <description>&lt;p&gt;The &lt;a href=&#34;https://github.com/ocadotechnology/pass4s&#34;&gt;pass4s&lt;/a&gt; provides a functional abstraction for messaging in Scala. It provides implementations for AWS SQS/SNS and ActiveMQ.&lt;/p&gt;&#xA;&lt;p&gt;In this post I want to show you the basic usage of the library to implement the messaging on top of SNS/SQS. All the examples in this post can be found in &lt;a href=&#34;https://github.com/majk-p/pass4s-playground&#34;&gt;https://github.com/majk-p/pass4s-playground&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;localstack&#34;&gt;Localstack&lt;/h2&gt;&#xA;&lt;p&gt;Before we see the Scala code, let&amp;rsquo;s setup &lt;a href=&#34;https://docs.localstack.cloud/overview/&#34;&gt;localstack&lt;/a&gt;, set up a SNS (Simple Notification Service) topic, SQS (Simple Queue Service) queue and a subscription between them.&#xA;This post assumes you have a basic understanding of SNS/SQS setup. If you need a refresher please refer to this part of AWS docs: &lt;a href=&#34;https://docs.aws.amazon.com/sns/latest/dg/subscribe-sqs-queue-to-sns-topic.html&#34;&gt;https://docs.aws.amazon.com/sns/latest/dg/subscribe-sqs-queue-to-sns-topic.html&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>TIL: Launching flashlight with Typescript is insane</title>
      <link>https://blog.michal.pawlik.dev/posts/til/flashlight-using-typescript/</link>
      <pubDate>Wed, 08 Feb 2023 00:00:00 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/til/flashlight-using-typescript/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; I wanted to launch a flashlight on Android device using Typescript and the experience was &lt;em&gt;far from ideal&lt;/em&gt;.&lt;/p&gt;&#xA;&lt;h1 id=&#34;the-task&#34;&gt;The task&lt;/h1&gt;&#xA;&lt;p&gt;Background: there&amp;rsquo;s a web application that runs a camera to scan for QR codes. Sometimes the light conditions are poor and scanning is difficult.&lt;/p&gt;&#xA;&lt;p&gt;The task: Launch the flashlight to improve the scanning experience.&lt;/p&gt;&#xA;&lt;p&gt;Doesn&amp;rsquo;t sound that difficult, does it?&lt;/p&gt;&#xA;&lt;h1 id=&#34;meet-the-camera-api&#34;&gt;Meet the camera API&lt;/h1&gt;&#xA;&lt;p&gt;So we want to obtain the camera stream, how do we do that? It seems the answer is simple. Meet the &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia&#34;&gt;MediaDevices.getUserMedia()&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Your own Home Assistant add-on</title>
      <link>https://blog.michal.pawlik.dev/posts/smarthome/home-assistant-addons/</link>
      <pubDate>Sat, 04 Feb 2023 23:00:00 +0100</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/smarthome/home-assistant-addons/</guid>
      <description>&lt;p&gt;In the previous post in the series I described the process of externalizing you HA (Home Assistant) using my custom addon. Make sure to check &lt;a href=&#34;https://blog.michal.pawlik.dev/posts/smarthome/expose-home-assistant/&#34;&gt;that out&lt;/a&gt; if you haven&amp;rsquo;t already. This time I&amp;rsquo;ll share the details of the add-on development process.&lt;/p&gt;&#xA;&lt;h1 id=&#34;first-steps&#34;&gt;First steps&lt;/h1&gt;&#xA;&lt;p&gt;When building the add-on my first steps obviously went towards the existing online resources. The first thing I&amp;rsquo;ve found was the extensive tutorial on &lt;a href=&#34;https://developers.home-assistant.io/docs/add-ons/tutorial&#34;&gt;https://developers.home-assistant.io/docs/add-ons/tutorial&lt;/a&gt;, but there seems to be an easier hands-on approach. Instead of following the tutorial we&amp;rsquo;ll use the official template from &lt;a href=&#34;https://github.com/home-assistant/addons-example&#34;&gt;https://github.com/home-assistant/addons-example&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Wrocław Scala User Group #2</title>
      <link>https://blog.michal.pawlik.dev/posts/wsug-002/</link>
      <pubDate>Sun, 29 Jan 2023 00:00:00 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/wsug-002/</guid>
      <description>&lt;p&gt;In this post I want to share a short recap of first Wrocław Scala User Group (WSUG) meetup. This will be kind of TIL entry, it doesn&amp;rsquo;t aim to cover the full presentation content. If you&amp;rsquo;d like to join the next meeting, join us at &lt;a href=&#34;https://www.meetup.com/pl-PL/wroclaw-scala-user-group/&#34;&gt;Wroclaw Scala User Group at meetup.com&lt;/a&gt;. The meetup was held in Polish so the slides are not translated.&lt;/p&gt;&#xA;&lt;h2 id=&#34;first-talk---pain-free-apis-with-smithy4s---jakub-kozłowski-kubukozhttpsgithubcomkubukoz&#34;&gt;First talk - ‘Pain-free APIs with Smithy4s’ - Jakub Kozłowski &lt;a href=&#34;https://github.com/kubukoz&#34;&gt;kubukoz&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;In this talk Jakub introduced us to Smithy - an IDL (Interface Definition Language) built for defining implementation agnostic API descriptions. During the talk we have focused on the aspects that are difficult when designing and evolving a system, namely the communication problems.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Externalize Home Assistant</title>
      <link>https://blog.michal.pawlik.dev/posts/smarthome/expose-home-assistant/</link>
      <pubDate>Fri, 20 Jan 2023 10:30:00 +0100</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/smarthome/expose-home-assistant/</guid>
      <description>&lt;p&gt;This is a third post in the Smart Home series. See the previous post if you haven&amp;rsquo;t already: &lt;a href=&#34;https://blog.michal.pawlik.dev/posts/smarthome/zigbee-setup/&#34;&gt;https://blog.michal.pawlik.dev/posts/smarthome/zigbee-setup/&lt;/a&gt;. Last time I wrote about Zigbee and shown how to control smart home devices. In this post I want to show you one of many ways you can use to expose your HA (Home Assistant) instance to the internet.&lt;/p&gt;&#xA;&lt;h2 id=&#34;why-expose&#34;&gt;Why expose?&lt;/h2&gt;&#xA;&lt;p&gt;All of the examples in previous posts were referring to local instance of Home Assistant. To work with it you had to be with the same network. While it&amp;rsquo;s not a problem when you are at home, there are cases when you want to access HA from the external network. Those cases include controlling the heat, accessing monitoring, switching light etc. when you are not home.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Wrocław Java User Group</title>
      <link>https://blog.michal.pawlik.dev/posts/wjug-0198/</link>
      <pubDate>Sat, 14 Jan 2023 00:00:00 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/wjug-0198/</guid>
      <description>&lt;p&gt;In this post I want to share a short recap of first Wrocław Scala Java Group (WSUG) meetup. This will be kind of TIL entry, it doesn&amp;rsquo;t aim to cover the full presentation content. You can find the full agenda at the &lt;a href=&#34;https://www.meetup.com/pl-PL/wroclawjug/events/290615129/&#34;&gt;event page&lt;/a&gt;. If you&amp;rsquo;d like to join the next meeting, join us at &lt;a href=&#34;https://www.meetup.com/pl-PL/WroclawJUG/&#34;&gt;Wroclaw Java User Group at meetup.com&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;We just had one talk this time, and it was delivered by yours truly.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Zigbee with Home Assistant - Smart Home</title>
      <link>https://blog.michal.pawlik.dev/posts/smarthome/zigbee-setup/</link>
      <pubDate>Thu, 05 Jan 2023 16:30:00 +0100</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/smarthome/zigbee-setup/</guid>
      <description>&lt;p&gt;This is a second post in the Smart Home series. See the previous post if you haven&amp;rsquo;t already: &lt;a href=&#34;https://blog.michal.pawlik.dev/posts/smarthome/smart-home-getting-started/&#34;&gt;https://blog.michal.pawlik.dev/posts/smarthome/smart-home-getting-started/&lt;/a&gt;. Last time we have set up the HA (Home Assistant), in this post we&amp;rsquo;ll learn about Zigbee and control some devices.&lt;/p&gt;&#xA;&lt;h2 id=&#34;zigbee&#34;&gt;Zigbee&lt;/h2&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Zigbee&#34;&gt;Zigbee&lt;/a&gt; is a specification for wireless communication protocols, very common solution for building home automation networks.&lt;/p&gt;&#xA;&lt;p&gt;Explaining new terms is always easier when there&amp;rsquo;s something well known you can relate to, so before describing Zigbee let&amp;rsquo;s recall something familiar, the typical WiFi network.&lt;/p&gt;</description>
    </item>
    <item>
      <title>TIL: Debugging Hugo - fixing publish date</title>
      <link>https://blog.michal.pawlik.dev/posts/til/publish-date-in-hugo/</link>
      <pubDate>Wed, 04 Jan 2023 17:15:00 +0100</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/til/publish-date-in-hugo/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; Today I learned how to fix post visibility by reading the documentation &lt;a href=&#34;https://gohugo.io/getting-started/usage/#draft-future-and-expired-content&#34;&gt;https://gohugo.io/getting-started/usage/#draft-future-and-expired-content&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;Last night I&amp;rsquo;ve been finishing my first blog post this year. Upon finishing the text and finding the icon it&amp;rsquo;s time to fill the metadata. Midnight was minutes away so I set the publish date to &lt;code&gt;2023-01-04&lt;/code&gt; (next day) and set the &lt;code&gt;draft&lt;/code&gt; flag to &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-problem&#34;&gt;The problem&lt;/h2&gt;&#xA;&lt;p&gt;Imagine how surprising it was to notice that the article I just wrote doesn&amp;rsquo;t show up on the main page. Time to debug. First thing is to double check the &lt;code&gt;draft&lt;/code&gt; state - all good. Perhaps I&amp;rsquo;ve made it &lt;code&gt;2022-01-04&lt;/code&gt; and the post landed a year back? nope, date&amp;rsquo;s correct.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Let&#39;s build a smart home</title>
      <link>https://blog.michal.pawlik.dev/posts/smarthome/smart-home-getting-started/</link>
      <pubDate>Wed, 04 Jan 2023 00:01:00 +0100</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/smarthome/smart-home-getting-started/</guid>
      <description>&lt;p&gt;New year is always a good excuse to start something new. This post starts a series on building a smart home. It&amp;rsquo;s not going to be a tutorial written by an expert, quite the opposite, I want to share my thoughts and experiences while learning.&lt;/p&gt;&#xA;&lt;p&gt;At this point I want to give credit to Kinga and Mikołaj - friends of my who inspired me with their smart home setup and guidance through first steps.&lt;/p&gt;</description>
    </item>
    <item>
      <title>On automating stuff</title>
      <link>https://blog.michal.pawlik.dev/posts/on-automating-stuff/</link>
      <pubDate>Thu, 29 Dec 2022 00:00:00 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/on-automating-stuff/</guid>
      <description>&lt;h2 id=&#34;note-on-automation&#34;&gt;Note on automation&lt;/h2&gt;&#xA;&lt;p&gt;A while back when I was working as an &lt;a href=&#34;https://en.wikipedia.org/wiki/Site_reliability_engineering&#34;&gt;SRE&lt;/a&gt;. I&amp;rsquo;ve learned this one approach that has proven useful multiple times. Whenever I prototype something, even if it&amp;rsquo;s as simple as one liner in bash, I put it into the file, making it a script. In the process I&amp;rsquo;d usually prepare a few of the, trying my best to name them meaningfully, put up a concise readme and push them to some repo.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Story of a burned down server</title>
      <link>https://blog.michal.pawlik.dev/posts/vps-from-ashes/</link>
      <pubDate>Tue, 27 Dec 2022 00:00:00 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/vps-from-ashes/</guid>
      <description>&lt;p&gt;Do you know that feeling, waking up in the morning just to learn your website and self hosted services are down for unknown reason? That moment when you feel your VPS has &lt;strong&gt;literally&lt;/strong&gt; moved to the cloud?&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-fire&#34;&gt;The fire&lt;/h2&gt;&#xA;&lt;p&gt;This is exactly what happened to me one day of March in 2021. I woke up in the morning, checked the news and learned that there&amp;rsquo;s an fire incident in SBG2 (sources: &lt;a href=&#34;https://us.ovhcloud.com/press/press-releases/2021/fire-our-strasbourg-site&#34;&gt;reference1&lt;/a&gt; &lt;a href=&#34;https://www.datacenterknowledge.com/uptime/fire-has-destroyed-ovh-s-strasbourg-data-center-sbg2&#34;&gt;reference2&lt;/a&gt;). My first thought this is why we do backups, then I realized I&amp;rsquo;m really going to use them. My main VPS was there and it was not responding.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Personal blog: choosing a platform</title>
      <link>https://blog.michal.pawlik.dev/posts/blog-platform/</link>
      <pubDate>Fri, 23 Dec 2022 00:00:00 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/blog-platform/</guid>
      <description>&lt;p&gt;Say you want to start a blog, perhaps even join &lt;a href=&#34;https://100daystooffload.com/&#34;&gt;#100DaysToOffload&lt;/a&gt;. There are some questions you need to ask yourself. How do I start? Do I create an account somewhere? Should I build a website?&lt;/p&gt;&#xA;&lt;p&gt;For the starters, you have two options. You can either go for using a platform or for self hosted.&lt;/p&gt;&#xA;&lt;h2 id=&#34;blogging-platforms&#34;&gt;Blogging platforms&lt;/h2&gt;&#xA;&lt;p&gt;Say you want someone to host the platform for you, then you have some better and worse choices. There is a plenty of platforms like medium.com, wordpress.com and alike. Some people try using platforms like instagram which I consider a terrible idea.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Using Caddy server as a reverse proxy</title>
      <link>https://blog.michal.pawlik.dev/posts/caddy-reverse-proxy/</link>
      <pubDate>Mon, 19 Dec 2022 00:00:00 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/caddy-reverse-proxy/</guid>
      <description>&lt;p&gt;In this post I want to share a simple solution for the simple problem I wanted to solve some time ago. The problem definition is following:&lt;/p&gt;&#xA;&lt;p&gt;I have a top level domain and a VPS operating on it. I also have a blog you are reading now hosted with &lt;a href=&#34;https://docs.gitlab.com/ee/user/project/pages/&#34;&gt;Gitlab Pages&lt;/a&gt;. I want to host a website from my top level domain.&lt;/p&gt;&#xA;&lt;p&gt;Hosting pages using Gitlab pages (similarly to &lt;a href=&#34;https://pages.github.com/&#34;&gt;Github Pages&lt;/a&gt;) is very convenient to set up, you just set up a pipeline and a subdomain configure the subdomain.&lt;/p&gt;</description>
    </item>
    <item>
      <title>TIL: Markdown presentations with Marp</title>
      <link>https://blog.michal.pawlik.dev/posts/til/presentations-with-marp/</link>
      <pubDate>Sun, 18 Dec 2022 00:00:00 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/til/presentations-with-marp/</guid>
      <description>&lt;p&gt;Lately I&amp;rsquo;ve been working on preparing learning materials in Scala. Usually when I work on preparing slides for public speaking I would use &lt;a href=&#34;https://slides.com/majkp/&#34;&gt;https://slides.com/majkp/&lt;/a&gt;, but this time I was looking for something self hosted.&lt;/p&gt;&#xA;&lt;p&gt;In this situation &lt;a href=&#34;https://revealjs.com/&#34;&gt;Reveal.js&lt;/a&gt; seems like an obvious alternative, but if you want to set up, you either have to download a fixed version which makes the upgrade hard, or build an npm project and add reveal as the dependency.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Scala type bounds - &lt;: vs &lt;:&lt;</title>
      <link>https://blog.michal.pawlik.dev/posts/scala/type-bounds-symbols/</link>
      <pubDate>Fri, 16 Dec 2022 00:00:00 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/scala/type-bounds-symbols/</guid>
      <description>&lt;p&gt;In this short entry I want to shed some light at the difference between &lt;code&gt;&amp;lt;:&lt;/code&gt; and &lt;code&gt;&amp;lt;:&amp;lt;&lt;/code&gt; in Scala.&lt;/p&gt;&#xA;&lt;p&gt;TL;DR&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;:&lt;/code&gt; is a language feature built into the compiler: upper type bound&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;:&amp;lt;&lt;/code&gt; is it&amp;rsquo;s generalization: generalized type constraints - it&amp;rsquo;s provided in the standard library&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Let&amp;rsquo;s start with the first one. &lt;code&gt;&amp;lt;:&lt;/code&gt; is called the &lt;a href=&#34;https://docs.scala-lang.org/tour/upper-type-bounds.html&#34;&gt;upper type bound&lt;/a&gt;.&#xA;We use it to express type boundaries for generic types as for example here:&lt;/p&gt;</description>
    </item>
    <item>
      <title>100 days to offload tracker</title>
      <link>https://blog.michal.pawlik.dev/posts/100-days-to-offload-list/</link>
      <pubDate>Thu, 15 Dec 2022 00:00:00 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/100-days-to-offload-list/</guid>
      <description>&lt;p&gt;This is a list of articles I wrote during my &lt;code&gt;#100DaysToOffload&lt;/code&gt;:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://blog.michal.pawlik.dev/posts/100-days-to-offload/&#34;&gt;https://blog.michal.pawlik.dev/posts/100-days-to-offload/&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://blog.michal.pawlik.dev/posts/wsug-001/&#34;&gt;https://blog.michal.pawlik.dev/posts/wsug-001/&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://blog.michal.pawlik.dev/posts/recruitment-homeworks-considered-harmful/&#34;&gt;https://blog.michal.pawlik.dev/posts/recruitment-homeworks-considered-harmful/&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://blog.michal.pawlik.dev/posts/til/value-class-typescript/&#34;&gt;https://blog.michal.pawlik.dev/posts/til/value-class-typescript/&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://blog.michal.pawlik.dev/posts/scala/type-bounds-symbols/&#34;&gt;https://blog.michal.pawlik.dev/posts/scala/type-bounds-symbols/&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://blog.michal.pawlik.dev/posts/til/presentations-with-marp/&#34;&gt;https://blog.michal.pawlik.dev/posts/til/presentations-with-marp/&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://blog.michal.pawlik.dev/posts/caddy-reverse-proxy/&#34;&gt;https://blog.michal.pawlik.dev/posts/caddy-reverse-proxy/&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://blog.michal.pawlik.dev/posts/blog-platform/&#34;&gt;https://blog.michal.pawlik.dev/posts/blog-platform/&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://blog.michal.pawlik.dev/posts/vps-from-ashes/&#34;&gt;https://blog.michal.pawlik.dev/posts/vps-from-ashes/&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://blog.michal.pawlik.dev/posts/smarthome/smart-home-getting-started/&#34;&gt;https://blog.michal.pawlik.dev/posts/smarthome/smart-home-getting-started/&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://blog.michal.pawlik.dev/posts/til/publish-date-in-hugo/&#34;&gt;https://blog.michal.pawlik.dev/posts/til/publish-date-in-hugo/&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://blog.michal.pawlik.dev/posts/smarthome/zigbee-setup/&#34;&gt;https://blog.michal.pawlik.dev/posts/smarthome/zigbee-setup/&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://blog.michal.pawlik.dev/posts/wjug-0198/&#34;&gt;https://blog.michal.pawlik.dev/posts/wjug-0198/&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://blog.michal.pawlik.dev/posts/smarthome/expose-home-assistant/&#34;&gt;https://blog.michal.pawlik.dev/posts/smarthome/expose-home-assistant/&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://blog.michal.pawlik.dev/posts/wsug-002/&#34;&gt;https://blog.michal.pawlik.dev/posts/wsug-002/&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://blog.michal.pawlik.dev/posts/smarthome/home-assistant-addons/&#34;&gt;https://blog.michal.pawlik.dev/posts/smarthome/home-assistant-addons/&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://blog.michal.pawlik.dev/posts/til/flashlight-using-typescript/&#34;&gt;https://blog.michal.pawlik.dev/posts/til/flashlight-using-typescript/&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://blog.michal.pawlik.dev/posts/scala/pass4s-basics/&#34;&gt;https://blog.michal.pawlik.dev/posts/scala/pass4s-basics/&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://blog.michal.pawlik.dev/posts/scala/pass4s-codecs/&#34;&gt;https://blog.michal.pawlik.dev/posts/scala/pass4s-codecs/&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://blog.michal.pawlik.dev/posts/scala/pass4s-s3-proxy/&#34;&gt;https://blog.michal.pawlik.dev/posts/scala/pass4s-s3-proxy/&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://blog.michal.pawlik.dev/posts/scala/scala-toolkits/&#34;&gt;https://blog.michal.pawlik.dev/posts/scala/scala-toolkits/&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://blog.michal.pawlik.dev/posts/tech-bytes-5-krakow-recap/&#34;&gt;https://blog.michal.pawlik.dev/posts/tech-bytes-5-krakow-recap/&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://blog.michal.pawlik.dev/posts/scala/scala-derivations/&#34;&gt;https://blog.michal.pawlik.dev/posts/scala/scala-derivations/&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;</description>
    </item>
    <item>
      <title>Recruitment homework considered harmful</title>
      <link>https://blog.michal.pawlik.dev/posts/recruitment-homeworks-considered-harmful/</link>
      <pubDate>Thu, 15 Dec 2022 00:00:00 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/recruitment-homeworks-considered-harmful/</guid>
      <description>&lt;p&gt;Job interview is not an easy thing, neither for the candidate, nor the recruiters. From the candidate&amp;rsquo;s perspective it&amp;rsquo;s stressful to be questioned, the recruiters need to make a good judgement. Interview process is a thing that&amp;rsquo;s easy to make wrong and expensive to make right. Recruitment mistakes are difficult to fix, when you hire someone and you haven&amp;rsquo;t tested them well enough it&amp;rsquo;s not an easy mistake to revert.&lt;/p&gt;</description>
    </item>
    <item>
      <title>TIL: Mimic value class in Typescript</title>
      <link>https://blog.michal.pawlik.dev/posts/til/value-class-typescript/</link>
      <pubDate>Thu, 15 Dec 2022 00:00:00 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/til/value-class-typescript/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; Today I learned how to mimic Scala-like value class in Typescript&lt;/p&gt;&#xA;&lt;p&gt;Doing day to day scala I often use value classes to model the data like:&lt;/p&gt;&#xA;&lt;div class=&#34;cyber-terminal&#34;&gt;&#xA;  &lt;div class=&#34;cyber-terminal__header&#34;&gt;&#xA;    &lt;span class=&#34;cyber-terminal__dot cyber-terminal__dot--red&#34;&gt;&lt;/span&gt;&#xA;    &lt;span class=&#34;cyber-terminal__dot cyber-terminal__dot--yellow&#34;&gt;&lt;/span&gt;&#xA;    &lt;span class=&#34;cyber-terminal__dot cyber-terminal__dot--green&#34;&gt;&lt;/span&gt;&#xA;    &lt;span class=&#34;cyber-terminal__title&#34;&gt;scala&lt;/span&gt;&#xA;    &lt;button class=&#34;cyber-terminal__copy&#34; type=&#34;button&#34; aria-label=&#34;Copy code&#34; data-copy&gt;&#xA;      &lt;i class=&#34;fa-regular fa-copy&#34;&gt;&lt;/i&gt;&#xA;    &lt;/button&gt;&#xA;  &lt;/div&gt;&#xA;  &lt;div class=&#34;cyber-terminal__body&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:2;-o-tab-size:2;tab-size:2;&#34;&gt;&lt;code class=&#34;language-scala&#34; data-lang=&#34;scala&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;final&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;UserId&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;(&lt;/span&gt;value&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd&#34;&gt;String&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;extends&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;AnyVal&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;final&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;City&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;(&lt;/span&gt;value&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd&#34;&gt;String&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;extends&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;AnyVal&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&lt;p&gt;This is especially useful when you want to add some meaning to primitive types. It also makes the compiler help you to avoid passing irrelevant data to downstream methods.&lt;/p&gt;&#xA;&lt;p&gt;Read more about value classes in the documentation &lt;a href=&#34;https://docs.scala-lang.org/overviews/core/value-classes.html&#34;&gt;https://docs.scala-lang.org/overviews/core/value-classes.html&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Wrocław Scala User Group - first meetup</title>
      <link>https://blog.michal.pawlik.dev/posts/wsug-001/</link>
      <pubDate>Tue, 13 Dec 2022 00:00:00 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/wsug-001/</guid>
      <description>&lt;p&gt;In this post I want to share a short recap of first Wrocław Scala User Group (WSUG) meetup. This will be kind of TIL entry, it doesn&amp;rsquo;t aim to cover the full presentation content. You can find the full agenda at the &lt;a href=&#34;https://www.meetup.com/pl-PL/wroclaw-scala-user-group/events/290081999/&#34;&gt;event page&lt;/a&gt;. If you&amp;rsquo;d like to join the next meeting, join us at &lt;a href=&#34;https://www.meetup.com/pl-PL/wroclaw-scala-user-group/&#34;&gt;Wroclaw Scala User Group at meetup.com&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;This is my second post in &lt;a href=&#34;https://100daystooffload.com/&#34;&gt;#100DaysToOffload&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;first-talk---scala-cli---whats-the-new-scala-runner-capable-of-by-łuksz-wroński-lwronskihttpsgithubcomlwronski&#34;&gt;First talk - Scala CLI - what&amp;rsquo;s the new Scala runner capable of? by Łuksz Wroński &lt;a href=&#34;https://github.com/lwronski&#34;&gt;lwronski&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;This talk was strictly focused on &lt;a href=&#34;https://scala-cli.virtuslab.org/&#34;&gt;scala-cli&lt;/a&gt;, a great command line utility for working with Scala. I&amp;rsquo;ve already introduced it in some of my articles (e.g. &lt;a href=&#34;https://blog.michal.pawlik.dev/posts/scala/refined/&#34;&gt;refined&lt;/a&gt;). If you&amp;rsquo;re not familiar with the tool, I strongly recommend visiting the &lt;a href=&#34;https://scala-cli.virtuslab.org/docs/getting_started&#34;&gt;getting started&lt;/a&gt; page, the documentation is really good and there&amp;rsquo;s no point rewriting it here.&lt;/p&gt;</description>
    </item>
    <item>
      <title>100 days to offload [1/100]</title>
      <link>https://blog.michal.pawlik.dev/posts/100-days-to-offload/</link>
      <pubDate>Mon, 12 Dec 2022 00:00:00 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/100-days-to-offload/</guid>
      <description>&lt;p&gt;Today I&amp;rsquo;m joining the &lt;em&gt;100 Days To Offload&lt;/em&gt; challenge. Starting from today I aim to publish 100 blog posts by 12.12.2023.&lt;/p&gt;&#xA;&lt;p&gt;The idea is described in more detail at the project page &lt;a href=&#34;https://100daystooffload.com/&#34;&gt;https://100daystooffload.com/&lt;/a&gt;. Quoting the page:&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Posts don’t need to be long-form, deep, meaningful, or even that well written. If there are spelling and grammar mistakes, or even if there’s no real point to the post, so what? What’s important is that you’re writing about the things you want to write about.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Global Day of Code Retreat 2022</title>
      <link>https://blog.michal.pawlik.dev/posts/scala/gdcr-2022/</link>
      <pubDate>Sat, 05 Nov 2022 00:00:00 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/scala/gdcr-2022/</guid>
      <description>&lt;p&gt;In this article I want to share my experience from Global Day of Code Retreat 2022.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-initiative&#34;&gt;The initiative&lt;/h2&gt;&#xA;&lt;p&gt;GDCR is an annual event organized on site and virtually all over the world. As the event page describes it:&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Coderetreats are free day-long, intensive practice events, focusing on the fundamentals of software development and design. By providing developers the opportunity to take part in focused practice, away from the pressures of &amp;ldquo;getting things done&amp;rdquo;, the coderetreat format has proven itself to be a highly effective means of learning and nurturing software development skills.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Type safety with refined</title>
      <link>https://blog.michal.pawlik.dev/posts/scala/refined/</link>
      <pubDate>Thu, 14 Jul 2022 00:00:00 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/scala/refined/</guid>
      <description>&lt;h2 id=&#34;goal&#34;&gt;Goal&lt;/h2&gt;&#xA;&lt;p&gt;In this article we&amp;rsquo;ll learn how to use the Scala type system for avoiding runtime errors. On our way we&amp;rsquo;ll learn some basics about &lt;a href=&#34;https://scala-cli.virtuslab.org/&#34;&gt;&lt;code&gt;scala-cli&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;bootstrap&#34;&gt;Bootstrap&lt;/h2&gt;&#xA;&lt;p&gt;In this article we&amp;rsquo;ll rely on simple examples, thus instead of &lt;code&gt;sbt&lt;/code&gt; we&amp;rsquo;ll use &lt;a href=&#34;https://scala-cli.virtuslab.org/&#34;&gt;&lt;code&gt;scala-cli&lt;/code&gt;&lt;/a&gt;, a lightweight command-line utility to work with Scala.&lt;/p&gt;&#xA;&lt;p&gt;First we&amp;rsquo;ll need to install the utility. For that visit &lt;a href=&#34;https://scala-cli.virtuslab.org/install&#34;&gt;https://scala-cli.virtuslab.org/install&lt;/a&gt; and select the method of your preference.&lt;/p&gt;&#xA;&lt;p&gt;Once that&amp;rsquo;s done you should have &lt;code&gt;scala-cli&lt;/code&gt; command available. It will allow you to easily run Scala programs and scripts. I encourage you to visit the getting started section of the documentation, especially the &lt;a href=&#34;https://scala-cli.virtuslab.org/docs/getting_started#a-project&#34;&gt;Project&lt;/a&gt; approach.&lt;/p&gt;</description>
    </item>
    <item>
      <title>OAuth2 Scala application with sttp-oauth2</title>
      <link>https://blog.michal.pawlik.dev/posts/scala/oauth2-app-p2/</link>
      <pubDate>Wed, 14 Jul 2021 00:00:00 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/scala/oauth2-app-p2/</guid>
      <description>&lt;h1 id=&#34;building-simple-scala-web-application-with-oauth2-github-login---part-2&#34;&gt;Building simple Scala web application with OAuth2 Github login - part 2&lt;/h1&gt;&#xA;&lt;p&gt;In the first part we have prepared a simple web application using Scala with Tapir and Http4s. It can be found in &lt;a href=&#34;https://github.com/majk-p/sample-webapp-demo/commit/fb7463225fab39b8bf99148efa67ef4d686e2475&#34;&gt;this commit&lt;/a&gt;. In this part we&amp;rsquo;ll integrate our application with Github, providing OAuth2 login and some basic API integration.&lt;/p&gt;&#xA;&lt;p&gt;Before we get started make sure to register a Github application. This article will guide you through the process: &lt;a href=&#34;https://docs.github.com/en/developers/apps/building-oauth-apps/creating-an-oauth-app&#34;&gt;https://docs.github.com/en/developers/apps/building-oauth-apps/creating-an-oauth-app&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>OAuth2 Scala application with sttp-oauth2, part 1</title>
      <link>https://blog.michal.pawlik.dev/posts/scala/oauth2-app-p1/</link>
      <pubDate>Wed, 07 Jul 2021 00:00:00 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/scala/oauth2-app-p1/</guid>
      <description>&lt;h1 id=&#34;building-simple-scala-web-application-with-oauth2-github-login---part-1&#34;&gt;Building simple Scala web application with OAuth2 Github login - part 1&lt;/h1&gt;&#xA;&lt;p&gt;Welcome to the first article in the series. In following posts we&amp;rsquo;re going to build a web application using Scala.&lt;/p&gt;&#xA;&lt;h2 id=&#34;goal&#34;&gt;Goal&lt;/h2&gt;&#xA;&lt;p&gt;In this series we&amp;rsquo;ll learn how to:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Start project from scratch&lt;/li&gt;&#xA;&lt;li&gt;Create web service&lt;/li&gt;&#xA;&lt;li&gt;Implement user login using OAuth2 &lt;a href=&#34;https://www.oauth.com/oauth2-servers/server-side-apps/authorization-code/&#34;&gt;authorization code&lt;/a&gt; grant&lt;/li&gt;&#xA;&lt;li&gt;Interact with other web services via HTTP calls, using JSON for data serialization&lt;/li&gt;&#xA;&lt;li&gt;Refactor the application to follow tagless final pattern&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;tech-stack&#34;&gt;Tech stack&lt;/h2&gt;&#xA;&lt;p&gt;We&amp;rsquo;re going to build our application using functional programming techniques and &lt;a href=&#34;https://scalac.io/blog/tagless-final-pattern-for-scala-code/&#34;&gt;Final Tagless&lt;/a&gt; encoding.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Reboot</title>
      <link>https://blog.michal.pawlik.dev/posts/reboot/</link>
      <pubDate>Tue, 06 Jul 2021 00:00:00 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/reboot/</guid>
      <description>&lt;p&gt;It&amp;rsquo;s been around 5 years since last post. A lot has changed since then, and it&amp;rsquo;s a good time for a reboot. From now on my posts will be written in english, potentially making them useful for a wider audience.&lt;/p&gt;&#xA;&lt;p&gt;All of my old posts are still available via direct links, but are no longer listed as most of them are already quite outdated. The only exception is &lt;a href=&#34;../posts/hacker-howto/&#34;&gt;Hacker howto&lt;/a&gt;, as it&amp;rsquo;s an official translation for &lt;a href=&#34;http://www.catb.org/esr/faqs/hacker-howto.html&#34;&gt;http://www.catb.org/esr/faqs/hacker-howto.html&lt;/a&gt; and I believe it&amp;rsquo;s stil very relevant.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to become a hacker? Oficjalne tłumaczenie</title>
      <link>https://blog.michal.pawlik.dev/posts/hacker-howto/</link>
      <pubDate>Thu, 07 Jan 2016 09:23:08 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/hacker-howto/</guid>
      <description>&lt;p&gt;Niniejszy dokument jest tłumaczeniem oryginału dostępnego na &lt;a href=&#34;http://www.catb.org/esr/faqs/hacker-howto.html&#34;&gt;http://www.catb.org/esr/faqs/hacker-howto.html&lt;/a&gt; w wersji 1.50. Autorem oryginału jest &lt;a href=&#34;http://catb.org/~esr/&#34;&gt;Eric S. Raymond&lt;/a&gt;.  Motywacją, dla której chcę podzielić się tłumaczeniem jest ogromna wartość edukacyjna dokumentu. W mojej opinii stanowi on zbiór bardzo cennych oraz inspirujących rad dla początkujących i rozwijających się programistów. Przed rozpoczęciem lektury warto zapoznać się z &lt;a href=&#34;https://pl.wikipedia.org/wiki/Haker_%28slang_komputerowy%29&#34;&gt;definicją pojęcia &amp;lsquo;hacker&amp;rsquo;&lt;/a&gt;. Zapraszam do lektury.&lt;/p&gt;&#xA;&lt;p&gt;&lt;em&gt;Aktualizacja:&lt;/em&gt; Dokument został zaakceptowany jako oficjalne tłumaczenie na stronie &lt;a href=&#34;http://www.catb.org/esr/faqs/hacker-howto.html&#34;&gt;oryginalnego tłumaczenia&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h1 id=&#34;dlaczego-powstał-ten-dokument&#34;&gt;Dlaczego powstał ten dokument?&lt;/h1&gt;&#xA;&lt;p&gt;Jako twórca &lt;a href=&#34;http://www.catb.org/jargon/&#34;&gt;Jargon File&lt;/a&gt;  (kompendium slangu hackerskiego przyp. tłum.) często otrzymuję prośby e-mailem od wielu entuzjastycznych nowicjuszy w Sieci pytających (w skrócie): &amp;ldquo;w jaki sposób mogę zostać doskonałym hackerem?&amp;rdquo;. Jeszcze w 1996 dostrzegłem brak FAQ czy innego dokumentu w sieci poruszającego ten temat, więc zdecydowałem się napisać własny. Dziś wielu hackerów uznaje ten dokument za wyczerpujący temat, moim zdaniem mówi to samo za siebie. Pomimo tego, nie uważam się za wyłączny autorytet w temacie; jeśli nie podoba Ci się teść tego dokumentu, napisz swój.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Wykrywanie ruchu z OpenCV</title>
      <link>https://blog.michal.pawlik.dev/posts/wykrywanie-ruchu-z-opencv/</link>
      <pubDate>Wed, 01 Jul 2015 09:48:37 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/wykrywanie-ruchu-z-opencv/</guid>
      <description>&lt;p&gt;&lt;strong&gt;OpenCV&lt;/strong&gt; (&lt;em&gt;Open Source Computer Vision&lt;/em&gt;) jest otwartą, wieloplaformową biblioteką służącą do analizy obrazu w czasie rzeczywistym. Napisana w języku C posiada jednak nakładki pozwalające na jej wykorzystanie między innymi w językach C++, C# czy Python. Jak zwykle, zapoznanie z tą biblioteką przeprowadzimy w ostatnim z wymienionych języków.&lt;/p&gt;&#xA;&lt;p&gt;W tym artykule chcę przedstawić kilka podstawowych możliwości, jakie daje &lt;a href=&#34;http://opencv.org/&#34;&gt;OpenCV&lt;/a&gt; i być może zachęcić czytelnika do poszerzenia wiedzy na temat tej biblioteki. Przedstawione niżej przykłady omówią pokrótce zagadnienia wykrywania ruchu oraz detekcji kształtów na obrazach.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Reverse engineering webaplikacji WRM</title>
      <link>https://blog.michal.pawlik.dev/posts/reverse-engineering-webaplikacji-wrm/</link>
      <pubDate>Mon, 18 May 2015 11:50:34 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/reverse-engineering-webaplikacji-wrm/</guid>
      <description>&lt;p&gt;Analiza kodu webaplikacji zdecydowanie różni się od reverse engineeringu jaki znamy z analizy aplikacji desktopowych czy mobilnych. W przypadku webaplikacji nie mamy kodu backendu, więc musimy kierować się przesłankami na jego temat, które wynikają z danych wynikowych. Jedyny kod do analizy jaki otrzymujemy to JavaScript załączony do strony.&lt;/p&gt;&#xA;&lt;p&gt;Na wstępie tego wpisu chcę zaznaczyć, że analizą webaplikacji zajmuję się jedynie hobbystycznie, nie mam profesjonalnego przygotowania i traktuję ją jako element poszerzania mojej wiedzy w dziedzinie web developmentu.&lt;/p&gt;</description>
    </item>
    <item>
      <title>OverTheWire - Solucje Natas 18 i 19</title>
      <link>https://blog.michal.pawlik.dev/posts/overthewire-solucja-natas-18-19/</link>
      <pubDate>Tue, 31 Mar 2015 06:38:16 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/overthewire-solucja-natas-18-19/</guid>
      <description>&lt;p&gt;Wpis jest kontynuacją rozwiązań hackme Natas na OverTheWire. Rozwiązania etapu 17 &lt;a href=&#34;http://michalp.net/blog/posts/overthewire-solucja-natas-17&#34;&gt;można znaleźć tutaj&lt;/a&gt;. Etapy 18 i 19 związane będzą z pojęciem sesji, a zatem również ciasteczek. Przed przystąpieniem do rozwiązania upewnij się, że posiadasz rozszerzenie pozwalające na modyfikacje ciastek w swojej przeglądarce.&lt;/p&gt;&#xA;&lt;h1 id=&#34;poziom-18&#34;&gt;Poziom 18&lt;/h1&gt;&#xA;&lt;h2 id=&#34;analiza&#34;&gt;Analiza&lt;/h2&gt;&#xA;&lt;p&gt;Po zalogowaniu na &lt;a href=&#34;http://natas18.natas.labs.overthewire.org/index.php&#34;&gt;poziom 18&lt;/a&gt; spoglądamy na kod źródłowy. Poniżej został on pozbawiony mylących komentarzy.&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;&amp;lt;?&#xD;&#xA;&#xD;&#xA;$maxid = 640; // 640 should be enough for everyone&#xD;&#xA;&#xD;&#xA;function isValidAdminLogin()&#xD;&#xA;{&#xD;&#xA;    if ($_REQUEST[&amp;quot;username&amp;quot;] == &amp;quot;admin&amp;quot;) {&#xD;&#xA;        /* This method of authentication appears to be unsafe and has been disabled for now. */&#xD;&#xA;        //return 1;&#xD;&#xA;    }&#xD;&#xA;    return 0;&#xD;&#xA;}&#xD;&#xA;&#xD;&#xA;function isValidID($id)&#xD;&#xA;{&#xD;&#xA;    return is_numeric($id);&#xD;&#xA;}&#xD;&#xA;&#xD;&#xA;function createID($user)&#xD;&#xA;{&#xD;&#xA;    global $maxid;&#xD;&#xA;    return rand(1, $maxid);&#xD;&#xA;}&#xD;&#xA;&#xD;&#xA;function debug($msg)&#xD;&#xA;{&#xD;&#xA;    if (array_key_exists(&amp;quot;debug&amp;quot;, $_GET)) {&#xD;&#xA;        print &amp;quot;DEBUG: $msg&amp;lt;br&amp;gt;&amp;quot;;&#xD;&#xA;    }&#xD;&#xA;}&#xD;&#xA;&#xD;&#xA;function my_session_start()&#xD;&#xA;{&#xD;&#xA;    if (array_key_exists(&amp;quot;PHPSESSID&amp;quot;, $_COOKIE) and isValidID($_COOKIE[&amp;quot;PHPSESSID&amp;quot;])) {&#xD;&#xA;        if (!session_start()) {&#xD;&#xA;            debug(&amp;quot;Session start failed&amp;quot;);&#xD;&#xA;            return false&#xD;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;img: overthewire.png;&#xA;} else {&#xA;debug(&amp;ldquo;Session start ok&amp;rdquo;);&#xA;if (!array_key_exists(&amp;ldquo;admin&amp;rdquo;, $_SESSION)) {&#xA;debug(&amp;ldquo;Session was old: admin flag set&amp;rdquo;);&#xA;$_SESSION[&amp;ldquo;admin&amp;rdquo;] = 0; // backwards compatible, secure&#xA;}&#xA;return true;&#xA;}&#xA;}&#xA;return false&#xA;img: overthewire.png;&#xA;}&lt;/p&gt;</description>
    </item>
    <item>
      <title>OverTheWire - Solucja Natas 17</title>
      <link>https://blog.michal.pawlik.dev/posts/overthewire-solucja-natas-17/</link>
      <pubDate>Sat, 28 Mar 2015 09:53:15 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/overthewire-solucja-natas-17/</guid>
      <description>&lt;p&gt;Wpis jest kontynuacją rozwiązań hackme Natas na OverTheWire. Rozwiązania etapu 16 &lt;a href=&#34;http://michalp.net/blog/posts/overthewire-solucja-natas-16&#34;&gt;można znaleźć tutaj&lt;/a&gt;. Etap 17 to kolejne zadanie związane z atakami SQLi, jest on rozwinięciem &lt;a href=&#34;http://michalp.net/blog/posts/overthewire-solucja-natas-15&#34;&gt;zadania numer 15&lt;/a&gt;. Polecam zapoznanie się z jego rozwiązaniem, gdyż będziemy nawiązywać do metody przedstawionej w poświęconym mu wpisie.&lt;/p&gt;&#xA;&lt;h2 id=&#34;analiza&#34;&gt;Analiza&lt;/h2&gt;&#xA;&lt;p&gt;Po zalogowaniu na &lt;a href=&#34;http://natas17.natas.labs.overthewire.org/index.php&#34;&gt;poziom 17&lt;/a&gt; spoglądamy na kod źródłowy:&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;/*&#xD;&#xA;CREATE TABLE `users` (&#xD;&#xA;  `username` varchar(64) DEFAULT NULL,&#xD;&#xA;  `password` varchar(64) DEFAULT NULL&#xD;&#xA;);&#xD;&#xA;*/&#xD;&#xA;&#xD;&#xA;if(array_key_exists(&amp;quot;username&amp;quot;, $_REQUEST)) {&#xD;&#xA;    $link = mysql_connect(&#39;localhost&#39;, &#39;natas17&#39;, &#39;&amp;lt;censored&amp;gt;&#39;);&#xD;&#xA;    mysql_select_db(&#39;natas17&#39;, $link);&#xD;&#xA;    &#xD;&#xA;    $query = &amp;quot;SELECT * from users where username=\&amp;quot;&amp;quot;.$_REQUEST[&amp;quot;username&amp;quot;].&amp;quot;\&amp;quot;&amp;quot;;&#xD;&#xA;    if(array_key_exists(&amp;quot;debug&amp;quot;, $_GET)) {&#xD;&#xA;        echo &amp;quot;Executing query: $query&amp;lt;br&amp;gt;&amp;quot;;&#xD;&#xA;    }&#xD;&#xA;&#xD;&#xA;    $res = mysql_query($query, $link);&#xD;&#xA;    if($res) {&#xD;&#xA;    if(mysql_num_rows($res) &amp;gt; 0) {&#xD;&#xA;        //echo &amp;quot;This user exists.&amp;lt;br&amp;gt;&amp;quot;;&#xD;&#xA;    } else {&#xD;&#xA;        //echo &amp;quot;This user doesn&#39;t exist.&amp;lt;br&amp;gt;&amp;quot;;&#xD;&#xA;    }&#xD;&#xA;    } else {&#xD;&#xA;        //echo &amp;quot;Error in query.&amp;lt;br&amp;gt;&amp;quot;;&#xD;&#xA;    }&#xD;&#xA;&#xD;&#xA;    mysql_close($link);&#xD;&#xA;} else { &#xD;&#xA;&#x9;// wyświetl formularz&#xD;&#xA;}&#xD;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;W porównaniu do kodu z zadania 15 widzimy jedną znaczącą różnicę. Skrypt nie odpowiada w żaden sposób na dane wprowadzone przez użytkownika. Jedyny modyfikator, który daje odpowiedź serwera to parametr &lt;code&gt;debug&lt;/code&gt;, który możemy zastosować w adresie url. Spowoduje on wyświetlenie wykonywanego zapytania.&lt;/p&gt;</description>
    </item>
    <item>
      <title>OverTheWire - Solucja Natas 16</title>
      <link>https://blog.michal.pawlik.dev/posts/overthewire-solucja-natas-16/</link>
      <pubDate>Mon, 02 Mar 2015 16:27:25 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/overthewire-solucja-natas-16/</guid>
      <description>&lt;p&gt;Wpis jest kontynuacją rozwiązań hackme Natas na OverTheWire. Rozwiązania etapu 15 &lt;a href=&#34;http://michalp.net/blog/posts/overthewire-solucja-natas-15&#34;&gt;można znaleźć tutaj&lt;/a&gt;. Etap 16 powiązany jest bezpośrednio z etapem numer 9, którego rozwiązanie możemy przypomnieć sobie &lt;a href=&#34;http://michalp.net/blog/posts/overthewire-solucje-natas-6-10&#34;&gt;w tym poście&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;analiza&#34;&gt;Analiza&lt;/h2&gt;&#xA;&lt;p&gt;Po zalogowaniu na &lt;a href=&#34;http://natas16.natas.labs.overthewire.org/index.php&#34;&gt;poziom 16&lt;/a&gt; spoglądamy na kod źródłowy:&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt; &amp;lt;?&#xD;&#xA;$key = &amp;quot;&amp;quot;;&#xD;&#xA;&#xD;&#xA;if (array_key_exists(&amp;quot;needle&amp;quot;, $_REQUEST)) {&#xD;&#xA;    $key = $_REQUEST[&amp;quot;needle&amp;quot;];&#xD;&#xA;}&#xD;&#xA;&#xD;&#xA;if ($key != &amp;quot;&amp;quot;) {&#xD;&#xA;    if (preg_match(&#39;/[;|&amp;amp;`\&#39;&amp;quot;]/&#39;, $key)) {&#xD;&#xA;        print &amp;quot;Input contains an illegal character!&amp;quot;;&#xD;&#xA;    } else {&#xD;&#xA;        passthru(&amp;quot;grep -i \&amp;quot;$key\&amp;quot; dictionary.txt&amp;quot;);&#xD;&#xA;    }&#xD;&#xA;}&#xD;&#xA;?&amp;gt; &#xD;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Nawiązując do rozwiązania poziomu numer 9, zauważamy że różnica leży w sprawdzeniu danych użytkownika. W kodzie występuje weryfikacja danych użytkownika pod kątem wyrażenia regularnego. W konsekwencji nie możemy użyć znaków [] ; | &amp;amp; \ ` &amp;rsquo; &amp;quot;  . Stanowi to problem, ponieważ nie możemy bezpośrednio &lt;em&gt;wydostać się&lt;/em&gt; z polecenia &lt;code&gt;grep&lt;/code&gt;. Rozwiązując zadania z gry &lt;a href=&#34;http://michalp.net/blog/posts/overthewire-solucje-bandit&#34;&gt;Bandit&lt;/a&gt; mogliśmy poznać składnię &lt;code&gt;$(polecenie)&lt;/code&gt;. Konstrukcja ta &lt;strong&gt;nie jest zabroniona&lt;/strong&gt; przez wyrażenie regularne w zadaniu, więc postaramy się zastosować ją w rozwiązaniu.&lt;/p&gt;</description>
    </item>
    <item>
      <title>OverTheWire - Solucja Natas 15</title>
      <link>https://blog.michal.pawlik.dev/posts/overthewire-solucja-natas-15/</link>
      <pubDate>Wed, 25 Feb 2015 10:23:35 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/overthewire-solucja-natas-15/</guid>
      <description>&lt;p&gt;Wpis jest kontynuacją rozwiązań hackme Natas na OverTheWire. Rozwiązania etapu 14 &lt;a href=&#34;http://michalp.net/blog/posts/overthewire-solucja-natas-14&#34;&gt;można znaleźć tutaj&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;analiza&#34;&gt;Analiza&lt;/h2&gt;&#xA;&lt;p&gt;Używając hasła uzyskanego na poprzednim &lt;a href=&#34;http://natas15.natas.labs.overthewire.org/index.php&#34;&gt;poziomie 15&lt;/a&gt; logujemy się na poziom 16. Otrzymujemy formularz, który pozwala sprawdzić czy w bazie znajduje się użytkownik o zadanym loginie. Jest to kolejne zadanie, w którym wykorzystamy podatność typu &lt;em&gt;SQL Injection&lt;/em&gt;, jednak tym razem w nieco innej formie.&lt;/p&gt;&#xA;&lt;p&gt;Kod źródłowy:&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;&amp;lt;?&#xD;&#xA;&#xD;&#xA;/*&#xD;&#xA;CREATE TABLE `users` (&#xD;&#xA;`username` varchar(64) DEFAULT NULL,&#xD;&#xA;`password` varchar(64) DEFAULT NULL&#xD;&#xA;);&#xD;&#xA;*/&#xD;&#xA;&#xD;&#xA;if (array_key_exists(&amp;quot;username&amp;quot;, $_REQUEST)) {&#xD;&#xA;    $link = mysql_connect(&#39;localhost&#39;, &#39;natas15&#39;, &#39;&amp;lt;censored&amp;gt;&#39;);&#xD;&#xA;    mysql_select_db(&#39;natas15&#39;, $link);&#xD;&#xA;    &#xD;&#xA;    $query = &amp;quot;SELECT * from users where username=\&amp;quot;&amp;quot; . $_REQUEST[&amp;quot;username&amp;quot;] . &amp;quot;\&amp;quot;&amp;quot;;&#xD;&#xA;    if (array_key_exists(&amp;quot;debug&amp;quot;, $_GET)) {&#xD;&#xA;        echo &amp;quot;Executing query: $query&amp;lt;br&amp;gt;&amp;quot;;&#xD;&#xA;    }&#xD;&#xA;    &#xD;&#xA;    $res = mysql_query($query, $link);&#xD;&#xA;    if ($res) {&#xD;&#xA;        if (mysql_num_rows($res) &amp;gt; 0) {&#xD;&#xA;            echo &amp;quot;This user exists.&amp;lt;br&amp;gt;&amp;quot;;&#xD;&#xA;        } else {&#xD;&#xA;            echo &amp;quot;This user doesn&#39;t exist.&amp;lt;br&amp;gt;&amp;quot;;&#xD;&#xA;        }&#xD;&#xA;    } else {&#xD;&#xA;        echo &amp;quot;Error in query.&amp;lt;br&amp;gt;&amp;quot;;&#xD;&#xA;    }&#xD;&#xA;    &#xD;&#xA;    mysql_close($link);&#xD;&#xA;} else {&#xD;&#xA;?&amp;gt;&#xD;&#xA;&#xD;&#xA;&amp;lt;form action=&amp;quot;index.php&amp;quot; method=&amp;quot;POST&amp;quot;&amp;gt;&#xD;&#xA;Username: &amp;lt;input name=&amp;quot;username&amp;quot;&amp;gt;&amp;lt;br&amp;gt;&#xD;&#xA;&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Check existence&amp;quot; /&amp;gt;&#xD;&#xA;&amp;lt;/form&amp;gt;&#xD;&#xA;&amp;lt;?&#xD;&#xA;}&#xD;&#xA;?&amp;gt; &#xD;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Jak widzimy, logika jest zbliżona do tej, którą poznaliśmy na poprzednim poziomie. Zmieniono nieco treść zapytania do bazy:&lt;/p&gt;</description>
    </item>
    <item>
      <title>OverTheWire - Solucja Natas 14</title>
      <link>https://blog.michal.pawlik.dev/posts/overthewire-solucja-natas-14/</link>
      <pubDate>Wed, 25 Feb 2015 09:58:34 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/overthewire-solucja-natas-14/</guid>
      <description>&lt;p&gt;Wpis jest kontynuacją rozwiązań hackme Natas na OverTheWire. Rozwiązania etapu 13 &lt;a href=&#34;http://michalp.net/blog/posts/overthewire-solucja-natas-13&#34;&gt;można znaleźć tutaj&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;analiza&#34;&gt;Analiza&lt;/h2&gt;&#xA;&lt;p&gt;Pozyskanym na poprzednim poziomie hasłem logujemy się do &lt;a href=&#34;http://natas14.natas.labs.overthewire.org/&#34;&gt;poziomu 14&lt;/a&gt;. Tym razem dany jest formularz logowania. Mamy również wgląd w kod źródłowy:&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;&amp;lt;?&#xD;&#xA;if (array_key_exists(&amp;quot;username&amp;quot;, $_REQUEST)) {&#xD;&#xA;    $link = mysql_connect(&#39;localhost&#39;, &#39;natas14&#39;, &#39;&amp;lt;censored&amp;gt;&#39;);&#xD;&#xA;    mysql_select_db(&#39;natas14&#39;, $link);&#xD;&#xA;    &#xD;&#xA;    $query = &amp;quot;SELECT * from users where username=\&amp;quot;&amp;quot; . $_REQUEST[&amp;quot;username&amp;quot;] . &amp;quot;\&amp;quot; and password=\&amp;quot;&amp;quot; . $_REQUEST[&amp;quot;password&amp;quot;] . &amp;quot;\&amp;quot;&amp;quot;;&#xD;&#xA;    if (array_key_exists(&amp;quot;debug&amp;quot;, $_GET)) {&#xD;&#xA;        echo &amp;quot;Executing query: $query&amp;lt;br&amp;gt;&amp;quot;;&#xD;&#xA;    }&#xD;&#xA;    &#xD;&#xA;    if (mysql_num_rows(mysql_query($query, $link)) &amp;gt; 0) {&#xD;&#xA;        echo &amp;quot;Successful login! The password for natas15 is &amp;lt;censored&amp;gt;&amp;lt;br&amp;gt;&amp;quot;;&#xD;&#xA;    } else {&#xD;&#xA;        echo &amp;quot;Access denied!&amp;lt;br&amp;gt;&amp;quot;;&#xD;&#xA;    }&#xD;&#xA;    mysql_close($link);&#xD;&#xA;} else {&#xD;&#xA;?&amp;gt;&#xD;&#xA;&#xD;&#xA;&amp;lt;form action=&amp;quot;index.php&amp;quot; method=&amp;quot;POST&amp;quot;&amp;gt;&#xD;&#xA;Username: &amp;lt;input name=&amp;quot;username&amp;quot;&amp;gt;&amp;lt;br&amp;gt;&#xD;&#xA;Password: &amp;lt;input name=&amp;quot;password&amp;quot;&amp;gt;&amp;lt;br&amp;gt;&#xD;&#xA;&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Login&amp;quot; /&amp;gt;&#xD;&#xA;&amp;lt;/form&amp;gt;&#xD;&#xA;&amp;lt;?&#xD;&#xA;}&#xD;&#xA;?&amp;gt;  &#xD;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Pod warunkiem wysłania formularza kod wykonuje zapytanie do bazy danych. Odpytuje tablicę &lt;code&gt;users&lt;/code&gt; w poszukiwaniu rekordów o zadanych loginie i haśle. Jeśli takie znajdzie, poznamy hasło do poziomu piętnastego. Oczywiście problem polega na tym, że nie znamy prawidłowego loginu i hasła. Należy jednak zauważyć, w jaki sposób wykonywane jest zapytanie:&lt;/p&gt;</description>
    </item>
    <item>
      <title>OverTheWire - Solucja Natas 13</title>
      <link>https://blog.michal.pawlik.dev/posts/overthewire-solucja-natas-13/</link>
      <pubDate>Tue, 24 Feb 2015 12:28:33 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/overthewire-solucja-natas-13/</guid>
      <description>&lt;p&gt;Wpis jest kontynuacją rozwiązań hackme Natas na OverTheWire. Rozwiązania etapu 12 &lt;a href=&#34;http://michalp.net/blog/posts/overthewire-solucja-natas-12&#34;&gt;można znaleźć tutaj&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;analiza&#34;&gt;Analiza&lt;/h2&gt;&#xA;&lt;p&gt;Hasłem uzyskanym na poprzednim etapie logujemy się do kolejnego poziomu. Kod różni się nieznacznie względem tego w poprzednim przykładzie. Odwiedzając stronę informowani jesteśmy o wprowadzeniu weryfikacji, czy wysyłany plik jest obrazem. Kod źódłowy:&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;&amp;lt;?&#xD;&#xA;function genRandomString()&#xD;&#xA;{&#xD;&#xA;    $length     = 10;&#xD;&#xA;    $characters = &amp;quot;0123456789abcdefghijklmnopqrstuvwxyz&amp;quot;;&#xD;&#xA;    $string     = &amp;quot;&amp;quot;;&#xD;&#xA;    for ($p = 0; $p &amp;lt; $length; $p++) {&#xD;&#xA;        $string .= $characters[mt_rand(0, strlen($characters) - 1)];&#xD;&#xA;    }&#xD;&#xA;    return $string;&#xD;&#xA;}&#xD;&#xA;&#xD;&#xA;function makeRandomPath($dir, $ext)&#xD;&#xA;{&#xD;&#xA;    do {&#xD;&#xA;        $path = $dir . &amp;quot;/&amp;quot; . genRandomString() . &amp;quot;.&amp;quot; . $ext;&#xD;&#xA;    } while (file_exists($path));&#xD;&#xA;    return $path;&#xD;&#xA;}&#xD;&#xA;&#xD;&#xA;function makeRandomPathFromFilename($dir, $fn)&#xD;&#xA;{&#xD;&#xA;    $ext = pathinfo($fn, PATHINFO_EXTENSION);&#xD;&#xA;    return makeRandomPath($dir, $ext);&#xD;&#xA;}&#xD;&#xA;&#xD;&#xA;if (array_key_exists(&amp;quot;filename&amp;quot;, $_POST)) {&#xD;&#xA;    $target_path = makeRandomPathFromFilename(&amp;quot;upload&amp;quot;, $_POST[&amp;quot;filename&amp;quot;]);&#xD;&#xA;    &#xD;&#xA;    if (filesize($_FILES[&#39;uploadedfile&#39;][&#39;tmp_name&#39;]) &amp;gt; 1000) {&#xD;&#xA;        echo &amp;quot;File is too big&amp;quot;;&#xD;&#xA;    } else if (!exif_imagetype($_FILES[&#39;uploadedfile&#39;][&#39;tmp_name&#39;])) {&#xD;&#xA;        echo &amp;quot;File is not an image&amp;quot;;&#xD;&#xA;    } else {&#xD;&#xA;        if (move_uploaded_file($_FILES[&#39;uploadedfile&#39;][&#39;tmp_name&#39;], $target_path)) {&#xD;&#xA;            echo &amp;quot;The file &amp;lt;a href=\&amp;quot;$target_path\&amp;quot;&amp;gt;$target_path&amp;lt;/a&amp;gt; has been uploaded&amp;quot;;&#xD;&#xA;        } else {&#xD;&#xA;            echo &amp;quot;There was an error uploading the file, please try again!&amp;quot;;&#xD;&#xA;        }&#xD;&#xA;    }&#xD;&#xA;} else {&#xD;&#xA;?&amp;gt;&#xD;&#xA;&#xD;&#xA;&amp;lt;form enctype=&amp;quot;multipart/form-data&amp;quot; action=&amp;quot;index.php&amp;quot; method=&amp;quot;POST&amp;quot;&amp;gt;&#xD;&#xA;&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;MAX_FILE_SIZE&amp;quot; value=&amp;quot;1000&amp;quot; /&amp;gt;&#xD;&#xA;&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;filename&amp;quot; value=&amp;quot;&amp;lt;?&#xD;&#xA;    print genRandomString();&#xD;&#xA;?&amp;gt;.jpg&amp;quot; /&amp;gt;&#xD;&#xA;Choose a JPEG to upload (max 1KB):&amp;lt;br/&amp;gt;&#xD;&#xA;&amp;lt;input name=&amp;quot;uploadedfile&amp;quot; type=&amp;quot;file&amp;quot; /&amp;gt;&amp;lt;br /&amp;gt;&#xD;&#xA;&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Upload File&amp;quot; /&amp;gt;&#xD;&#xA;&amp;lt;/form&amp;gt;&#xD;&#xA;&amp;lt;?&#xD;&#xA;}&#xD;&#xA;?&amp;gt;&#xD;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Wspomniana różnica składa się na dodatkowy warunek przy weryfikacji danych:&lt;/p&gt;</description>
    </item>
    <item>
      <title>OverTheWire - Solucja Natas 12</title>
      <link>https://blog.michal.pawlik.dev/posts/overthewire-solucja-natas-12/</link>
      <pubDate>Mon, 23 Feb 2015 14:54:03 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/overthewire-solucja-natas-12/</guid>
      <description>&lt;p&gt;Wpis jest kontynuacją rozwiązań hackme Natas na OverTheWire. Rozwiązania etapu 11 &lt;a href=&#34;http://michalp.net/blog/posts/overthewire-solucje-natas-11&#34;&gt;można znaleźć tutaj&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;analiza&#34;&gt;Analiza&lt;/h2&gt;&#xA;&lt;p&gt;Hasłem uzyskanym na poprzednim etapie logujemy się do kolejnego poziomu. Na tym poziomie mamy do czynienia z formularzem wstawiania plików na serwer. Spójrzmy na kod:&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;&amp;lt;?&#xD;&#xA;&#xD;&#xA;function genRandomString()&#xD;&#xA;{&#xD;&#xA;    $length     = 10;&#xD;&#xA;    $characters = &amp;quot;0123456789abcdefghijklmnopqrstuvwxyz&amp;quot;;&#xD;&#xA;    $string     = &amp;quot;&amp;quot;;&#xD;&#xA;    &#xD;&#xA;    for ($p = 0; $p &amp;lt; $length; $p++) {&#xD;&#xA;        $string .= $characters[mt_rand(0, strlen($characters) - 1)];&#xD;&#xA;    }&#xD;&#xA;    &#xD;&#xA;    return $string;&#xD;&#xA;}&#xD;&#xA;&#xD;&#xA;function makeRandomPath($dir, $ext)&#xD;&#xA;{&#xD;&#xA;    do {&#xD;&#xA;        $path = $dir . &amp;quot;/&amp;quot; . genRandomString() . &amp;quot;.&amp;quot; . $ext;&#xD;&#xA;    } while (file_exists($path));&#xD;&#xA;    return $path;&#xD;&#xA;}&#xD;&#xA;&#xD;&#xA;function makeRandomPathFromFilename($dir, $fn)&#xD;&#xA;{&#xD;&#xA;    $ext = pathinfo($fn, PATHINFO_EXTENSION);&#xD;&#xA;    return makeRandomPath($dir, $ext);&#xD;&#xA;}&#xD;&#xA;&#xD;&#xA;if (array_key_exists(&amp;quot;filename&amp;quot;, $_POST)) {&#xD;&#xA;    $target_path = makeRandomPathFromFilename(&amp;quot;upload&amp;quot;, $_POST[&amp;quot;filename&amp;quot;]);&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    if (filesize($_FILES[&#39;uploadedfile&#39;][&#39;tmp_name&#39;]) &amp;gt; 1000) {&#xD;&#xA;        echo &amp;quot;File is too big&amp;quot;;&#xD;&#xA;    } else {&#xD;&#xA;        if (move_uploaded_file($_FILES[&#39;uploadedfile&#39;][&#39;tmp_name&#39;], $target_path)) {&#xD;&#xA;            echo &amp;quot;The file &amp;lt;a href=\&amp;quot;$target_path\&amp;quot;&amp;gt;$target_path&amp;lt;/a&amp;gt; has been uploaded&amp;quot;;&#xD;&#xA;        } else {&#xD;&#xA;            echo &amp;quot;There was an error uploading the file, please try again!&amp;quot;;&#xD;&#xA;        }&#xD;&#xA;    }&#xD;&#xA;} else {&#xD;&#xA;?&amp;gt;&#xD;&#xA;&#xD;&#xA;&amp;lt;form enctype=&amp;quot;multipart/form-data&amp;quot; action=&amp;quot;index.php&amp;quot; method=&amp;quot;POST&amp;quot;&amp;gt;&#xD;&#xA;&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;MAX_FILE_SIZE&amp;quot; value=&amp;quot;1000&amp;quot; /&amp;gt;&#xD;&#xA;&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;filename&amp;quot; value=&amp;quot;&amp;lt;?&#xD;&#xA;    print genRandomString();&#xD;&#xA;?&amp;gt;.jpg&amp;quot; /&amp;gt;&#xD;&#xA;Choose a JPEG to upload (max 1KB):&amp;lt;br/&amp;gt;&#xD;&#xA;&amp;lt;input name=&amp;quot;uploadedfile&amp;quot; type=&amp;quot;file&amp;quot; /&amp;gt;&amp;lt;br /&amp;gt;&#xD;&#xA;&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Upload File&amp;quot; /&amp;gt;&#xD;&#xA;&amp;lt;/form&amp;gt;&#xD;&#xA;&amp;lt;?&#xD;&#xA;}&#xD;&#xA;?&amp;gt; &#xD;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Kod możemy podzielić na dwie sekcje. Pierwsza to definicje trzech funkcji: &lt;code&gt;genRandomString()&lt;/code&gt;, &lt;code&gt;makeRandomPath()&lt;/code&gt;, &lt;code&gt;makeRandomPathFromFilename()&lt;/code&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>OverTheWire - Solucja Natas 11</title>
      <link>https://blog.michal.pawlik.dev/posts/overthewire-solucje-natas-11/</link>
      <pubDate>Mon, 23 Feb 2015 10:23:27 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/overthewire-solucje-natas-11/</guid>
      <description>&lt;p&gt;Wpis jest kontynuacją rozwiązań hackme Natas na OverTheWire. Rozwiązania etapów 6-10 przedstawione zostały &lt;a href=&#34;http://michalp.net/blog/posts/overthewire-solucje-natas-6-10&#34;&gt;w tym wpisie&lt;/a&gt;. W związku ze wzrostem skomplikowania zadań, rozwiązania stają się coraz dłuższe, więc kolejne rozwiązania będą pojawiać się w odrębnych artykułach.&lt;/p&gt;&#xA;&lt;h2 id=&#34;analiza&#34;&gt;Analiza&lt;/h2&gt;&#xA;&lt;p&gt;Hasłem uzyskanym na poprzednim etapie logujemy się do kolejnego poziomu. Tym razem otrzymujemy formularz, dzięki któremu możemy zmienić tło strony. Dostępny jest również kod źródłowy:&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;&amp;lt;?&#xD;&#xA;$defaultdata = array(&#xD;&#xA;    &amp;quot;showpassword&amp;quot; =&amp;gt; &amp;quot;no&amp;quot;,&#xD;&#xA;    &amp;quot;bgcolor&amp;quot; =&amp;gt; &amp;quot;#ffffff&amp;quot;&#xD;&#xA;);&#xD;&#xA;&#xD;&#xA;function xor_encrypt($in)&#xD;&#xA;{&#xD;&#xA;    $key     = &#39;&amp;lt;censored&amp;gt;&#39;;&#xD;&#xA;    $text    = $in;&#xD;&#xA;    $outText = &#39;&#39;;&#xD;&#xA;    &#xD;&#xA;    // Iterate through each character&#xD;&#xA;    for ($i = 0; $i &amp;lt; strlen($text); $i++) {&#xD;&#xA;        $outText .= $text[$i] ^ $key[$i % strlen($key)];&#xD;&#xA;    }&#xD;&#xA;    return $outText;&#xD;&#xA;}&#xD;&#xA;&#xD;&#xA;function loadData($def)&#xD;&#xA;{&#xD;&#xA;    global $_COOKIE;&#xD;&#xA;    $mydata = $def;&#xD;&#xA;    if (array_key_exists(&amp;quot;data&amp;quot;, $_COOKIE)) {&#xD;&#xA;        $tempdata = json_decode(xor_encrypt(base64_decode($_COOKIE[&amp;quot;data&amp;quot;])), true);&#xD;&#xA;        if (is_array($tempdata) &amp;amp;&amp;amp; array_key_exists(&amp;quot;showpassword&amp;quot;, $tempdata) &amp;amp;&amp;amp; array_key_exists(&amp;quot;bgcolor&amp;quot;, $tempdata)) {&#xD;&#xA;            if (preg_match(&#39;/^#(?:[a-f\d]{6})$/i&#39;, $tempdata[&#39;bgcolor&#39;])) {&#xD;&#xA;                $mydata[&#39;showpassword&#39;] = $tempdata[&#39;showpassword&#39;];&#xD;&#xA;                $mydata[&#39;bgcolor&#39;]      = $tempdata[&#39;bgcolor&#39;];&#xD;&#xA;            }&#xD;&#xA;        }&#xD;&#xA;    }&#xD;&#xA;    return $mydata;&#xD;&#xA;}&#xD;&#xA;&#xD;&#xA;function saveData($d)&#xD;&#xA;{&#xD;&#xA;    setcookie(&amp;quot;data&amp;quot;, base64_encode(xor_encrypt(json_encode($d))));&#xD;&#xA;}&#xD;&#xA;&#xD;&#xA;$data = loadData($defaultdata);&#xD;&#xA;&#xD;&#xA;if (array_key_exists(&amp;quot;bgcolor&amp;quot;, $_REQUEST)) {&#xD;&#xA;    if (preg_match(&#39;/^#(?:[a-f\d]{6})$/i&#39;, $_REQUEST[&#39;bgcolor&#39;])) {&#xD;&#xA;        $data[&#39;bgcolor&#39;] = $_REQUEST[&#39;bgcolor&#39;];&#xD;&#xA;    }&#xD;&#xA;}&#xD;&#xA;&#xD;&#xA;saveData($data);&#xD;&#xA;?&amp;gt;&#xD;&#xA;&#xD;&#xA;&amp;lt;h1&amp;gt;natas11&amp;lt;/h1&amp;gt;&#xD;&#xA;&amp;lt;div id=&amp;quot;content&amp;quot;&amp;gt;&#xD;&#xA;&amp;lt;body style=&amp;quot;background: &amp;lt;?= $data[&#39;bgcolor&#39;] ?&amp;gt;;&amp;quot;&amp;gt;&#xD;&#xA;Cookies are protected with XOR encryption&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&#xD;&#xA;&#xD;&#xA;&amp;lt;?&#xD;&#xA;if ($data[&amp;quot;showpassword&amp;quot;] == &amp;quot;yes&amp;quot;) {&#xD;&#xA;    print &amp;quot;The password for natas12 is &amp;lt;censored&amp;gt;&amp;lt;br&amp;gt;&amp;quot;;&#xD;&#xA;}&#xD;&#xA;&#xD;&#xA;?&amp;gt;&#xD;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Przeanalizujmy jego działanie w kolejności wykonywania. Cała mechanika skryptu opiera się o następujący fragment:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Własny plugin do Spotlight</title>
      <link>https://blog.michal.pawlik.dev/posts/wlasny-plugin-do-spotlight/</link>
      <pubDate>Thu, 19 Feb 2015 19:35:23 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/wlasny-plugin-do-spotlight/</guid>
      <description>&lt;p&gt;&lt;strong&gt;Flashlight&lt;/strong&gt; to nieoficjalne API dla Spotlight (błyskawicznej wyszukiwarki dla OSX), umożliwiające programowe przetwarzanie zapytań i dodawanie własnych wyników wyszukiwania. Bliższy opis modułu można znaleźć na &lt;a href=&#34;https://github.com/nate-parrott/Flashlight&#34;&gt;GitHubie&lt;/a&gt;. W tym wpisie przybliżę temat tworzenia własnego pluginu dla &lt;strong&gt;Flashlight&lt;/strong&gt;. Artykuł jest inspirowany &lt;a href=&#34;https://github.com/nate-parrott/Flashlight/wiki/Creating-a-Plugin&#34;&gt;instrukcją&lt;/a&gt; opublikowaną na wiki projektu.&lt;/p&gt;&#xA;&lt;h2 id=&#34;zasada-działania&#34;&gt;Zasada działania&lt;/h2&gt;&#xA;&lt;p&gt;Każdy plugin rejestruje wyrażenia, na które będzie reagował. W ramach artykułu stworzymy plugin pozwalający wysłać mail z ustawionego jako domyślny klienta pocztowego. Pełny kod pluginu dostępny jest również w &lt;a href=&#34;https://github.com/majk-p/mpmail-plugin&#34;&gt;moim repozytorium GitHub&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>OverTheWire - Solucje Natas 6-10</title>
      <link>https://blog.michal.pawlik.dev/posts/overthewire-solucje-natas-6-10/</link>
      <pubDate>Wed, 18 Feb 2015 11:10:25 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/overthewire-solucje-natas-6-10/</guid>
      <description>&lt;p&gt;Wpis jest kontynuacją rozwiązań hackme &lt;em&gt;Natas&lt;/em&gt; na &lt;a href=&#34;http://overthewire.org/wargames/&#34;&gt;OverTheWire&lt;/a&gt;. Rozwiązania etapów 0-5 &lt;a href=&#34;http://michalp.net/blog/posts/overthewire-solucje-natas-0-5&#34;&gt;przedstawione zostały w tym wpisie&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;rozwiązania&#34;&gt;Rozwiązania&lt;/h2&gt;&#xA;&lt;h3 id=&#34;natas6&#34;&gt;Natas6&lt;/h3&gt;&#xA;&lt;p&gt;Kożystając z hasła uzyskanego na poziomie 5 logujemy się do natas6. W tym przykładzie udostępniono nam kod źródłowy skryptu. Jego zawartość:&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;&amp;lt;?&#xD;&#xA;include &amp;quot;includes/secret.inc&amp;quot;;&#xD;&#xA;    if(array_key_exists(&amp;quot;submit&amp;quot;, $_POST)) {&#xD;&#xA;        if($secret == $_POST[&#39;secret&#39;]) {&#xD;&#xA;        print &amp;quot;Access granted. The password for natas7 is &amp;lt;censored&amp;gt;&amp;quot;;&#xD;&#xA;    } else {&#xD;&#xA;        print &amp;quot;Wrong secret&amp;quot;;&#xD;&#xA;    }&#xD;&#xA;    }&#xD;&#xA;?&amp;gt;&#xD;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Zauważamy, że zawartość zmiennej &lt;code&gt;secret&lt;/code&gt; porównywana jest z zawartością &lt;code&gt;$secret&lt;/code&gt;. Zmienna ta nie jest definiowana w ramach skryptu, jednak skrypt rozpoczyna się dyrektywą &lt;em&gt;include&lt;/em&gt;, która wczytuje zawartość pliku &lt;code&gt;includes/secret.inc&lt;/code&gt;. Odwiedzając adres &lt;a href=&#34;http://natas6.natas.labs.overthewire.org/includes/secret.inc&#34;&gt;http://natas6.natas.labs.overthewire.org/includes/secret.inc&lt;/a&gt; zauważamy pustą stronę, jednak rzut oka na źródło pozwala nam poznać zawartość zmiennej &lt;code&gt;$secret&lt;/code&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>OverTheWire - Solucje Natas 0-5</title>
      <link>https://blog.michal.pawlik.dev/posts/overthewire-solucje-natas-0-5/</link>
      <pubDate>Tue, 17 Feb 2015 21:04:45 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/overthewire-solucje-natas-0-5/</guid>
      <description>&lt;p&gt;Wpis ten rozpoczyna serię artykułów opisujących rozwiązania kolejnych poziomów hackme &lt;em&gt;Natas&lt;/em&gt; na &lt;a href=&#34;http://overthewire.org/wargames/&#34;&gt;OverTheWire&lt;/a&gt;. Zaleca się uprzednio rozwiązać zagadki zawarte w grze &lt;em&gt;Bandit&lt;/em&gt;, których rozwiązanie &lt;a href=&#34;http://michalp.net/blog/posts/overthewire-solucje-bandit&#34;&gt;opisałem już na blogu&lt;/a&gt;, jednak nie jest to obowiązkowe.&lt;/p&gt;&#xA;&lt;h2 id=&#34;wstęp&#34;&gt;Wstęp&lt;/h2&gt;&#xA;&lt;p&gt;Seria Natas składa się z zadań dotyczących atakowania webaplikacji. W przeciwieństwie do &lt;em&gt;Bandit&lt;/em&gt; na każdym etapie logujemy się loginem natasNR_POZIOMU oraz uzyskanym na poprzednim poziomie hasłem.&lt;/p&gt;&#xA;&lt;h2 id=&#34;rozwiązania&#34;&gt;Rozwiązania&lt;/h2&gt;&#xA;&lt;p&gt;W ramach pierwszego artykułu rozwiążemy zadania 0-5, następne rozwiązania ukazywać będą się cyklicznie w kolejnych artykułach.&lt;/p&gt;</description>
    </item>
    <item>
      <title>OverTheWire - solucje &amp;quot;Bandit&amp;quot;</title>
      <link>https://blog.michal.pawlik.dev/posts/overthewire-solucje-bandit/</link>
      <pubDate>Mon, 09 Feb 2015 17:36:41 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/overthewire-solucje-bandit/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;http://overthewire.org/wargames/&#34;&gt;OverTheWire&lt;/a&gt; to projekt społecznościowy hostowany na GitHub. Stanowi on kolekcję gier typu hackme, dzięki którym możemy sprawdzić i poszerzyć swoją wiedzę z dziedziny o *nixach i zabezpieczeniach. Wyróżniającą cechą OverTheWire jest forma zadań, które rozwiązujemy na rzeczywistych systemach.&lt;/p&gt;&#xA;&lt;p&gt;W dzisiejszym wpisie opiszę rozwiązania wszystkich etapów gry &lt;a href=&#34;http://overthewire.org/wargames/bandit/&#34;&gt;Bandit&lt;/a&gt;. Celem wpisu jest pomoc osobom, które utknęły w trakcie rozwiązywania zadań.&lt;/p&gt;&#xA;&lt;h2 id=&#34;rozwiązania&#34;&gt;Rozwiązania&lt;/h2&gt;&#xA;&lt;p&gt;Do rozwiązania zadań potrzebny będzie klient SSH. Jeśli pracujesz w systemach Linux/Unix do połączenia posłuży Ci komenda &lt;code&gt;ssh&lt;/code&gt; w terminalu. W systemach Windows posłużyć może &lt;a href=&#34;http://the.earth.li/~sgtatham/putty/latest/x86/putty.exe&#34;&gt;putty&lt;/a&gt;, którego krótki opis znajdziemy &lt;a href=&#34;http://kb.mediatemple.net/questions/1595/Using+SSH+in+PuTTY+%28Windows%29#gs&#34;&gt;pod tym adresem&lt;/a&gt;. Do rozwiązania zadań posłużyłem się komputerem z systemem Linux.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Obrazek śledzący - skrypt w Pythonie</title>
      <link>https://blog.michal.pawlik.dev/posts/obrazek-sledzacy-skrypt-w-pythonie/</link>
      <pubDate>Sat, 24 Jan 2015 23:33:32 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/obrazek-sledzacy-skrypt-w-pythonie/</guid>
      <description>&lt;p&gt;Nie jest tajemnicą, że nasze postępowanie w sieci jest rejestrowane. Zajmują się tym w różnych celach różne podmioty. Najczęstszym celem stosowania mechanizmów śledzenia są mechanizmy analityki. W tym artykule pochylimy się nad tematem z nieco bardziej prywatnej perspektywy. Technika, którą przybliżę nazywana jest metodą &lt;em&gt;obrazka śledzącego&lt;/em&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;zasada-działania&#34;&gt;Zasada działania&lt;/h2&gt;&#xA;&lt;p&gt;W celu zrozumienia tej metody, należy przeanalizować proces przeglądania obrazów za pośrednictwem przeglądarki. Jest on bardzo prosty. Niezależnie, czy obraz jest elementem strony internetowej czy odwiedzamy go bezpośrednio - w każdym przypadku mamy do czynienia z pobraniem zasobu z serwera. Poniższy schemat przedstawia proces w sposób uproszczony:&lt;/p&gt;</description>
    </item>
    <item>
      <title>CrunchBang Linux</title>
      <link>https://blog.michal.pawlik.dev/posts/crunchbang-linux/</link>
      <pubDate>Sun, 21 Dec 2014 09:44:47 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/crunchbang-linux/</guid>
      <description>&lt;p&gt;Od pewnego czasu zamierzałem zmienić system na netbooku. Dotychczas z pewnych względów musiałem używać systemu Windows 8.1, jednak teraz mogę powrócić do Linuxa. W mojej opinii system ten jest wydajniejszy, lepiej spełnia moje oczekiwania.&lt;/p&gt;&#xA;&lt;h2 id=&#34;wybór-dystrybucji&#34;&gt;Wybór dystrybucji&lt;/h2&gt;&#xA;&lt;p&gt;Zmieniając system kierowałem się przede wszystkim oczekiwaniem niskiego zużycia zasobów i dużej wydajności. Rozważałem kilka możliwości wybierając dystrybucję. Pierwszym pomysłem było Xubuntu, jednak uznałem, że wiązałoby się to w moim przypadku ze zmianą sporej części standardowo instalowanego oprogramowania. Kolejną rozważaną opcją był czysty Debian i dobór paczek do własnych potrzeb. W ostatecznym rozrachunku uznałem jednak, że nie ma potrzeby wyważać otwartych drzwi. Przegląd &lt;a href=&#34;http://distrowatch.com/index.php?language=PL&#34;&gt;distrowatch&lt;/a&gt; pod kątem moich potrzeb zaowocował wyborem dystrybucji &lt;a href=&#34;http://crunchbang.org/&#34;&gt;CrunchBag Linux&lt;/a&gt;. Jest to dystrybucja oparta na Debianie, używająca środowiska graficznego &lt;a href=&#34;http://pl.wikipedia.org/wiki/Openbox&#34;&gt;OpenBox&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Podstawy jQuery #5</title>
      <link>https://blog.michal.pawlik.dev/posts/podstawy-jquery-5/</link>
      <pubDate>Wed, 17 Dec 2014 11:14:32 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/podstawy-jquery-5/</guid>
      <description>&lt;p&gt;Po dłuższej przerwie powracamy do serii &lt;a href=&#34;http://michalp.net/blog/search/jquery&#34;&gt;Podstawy jQuery&lt;/a&gt;. Dzisiejszy artykuł poświęcimy praktycznemu zastosowaniu poznanej wiedzy.&lt;/p&gt;&#xA;&lt;h2 id=&#34;założenia-projektu&#34;&gt;Założenia projektu&lt;/h2&gt;&#xA;&lt;p&gt;Celem projektu będzie stworzenie skryptu, który pozwoli na utworzenie kolejki wczytywania obrazów na stronie. W internecie możemy znaleźć wiele rozmaitych stron zawierających jedynie &lt;em&gt;memy&lt;/em&gt; czy inne obrazy. Częstym problemem takich stron jest powolne buforowanie obrazów, szczególnie &lt;em&gt;gifów&lt;/em&gt;. Przedstawione tu rozwiązanie nie eliminuje problemu, jednak uzyskany efekt pozwoli poświęcić całe łącze użytkownika na wczytywanie każdego kolejnego obrazu, pozwalając na zachowanie płynności przeglądania.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Podstawy jQuery #4</title>
      <link>https://blog.michal.pawlik.dev/posts/podstawy-jquery-4/</link>
      <pubDate>Sat, 20 Sep 2014 20:37:30 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/podstawy-jquery-4/</guid>
      <description>&lt;p&gt;W kolejnej, czwartej już części serii &lt;a href=&#34;http://michalp.net/blog/posts/podstawy-jquery-3&#34;&gt;dokończymy temat&lt;/a&gt; technologii &lt;strong&gt;AJAX&lt;/strong&gt;. Na wstępie zaznaczam, że seria &lt;a href=&#34;http://michalp.net/blog/search/jquery&#34;&gt;Podstawy jQuery&lt;/a&gt; nie pokryje całego spektrum możliwości, jakie niesie za sobą ta technologia, a jedynie wprowadza do tematu. Dzisiejszy (krótszy niż zwykle) artykuł  zapozna nas z dwiema pozostałymi metodami.&lt;/p&gt;&#xA;&lt;h2 id=&#34;getscript&#34;&gt;getScript()&lt;/h2&gt;&#xA;&lt;p&gt;Pierwszą z metod jest &lt;a href=&#34;http://api.jquery.com/jquery.getscript/&#34;&gt;getScript()&lt;/a&gt;. Tworząc witryny, szczególnie takie, które wymagać będą zastosowania zewnętrznych mechanizmów JavaScript, pewne możliwości będą udostępniane użytkownikowi tylko pod pewnymi warunkami. Czasami źródło skryptu będzie różne w zależności od wyboru użytkownika bądź cech jego przeglądarki. Dobrym przykładem może być np mechanizm kodu Captcha udostępniany przez Google, który pojawia się tylko kiedy użytkownik wysyła pewne dane do naszej strony. Przykładowe zastosowanie:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Podstawy jQuery #3</title>
      <link>https://blog.michal.pawlik.dev/posts/podstawy-jquery-3/</link>
      <pubDate>Tue, 16 Sep 2014 17:12:10 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/podstawy-jquery-3/</guid>
      <description>&lt;p&gt;W trzecim artykule z serii &lt;strong&gt;Podstaw jQuery&lt;/strong&gt; zakończymy temat zdarzeń przeglądarki i przystąpimy do obsługi technologi  &lt;a href=&#34;https://pl.wikipedia.org/wiki/AJAX&#34;&gt;AJAX&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;dynaimczna-zawartość-dokumentu&#34;&gt;Dynaimczna zawartość dokumentu&lt;/h2&gt;&#xA;&lt;p&gt;Biblioteka jQuery pozwala nam, jak wspomniano w &lt;a href=&#34;http://michalp.net/blog/search/jquery&#34;&gt;poprzednich częściach&lt;/a&gt;, modyfikować zawartość strony. Wspomniane w &lt;a href=&#34;http://michalp.net/blog/posts/podstawy-jquery-2&#34;&gt;drugiej części serii&lt;/a&gt; metody obsługi zdarzeń mają pewną wadę związaną z dynamiczną zawartością. Polega ona na tym, że zdarzenie obsługiwane jest &lt;strong&gt;jedynie na obiektach obecnych w dokumencie&lt;/strong&gt; w chwili wykonania metody.&#xA;Kiedy rozważamy podstawowe zapotrzebowanie na obsługę zdarzeń nie stanowi to być może problemu. Problem pojawia się, kiedy nie mamy pewności ile obiektów i w jakiej kolejności będą się pojawiać. Szczęśliwie takie problemy zostały przewidziane przez twórców biblioteki. Z pomocą przychodzą nam metody &lt;a href=&#34;http://api.jquery.com/on/&#34;&gt;on()&lt;/a&gt; oraz &lt;a href=&#34;http://api.jquery.com/off&#34;&gt;off()&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Nowy design portfolio oraz bloga</title>
      <link>https://blog.michal.pawlik.dev/posts/nowy-design-portfolio-oraz-bloga/</link>
      <pubDate>Mon, 15 Sep 2014 20:36:15 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/nowy-design-portfolio-oraz-bloga/</guid>
      <description>&lt;p&gt;Ostatnia nieaktywność spowodowana była kilkoma czynnikami. Jednym z jej powodów było wprowadzenie nowej szaty graficznej. Nowy dobór barw, projekt &lt;a href=&#34;http://michalp.net&#34;&gt;strony głównej&lt;/a&gt;, a przede wszystkim logo zawdzięczam &lt;a href=&#34;http://norbit.portfoliobox.me/&#34;&gt;Norbertowi Kowalczykowi&lt;/a&gt;. Składam serdeczne podziękowania i zapraszam do zapoznania z &lt;a href=&#34;http://norbit.portfoliobox.me/&#34;&gt;Jego portfolio&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Już wkrótce trzecia odsłona &lt;a href=&#34;http://michalp.net/blog/search/jquery&#34;&gt;podstaw jQuery&lt;/a&gt;. W planach również wstęp do tworzenia prostych web-aplikacji oraz tworzenie domowego serwera opartego o Debian Linux.&lt;/p&gt;&#xA;&lt;p&gt;Zapraszam&lt;/p&gt;</description>
    </item>
    <item>
      <title>Podstawy jQuery #2</title>
      <link>https://blog.michal.pawlik.dev/posts/podstawy-jquery-2/</link>
      <pubDate>Fri, 22 Aug 2014 21:26:04 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/podstawy-jquery-2/</guid>
      <description>&lt;p&gt;W drugim artykule z serii &lt;strong&gt;Podstaw jQuery&lt;/strong&gt; dokładniej zapoznamy się z obsługą &lt;a href=&#34;http://www.w3schools.com/js/js_htmldom_events.asp&#34;&gt;zdarzeń przeglądarki&lt;/a&gt; oraz możliwościami jQuery w zakresie modyfikacji treści strony internetowej. W trakcie pracy bazować będziemy na &lt;a href=&#34;http://michalp.net/blog/posts/podstawy-jquery&#34;&gt;poprzednim artykule serii&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;zdarzenia-przeglądarki&#34;&gt;Zdarzenia przeglądarki&lt;/h2&gt;&#xA;&lt;p&gt;&lt;strong&gt;Zdarzenia&lt;/strong&gt; (events) to mechanizm JavaScript pozwalający na wykonanie określonego przez programistę kodu w chwili, kiedy wystąpi określone zdarzenie. Zdarzeniem takim może być kliknięcie w określony element strony, naciśnięcie klawisza czy zakończenie zapytania &lt;a href=&#34;https://pl.wikipedia.org/wiki/AJAX&#34;&gt;AJAX&lt;/a&gt; (co omówimy w dalszej części serii).&#xA;Zdarzenia możemy podzielić według elementów, który emitują informację o ich wystąpieniu:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Podstawy jQuery #1</title>
      <link>https://blog.michal.pawlik.dev/posts/podstawy-jquery/</link>
      <pubDate>Thu, 21 Aug 2014 17:34:48 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/podstawy-jquery/</guid>
      <description>&lt;p&gt;Jest to pierwszy z planowanego cyklu artykułów na temat biblioteki &lt;a href=&#34;http://jquery.com&#34;&gt;jQuery&lt;/a&gt;. Celem cyklu jest przybliżenie możliwości biblioteki, przedstawienie jej użycia w sposób prosty i przystępny nawet dla osób niedoświadczonych w programowaniu. Przystępując do lektury tego kursu czytelnik powinien jednak mieć &lt;strong&gt;podstawową wiedzę w zakresie HTML i CSS&lt;/strong&gt;. Zaczynamy!&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;http://code.jquery.com/&#34;&gt;Biblioteka jQuery&lt;/a&gt; to jeden z najlepszych projektów ułatwiających pracę w Java Script. Od swojego powstania w 2006r. do dziś projekt zaskarbił sobie sympatię twórców Front-endów i firm tworzących webaplikacje. Zminimalizowany kod źródłowy waży niecałe 38kb, zatem za projektem stoją wydajność i niezawodność.&lt;/p&gt;</description>
    </item>
    <item>
      <title>System statystyk Piwik</title>
      <link>https://blog.michal.pawlik.dev/posts/system-statystyk-piwik/</link>
      <pubDate>Wed, 20 Aug 2014 17:19:21 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/system-statystyk-piwik/</guid>
      <description>&lt;p&gt;&lt;strong&gt;Piwik&lt;/strong&gt; to otwartoźódłowy system służący do analizy ruchu na witrynach www. Został napisany w języku PHP, opiera się o bazę danych MySQL. Jest bardzo dobrą alternatywą dla google analytics, ponieważ wszystkie dane i statystyki pozostają na naszym serwerze. Modułowa budowa systemu i pełne spolszczenie sprawiają, że korzystanie z systemu jest bardzo proste i intuicyjne. Więcej zalet Piwik&amp;rsquo;a można poznać &lt;a href=&#34;http://michalbrys.pl/blog/alternatywa-dla-google-analytics/&#34;&gt;w tym wpisie&lt;/a&gt;. W tym artykule opiszę proces instalacji z paczki debiana. Opis instalacji zakłada, że w systemie są już zainstalowane i skonfigurowane serwery &lt;strong&gt;Apache&lt;/strong&gt; i &lt;strong&gt;MySQL&lt;/strong&gt;. Instalacja z paczki jest jak zwykle łatwiejsza niż w przypadku instalacji ze źródeł i przebiega następująco:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Podstawowe mnemotechniki</title>
      <link>https://blog.michal.pawlik.dev/posts/podstawowe-mnemotechniki/</link>
      <pubDate>Wed, 20 Aug 2014 12:14:48 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/podstawowe-mnemotechniki/</guid>
      <description>&lt;p&gt;Wielokrotnie zdarza się, że potrzebujemy zapamiętać listę przedmiotów czy czynności. W takiej sytuacji przydaje się notatnik czy aplikacja na smartfon jak &lt;a href=&#34;http://evernote.com&#34;&gt;Evernote&lt;/a&gt;. W tym artykule chcę jednak poruszyć inną metodę, która nie wymaga żadnego narzędzia. Miałem ostatnio okazję zapoznać się z dość starą już książką &lt;a href=&#34;http://lubimyczytac.pl/ksiazka/77719/pamiec-na-zawolanie-metody-i-techniki-pamieciowe&#34;&gt;Tonego Buzana - Pamięć na zawołanie&lt;/a&gt;. Właśnie ta publikacja nauczyła mnie &lt;strong&gt;metody haków pamięciowych&lt;/strong&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Haki pamięciowe to rodzaj zakładek, pomagających zapamiętać listę numerowaną od 1 do 10. Jej skuteczność polega na wymuszeniu współpracy prawej i lewej półkuli naszego mózgu. W tym celu metoda zaprzęga skojarzenia i wyobraźnie.&#xA;Pierwszym krokiem na drodze do korzystania z metody jest utworzenie systemu zakładek. Wyobraźmy sobie liczby od 1 do 10 i postarajmy się wyobrazić analogiczne do nich przedmioty/zwierzęta. Dla przykładu:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Jailbreak Kindle keyboard</title>
      <link>https://blog.michal.pawlik.dev/posts/jailbreak-kindle-keyboard/</link>
      <pubDate>Tue, 19 Aug 2014 22:55:30 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/jailbreak-kindle-keyboard/</guid>
      <description>&lt;p&gt;Jestem szczęśliwym posiadaczem Kindle 3. Ostatnio jednak zechciałem zmienić wygląd ekranu blokady. Okazuje się, że Amazon nie przewiduje standardowo takiej możliwości. Dzięki użytkownikom forum MobileRead jest to jednak możliwe. Wgranie modyfikacji umożliwiającej tę zmianę wymaga uprzedniego przeprowadzenia Jailbreaku. Jest to na szczęście legalne, Amazon &lt;a href=&#34;http://www.amazon.com/gp/help/customer/display.html?nodeId=200203720&#34;&gt;udostępnił oprogramowanie Kindle jako OpenSource&lt;/a&gt;.&#xA;Zmianę obrazów ekranu blokady umożliwia modyfikacja udostępniona przez &lt;a href=&#34;yifan.lu&#34;&gt;Yifan Lu&lt;/a&gt;, udostępniona wraz z plikami jailbreaka w tym &lt;a href=&#34;http://www.mobileread.com/forums/showthread.php?t=88004&#34;&gt;wątku&lt;/a&gt;.&#xA;Sam proces jest bardzo prosty i szczegółowo opisany &lt;a href=&#34;http://wiki.mobileread.com/wiki/Kindle_Screen_Saver_Hack_for_all_2.x,_3.x_%26_4.x_Kindles&#34;&gt;tutaj&lt;/a&gt;.&#xA;W skrócie:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Blog ruszył</title>
      <link>https://blog.michal.pawlik.dev/posts/pocztek-bloga/</link>
      <pubDate>Tue, 19 Aug 2014 17:52:45 +0000</pubDate>
      <guid>https://blog.michal.pawlik.dev/posts/pocztek-bloga/</guid>
      <description>&lt;p&gt;Z dniem dzisiejszym rusza blog, mam nadzieję że przyda się on nie tylko mnie :)&#xA;Celem bloga jest udokumentowanie i przedstawienie niektórych efektów mojej pracy. Planowana tematyka bloga to IT: programowanie, Linux i technologie webowe.&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
