GitHub
Tests: 12 • Commercial: 2 • Pet projects: 4 • Legacy: 4
Total: 22

.NET Framework

Test
2021

Project Request

ASP.NET MVC • C# • SQL Server
Idea of the project: if someone wants to order a project development, here you can send an application.
Test
2020

ProjectC

ASP.NET MVC • C# • JSON • jQuery
JSON data processing.
Test
2020

Vehicle Maintenance

ASP.NET MVC • VB.NET • JSON
Idea of the project: if someone wants to order a project development, here you can send an application.
Test
2019

Movie Navigator

ASP.NET MVC • VB.NET
Request information about movie from IMDB.
Test
2018

Customers Exchange

ASP.NET MVC • C# • SQL Server
Automated teller machine emulation.
Test
2016

ATM

ASP.NET MVC • C#
Automated teller machine emulation.

.NET Core

Pet project
2022

Mail Daemon

.NET 8 • Console • JSON
Utility to send mails with customizable settings.

Custom

Code
2024

Buns of code

.NET Framework • C# • JavaScript
Code snippets from my projects, ready to use; tiny tests; code examples.

PHP

Test
2024

Mediabox

PHP 8 • Laravel 11 • Vue.js • Composer • SQLite
Test project for media files management.
Test
2020

Loan Castle

PHP • MariaDB
Jums jāizstrādā kāda lielāk projekta prototips. Izstrādājot prototipu, paturiet prātā, ka projektam attīstoties, šo prototipu varētu vajadzēt pilnveidot.
Test
2020

Content Management

PHP • MySQL • AJAX
Создать простой сайт, где будет страница с формой для авторизации и страница для авторизованного пользователя.
Test
2019

Laravel

PHP • Laravel • Vue.js • Composer • SQLite
Izveidot aplikāciju, kura ik pēc noteikta intervāla (60 sekundes) veic ierakstu datubāzē izmantojot Laravel freimworka iebūvēto funkcionalitāti.
Test
2019

Phone Check

PHP • JavaScript • JSON • Docker
Implement application to detect country by phone number.

Frontend

Test
2021

Forex Wall

npm • React
For this exercise, what we need is a simple live wall for tracking currencies.

Business projects

Commercial
2008

Certification Center

.NET Framework 4.8 • ASP.NET Web Forms • C# • LINQ • SQL Server • ADO.NET • Dapper • JavaScript • jQuery • Git
Transport registration and certification services in Latvia, Customer Relationship Management.
Commercial
2000

Amerikas Auto

.NET Framework 4.8 • ASP.NET Web Forms • C# • LINQ • SQL Server • ADO.NET • Entity Framework • JavaScript • jQuery • Git
Car service and spare parts for all USA and European car models, Customer Relationship Management.

Pet projects

Pet project
2023

Geolocation Assistant

.NET 8 • ASP.NET Core • C# • Web API • JSON • Git
Website for determining geolocation by IP or geotagged photo.
Pet project
2008

Web Dynamics

.NET Framework 4.8 • ASP.NET Web Forms • C# • LINQ • Web API • JSON • SQL Server • Dapper • JavaScript • jQuery • SVG • Git
Software development blog. Articles, books, videos, content management.
Pet project
2000

Blackball

.NET Framework 4.8 • ASP.NET Web Forms • C# • LINQ • Web API • JSON • XML • SQL Server • Dapper • JavaScript • jQuery • SVG • Git
My entertainment portal created from scratch.

Good old times

Legacy
2000

DOS Clock

Turbo Pascal • Assembler
Digital clock.
Legacy
2000

BrainOut

Turbo Pascal • Assembler
Tank battle game.
Legacy
1999

Airport Administrator

Turbo Pascal
Курсовая работа в институте.
Legacy
1998

Atomizer

Turbo Pascal • Assembler
Atomizer, aka «Studio2D». Graphic raster editor. AGI is my own «Atomizer Generated Image» file format.

Mail Daemon

2022-2024 Pet project

Utility to send mails with customizable settings.

