<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: mafflerbach</title>
    <description>The latest articles on DEV Community by mafflerbach (@mafflerbach).</description>
    <link>https://dev.to/mafflerbach</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F435157%2Fb552856d-0c19-4cf0-a0bb-0546d14d536d.jpg</url>
      <title>DEV Community: mafflerbach</title>
      <link>https://dev.to/mafflerbach</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mafflerbach"/>
    <language>en</language>
    <item>
      <title>Maintaining and Supporting Over 50 Services with Java, Apache Camel, and ActiveMQ/Kafka.</title>
      <dc:creator>mafflerbach</dc:creator>
      <pubDate>Sun, 07 May 2023 19:12:02 +0000</pubDate>
      <link>https://dev.to/mafflerbach/maintaining-and-supporting-over-50-services-with-java-apache-camel-and-activemqkafka-1kc1</link>
      <guid>https://dev.to/mafflerbach/maintaining-and-supporting-over-50-services-with-java-apache-camel-and-activemqkafka-1kc1</guid>
      <description>&lt;p&gt;Maintaining and supporting over 50 services can be quite a challenging task, but with the right tools and processes in place, it can become a manageable task. In this blog post, we will share some of our general experiences on how we maintain and support these services.&lt;/p&gt;

&lt;p&gt;We are running our services in java using the apache camel framework and using activeMq or kafka as a message bus system. All of our services implement the Dead Letter Queue (DLQ) pattern, which is implemented on the framework level. The modules of our services are strictly divided into filter, enrich, transform or send.&lt;/p&gt;

&lt;p&gt;One of the daily tasks of our support team is to check if messages are failing and then contacting the stakeholder to determine whether we should dump and forget the message or replay it. It can get tedious to communicate with the creator or receiver of the message and wait for their response, as we are just a "man in the middle" and do not have any ownership over the content of the message.&lt;/p&gt;

&lt;p&gt;However, our centralized logging and monitoring system, consisting of log4j and fluentd, has proven to be a useful tool. The logs are accessible via openSearch and allow us to quickly identify any issues. Monitoring is handled by Grafana and Prometheus as a data source, while Opsgeni serves as our alerting system. With all these tools in place, we are quickly alerted whenever something goes wrong, allowing us to address it promptly.&lt;/p&gt;

&lt;p&gt;Automated testing is also crucial in maintaining our services. We rely on integration tests based on jbehave, which helps us to detect issues early in the development cycle. We have also implemented a standard failure handling mechanism that is implemented at the framework level. This mechanism handles error messages and puts them on the right dead letter queue while also implementing an automated retry mechanism.&lt;/p&gt;

&lt;p&gt;In conclusion, maintaining and supporting over 50 services can be quite challenging, but with the right tools, processes, and mindset in place, it becomes a manageable task. Good communication, automated testing, a robust monitoring system, and a profound failure handling mechanism are all essential aspects of maintaining these services. By leveraging these tools and processes, we ensure that our services remain reliable, performant, and meet our stakeholder's needs.&lt;/p&gt;

</description>
      <category>java</category>
      <category>dlq</category>
      <category>maintaining</category>
    </item>
    <item>
      <title>How to Improve Service Resilience and Reliability with Error Monitoring and Logging</title>
      <dc:creator>mafflerbach</dc:creator>
      <pubDate>Fri, 28 Apr 2023 16:56:35 +0000</pubDate>
      <link>https://dev.to/mafflerbach/how-to-improve-service-resilience-and-reliability-with-error-monitoring-and-logging-1mkp</link>
      <guid>https://dev.to/mafflerbach/how-to-improve-service-resilience-and-reliability-with-error-monitoring-and-logging-1mkp</guid>
      <description>&lt;h1&gt;
  
  
  How to Improve Service Resilience and Reliability with Error Monitoring and Logging
&lt;/h1&gt;

&lt;p&gt;When building complex applications on Kubernetes, it's important to ensure that your services are reliable and resilient. One way to do this is by implementing error monitoring and logging, which can help you quickly detect and diagnose issues, as well as identify potential areas for improvement. In this blog post, we'll explore some best practices for error monitoring and logging in a Kubernetes environment with Java-based services.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Error Monitoring and Logging is Important
&lt;/h2&gt;

&lt;p&gt;Error monitoring and logging provides several benefits, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Improved Service Reliability&lt;/strong&gt;: By monitoring your services for errors and logging relevant information, you can quickly identify and resolve issues before they become major problems.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Faster Debugging and Troubleshooting&lt;/strong&gt;: When an issue does occur, having detailed logs and error messages can help you quickly identify the root cause of the problem and develop a solution.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Better Service Performance&lt;/strong&gt;: By analyzing your logs and monitoring metrics, you can identify areas for improvement and optimize your services for better performance.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Best Practices for Error Monitoring and Logging in Kubernetes
&lt;/h2&gt;

&lt;p&gt;To implement error monitoring and logging in a Kubernetes environment with Java-based services, here are some best practices to follow:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Use a Centralized Logging Solution
&lt;/h3&gt;

&lt;p&gt;With multiple services running on a Kubernetes cluster, it can be challenging to monitor logs and error messages across all services. That's why it's important to use a centralized logging solution, such as Elasticsearch or OpenSearch, which allows you to collect, analyze, and search logs from all of your services in one place.&lt;/p&gt;

