<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>C# on Christian Martínez De La Rosa</title><link>https://christt105.github.io/es/tags/c%23/</link><description>Recent content in C# on Christian Martínez De La Rosa</description><generator>Hugo -- gohugo.io</generator><language>es</language><lastBuildDate>Fri, 27 Mar 2026 00:00:00 +0100</lastBuildDate><atom:link href="https://christt105.github.io/es/tags/c%23/index.xml" rel="self" type="application/rss+xml"/><item><title>Pokétch</title><link>https://christt105.github.io/es/projects/poketch/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://christt105.github.io/es/projects/poketch/</guid><enclosure url="https://christt105.github.io/projects/poketch/Poketch.webp" length="2768" type="image/webp"/><description>&lt;p&gt;Pokétch Unity es una recreación del dispositivo Pokereloj de Pokémon Platinum, desarrollado en Unity con todas las funcionalidades originales más nuevas.&lt;/p&gt;</description></item><item><title>mnamer Telegram Bot</title><link>https://christt105.github.io/es/projects/mnamer-telegram-bot/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://christt105.github.io/es/projects/mnamer-telegram-bot/</guid><enclosure url="https://christt105.github.io/projects/mnamer-telegram-bot/cover.png" length="45421" type="image/png"/><description>&lt;p&gt;&lt;code&gt;mnamer-telegram&lt;/code&gt; es un bot de Telegram para self-hosting que automatiza el renombrado y el movimiento de contenido descargado a la biblioteca de Jellyfin usando &lt;code&gt;mnamer&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Características principales:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Detecta archivos nuevos con un watcher y calcula nombres propuestos con &lt;code&gt;mnamer&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Envía el resultado por Telegram con sugerencias de renombre y enlaces a TMDB / TheTVDB.&lt;/li&gt;
&lt;li&gt;Acepta o corrige la propuesta mediante respuestas/ID y mueve el archivo sólo tras confirmación.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;La idea principal es transformar un flujo manual de línea de comandos en uno fluido y accesible desde móvil.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Ejemplo" class="gallery-image" data-flex-basis="160px" data-flex-grow="66" height="833" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://christt105.github.io/projects/mnamer-telegram-bot/example.png" width="556"&gt;&lt;/p&gt;</description></item><item><title>Automatizando mi biblioteca de Jellyfin con mnamer y un bot de Telegram</title><link>https://christt105.github.io/es/blog/mnamer-telegram-bot/</link><pubDate>Fri, 27 Mar 2026 00:00:00 +0100</pubDate><guid>https://christt105.github.io/es/blog/mnamer-telegram-bot/</guid><enclosure url="https://christt105.github.io/blog/mnamer-telegram-bot/cover.png" length="45421" type="image/png"/><description>&lt;p&gt;¡Hola de nuevo!&lt;/p&gt;
&lt;p&gt;Esta vez os traigo un proyecto que llevaba meses parado. Estoy intentando completar mi lista de proyectos pausados para darme un poco de paz. Seguimos con el tema del self-hosting, esta vez con un bot de Telegram.&lt;/p&gt;
&lt;h2 id="problema"&gt;Problema
&lt;/h2&gt;&lt;p&gt;La idea vino cuando empecé a usar en el mini PC el descargador P2P vulgarmente llamado &amp;ldquo;la mula&amp;rdquo;. Cuando una descarga acababa no tenía forma de saberlo, y tenía que ir manualmente, crear la carpeta con el nombre correcto en mi biblioteca de Jellyfin y pegar el archivo ahí cambiándole el nombre. Como principiante en esto de automatizar cosas, era algo que no me podía permitir.&lt;/p&gt;
&lt;h2 id="preludio"&gt;Preludio
&lt;/h2&gt;&lt;p&gt;Al poco tiempo probé &lt;a class="link" href="https://www.tinymediamanager.org/" target="_blank" rel="noopener"
 &gt;tinyMediaManager&lt;/a&gt; en Docker, pero era prácticamente inusable desde el teléfono móvil, que es mi dispositivo habitual para manejar eso.&lt;/p&gt;