.NET 8 Console JSON
Information
Source code
Root / MailDaemon.ConsoleApp / Program.cs
using Microsoft.Extensions.Configuration; using System; using System.IO; using System.Net.Mail; using System.Text; using System.Threading; using MailDaemon.Core; namespace MailDaemon.ConsoleApp { internal class Program {         private static string PreviewsDirPath { get; set; }         private static string ReportsDirPath { get; set; } private static void Main(string[] args) {             var configuration = new ConfigurationBuilder()                 .SetBasePath(Directory.GetCurrentDirectory())                 .AddJsonFile("appSettings.json", optional: true, reloadOnChange: true)                 .AddEnvironmentVariables().Build();                          var displayHelp = false;             var mailDaemonService = new MailDaemonService();             var mailAgent = new MailAgent(); if (args.Length > 0)             {                 try { var argIndex = 0; foreach (var arg in args) { switch (arg.ToLower()) { case "-v": mailDaemonService.JustValidate = true; break; case "-d": mailDaemonService.SendDemo = true; break; case "-gp": mailDaemonService.GeneratePreview = true; break; case "-p": mailDaemonService.MailProfileFilename = Path.Combine(Environment.CurrentDirectory, "MailProfiles", args[argIndex + 1]); break; case "-h": displayHelp = true; break; } argIndex++; } }                 catch (Exception ex)                 {                     DisplayErrorMessage(ex.Message);                     return;                 }             } if (!string.IsNullOrEmpty(mailDaemonService.MailProfileFilename) && !File.Exists(mailDaemonService.MailProfileFilename)) { DisplayErrorMessage($"Mail profile \"{mailDaemonService.MailProfileFilename}\" not exists."); return; } // TBD: Think about whether someone needs this information //Console.WriteLine("=== Mail Daemon 0.8 ==="); //Console.WriteLine("Author:\t\tSergey Drozdov"); //Console.WriteLine("Email:\t\tsergey.drozdov.0305@gmail.com"); //Console.WriteLine("Website:\thttps://sd.blackball.lv/sergey-drozdov"); //Console.Write(Environment.NewLine);             if (displayHelp)             {                 Console.WriteLine("Description:");                 Console.WriteLine("-v\t\tValidation mode to verify mail profile integrity. With this argument mails not sending to recipients.");                 Console.WriteLine("-d\t\tSend demo mail only to sender. With this argument mails not sending to recipients.");                 Console.WriteLine("-gp\t\tCreate files on disk with generated mails for each recipient.");                 Console.WriteLine("-p\t\tName of the mail profile.");                 WaitForExit();                 return;             } // configure SMTP server info             mailAgent.SmtpHost = configuration["MailServer:SmtpHost"];             mailAgent.SmtpPort = Convert.ToInt32(configuration["MailServer:SmtpPort"]);             mailAgent.SmtpUsername = configuration["MailServer:SmtpUsername"];             mailAgent.SmtpPassword = configuration["MailServer:SmtpPassword"];             mailAgent.SmtpEnableSSL = Convert.ToBoolean(configuration["MailServer:SmtpEnableSSL"]); if (mailDaemonService.JustValidate)             {                 Console.ForegroundColor = ConsoleColor.Yellow;                 Console.WriteLine("--- Validation mode: do not send any mail. Just validate mail profile and recipients.");                 Console.WriteLine("");                 Console.ResetColor();             }             if (string.IsNullOrEmpty(mailDaemonService.MailProfileFilename))              mailDaemonService.MailProfileFilename = Path.Combine(Environment.CurrentDirectory, "MailProfiles", configuration["App:MailProfile"]);             Console.ForegroundColor = ConsoleColor.Yellow;             Console.WriteLine($"--- Mail profile: \"{Path.GetFileName(mailDaemonService.MailProfileFilename)}\"");             Console.ResetColor(); try { mailDaemonService.ReadMailProfile(); } catch (Exception ex) { mailDaemonService.AddError(ex.Message); } mailDaemonService.ValidateMailProfile(); ReportsDirPath = Path.Combine(Environment.CurrentDirectory, "reports"); if (!Directory.Exists(ReportsDirPath)) Directory.CreateDirectory(ReportsDirPath); if (mailDaemonService.GeneratePreview) { try { PreviewsDirPath = Path.Combine(Environment.CurrentDirectory, "previews", Path.GetFileName(mailDaemonService.MailProfileFilename)); if (!Directory.Exists(PreviewsDirPath)) Directory.CreateDirectory(PreviewsDirPath); else { foreach (var filePath in Directory.EnumerateFiles(PreviewsDirPath)) { File.Delete(filePath); } } } catch (Exception ex) { DisplayErrorMessage(ex.Message); WaitForExit(); return; } } mailDaemonService.Operator.Address = configuration["Operator:address"]; mailDaemonService.Operator.Name = configuration["Operator:name"]; if (mailDaemonService.MailProfile.MailBodyTemplateFilePath.StartsWith(".\\"))                 mailDaemonService.MailProfile.MailBodyTemplateFilePath = Path.Combine(Environment.CurrentDirectory, mailDaemonService.MailProfile.MailBodyTemplateFilePath.Replace(".\\", ""));             mailDaemonService.MailProfile.MailBody = mailDaemonService.ReadMailBodyTemplate(mailDaemonService.MailProfile.MailBodyTemplateFilePath);             // show errors             if (mailDaemonService.Errors.Count > 0)             {                 SetErrorMessagesStyle();                 Console.WriteLine("");                 Console.WriteLine("Errors:");                 foreach (var message in mailDaemonService.Errors)                 {                     DisplayErrorMessage(message.Message);                 }             }             // show warnings             if (mailDaemonService.Warnings.Count > 0)             {                 SetWarningMessagesStyle();                 Console.WriteLine("");                 Console.WriteLine("Warnings:");                 foreach (var message in mailDaemonService.Warnings)                 {                     DisplayWarningMessage(message);                 }             }             // if mail profile contains errors - stop execution             if (mailDaemonService.Errors.Count > 0)             {                 WaitForExit();                 return;             }             // if mail profile contains warnings - ask user to continue or not             if (mailDaemonService.Warnings.Count > 0)             {                 Console.WriteLine("");                 Console.Write("Continue? [Y/N]");                 var confirmed = false;                 string key;                 while (!confirmed)                 {                     key = Console.ReadLine().ToLower();                     if (key == "y")                     {                         confirmed = true;                     }                     if (key == "n")                     { WaitForExit();                         return;                     }                 }             }                         var counter = 0;             var recipientsReport = new StringBuilder();             foreach (var recipient in mailDaemonService.MailProfile.Recipients)             {                 var recipientReportInfo = new StringBuilder();                 try          { // TBD: add support for HTML and plain text files                     if (string.IsNullOrEmpty(recipient.MailBodyTemplateFilePath)) recipient.MailBodyTemplateFilePath = mailDaemonService.MailProfile.MailBodyTemplateFilePath; mailDaemonService.MailProfile.MailBody = mailDaemonService.ReadMailBodyTemplate(recipient.MailBodyTemplateFilePath); var mailMessage = mailDaemonService.GenerateMailMessage(recipient);                     // display mail sending process counter++; if (recipient.Skip.GetValueOrDefault()) Console.ForegroundColor = ConsoleColor.DarkGray;                     else Console.ForegroundColor = ConsoleColor.White; Console.WriteLine($"({counter}) {recipient.Company?.ToUpper()} {recipient.Name}"); Console.WriteLine($"Mail: {recipient.Address}");                     Console.WriteLine($"Subject: {mailMessage.Subject}");                     Console.WriteLine($"Template: {(!string.IsNullOrEmpty(recipient.MailBodyTemplateFilePath) ? recipient.MailBodyTemplateFilePath : mailDaemonService.MailProfile.MailBodyTemplateFilePath)}"); if (recipient.Skip.GetValueOrDefault()) recipientReportInfo.AppendLine("<div style=\"color: #999\">"); recipientReportInfo.AppendLine($"({counter}) {recipient.Company?.ToUpper()} {recipient.Name} <a href=\"mailto:{recipient.Address}\">{recipient.Address}</a>");                     recipientReportInfo.AppendLine($"<div>Subject: {mailMessage.Subject}</div>");                     if (!string.IsNullOrEmpty(recipient.MailBodyTemplateFilePath) && recipient.MailBodyTemplateFilePath != mailDaemonService.MailProfile.MailBodyTemplateFilePath)                     recipientReportInfo.AppendLine($"<div>Template: {recipient.MailBodyTemplateFilePath}</div>"); // recipient related attachments use at first if (recipient.Attachments != null) { foreach (var attachment in recipient.Attachments) { if (File.Exists(attachment.Path)) { Console.WriteLine($"\tAttachment: \"{attachment.Path}\""); recipientReportInfo.AppendLine($"<div style=\"padding-left: 40px\">Attachment: \"{attachment.Path}\"</div>"); } else { DisplayWarningMessage($"\tAttachment: file \"{attachment.Path}\" not exists."); recipientReportInfo.AppendLine($"<div style=\"padding-left: 40px; color: #aa0000\">Attachment: file \"{attachment.Path}\" not exists.</div>"); } } } // attachments if (mailDaemonService.MailProfile.Attachments != null)                     {                         foreach (var attachment in mailDaemonService.MailProfile.Attachments)                         {                             if (File.Exists(attachment.Path))                             {                                 Console.WriteLine($"\tAttachment: \"{attachment.Path}\"");                                 recipientReportInfo.AppendLine($"<div style=\"padding-left: 40px\">Attachment: \"{attachment.Path}\"</div>");                             }                             else                             {                                 DisplayWarningMessage($"\tAttachment: file \"{attachment.Path}\" not exists.");                                 recipientReportInfo.AppendLine($"<div style=\"padding-left: 40px\">Attachment: file \"{attachment.Path}\" not exists.</div>");                             }                         }                     } if (recipient.Skip.GetValueOrDefault()) { recipientReportInfo.AppendLine("--- Skipped ---"); recipientReportInfo.AppendLine("</div>"); } if (mailDaemonService.SendDemo)                     {                         Console.ForegroundColor = ConsoleColor.Cyan;                         Console.WriteLine($"--- Send demo to sender address: {mailDaemonService.MailProfile.Sender.Address} ---");                         Console.ResetColor(); } if (mailDaemonService.GeneratePreview) { Console.ForegroundColor = ConsoleColor.Cyan; Console.WriteLine($"--- Create file \"{recipient.Address}.html\" with preview ---"); Console.ResetColor(); try { var fileNamePrefix = "";                             if (recipient.Skip.GetValueOrDefault()) fileNamePrefix = "(skipped)_"; var previewFilePath = Path.Combine(PreviewsDirPath, $"{fileNamePrefix}{recipient.Address}{Path.GetExtension(recipient.MailBodyTemplateFilePath)}"); File.WriteAllText(previewFilePath, mailMessage.Body); } catch (Exception ex) { DisplayErrorMessage(ex.Message); } } if (!mailDaemonService.JustValidate)                     { if (recipient.Skip.GetValueOrDefault()) { Console.ForegroundColor = ConsoleColor.Cyan; Console.WriteLine("--- Skipped ---"); Console.ResetColor(); Console.WriteLine(""); } else { var mailSendResult = mailAgent.Send(mailMessage);                          if (!mailSendResult.Success)                          {                              DisplayErrorMessage(mailSendResult.Message);                          }                          else                          {                              Console.ForegroundColor = ConsoleColor.Green;                              Console.WriteLine("--- Sent ---");                              Console.ResetColor();                              Console.WriteLine("");                          } }                     } else { if (recipient.Skip.GetValueOrDefault()) { Console.ForegroundColor = ConsoleColor.Cyan; Console.WriteLine("--- Skipped ---"); Console.ResetColor(); }                         Console.WriteLine(""); } }                 catch (Exception ex)                 {                     DisplayErrorMessage(ex.InnerException != null ? ex.InnerException.Message : ex.Message);                     Console.WriteLine("--- Error ---");                     Console.WriteLine("");                 }                 recipientReportInfo.AppendLine("<br/>");                 recipientsReport.AppendLine(recipientReportInfo.ToString());                 Thread.Sleep(mailDaemonService.SendSleep);             } var report = GenerateReport(mailDaemonService, recipientsReport); try { var reportFilePath = Path.Combine(ReportsDirPath, $"report_{Path.GetFileName(mailDaemonService.MailProfileFilename)}_{DateTime.Now:dd.MM.yyyy_HH-mm}.html"); File.WriteAllText(reportFilePath, report); } catch (Exception ex) {                 DisplayWarningMessage(ex.Message); Console.Write("Press any key to continue..."); Console.ReadKey(); } if (!mailDaemonService.JustValidate)             {                 // send status report to sender                 try                 {                     var mailMessage = new MailMessage();                     mailMessage.To.Add(mailDaemonService.GetMailAddress(mailDaemonService.Operator.Address, mailDaemonService.Operator.Name));                     mailMessage.From = mailDaemonService.GetMailAddress(mailDaemonService.MailProfile.Sender.Address, mailDaemonService.MailProfile.Sender.Name);                     mailMessage.ReplyToList.Add(mailMessage.From);                     mailMessage.Headers.Add("Reply-To", mailDaemonService.MailProfile.Sender.Address);                     mailMessage.Subject = "Mail Daemon: mails has been sent";                     mailMessage.SubjectEncoding = Encoding.UTF8;                     mailMessage.IsBodyHtml = true;                     mailMessage.BodyEncoding = Encoding.UTF8; mailMessage.Body = report;                     mailAgent.Send(mailMessage);                     Console.ForegroundColor = ConsoleColor.Yellow;                     Console.WriteLine("--- Mails has been sent ---");                     Console.ForegroundColor = ConsoleColor.White;                 }                 catch (Exception ex)                 {                     DisplayErrorMessage(ex.InnerException != null ? ex.InnerException.Message : ex.Message);                     Console.WriteLine("--- Error ---");                 }                 Thread.Sleep(5000);             }             else             {                 WaitForExit();             }             if (mailDaemonService.SendDemo) WaitForExit();         } private static string GenerateReport(MailDaemonService mailDaemonService, StringBuilder recipientsReport) { var report = new StringBuilder(); report.AppendLine("<!DOCTYPE html>"); report.AppendLine("<html>"); report.AppendLine("<head>"); report.AppendLine("<meta charset=\"utf-8\" />"); report.AppendLine("<title>Mail Daemon report</title>"); report.AppendLine("</head>"); report.AppendLine("<body>"); report.AppendLine($"<div>{mailDaemonService.MailProfile.Recipients.Count} mails has been sent.</div>"); report.AppendLine($"<div>Mail profile: \"{mailDaemonService.MailProfileFilename}\"</div>"); report.AppendLine($"<div>Mail template: \"{mailDaemonService.MailProfile.MailBodyTemplateFilePath}\"</div>"); report.AppendLine("<br/>"); report.AppendLine($"<div><strong>Recipients:</strong></div>"); report.AppendLine($"<div>{recipientsReport}</div>"); report.AppendLine("</body>"); report.AppendLine("</html>"); return report.ToString(); } private static void SetErrorMessagesStyle()         {             Console.ForegroundColor = ConsoleColor.Red;         }         private static void SetWarningMessagesStyle()         {             Console.ForegroundColor = ConsoleColor.Magenta;         }         private static void DisplayErrorMessage(string message)         {             Console.ForegroundColor = ConsoleColor.Red;             Console.WriteLine(message);             Console.ResetColor();         }         private static void DisplayWarningMessage(string message)         {             Console.ForegroundColor = ConsoleColor.Magenta;             Console.WriteLine(message);             Console.ResetColor();         }         private static void WaitForExit()         {             Console.ForegroundColor = ConsoleColor.White;             Console.WriteLine("");             Console.Write("Press any key to exit...");             Console.ReadKey();         }     } }