&lt;p&gt;In this setup, you can use Elastic File System (EFS) to store logs as files, which can then be collected by a log aggregation agent like Fluentd. Fluentd can then forward these logs to your Elasticsearch or OpenSearch instance for indexing and searching.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Monitor Kubernetes Metrics
&lt;/h3&gt;

&lt;p&gt;In addition to monitoring logs and error messages, it's also important to monitor Kubernetes metrics, such as CPU and memory usage, network traffic, and application performance. This can help you identify potential issues and optimize your services for better performance.&lt;/p&gt;

&lt;p&gt;To monitor Kubernetes metrics, you can use Prometheus and Grafana. Prometheus collects metrics from your Kubernetes cluster and services, while Grafana provides a user-friendly dashboard for visualizing and analyzing these metrics.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Set Up Alerts
&lt;/h3&gt;

&lt;p&gt;Monitoring logs and metrics is important, but it's even more important to set up alerts for critical errors and issues. This allows you to be notified immediately when an issue occurs, so you can quickly respond and prevent any potential downtime or performance degradation.&lt;/p&gt;

&lt;p&gt;For this, you can use a tool like Opsgenie, which provides intelligent alerting based on the severity and type of issue. You can configure Opsgenie to send notifications to specific individuals or groups via email, SMS, or phone call.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Use Breadcrumb Logging
&lt;/h3&gt;

&lt;p&gt;Finally, it's important to implement breadcrumb logging, which involves adding small pieces of information to your logs at key points in your application. This can help you identify the flow of your application and the context in which errors occur, which can be especially useful when trying to troubleshoot complex issues.&lt;/p&gt;

&lt;p&gt;To implement breadcrumb logging in your Java-based services, you can use a logging library like Logback or Log4j2, which provide support for adding context information to your logs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;By following these best practices for error monitoring and logging in a Kubernetes environment with Java-based services, you can improve the reliability and resilience of your services, as well as optimize their performance. With centralized logging, Kubernetes metrics monitoring, alerts, and breadcrumb logging, you can quickly detect and diagnose issues, and ensure that your services are performing at their best.&lt;/p&gt;

</description>
      <category>monitoring</category>
      <category>kubernetes</category>
      <category>logging</category>
      <category>java</category>
    </item>
    <item>
      <title>PlantUML and Jira: Combining Forces to Simplify Gantt Chart Creation</title>
      <dc:creator>mafflerbach</dc:creator>
      <pubDate>Fri, 21 Apr 2023 15:56:35 +0000</pubDate>
      <link>https://dev.to/mafflerbach/plantuml-and-jira-combining-forces-to-simplify-gantt-chart-creation-2ob5</link>
      <guid>https://dev.to/mafflerbach/plantuml-and-jira-combining-forces-to-simplify-gantt-chart-creation-2ob5</guid>
      <description>&lt;p&gt;Are you tired of manually creating Gantt charts to track your project's progress? Look no further than PlantUML and Jira! These two powerful tools can combine forces to simplify the process and save you time.&lt;/p&gt;

&lt;p&gt;To get started, you'll need to extract the Jira tickets related to an Epic. Don't worry, it's easier than it sounds. Simply navigate to your Epic in Jira and select the "Export" option. From there, choose "Excel (all fields)" and save the file to your computer.&lt;/p&gt;

&lt;p&gt;Now that you have your Jira tickets, it's time to create your PlantUML file for the Gantt chart. If you're not familiar with PlantUML, it's a tool that allows you to create diagrams using a simple text syntax. To create a Gantt chart, you'll need to use the "gantt" keyword followed by the tasks and their start and end dates.&lt;/p&gt;

&lt;p&gt;To incorporate your Jira tickets, you can add them as tasks in your PlantUML file using the Jira ticket number as the task name. You can also include additional information such as the task assignee and due date.&lt;/p&gt;

&lt;p&gt;Here is an example of what your PlantUML code might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@startgantt
Project starts the 2023-04-21
Project starts the 21th of april 2023


[Jira Ticket-1] starts 2023-04-21 and  lasts  3 days 
[Jira Ticket-2] starts 2023-04-24 and  lasts  2 days 
[Jira Ticket-3] starts 2023-04-26 and  lasts  1 days 
[Jira Ticket-4] starts 2023-04-27 and  lasts  4 days 
[Jira Ticket-5] starts 2023-05-03 and  lasts  2 days 
[Jira Ticket-6] starts 2023-05-05 and  lasts  1 days 
[Jira Ticket-7] starts 2023-05-06 and  lasts  3 days 
[Jira Ticket-8] starts 2023-05-10 and  lasts  2 days 
[Jira Ticket-9] starts 2023-05-12 and  lasts  3 days 
[Jira Ticket-10] starts 2023-05-15 and lasts 1 days 


@endgantt

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For generating a PNG you just call&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;java -jar plantuml.jar path/to/your/file -tpng -o path/for/outpu/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you have your PlantUML file set up, it's time to generate the Gantt chart. There are several ways to do this, but one popular option is to use the PlantUML extension for Visual Studio Code. Simply open your PlantUML file in Visual Studio Code and use the extension to generate the Gantt chart.&lt;/p&gt;

&lt;p&gt;Of course, there are other ways to connect the dependencies between the tickets and add more information. You can find &lt;a href="https://plantuml.com/de/gantt-diagram"&gt;here&lt;/a&gt; more documentation, and perhaps other ideas for creating a quick timeline for your project. &lt;/p&gt;