&lt;p&gt;Poco después busqué otras opciones y encontré &lt;a class="link" href="https://github.com/jkwill87/mnamer" target="_blank" rel="noopener"
 &gt;mnamer&lt;/a&gt;, un programa por consola que renombra películas y series. Era exactamente lo que buscaba. Usa &lt;a class="link" href="https://www.themoviedb.org/" target="_blank" rel="noopener"
 &gt;TMDB&lt;/a&gt; para las películas y &lt;a class="link" href="https://thetvdb.com/" target="_blank" rel="noopener"
 &gt;TheTVDB&lt;/a&gt; para las series (que lo prefiero porque tiene mejores reglas para algunos animes). Con unos comandos puedes hacer que lea todos los archivos de vídeo de una carpeta y los renombre y coloque en las carpetas pertinentes de tu biblioteca.&lt;/p&gt;
&lt;p&gt;Estuve usando mnamer un tiempo; cuando algo acababa de descargar, abría la consola de comandos por SSH y ejecutaba un alias que me creé.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Ruta al docker-compose de mnamer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;MNAMER_COMPOSE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/home/christian/Server/70-79_Media/74_gestion_media/mnamer/docker-compose.yml&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Ejecutar mnamer genérico&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;alias&lt;/span&gt; &lt;span class="nv"&gt;mnamer&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;docker compose -f &lt;/span&gt;&lt;span class="nv"&gt;$MNAMER_COMPOSE&lt;/span&gt;&lt;span class="s2"&gt; run --rm mnamer&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Ejecutar en modo prueba (no mueve nada, solo muestra)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;alias&lt;/span&gt; mnamer-test&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;docker compose -f &lt;/span&gt;&lt;span class="nv"&gt;$MNAMER_COMPOSE&lt;/span&gt;&lt;span class="s2"&gt; run --rm mnamer --test -r /data/Descargas&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Ejecutar en modo real (mueve de Descargas a destino)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;alias&lt;/span&gt; mnamer-run&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;docker compose -f $MNAMER_COMPOSE run --rm mnamer -r /data/Descargas&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;alias&lt;/span&gt; mnamer-tmdb&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;docker compose -f $MNAMER_COMPOSE run --rm mnamer -r /data/Descargas --id-tmdb&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;alias&lt;/span&gt; mnamer-tvdb&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;docker compose -f $MNAMER_COMPOSE run --rm mnamer -r /data/Descargas --id-tvdb&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Tenía mnamer en un contenedor Docker y creé algunos comandos para hacerlo funcionar sin tener que escribir gran cosa. Con &lt;code&gt;mnamer-test&lt;/code&gt; podía comprobar que todo se iba a renombrar correctamente. Si algo no lo pillaba bien, ejecutaba &lt;code&gt;mnamer-tmdb&lt;/code&gt; o &lt;code&gt;mnamer-tvdb&lt;/code&gt; y le pasaba el ID que buscaba en el navegador. Si todo estaba bien, simplemente ejecutaba &lt;code&gt;mnamer-run --batch&lt;/code&gt; para que lo hiciera todo del tirón. Como podéis comprobar, seguía siendo bastante manual; había mucho margen de mejora.&lt;/p&gt;
&lt;p&gt;Unos meses antes estuve trasteando con los bots de Telegram. Intenté crear uno con Python, pero me acabé agobiando y pasé a C# usando &lt;a class="link" href="https://github.com/wiz0u/WTelegramBot" target="_blank" rel="noopener"
 &gt;WTelegramBot&lt;/a&gt;, una API exquisita para crear bots con muchísimas funcionalidades y en un lenguaje con el que me sentía más a gusto. Ese bot está en pausa, otro proyecto más en la lista interminable.&lt;/p&gt;
