teleren/devto huggingface dataset:
Introduction to UPnP Client for Rust
Tags: upnp, rust, network, programming
Published: 2023-01-30 22:06:15

The Universal Plug and Play (UPnP) protocol is a set of networking protocols that allows for seamless discovery and communication between networked devices. UPnP enables devices such as smart home appliances, gaming consoles, and media players to discover each other and exchange information on a network.

This Rust crate provides a UPnP client library, making it easy for developers to build UPnP-enabled applications in Rust. With this library, developers can discover UPnP devices on the network, retrieve information about them, and communicate with them using UPnP services.

### Features
- Discover UPnP devices on the network
- Retrieve information about UPnP devices such as device type, friendly name, manufacturer, model, and services
- Communicate with UPnP services using control and event URLs

### Getting Started
To start using the UPnP Client crate in your Rust project, add the following to your `Cargo.toml` file:
```toml
[dependencies]
upnp-client = "0.1"
```
### Example Usage
Here's a basic example that demonstrates how to use the UPnP Client library to discover UPnP devices on the network and retrieve information about them. The example will print out a JSON representation of each device found on the network, including its device type, friendly name, location, manufacturer, model, and services.

```rust
use colored_json::prelude::*;
use futures_util::StreamExt;

use crate::discovery::discover_pnp_locations;

mod discovery;
mod types;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let devices = discover_pnp_locations();
    tokio::pin!(devices);

    while let Some(device) = devices.next().await {
        let json = serde_json::to_string_pretty(&device)?;
        println!("{}", json.to_colored_json_auto()?);
    }

    Ok(())
}
```
The example uses the discover_pnp_locations function from the discovery module to initiate UPnP device discovery on the network. The function returns a stream of UPnP devices, which the example loops through and prints out in a JSON format.

### Conclusion
The UPnP Client library for Rust provides a convenient and easy-to-use solution for discovering and communicating with UPnP devices on a network. With its powerful features, developers can quickly build UPnP-enabled applications in Rust.
If you're interested in contributing to the `upnp-client-rs` project, you're more than welcome to do so! This Rust crate is open-source and hosted on GitHub at https://github.com/tsirysndr/upnp-client-rs, so feel free to check it out and make any contributions you feel would be useful. Whether you have bug fixes, improvements, or new features, all contributions are appreciated. Before submitting a pull request, please make sure to review the contribution guidelines in the repository's `CONTRIBUTING.md` file.
Jornada para me tornar um DevOps Jr
Tags: devops, devjournal, career, community
Published: 2023-01-30 21:57:29

## O começo

### A Comunidade e o DevOpsDay Vitoria

No inicio eu estudava e trabalhava com frontend, mas fui muito bem abraçado e acolhido pela comunidade DevOps, costumo dizer que fui adotado por eles, mas sinto que a palavra que defini essa comunidade é **ACOLHIMENTO**. 

Sempre me senti um pouco sozinho no meio da TI por não conhecer pessoas com mesmos ideais que eu. E estar com eles me traz muito uma sensação que estou em um ambiente de amizade e seguro.