&lt;p&gt;And there you have it, a Gantt chart created from your Jira tickets using PlantUML! Not only does this simplify the process, but it also ensures that your Gantt chart is up-to-date with your project's progress.&lt;/p&gt;

&lt;p&gt;So next time you need to create a Gantt chart, consider using PlantUML and Jira. It may not be as exciting as a superhero team-up, but it will certainly make your project management tasks more efficient.&lt;/p&gt;

&lt;p&gt;In conclusion, by combining PlantUML and Jira, you can create Gantt charts quickly and easily. With just a few simple steps, you'll have a comprehensive overview of your project's progress. So why not give it a try and see how much time you can save?&lt;/p&gt;

</description>
      <category>plantuml</category>
      <category>jira</category>
      <category>gantcharts</category>
      <category>projectmanagment</category>
    </item>
    <item>
      <title>DLQ Integration Patterns: A high-level Comparison of Apache Camel and Spring Boot</title>
      <dc:creator>mafflerbach</dc:creator>
      <pubDate>Fri, 14 Apr 2023 08:12:35 +0000</pubDate>
      <link>https://dev.to/mafflerbach/dlq-integration-patterns-a-high-level-comparison-of-apache-camel-and-spring-boot-3l72</link>
      <guid>https://dev.to/mafflerbach/dlq-integration-patterns-a-high-level-comparison-of-apache-camel-and-spring-boot-3l72</guid>
      <description>&lt;p&gt;This article provides only a high-level overview of the DLQ integration patterns in Apache Camel and Spring Boot. There is much more to explore and learn about these integration frameworks and their capabilities. The DLQ integration pattern is just the tip of the iceberg when it comes to the features and tools provided by Apache Camel and Spring Boot. Nevertheless, this article aims to provide an introduction to the DLQ integration pattern and to highlight the strengths and weaknesses of these frameworks in this context.&lt;/p&gt;

&lt;p&gt;The use of Dead Letter Queues (DLQs) in messaging systems is, in my opinion, one of the best patterns for implementing resilient and decoupled systems, providing a way to handle messages that could not be successfully processed. DLQs are used to store messages that have failed processing, allowing the message to be retried later or manually inspected by a developer.&lt;/p&gt;

&lt;p&gt;Integration frameworks such as Apache Camel and Spring Boot provide support for implementing DLQ integration patterns. In this article, we will compare the DLQ integration patterns provided by Apache Camel and Spring Boot and discuss their advantages and disadvantages.&lt;/p&gt;

&lt;h3&gt;
  
  
  About Apache Camel
&lt;/h3&gt;

&lt;h4&gt;
  
  
  DLQ integration patterns in Apache Camel
&lt;/h4&gt;

&lt;p&gt;Apache Camel is a powerful open source integration framework that provides support for various integration patterns, including DLQ integration. Camel allows developers to configure a separate channel for messages that could not be processed. The failed message is sent to the DLC channel where it can be retried or manually inspected. Camel provides a wide range of components that allow developers to integrate with different systems and protocols, making it a solid choice for enterprise-level integration.&lt;/p&gt;

&lt;h5&gt;
  
  
  Benefits of DLQ Integration in Apache Camel
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;Apache Camel provides a wide range of components that allow developers to integrate with various systems and protocols.&lt;/li&gt;
&lt;li&gt;Apache Camel has a large and active community that provides support and resources for developers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Disadvantages of DLQ integration in Apache Camel
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Configuring the DLC pattern in Camel can be complex and requires a good understanding of the framework.&lt;/li&gt;
&lt;li&gt;Developers may need to write custom code to implement the DLQ integration pattern in Camel.&lt;/li&gt;
&lt;li&gt;The documentation and usage of Camel can be limited compared to other frameworks, which can make it more difficult for developers to learn and use effectively.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  About Spring Boot
&lt;/h3&gt;

&lt;p&gt;Spring Boot is a popular open source framework for building enterprise-level applications. Spring Boot provides a set of features and tools that enable developers to quickly build and deploy applications. Spring Boot also provides support for integration with various messaging systems, making it a popular choice for implementing DLQ integration patterns.&lt;/p&gt;

&lt;h4&gt;
  
  
  DLQ Integration Patterns in Spring Boot
&lt;/h4&gt;

&lt;p&gt;Spring Boot provides support for the DLQ integration pattern through the use of the Error Channel pattern. The Error Channel pattern allows developers to configure a separate channel for messages that could not be processed. The failed message is sent to the error channel where it can be retried or manually inspected.&lt;/p&gt;

&lt;h5&gt;
  
  
  Benefits of DLQ integration in Spring Boot
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;Spring Boot provides a set of features and tools that enable developers to quickly build and deploy applications.&lt;/li&gt;
&lt;li&gt;The error channel pattern in Spring Boot provides a simple and easy-to-use way to handle failed messages.&lt;/li&gt;
&lt;li&gt;Spring Boot has a large and active community that provides support and resources for developers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  Disadvantages of DLQ integration in Spring Boot
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;Spring Boot provides limited support for integration with certain messaging systems, which can be a limitation in some cases.&lt;/li&gt;
&lt;li&gt;The error channel pattern in Spring Boot may not be as flexible as the DLC pattern in Apache Camel, which may limit some use cases.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Conclusion
&lt;/h4&gt;