&lt;h2 id="la-travesía-del-bot"&gt;La travesía del bot
&lt;/h2&gt;&lt;p&gt;Con las ideas claras, a finales del año pasado estuve trabajando unos días en el bot. La idea principal era que cada vez que hubiera un archivo en una carpeta, el bot enviara un mensaje con la propuesta de mnamer y un link a TMDB o TheTVDB para poder comprobar que era correcto. Una vez hecha la comprobación, pulsar un botón y que se enviara a la biblioteca.&lt;/p&gt;
&lt;p&gt;Hice algo muy básico para comprobar si había archivos y enviar un mensaje con la propuesta de mnamer y un botón para aceptar. Si mnamer estaba equivocado, debía ir manualmente al disco duro, cambiarle el nombre y volver a probar, cosa que no solía pasar, pero era realmente molesto.&lt;/p&gt;
&lt;p&gt;Estuve unos meses así hasta que en febrero decidí continuar. Añadí el File Watcher y que pudieras contestar con un ID para rectificar. También intenté arreglar el tema de los permisos de los archivos y ahora el contenedor se ejecuta con el usuario 1000:1000 por defecto; aunque a mí me funciona, creo que no está del todo bien implementado.&lt;/p&gt;
&lt;p&gt;Lo volví a dejar porque me iba bastante bien, hasta hace pocos días que me puse a arreglar un par de cosas y a crear toda la documentación para que otra gente lo pudiera probar. Configuré que GitHub Actions generara una imagen Docker cada vez que creara una tag e hice el repositorio público.&lt;/p&gt;
&lt;p&gt;Y así está el estado actual. Imagino que iré mejorándolo poco a poco si la gente lo usa, como acaba de pasar hace nada, que un amigo me ha enviado una PR arreglando los IDs de los usuarios; es la parte más reconfortante de la programación. Creo que es algo complejo de configurar, pero hasta que más gente no lo intente no sé cómo hacerlo mejor.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Ejemplo del bot renombrando" class="gallery-image" data-flex-basis="160px" data-flex-grow="66" height="833" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://christt105.github.io/blog/mnamer-telegram-bot/example.png" width="556"&gt;&lt;/p&gt;
&lt;p&gt;Si te interesa el código fuente del proyecto o las instrucciones para instalarlo, lo puedes encontrar en mi cuenta de GitHub:&lt;/p&gt;
&lt;a class="github-repo-card" href="https://github.com/christt105/mnamer-telegram" target="_blank" rel="noopener"&gt;
 &lt;img src="https://avatars.githubusercontent.com/u/36189169?v=4" alt="christt105 avatar" class="repo-avatar"&gt;
 &lt;h3&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-brand-github" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"&gt;
 &lt;path stroke="none" d="M0 0h24v24H0z" fill="none"/&gt;
 &lt;path d="M9 19c-4.3 1.4 -4.3 -2.5 -6 -3m12 5v-3.5c0 -1 .1 -1.4 -.5 -2c2.8 -.3 5.5 -1.4 5.5 -6a4.6 4.6 0 0 0 -1.3 -3.2a4.2 4.2 0 0 0 -.1 -3.2s-1.1 -.3 -3.5 1.3a12.3 12.3 0 0 0 -6.2 0c-2.4 -1.6 -3.5 -1.3 -3.5 -1.3a4.2 4.2 0 0 0 -.1 3.2a4.6 4.6 0 0 0 -1.3 3.2c0 4.6 2.7 5.7 5.5 6c-.6 .6 -.6 1.2 -.5 2v3.5" /&gt;