Sempre gostei de ensinar, tanto que comecei meu [blog](https://dev.to/henriquebros) e fiz o [Arduino4Noobs](https://github.com/HenriqueBros/Arduino4noobs) junto com a comunidade [He4rt](https://twitter.com/He4rtDevs), e fazendo parte de movimentos sociais como o [nucleo de tecnologia do MTST](https://nucleodetecnologia.com.br), onde ensinamos programação e temos diversos projetos para ajudar e facilitar a vida dos acampados.

No meio disso tudo fui ficando cada vez mais próximo do Jeferson o [badtux_](https://twitter.com/badtux_), fizemos o bonde o MTST, fui para o DevOpsDay Vitoria, que ai está um ponto importante, pois sinto que depois desse evento minha vida mudou completamente.

Eu estava a muitos meses sem sair de casa devido a depressão, mas estar no DevOpsDay, me deu muito mais energia, vi como somos muito queridos, conheci pessoas super importantes para mim, e recebi os  melhores abraços.

Depois de algum tempo comecei minha mentoria com o Jef e virei embaixador [LINUXtips](https://twitter.com/LINUXtipsBR) e com todo esse esfôrço e dedicação junto com o Jef consegui a minha vaga como Analista DevOps na [SPIRITSEC](https://spiritsec.com/).

E o melhor e o que mais gosto disso tudo, foi que conheci pessoas que hoje são meus amigos e que tenho um imenso carinho e admiração.


## Entrando na SpiritSec

### A primeira Semana

Comecei na Spiritsec  dia 18/01/2023. Nessa Primeira semana aprendi muitas coisas novas e consegui aplicar muitos conhecimentos adquiridos com os cursos da Linuxtips. Trabalhar junto do Gleydson ( criador do [Guia Foca](https://www.guiafoca.org/) ), Michelle, Gian e Mateus tornam esse inicio de carreira muito mais tranquilo, me dando confiança e animo nos novos desafios.

Estou feliz com minha evolução e como consigo ver uma grande crescimento profissional e pessoal junto com a SpiritSec
What type of SSD do you need?
Tags: ssd
Published: 2023-01-30 21:55:15

Get the most out of your PC with an SSD! But how do you determine which is best for you? Let us provide guidance and lead to a solution in two easy steps. Get ready - discover the superior speed, graphics quality or game-load times that can be yours when using an appropriate SSD tailored specifically to your needs.

## Ensure that your SSD is compatible with the device it will be used for
Whether you're building a PC from scratch, upgrading an existing device or shopping for a ready-to-use computer system: to ensure seamless installation of your internal SSD, it's best to begin by researching the type and compatibility. Most devices support 2.5 inch drives; however if you are looking at using other variants like M2 cards then locate the model number of your motherboard/PC online in order to ascertain which connectors can be used with ease.

## 2.5 SSDs
A 2.5-inch SSD can offer effortless setup and is the most popular size, making it ideal for everyday use in laptops, consoles, desktop PCs (with mounting brackets) or NAS devices. Before installation make sure to double-check its height – 7mm fits a 9.5mm drive slot but requires an extra obtaining spacer/mounting bracket if needed!

## mSATA SSDs
An [mSATA SSD](https://innobytech.com/best-msata-ssd/) is an ideal choice for users wanting to upgrade their laptop or desktop with a compact, easily accessible storage solution. Installation of the card requires minimal technical knowledge and can be done quickly. Perfect for everyday use such as gaming or audiovisual editing. Those looking to enjoy these benefits should check they have an appropriate device equipped with the correct mSATA slot before proceeding.

## M.2 SSDs
Whether for gaming, photo or audio editing, M.2 cards are an attractive option to enhance the performance of your PC. Unlike most computer upgrades which require a fair amount of technical knowledge and preparation time prior to installation, setting up an M.2 card is relatively accessible with average DIY setup skills - as long as you pay extra attention to the key type needed by SSDs in addition to interface and protocol requirements associated with this device!

## PCIe
Upgrade your desktop setup and get ahead of the competition with a PCIe SSD. This powerful device enables you to enjoy top-tier performance, perfect for gaming or intensive tasks such as audiovisual editing. Installing it is straightforward: all you need is reasonable computer knowledge and an available slot in your machine's case – ideal if there are no M.2 slots left on the motherboard!

## Conclusion
Whatever your usage needs, there is a range of solid state drives available to get the most out of your PC. Ensure accurate compatibility for a successful installation and enjoy the benefits of superior speed, graphics quality or game-load times! With these considerations in mind, you'll be fully prepared for that ultimate upgrade.
These Are the 2 Most Difficult Choices I’ve Ever Had to Make Personally to Help Me Grow and Reach My Goals.
Tags: beginners, productivity, watercooler, writing
Published: 2023-01-30 21:54:04

When I was 22 (and joined the workforce), I decided to focus on myself first.

Of course, whenever we set goals in life, life tests us. And I was no exception.

These were the two most difficult decisions I'd ever had to make in my life, and both directly impacted how I saw my environment and how I framed it in a way that helped me grow.

## Hard Choice #1: Engineering your environment by cutting "bad ones"

The environment we live in is what makes us who we are.

Being in an environment that encourages your goals will make achieving them easier, while an environment that discourages them will make it nearly impossible. So after setting my goal to focus on myself and my growth, I thought long and hard about my current environment (including work, activities, and friends). I then tried to assess how they either encouraged or discouraged me from achieving my goals and set my time accordingly.

I focused on the activities that helped me achieve them and cut down on the ones that hindered me.

Spending less time on activities and with people that discouraged my goals was challenging; after all, there was a reason they were in my life. Still, in the end, I chose to immerse myself in environments that assisted me in achieving my goals, making them easier to achieve.

## Hard Choice #2: Not dwelling on the past but focusing on the future

We love to focus on the past; it's all we've ever known.

But times are changing, and so are our goals, priorities, and needs. So one day, I decided not to be controlled by my past and actively focus on what was ahead. Judging actions, habits, and even other people not by what they did in the past but by what they are doing now was hard, but it helped me to cut back on some aspects that were not good for me at the time.

It was hard to stop doing these things; after all, I've been doing them my entire life.

But these habits were the ones stopping me from achieving my goals. And by cutting down on them, I had the opportunity to replace them with new habits and friends that helped me achieve my goals. And in the end, it felt freeing, like removing ankle weights to sprint faster than before.

So instead of continuing my past, I tried to actively influence my future.

---

It was not easy to make these decisions.

But here's the thing:

Being forced to make these choices ultimately got me to where I am today, which is focusing on my goals and my path there. It helped me create an environment that allows me to grow further and move closer to my goal daily.
📢 DOMAINE.NC mobile v1.0.7 sur le PlayStore 🛍️
Tags: flutter, mobile, showdev, opensource
Published: 2023-01-30 21:47:29

## ❔ About

After having published our public API, we wanted to build a community driven & open sourced mobile app on top of it.

See [dedicated series](https://dev.to/adriens/series/18166) for more.

{% embed https://dev.to/optnc/showcase-your-digital-services-on-killercoda-e6g %}


## 🍿 Demo

{% youtube lvai3AcOu5M %}

## 🔖 Resources

{% github lschaeffer313/domaine-nc-mobile %}

## 🛍️ Play Store

[![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h5x6q6obxctteuo3naya.png)](https://play.google.com/store/apps/details?id=nc.laurent.domaine_nc_mobile)
Migrating from Chakra UI to Tailwind CSS - My experience
Tags: tailwindcss, chakraui, performance, javascript
Published: 2023-01-30 21:45:34

> My personal experience while migrating a Next.js app from Chakra UI and Framer Motion to Tailwind CSS and Headless UI.

## Intro

I was very pleased by Chakra UI developer experience, feels like it combines the best of 2 worlds:

- It has the benefits of a component library,
- And a styling interface similar to Tailwind CSS.

But some time ago I stumbled with [this issue](https://github.com/chakra-ui/chakra-ui/discussions/5277) that raised some concerns on Chakra UI bundle size. My first reaction was that it wasn’t really an issue, since I was coming from Material UI which felt a lot heavier. But then I started auditing my app with Lighthouse and noticed that my performace score could be improved, so then I decided to give Tailwind CSS a go with the idea of the benefits of a reduced JS bundle size.

## Migration process

- Branched of from `master` and completely removed Chakra UI alongside it’s peer dependencies (Emotion and Framer Motion)
- Installed Tailwind CSS setup alongside Headless UI (mostly for it’s Transition component).
- Refactored every page and component to delete any trace of Chakra UI and replaced everything with native HTML component and added all the required Tailwind UI `className`  to maintain the same look and feel of the site.

The whole process took me a few weeks on my spare time, wasn’t particulary difficult (except for some of the animations, kudos to Framer Motion) but it was a bit tedious.

## Benchmarks

For performance benchmarking I only used Lighthouse. Tested with different specs (on both Windows and Mac OS).

I was expecting to have reduced the JS bundle size and thus improving the overall performance score, but to my surprise it didn’t turn out like that. The bundle size was indeed improved remarkably (almost by 50%) and some of the metrics improved but one in particular got much worst: **Largest Contentful Paint**. On avarage, the metric was crippled by a whooping 80%.

On both versions (Chakra UI and Tailwind CSS) the largest contentful element is the same, the first image on the DOM.

## Conclussion and questions

Well, overall it feels a bit frustrating that after all the exciment and the work it took to migrate from Chakra UI to Tailwind CSS the results are not very convincing.

Althought I’m very curious about why is the Largest Contentful Paint metric being affected so badly? What could be causing such a negative impact? I can’t find any reasonable cause.

## Update 2023

The negative impact on the LCP was mostly due to difference in CSS transitions duration. I used the default durations from Tailwind CSS which were a little longer than the ones I used with Chakra UI and this caused a delay on the largest contentful paint.

## Source code

You can fin the source code on this repository:

- https://github.com/oncet/gurim-next

The `master` branch uses Chakra UI and the `feature/headlessui` branch uses Tailwind CSS.

If you want to run the project locally you need to setup a single environmental variable, just ping me.
GraphQl with RTK Query
Tags: graphql, rtk, redux, reactnative
Published: 2023-01-30 21:42:00

I am a huge fan of the RTKQuery and how it works with the fetchBaseQuery for calling REST APIs but the beauty of it is that it can work quite the same way for GraphQl endpoints as well. But sadly the documentation on the Redux Toolkit documentation is not broad enough, at least in the aspect of mutations.

So i think i can help with that - both queries and mutations.

Now, right into it, let's say we have our project setup and we have the services for a blog post set up to getBlogPosts from a graphql endpoint.

```
import {  createApi } from '@reduxjs/toolkit/query/react'
import { gql } from 'graphql-request'
import {graphqlRequestBaseQuery} from '@rtk-query/graphql-request-base-query'

export const postStatuses = ['draft', 'published', 'pending_review'] as const

export interface Post {
  id: string
  title: string
  author: string
  content: string
  status: typeof postStatuses[number]
  created_at: string
  updated_at: string
}

export interface Pagination {
  page: number
  per_page: number
  total: number
  total_pages: number
}

export interface GetPostsResponse extends Pagination {
  data: {
    posts: Post[]
  }
}

export const api = createApi({
  baseQuery: graphqlRequestBaseQuery({
    url: '/graphql',
  }),
  endpoints: (builder) => ({
    getPosts: builder.query<
      GetPostsResponse,
      { page?: number; per_page?: number }
    >({
      query: ({ page, per_page }) => ({
        document: gql`
          query GetPosts($page: Int = 1, $per_page: Int = 10){
            posts(page: $page, per_page: $per_page) {
              id
              title
            }
          }
        `,
        variables: {
          page,
          per_page,
        },
      }),
    }),
  }),
})
export const { useGetPostsQuery } = api
```

Now to post a blog, i.e. make a mutation we will need to further add another block of code.

```
   addPost: builder.mutation<any, any>({
      query: ({id, title, content}) => ({
        document: gql`
          mutation addPost($id: Int!, $title: String!, content: String!) {
            addPost(id: $id, title: $title, content: $content)
          }
        `,
        variables: {
          id,
          title,
          content,
        },
      }),
    }),

...
...
export const { useGetPostsQuery, useAddPostMutation } = api
```
and the same can work for deleting posts and whatever mutations we need to make.

I hope this helps someone that needs it, I would also like to know what alternatives you use in calling your graphql APIs.
Building software for cattle farmers. Part 1. Android release
Tags: android, mobile, kotlin, tristan
Published: 2023-01-30 20:43:40

### What I have built 
- [GitHub code](https://github.com/thePlebDev/CalfTracker)
- [Google play store release](https://play.google.com/store/apps/details?id=com.elliottsoftware.calftracker)

- The application is pretty simple, I have create a CRUD application that allows cattle farmers to track calves(baby cows) during calving season. I have also recently added a feature that gives access the the current days weather information based on the users geolocation.

### Main features
- creating, reading, updating and deleting calves
- local and online database storage for individual users
- 24hr weather updates

### Upcoming features
- support for multiple screen sizes
- better swipe to delete functionality
- undo functionality when something is deleted by mistake
- sorting functionality
- release the app in more countries

### Feature request
- If you have any ideas about how to make the app better, please make a feature request on the projects GitHub issues page found [HERE](https://github.com/thePlebDev/CalfTracker/issues).

### Conclusion
- I will be posting weekly updates every Monday, so make sure to follow to stay updated on the project. If you want to hear more from me or have any further questions, Make sure to give me a follow on [Twitter](https://twitter.com/AndroidTristan) or comment down below. Thank you.
Vue Form Validation using Yup
Tags: vue, webdev, javascript, yup
Published: 2023-01-30 20:34:38

This blog post will show you how to validate forms in Vue 3 using Yup.

## Setup

In this blog post, I will use the following setup:

- Vue 3 with TypeScript, Prettier, and ESLint.
- Yup, for form validation.

If you don't use TypeScript, you can skip the parts specific to TypeScript.

Before we can start, we will have to add Yup as a dependency in our project.

```shell
npm install yup
```

## Simple Form Validation

### Creating a form

First, we will create a simple form with a single input field.

```vue
<template>
  <form @submit.prevent="validateForm">
    <label for="name">Name</label>
    <input type="text" id="name" v-model="formInput.name" />
    <button type="submit">Submit</button>
  </form>
</template>

<script setup lang="ts">
import { reactive } from "vue";

const formInput = reactive({
  name: "",
});
</script>
```

### Adding a validation schema

Now that we have a form, we can add a validation schema. To do this, we will use Yup.

Yup allows us to create a schema containing each field's rules. In our case, we only have one field, `name`.

```typescript
import { object, string } from 'yup';

const schema = object({
  name: string().required('Name is required'),
});
```

The field `name` should be a string and is required.
Please note that when using Yup, if a string is required, then an empty string is not allowed.

### Validating the form input

We can validate the form input now that we have our form and schema.

```typescript
const validateForm = () => {
  try {
    schema.validateSync(formInput);
  } catch (error) {
    console.log(error);
  }
};
```

We'll show an error message in the console if the validation fails.

Our complete component looks like this:

```vue
<template>
  <form @submit.prevent="validateForm">
    <label for="name">Name</label>
    <input type="text" id="name" v-model="formInput.name" />
    <button type="submit">Submit</button>
  </form>
</template>

<script setup lang="ts">
import { object, string } from "yup";
import { reactive } from "vue";

const formInput = reactive({
  name: "",
});

const schema = object({
  name: string().required(),
});

const validateForm = () => {
  try {
    schema.validateSync(formInput);
  } catch (error) {
    console.log(error);
  }
};
</script>
```

Now that we have a simple form validation, we can address some missing features.

- Our form only has one field
- We don't show any error messages to the user; without this the user will not know what went wrong.
- We only validate the form when the user submits the form,
  the user experience would be improved if we validated the form as the user types.

I'll address these issues in another blog post if there is enough interest.
Weekly Challenge 202
Tags: perl
Published: 2023-01-30 20:03:40

[Challenge 202](https://theweeklychallenge.org/blog/perl-weekly-challenge-202/)

My answers will also be on [github](https://github.com/manwar/perlweeklychallenge-club/tree/master/challenge-202/zapwai).
## Task One
Given a list of integers, write a script to print 1 if there are THREE consecutive odds in the given array, otherwise print 0.

## Task Two
In a list of altitudes, return the first widest valley.

## Solution to Task One
On this I return 0 if there aren't three neighboring odds, otherwise pass through to check that they are consecutive. 

```
use v5.30.0;
my @array1 = (1,5,3,6);
my @array2 = (2,6,3,5);
my @array3 = (1,2,3,4);
my @array4 = (2,3,5,7);
my @test = (\@array1, \@array2,\@array3,\@array4);    
sub are_three_odds {
    my @list = @_;
    my @ind;
    for (0 .. $#list - 2) {
	push @ind, $_ if ( ($list[$_] % 2 == 1) && ($list[$_ + 1] % 2 == 1) && ($list[$_ + 2] % 2 == 1) );
    }
    return 0 unless (@ind);
    foreach (@ind) {
	my @set = ($list[$_],$list[$_+1],$list[$_+2]);
	@set = sort {$a <=> $b} @set;
	if ( ($set[2] - $set[1]) == ($set[1] - $set[0])) {
	    return 1;
	}
    }
    return 0;
}

for (0 .. $#test) {
    my @array = @{$test[$_]};
    say "Input: (".join(",",@array).")";
    say "Output: " . are_three_odds(@array);
}

```

## Solution to Task Two
This I was able to manage with a few flags and one pass of the array. Once we stop increasing, the valley is over. Push all valleys to a collection then return the longest.

```
use v5.30.0;
my @array1 = (1, 5, 5, 2, 8);
my @array2 = (2,6,8,5);
my @array3 = (9,8,13,13,2,2,15,17);
my @array4 = (2,1,2,1,3);
my @array5 = (1,3,3,2,1,2,3,3,2);
my @test = (\@array1,\@array2,\@array3,\@array4,\@array5);
for my $ref (@test) {
    my @array = @$ref;
    my @valley;		      # push an array ref to each valley here.
    my $begin_index = 0;
    my $incr_flag = 0;		# flag after descent is complete.
    for (0 .. $#array - 1) {
	if ($incr_flag) {
	    if ( $array[$_ + 1] < $array[$_] ) {
		push @valley, [ @array[$begin_index .. $_] ];
		$begin_index = $_;
		for my $i (1 .. $_) { # check if it was level
		    if ( $array[$_] == $array[$_ - $i] ) {
			$begin_index--;
		    } else {
			last;
		    }
		}
		$incr_flag = 0;
	    }
	} else {
	    if ( $array[$_ + 1] > $array[$_] ) {
		$incr_flag = 1;
	    }
	}
    }
    push @valley, [ @array[$begin_index .. $#array] ];
    my $max = 0;
    my $ind;
    for (0 .. $#valley) {
	if (scalar @{$valley[$_]} > $max) {
	    $max = scalar @{$valley[$_]};
	    $ind = $_;
	}
    }
    say "Input: @array";
    say "Output: @{$valley[$ind]}";
    say "-" x 10;
}

```