&lt;p&gt;Both Apache Camel and Spring Boot provide support for implementing DLQ integration patterns. Apache Camel provides a wide range of components that allow developers to integrate with different systems and protocols, making it a solid choice for enterprise-level integration. Spring Boot provides a set of features and tools that enable developers to quickly build and deploy applications, making it a popular choice for implementation. &lt;/p&gt;

</description>
      <category>dlqintegration</category>
      <category>apachecamel</category>
      <category>springboot</category>
      <category>integrationframeworks</category>
    </item>
    <item>
      <title>Keeping Your Services Running Smoothly: A Guide to Java and Kubernetes Maintenance</title>
      <dc:creator>mafflerbach</dc:creator>
      <pubDate>Fri, 07 Apr 2023 13:32:48 +0000</pubDate>
      <link>https://dev.to/mafflerbach/keeping-your-services-running-smoothly-a-guide-to-java-and-kubernetes-maintenance-481c</link>
      <guid>https://dev.to/mafflerbach/keeping-your-services-running-smoothly-a-guide-to-java-and-kubernetes-maintenance-481c</guid>
      <description>&lt;p&gt;Welcome to the world of Java and Kubernetes maintenance, where the joy of coding meets the agony of production! Keeping your services running smoothly is no easy feat, especially when dealing with complex integration patterns like the Dead Letter Queue. But fear not, my fellow developer, for I am here to guide you through the treacherous waters of maintenance and help you avoid the pitfalls that come with it.&lt;/p&gt;

&lt;p&gt;Let’s start with Apache Camel, the integration framework that has been making waves in the developer community for quite some time now. With its extensive library of components, Camel is the go-to choice for many developers when it comes to building complex integration solutions. However, with great power comes great responsibility, and Camel is no exception to this rule.&lt;/p&gt;

&lt;p&gt;When working with Camel, one of the most common patterns that developers come across is the Dead Letter Queue (DLQ). For those of you who are unfamiliar with this pattern, it is used to handle messages that could not be delivered to their destination for various reasons. These reasons could range from network issues to incorrect message formats, and they can wreak havoc on your system if not handled properly.&lt;/p&gt;

&lt;p&gt;To implement the DLQ pattern, you first need to create a separate queue where all the undeliverable messages will be sent. This queue is called the Dead Letter Queue, and it should be monitored regularly to ensure that no messages are stuck there. To achieve this, you can set up an alert system that notifies you whenever a message is added to the DLQ.&lt;/p&gt;

&lt;p&gt;Now, let’s move on to the old stack, which consists of Spring and ActiveMQ. While this stack has been a reliable choice for many years, it’s time to move on and embrace the new stack based on Spring Boot and Kafka. Why, you ask? Well, for starters, Spring Boot provides a more streamlined development experience and allows you to focus on writing code rather than configuring the environment. And Kafka, on the other hand, is a highly scalable and fault-tolerant messaging system that can handle millions of messages per second.&lt;/p&gt;

&lt;p&gt;Migrating from the old stack to the new stack may seem daunting at first, but fear not, for it is not as difficult as it seems. You can start by creating a new project based on Spring Boot and Kafka and gradually migrate your code from the old project to the new one. This way, you can keep your existing codebase intact while gradually moving towards the new stack.&lt;/p&gt;

&lt;p&gt;But before you start migrating, make sure to thoroughly test your code to ensure that it works as expected. This is especially important when dealing with integration patterns like the DLQ, as any mistakes can have severe consequences. You can use tools like JUnit and Mockito to test your code and catch any errors before they make their way to production.&lt;/p&gt;

&lt;p&gt;In conclusion, maintaining Java and Kubernetes services can be a daunting task, but with the right approach, it can also be a rewarding one. When working with integration frameworks like Apache Camel, make sure to follow best practices and pay special attention to patterns like the Dead Letter Queue. And when migrating from the old stack to the new stack, take it slow and test your code thoroughly to avoid any unwanted surprises. And remember, a touch of humor can make even the most challenging tasks more enjoyable. So, keep calm and code on!&lt;/p&gt;

</description>
      <category>apachecamel</category>
      <category>dlq</category>
      <category>kubernetes</category>
      <category>java</category>
    </item>
    <item>
      <title>Fugitive - vim and git</title>
      <dc:creator>mafflerbach</dc:creator>
      <pubDate>Sat, 16 Jan 2021 17:30:50 +0000</pubDate>
      <link>https://dev.to/mafflerbach/fungitive-vim-and-git-pi5</link>
      <guid>https://dev.to/mafflerbach/fungitive-vim-and-git-pi5</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/tpope/vim-fugitive"&gt;vim-fugitive&lt;/a&gt; is the go-to git extension for VIM. I think there is no other git extension which is working so well. &lt;br&gt;
Fugitive is not only a simple git wrapper, but it can act like, if its needed.&lt;/p&gt;