&lt;/svg&gt;


 christt105/mnamer-telegram&lt;/h3&gt;
 &lt;p&gt;Telegram bot that automates media library organization using mnamer with interactive approval workflows.&lt;/p&gt;
 &lt;div class="repo-stats"&gt;
 &lt;span&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="currentColor" class="icon icon-tabler icons-tabler-filled icon-tabler-star"&gt;&lt;path stroke="none" d="M0 0h24v24H0z" fill="none"/&gt;&lt;path d="M8.243 7.34l-6.38 .925l-.113 .023a1 1 0 0 0 -.44 1.684l4.622 4.499l-1.09 6.355l-.013 .11a1 1 0 0 0 1.464 .944l5.706 -3l5.693 3l.1 .046a1 1 0 0 0 1.352 -1.1l-1.091 -6.355l4.624 -4.5l.078 -.085a1 1 0 0 0 -.633 -1.62l-6.38 -.926l-2.852 -5.78a1 1 0 0 0 -1.794 0l-2.853 5.78z" /&gt;&lt;/svg&gt; 2&lt;/span&gt;
 &lt;span&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-git-fork"&gt;&lt;path stroke="none" d="M0 0h24v24H0z" fill="none"/&gt;&lt;path d="M10 18a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" /&gt;&lt;path d="M5 6a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" /&gt;&lt;path d="M15 6a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" /&gt;&lt;path d="M7 8v2a2 2 0 0 0 2 2h6a2 2 0 0 0 2 -2v-2" /&gt;&lt;path d="M12 12l0 4" /&gt;&lt;/svg&gt; 1&lt;/span&gt;
 &lt;span&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-calendar-event"&gt;&lt;path stroke="none" d="M0 0h24v24H0z" fill="none"/&gt;&lt;path d="M4 7a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2l0 -12" /&gt;&lt;path d="M16 3l0 4" /&gt;&lt;path d="M8 3l0 4" /&gt;&lt;path d="M4 11l16 0" /&gt;&lt;path d="M8 15h2v2h-2l0 -2" /&gt;&lt;/svg&gt; 2026-03-28&lt;/span&gt;
 &lt;/div&gt;
 &lt;/a&gt;
&lt;h2 id="conclusión"&gt;Conclusión
&lt;/h2&gt;&lt;p&gt;Es la primera vez que hago un programa con C# directamente; mi experiencia con C# suele ser casi siempre dentro del entorno de Unity. Sé que hay muchas cosas mal y mejorables, pero estoy disfrutando aprendiendo nuevas formas de programar.&lt;/p&gt;
&lt;p&gt;Otro proyecto bastante reducido que puedo tachar de mi lista de pendientes y pasar a otra cosa. Si tienes un setup parecido y quieres probar el bot, te animo a que lo hagas y dejes una estrella en &lt;a class="link" href="https://github.com/christt105/mnamer-telegram" target="_blank" rel="noopener"
 &gt;el repositorio&lt;/a&gt;. He publicado mi ejemplo de como lo tengo yo montado aquí: &lt;a class="link" href="https://github.com/christt105/mnamer-telegram/discussions/2" target="_blank" rel="noopener"
 &gt;https://github.com/christt105/mnamer-telegram/discussions/2&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;¡Nos vemos en el siguiente post!&lt;/p&gt;</description></item><item><title>Boxing AR</title><link>https://christt105.github.io/es/projects/boxingar/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://christt105.github.io/es/projects/boxingar/</guid><enclosure url="https://christt105.github.io/projects/boxingar/roboboxing.webp" length="14842" type="image/webp"/><description>&lt;p&gt;¡Controla un robot boxeador y alcanza la gloria del RoboBoxing!&lt;/p&gt;</description></item><item><title>Empty Universe</title><link>https://christt105.github.io/es/projects/emptyuniverse/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://christt105.github.io/es/projects/emptyuniverse/</guid><enclosure url="https://christt105.github.io/projects/emptyuniverse/emptyuniverse.webp" length="42266" type="image/webp"/><description>&lt;p&gt;Empty Universe es una aventura exhaustiva donde tendrás que defender la nave de los enemigos. Tendrás tres tipos de astronautas bajo tu control. Cada astronauta tiene su propio trabajo para cubrir todas las necesidades de la nave.&lt;/p&gt;
&lt;p&gt;Sobrevive cinco días y noches para ganar. No dejes que los enemigos maten a tus astronautas y gestiona bien tus recursos.&lt;/p&gt;</description></item><item><title>Fishing Trash</title><link>https://christt105.github.io/es/projects/fishingtrash/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://christt105.github.io/es/projects/fishingtrash/</guid><enclosure url="https://christt105.github.io/projects/fishingtrash/fishing-trash.webp" length="28690" type="image/webp"/><description>&lt;p&gt;Un GameJam con &amp;lsquo;mar&amp;rsquo; y &amp;lsquo;basura&amp;rsquo; como tema.&lt;/p&gt;</description></item></channel></rss>