&lt;p&gt;The most used mapping in my case are:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;
&lt;span class="nb"&gt;noremap&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;leader&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;ge &lt;span class="p"&gt;:&lt;/span&gt;Gblame&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;CR&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nb"&gt;noremap&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;leader&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;gs &lt;span class="p"&gt;:&lt;/span&gt;Gstatus&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;CR&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nb"&gt;noremap&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;leader&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;gc &lt;span class="p"&gt;:&lt;/span&gt;Gcommit&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;CR&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nb"&gt;noremap&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;leader&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;gl &lt;span class="p"&gt;:&lt;/span&gt;Gpull&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;CR&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nb"&gt;noremap&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;leader&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;gh &lt;span class="p"&gt;:&lt;/span&gt;Gpush&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;CR&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With &lt;code&gt;Gstatus&lt;/code&gt; you get a git status of your current repository.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SOv33uqm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.dropbox.com/s/3jrhm17jzdwysxk/fungitive-git-status.png%3Fraw%3D1" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SOv33uqm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.dropbox.com/s/3jrhm17jzdwysxk/fungitive-git-status.png%3Fraw%3D1" alt="fungitive-git-status.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want to stage a file. Use &lt;code&gt;s&lt;/code&gt; or &lt;code&gt;-&lt;/code&gt; for staging the file. &lt;br&gt;
You can also stage all your file at once, if you are using &lt;code&gt;s&lt;/code&gt; or &lt;code&gt;-&lt;/code&gt; on the header &lt;code&gt;Unstage&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you want to unstage, us &lt;code&gt;u&lt;/code&gt; on your item, or on the &lt;code&gt;Stage&lt;/code&gt; header.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Hmxh6t-d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.dropbox.com/s/gyhg28l1ik2zpzq/fungitive-git-status-2.png%3Fraw%3D1" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Hmxh6t-d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.dropbox.com/s/gyhg28l1ik2zpzq/fungitive-git-status-2.png%3Fraw%3D1" alt="fungitive-git-status-2.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want to see a diff, you go on the line of your changed file and hit &lt;code&gt;=&lt;/code&gt; or &lt;code&gt;i&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LxY2CMba--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.dropbox.com/s/sj07plb9m2yasfc/fungitive-git-status-3.png%3Fraw%3D1" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LxY2CMba--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.dropbox.com/s/sj07plb9m2yasfc/fungitive-git-status-3.png%3Fraw%3D1" alt="fungitive-git-status-3.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want to open the file, hit &lt;code&gt;Enter&lt;/code&gt;. The status buffer will stays, and the selected file will be open in a different buffer.&lt;/p&gt;

&lt;p&gt;With &lt;code&gt;Gcommit&lt;/code&gt; a additional split for your commit message will open. With save and close, the commit will be executed.&lt;/p&gt;

&lt;p&gt;With &lt;code&gt;Gpush&lt;/code&gt; your commit will be pushed to your remote. &lt;/p&gt;

&lt;p&gt;In the case you have to revert you local changes, with &lt;code&gt;Gread&lt;/code&gt; it will be performing a &lt;code&gt;git checkout -- %&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If you want to take a look on your git logs? No problem, fungitive is covering that too.&lt;br&gt;
It will open your git log in a quickfix list, and it shows you what happened in previous commits.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NzudJRpp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.dropbox.com/s/7tszan44vy7p1vw/fungitive-git-log.png%3Fraw%3D1" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NzudJRpp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.dropbox.com/s/7tszan44vy7p1vw/fungitive-git-log.png%3Fraw%3D1" alt="fungitive-git-log.png"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>git</category>
      <category>vim</category>
      <category>fugitive</category>
    </item>
    <item>
      <title>How to build a Keyboard</title>
      <dc:creator>mafflerbach</dc:creator>
      <pubDate>Sat, 09 Jan 2021 11:57:57 +0000</pubDate>
      <link>https://dev.to/mafflerbach/how-to-build-a-keyboard-pb0</link>
      <guid>https://dev.to/mafflerbach/how-to-build-a-keyboard-pb0</guid>
      <description>&lt;p&gt;You believe it, or not - building a Keyboard is simple. &lt;br&gt;
Building a split Keyboard is a little bit more complex, but if you understand the basics, it's still possible.&lt;br&gt;
In this series, we are building a split mechanical keyboard with led lights. We will setup our firmware which is based on &lt;a href="https://qmk.fm/"&gt;QMK&lt;/a&gt;, which is the most famous and customizable firmware for DIY keyboards. And we will create our keymaps and defining our layers on our will. &lt;/p&gt;

&lt;p&gt;I build already a split keyboard and it was a fun experience, and it is my daily driver. But because it is fun to build one, I want to build my next keyboard, which will complete different in keys key positioning and look and feel. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gxwEHXpb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.dropbox.com/s/26rdgwjzgtyna7e/keyboard-top.jpg%3Fraw%3D1" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gxwEHXpb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.dropbox.com/s/26rdgwjzgtyna7e/keyboard-top.jpg%3Fraw%3D1" alt="keyboard-top.png" width="880" height="660"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sahxJ7j9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.dropbox.com/s/9v9i6stqeapsqzj/keyboard-bottom.jpg%3Fraw%3D1" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sahxJ7j9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.dropbox.com/s/9v9i6stqeapsqzj/keyboard-bottom.jpg%3Fraw%3D1" alt="keyboard-bottom.png" width="880" height="660"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If I put my both half together, you will see, it is a standard US 60% keyboard. I have two additional layer for my F keys, and audio and light control as well.&lt;/p&gt;

&lt;p&gt;But to build a Keyboard is not cheap. &lt;br&gt;
This build has a price tag of something around 130 Euros (~159 USD), and that is just summarize the part cost. The hours of work is not included.&lt;/p&gt;

&lt;p&gt;Of course its easier, and less time consuming and cheaper, to just buy a keyboard. And in comparison to a massmarket mechanical keyboard ,it is a expensive Keyboard.&lt;br&gt;
But I enjoy to tinker, I love the process of making things and the outcome will be a keyboard which is fitting my needs. &lt;/p&gt;

&lt;p&gt;This time I decide to build a keyboard which is quite different to a normal staged layout. This layout called &lt;code&gt;columnar staged&lt;/code&gt; it will be similar to an redox. I want to use this templates from &lt;a href="https://www.thingiverse.com/thing:2886662"&gt;thingivers&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The top and bottom plate will be modified, so that the Arduinos are placed visible and beside the key areas. With my current keyboard I got used to it, that both part have quite a distance to each others, to have the Arduinos right to the center will be not a problem for me. My next goal is, to have it as flat as possible. My current setup is a little bit to high in my opinion. Also the reason why the Arduinos is on the side instead underneath the top plate. The top and bottom plate is again clear acrylic and I want to use LEDs as back-lights. I know its possible to have LEDs for each keys with the custom firmware, but don't know if its maybe again the wish of having it as flat as possible for a hardwired keyboard.&lt;/p&gt;

&lt;h2&gt;
  
  
  Partlist
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Switches Kailh Low Profile Red pro (Linear 35g) (70 PCS 50 EUR)&lt;/li&gt;
&lt;li&gt;top and bottom plate (49 EUR Lasercut services)&lt;/li&gt;
&lt;li&gt;arduino (Pro Micro)  (3PCS 10 EUR)&lt;/li&gt;
&lt;li&gt;3.5mm male and female jacks (5pcs 9 EUR)&lt;/li&gt;
&lt;li&gt;keycaps (17 EUR)&lt;/li&gt;
&lt;li&gt;diodes 1N4148 (100pcs 1.90 EUR)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Other stuff
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;solderiron&lt;/li&gt;
&lt;li&gt;resistors&lt;/li&gt;
&lt;li&gt;cables&lt;/li&gt;
&lt;li&gt;usb cable with data line&lt;/li&gt;
&lt;li&gt;spacer for top and bottom plate&lt;/li&gt;
&lt;li&gt;perf board&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You see, my next board will be also something around the 159 USD mark.&lt;/p&gt;

&lt;p&gt;In my next part I will go deeper into Keyboard matrices, QMK firmware and how to create the keymaps.&lt;/p&gt;

</description>
      <category>keyboard</category>
      <category>diy</category>
      <category>mechanical</category>
    </item>
    <item>
      <title>Write github reviews comments from vim</title>
      <dc:creator>mafflerbach</dc:creator>
      <pubDate>Sat, 02 Jan 2021 14:04:11 +0000</pubDate>
      <link>https://dev.to/mafflerbach/write-github-reviews-comments-from-vim-310n</link>
      <guid>https://dev.to/mafflerbach/write-github-reviews-comments-from-vim-310n</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/AGhost-7/critiq.vim"&gt;Critiq&lt;/a&gt; is a neovim plugin to review github pull requests. &lt;/p&gt;

&lt;p&gt;To setup Critic you have to set environment variables in your shell. &lt;br&gt;
Be aware - if you want to use it in a corporate field, you access token should authorized the sso from your organization.&lt;/p&gt;

&lt;p&gt;Usually you are doing it in exporting this in you shell rc file. &lt;br&gt;
In my case it is the &lt;code&gt;~/.zshrc&lt;/code&gt; in bash it is in the &lt;code&gt;~/.bashrc&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;GH_PASS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Your github token generated [here](https://github.com/settings/tokens)"&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;GH_USER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"YourGithubUsername"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With &lt;code&gt;:Critiq&lt;/code&gt; you get an separated buffer with all the open pull requests. &lt;/p&gt;

&lt;p&gt;With enter, you will open the diff which belongs to the pr.&lt;br&gt;
With &lt;code&gt;:CritiqCommentLine&lt;/code&gt; you can right away commenting on the line. It will open a separated split buffer. With &lt;code&gt;:CritiqSubmitComment&lt;/code&gt; &lt;br&gt;
it will post your comment on github. &lt;/p&gt;

&lt;p&gt;In the case that you are satisfied with the PR, you can also use &lt;code&gt;CritiqApprove&lt;/code&gt; to approve the request.&lt;/p&gt;

&lt;p&gt;Sadly this extension is not touched for a long time. It will still do the work, but occasionally you will facing some error, if you want to open a pr. But in general you are able to work with that extension.&lt;/p&gt;

&lt;p&gt;This are the main feature in my opinion. &lt;/p&gt;

&lt;p&gt;But there are a lot more possibilities if we take a look on the Commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;:CritiqApprove
:CritiqBrowsePr
:CritiqCheckout
:CritiqComment
:CritiqCommentLine
:CritiqDeleteBranch
:CritiqEditLabels
:CritiqListComments
:CritiqListCommits
:CritiqLoadMorePrs
:CritiqMerge
:CritiqOpenFile
:CritiqOpenPr
:CritiqPull
:CritiqRequestChanges
:CritiqSubmitComment
:CritiqSubmitReview
:CritiqToggleLabel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I will try to adapt my workflow and figuring out if this will feel comfortable, but it looks promising. &lt;/p&gt;

</description>
      <category>github</category>
      <category>nvim</category>
      <category>review</category>
    </item>
    <item>
      <title>qutebrowser loading browser session from command line</title>
      <dc:creator>mafflerbach</dc:creator>
      <pubDate>Sun, 27 Dec 2020 22:23:33 +0000</pubDate>
      <link>https://dev.to/mafflerbach/qutebrowser-loading-browser-session-from-command-line-4i2l</link>
      <guid>https://dev.to/mafflerbach/qutebrowser-loading-browser-session-from-command-line-4i2l</guid>
      <description>&lt;p&gt;This will be a shot one. In qutebrowser you have the possibility to save browser sessions. This will save all your current open tabs.&lt;br&gt;
You can obviously loading this session files, and all the tabs will be restored.&lt;/p&gt;

&lt;p&gt;In my case it comes handy, in support weeks when I have to monitor different pages.&lt;/p&gt;

&lt;p&gt;And to have a more direct access, I wrote a two liner and combine rofi with that. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xD86MJ3Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.dropbox.com/s/v14bgc3twjhk1h9/qutebrowser-session-selector.png%3Fraw%3D1" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xD86MJ3Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.dropbox.com/s/v14bgc3twjhk1h9/qutebrowser-session-selector.png%3Fraw%3D1" alt="qutebrowser-session-selector.png" width="880" height="601"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="nv"&gt;sessions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt; &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.local/share/qutebrowser/sessions | rofi &lt;span class="nt"&gt;-dmenu&lt;/span&gt; &lt;span class="nt"&gt;-theme&lt;/span&gt; ~/dotfiles/i3/rofi.rasi&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$sessions&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;qutebrowser &lt;span class="s2"&gt;":session-load &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;sessions&lt;/span&gt;&lt;span class="p"&gt;/\.yml/&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>automation</category>
      <category>qutebrowser</category>
      <category>cli</category>
    </item>
    <item>
      <title>Why I love programming</title>
      <dc:creator>mafflerbach</dc:creator>
      <pubDate>Tue, 22 Dec 2020 21:44:53 +0000</pubDate>
      <link>https://dev.to/mafflerbach/why-i-love-programming-55jl</link>
      <guid>https://dev.to/mafflerbach/why-i-love-programming-55jl</guid>
      <description>&lt;p&gt;I am now for 16 years in this industry. And still I become exited about new technologies and there possibilities.&lt;br&gt;
I like to have the chance to program everything what comes in my mind.&lt;/p&gt;

&lt;p&gt;I have a boring workflow? I can write a script for this.&lt;br&gt;
I want to scan a qr code to prepare my groceries and prepping the week? I have a script for that. &lt;br&gt;
The current look of my media center is not on point of my taste? I can change how I want it, or writing one from scratch. &lt;br&gt;
I want to build my custom keyboard? Considered as done. &lt;/p&gt;

&lt;p&gt;And with every small script, or every time I "just play" I am learning new stuff or even new languages.&lt;/p&gt;

&lt;p&gt;I started with rust, because of curiosity, and start to work on a media center based on mpv.&lt;br&gt;
On the way, I learn rust with real problems to solve. How to do Frontend, how to manage Backend. Writing to a database and on a socket to use mpv. Scanning the directories for Content, and ask third-party APIs to get movie informations and some other bits and bytes to solve my problems, or my feature list.&lt;/p&gt;

&lt;p&gt;Today I played around with python and speech-recognition and hacking something together to have an alexa "clone". &lt;/p&gt;

&lt;p&gt;I wrote a tool for smoke testing our solutions also in rust. This contains writing on a message queue, and getting the logs from the remote server, where the solutions is deployed. Of course in that manner, that I just can copy and paste the outcome to jira. Now when I am thinking of, my next task will be that the smoke tester will do the comment as well (yeah I am lazy af and hate jira). &lt;/p&gt;

&lt;p&gt;I am using awesome wm. You can literally program every aspect and not only related to the look and feel. Its written in Lua. I write lots of smaller things in bash.&lt;/p&gt;

&lt;p&gt;The power of coding in general is, to make my life easier when I am sitting at my pc. I really enjoy the process of fiddling stuff out, learn new languages or get a peak in side a new technology. To solve complex problems and provide a program for that in the best way possible, is pure excitement for me. &lt;/p&gt;

&lt;p&gt;I hope that I will never lose that joy and my curiosity for my profession. I am really in the lucky position, that my hobby is my job.&lt;/p&gt;

</description>
      <category>story</category>
      <category>personal</category>
    </item>
    <item>
      <title>Openfortivpn - automatet network interface switcher</title>
      <dc:creator>mafflerbach</dc:creator>
      <pubDate>Thu, 17 Dec 2020 10:21:39 +0000</pubDate>
      <link>https://dev.to/mafflerbach/openfortivpn-automatet-network-interface-switcher-l09</link>
      <guid>https://dev.to/mafflerbach/openfortivpn-automatet-network-interface-switcher-l09</guid>
      <description>&lt;p&gt;On our workplace we have to use Fortinet to connect to our VPN Network.&lt;br&gt;
But if I'm connected to wifi and cable, some how I have issues to resolve addresses within the company network. So every time, I deactivate my wifi and establish then the VPN connection. &lt;br&gt;
But - most of the time I forget this step. So I disconnect the VPN, deactivate wifi, and reactivate the connection. We have also two way Auth activated, so in a bad case I have to type three times Auth passwords (root pw, because its needed from client, network Auth from the company, and the two way Auth pin, which will be send to me)&lt;/p&gt;

&lt;p&gt;So, I wrote a script...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="nv"&gt;cableInterface&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"enp0s31f6"&lt;/span&gt;
&lt;span class="nv"&gt;wifiInterface&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"wlp3s0"&lt;/span&gt;

&lt;span class="nv"&gt;wireConnecton&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;ethtool &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$cableInterface&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;Link | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;&lt;span class="s1"&gt;' '&lt;/span&gt; &lt;span class="nt"&gt;-f3&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;wifiConnecton&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;ethtool &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$wifiInterface&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;Link | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;&lt;span class="s1"&gt;' '&lt;/span&gt; &lt;span class="nt"&gt;-f3&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;while&lt;/span&gt; :&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    case&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
        &lt;span class="nt"&gt;-c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 

            tmux kill-session &lt;span class="nt"&gt;-t&lt;/span&gt; VPN
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$wifiConnecton&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"yes"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$wireConnecton&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"yes"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
                &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"disable wifi"&lt;/span&gt;
                nmcli device disconnect &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$wifiInterface&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
            &lt;span class="k"&gt;fi&lt;/span&gt;

            &lt;span class="c"&gt;# activate wifi if i am not on cable&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$wifiConnecton&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"no"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$wireConnecton&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"no"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
                &lt;/span&gt;nmcli device connect &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$wifiInterface&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
            &lt;span class="k"&gt;fi&lt;/span&gt;
            &lt;span class="c"&gt;# get passwords and usernames&lt;/span&gt;
            &lt;span class="nv"&gt;sysPass&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;pass show path/to/rootPw | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-n1&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
            &lt;span class="nv"&gt;pass&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;pass show path/for/vpnaccess | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-n1&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
            &lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;pass show path/for/vpnaccess | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-n1&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

            &lt;span class="c"&gt;# create new tmux session named VPN and establish vpn connection&lt;/span&gt;
            &lt;span class="nb"&gt;sleep &lt;/span&gt;2
            tmux new-session &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"VPN"&lt;/span&gt;  &lt;span class="nb"&gt;sudo&lt;/span&gt; /usr/bin/openfortivpn &lt;span class="nt"&gt;-c&lt;/span&gt; /etc/openfortivpn/config &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;  &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$pass&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
            &lt;span class="nb"&gt;sleep &lt;/span&gt;1
            &lt;span class="c"&gt;# send root password to system auth&lt;/span&gt;
            tmux send-keys &lt;span class="nt"&gt;-t&lt;/span&gt; &lt;span class="s2"&gt;"VPN:0"&lt;/span&gt; &lt;span class="nv"&gt;$sysPass&lt;/span&gt; Enter
            &lt;span class="p"&gt;;;&lt;/span&gt;
        &lt;span class="nt"&gt;-k&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
            &lt;span class="c"&gt;# kill vpn conneciton &lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$wifiConnecton&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"no"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
                 &lt;/span&gt;nmcli device connect &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$wifiInterface&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
            &lt;span class="k"&gt;fi
            &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;pass show path/to/rootPw | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-n1&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; | &lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-S&lt;/span&gt; killall openfortivpn 
            &lt;span class="c"&gt;# kill session&lt;/span&gt;
            tmux kill-session &lt;span class="nt"&gt;-t&lt;/span&gt; VPN
            &lt;span class="p"&gt;;;&lt;/span&gt;
        &lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nb"&gt;break
    &lt;/span&gt;&lt;span class="k"&gt;esac
    &lt;/span&gt;&lt;span class="nb"&gt;shift
&lt;/span&gt;&lt;span class="k"&gt;done&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But I want to add some additional breeze. I am using rofi not only as window switcher and application launcher. I trigger as well some custom script e.g. change my wallpaper and color theme, or trigger Jenkins builds. So I add this script to my custom launcher, and now I just have to type in the pin which will be send to my mobile phone.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yZP-ZE0m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.dropbox.com/s/xevwns0vh9nr87q/vpn-rofi.png%3Fraw%3D1" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yZP-ZE0m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.dropbox.com/s/xevwns0vh9nr87q/vpn-rofi.png%3Fraw%3D1" alt="vpn-rofi.png" width="880" height="587"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>nvim</category>
      <category>programming</category>
      <category>setup</category>
    </item>
    <item>
      <title>Animated glassmorphism login in css and html</title>
      <dc:creator>mafflerbach</dc:creator>
      <pubDate>Thu, 10 Dec 2020 09:23:43 +0000</pubDate>
      <link>https://dev.to/mafflerbach/animated-glassmorphism-login-in-css-and-html-3jf1</link>
      <guid>https://dev.to/mafflerbach/animated-glassmorphism-login-in-css-and-html-3jf1</guid>
      <description>&lt;p&gt;I really like this blury glass effects, so I try to implement something in css and html.&lt;/p&gt;

&lt;p&gt;I did't use any thirdparty js lib for the animation as well and it looks awesome (imo) and it was really simple to implement.&lt;/p&gt;

&lt;p&gt;Here is jsfiddle:&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://jsfiddle.net/mafflerbach/8ervpqw4/5//embedded/result,html,css//dark" width="100%" height="600"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>css</category>
      <category>html</category>
    </item>
  </channel>
</rss>
