diff --git a/HwProj.AuthService/HwProj.AuthService.API/ApplicationProfile.cs b/HwProj.AuthService/HwProj.AuthService.API/ApplicationProfile.cs index fd607c4a2..455c5bec5 100644 --- a/HwProj.AuthService/HwProj.AuthService.API/ApplicationProfile.cs +++ b/HwProj.AuthService/HwProj.AuthService.API/ApplicationProfile.cs @@ -8,7 +8,7 @@ public class ApplicationProfile : Profile { public ApplicationProfile() { - CreateMap(); + CreateMap(); CreateMap(); CreateMap(); CreateMap(); diff --git a/HwProj.AuthService/HwProj.AuthService.API/Controllers/AccountController.cs b/HwProj.AuthService/HwProj.AuthService.API/Controllers/AccountController.cs index 76877deac..6cb09eb4b 100644 --- a/HwProj.AuthService/HwProj.AuthService.API/Controllers/AccountController.cs +++ b/HwProj.AuthService/HwProj.AuthService.API/Controllers/AccountController.cs @@ -90,7 +90,7 @@ public async Task EditExternal([FromBody] EditExternalViewModel m [HttpGet("findByEmail/{email}")] - [ProducesResponseType(typeof(User), (int)HttpStatusCode.OK)] + [ProducesResponseType(typeof(UserViewModel), (int)HttpStatusCode.OK)] public async Task FindByEmail(string email) { var user = await _userManager.FindByEmailAsync(email); @@ -99,9 +99,9 @@ public async Task FindByEmail(string email) [HttpPost("getRole")] [ProducesResponseType(typeof(string), (int)HttpStatusCode.OK)] - public async Task GetRolesAsync([FromBody] User user) + public async Task GetRolesAsync([FromBody] UserViewModel userViewModel) { - var roles = await _userManager.GetRolesAsync(user); + var roles = await _userManager.GetRolesAsync(userViewModel); return Ok(roles[0]); } diff --git a/HwProj.AuthService/HwProj.AuthService.API/Models/IdentityContext.cs b/HwProj.AuthService/HwProj.AuthService.API/Models/IdentityContext.cs index 6f35c9636..8c9b76ecc 100644 --- a/HwProj.AuthService/HwProj.AuthService.API/Models/IdentityContext.cs +++ b/HwProj.AuthService/HwProj.AuthService.API/Models/IdentityContext.cs @@ -4,7 +4,7 @@ namespace HwProj.AuthService.API.Models { - public sealed class IdentityContext : IdentityDbContext + public sealed class IdentityContext : IdentityDbContext { public IdentityContext(DbContextOptions options) : base(options) diff --git a/HwProj.AuthService/HwProj.AuthService.API/RoleInitializer.cs b/HwProj.AuthService/HwProj.AuthService.API/RoleInitializer.cs index f3bcd0143..353cfc3d8 100644 --- a/HwProj.AuthService/HwProj.AuthService.API/RoleInitializer.cs +++ b/HwProj.AuthService/HwProj.AuthService.API/RoleInitializer.cs @@ -9,7 +9,7 @@ namespace HwProj.AuthService.API { public class RoleInitializer { - public static async Task InitializeAsync(UserManager userManager, RoleManager roleManager, IEventBus eventBus) + public static async Task InitializeAsync(UserManager userManager, RoleManager roleManager, IEventBus eventBus) { if(await roleManager.FindByNameAsync(Roles.LecturerRole) == null) { @@ -26,7 +26,7 @@ public static async Task InitializeAsync(UserManager userManager, RoleMana if (await userManager.FindByEmailAsync(email) == null) { - var admin = new User { + var admin = new UserViewModel { Email = email, Name = "Admin", UserName = "Admin" diff --git a/HwProj.AuthService/HwProj.AuthService.API/Services/AccountService.cs b/HwProj.AuthService/HwProj.AuthService.API/Services/AccountService.cs index 6442de8e2..bc9db6142 100644 --- a/HwProj.AuthService/HwProj.AuthService.API/Services/AccountService.cs +++ b/HwProj.AuthService/HwProj.AuthService.API/Services/AccountService.cs @@ -17,13 +17,13 @@ namespace HwProj.AuthService.API.Services public class AccountService : IAccountService { private readonly IUserManager _userManager; - private readonly SignInManager _signInManager; + private readonly SignInManager _signInManager; private readonly IAuthTokenService _tokenService; private readonly IEventBus _eventBus; private readonly IMapper _mapper; public AccountService(IUserManager userManager, - SignInManager signInManager, + SignInManager signInManager, IAuthTokenService authTokenService, IEventBus eventBus, IMapper mapper) @@ -133,7 +133,7 @@ public async Task> RegisterUserAsync(RegisterDataDTO mo return Result.Failed("Пароль должен содержать не менее 6 символов"); } - var user = _mapper.Map(model); + var user = _mapper.Map(model); user.UserName = user.Email.Split('@')[0]; var createUserTask = model.IsExternalAuth @@ -201,40 +201,40 @@ public async Task GetAllStudents() .ToArray();; } - private Task ChangeUserNameTask(User user, EditDataDTO model) + private Task ChangeUserNameTask(UserViewModel userViewModel, EditDataDTO model) { if (!string.IsNullOrWhiteSpace(model.Name)) { - user.Name = model.Name; + userViewModel.Name = model.Name; } if (!string.IsNullOrWhiteSpace(model.Name)) { - user.Surname = model.Surname; + userViewModel.Surname = model.Surname; } if (!string.IsNullOrWhiteSpace(model.Name)) { - user.MiddleName = model.MiddleName; + userViewModel.MiddleName = model.MiddleName; } - return _userManager.UpdateAsync(user); + return _userManager.UpdateAsync(userViewModel); } - private Task ChangePasswordAsync(User user, EditDataDTO model) + private Task ChangePasswordAsync(UserViewModel userViewModel, EditDataDTO model) { return !string.IsNullOrWhiteSpace(model.NewPassword) - ? _userManager.ChangePasswordAsync(user, model.CurrentPassword, model.NewPassword) + ? _userManager.ChangePasswordAsync(userViewModel, model.CurrentPassword, model.NewPassword) : Task.FromResult(IdentityResult.Success); } - private async Task SignIn(User user, string password) + private async Task SignIn(UserViewModel userViewModel, string password) { - await _signInManager.PasswordSignInAsync(user, password, false, false) + await _signInManager.PasswordSignInAsync(userViewModel, password, false, false) .ConfigureAwait(false); } - private async Task> GetToken(User user) + private async Task> GetToken(UserViewModel userViewModel) { - return Result.Success(await _tokenService.GetTokenAsync(user).ConfigureAwait(false)); + return Result.Success(await _tokenService.GetTokenAsync(userViewModel).ConfigureAwait(false)); } } } diff --git a/HwProj.AuthService/HwProj.AuthService.API/Services/AuthTokenService.cs b/HwProj.AuthService/HwProj.AuthService.API/Services/AuthTokenService.cs index e457a6126..b7165b23d 100644 --- a/HwProj.AuthService/HwProj.AuthService.API/Services/AuthTokenService.cs +++ b/HwProj.AuthService/HwProj.AuthService.API/Services/AuthTokenService.cs @@ -15,21 +15,21 @@ namespace HwProj.AuthService.API.Services { public class AuthTokenService : IAuthTokenService { - private readonly UserManager _userManager; + private readonly UserManager _userManager; private readonly IConfigurationSection _configuration; - public AuthTokenService(UserManager userManager, IConfiguration configuration) + public AuthTokenService(UserManager userManager, IConfiguration configuration) { _userManager = userManager; _configuration = configuration.GetSection("AppSettings"); } - public async Task GetTokenAsync(User user) + public async Task GetTokenAsync(UserViewModel userViewModel) { var securityKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(_configuration["SecurityKey"])); var timeNow = DateTime.UtcNow; - var userRoles = await _userManager.GetRolesAsync(user).ConfigureAwait(false); + var userRoles = await _userManager.GetRolesAsync(userViewModel).ConfigureAwait(false); var token = new JwtSecurityToken( issuer: _configuration["ApiName"], @@ -37,9 +37,9 @@ public async Task GetTokenAsync(User user) expires: timeNow.AddMinutes(int.Parse(_configuration["ExpireInForToken"])), claims: new[] { - new Claim("_userName", user.UserName), - new Claim("_id", user.Id), - new Claim(ClaimTypes.Email, user.Email), + new Claim("_userName", userViewModel.UserName), + new Claim("_id", userViewModel.Id), + new Claim(ClaimTypes.Email, userViewModel.Email), new Claim(ClaimTypes.Role, userRoles.FirstOrDefault() ?? Roles.StudentRole) }, signingCredentials: new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256)); diff --git a/HwProj.AuthService/HwProj.AuthService.API/Services/IAuthTokenService.cs b/HwProj.AuthService/HwProj.AuthService.API/Services/IAuthTokenService.cs index ee0caef99..e96832cd8 100644 --- a/HwProj.AuthService/HwProj.AuthService.API/Services/IAuthTokenService.cs +++ b/HwProj.AuthService/HwProj.AuthService.API/Services/IAuthTokenService.cs @@ -6,6 +6,6 @@ namespace HwProj.AuthService.API.Services { public interface IAuthTokenService { - Task GetTokenAsync(User user); + Task GetTokenAsync(UserViewModel userViewModel); } } diff --git a/HwProj.AuthService/HwProj.AuthService.API/Services/IUserManager.cs b/HwProj.AuthService/HwProj.AuthService.API/Services/IUserManager.cs index 9ce9db520..09796d197 100644 --- a/HwProj.AuthService/HwProj.AuthService.API/Services/IUserManager.cs +++ b/HwProj.AuthService/HwProj.AuthService.API/Services/IUserManager.cs @@ -7,17 +7,17 @@ namespace HwProj.AuthService.API.Services { public interface IUserManager { - Task CreateAsync(User user); - Task CreateAsync(User user, string password); - Task FindByIdAsync(string id); - Task FindByEmailAsync(string email); - Task UpdateAsync(User user); - Task AddToRoleAsync(User user, string role); - Task RemoveFromRoleAsync(User user, string role); - Task> GetRolesAsync(User user); - Task IsEmailConfirmedAsync(User user); - Task CheckPasswordAsync(User user, string password); - Task ChangePasswordAsync(User user, string currentPassword, string newPassword); - Task> GetUsersInRoleAsync(string role); + Task CreateAsync(UserViewModel userViewModel); + Task CreateAsync(UserViewModel userViewModel, string password); + Task FindByIdAsync(string id); + Task FindByEmailAsync(string email); + Task UpdateAsync(UserViewModel userViewModel); + Task AddToRoleAsync(UserViewModel userViewModel, string role); + Task RemoveFromRoleAsync(UserViewModel userViewModel, string role); + Task> GetRolesAsync(UserViewModel userViewModel); + Task IsEmailConfirmedAsync(UserViewModel userViewModel); + Task CheckPasswordAsync(UserViewModel userViewModel, string password); + Task ChangePasswordAsync(UserViewModel userViewModel, string currentPassword, string newPassword); + Task> GetUsersInRoleAsync(string role); } } diff --git a/HwProj.AuthService/HwProj.AuthService.API/Services/ProxyUserManager.cs b/HwProj.AuthService/HwProj.AuthService.API/Services/ProxyUserManager.cs index e583ce6b3..2fd66cfcd 100644 --- a/HwProj.AuthService/HwProj.AuthService.API/Services/ProxyUserManager.cs +++ b/HwProj.AuthService/HwProj.AuthService.API/Services/ProxyUserManager.cs @@ -9,69 +9,69 @@ namespace HwProj.AuthService.API.Services { public class ProxyUserManager : IUserManager { - private readonly UserManager _aspUserManager; + private readonly UserManager _aspUserManager; - public ProxyUserManager(UserManager aspUserManager) + public ProxyUserManager(UserManager aspUserManager) { _aspUserManager = aspUserManager; } - public Task CreateAsync(User user) + public Task CreateAsync(UserViewModel userViewModel) { - return _aspUserManager.CreateAsync(user); + return _aspUserManager.CreateAsync(userViewModel); } - public Task CreateAsync(User user, string password) + public Task CreateAsync(UserViewModel userViewModel, string password) { - return _aspUserManager.CreateAsync(user, password); + return _aspUserManager.CreateAsync(userViewModel, password); } - public Task FindByIdAsync(string id) + public Task FindByIdAsync(string id) { return _aspUserManager.FindByIdAsync(id); } - public Task FindByEmailAsync(string email) + public Task FindByEmailAsync(string email) { return _aspUserManager.FindByEmailAsync(email); } - public Task UpdateAsync(User user) + public Task UpdateAsync(UserViewModel userViewModel) { - return _aspUserManager.UpdateAsync(user); + return _aspUserManager.UpdateAsync(userViewModel); } - public Task AddToRoleAsync(User user, string role) + public Task AddToRoleAsync(UserViewModel userViewModel, string role) { - return _aspUserManager.AddToRoleAsync(user, role); + return _aspUserManager.AddToRoleAsync(userViewModel, role); } - public Task RemoveFromRoleAsync(User user, string role) + public Task RemoveFromRoleAsync(UserViewModel userViewModel, string role) { - return _aspUserManager.RemoveFromRoleAsync(user, role); + return _aspUserManager.RemoveFromRoleAsync(userViewModel, role); } - public Task> GetRolesAsync(User user) + public Task> GetRolesAsync(UserViewModel userViewModel) { - return _aspUserManager.GetRolesAsync(user); + return _aspUserManager.GetRolesAsync(userViewModel); } - public Task IsEmailConfirmedAsync(User user) + public Task IsEmailConfirmedAsync(UserViewModel userViewModel) { - return _aspUserManager.IsEmailConfirmedAsync(user); + return _aspUserManager.IsEmailConfirmedAsync(userViewModel); } - public Task CheckPasswordAsync(User user, string password) + public Task CheckPasswordAsync(UserViewModel userViewModel, string password) { - return _aspUserManager.CheckPasswordAsync(user, password); + return _aspUserManager.CheckPasswordAsync(userViewModel, password); } - public Task ChangePasswordAsync(User user, string currentPassword, string newPassword) + public Task ChangePasswordAsync(UserViewModel userViewModel, string currentPassword, string newPassword) { - return _aspUserManager.ChangePasswordAsync(user, currentPassword, newPassword); + return _aspUserManager.ChangePasswordAsync(userViewModel, currentPassword, newPassword); } - public Task> GetUsersInRoleAsync(string role) + public Task> GetUsersInRoleAsync(string role) { return _aspUserManager.GetUsersInRoleAsync(role); } diff --git a/HwProj.AuthService/HwProj.AuthService.API/Startup.cs b/HwProj.AuthService/HwProj.AuthService.API/Startup.cs index 2113dd594..e8242561d 100644 --- a/HwProj.AuthService/HwProj.AuthService.API/Startup.cs +++ b/HwProj.AuthService/HwProj.AuthService.API/Startup.cs @@ -64,7 +64,7 @@ public void ConfigureServices(IServiceCollection services) services.AddDbContext(options => options.UseSqlServer(connectionString)); - services.AddIdentity(opts => + services.AddIdentity(opts => { opts.User.RequireUniqueEmail = true; opts.Password.RequiredLength = 6; @@ -74,7 +74,7 @@ public void ConfigureServices(IServiceCollection services) opts.Password.RequireDigit = false; }) .AddEntityFrameworkStores() - .AddUserManager>() + .AddUserManager>() .AddRoleManager>() .AddDefaultTokenProviders(); @@ -91,7 +91,7 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env) using (var scope = app.ApplicationServices.CreateScope()) { - var userManager = scope.ServiceProvider.GetService(typeof(UserManager)) as UserManager; + var userManager = scope.ServiceProvider.GetService(typeof(UserManager)) as UserManager; var rolesManager = scope.ServiceProvider.GetService(typeof(RoleManager)) as RoleManager; var eventBus = scope.ServiceProvider.GetService(); diff --git a/HwProj.AuthService/HwProj.AuthService.Client/AuthServiceClient.cs b/HwProj.AuthService/HwProj.AuthService.Client/AuthServiceClient.cs index a8dc5ad3c..6e725e8dc 100644 --- a/HwProj.AuthService/HwProj.AuthService.Client/AuthServiceClient.cs +++ b/HwProj.AuthService/HwProj.AuthService.Client/AuthServiceClient.cs @@ -134,7 +134,7 @@ public async Task FindByEmailAsync(string email) }; var response = await _httpClient.SendAsync(httpRequest); - var user = await response.DeserializeAsync(); + var user = await response.DeserializeAsync(); return user?.Id; } diff --git a/HwProj.Common/HwProj.Models/AuthService/ViewModels/User.cs b/HwProj.Common/HwProj.Models/AuthService/ViewModels/UserViewModel.cs similarity index 82% rename from HwProj.Common/HwProj.Models/AuthService/ViewModels/User.cs rename to HwProj.Common/HwProj.Models/AuthService/ViewModels/UserViewModel.cs index b2975e353..92ecd955d 100644 --- a/HwProj.Common/HwProj.Models/AuthService/ViewModels/User.cs +++ b/HwProj.Common/HwProj.Models/AuthService/ViewModels/UserViewModel.cs @@ -2,7 +2,7 @@ namespace HwProj.Models.AuthService.ViewModels { - public class User : IdentityUser + public class UserViewModel : IdentityUser { public string GitHubId { get; set; } @@ -14,7 +14,7 @@ public class User : IdentityUser public bool IsExternalAuth { get; set; } - public User() + public UserViewModel() { } } diff --git a/HwProj.Common/HwProj.Models/TelegramBotService/UserTelegram.cs b/HwProj.Common/HwProj.Models/TelegramBotService/UserTelegram.cs new file mode 100644 index 000000000..37534120c --- /dev/null +++ b/HwProj.Common/HwProj.Models/TelegramBotService/UserTelegram.cs @@ -0,0 +1,27 @@ +using HwProj.Repositories; + +namespace HwProj.Models.TelegramBotService +{ + public class UserTelegram : IEntity + { + public long Id { get; set; } + + public long ChatId { get; set; } + + public string AccountId { get; set; } + + public bool IsLecture { get; set; } + + public bool IsRegistered { get; set; } + + public string? Code { get; set; } + + public string? Comment { get; set; } + + public long? TaskIdToSend { get; set; } + + public string? GitHubUrl { get; set; } + + public string? Operation { get; set; } + } +} \ No newline at end of file diff --git a/HwProj.Common/HwProj.Utils/Configuration/StartupExtensions.cs b/HwProj.Common/HwProj.Utils/Configuration/StartupExtensions.cs index 9c19fdb44..6c0f408c9 100644 --- a/HwProj.Common/HwProj.Utils/Configuration/StartupExtensions.cs +++ b/HwProj.Common/HwProj.Utils/Configuration/StartupExtensions.cs @@ -78,6 +78,7 @@ public static IServiceCollection ConfigureHwProjServices(this IServiceCollection services.AddTransient(); + services.AddHttpContextAccessor(); return services; diff --git a/HwProj.CoursesService/HwProj.CoursesService.API/Controllers/HomeworksController.cs b/HwProj.CoursesService/HwProj.CoursesService.API/Controllers/HomeworksController.cs index 20c958003..7308e3c66 100644 --- a/HwProj.CoursesService/HwProj.CoursesService.API/Controllers/HomeworksController.cs +++ b/HwProj.CoursesService/HwProj.CoursesService.API/Controllers/HomeworksController.cs @@ -1,4 +1,6 @@ -using System.Threading.Tasks; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; using AutoMapper; using HwProj.CoursesService.API.Filters; using HwProj.CoursesService.API.Models; @@ -38,6 +40,13 @@ public async Task GetHomework(long homeworkId) homework.Tasks.ForEach(t => t.PutPossibilityForSendingSolution()); return homework; } + + [HttpGet("{courseId}/getAll")] + public async Task GetAllHomeworkFromCourse(long courseId) + { + var homeworkFromDb = await _homeworksService.GetAllHomeworkFromCourseAsync(courseId); + return homeworkFromDb.ToArray(); + } [HttpDelete("delete/{homeworkId}")] public async Task DeleteHomework(long homeworkId) diff --git a/HwProj.CoursesService/HwProj.CoursesService.API/Events/NewHomeworkEvent.cs b/HwProj.CoursesService/HwProj.CoursesService.API/Events/NewHomeworkEvent.cs index e4b47482b..50ff3693a 100644 --- a/HwProj.CoursesService/HwProj.CoursesService.API/Events/NewHomeworkEvent.cs +++ b/HwProj.CoursesService/HwProj.CoursesService.API/Events/NewHomeworkEvent.cs @@ -6,11 +6,14 @@ namespace HwProj.CoursesService.API.Events public class NewHomeworkEvent : Event { public string Homework { get; set; } + + public long HomeworkId { get; set; } public CourseViewModel Course { get; set; } - public NewHomeworkEvent(string homework, CourseViewModel course) + public NewHomeworkEvent(string homework, long homeworkId, CourseViewModel course) { Homework = homework; + homeworkId = homeworkId; Course = course; } } diff --git a/HwProj.CoursesService/HwProj.CoursesService.API/Services/HomeworksService.cs b/HwProj.CoursesService/HwProj.CoursesService.API/Services/HomeworksService.cs index cab03b83d..6218dd464 100644 --- a/HwProj.CoursesService/HwProj.CoursesService.API/Services/HomeworksService.cs +++ b/HwProj.CoursesService/HwProj.CoursesService.API/Services/HomeworksService.cs @@ -30,7 +30,7 @@ public async Task AddHomeworkAsync(long courseId, Homework homework) var course = await _coursesRepository.GetWithCourseMatesAsync(courseId); var courseModel = _mapper.Map(course); - _eventBus.Publish(new NewHomeworkEvent(homework.Title, courseModel)); + _eventBus.Publish(new NewHomeworkEvent(homework.Title, homework.Id, courseModel)); return await _homeworksRepository.AddAsync(homework); } @@ -40,6 +40,11 @@ public async Task GetHomeworkAsync(long homeworkId) return await _homeworksRepository.GetWithTasksAsync(homeworkId); } + public async Task GetAllHomeworkFromCourseAsync(long courseId) + { + return await _homeworksRepository.GetAllWithTasksByCourseAsync(courseId); + } + public async Task DeleteHomeworkAsync(long homeworkId) { await _homeworksRepository.DeleteAsync(homeworkId); diff --git a/HwProj.CoursesService/HwProj.CoursesService.API/Services/IHomeworksService.cs b/HwProj.CoursesService/HwProj.CoursesService.API/Services/IHomeworksService.cs index 5c2d98a60..06f47f958 100644 --- a/HwProj.CoursesService/HwProj.CoursesService.API/Services/IHomeworksService.cs +++ b/HwProj.CoursesService/HwProj.CoursesService.API/Services/IHomeworksService.cs @@ -9,6 +9,8 @@ public interface IHomeworksService Task GetHomeworkAsync(long homeworkId); + Task GetAllHomeworkFromCourseAsync(long courseId); + Task DeleteHomeworkAsync(long homeworkId); Task UpdateHomeworkAsync(long homeworkId, Homework update); diff --git a/HwProj.CoursesService/HwProj.CoursesService.Client/ConfigurationExtensions.cs b/HwProj.CoursesService/HwProj.CoursesService.Client/ConfigurationExtensions.cs index 34c6839bf..5c896b3cf 100644 --- a/HwProj.CoursesService/HwProj.CoursesService.Client/ConfigurationExtensions.cs +++ b/HwProj.CoursesService/HwProj.CoursesService.Client/ConfigurationExtensions.cs @@ -1,6 +1,6 @@ -using System; -using System.Net.Http; +using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; namespace HwProj.CoursesService.Client { @@ -9,6 +9,8 @@ public static class ConfigurationExtensions public static IServiceCollection AddCoursesServiceClient(this IServiceCollection services) { services.AddScoped(); + /*services.AddHttpContextAccessor();*/ + /*services.TryAddSingleton();*/ return services; } } diff --git a/HwProj.CoursesService/HwProj.CoursesService.Client/CoursesServiceClient.cs b/HwProj.CoursesService/HwProj.CoursesService.Client/CoursesServiceClient.cs index aab971ff4..4790afd3c 100644 --- a/HwProj.CoursesService/HwProj.CoursesService.Client/CoursesServiceClient.cs +++ b/HwProj.CoursesService/HwProj.CoursesService.Client/CoursesServiceClient.cs @@ -166,6 +166,15 @@ public async Task GetHomework(long homeworkId) return await response.DeserializeAsync(); } + public async Task GetAllHomeworkByCourse(long courseId) + { + using var httpRequest = new HttpRequestMessage( + HttpMethod.Get, + _coursesServiceUri + $"api/Homeworks/{courseId}/getAll"); + var response = await _httpClient.SendAsync(httpRequest); + return await response.DeserializeAsync(); + } + public async Task UpdateHomework(CreateHomeworkViewModel model, long homeworkId) { using var httpRequest = new HttpRequestMessage( diff --git a/HwProj.CoursesService/HwProj.CoursesService.Client/ICoursesServiceClient.cs b/HwProj.CoursesService/HwProj.CoursesService.Client/ICoursesServiceClient.cs index 0539ba487..e797b2ac4 100644 --- a/HwProj.CoursesService/HwProj.CoursesService.Client/ICoursesServiceClient.cs +++ b/HwProj.CoursesService/HwProj.CoursesService.Client/ICoursesServiceClient.cs @@ -17,6 +17,7 @@ public interface ICoursesServiceClient Task GetAllUserCourses(string userId); Task AddHomeworkToCourse(CreateHomeworkViewModel model, long courseId); Task GetHomework(long homeworkId); + Task GetAllHomeworkByCourse(long courseId); Task UpdateHomework(CreateHomeworkViewModel model, long homeworkId); Task DeleteHomework(long homeworkId); Task GetTask(long taskId); diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/ConfirmTelegramBotEventHandler.cs b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/ConfirmTelegramBotEventHandler.cs new file mode 100644 index 000000000..3c6198ec8 --- /dev/null +++ b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/ConfirmTelegramBotEventHandler.cs @@ -0,0 +1,34 @@ +using System; +using System.Threading.Tasks; +using HwProj.EventBus.Client.Interfaces; +using HwProj.Models.NotificationsService; +using HwProj.NotificationsService.API.Repositories; +using HwProj.TelegramBotService.API.Events; + +namespace HwProj.NotificationsService.API.EventHandlers +{ + public class ConfirmTelegramBotEventHandler: IEventHandler + { + private readonly INotificationsRepository _notificationRepository; + + + public ConfirmTelegramBotEventHandler(INotificationsRepository notificationRepository) + { + _notificationRepository = notificationRepository; + } + + public async Task HandleAsync(ConfirmTelegramBotEvent @event) + { + var notification = new Notification + { + Sender = "TelegramBotService", + Body = $"Ваш код для телеграмма - {@event.Code}.", + Category = "TelegramBotService", + Date = DateTime.UtcNow, + HasSeen = false, + Owner = @event.StudentId + }; + await _notificationRepository.AddAsync(notification); + } + } +} \ No newline at end of file diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/EditProfileEventHandler.cs b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/EditProfileEventHandler.cs index 78b1494b6..a1d5535bb 100644 --- a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/EditProfileEventHandler.cs +++ b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/EditProfileEventHandler.cs @@ -1,24 +1,35 @@ using System; using System.Threading.Tasks; +using AutoMapper; using HwProj.AuthService.API.Events; +using HwProj.AuthService.Client; using HwProj.EventBus.Client.Interfaces; +using HwProj.Models.AuthService.DTO; using HwProj.Models.NotificationsService; using HwProj.NotificationsService.API.Repositories; +using HwProj.NotificationsService.API.Services; namespace HwProj.NotificationsService.API.EventHandlers { public class EditProfileEventHandler : IEventHandler { private readonly INotificationsRepository _notificationRepository; + private readonly INotificationsService _notificationsService; + private readonly IAuthServiceClient _authServiceClient; + private readonly IMapper _mapper; - public EditProfileEventHandler(INotificationsRepository notificationRepository) + + public EditProfileEventHandler(INotificationsRepository notificationRepository, INotificationsService notificationsService, IMapper mapper, IAuthServiceClient authServiceClient) { _notificationRepository = notificationRepository; + _notificationsService = notificationsService; + _mapper = mapper; + _authServiceClient = authServiceClient; } public async Task HandleAsync(EditProfileEvent @event) { - await _notificationRepository.AddAsync(new Notification + var notification = new Notification { Sender = "AuthService", Body = "Ваш профиль был успешно отредактирован.", @@ -26,7 +37,13 @@ await _notificationRepository.AddAsync(new Notification Date = DateTime.UtcNow, HasSeen = false, Owner = @event.UserId - }); + }; + await _notificationRepository.AddAsync(notification); + var studentAccount = await _authServiceClient.GetAccountData(notification.Owner); + var studentModel = _mapper.Map(studentAccount); + + await _notificationsService.SendEmailAsync(notification, studentModel.Email, "Редактирование профиля"); + await _notificationsService.SendTelegramMessageAsync(notification); } } } \ No newline at end of file diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/InviteLecturerEventHandler.cs b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/InviteLecturerEventHandler.cs index fae880c09..714ed29da 100644 --- a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/InviteLecturerEventHandler.cs +++ b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/InviteLecturerEventHandler.cs @@ -1,24 +1,34 @@ using System; using System.Threading.Tasks; +using AutoMapper; using HwProj.AuthService.API.Events; +using HwProj.AuthService.Client; using HwProj.EventBus.Client.Interfaces; +using HwProj.Models.AuthService.DTO; using HwProj.Models.NotificationsService; using HwProj.NotificationsService.API.Repositories; +using HwProj.NotificationsService.API.Services; namespace HwProj.NotificationsService.API.EventHandlers { public class InviteLecturerEventHandler : IEventHandler { private readonly INotificationsRepository _notificationRepository; + private readonly INotificationsService _notificationsService; + private readonly IAuthServiceClient _authServiceClient; + private readonly IMapper _mapper; - public InviteLecturerEventHandler(INotificationsRepository notificationRepository) + public InviteLecturerEventHandler(INotificationsRepository notificationRepository, INotificationsService notificationsService, IAuthServiceClient authServiceClient, IMapper mapper) { _notificationRepository = notificationRepository; + _notificationsService = notificationsService; + _authServiceClient = authServiceClient; + _mapper = mapper; } public async Task HandleAsync(InviteLecturerEvent @event) { - await _notificationRepository.AddAsync(new Notification + var notification = new Notification { Sender = "AuthService", Body = "Вас добавили в список лекторов.", @@ -26,7 +36,14 @@ await _notificationRepository.AddAsync(new Notification Date = DateTime.UtcNow, HasSeen = false, Owner = @event.UserId - }); + }; + await _notificationRepository.AddAsync(notification); + + var studentAccount = await _authServiceClient.GetAccountData(notification.Owner); + var studentModel = _mapper.Map(studentAccount); + + await _notificationsService.SendEmailAsync(notification, studentModel.Email, "HwProj"); + await _notificationsService.SendTelegramMessageAsync(notification); } } } \ No newline at end of file diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/LecturerAcceptToCourseEventHandler.cs b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/LecturerAcceptToCourseEventHandler.cs index 5993b56ca..af1c87f7a 100644 --- a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/LecturerAcceptToCourseEventHandler.cs +++ b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/LecturerAcceptToCourseEventHandler.cs @@ -5,23 +5,27 @@ using HwProj.EventBus.Client.Interfaces; using HwProj.Models.NotificationsService; using HwProj.NotificationsService.API.Repositories; +using HwProj.NotificationsService.API.Services; namespace HwProj.NotificationsService.API.EventHandlers { public class LecturerAcceptToCourseEventHandler : IEventHandler { private readonly INotificationsRepository _notificationRepository; - private readonly IAuthServiceClient _authClient; + private readonly INotificationsService _notificationsService; + private readonly IAuthServiceClient _authServiceClient; - public LecturerAcceptToCourseEventHandler(INotificationsRepository notificationRepository, IAuthServiceClient authClient) + + public LecturerAcceptToCourseEventHandler(INotificationsRepository notificationRepository, INotificationsService notificationsService, IAuthServiceClient authServiceClient) { _notificationRepository = notificationRepository; - _authClient = authClient; + _notificationsService = notificationsService; + _authServiceClient = authServiceClient; } public async Task HandleAsync(LecturerAcceptToCourseEvent @event) { - await _notificationRepository.AddAsync(new Notification + var notification = new Notification { Sender = "CourseService", Body = $"Вас приняли на курс {@event.CourseName}.", @@ -29,7 +33,13 @@ await _notificationRepository.AddAsync(new Notification Date = DateTime.UtcNow, HasSeen = false, Owner = @event.StudentId - }); + }; + await _notificationRepository.AddAsync(notification); + var student = await _authServiceClient.GetAccountData(notification.Owner); + await _notificationsService.SendEmailAsync(notification, student.Email, "HwProj"); + + notification.Body = $"Вас приняли на курс {@event.CourseName}."; + await _notificationsService.SendTelegramMessageAsync(notification); } } } \ No newline at end of file diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/LecturerRejectToCourseEventHandler.cs b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/LecturerRejectToCourseEventHandler.cs index 94dfdf367..86e90bcab 100644 --- a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/LecturerRejectToCourseEventHandler.cs +++ b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/LecturerRejectToCourseEventHandler.cs @@ -5,23 +5,27 @@ using HwProj.EventBus.Client.Interfaces; using HwProj.Models.NotificationsService; using HwProj.NotificationsService.API.Repositories; +using HwProj.NotificationsService.API.Services; namespace HwProj.NotificationsService.API.EventHandlers { public class LecturerRejectToCourseEventHandler : IEventHandler { private readonly INotificationsRepository _notificationRepository; - private readonly IAuthServiceClient _authClient; + private readonly INotificationsService _notificationsService; + private readonly IAuthServiceClient _authServiceClient; - public LecturerRejectToCourseEventHandler(INotificationsRepository notificationRepository, IAuthServiceClient authClient) + + public LecturerRejectToCourseEventHandler(INotificationsRepository notificationRepository, INotificationsService notificationsService, IAuthServiceClient authServiceClient) { _notificationRepository = notificationRepository; - _authClient = authClient; + _notificationsService = notificationsService; + _authServiceClient = authServiceClient; } public async Task HandleAsync(LecturerRejectToCourseEvent @event) { - await _notificationRepository.AddAsync(new Notification + var notification = new Notification { Sender = "CourseService", Body = $"Вас не приняли на курс {@event.CourseName}.", @@ -29,7 +33,13 @@ await _notificationRepository.AddAsync(new Notification Date = DateTime.UtcNow, HasSeen = false, Owner = @event.StudentId - }); + }; + await _notificationRepository.AddAsync(notification); + var student = await _authServiceClient.GetAccountData(notification.Owner); + await _notificationsService.SendEmailAsync(notification, student.Email, "HwProj"); + + notification.Body = $"Вас не приняли на курс {@event.CourseName}."; + await _notificationsService.SendTelegramMessageAsync(notification); } } } \ No newline at end of file diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/NewCourseMateHandler.cs b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/NewCourseMateHandler.cs index 2b0ce81a0..a1a978440 100644 --- a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/NewCourseMateHandler.cs +++ b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/NewCourseMateHandler.cs @@ -5,6 +5,7 @@ using HwProj.EventBus.Client.Interfaces; using HwProj.Models.NotificationsService; using HwProj.NotificationsService.API.Repositories; +using HwProj.NotificationsService.API.Services; namespace HwProj.NotificationsService.API.EventHandlers { @@ -12,11 +13,14 @@ public class NewCourseMateHandler : IEventHandler { private readonly INotificationsRepository _notificationRepository; private readonly IAuthServiceClient _authClient; + private readonly INotificationsService _notificationsService; - public NewCourseMateHandler(INotificationsRepository notificationRepository, IAuthServiceClient authClient) + + public NewCourseMateHandler(INotificationsRepository notificationRepository, IAuthServiceClient authClient, INotificationsService notificationsService) { _notificationRepository = notificationRepository; _authClient = authClient; + _notificationsService = notificationsService; } public async Task HandleAsync(NewCourseMateEvent @event) @@ -25,15 +29,23 @@ public async Task HandleAsync(NewCourseMateEvent @event) foreach (var m in @event.MentorIds.Split('/')) { - await _notificationRepository.AddAsync(new Notification + var notification = new Notification { Sender = "CourseService", - Body = $"Пользователь {user.Name} {user.Surname} подал(-а) заявку на вступление в курс {@event.CourseName}.", + Body = + $"Пользователь {user.Name} {user.Surname}" + + $" подал заявку на вступление в курс {@event.CourseName}.", Category = "CourseService", Date = DateTime.UtcNow, HasSeen = false, Owner = m - }); + }; + await _notificationRepository.AddAsync(notification); + var mentor = await _authClient.GetAccountData(notification.Owner); + await _notificationsService.SendEmailAsync(notification, mentor.Email, "HwProj"); + + notification.Body = $"Пользователь {user.Name} {user.Surname} подал заявку на вступление в курс {@event.CourseName}."; + await _notificationsService.SendTelegramMessageAsync(notification); } } } diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/NewHomeworkEventHandler.cs b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/NewHomeworkEventHandler.cs index 74889e16c..bd43c5484 100644 --- a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/NewHomeworkEventHandler.cs +++ b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/NewHomeworkEventHandler.cs @@ -1,36 +1,59 @@ using System; using System.Threading.Tasks; -using HwProj.AuthService.API.Events; +using AutoMapper; +using HwProj.AuthService.Client; using HwProj.EventBus.Client.Interfaces; using HwProj.Models.NotificationsService; using HwProj.NotificationsService.API.Repositories; using HwProj.CoursesService.API.Events; +using HwProj.Models.AuthService.DTO; +using HwProj.NotificationsService.API.Services; +using Telegram.Bot.Types.ReplyMarkups; namespace HwProj.NotificationsService.API.EventHandlers { - // ReSharper disable once UnusedType.Global public class NewHomeworkEventHandler : IEventHandler { private readonly INotificationsRepository _notificationRepository; + private readonly INotificationsService _notificationsService; + private readonly IAuthServiceClient _authServiceClient; + private readonly IMapper _mapper; - public NewHomeworkEventHandler(INotificationsRepository notificationRepository) + + public NewHomeworkEventHandler(INotificationsRepository notificationRepository, + INotificationsService notificationsService, IAuthServiceClient authServiceClient, IMapper mapper) { _notificationRepository = notificationRepository; + _notificationsService = notificationsService; + _authServiceClient = authServiceClient; + _mapper = mapper; } public async Task HandleAsync(NewHomeworkEvent @event) { - foreach(var student in @event.Course.CourseMates) + foreach (var student in @event.Course.CourseMates) { - await _notificationRepository.AddAsync(new Notification + var studentAccount = await _authServiceClient.GetAccountData(student.StudentId); + var studentModel = _mapper.Map(studentAccount); + var notification = new Notification { Sender = "CourseService", - Body = $"В курсе {@event.Course.Name} опубликована новая домашка {@event.Homework}.", + Body = $"В курсе {@event.Course.Name}" + + $" опубликована новая домашка {@event.Homework}.", Category = "CourseService", Date = DateTime.UtcNow, HasSeen = false, Owner = student.StudentId + }; + await _notificationRepository.AddAsync(notification); + await _notificationsService.SendEmailAsync(notification, studentModel.Email, "Домашняя работа"); + notification.Body = $"В курсе {@event.Course.Name} опубликована новая домашка {@event.Homework}."; // + var inlineKeyboard = new InlineKeyboardMarkup(new InlineKeyboardButton + { + Text = $"{@event.Homework}", + CallbackData = $"/homeworks {@event.Course.Id}" }); + await _notificationsService.SendTelegramMessageWithKeyboardAsync(notification, inlineKeyboard); } } } diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/RateEventHandler.cs b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/RateEventHandler.cs index ec5d2ba66..c82fd42ce 100644 --- a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/RateEventHandler.cs +++ b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/RateEventHandler.cs @@ -1,26 +1,32 @@ using System; using System.Threading.Tasks; -using HwProj.AuthService.API.Events; +using HwProj.AuthService.Client; using HwProj.EventBus.Client.Interfaces; using HwProj.Models.NotificationsService; using HwProj.NotificationsService.API.Repositories; +using HwProj.NotificationsService.API.Services; using HwProj.SolutionsService.API.Events; +using Telegram.Bot.Types.ReplyMarkups; namespace HwProj.NotificationsService.API.EventHandlers { - // ReSharper disable once UnusedType.Global public class RateEventHandler : IEventHandler { private readonly INotificationsRepository _notificationRepository; + private readonly INotificationsService _notificationsService; + private readonly IAuthServiceClient _authServiceClient; - public RateEventHandler(INotificationsRepository notificationRepository) + + public RateEventHandler(INotificationsRepository notificationRepository, INotificationsService notificationsService, IAuthServiceClient authServiceClient) { _notificationRepository = notificationRepository; + _notificationsService = notificationsService; + _authServiceClient = authServiceClient; } public async Task HandleAsync(RateEvent @event) { - await _notificationRepository.AddAsync(new Notification + var notification = new Notification { Sender = "SolutionService", Body = $"Задача {@event.Task.Title} оценена.", @@ -28,7 +34,18 @@ await _notificationRepository.AddAsync(new Notification Date = DateTime.UtcNow, HasSeen = false, Owner = @event.Solution.StudentId - }); ; + }; + await _notificationRepository.AddAsync(notification); + var studentModel = await _authServiceClient.GetAccountData(notification.Owner); + await _notificationsService.SendEmailAsync(notification, studentModel.Email, "Оценка"); + + notification.Body = $"Задача {@event.Task.Title} оценена."; + var inlineKeyboard = new InlineKeyboardMarkup(new InlineKeyboardButton + { + Text = $"{@event.Task.Title}", + CallbackData = $"/solutioninfo {@event.SolutionId}" + }); + await _notificationsService.SendTelegramMessageWithKeyboardAsync(notification, inlineKeyboard); } } } \ No newline at end of file diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/RegisterEventHandler.cs b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/RegisterEventHandler.cs index 27e20baa2..11b66f3a7 100644 --- a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/RegisterEventHandler.cs +++ b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/RegisterEventHandler.cs @@ -4,22 +4,24 @@ using HwProj.EventBus.Client.Interfaces; using HwProj.Models.NotificationsService; using HwProj.NotificationsService.API.Repositories; +using HwProj.NotificationsService.API.Services; namespace HwProj.NotificationsService.API.EventHandlers { - // ReSharper disable once UnusedType.Global public class RegisterEventHandler : IEventHandler { private readonly INotificationsRepository _notificationRepository; + private readonly INotificationsService _notificationsService; - public RegisterEventHandler(INotificationsRepository notificationRepository) + public RegisterEventHandler(INotificationsRepository notificationRepository, INotificationsService notificationsService) { _notificationRepository = notificationRepository; + _notificationsService = notificationsService; } public async Task HandleAsync(StudentRegisterEvent @event) { - await _notificationRepository.AddAsync(new Notification + var notification = new Notification { Sender = "AuthService", Body = $"{@event.Name} {@event.Surname}, Добро Пожаловать в HwProj2.", @@ -27,7 +29,9 @@ await _notificationRepository.AddAsync(new Notification Date = DateTime.UtcNow, HasSeen = false, Owner = @event.UserId - }); + }; + await _notificationRepository.AddAsync(notification); + await _notificationsService.SendEmailAsync(notification, @event.Email, "HwProj"); } } } \ No newline at end of file diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/StudentPassTaskEventHandler.cs b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/StudentPassTaskEventHandler.cs index 0f75d10be..1b2856141 100644 --- a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/StudentPassTaskEventHandler.cs +++ b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/StudentPassTaskEventHandler.cs @@ -1,36 +1,50 @@ using System; using System.Threading.Tasks; -using HwProj.AuthService.API.Events; +using HwProj.AuthService.Client; using HwProj.EventBus.Client.Interfaces; using HwProj.Models.NotificationsService; using HwProj.NotificationsService.API.Repositories; +using HwProj.NotificationsService.API.Services; using HwProj.SolutionsService.API.Events; namespace HwProj.NotificationsService.API.EventHandlers { - // ReSharper disable once UnusedType.Global public class StudentPassTaskEventHandler : IEventHandler { private readonly INotificationsRepository _notificationRepository; + private readonly INotificationsService _notificationsService; + private readonly IAuthServiceClient _authServiceClient; - public StudentPassTaskEventHandler(INotificationsRepository notificationRepository) + + public StudentPassTaskEventHandler(INotificationsRepository notificationRepository, INotificationsService notificationsService, IAuthServiceClient authServiceClient) { _notificationRepository = notificationRepository; + _notificationsService = notificationsService; + _authServiceClient = authServiceClient; } public async Task HandleAsync(StudentPassTaskEvent @event) { foreach (var m in @event.Course.MentorIds.Split('/')) { - await _notificationRepository.AddAsync(new Notification + var notification = new Notification { Sender = "SolutionService", - Body = $"{@event.Student.Name} {@event.Student.Surname} добавил(-а) новое решение задачи {@event.Task.Title} из курса {@event.Course.Name}.", + Body = $"{@event.Student.Name} {@event.Student.Surname} добавил(-a) новое " + + $"решение " + + $"задачи {@event.Task.Title}" + + $" из курса {@event.Course.Name}.", Category = "SolutionService", Date = DateTime.UtcNow, HasSeen = false, Owner = m, - }); + }; + await _notificationRepository.AddAsync(notification); + var mentor = await _authServiceClient.GetAccountData(notification.Owner); + await _notificationsService.SendEmailAsync(notification, mentor.Email, "HwProj"); + + notification.Body = $"{@event.Student.Name} {@event.Student.Surname} добавил новое решение задачи {@event.Task.Title} из курса {@event.Course.Name}."; + await _notificationsService.SendTelegramMessageAsync(notification); } } } diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/UpdateHomeworkEventHandler.cs b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/UpdateHomeworkEventHandler.cs index 41eba9fea..e3eb16622 100644 --- a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/UpdateHomeworkEventHandler.cs +++ b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/UpdateHomeworkEventHandler.cs @@ -1,36 +1,54 @@ using System; using System.Threading.Tasks; -using HwProj.AuthService.API.Events; +using HwProj.AuthService.Client; using HwProj.EventBus.Client.Interfaces; using HwProj.Models.NotificationsService; using HwProj.NotificationsService.API.Repositories; using HwProj.CoursesService.API.Events; +using HwProj.NotificationsService.API.Services; +using Telegram.Bot.Types.ReplyMarkups; namespace HwProj.NotificationsService.API.EventHandlers { - // ReSharper disable once UnusedType.Global public class UpdateHomeworkEventHandler : IEventHandler { private readonly INotificationsRepository _notificationRepository; + private readonly INotificationsService _notificationsService; + private readonly IAuthServiceClient _authServiceClient; - public UpdateHomeworkEventHandler(INotificationsRepository notificationRepository) + + public UpdateHomeworkEventHandler(INotificationsRepository notificationRepository, INotificationsService notificationsService, IAuthServiceClient authServiceClient) { _notificationRepository = notificationRepository; + _notificationsService = notificationsService; + _authServiceClient = authServiceClient; } public async Task HandleAsync(UpdateHomeworkEvent @event) { foreach (var student in @event.Course.CourseMates) { - await _notificationRepository.AddAsync(new Notification + var notification = new Notification { Sender = "CourseService", - Body = $"В курсе {@event.Course.Name} домашнее задание {@event.Homework.Title} обновлено.", + Body = $"В курсе {@event.Course.Name}" + + $" домашнее задание {@event.Homework.Title} обновлено.", Category = "CourseService", Date = DateTime.UtcNow, HasSeen = false, Owner = student.StudentId + }; + await _notificationRepository.AddAsync(notification); + var studentModel = await _authServiceClient.GetAccountData(student.StudentId); + await _notificationsService.SendEmailAsync(notification, studentModel.Email, "Домашняя работа"); + + notification.Body = $"В курсе {@event.Course.Name} домашнее задание {@event.Homework.Title} обновлено.";// клава + var inlineKeyboard = new InlineKeyboardMarkup(new InlineKeyboardButton + { + Text = $"{@event.Homework.Title}", + CallbackData = $"/task {@event.Homework.Id}" }); + await _notificationsService.SendTelegramMessageWithKeyboardAsync(notification, inlineKeyboard); } } } diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/UpdateTaskMaxRatingEventHandler.cs b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/UpdateTaskMaxRatingEventHandler.cs index a23588839..d233881d0 100644 --- a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/UpdateTaskMaxRatingEventHandler.cs +++ b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/UpdateTaskMaxRatingEventHandler.cs @@ -1,36 +1,58 @@ using System; using System.Threading.Tasks; -using HwProj.AuthService.API.Events; +using AutoMapper; +using HwProj.AuthService.Client; using HwProj.EventBus.Client.Interfaces; using HwProj.Models.NotificationsService; using HwProj.NotificationsService.API.Repositories; using HwProj.CoursesService.API.Events; +using HwProj.Models.AuthService.DTO; +using HwProj.NotificationsService.API.Services; +using Telegram.Bot.Types.ReplyMarkups; namespace HwProj.NotificationsService.API.EventHandlers { - // ReSharper disable once UnusedType.Global public class UpdateTaskMaxRatingEventHandler : IEventHandler { private readonly INotificationsRepository _notificationRepository; + private readonly INotificationsService _notificationsService; + private readonly IAuthServiceClient _authServiceClient; + private readonly IMapper _mapper; - public UpdateTaskMaxRatingEventHandler(INotificationsRepository notificationRepository) + + public UpdateTaskMaxRatingEventHandler(INotificationsRepository notificationRepository, INotificationsService notificationsService, IAuthServiceClient authServiceClient, IMapper mapper) { _notificationRepository = notificationRepository; + _notificationsService = notificationsService; + _authServiceClient = authServiceClient; + _mapper = mapper; } public async Task HandleAsync(UpdateTaskMaxRatingEvent @event) { foreach (var student in @event.Course.CourseMates) { - await _notificationRepository.AddAsync(new Notification + var notification =new Notification { Sender = "CourseService", - Body = $"Задача обновлена.", + Body = $"Задача из {@event.Course.Name} обновлена.", Category = "CourseService", Date = DateTime.UtcNow, HasSeen = false, Owner = student.StudentId + }; + await _notificationRepository.AddAsync(notification); + var studentAccount = await _authServiceClient.GetAccountData(student.StudentId); + var studentModel = _mapper.Map(studentAccount); + await _notificationsService.SendEmailAsync(notification, studentModel.Email, "Домашняя работа"); + + notification.Body = $"Задача {@event.Task.Title} из {@event.Course.Name} обновлена.";// клава + var inlineKeyboard = new InlineKeyboardMarkup(new InlineKeyboardButton + { + Text = $"{@event.Task.Title}", + CallbackData = $"/taskinfo {@event.Task.Id}" }); + await _notificationsService.SendTelegramMessageWithKeyboardAsync(notification, inlineKeyboard); } } } diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/HwProj.NotificationsService.API.csproj b/HwProj.NotificationsService/HwProj.NotificationsService.API/HwProj.NotificationsService.API.csproj index 1b878c814..d24a089f3 100644 --- a/HwProj.NotificationsService/HwProj.NotificationsService.API/HwProj.NotificationsService.API.csproj +++ b/HwProj.NotificationsService/HwProj.NotificationsService.API/HwProj.NotificationsService.API.csproj @@ -11,6 +11,7 @@ + @@ -25,6 +26,8 @@ + + diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/Services/INotificationsService.cs b/HwProj.NotificationsService/HwProj.NotificationsService.API/Services/INotificationsService.cs index 0d7492a5d..2a0ff886d 100644 --- a/HwProj.NotificationsService/HwProj.NotificationsService.API/Services/INotificationsService.cs +++ b/HwProj.NotificationsService/HwProj.NotificationsService.API/Services/INotificationsService.cs @@ -1,5 +1,6 @@ using HwProj.Models.NotificationsService; using System.Threading.Tasks; +using Telegram.Bot.Types.ReplyMarkups; namespace HwProj.NotificationsService.API.Services { @@ -8,5 +9,8 @@ public interface INotificationsService Task AddNotificationAsync(Notification notification); Task GetAsync(string userId, NotificationFilter filter = null); Task MarkAsSeenAsync(string userId, long[] notificationIds); + Task SendEmailAsync(Notification notification, string email, string topic); + Task SendTelegramMessageAsync(Notification notification); + Task SendTelegramMessageWithKeyboardAsync(Notification notification, InlineKeyboardMarkup inlineKeyboard); } } \ No newline at end of file diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/Services/NotificationsService.cs b/HwProj.NotificationsService/HwProj.NotificationsService.API/Services/NotificationsService.cs index e30953df2..1ef973e27 100644 --- a/HwProj.NotificationsService/HwProj.NotificationsService.API/Services/NotificationsService.cs +++ b/HwProj.NotificationsService/HwProj.NotificationsService.API/Services/NotificationsService.cs @@ -1,8 +1,15 @@ -using System.Linq; +using System; +using System.Linq; using System.Threading.Tasks; using AutoMapper; using HwProj.Models.NotificationsService; using HwProj.NotificationsService.API.Repositories; +using HwProj.TelegramBotService.Client; +using Microsoft.Extensions.Configuration; +using MimeKit; +using Telegram.Bot; +using Telegram.Bot.Types.Enums; +using Telegram.Bot.Types.ReplyMarkups; namespace HwProj.NotificationsService.API.Services { @@ -10,11 +17,21 @@ public class NotificationsService : INotificationsService { private readonly INotificationsRepository _repository; private readonly IMapper _mapper; + private readonly IConfigurationSection _configuration; + private readonly IConfigurationSection _configurationMail; + private readonly TelegramBotClient _botClient; + private readonly ITelegramBotServiceClient _telegramBotServiceClient; + private readonly MailKit.Net.Smtp.SmtpClient _client; - public NotificationsService(INotificationsRepository repository, IMapper mapper) + public NotificationsService(INotificationsRepository repository, IMapper mapper, IConfiguration configuration, ITelegramBotServiceClient telegramBotServiceClient) { _repository = repository; _mapper = mapper; + _configuration = configuration.GetSection("Telegram"); + _configurationMail = configuration.GetSection("Notification"); + _telegramBotServiceClient = telegramBotServiceClient; + _botClient = new TelegramBotClient(_configuration["Token"]); + _client = new MailKit.Net.Smtp.SmtpClient(); } public async Task AddNotificationAsync(Notification notification) @@ -38,5 +55,43 @@ public async Task MarkAsSeenAsync(string userId, long[] notificationIds) await _repository.UpdateBatchAsync(userId, notificationIds, t => new Notification {HasSeen = true}); } + + public async Task SendEmailAsync(Notification notification, string email, string topic) + { + var emailMessage = new MimeMessage(); + + emailMessage.From.Add(new MailboxAddress("HwProj-2.0.1", _configurationMail["Mail"])); + emailMessage.To.Add(new MailboxAddress("", email)); + emailMessage.Subject = topic; + emailMessage.Body = new TextPart(MimeKit.Text.TextFormat.Html) + { + Text = notification.Body + }; + + await _client.ConnectAsync(_configurationMail["ConnectSite"], 465, true); + await _client.AuthenticateAsync(_configurationMail["Mail"], _configurationMail["Password"]); + await _client.SendAsync(emailMessage); + + await _client.DisconnectAsync(true); + + } + + public async Task SendTelegramMessageAsync(Notification notification) + { + var (checkUser, user) = await _telegramBotServiceClient.CheckUser(notification.Owner); + if (checkUser) + { + await _botClient.SendTextMessageAsync(user, notification.Body, ParseMode.Markdown); + } + } + + public async Task SendTelegramMessageWithKeyboardAsync(Notification notification, InlineKeyboardMarkup inlineKeyboard) + { + var (checkUser, user) = await _telegramBotServiceClient.CheckUser(notification.Owner); + if (checkUser) + { + await _botClient.SendTextMessageAsync(user, notification.Body, ParseMode.Markdown, replyMarkup:inlineKeyboard); + } + } } } \ No newline at end of file diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/Startup.cs b/HwProj.NotificationsService/HwProj.NotificationsService.API/Startup.cs index 16c73e160..04ae3d4ab 100644 --- a/HwProj.NotificationsService/HwProj.NotificationsService.API/Startup.cs +++ b/HwProj.NotificationsService/HwProj.NotificationsService.API/Startup.cs @@ -1,4 +1,10 @@ -using HwProj.AuthService.API.Events; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using System.Net.Http; +using HwProj.AuthService.API.Events; using HwProj.AuthService.Client; using HwProj.EventBus.Client.Interfaces; using HwProj.NotificationsService.API.EventHandlers; @@ -16,6 +22,8 @@ using HwProj.CoursesService.Client; using HwProj.SolutionsService.API.Events; using HwProj.SolutionsService.Client; +using HwProj.TelegramBotService.API.Events; +using HwProj.TelegramBotService.Client; using UpdateTaskMaxRatingEvent = HwProj.CoursesService.API.Events.UpdateTaskMaxRatingEvent; namespace HwProj.NotificationsService.API @@ -31,11 +39,12 @@ public Startup(IConfiguration configuration) public void ConfigureServices(IServiceCollection services) { - var connectionString = ConnectionString.GetConnectionString(Configuration); + var connectionString = ConnectionString.GetConnectionString(Configuration); services.AddDbContext(options => options.UseSqlServer(connectionString)); services.AddScoped(); services.AddScoped(); services.AddEventBus(Configuration); + services.AddTransient, ConfirmTelegramBotEventHandler>(); services.AddTransient, RegisterEventHandler>(); services.AddTransient, RateEventHandler>(); services.AddTransient, EditProfileEventHandler>(); @@ -52,12 +61,14 @@ public void ConfigureServices(IServiceCollection services) services.AddAuthServiceClient(); services.AddCoursesServiceClient(); services.AddSolutionServiceClient(); + services.AddTelegramBotClient(); services.ConfigureHwProjServices("Notifications API"); } public void Configure(IApplicationBuilder app, IHostingEnvironment env, IEventBus eventBus) { + eventBus.Subscribe(); eventBus.Subscribe(); eventBus.Subscribe(); eventBus.Subscribe(); diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/appsettings.json b/HwProj.NotificationsService/HwProj.NotificationsService.API/appsettings.json index f28fd9416..01c5bf68f 100644 --- a/HwProj.NotificationsService/HwProj.NotificationsService.API/appsettings.json +++ b/HwProj.NotificationsService/HwProj.NotificationsService.API/appsettings.json @@ -21,6 +21,17 @@ "Auth": "http://localhost:5001", "Courses": "http://localhost:5002", "Notifications": "http://localhost:5006", - "Solutions": "http://localhost:5007" + "Solutions": "http://localhost:5007", + "TelegramBot" : "http://localhost:5009" + }, + "Notification": { + "Mail": "testhwproj@gmail.com", + "ConnectSite": "smtp.gmail.com", + "Password": "HwProj-2.0.1", + "Url": "http://localhost:3000" + }, + "Telegram": { + "Token" : "1921590728:AAFFUK6qijY5IoVPiDWtpTCNc2rSh8Fb7EU", + "Url" : "https://4ba7-92-42-26-35.ngrok.io/" } } diff --git a/HwProj.SolutionsService/HwProj.SolutionsService.API/Events/RateEvent.cs b/HwProj.SolutionsService/HwProj.SolutionsService.API/Events/RateEvent.cs index 9a1d88091..18c9dda47 100644 --- a/HwProj.SolutionsService/HwProj.SolutionsService.API/Events/RateEvent.cs +++ b/HwProj.SolutionsService/HwProj.SolutionsService.API/Events/RateEvent.cs @@ -6,13 +6,16 @@ namespace HwProj.SolutionsService.API.Events { public class RateEvent : Event { - public HomeworkTaskViewModel Task { get; set; } - public SolutionViewModel Solution { get; set; } + public HomeworkTaskViewModel Task { get; } + public SolutionViewModel Solution { get; } + + public long SolutionId { get; } - public RateEvent(HomeworkTaskViewModel task, SolutionViewModel solution) + public RateEvent(HomeworkTaskViewModel task, SolutionViewModel solution, long solutionId) { Task = task; Solution = solution; + SolutionId = solutionId; } } } diff --git a/HwProj.SolutionsService/HwProj.SolutionsService.API/Services/SolutionsService.cs b/HwProj.SolutionsService/HwProj.SolutionsService.API/Services/SolutionsService.cs index 84e17aa3f..0c28a736d 100644 --- a/HwProj.SolutionsService/HwProj.SolutionsService.API/Services/SolutionsService.cs +++ b/HwProj.SolutionsService/HwProj.SolutionsService.API/Services/SolutionsService.cs @@ -22,7 +22,9 @@ public class SolutionsService : ISolutionsService private readonly IMapper _mapper; private readonly ICoursesServiceClient _coursesServiceClient; private readonly IAuthServiceClient _authServiceClient; - public SolutionsService(ISolutionsRepository solutionsRepository, IEventBus eventBus, IMapper mapper, ICoursesServiceClient coursesServiceClient, IAuthServiceClient authServiceClient) + + public SolutionsService(ISolutionsRepository solutionsRepository, IEventBus eventBus, IMapper mapper, + ICoursesServiceClient coursesServiceClient, IAuthServiceClient authServiceClient) { _solutionsRepository = solutionsRepository; _eventBus = eventBus; @@ -47,12 +49,12 @@ public async Task GetTaskSolutionsFromStudentAsync(long taskId, stri .FindAll(solution => solution.TaskId == taskId && solution.StudentId == studentId) .ToArrayAsync(); } - - + + public async Task PostOrUpdateAsync(long taskId, Solution solution) { solution.PublicationDate = DateTime.UtcNow; - var allSolutionsForTask= await GetTaskSolutionsFromStudentAsync(taskId, solution.StudentId); + var allSolutionsForTask = await GetTaskSolutionsFromStudentAsync(taskId, solution.StudentId); var currentSolution = allSolutionsForTask.FirstOrDefault(s => s.Id == solution.Id); var solutionModel = _mapper.Map(solution); var task = await _coursesServiceClient.GetTask(solution.TaskId); @@ -69,7 +71,7 @@ public async Task PostOrUpdateAsync(long taskId, Solution solution) var id = await _solutionsRepository.AddAsync(solution); return id; } - + await _solutionsRepository.UpdateAsync(currentSolution.Id, s => new Solution() { State = SolutionState.Rated, @@ -90,8 +92,9 @@ public async Task RateSolutionAsync(long solutionId, int newRating, string lectu { var solutionModel = _mapper.Map(solution); var taskModel = _mapper.Map(task); - _eventBus.Publish(new RateEvent(taskModel, solutionModel)); - var state = newRating >= task.MaxRating ? SolutionState.Final : SolutionState.Rated; + _eventBus.Publish(new RateEvent(taskModel, solutionModel, solution.Id)); + SolutionState state = newRating >= task.MaxRating ? SolutionState.Final : SolutionState.Rated; + await _solutionsRepository.RateSolutionAsync(solutionId, state, newRating, lecturerComment); } } diff --git a/HwProj.TelegramBot/HwProj.TelegramBotService.API/.dockerignore b/HwProj.TelegramBot/HwProj.TelegramBotService.API/.dockerignore new file mode 100644 index 000000000..cd967fc3a --- /dev/null +++ b/HwProj.TelegramBot/HwProj.TelegramBotService.API/.dockerignore @@ -0,0 +1,25 @@ +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/.idea +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/azds.yaml +**/bin +**/charts +**/docker-compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +LICENSE +README.md \ No newline at end of file diff --git a/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/CheckCodeCommand.cs b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/CheckCodeCommand.cs new file mode 100644 index 000000000..382896b9b --- /dev/null +++ b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/CheckCodeCommand.cs @@ -0,0 +1,31 @@ +using System.Threading.Tasks; +using HwProj.TelegramBotService.API.Service; +using Telegram.Bot; +using Telegram.Bot.Types; +using Telegram.Bot.Types.ReplyMarkups; + +namespace HwProj.TelegramBotService.API.Commands +{ + public class CheckCodeCommand : Commands + { + private readonly TelegramBotClient _botClient; + private readonly IUserTelegramService _userTelegramService; + + public CheckCodeCommand(TelegramBot telegramBot, IUserTelegramService userTelegramService) + { + _botClient = telegramBot.GetBot().Result; + _userTelegramService = userTelegramService; + } + + public override string Name => CommandNames.CheckCodeCommand; + + public override async Task ExecuteAsync(Update update) + { + var user = await _userTelegramService.AddFinishUser(update.Message.Chat.Id, update.Message.Text); + + var inlineKeyboard = new InlineKeyboardMarkup(GetButton("Мои курсы", "/courses")); + + await _botClient.SendTextMessageAsync(user.ChatId, "Добро пожаловать в Hw-ProjBot!", replyMarkup: inlineKeyboard); + } + } +} \ No newline at end of file diff --git a/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/CommandNames.cs b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/CommandNames.cs new file mode 100644 index 000000000..5a1ae8f43 --- /dev/null +++ b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/CommandNames.cs @@ -0,0 +1,20 @@ +namespace HwProj.TelegramBotService.API.Commands +{ + public static class CommandNames + { + public const string StartCommand = "/start"; + public const string GetCourses = "/courses"; // /courses {courseId} + public const string GetHomeworks = "/homeworks"; // /homeworks {courseId} + public const string GetTasks = "/task"; // /task {homeworksId} + public const string GetTaskInfo = "/taskinfo"; // /taskinfo {taskId} + public const string GetSolutionsFromTask = "/solutions"; // /solutions {taskId} + public const string GetSolutionInfo = "/solutioninfo"; // /solutioninfo {solutionId} + public const string GetStatistics = "/statistics"; // /statistics {courseId} + public const string WaitCodeCommand = "wait_code"; + public const string CheckCodeCommand = "check_code"; + public const string ErrorCommand = "error_response"; + public const string WaitPullRequest = "wait_pull_request"; + public const string SendSolution = "send_solution"; + public const string SaveUrlAndWaitComment = "wait_comment"; + } +} \ No newline at end of file diff --git a/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/Commands.cs b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/Commands.cs new file mode 100644 index 000000000..cae490620 --- /dev/null +++ b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/Commands.cs @@ -0,0 +1,20 @@ +using System.Threading.Tasks; +using Telegram.Bot.Types; +using Telegram.Bot.Types.ReplyMarkups; + +namespace HwProj.TelegramBotService.API.Commands +{ + public abstract class Commands + { + public abstract string Name { get; } + + public abstract Task ExecuteAsync(Update update); + + protected InlineKeyboardButton GetButton(string text, string callbackData) + => new() + { + Text = text, + CallbackData = callbackData + }; + } +} \ No newline at end of file diff --git a/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/ErrorCommand.cs b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/ErrorCommand.cs new file mode 100644 index 000000000..3ee58c8b6 --- /dev/null +++ b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/ErrorCommand.cs @@ -0,0 +1,29 @@ +using System.Threading.Tasks; +using HwProj.TelegramBotService.API.Service; +using Telegram.Bot; +using Telegram.Bot.Types; +using Telegram.Bot.Types.Enums; + +namespace HwProj.TelegramBotService.API.Commands +{ + public class ErrorCommand : Commands + { + private readonly TelegramBotClient _botClient; + private readonly IUserTelegramService _userTelegramService; + + public ErrorCommand(TelegramBot telegramBot, IUserTelegramService userTelegramService) + { + _botClient = telegramBot.GetBot().Result; + _userTelegramService = userTelegramService; + } + + public override string Name => CommandNames.ErrorCommand; + + public override async Task ExecuteAsync(Update update) + { + var user = await _userTelegramService.UserByUpdate(update); + + await _botClient.SendTextMessageAsync(user.ChatId, "Повторите ещё раз!", ParseMode.Markdown); + } + } +} \ No newline at end of file diff --git a/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/GetCourses.cs b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/GetCourses.cs new file mode 100644 index 000000000..932437b49 --- /dev/null +++ b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/GetCourses.cs @@ -0,0 +1,46 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using HwProj.CoursesService.Client; +using HwProj.TelegramBotService.API.Service; +using Telegram.Bot; +using Telegram.Bot.Types; +using Telegram.Bot.Types.Enums; +using Telegram.Bot.Types.ReplyMarkups; + +namespace HwProj.TelegramBotService.API.Commands +{ + public class GetCourses : Commands + { + private readonly ICoursesServiceClient _coursesServiceClient; + private readonly TelegramBotClient _botClient; + private readonly IUserTelegramService _userTelegramService; + + public GetCourses(TelegramBot telegramBot, ICoursesServiceClient coursesServiceClient, IUserTelegramService userTelegramService) + { + _botClient = telegramBot.GetBot().Result; + _coursesServiceClient = coursesServiceClient; + _userTelegramService = userTelegramService; + } + + public override string Name => CommandNames.GetCourses; + + public override async Task ExecuteAsync(Update update) + { + var user = await _userTelegramService.UserByUpdate(update); + var courses = _coursesServiceClient.GetAllUserCourses(user.AccountId).Result; + + await _botClient.SendTextMessageAsync(user.ChatId, "*Выберите курс для просмотра домашних работ или статистики:*", ParseMode.Markdown); + + foreach (var course in courses) + { + var rows = new List(); + var cols = new List(); + cols.Add(GetButton("Домашние работы", $"/homeworks {course.Id}")); + cols.Add(GetButton("Cтатистика", $"/statistics {course.Id}")); + rows.Add(cols.ToArray()); + var keyboardMarkup = new InlineKeyboardMarkup(rows.ToArray()); + await _botClient.SendTextMessageAsync(user.ChatId, "Курс:" + $" {course.Name}", ParseMode.Html, replyMarkup:keyboardMarkup); + } + } + } +} \ No newline at end of file diff --git a/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/GetHomeworks.cs b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/GetHomeworks.cs new file mode 100644 index 000000000..a27bdcc8c --- /dev/null +++ b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/GetHomeworks.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using HwProj.CoursesService.Client; +using HwProj.TelegramBotService.API.Service; +using Telegram.Bot; +using Telegram.Bot.Types; +using Telegram.Bot.Types.Enums; +using Telegram.Bot.Types.ReplyMarkups; + +namespace HwProj.TelegramBotService.API.Commands +{ + public class GetHomeworks : Commands + { + private readonly ICoursesServiceClient _coursesServiceClient; + private readonly TelegramBotClient _botClient; + private readonly IUserTelegramService _userTelegramService; + + public GetHomeworks(TelegramBot telegramBot, ICoursesServiceClient coursesServiceClient, IUserTelegramService userTelegramService) + { + _botClient = telegramBot.GetBot().Result; + _coursesServiceClient = coursesServiceClient; + _userTelegramService = userTelegramService; + } + + public override string Name => CommandNames.GetHomeworks; + + public override async Task ExecuteAsync(Update update) + { + var user = await _userTelegramService.UserByUpdate(update); + var message = update.CallbackQuery.Data; + var text = message.Split(' '); + var homeworks = _coursesServiceClient.GetAllHomeworkByCourse(Int32.Parse(text[1])).Result; + var course = _coursesServiceClient.GetCourseById(Int32.Parse(text[1]), user.AccountId).Result; + + var rows = new List(); + var cols = new List(); + for (var i = 1; i < homeworks.Length + 1; i++) + { + cols.Add(GetButton(homeworks[i - 1].Title, $"/task {homeworks[i - 1].Id}")); + if (i % 3 != 0) continue; + rows.Add(cols.ToArray()); + cols = new List(); + } + if (homeworks.Length < 3) + { + rows.Add(cols.ToArray()); + } + + cols = new List(); + cols.Add(GetButton("Мои курсы", $"/courses")); + rows.Add(cols.ToArray()); + var keyboardMarkup = new InlineKeyboardMarkup(rows.ToArray()); + await _botClient.SendTextMessageAsync( + user.ChatId, + $"Курс: {course.Name}\nВыберите домашнюю работу", + ParseMode.Html, + replyMarkup:keyboardMarkup); + } + } +} \ No newline at end of file diff --git a/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/GetSolutionInfo.cs b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/GetSolutionInfo.cs new file mode 100644 index 000000000..f585d362a --- /dev/null +++ b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/GetSolutionInfo.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using HwProj.CoursesService.Client; +using HwProj.SolutionsService.Client; +using HwProj.TelegramBotService.API.Service; +using Telegram.Bot; +using Telegram.Bot.Types; +using Telegram.Bot.Types.Enums; +using Telegram.Bot.Types.ReplyMarkups; + +namespace HwProj.TelegramBotService.API.Commands +{ + public class GetSolutionInfo : Commands + { + private readonly ISolutionsServiceClient _solutionsServiceClient; + private readonly ICoursesServiceClient _coursesServiceClient; + private readonly TelegramBotClient _botClient; + private readonly IUserTelegramService _userTelegramService; + + public GetSolutionInfo(TelegramBot telegramBot, ISolutionsServiceClient solutionsServiceClient, + IUserTelegramService userTelegramService, ICoursesServiceClient coursesServiceClient) + { + _botClient = telegramBot.GetBot().Result; + _solutionsServiceClient = solutionsServiceClient; + _userTelegramService = userTelegramService; + _coursesServiceClient = coursesServiceClient; + } + + public override string Name => CommandNames.GetSolutionInfo; + + public override async Task ExecuteAsync(Update update) + { + var user = await _userTelegramService.UserByUpdate(update); + var message = update.CallbackQuery.Data; + var text = message.Split(' '); + var solution =_solutionsServiceClient.GetSolutionById(Int32.Parse(text[1])).Result; + var task = _coursesServiceClient.GetTask(solution.TaskId).Result; + var hw = _coursesServiceClient.GetHomework(task.HomeworkId).Result; + + var rows = new List(); + var cols = new List(); + + cols.Add(GetButton($"Решения {task.Title}", $"/solutions {task.Id}")); + cols.Add(GetButton("Мои курсы", $"/courses")); + rows.Add(cols.ToArray()); + cols = new List(); + cols.Add(GetButton("Мои домашки", $"/homeworks {hw.CourseId}")); + cols.Add(GetButton("Мои задачи", $"/task {task.HomeworkId}")); + rows.Add(cols.ToArray()); + cols = new List(); + cols.Add(new InlineKeyboardButton {Text = "Github", Url = solution.GithubUrl}); + rows.Add(cols.ToArray()); + + var keyboardMarkup = new InlineKeyboardMarkup(rows.ToArray()); + + await _botClient.SendTextMessageAsync(user.ChatId, + $"Отзыв преподователя: {solution.LecturerComment}." + + $"\nОценка: {solution.Rating}/{task.MaxRating}.", + ParseMode.Html, + replyMarkup:keyboardMarkup); + } + } +} \ No newline at end of file diff --git a/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/GetSolutionsFromTask.cs b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/GetSolutionsFromTask.cs new file mode 100644 index 000000000..7532f2f8e --- /dev/null +++ b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/GetSolutionsFromTask.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using HwProj.SolutionsService.Client; +using HwProj.TelegramBotService.API.Service; +using Telegram.Bot; +using Telegram.Bot.Types; +using Telegram.Bot.Types.Enums; +using Telegram.Bot.Types.ReplyMarkups; +using HwProj.CoursesService.Client; + +namespace HwProj.TelegramBotService.API.Commands +{ + public class GetSolutionsFromTask: Commands + { + private readonly TelegramBotClient _botClient; + private readonly IUserTelegramService _userTelegramService; + private readonly ISolutionsServiceClient _solutionsServiceClient; + private readonly ICoursesServiceClient _coursesServiceClient; + + public GetSolutionsFromTask(TelegramBot telegramBot, IUserTelegramService userTelegramService, ISolutionsServiceClient solutionsServiceClient, ICoursesServiceClient coursesServiceClient) + { + _botClient = telegramBot.GetBot().Result; + _solutionsServiceClient = solutionsServiceClient; + _userTelegramService = userTelegramService; + _coursesServiceClient = coursesServiceClient; + } + + public override string Name => CommandNames.GetSolutionsFromTask; + + public override async Task ExecuteAsync(Update update) + { + var user = await _userTelegramService.UserByUpdate(update); + var message = update.CallbackQuery.Data; + var text = message.Split(' '); + var solutions = _solutionsServiceClient.GetUserSolution(Int32.Parse(text[1]), user.AccountId).Result; + var task = _coursesServiceClient.GetTask(Int32.Parse(text[1])).Result; + var hw = _coursesServiceClient.GetHomework(task.HomeworkId).Result; + var course = _coursesServiceClient.GetCourseById(hw.CourseId, user.AccountId).Result; + + var rows = new List(); + var cols = new List(); + for (var i = 1; i < solutions.Length + 1; i++) + { + cols.Add(GetButton($"Попытка {i}", $"/solutioninfo {solutions[i - 1].Id}")); + if (i % 3 != 0) continue; + rows.Add(cols.ToArray()); + cols = new List(); + } + + rows.Add(cols.ToArray()); + cols = new List(); + cols.Add(GetButton("Мои курсы", $"/courses")); + cols.Add(GetButton("Мои домашки", $"/homeworks {hw.CourseId}")); + cols.Add(GetButton("Мои задачи", $"/task {task.HomeworkId}")); + rows.Add(cols.ToArray()); + + var keyboardMarkup = new InlineKeyboardMarkup(rows.ToArray()); + + await _botClient.SendTextMessageAsync(user.ChatId, + $"Курс: {course.Name}" + + $"\nДомашнаяя работа: {hw.Title}" + + $"\nЗадача: {task.Title}" + + "\nВыберите решение:", + ParseMode.Html, + replyMarkup : keyboardMarkup); + } + } +} \ No newline at end of file diff --git a/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/GetStatistics.cs b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/GetStatistics.cs new file mode 100644 index 000000000..dadb4e491 --- /dev/null +++ b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/GetStatistics.cs @@ -0,0 +1,69 @@ +using System; +using System.Linq; +using System.Threading.Tasks; +using HwProj.CoursesService.Client; +using HwProj.SolutionsService.Client; +using HwProj.TelegramBotService.API.Service; +using Telegram.Bot; +using Telegram.Bot.Types; +using Telegram.Bot.Types.Enums; +using Telegram.Bot.Types.ReplyMarkups; + +namespace HwProj.TelegramBotService.API.Commands +{ + public class GetStatistics: Commands + { + private readonly TelegramBotClient _botClient; + private readonly IUserTelegramService _userTelegramService; + private readonly ISolutionsServiceClient _solutionsServiceClient; + private readonly ICoursesServiceClient _coursesServiceClient; + + public GetStatistics(TelegramBot telegramBot, IUserTelegramService userTelegramService, ICoursesServiceClient coursesServiceClient, ISolutionsServiceClient solutionsServiceClient) + { + _botClient = telegramBot.GetBot().Result; + _userTelegramService = userTelegramService; + _coursesServiceClient = coursesServiceClient; + _solutionsServiceClient = solutionsServiceClient; + } + + public override string Name => CommandNames.GetStatistics; + + public override async Task ExecuteAsync(Update update) + { + var user = await _userTelegramService.UserByUpdate(update); + var message = update.CallbackQuery.Data; + var text = message.Split(' '); + var course = _coursesServiceClient.GetCourseById(Int64.Parse(text[1]), user.AccountId).Result; + var statistics = _solutionsServiceClient.GetCourseStatistics(course.Id, course.MentorIds.Split("/")[0]).Result; + var statistic = statistics.First(cm => cm.Id == user.AccountId); + int maxRating = 0; + int? studentRating = 0; + foreach (var hw in statistic.Homeworks) + { + foreach (var task in hw.Tasks) + { + studentRating += task.Solution.Max(cm => cm.Rating); + } + } + + var hwModel = _coursesServiceClient.GetAllHomeworkByCourse(course.Id).Result; + foreach (var hw in hwModel) + { + maxRating += hw.Tasks.Max(cm => cm.MaxRating); + } + + if (studentRating == null) + { + studentRating = 0; + } + + var inlineKeyboard = new InlineKeyboardMarkup(GetButton("Мои курсы", "/courses")); + + await _botClient.SendTextMessageAsync(user.ChatId, + $"Курс: {course.Name}." + + $"\nБаллы: {studentRating}/{maxRating}", + ParseMode.Html, + replyMarkup:inlineKeyboard); + } + } +} \ No newline at end of file diff --git a/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/GetTaskInfo.cs b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/GetTaskInfo.cs new file mode 100644 index 000000000..3a818942a --- /dev/null +++ b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/GetTaskInfo.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using HwProj.CoursesService.Client; +using HwProj.TelegramBotService.API.Service; +using Telegram.Bot; +using Telegram.Bot.Types; +using Telegram.Bot.Types.Enums; +using Telegram.Bot.Types.ReplyMarkups; + +namespace HwProj.TelegramBotService.API.Commands +{ + public class GetTaskInfo : Commands + { + private readonly ICoursesServiceClient _coursesServiceClient; + private readonly TelegramBotClient _botClient; + private readonly IUserTelegramService _userTelegramService; + + public GetTaskInfo(TelegramBot telegramBot, ICoursesServiceClient coursesServiceClient, + IUserTelegramService userTelegramService) + { + _botClient = telegramBot.GetBot().Result; + _coursesServiceClient = coursesServiceClient; + _userTelegramService = userTelegramService; + } + + public override string Name => CommandNames.GetTaskInfo; + + public override async Task ExecuteAsync(Update update) + { + var user = await _userTelegramService.UserByUpdate(update); + var message = update.CallbackQuery.Data; + var text = message.Split(' '); + var task = _coursesServiceClient.GetTask(Int64.Parse(text[1])).Result; + var hw = _coursesServiceClient.GetHomework(task.HomeworkId).Result; + + var rows = new List(); + var cols = new List(); + cols.Add(GetButton($"Решения {task.Title}", $"/solutions {task.Id}")); + rows.Add(cols.ToArray()); + cols = new List(); + cols.Add(GetButton("Мои курсы", $"/courses")); + cols.Add(GetButton("Мои домашки", $"/homeworks {hw.CourseId}")); + cols.Add(GetButton("Мои задачи", $"/task {task.HomeworkId}")); + rows.Add(cols.ToArray()); + cols = new List(); + cols.Add(GetButton($"Отправить решение {task.Title}", $"wait_pull_request {task.Id}")); + rows.Add(cols.ToArray()); + + var keyboardMarkup = new InlineKeyboardMarkup(rows.ToArray()); + + await _botClient.SendTextMessageAsync(user.ChatId, + $"Название {task.Title}." + + $"\nОписание: {task.Description}." + + $"\nДата публикации: {task.PublicationDate.Date}." + + $"\nДедлайн: {task.DeadlineDate}." + + $"\nМаксимальный балл: {task.MaxRating}.", + ParseMode.Html, + replyMarkup:keyboardMarkup); + } + } +} \ No newline at end of file diff --git a/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/GetTasks.cs b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/GetTasks.cs new file mode 100644 index 000000000..b9e1a17fa --- /dev/null +++ b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/GetTasks.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using HwProj.CoursesService.Client; +using HwProj.TelegramBotService.API.Service; +using Telegram.Bot; +using Telegram.Bot.Types; +using Telegram.Bot.Types.Enums; +using Telegram.Bot.Types.ReplyMarkups; + +namespace HwProj.TelegramBotService.API.Commands +{ + public class GetTasks : Commands + { + private readonly ICoursesServiceClient _coursesServiceClient; + private readonly TelegramBotClient _botClient; + private readonly IUserTelegramService _userTelegramService; + + public GetTasks(TelegramBot telegramBot, ICoursesServiceClient coursesServiceClient, + IUserTelegramService userTelegramService) + { + _botClient = telegramBot.GetBot().Result; + _coursesServiceClient = coursesServiceClient; + _userTelegramService = userTelegramService; + } + + public override string Name => CommandNames.GetTasks; + + public override async Task ExecuteAsync(Update update) + { + var user = await _userTelegramService.UserByUpdate(update); + var message = update.CallbackQuery.Data; + var text = message.Split(' '); + var hw = _coursesServiceClient.GetHomework(Int32.Parse(text[1])).Result; + var course = _coursesServiceClient.GetCourseById(hw.CourseId, user.AccountId).Result; + var tasks = hw.Tasks.ToArray(); + var rows = new List(); + var cols = new List(); + for (var i = 1; i < tasks.Length + 1; i++) + { + cols.Add(GetButton(tasks[i - 1].Title, $"/taskinfo {tasks[i - 1].Id}")); + if (i % 3 != 0) continue; + rows.Add(cols.ToArray()); + cols = new List(); + } + + if (tasks.Length < 3) + { + rows.Add(cols.ToArray()); + } + + cols = new List(); + cols.Add(GetButton("Мои курсы", $"/courses")); + cols.Add(GetButton("Мои домашки", $"/homeworks {hw.CourseId}")); + rows.Add(cols.ToArray()); + + var keyboardMarkup = new InlineKeyboardMarkup(rows.ToArray()); + await _botClient.SendTextMessageAsync( + user.ChatId, + $"Курс: {course.Name}" + + $"\nHomework: {hw.Title}" + + $"\nОписание: {hw.Description}" + + "\nВыберите задачу:", + ParseMode.Html, + replyMarkup:keyboardMarkup); + } + } +} \ No newline at end of file diff --git a/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/SaveUrlAndWaitComment.cs b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/SaveUrlAndWaitComment.cs new file mode 100644 index 000000000..26052ad03 --- /dev/null +++ b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/SaveUrlAndWaitComment.cs @@ -0,0 +1,34 @@ +using System; +using System.Threading.Tasks; +using HwProj.TelegramBotService.API.Service; +using Telegram.Bot; +using Telegram.Bot.Types; +using Telegram.Bot.Types.Enums; + +namespace HwProj.TelegramBotService.API.Commands +{ + public class SaveUrlAndWaitComment : Commands + { + private readonly TelegramBotClient _botClient; + private readonly IUserTelegramService _userTelegramService; + + public SaveUrlAndWaitComment(TelegramBot telegramBot, IUserTelegramService userTelegramService) + { + _botClient = telegramBot.GetBot().Result; + _userTelegramService = userTelegramService; + } + + public override string Name => CommandNames.SaveUrlAndWaitComment; + + public override async Task ExecuteAsync(Update update) + { + var message = update.Message.Text; + + + var user = await _userTelegramService.AddGitHubUrlToTask(update, message); + + await _botClient.SendTextMessageAsync(user.ChatId, "Добавьте комментарий к решению.", + ParseMode.Markdown); + } + } +} \ No newline at end of file diff --git a/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/SendSolution.cs b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/SendSolution.cs new file mode 100644 index 000000000..56dbd9e02 --- /dev/null +++ b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/SendSolution.cs @@ -0,0 +1,47 @@ +using System; +using System.Threading.Tasks; +using HwProj.Models.SolutionsService; +using HwProj.SolutionsService.Client; +using HwProj.TelegramBotService.API.Service; +using Telegram.Bot; +using Telegram.Bot.Types; +using Telegram.Bot.Types.Enums; + +namespace HwProj.TelegramBotService.API.Commands +{ + public class SendSolution: Commands + { + private readonly TelegramBotClient _botClient; + private readonly IUserTelegramService _userTelegramService; + private readonly ISolutionsServiceClient _solutionsService; + + public SendSolution(TelegramBot telegramBot, IUserTelegramService userTelegramService, ISolutionsServiceClient solutionsService) + { + _botClient = telegramBot.GetBot().Result; + _userTelegramService = userTelegramService; + _solutionsService = solutionsService; + } + + public override string Name => CommandNames.SendSolution; + + public override async Task ExecuteAsync(Update update) + { + var user = await _userTelegramService.UserByUpdate(update); + var message = update.Message.Text; + + var solutionModel = new SolutionViewModel + { + GithubUrl = user.GitHubUrl, + Comment = message, + StudentId = user.AccountId, + PublicationDate = DateTime.Now, + LecturerComment = "" + }; + + await _solutionsService.PostSolution(solutionModel, Convert.ToInt64(user.TaskIdToSend)); + + await _botClient.SendTextMessageAsync(user.ChatId, "Решение отправлено.", + ParseMode.Markdown); + } + } +} \ No newline at end of file diff --git a/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/StartCommand.cs b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/StartCommand.cs new file mode 100644 index 000000000..02973c424 --- /dev/null +++ b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/StartCommand.cs @@ -0,0 +1,32 @@ +using System.Threading.Tasks; +using HwProj.TelegramBotService.API.Service; +using Telegram.Bot; +using Telegram.Bot.Types; +using Telegram.Bot.Types.Enums; + +namespace HwProj.TelegramBotService.API.Commands +{ + public class StartCommand : Commands + { + private readonly TelegramBotClient _botClient; + private readonly IUserTelegramService _userTelegramService; + + public StartCommand(TelegramBot telegramBot, IUserTelegramService userTelegramService) + { + _botClient = telegramBot.GetBot().Result; + _userTelegramService = userTelegramService; + } + + public override string Name => CommandNames.StartCommand; + + public override async Task ExecuteAsync(Update update) + { + await _userTelegramService.DeleteUser(update); + + var user = await _userTelegramService.CreateUser(update.Message.Chat.Id); + + await _botClient.SendTextMessageAsync(user.ChatId, "Добро пожаловать!\nВведите ваш e-mail на Hw-Proj2.0.1", + ParseMode.Markdown); + } + } +} \ No newline at end of file diff --git a/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/WaitCodeCommand.cs b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/WaitCodeCommand.cs new file mode 100644 index 000000000..4217d28d7 --- /dev/null +++ b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/WaitCodeCommand.cs @@ -0,0 +1,36 @@ +using System.Threading.Tasks; +using HwProj.TelegramBotService.API.Service; +using Telegram.Bot; +using Telegram.Bot.Types; +using Telegram.Bot.Types.Enums; + +namespace HwProj.TelegramBotService.API.Commands +{ + public class WaitCodeCommand : Commands + { + private readonly TelegramBotClient _botClient; + private readonly IUserTelegramService _userTelegramService; + + public WaitCodeCommand(TelegramBot telegramBot, IUserTelegramService userTelegramService) + { + _botClient = telegramBot.GetBot().Result; + _userTelegramService = userTelegramService; + } + + public override string Name => CommandNames.WaitCodeCommand; + + public override async Task ExecuteAsync(Update update) + { + var user = await _userTelegramService.AddEmailToUser(update.Message.Chat.Id, update.Message?.Text); + + if (user == null) + { + await _botClient.SendTextMessageAsync(update.Message.Chat.Id, + "E-mail не зарегистрирован на Hw-Proj2.0.1." + + "\nВведите /start", ParseMode.Markdown); + } + + await _botClient.SendTextMessageAsync(user.ChatId, "Ваш код отправлен.\nВведите его:", ParseMode.Markdown); + } + } +} \ No newline at end of file diff --git a/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/WaitPullRequest.cs b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/WaitPullRequest.cs new file mode 100644 index 000000000..fc119b1a6 --- /dev/null +++ b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Commands/WaitPullRequest.cs @@ -0,0 +1,36 @@ +using System; +using System.Threading.Tasks; +using HwProj.Models.TelegramBotService; +using HwProj.SolutionsService.Client; +using HwProj.TelegramBotService.API.Service; +using Telegram.Bot; +using Telegram.Bot.Types; +using Telegram.Bot.Types.Enums; + +namespace HwProj.TelegramBotService.API.Commands +{ + public class WaitPullRequest : Commands + { + private readonly TelegramBotClient _botClient; + private readonly IUserTelegramService _userTelegramService; + + public WaitPullRequest(TelegramBot telegramBot, IUserTelegramService userTelegramService) + { + _botClient = telegramBot.GetBot().Result; + _userTelegramService = userTelegramService; + } + + public override string Name => CommandNames.WaitPullRequest; + + public override async Task ExecuteAsync(Update update) + { + var message = update.CallbackQuery.Data; + var text = message.Split(' '); + + var user = await _userTelegramService.AddTaskIdAndWaitPullRequest(update, Int64.Parse(text[1])); + + await _botClient.SendTextMessageAsync(user.ChatId, "Отправьте ссылку на pull request.", + ParseMode.Markdown); + } + } +} \ No newline at end of file diff --git a/HwProj.TelegramBot/HwProj.TelegramBotService.API/Controllers/TelegramBotController.cs b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Controllers/TelegramBotController.cs new file mode 100644 index 000000000..48d1ebb25 --- /dev/null +++ b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Controllers/TelegramBotController.cs @@ -0,0 +1,43 @@ +using System; +using System.Threading.Tasks; +using HwProj.Models.TelegramBotService; +using HwProj.TelegramBotService.API.Models; +using HwProj.TelegramBotService.API.Service; +using Microsoft.AspNetCore.Mvc; +using Telegram.Bot.Types; + +namespace HwProj.TelegramBotService.API.Controllers +{ + [ApiController] + [Route("api/[controller]")] + public class TelegramBotController : Controller + { + private readonly ICommandService _commandService; + private readonly IUserTelegramService _userTelegramService; + + public TelegramBotController(ICommandService commandService, IUserTelegramService userTelegramService) + { + _commandService = commandService; + _userTelegramService = userTelegramService; + } + + [HttpPost] + public async Task Update([FromBody] Update update) + { + + if (update?.Message?.Chat == null && update?.CallbackQuery == null) + { + return Ok(); + } + await _commandService.Execute(update); + return Ok(); + } + + [HttpGet("check/{studentId}")] + public async Task CheckUserTelegram(string studentId) + { + var response = await _userTelegramService.CheckTelegramUserModelByStudentId(studentId); + return Ok(response); + } + } +} \ No newline at end of file diff --git a/HwProj.TelegramBot/HwProj.TelegramBotService.API/Dockerfile b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Dockerfile new file mode 100644 index 000000000..de38d5668 --- /dev/null +++ b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Dockerfile @@ -0,0 +1,20 @@ +FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base +WORKDIR /app +EXPOSE 80 +EXPOSE 443 + +FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build +WORKDIR /src +COPY ["HwProj.TelegramBot/HwProj.TelegramBotAPI/HwProj.TelegramBotAPI.csproj", "HwProj.TelegramBotAPI/"] +RUN dotnet restore "HwProj.TelegramBot/HwProj.TelegramBotAPI/HwProj.TelegramBotAPI.csproj" +COPY . . +WORKDIR "/src/HwProj.TelegramBotAPI" +RUN dotnet build "HwProj.TelegramBotAPI.csproj" -c Release -o /app/build + +FROM build AS publish +RUN dotnet publish "HwProj.TelegramBotAPI.csproj" -c Release -o /app/publish + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "HwProj.TelegramBotAPI.dll"] diff --git a/HwProj.TelegramBot/HwProj.TelegramBotService.API/Events/ConfirmTelegramBotEvent.cs b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Events/ConfirmTelegramBotEvent.cs new file mode 100644 index 000000000..70ee043b4 --- /dev/null +++ b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Events/ConfirmTelegramBotEvent.cs @@ -0,0 +1,19 @@ +using HwProj.EventBus.Client; +using HwProj.Models.TelegramBotService; +using HwProj.TelegramBotService.API.Models; + +namespace HwProj.TelegramBotService.API.Events +{ + public class ConfirmTelegramBotEvent : Event + { + public string StudentId { get; } + + public string Code { get; } + + public ConfirmTelegramBotEvent(string studentId, string code) + { + StudentId = studentId; + Code = code; + } + } +} \ No newline at end of file diff --git a/HwProj.TelegramBot/HwProj.TelegramBotService.API/HwProj.TelegramBotService.API.csproj b/HwProj.TelegramBot/HwProj.TelegramBotService.API/HwProj.TelegramBotService.API.csproj new file mode 100644 index 000000000..8358aee3d --- /dev/null +++ b/HwProj.TelegramBot/HwProj.TelegramBotService.API/HwProj.TelegramBotService.API.csproj @@ -0,0 +1,29 @@ + + + + netcoreapp2.2 + Windows + latest + HwProj.TelegramBotService.API + + + + + + + + + + + + + + + + + + + + + + diff --git a/HwProj.TelegramBot/HwProj.TelegramBotService.API/Models/TelegramBotContext.cs b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Models/TelegramBotContext.cs new file mode 100644 index 000000000..c71ca70a7 --- /dev/null +++ b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Models/TelegramBotContext.cs @@ -0,0 +1,17 @@ +using HwProj.Models.TelegramBotService; +using Microsoft.EntityFrameworkCore; + +namespace HwProj.TelegramBotService.API.Models +{ + public sealed class TelegramBotContext : DbContext + { + public DbSet TelegramUser { get; set; } + + public TelegramBotContext(DbContextOptions options) + : base(options) + { + Database.EnsureCreated(); + } + + } +} \ No newline at end of file diff --git a/HwProj.TelegramBot/HwProj.TelegramBotService.API/Program.cs b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Program.cs new file mode 100644 index 000000000..adf41576c --- /dev/null +++ b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Program.cs @@ -0,0 +1,17 @@ +using Microsoft.AspNetCore; +using Microsoft.AspNetCore.Hosting; + +namespace HwProj.TelegramBotService.API +{ + public class Program + { + public static void Main(string[] args) + { + CreateWebHostBuilder(args).Build().Run(); + } + + public static IWebHostBuilder CreateWebHostBuilder(string[] args) => + WebHost.CreateDefaultBuilder(args) + .UseStartup(); + } +} \ No newline at end of file diff --git a/HwProj.TelegramBot/HwProj.TelegramBotService.API/Properties/launchSettings.json b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Properties/launchSettings.json new file mode 100644 index 000000000..40af5352c --- /dev/null +++ b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Properties/launchSettings.json @@ -0,0 +1,31 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:1307", + "sslPort": 44300 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "HwProj.TelegramBotAPI": { + "commandName": "Project", + "launchBrowser": true, + "launchUrl": "swagger", + + "applicationUrl": "http://localhost:5009", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} \ No newline at end of file diff --git a/HwProj.TelegramBot/HwProj.TelegramBotService.API/Repositories/ITelegramBotRepository.cs b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Repositories/ITelegramBotRepository.cs new file mode 100644 index 000000000..158297801 --- /dev/null +++ b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Repositories/ITelegramBotRepository.cs @@ -0,0 +1,14 @@ +using System.Linq; +using System.Threading.Tasks; +using HwProj.Models.TelegramBotService; +using HwProj.Repositories; + +namespace HwProj.TelegramBotService.API.Repositories +{ + public interface ITelegramBotRepository : ICrudRepository + { + IQueryable GetUserTelegramByChatId(long chatId); + + Task GetChatIdByAccountId(string accountId); + } +} \ No newline at end of file diff --git a/HwProj.TelegramBot/HwProj.TelegramBotService.API/Repositories/TelegramBotRepository.cs b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Repositories/TelegramBotRepository.cs new file mode 100644 index 000000000..c463d4c71 --- /dev/null +++ b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Repositories/TelegramBotRepository.cs @@ -0,0 +1,27 @@ +using System.Linq; +using System.Threading.Tasks; +using HwProj.Models.TelegramBotService; +using HwProj.Repositories; +using HwProj.TelegramBotService.API.Models; +using Microsoft.EntityFrameworkCore; + +namespace HwProj.TelegramBotService.API.Repositories +{ + public class TelegramBotRepository : CrudRepository, ITelegramBotRepository + { + public TelegramBotRepository(TelegramBotContext context) + : base(context) + { + } + + public IQueryable GetUserTelegramByChatId(long chatId) + { + return Context.Set().Where(h => h.ChatId == chatId); + } + + public async Task GetChatIdByAccountId(string accountId) + { + return await Context.Set().FirstAsync(h => h.AccountId == accountId); + } + } +} \ No newline at end of file diff --git a/HwProj.TelegramBot/HwProj.TelegramBotService.API/Service/CommandService.cs b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Service/CommandService.cs new file mode 100644 index 000000000..4eeee0a88 --- /dev/null +++ b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Service/CommandService.cs @@ -0,0 +1,107 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using HwProj.TelegramBotService.API.Commands; +using HwProj.TelegramBotService.API.Models; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using Telegram.Bot.Types; +using Telegram.Bot.Types.Enums; + +namespace HwProj.TelegramBotService.API.Service +{ + public class CommandService : ICommandService + { + private readonly TelegramBotContext _context; + private readonly List _commands; + private Commands.Commands _lastCommand; + + public CommandService(IServiceProvider serviceProvider, TelegramBotContext context) + { + _context = context; + _commands = serviceProvider.GetServices().ToList(); + } + + public async Task Execute(Update update) + { + if (update?.Message?.Chat == null && update?.CallbackQuery == null) + { + return; + } + + if (update.Type == UpdateType.Message) + { + var message = update.Message?.Text; + switch (message) + { + case "/start": + await ExecuteCommand(CommandNames.StartCommand, update); + return; + case "/courses": + await ExecuteCommand(CommandNames.GetCourses, update); + return; + } + + var user = _context.TelegramUser.FirstOrDefaultAsync(x => x.ChatId == update.Message.Chat.Id).Result; + switch (user.Operation) + { + case "wait_code": + await ExecuteCommand(CommandNames.WaitCodeCommand, update); + return; + case "check_code": + await ExecuteCommand(CommandNames.CheckCodeCommand, update); + return; + case "wait_url": + await ExecuteCommand(CommandNames.SaveUrlAndWaitComment, update); + return; + case "wait_comment": + await ExecuteCommand(CommandNames.SendSolution, update); + return; + } + } + else if (update.Type == UpdateType.CallbackQuery) + { + var user = _context.TelegramUser.FirstOrDefaultAsync(x => x.ChatId == update.CallbackQuery.Message.Chat.Id).Result; + if (user.IsLecture == false) + { + switch (update.CallbackQuery.Data.Split(' ')[0]) + { + case "/courses": + await ExecuteCommand(CommandNames.GetCourses, update); + return; + case "/homeworks": + await ExecuteCommand(CommandNames.GetHomeworks, update); + return; + case "/statistics": + await ExecuteCommand(CommandNames.GetStatistics, update); + return; + case "/task": + await ExecuteCommand(CommandNames.GetTasks, update); + return; + case "/taskinfo": + await ExecuteCommand(CommandNames.GetTaskInfo, update); + return; + case "/solutions": + await ExecuteCommand(CommandNames.GetSolutionsFromTask, update); + return; + case "/solutioninfo": + await ExecuteCommand(CommandNames.GetSolutionInfo, update); + return; + case "wait_pull_request": + await ExecuteCommand(CommandNames.WaitPullRequest, update); + return; + } + } + } + + await ExecuteCommand(CommandNames.ErrorCommand, update); + } + + private async Task ExecuteCommand(string commandName, Update update) + { + _lastCommand = _commands.First(x=> x.Name == commandName); + await _lastCommand.ExecuteAsync(update); + } + } +} \ No newline at end of file diff --git a/HwProj.TelegramBot/HwProj.TelegramBotService.API/Service/ICommandService.cs b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Service/ICommandService.cs new file mode 100644 index 000000000..162d1d85d --- /dev/null +++ b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Service/ICommandService.cs @@ -0,0 +1,10 @@ +using System.Threading.Tasks; +using Telegram.Bot.Types; + +namespace HwProj.TelegramBotService.API.Service +{ + public interface ICommandService + { + Task Execute(Update update); + } +} \ No newline at end of file diff --git a/HwProj.TelegramBot/HwProj.TelegramBotService.API/Service/IUserTelegramService.cs b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Service/IUserTelegramService.cs new file mode 100644 index 000000000..ab00c60eb --- /dev/null +++ b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Service/IUserTelegramService.cs @@ -0,0 +1,20 @@ +using System.Threading.Tasks; +using HwProj.Models.TelegramBotService; +using HwProj.TelegramBotService.API.Models; +using Telegram.Bot.Types; + +namespace HwProj.TelegramBotService.API.Service +{ + public interface IUserTelegramService + { + Task CreateUser(long chatId); + Task AddEmailToUser(long chatId, string message); + Task AddFinishUser(long chatId, string message); + Task UserByUpdate(Update update); + Task<(bool, long)> CheckTelegramUserModelByStudentId(string studentId); + Task ChatIdByStudentId(string studentId); + Task AddTaskIdAndWaitPullRequest(Update update, long taskId); + Task AddGitHubUrlToTask(Update update, string url); + Task DeleteUser(Update update); + } +} \ No newline at end of file diff --git a/HwProj.TelegramBot/HwProj.TelegramBotService.API/Service/TelegramBot.cs b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Service/TelegramBot.cs new file mode 100644 index 000000000..b7f36f094 --- /dev/null +++ b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Service/TelegramBot.cs @@ -0,0 +1,32 @@ +using System.Threading.Tasks; +using Microsoft.Extensions.Configuration; +using Telegram.Bot; + +namespace HwProj.TelegramBotService.API.Service +{ + public class TelegramBot + { + private readonly IConfiguration _configuration; + private TelegramBotClient _botClient; + + public TelegramBot(IConfiguration configuration) + { + _configuration = configuration; + } + + public async Task GetBot() + { + if (_botClient != null) + { + return _botClient; + } + + _botClient = new TelegramBotClient(_configuration["Token"]); + + var hook = $"{_configuration["Url"]}api/TelegramBot"; + await _botClient.SetWebhookAsync(hook); + + return _botClient; + } + } +} \ No newline at end of file diff --git a/HwProj.TelegramBot/HwProj.TelegramBotService.API/Service/UserTelegramService.cs b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Service/UserTelegramService.cs new file mode 100644 index 000000000..b91e9eaa0 --- /dev/null +++ b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Service/UserTelegramService.cs @@ -0,0 +1,207 @@ +using System; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using HwProj.AuthService.Client; +using HwProj.EventBus.Client.Interfaces; +using HwProj.Models.TelegramBotService; +using HwProj.TelegramBotService.API.Events; +using HwProj.TelegramBotService.API.Models; +using HwProj.TelegramBotService.API.Repositories; +using Microsoft.EntityFrameworkCore; +using Telegram.Bot.Types; + +namespace HwProj.TelegramBotService.API.Service +{ + public class UserTelegramTelegramService : IUserTelegramService + { + private readonly ITelegramBotRepository _telegramBotRepository; + private readonly IAuthServiceClient _authClient; + private readonly IEventBus _eventBus; + + public UserTelegramTelegramService(IAuthServiceClient authClient, IEventBus eventBus, ITelegramBotRepository telegramBotRepository) + { + _authClient = authClient; + _eventBus = eventBus; + _telegramBotRepository = telegramBotRepository; + } + + public async Task CreateUser(long chatId) + { + var random = new Random(); + var chars = "ABCEFGHJKPQRSTXYZ0123456789"; + var code = new StringBuilder(); + code.Append(chars[random.Next(chars.Length)]); + code.Append(chars[random.Next(chars.Length)]); + code.Append(chars[random.Next(chars.Length)]); + code.Append(chars[random.Next(chars.Length)]); + code.Append(chars[random.Next(chars.Length)]); + code.Append(chars[random.Next(chars.Length)]); + var newUser = new UserTelegram + { + ChatId = chatId, + AccountId = null!, + IsLecture = false, + IsRegistered = false, + Code = code.ToString(), + Operation = "wait_code", + }; + var user = await _telegramBotRepository.AddAsync(newUser); + return await _telegramBotRepository.FindAsync(x => x.Id == user); + } + + public async Task AddEmailToUser(long chatId, string message) + { + var user = _telegramBotRepository.GetUserTelegramByChatId(chatId); + var userModel = user.ToArray()[0]; + if (userModel.Operation != "wait_code" || user == null) + { + await _telegramBotRepository.DeleteAsync(userModel.Id); + return null; + } + + var accountId = await _authClient.FindByEmailAsync(message); + var studentModel = await _authClient.GetAccountData(accountId); + userModel.Operation = "check_code"; + userModel.AccountId = accountId; + userModel.IsLecture = studentModel.Role == "Lecture"; + var newUserModel = new UserTelegram + { + ChatId = userModel.ChatId, + AccountId = accountId, + IsLecture = userModel.IsLecture, + IsRegistered = false, + Code = userModel.Code, + Operation = "check_code", + }; + await _telegramBotRepository.UpdateAsync(userModel.Id, x => new UserTelegram + { + ChatId = userModel.ChatId, + AccountId = accountId, + IsLecture = userModel.IsLecture, + IsRegistered = false, + Code = userModel.Code, + Operation = "check_code", + }); + _eventBus.Publish(new ConfirmTelegramBotEvent(userModel.AccountId, userModel.Code)); + return userModel; + } + + public async Task AddFinishUser(long chatId, string message) + { + var user = _telegramBotRepository.GetUserTelegramByChatId(chatId); + var userModel = user.ToArray()[0]; + if (userModel.Operation != "check_code" || userModel.Code != message || user == null) + { + await _telegramBotRepository.DeleteAsync(userModel.Id); + return null; + } + + userModel.Operation = "finish"; + userModel.IsRegistered = true; + var newUserModel = new UserTelegram + { + ChatId = userModel.ChatId, + AccountId = userModel.AccountId, + IsLecture = userModel.IsLecture, + IsRegistered = true, + Code = userModel.Code, + Operation = "finish", + }; + await _telegramBotRepository.UpdateAsync(userModel.Id,x => new UserTelegram + { + ChatId = userModel.ChatId, + AccountId = userModel.AccountId, + IsLecture = userModel.IsLecture, + IsRegistered = true, + Code = userModel.Code, + Operation = "finish", + }); + return userModel; + } + + public async Task UserByUpdate(Update update) + { + var user = update.Message == null + ? await _telegramBotRepository.FindAsync(cm => cm.ChatId ==update.CallbackQuery.Message.Chat.Id) + : await _telegramBotRepository.FindAsync(cm => cm.ChatId ==update.Message.Chat.Id); + var newUserModel = new UserTelegram { + ChatId = user.ChatId, + AccountId = user.AccountId, + IsLecture = user.IsLecture, + IsRegistered = user.IsRegistered, + Code = user.Code, + Operation = "finish", + }; + await _telegramBotRepository.UpdateAsync(user.Id, x => new UserTelegram + { + ChatId = user.ChatId, + AccountId = user.AccountId, + IsLecture = user.IsLecture, + IsRegistered = user.IsRegistered, + Code = user.Code, + Operation = "finish", + }); + return newUserModel; + } + + public async Task<(bool, long)> CheckTelegramUserModelByStudentId(string studentId) + { + var user = await _telegramBotRepository.FindAsync(cm => cm.AccountId == studentId).ConfigureAwait(false); + return (user != null, user?.ChatId ?? 0); + } + + public async Task ChatIdByStudentId(string studentId) + { + var user = await _telegramBotRepository.FindAsync(cm => cm.AccountId == studentId).ConfigureAwait(false); + return user.ChatId; + } + + public async Task AddTaskIdAndWaitPullRequest(Update update, long taskId) + { + var user = _telegramBotRepository.GetUserTelegramByChatId(update.CallbackQuery.Message.Chat.Id).ToArray()[0]; + var newUserModel = new UserTelegram + { + ChatId = user.ChatId, + AccountId = user.AccountId, + IsLecture = user.IsLecture, + IsRegistered = user.IsRegistered, + Code = user.Code, + Operation = "wait_url", + TaskIdToSend = taskId + }; + await _telegramBotRepository.UpdateAsync(user.Id, x => newUserModel); + return newUserModel; + } + + public async Task AddGitHubUrlToTask(Update update, string url) + { + var user = _telegramBotRepository.GetUserTelegramByChatId(update.CallbackQuery.Message.Chat.Id).ToArray()[0]; + var newUserModel = new UserTelegram + { + ChatId = user.ChatId, + AccountId = user.AccountId, + IsLecture = user.IsLecture, + IsRegistered = user.IsRegistered, + Code = user.Code, + Operation = "wait_comment", + TaskIdToSend = user.TaskIdToSend, + GitHubUrl = url + }; + await _telegramBotRepository.UpdateAsync(user.Id, x => newUserModel); + return newUserModel; + } + + public async Task DeleteUser(Update update) + { + var user = update.Message == null + ? await _telegramBotRepository.FindAsync(x => x.ChatId == update.CallbackQuery.Message.Chat.Id) + : await _telegramBotRepository.FindAsync(x => x.ChatId == update.Message.Chat.Id); + if (user == null) + { + return; + } + await _telegramBotRepository.DeleteAsync(user.Id); + } + } +} \ No newline at end of file diff --git a/HwProj.TelegramBot/HwProj.TelegramBotService.API/Startup.cs b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Startup.cs new file mode 100644 index 000000000..21f69fec5 --- /dev/null +++ b/HwProj.TelegramBot/HwProj.TelegramBotService.API/Startup.cs @@ -0,0 +1,65 @@ +using System; +using HwProj.AuthService.Client; +using HwProj.CoursesService.Client; +using HwProj.SolutionsService.Client; +using HwProj.TelegramBotService.API.Commands; +using HwProj.TelegramBotService.API.Models; +using HwProj.TelegramBotService.API.Repositories; +using HwProj.TelegramBotService.API.Service; +using HwProj.Utils.Configuration; +using Microsoft.AspNetCore.Builder; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using IHostingEnvironment = Microsoft.AspNetCore.Hosting.IHostingEnvironment; + +namespace HwProj.TelegramBotService.API +{ + public class Startup + { + public Startup(IConfiguration configuration) + { + Configuration = configuration; + } + + public IConfiguration Configuration { get; } + + public void ConfigureServices(IServiceCollection services) + { + var connectionString = Configuration.GetConnectionString("DefaultConnection"); + services.AddDbContext(options => options.UseSqlServer(connectionString)); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + + services.AddHttpClient(); + services.AddAuthServiceClient(); + services.AddSolutionServiceClient(); + services.AddCoursesServiceClient(); + + services.AddEventBus(Configuration); + services.ConfigureHwProjServices("Telegram API"); + } + + public void Configure(IApplicationBuilder app, IHostingEnvironment env, IServiceProvider serviceProvider) + { + app.ConfigureHwProj(env, "Telegram API"); + serviceProvider.GetRequiredService().GetBot().Wait(); + } + } +} \ No newline at end of file diff --git a/HwProj.TelegramBot/HwProj.TelegramBotService.API/appsettings.Development.json b/HwProj.TelegramBot/HwProj.TelegramBotService.API/appsettings.Development.json new file mode 100644 index 000000000..8983e0fc1 --- /dev/null +++ b/HwProj.TelegramBot/HwProj.TelegramBotService.API/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + } +} diff --git a/HwProj.TelegramBot/HwProj.TelegramBotService.API/appsettings.json b/HwProj.TelegramBot/HwProj.TelegramBotService.API/appsettings.json new file mode 100644 index 000000000..2bd125452 --- /dev/null +++ b/HwProj.TelegramBot/HwProj.TelegramBotService.API/appsettings.json @@ -0,0 +1,28 @@ +{ + "ConnectionStrings": { + "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=TelegramBotServiceDB;Trusted_Connection=True;" + }, + "Logging": { + "LogLevel": { + "Default": "Warning" + } + }, + "AllowedHosts": "*", + "EventBus": { + "EventBusHostName": "localhost", + "EventBusUserName": "guest", + "EventBusPassword": "guest", + "EventBusVirtualHost": "/", + "EventBusQueueName": "TelegramBot", + "EventBusRetryCount": "5" + }, + "Services": { + "Auth": "http://localhost:5001", + "Courses": "http://localhost:5002", + "Notifications": "http://localhost:5006", + "Solutions": "http://localhost:5007", + "TelegramBot" : "http://localhost:5009" + }, + "Token" : "1921590728:AAFFUK6qijY5IoVPiDWtpTCNc2rSh8Fb7EU", + "Url" : "https://4ba7-92-42-26-35.ngrok.io/" +} \ No newline at end of file diff --git a/HwProj.TelegramBot/HwProj.TelegramBotService.Client/ConfigurationExtensions.cs b/HwProj.TelegramBot/HwProj.TelegramBotService.Client/ConfigurationExtensions.cs new file mode 100644 index 000000000..7dad352c8 --- /dev/null +++ b/HwProj.TelegramBot/HwProj.TelegramBotService.Client/ConfigurationExtensions.cs @@ -0,0 +1,13 @@ +using Microsoft.Extensions.DependencyInjection; + +namespace HwProj.TelegramBotService.Client +{ + public static class ConfigurationExtensions + { + public static IServiceCollection AddTelegramBotClient(this IServiceCollection services) + { + services.AddScoped(); + return services; + } + } +} \ No newline at end of file diff --git a/HwProj.TelegramBot/HwProj.TelegramBotService.Client/HwProj.TelegramBotService.Client.csproj b/HwProj.TelegramBot/HwProj.TelegramBotService.Client/HwProj.TelegramBotService.Client.csproj new file mode 100644 index 000000000..3aca46f48 --- /dev/null +++ b/HwProj.TelegramBot/HwProj.TelegramBotService.Client/HwProj.TelegramBotService.Client.csproj @@ -0,0 +1,16 @@ + + + + netcoreapp2.2 + latest + + + + + + + + + + + diff --git a/HwProj.TelegramBot/HwProj.TelegramBotService.Client/ITelegramBotServiceClient.cs b/HwProj.TelegramBot/HwProj.TelegramBotService.Client/ITelegramBotServiceClient.cs new file mode 100644 index 000000000..1d1a8fcc3 --- /dev/null +++ b/HwProj.TelegramBot/HwProj.TelegramBotService.Client/ITelegramBotServiceClient.cs @@ -0,0 +1,11 @@ +using System.Threading.Tasks; +using HwProj.Models.TelegramBotService; +using Telegram.Bot.Types; + +namespace HwProj.TelegramBotService.Client +{ + public interface ITelegramBotServiceClient + { + Task<(bool, long)> CheckUser(string studentId); + } +} \ No newline at end of file diff --git a/HwProj.TelegramBot/HwProj.TelegramBotService.Client/TelegramBotServiceClient.cs b/HwProj.TelegramBot/HwProj.TelegramBotService.Client/TelegramBotServiceClient.cs new file mode 100644 index 000000000..0bc860cf7 --- /dev/null +++ b/HwProj.TelegramBot/HwProj.TelegramBotService.Client/TelegramBotServiceClient.cs @@ -0,0 +1,40 @@ +using System; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using HwProj.HttpUtils; +using HwProj.Models.TelegramBotService; +using Microsoft.Extensions.Configuration; +using Newtonsoft.Json; +using Telegram.Bot.Types; + +namespace HwProj.TelegramBotService.Client +{ + public class TelegramBotServiceClient : ITelegramBotServiceClient + { + private readonly HttpClient _httpClient; + private readonly Uri _telegramBotUri; + + public TelegramBotServiceClient(IHttpClientFactory clientFactory, IConfiguration configuration) + { + _httpClient = clientFactory.CreateClient(); + _telegramBotUri = new Uri(configuration.GetSection("Services")["TelegramBot"]); + } + + public async Task<(bool, long)> CheckUser(string studentId) + { + using var httpRequest = new HttpRequestMessage( + HttpMethod.Get, + _telegramBotUri + $"api/TelegramBot/check/{studentId}") + { + Content = new StringContent( + JsonConvert.SerializeObject(studentId), + Encoding.UTF8, + "application/json") + }; + + var response = await _httpClient.SendAsync(httpRequest); + return await response.DeserializeAsync<(bool, long)>(); + } + } +} \ No newline at end of file diff --git a/HwProj.TelegramBotService.Test/HwProj.TelegramBotService.Test.csproj b/HwProj.TelegramBotService.Test/HwProj.TelegramBotService.Test.csproj new file mode 100644 index 000000000..6c8fbd343 --- /dev/null +++ b/HwProj.TelegramBotService.Test/HwProj.TelegramBotService.Test.csproj @@ -0,0 +1,32 @@ + + + + netcoreapp2.2 + + false + + latest + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/HwProj.TelegramBotService.Test/TelegramBotServiceClientTest.cs b/HwProj.TelegramBotService.Test/TelegramBotServiceClientTest.cs new file mode 100644 index 000000000..79451cc7a --- /dev/null +++ b/HwProj.TelegramBotService.Test/TelegramBotServiceClientTest.cs @@ -0,0 +1,204 @@ +using System; +using System.Linq; +using System.Net.Http; +using System.Net.Mail; +using System.Text; +using System.Threading.Tasks; +using NUnit.Framework; +using HwProj.AuthService.Client; +using HwProj.EventBus.Client.Interfaces; +using HwProj.Models.AuthService.ViewModels; +using HwProj.Models.TelegramBotService; +using HwProj.TelegramBotService.API.Models; +using HwProj.TelegramBotService.API.Repositories; +using HwProj.TelegramBotService.API.Service; +using HwProj.TelegramBotService.Client; +using Microsoft.AspNetCore.Mvc.Testing; +using Microsoft.AspNetCore.TestHost; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Options; +using Microsoft.Extensions.DependencyInjection; +using AutoFixture; +using FluentAssertions; +using HwProj.Models.NotificationsService; +using HwProj.NotificationsService.Client; +using Moq; +using Newtonsoft.Json; +using Telegram.Bot; +using Telegram.Bot.Types; +using Telegram.Bot.Types.Enums; +using Startup = HwProj.TelegramBotService.API.Startup; + +namespace HwProj.TelegramBotService.Test +{ + public class Tests + { + private readonly UserTelegramTelegramService _userTelegramTelegramService; + private readonly AuthServiceClient _authService; + + public Tests() + { + var eventBus = new Mock(); + _authService = CreateAuthServiceClient(); + var mock = new Mock(); + var repo = new Mock(); + _userTelegramTelegramService = new UserTelegramTelegramService(mock.Object, eventBus.Object, repo.Object); + } + + private TelegramBotServiceClient CreateTelegramBotServiceClient() + { + var mockIConfiguration = new Mock(); + mockIConfiguration + .Setup(x => x.GetSection("Services")["TelegramBot"]) + .Returns("http://localhost:5009"); + + var mockClientFactory = new Mock(); + mockClientFactory + .Setup(x => x.CreateClient(Options.DefaultName)) + .Returns(new HttpClient()); + + return new TelegramBotServiceClient(mockClientFactory.Object, mockIConfiguration.Object); + } + + private NotificationsServiceClient CreateNotificationsServiceClient() + { + var mockIConfiguration = new Mock(); + mockIConfiguration + .Setup(x => x.GetSection("Services")["Notifications"]) + .Returns("http://localhost:5006"); + + var mockClientFactory = new Mock(); + mockClientFactory + .Setup(x => x.CreateClient(Options.DefaultName)) + .Returns(new HttpClient()); + + return new NotificationsServiceClient(mockClientFactory.Object, mockIConfiguration.Object); + } + + private AuthServiceClient CreateAuthServiceClient() + { + var mockIConfiguration = new Mock(); + mockIConfiguration.Setup(x => x.GetSection("Services")["Auth"]).Returns("http://localhost:5001"); + var mockClientFactory = new Mock(); + mockClientFactory.Setup(x => x.CreateClient(Options.DefaultName)).Returns(new HttpClient()); + return new AuthServiceClient(mockClientFactory.Object, mockIConfiguration.Object); + } + + private static RegisterViewModel GenerateRegisterViewModel() + { + var password = new Fixture().Create(); + + var fixture = new Fixture().Build() + .With(x => x.Email, new Fixture().Create().Address) + .With(x => x.Password, password) + .With(x => x.PasswordConfirm, password); + + return fixture.Create(); + } + + private async Task<(string, string)> CreateAndRegisterUser() + { + var userData = GenerateRegisterViewModel(); + await _authService.Register(userData); + var userId = await _authService.FindByEmailAsync(userData.Email); + return (userId, userData.Email); + } + + private async Task RegisterTelegramUser(string userId, string email) + { + var chatId = new Fixture().Create(); + var userTelegram = new UserTelegram + { + ChatId = chatId, + AccountId = null!, + IsLecture = false, + IsRegistered = false, + Code = "AAAAA", + Operation = "wait_code" + }; + await _userTelegramTelegramService.CreateUser(chatId); + userTelegram = await _userTelegramTelegramService.AddEmailToUser(chatId, email); + await _userTelegramTelegramService.AddFinishUser(chatId, userTelegram.Code); + return userTelegram.ChatId; + } + + public Update createUpdate(long chatId) + { + var fixture = new Fixture(); + fixture.Behaviors.OfType().ToList().ForEach(b => fixture.Behaviors.Remove(b)); + fixture.Behaviors.Add(new OmitOnRecursionBehavior()); + var chat = fixture.Build() + .With(h => h.Id, chatId) + .Create(); + var msg = fixture.Build() + .With(h => h.Text, "/start") + .With(h => h.Chat, chat) + .Create(); + return fixture.Build() + .With(h => h.Message, msg) + .Create(); + } + + [Test] + public async Task СheckUserTest() + { + var (studentId, email) = await CreateAndRegisterUser(); + var telegramBotServiceClient = CreateTelegramBotServiceClient(); + var notificationsClient = CreateNotificationsServiceClient(); + var webHost = new WebApplicationFactory(); + var client = webHost.CreateClient(); + var chatId = new Fixture().Create(); + var upd = createUpdate(chatId); + + using var httpRequest = new HttpRequestMessage( + HttpMethod.Post, + "http://localhost:5009/api/TelegramBot"); + httpRequest.Content = new StringContent( + JsonConvert.SerializeObject(upd, Formatting.Indented, new JsonSerializerSettings + { + NullValueHandling = NullValueHandling.Ignore + }), + Encoding.UTF8, + "application/json"); + await client.SendAsync(httpRequest); + + upd.Message.Text = email; + using var httpRequest1 = new HttpRequestMessage( + HttpMethod.Post, + "http://localhost:5009/api/TelegramBot"); + httpRequest1.Content = new StringContent( + JsonConvert.SerializeObject(upd, Formatting.Indented, new JsonSerializerSettings + { + NullValueHandling = NullValueHandling.Ignore + }), + Encoding.UTF8, + "application/json"); + await client.SendAsync(httpRequest1); + + var notifications = await notificationsClient.Get(studentId, new NotificationFilter()); + while (notifications.Length != 2) + { + notifications = await notificationsClient.Get(studentId, new NotificationFilter()); + } + var text = notifications[1].Body.Split(' ')[5]; + upd.Message.Text = text; + using var httpRequest2 = new HttpRequestMessage( + HttpMethod.Post, + "http://localhost:5009/" + $"api/TelegramBot"); + httpRequest2.Content = new StringContent( + JsonConvert.SerializeObject(upd, Formatting.Indented, new JsonSerializerSettings + { + NullValueHandling = NullValueHandling.Ignore + }), + Encoding.UTF8, + "application/json"); + await client.SendAsync(httpRequest2); + + var (check, _) = await telegramBotServiceClient.CheckUser(studentId); + check.Should().BeTrue(); + } + + } +} + diff --git a/HwProj.sln b/HwProj.sln index 3961fc3c1..def8db52a 100644 --- a/HwProj.sln +++ b/HwProj.sln @@ -69,6 +69,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HwProj.SolutionsService.Cli EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HwProj.Exceptions", "HwProj.Common\HwProj.Exceptions\HwProj.Exceptions.csproj", "{51463655-7668-4C7D-9FDE-D4D7CDAA82B8}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "HwProj.TelegramBotService", "HwProj.TelegramBotService", "{42822186-2040-4216-9C1D-9849EA5D3CB5}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HwProj.TelegramBotService.Client", "HwProj.TelegramBot\HwProj.TelegramBotService.Client\HwProj.TelegramBotService.Client.csproj", "{00F850B0-419E-44EA-9AFC-CBF3CBA26C91}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HwProj.TelegramBotService.API", "HwProj.TelegramBot\HwProj.TelegramBotService.API\HwProj.TelegramBotService.API.csproj", "{677D77E8-ACFA-49FE-A752-F787B5F7A3EE}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HwProj.TelegramBotService.Test", "HwProj.TelegramBotService.Test\HwProj.TelegramBotService.Test.csproj", "{CAA4898C-B20E-4EC5-A37C-921A777D4935}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -159,6 +167,18 @@ Global {51463655-7668-4C7D-9FDE-D4D7CDAA82B8}.Debug|Any CPU.Build.0 = Debug|Any CPU {51463655-7668-4C7D-9FDE-D4D7CDAA82B8}.Release|Any CPU.ActiveCfg = Release|Any CPU {51463655-7668-4C7D-9FDE-D4D7CDAA82B8}.Release|Any CPU.Build.0 = Release|Any CPU + {00F850B0-419E-44EA-9AFC-CBF3CBA26C91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {00F850B0-419E-44EA-9AFC-CBF3CBA26C91}.Debug|Any CPU.Build.0 = Debug|Any CPU + {00F850B0-419E-44EA-9AFC-CBF3CBA26C91}.Release|Any CPU.ActiveCfg = Release|Any CPU + {00F850B0-419E-44EA-9AFC-CBF3CBA26C91}.Release|Any CPU.Build.0 = Release|Any CPU + {677D77E8-ACFA-49FE-A752-F787B5F7A3EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {677D77E8-ACFA-49FE-A752-F787B5F7A3EE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {677D77E8-ACFA-49FE-A752-F787B5F7A3EE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {677D77E8-ACFA-49FE-A752-F787B5F7A3EE}.Release|Any CPU.Build.0 = Release|Any CPU + {CAA4898C-B20E-4EC5-A37C-921A777D4935}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CAA4898C-B20E-4EC5-A37C-921A777D4935}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CAA4898C-B20E-4EC5-A37C-921A777D4935}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CAA4898C-B20E-4EC5-A37C-921A777D4935}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -185,6 +205,9 @@ Global {0CBD72C5-1CCF-4C13-8046-732398816160} = {1EAEB779-E7C8-4EF9-B9A9-22CB8E3C246D} {C1ACAB32-4100-4C19-AE08-57FA9BA75DF2} = {A85A3030-2878-4923-B450-9683832CDAC1} {51463655-7668-4C7D-9FDE-D4D7CDAA82B8} = {77D857A8-45C6-4432-B4BF-A2F2C9ECA7FE} + {00F850B0-419E-44EA-9AFC-CBF3CBA26C91} = {42822186-2040-4216-9C1D-9849EA5D3CB5} + {677D77E8-ACFA-49FE-A752-F787B5F7A3EE} = {42822186-2040-4216-9C1D-9849EA5D3CB5} + {CAA4898C-B20E-4EC5-A37C-921A777D4935} = {42822186-2040-4216-9C1D-9849EA5D3CB5} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {C03BF138-4A5B-4261-9495-6D3AC6CE9779} diff --git a/hwproj.front/package-lock.json b/hwproj.front/package-lock.json index 30e284109..95ec1ccb2 100644 --- a/hwproj.front/package-lock.json +++ b/hwproj.front/package-lock.json @@ -6569,6 +6569,14 @@ "eslint-visitor-keys": "^2.0.0" } }, + "@v9v/ts-react-telegram-login": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@v9v/ts-react-telegram-login/-/ts-react-telegram-login-1.1.1.tgz", + "integrity": "sha512-aWzELPBBfZET5L7Ud3IPApCz2qzJUXF1lBDFIpaKnG6vehe4F9GT7Ss+A/buOTYh1VgraQ03oh3f/ncNy1AdhA==", + "requires": { + "react": "^16.13.1" + } + }, "@webassemblyjs/ast": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", @@ -6774,6 +6782,11 @@ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==" }, + "add": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/add/-/add-2.0.6.tgz", + "integrity": "sha1-JI8Kn25aUo7yKV2+7DBTITCuIjU=" + }, "address": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/address/-/address-1.1.2.tgz", @@ -16261,6 +16274,14 @@ "remove-accents": "0.4.2" } }, + "material-ui-image": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/material-ui-image/-/material-ui-image-3.3.2.tgz", + "integrity": "sha512-WE5QE0Rjdx9jPKuI0LWI7s8VQ9cifPIXObu8AUCRcidXGV3NqPI9C8c9A/C0MofKpkZ3buG8+IT9N7GgSmxXeg==", + "requires": { + "prop-types": "^15.5.8" + } + }, "md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", @@ -17285,6 +17306,11 @@ "word-wrap": "^1.2.3" } }, + "or": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/or/-/or-0.2.0.tgz", + "integrity": "sha1-mQTqYeJZQ/k14g9PR0ngoUGoK2o=" + }, "original": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", @@ -19633,9 +19659,9 @@ } }, "react-social-login-buttons": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/react-social-login-buttons/-/react-social-login-buttons-3.5.1.tgz", - "integrity": "sha512-3TjHYARN9cOfEEl6uQeeB1oMV/dJ2lyxqK98Y+HuvP0E9Q0HJoFvNps6h6EYKE6Yw6LMllUeR5264tSqalM/ww==" + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/react-social-login-buttons/-/react-social-login-buttons-3.6.0.tgz", + "integrity": "sha512-m5E72jHWgC4VBxRziZYQC5kQIzooGRF+dDE97K5JgSlcDPXkNxCjCzP+Qp9fNhNujG7APvPx2Qhzi1BO2xi17Q==" }, "react-syntax-highlighter": { "version": "13.5.3", @@ -19650,6 +19676,22 @@ "refractor": "^3.1.0" } }, + "react-telegram-auth": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/react-telegram-auth/-/react-telegram-auth-1.0.3.tgz", + "integrity": "sha512-0OXTscv1rEfC//UzO9pO2Pxlkqw7t4tOBIOOwfRw+F4VxgQy5f0Z8bw9wa7CrUEKm7Xcs/bNhe8PGas5jg6GhA==", + "requires": { + "react": "^16.13.1" + } + }, + "react-telegram-login": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/react-telegram-login/-/react-telegram-login-1.1.2.tgz", + "integrity": "sha512-pDP+bvfaklWgnK5O6yvZnIwgky0nnYUU6Zhk0EjdMSkPsLQoOzZRsXIoZnbxyBXhi7346bsxMH+EwwJPTxClDw==", + "requires": { + "react": "^16.13.1" + } + }, "react-textarea-autosize": { "version": "8.3.3", "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.3.3.tgz", @@ -21940,6 +21982,16 @@ } } }, + "telegram-login-button": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/telegram-login-button/-/telegram-login-button-0.0.3.tgz", + "integrity": "sha512-R5f3z/YANJjFxIBQxagjrVf+1im/u2CecKlTbFjun9MhPAge8KY3gJ8gTp0TuVJ+L5JShlRDdvrGQibjUiUk0Q==", + "dev": true, + "requires": { + "@babel/runtime": "^7.6.0", + "prop-types": "^15.7.2" + } + }, "telejson": { "version": "5.3.3", "resolved": "https://registry.npmjs.org/telejson/-/telejson-5.3.3.tgz", @@ -24566,6 +24618,11 @@ } } }, + "yarn": { + "version": "1.22.17", + "resolved": "https://registry.npmjs.org/yarn/-/yarn-1.22.17.tgz", + "integrity": "sha512-H0p241BXaH0UN9IeH//RT82tl5PfNraVpSpEoW+ET7lmopNC61eZ+A+IDvU8FM6Go5vx162SncDL8J1ZjRBriQ==" + }, "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/hwproj.front/package.json b/hwproj.front/package.json index 070b9a68c..053bb40d5 100644 --- a/hwproj.front/package.json +++ b/hwproj.front/package.json @@ -18,6 +18,8 @@ "@types/react-syntax-highlighter": "^10.2.1", "@types/remarkable": "^1.7.4", "@types/request": "^2.48.7", + "@v9v/ts-react-telegram-login": "^1.1.1", + "add": "^2.0.6", "axios": "^0.21.1", "bootstrap": "^4.3.1", "classnames": "^2.3.1", @@ -28,6 +30,8 @@ "html-react-parser": "^1.2.8", "jwt-decode": "^3.1.2", "lowdb": "^1.0.0", + "material-ui-image": "^3.3.2", + "or": "^0.2.0", "portable-fetch": "^3.0.0", "prop-types": "^15.7.2", "react": "^16.12.0", @@ -37,7 +41,10 @@ "react-query": "^3.21.1", "react-router-dom": "^5.2.1", "react-scripts": "^4.0.3", - "react-social-login-buttons": "^3.5.1" + "react-social-login-buttons": "^3.6.0", + "react-telegram-auth": "^1.0.3", + "react-telegram-login": "^1.1.2", + "yarn": "^1.22.17" }, "scripts": { "start": "react-scripts start", @@ -68,6 +75,7 @@ "@types/react-dom": "^16.9.14", "@types/react-router-dom": "^4.3.5", "prettier": "2.2.1", + "telegram-login-button": "0.0.3", "typescript": "^3.9.10" } } diff --git a/hwproj.front/src/api/api.ts b/hwproj.front/src/api/api.ts index 8a97ad17d..49b3eeb53 100644 --- a/hwproj.front/src/api/api.ts +++ b/hwproj.front/src/api/api.ts @@ -5,7 +5,7 @@ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) * * OpenAPI spec version: v1 - * + * * * NOTE: This class is auto generated by the swagger code generator program. * https://github.com/swagger-api/swagger-codegen.git @@ -79,43 +79,43 @@ export class RequiredError extends Error { } /** - * + * * @export * @interface AccountDataDto */ export interface AccountDataDto { /** - * + * * @type {string} * @memberof AccountDataDto */ name?: string; /** - * + * * @type {string} * @memberof AccountDataDto */ surname?: string; /** - * + * * @type {string} * @memberof AccountDataDto */ middleName?: string; /** - * + * * @type {string} * @memberof AccountDataDto */ email?: string; /** - * + * * @type {string} * @memberof AccountDataDto */ role?: string; /** - * + * * @type {boolean} * @memberof AccountDataDto */ @@ -123,19 +123,19 @@ export interface AccountDataDto { } /** - * + * * @export * @interface CourseMateViewModel */ export interface CourseMateViewModel { /** - * + * * @type {string} * @memberof CourseMateViewModel */ studentId?: string; /** - * + * * @type {boolean} * @memberof CourseMateViewModel */ @@ -143,61 +143,61 @@ export interface CourseMateViewModel { } /** - * + * * @export * @interface CourseViewModel */ export interface CourseViewModel { /** - * + * * @type {number} * @memberof CourseViewModel */ id?: number; /** - * + * * @type {string} * @memberof CourseViewModel */ name?: string; /** - * + * * @type {string} * @memberof CourseViewModel */ groupName?: string; /** - * + * * @type {boolean} * @memberof CourseViewModel */ isOpen?: boolean; /** - * + * * @type {boolean} * @memberof CourseViewModel */ isCompleted?: boolean; /** - * + * * @type {string} * @memberof CourseViewModel */ mentorIds?: string; /** - * + * * @type {string} * @memberof CourseViewModel */ inviteCode?: string; /** - * + * * @type {Array} * @memberof CourseViewModel */ courseMates?: Array; /** - * + * * @type {Array} * @memberof CourseViewModel */ @@ -205,25 +205,25 @@ export interface CourseViewModel { } /** - * + * * @export * @interface CreateCourseViewModel */ export interface CreateCourseViewModel { /** - * + * * @type {string} * @memberof CreateCourseViewModel */ name: string; /** - * + * * @type {string} * @memberof CreateCourseViewModel */ groupName?: string; /** - * + * * @type {boolean} * @memberof CreateCourseViewModel */ @@ -231,31 +231,31 @@ export interface CreateCourseViewModel { } /** - * + * * @export * @interface CreateGroupViewModel */ export interface CreateGroupViewModel { /** - * + * * @type {string} * @memberof CreateGroupViewModel */ name: string; /** - * + * * @type {Array} * @memberof CreateGroupViewModel */ groupMates: Array; /** - * + * * @type {number} * @memberof CreateGroupViewModel */ courseId: number; /** - * + * * @type {Array} * @memberof CreateGroupViewModel */ @@ -263,25 +263,25 @@ export interface CreateGroupViewModel { } /** - * + * * @export * @interface CreateHomeworkViewModel */ export interface CreateHomeworkViewModel { /** - * + * * @type {string} * @memberof CreateHomeworkViewModel */ title: string; /** - * + * * @type {string} * @memberof CreateHomeworkViewModel */ description?: string; /** - * + * * @type {Array} * @memberof CreateHomeworkViewModel */ @@ -289,49 +289,49 @@ export interface CreateHomeworkViewModel { } /** - * + * * @export * @interface CreateTaskViewModel */ export interface CreateTaskViewModel { /** - * + * * @type {string} * @memberof CreateTaskViewModel */ title: string; /** - * + * * @type {string} * @memberof CreateTaskViewModel */ description?: string; /** - * + * * @type {boolean} * @memberof CreateTaskViewModel */ hasDeadline?: boolean; /** - * + * * @type {Date} * @memberof CreateTaskViewModel */ deadlineDate?: Date; /** - * + * * @type {boolean} * @memberof CreateTaskViewModel */ isDeadlineStrict?: boolean; /** - * + * * @type {Date} * @memberof CreateTaskViewModel */ publicationDate?: Date; /** - * + * * @type {number} * @memberof CreateTaskViewModel */ @@ -339,37 +339,37 @@ export interface CreateTaskViewModel { } /** - * + * * @export * @interface EditAccountViewModel */ export interface EditAccountViewModel { /** - * + * * @type {string} * @memberof EditAccountViewModel */ name: string; /** - * + * * @type {string} * @memberof EditAccountViewModel */ surname: string; /** - * + * * @type {string} * @memberof EditAccountViewModel */ middleName?: string; /** - * + * * @type {string} * @memberof EditAccountViewModel */ currentPassword: string; /** - * + * * @type {string} * @memberof EditAccountViewModel */ @@ -377,25 +377,25 @@ export interface EditAccountViewModel { } /** - * + * * @export * @interface EditExternalViewModel */ export interface EditExternalViewModel { /** - * + * * @type {string} * @memberof EditExternalViewModel */ name: string; /** - * + * * @type {string} * @memberof EditExternalViewModel */ surname: string; /** - * + * * @type {string} * @memberof EditExternalViewModel */ @@ -403,13 +403,13 @@ export interface EditExternalViewModel { } /** - * + * * @export * @interface GroupMateViewModel */ export interface GroupMateViewModel { /** - * + * * @type {string} * @memberof GroupMateViewModel */ @@ -417,37 +417,37 @@ export interface GroupMateViewModel { } /** - * + * * @export * @interface GroupViewModel */ export interface GroupViewModel { /** - * + * * @type {number} * @memberof GroupViewModel */ id?: number; /** - * + * * @type {number} * @memberof GroupViewModel */ courseId?: number; /** - * + * * @type {string} * @memberof GroupViewModel */ name?: string; /** - * + * * @type {Array} * @memberof GroupViewModel */ tasks?: Array; /** - * + * * @type {Array} * @memberof GroupViewModel */ @@ -455,73 +455,73 @@ export interface GroupViewModel { } /** - * + * * @export * @interface HomeworkTaskViewModel */ export interface HomeworkTaskViewModel { /** - * + * * @type {number} * @memberof HomeworkTaskViewModel */ id?: number; /** - * + * * @type {string} * @memberof HomeworkTaskViewModel */ title?: string; /** - * + * * @type {string} * @memberof HomeworkTaskViewModel */ description?: string; /** - * + * * @type {number} * @memberof HomeworkTaskViewModel */ maxRating?: number; /** - * + * * @type {boolean} * @memberof HomeworkTaskViewModel */ hasDeadline?: boolean; /** - * + * * @type {Date} * @memberof HomeworkTaskViewModel */ deadlineDate?: Date; /** - * + * * @type {boolean} * @memberof HomeworkTaskViewModel */ isDeadlineStrict?: boolean; /** - * + * * @type {boolean} * @memberof HomeworkTaskViewModel */ canSendSolution?: boolean; /** - * + * * @type {Date} * @memberof HomeworkTaskViewModel */ publicationDate?: Date; /** - * + * * @type {number} * @memberof HomeworkTaskViewModel */ homeworkId?: number; /** - * + * * @type {boolean} * @memberof HomeworkTaskViewModel */ @@ -529,43 +529,43 @@ export interface HomeworkTaskViewModel { } /** - * + * * @export * @interface HomeworkViewModel */ export interface HomeworkViewModel { /** - * + * * @type {number} * @memberof HomeworkViewModel */ id?: number; /** - * + * * @type {string} * @memberof HomeworkViewModel */ title?: string; /** - * + * * @type {string} * @memberof HomeworkViewModel */ description?: string; /** - * + * * @type {Date} * @memberof HomeworkViewModel */ date?: Date; /** - * + * * @type {number} * @memberof HomeworkViewModel */ courseId?: number; /** - * + * * @type {Array} * @memberof HomeworkViewModel */ @@ -573,13 +573,13 @@ export interface HomeworkViewModel { } /** - * + * * @export * @interface InviteLecturerViewModel */ export interface InviteLecturerViewModel { /** - * + * * @type {string} * @memberof InviteLecturerViewModel */ @@ -587,25 +587,25 @@ export interface InviteLecturerViewModel { } /** - * + * * @export * @interface LoginViewModel */ export interface LoginViewModel { /** - * + * * @type {string} * @memberof LoginViewModel */ email: string; /** - * + * * @type {string} * @memberof LoginViewModel */ password: string; /** - * + * * @type {boolean} * @memberof LoginViewModel */ @@ -613,43 +613,43 @@ export interface LoginViewModel { } /** - * + * * @export * @interface NotificationViewModel */ export interface NotificationViewModel { /** - * + * * @type {number} * @memberof NotificationViewModel */ id?: number; /** - * + * * @type {string} * @memberof NotificationViewModel */ sender?: string; /** - * + * * @type {string} * @memberof NotificationViewModel */ owner?: string; /** - * + * * @type {string} * @memberof NotificationViewModel */ category?: string; /** - * + * * @type {string} * @memberof NotificationViewModel */ body?: string; /** - * + * * @type {boolean} * @memberof NotificationViewModel */ @@ -657,43 +657,43 @@ export interface NotificationViewModel { } /** - * + * * @export * @interface RegisterViewModel */ export interface RegisterViewModel { /** - * + * * @type {string} * @memberof RegisterViewModel */ name: string; /** - * + * * @type {string} * @memberof RegisterViewModel */ surname: string; /** - * + * * @type {string} * @memberof RegisterViewModel */ middleName?: string; /** - * + * * @type {string} * @memberof RegisterViewModel */ email: string; /** - * + * * @type {string} * @memberof RegisterViewModel */ password: string; /** - * + * * @type {string} * @memberof RegisterViewModel */ @@ -701,19 +701,19 @@ export interface RegisterViewModel { } /** - * + * * @export * @interface Result */ export interface Result { /** - * + * * @type {boolean} * @memberof Result */ succeeded?: boolean; /** - * + * * @type {Array} * @memberof Result */ @@ -721,25 +721,25 @@ export interface Result { } /** - * + * * @export * @interface ResultTokenCredentials */ export interface ResultTokenCredentials { /** - * + * * @type {TokenCredentials} * @memberof ResultTokenCredentials */ value?: TokenCredentials; /** - * + * * @type {boolean} * @memberof ResultTokenCredentials */ succeeded?: boolean; /** - * + * * @type {Array} * @memberof ResultTokenCredentials */ @@ -747,67 +747,67 @@ export interface ResultTokenCredentials { } /** - * + * * @export * @interface Solution */ export interface Solution { /** - * + * * @type {number} * @memberof Solution */ id?: number; /** - * + * * @type {string} * @memberof Solution */ githubUrl?: string; /** - * + * * @type {string} * @memberof Solution */ comment?: string; /** - * + * * @type {number} * @memberof Solution */ state?: Solution.StateEnum; /** - * + * * @type {number} * @memberof Solution */ rating?: number; /** - * + * * @type {string} * @memberof Solution */ studentId?: string; /** - * + * * @type {number} * @memberof Solution */ groupId?: number; /** - * + * * @type {number} * @memberof Solution */ taskId?: number; /** - * + * * @type {Date} * @memberof Solution */ publicationDate?: Date; /** - * + * * @type {string} * @memberof Solution */ @@ -831,37 +831,37 @@ export namespace Solution { } /** - * + * * @export * @interface SolutionViewModel */ export interface SolutionViewModel { /** - * + * * @type {string} * @memberof SolutionViewModel */ githubUrl: string; /** - * + * * @type {string} * @memberof SolutionViewModel */ comment?: string; /** - * + * * @type {string} * @memberof SolutionViewModel */ studentId?: string; /** - * + * * @type {Date} * @memberof SolutionViewModel */ publicationDate?: Date; /** - * + * * @type {string} * @memberof SolutionViewModel */ @@ -869,19 +869,19 @@ export interface SolutionViewModel { } /** - * + * * @export * @interface StatisticsCourseHomeworksModel */ export interface StatisticsCourseHomeworksModel { /** - * + * * @type {number} * @memberof StatisticsCourseHomeworksModel */ id?: number; /** - * + * * @type {Array} * @memberof StatisticsCourseHomeworksModel */ @@ -889,31 +889,31 @@ export interface StatisticsCourseHomeworksModel { } /** - * + * * @export * @interface StatisticsCourseMatesModel */ export interface StatisticsCourseMatesModel { /** - * + * * @type {string} * @memberof StatisticsCourseMatesModel */ id?: string; /** - * + * * @type {string} * @memberof StatisticsCourseMatesModel */ name?: string; /** - * + * * @type {string} * @memberof StatisticsCourseMatesModel */ surname?: string; /** - * + * * @type {Array} * @memberof StatisticsCourseMatesModel */ @@ -921,25 +921,25 @@ export interface StatisticsCourseMatesModel { } /** - * + * * @export * @interface StatisticsCourseSolutionsModel */ export interface StatisticsCourseSolutionsModel { /** - * + * * @type {number} * @memberof StatisticsCourseSolutionsModel */ id?: number; /** - * + * * @type {number} * @memberof StatisticsCourseSolutionsModel */ state?: StatisticsCourseSolutionsModel.StateEnum; /** - * + * * @type {number} * @memberof StatisticsCourseSolutionsModel */ @@ -963,19 +963,19 @@ export namespace StatisticsCourseSolutionsModel { } /** - * + * * @export * @interface StatisticsCourseTasksModel */ export interface StatisticsCourseTasksModel { /** - * + * * @type {number} * @memberof StatisticsCourseTasksModel */ id?: number; /** - * + * * @type {Array} * @memberof StatisticsCourseTasksModel */ @@ -983,19 +983,19 @@ export interface StatisticsCourseTasksModel { } /** - * + * * @export * @interface TokenCredentials */ export interface TokenCredentials { /** - * + * * @type {string} * @memberof TokenCredentials */ accessToken?: string; /** - * + * * @type {number} * @memberof TokenCredentials */ @@ -1003,31 +1003,31 @@ export interface TokenCredentials { } /** - * + * * @export * @interface UpdateCourseViewModel */ export interface UpdateCourseViewModel { /** - * + * * @type {string} * @memberof UpdateCourseViewModel */ name: string; /** - * + * * @type {string} * @memberof UpdateCourseViewModel */ groupName?: string; /** - * + * * @type {boolean} * @memberof UpdateCourseViewModel */ isOpen: boolean; /** - * + * * @type {boolean} * @memberof UpdateCourseViewModel */ @@ -1035,25 +1035,25 @@ export interface UpdateCourseViewModel { } /** - * + * * @export * @interface UpdateGroupViewModel */ export interface UpdateGroupViewModel { /** - * + * * @type {string} * @memberof UpdateGroupViewModel */ name?: string; /** - * + * * @type {Array} * @memberof UpdateGroupViewModel */ tasks?: Array; /** - * + * * @type {Array} * @memberof UpdateGroupViewModel */ @@ -1061,43 +1061,43 @@ export interface UpdateGroupViewModel { } /** - * + * * @export * @interface UserCourseDescription */ export interface UserCourseDescription { /** - * + * * @type {number} * @memberof UserCourseDescription */ id?: number; /** - * + * * @type {string} * @memberof UserCourseDescription */ name?: string; /** - * + * * @type {string} * @memberof UserCourseDescription */ groupName?: string; /** - * + * * @type {boolean} * @memberof UserCourseDescription */ isOpen?: boolean; /** - * + * * @type {boolean} * @memberof UserCourseDescription */ isCompleted?: boolean; /** - * + * * @type {boolean} * @memberof UserCourseDescription */ @@ -1105,19 +1105,19 @@ export interface UserCourseDescription { } /** - * + * * @export * @interface UserDataDto */ export interface UserDataDto { /** - * + * * @type {AccountDataDto} * @memberof UserDataDto */ userData?: AccountDataDto; /** - * + * * @type {Array} * @memberof UserDataDto */ @@ -1132,8 +1132,8 @@ export interface UserDataDto { export const AccountApiFetchParamCreator = function (configuration?: Configuration) { return { /** - * - * @param {EditExternalViewModel} [model] + * + * @param {EditExternalViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -1147,8 +1147,8 @@ export const AccountApiFetchParamCreator = function (configuration?: Configurati // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -1167,8 +1167,8 @@ export const AccountApiFetchParamCreator = function (configuration?: Configurati }; }, /** - * - * @param {EditAccountViewModel} [model] + * + * @param {EditAccountViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -1182,8 +1182,8 @@ export const AccountApiFetchParamCreator = function (configuration?: Configurati // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -1202,7 +1202,7 @@ export const AccountApiFetchParamCreator = function (configuration?: Configurati }; }, /** - * + * * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -1216,8 +1216,8 @@ export const AccountApiFetchParamCreator = function (configuration?: Configurati // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -1232,8 +1232,8 @@ export const AccountApiFetchParamCreator = function (configuration?: Configurati }; }, /** - * - * @param {string} userId + * + * @param {string} userId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -1252,8 +1252,8 @@ export const AccountApiFetchParamCreator = function (configuration?: Configurati // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -1268,7 +1268,7 @@ export const AccountApiFetchParamCreator = function (configuration?: Configurati }; }, /** - * + * * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -1282,8 +1282,8 @@ export const AccountApiFetchParamCreator = function (configuration?: Configurati // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -1298,8 +1298,8 @@ export const AccountApiFetchParamCreator = function (configuration?: Configurati }; }, /** - * - * @param {string} [tokenId] + * + * @param {string} [tokenId] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -1313,8 +1313,8 @@ export const AccountApiFetchParamCreator = function (configuration?: Configurati // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -1333,8 +1333,8 @@ export const AccountApiFetchParamCreator = function (configuration?: Configurati }; }, /** - * - * @param {InviteLecturerViewModel} [model] + * + * @param {InviteLecturerViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -1348,8 +1348,8 @@ export const AccountApiFetchParamCreator = function (configuration?: Configurati // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -1368,8 +1368,8 @@ export const AccountApiFetchParamCreator = function (configuration?: Configurati }; }, /** - * - * @param {LoginViewModel} [model] + * + * @param {LoginViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -1383,8 +1383,8 @@ export const AccountApiFetchParamCreator = function (configuration?: Configurati // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -1403,8 +1403,8 @@ export const AccountApiFetchParamCreator = function (configuration?: Configurati }; }, /** - * - * @param {RegisterViewModel} [model] + * + * @param {RegisterViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -1418,8 +1418,8 @@ export const AccountApiFetchParamCreator = function (configuration?: Configurati // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -1447,8 +1447,8 @@ export const AccountApiFetchParamCreator = function (configuration?: Configurati export const AccountApiFp = function(configuration?: Configuration) { return { /** - * - * @param {EditExternalViewModel} [model] + * + * @param {EditExternalViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -1465,8 +1465,8 @@ export const AccountApiFp = function(configuration?: Configuration) { }; }, /** - * - * @param {EditAccountViewModel} [model] + * + * @param {EditAccountViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -1483,7 +1483,7 @@ export const AccountApiFp = function(configuration?: Configuration) { }; }, /** - * + * * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -1500,8 +1500,8 @@ export const AccountApiFp = function(configuration?: Configuration) { }; }, /** - * - * @param {string} userId + * + * @param {string} userId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -1518,7 +1518,7 @@ export const AccountApiFp = function(configuration?: Configuration) { }; }, /** - * + * * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -1535,8 +1535,8 @@ export const AccountApiFp = function(configuration?: Configuration) { }; }, /** - * - * @param {string} [tokenId] + * + * @param {string} [tokenId] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -1553,8 +1553,8 @@ export const AccountApiFp = function(configuration?: Configuration) { }; }, /** - * - * @param {InviteLecturerViewModel} [model] + * + * @param {InviteLecturerViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -1571,8 +1571,8 @@ export const AccountApiFp = function(configuration?: Configuration) { }; }, /** - * - * @param {LoginViewModel} [model] + * + * @param {LoginViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -1589,8 +1589,8 @@ export const AccountApiFp = function(configuration?: Configuration) { }; }, /** - * - * @param {RegisterViewModel} [model] + * + * @param {RegisterViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -1616,8 +1616,8 @@ export const AccountApiFp = function(configuration?: Configuration) { export const AccountApiFactory = function (configuration?: Configuration, fetch?: FetchAPI, basePath?: string) { return { /** - * - * @param {EditExternalViewModel} [model] + * + * @param {EditExternalViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -1625,8 +1625,8 @@ export const AccountApiFactory = function (configuration?: Configuration, fetch? return AccountApiFp(configuration).apiAccountEditExternalPut(model, options)(fetch, basePath); }, /** - * - * @param {EditAccountViewModel} [model] + * + * @param {EditAccountViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -1634,7 +1634,7 @@ export const AccountApiFactory = function (configuration?: Configuration, fetch? return AccountApiFp(configuration).apiAccountEditPut(model, options)(fetch, basePath); }, /** - * + * * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -1642,8 +1642,8 @@ export const AccountApiFactory = function (configuration?: Configuration, fetch? return AccountApiFp(configuration).apiAccountGetAllStudentsGet(options)(fetch, basePath); }, /** - * - * @param {string} userId + * + * @param {string} userId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -1651,7 +1651,7 @@ export const AccountApiFactory = function (configuration?: Configuration, fetch? return AccountApiFp(configuration).apiAccountGetUserDataByUserIdGet(userId, options)(fetch, basePath); }, /** - * + * * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -1659,8 +1659,8 @@ export const AccountApiFactory = function (configuration?: Configuration, fetch? return AccountApiFp(configuration).apiAccountGetUserDataGet(options)(fetch, basePath); }, /** - * - * @param {string} [tokenId] + * + * @param {string} [tokenId] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -1668,8 +1668,8 @@ export const AccountApiFactory = function (configuration?: Configuration, fetch? return AccountApiFp(configuration).apiAccountGooglePost(tokenId, options)(fetch, basePath); }, /** - * - * @param {InviteLecturerViewModel} [model] + * + * @param {InviteLecturerViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -1677,8 +1677,8 @@ export const AccountApiFactory = function (configuration?: Configuration, fetch? return AccountApiFp(configuration).apiAccountInviteNewLecturerPost(model, options)(fetch, basePath); }, /** - * - * @param {LoginViewModel} [model] + * + * @param {LoginViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -1686,8 +1686,8 @@ export const AccountApiFactory = function (configuration?: Configuration, fetch? return AccountApiFp(configuration).apiAccountLoginPost(model, options)(fetch, basePath); }, /** - * - * @param {RegisterViewModel} [model] + * + * @param {RegisterViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -1705,8 +1705,8 @@ export const AccountApiFactory = function (configuration?: Configuration, fetch? */ export class AccountApi extends BaseAPI { /** - * - * @param {EditExternalViewModel} [model] + * + * @param {EditExternalViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof AccountApi @@ -1716,8 +1716,8 @@ export class AccountApi extends BaseAPI { } /** - * - * @param {EditAccountViewModel} [model] + * + * @param {EditAccountViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof AccountApi @@ -1727,7 +1727,7 @@ export class AccountApi extends BaseAPI { } /** - * + * * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof AccountApi @@ -1737,8 +1737,8 @@ export class AccountApi extends BaseAPI { } /** - * - * @param {string} userId + * + * @param {string} userId * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof AccountApi @@ -1748,7 +1748,7 @@ export class AccountApi extends BaseAPI { } /** - * + * * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof AccountApi @@ -1758,8 +1758,8 @@ export class AccountApi extends BaseAPI { } /** - * - * @param {string} [tokenId] + * + * @param {string} [tokenId] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof AccountApi @@ -1769,8 +1769,8 @@ export class AccountApi extends BaseAPI { } /** - * - * @param {InviteLecturerViewModel} [model] + * + * @param {InviteLecturerViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof AccountApi @@ -1780,8 +1780,8 @@ export class AccountApi extends BaseAPI { } /** - * - * @param {LoginViewModel} [model] + * + * @param {LoginViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof AccountApi @@ -1791,8 +1791,8 @@ export class AccountApi extends BaseAPI { } /** - * - * @param {RegisterViewModel} [model] + * + * @param {RegisterViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof AccountApi @@ -1810,10 +1810,10 @@ export class AccountApi extends BaseAPI { export const CourseGroupsApiFetchParamCreator = function (configuration?: Configuration) { return { /** - * - * @param {number} courseId - * @param {number} groupId - * @param {string} [userId] + * + * @param {number} courseId + * @param {number} groupId + * @param {string} [userId] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -1837,8 +1837,8 @@ export const CourseGroupsApiFetchParamCreator = function (configuration?: Config // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -1857,9 +1857,9 @@ export const CourseGroupsApiFetchParamCreator = function (configuration?: Config }; }, /** - * - * @param {number} courseId - * @param {CreateGroupViewModel} [model] + * + * @param {number} courseId + * @param {CreateGroupViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -1878,8 +1878,8 @@ export const CourseGroupsApiFetchParamCreator = function (configuration?: Config // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -1898,9 +1898,9 @@ export const CourseGroupsApiFetchParamCreator = function (configuration?: Config }; }, /** - * - * @param {number} courseId - * @param {number} groupId + * + * @param {number} courseId + * @param {number} groupId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -1924,8 +1924,8 @@ export const CourseGroupsApiFetchParamCreator = function (configuration?: Config // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -1940,8 +1940,8 @@ export const CourseGroupsApiFetchParamCreator = function (configuration?: Config }; }, /** - * - * @param {number} courseId + * + * @param {number} courseId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -1960,8 +1960,8 @@ export const CourseGroupsApiFetchParamCreator = function (configuration?: Config // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -1976,8 +1976,8 @@ export const CourseGroupsApiFetchParamCreator = function (configuration?: Config }; }, /** - * - * @param {number} courseId + * + * @param {number} courseId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -1996,8 +1996,8 @@ export const CourseGroupsApiFetchParamCreator = function (configuration?: Config // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -2012,10 +2012,10 @@ export const CourseGroupsApiFetchParamCreator = function (configuration?: Config }; }, /** - * - * @param {number} courseId - * @param {number} groupId - * @param {string} [userId] + * + * @param {number} courseId + * @param {number} groupId + * @param {string} [userId] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -2039,8 +2039,8 @@ export const CourseGroupsApiFetchParamCreator = function (configuration?: Config // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -2059,10 +2059,10 @@ export const CourseGroupsApiFetchParamCreator = function (configuration?: Config }; }, /** - * - * @param {number} courseId - * @param {number} groupId - * @param {UpdateGroupViewModel} [model] + * + * @param {number} courseId + * @param {number} groupId + * @param {UpdateGroupViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -2086,8 +2086,8 @@ export const CourseGroupsApiFetchParamCreator = function (configuration?: Config // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -2106,8 +2106,8 @@ export const CourseGroupsApiFetchParamCreator = function (configuration?: Config }; }, /** - * - * @param {number} groupId + * + * @param {number} groupId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -2126,8 +2126,8 @@ export const CourseGroupsApiFetchParamCreator = function (configuration?: Config // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -2142,8 +2142,8 @@ export const CourseGroupsApiFetchParamCreator = function (configuration?: Config }; }, /** - * - * @param {number} groupId + * + * @param {number} groupId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -2162,8 +2162,8 @@ export const CourseGroupsApiFetchParamCreator = function (configuration?: Config // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -2187,10 +2187,10 @@ export const CourseGroupsApiFetchParamCreator = function (configuration?: Config export const CourseGroupsApiFp = function(configuration?: Configuration) { return { /** - * - * @param {number} courseId - * @param {number} groupId - * @param {string} [userId] + * + * @param {number} courseId + * @param {number} groupId + * @param {string} [userId] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -2207,9 +2207,9 @@ export const CourseGroupsApiFp = function(configuration?: Configuration) { }; }, /** - * - * @param {number} courseId - * @param {CreateGroupViewModel} [model] + * + * @param {number} courseId + * @param {CreateGroupViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -2226,9 +2226,9 @@ export const CourseGroupsApiFp = function(configuration?: Configuration) { }; }, /** - * - * @param {number} courseId - * @param {number} groupId + * + * @param {number} courseId + * @param {number} groupId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -2245,8 +2245,8 @@ export const CourseGroupsApiFp = function(configuration?: Configuration) { }; }, /** - * - * @param {number} courseId + * + * @param {number} courseId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -2263,8 +2263,8 @@ export const CourseGroupsApiFp = function(configuration?: Configuration) { }; }, /** - * - * @param {number} courseId + * + * @param {number} courseId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -2281,10 +2281,10 @@ export const CourseGroupsApiFp = function(configuration?: Configuration) { }; }, /** - * - * @param {number} courseId - * @param {number} groupId - * @param {string} [userId] + * + * @param {number} courseId + * @param {number} groupId + * @param {string} [userId] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -2301,10 +2301,10 @@ export const CourseGroupsApiFp = function(configuration?: Configuration) { }; }, /** - * - * @param {number} courseId - * @param {number} groupId - * @param {UpdateGroupViewModel} [model] + * + * @param {number} courseId + * @param {number} groupId + * @param {UpdateGroupViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -2321,8 +2321,8 @@ export const CourseGroupsApiFp = function(configuration?: Configuration) { }; }, /** - * - * @param {number} groupId + * + * @param {number} groupId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -2339,8 +2339,8 @@ export const CourseGroupsApiFp = function(configuration?: Configuration) { }; }, /** - * - * @param {number} groupId + * + * @param {number} groupId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -2366,10 +2366,10 @@ export const CourseGroupsApiFp = function(configuration?: Configuration) { export const CourseGroupsApiFactory = function (configuration?: Configuration, fetch?: FetchAPI, basePath?: string) { return { /** - * - * @param {number} courseId - * @param {number} groupId - * @param {string} [userId] + * + * @param {number} courseId + * @param {number} groupId + * @param {string} [userId] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -2377,9 +2377,9 @@ export const CourseGroupsApiFactory = function (configuration?: Configuration, f return CourseGroupsApiFp(configuration).apiCourseGroupsByCourseIdAddStudentInGroupByGroupIdPost(courseId, groupId, userId, options)(fetch, basePath); }, /** - * - * @param {number} courseId - * @param {CreateGroupViewModel} [model] + * + * @param {number} courseId + * @param {CreateGroupViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -2387,9 +2387,9 @@ export const CourseGroupsApiFactory = function (configuration?: Configuration, f return CourseGroupsApiFp(configuration).apiCourseGroupsByCourseIdCreatePost(courseId, model, options)(fetch, basePath); }, /** - * - * @param {number} courseId - * @param {number} groupId + * + * @param {number} courseId + * @param {number} groupId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -2397,8 +2397,8 @@ export const CourseGroupsApiFactory = function (configuration?: Configuration, f return CourseGroupsApiFp(configuration).apiCourseGroupsByCourseIdDeleteByGroupIdDelete(courseId, groupId, options)(fetch, basePath); }, /** - * - * @param {number} courseId + * + * @param {number} courseId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -2406,8 +2406,8 @@ export const CourseGroupsApiFactory = function (configuration?: Configuration, f return CourseGroupsApiFp(configuration).apiCourseGroupsByCourseIdGetAllGet(courseId, options)(fetch, basePath); }, /** - * - * @param {number} courseId + * + * @param {number} courseId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -2415,10 +2415,10 @@ export const CourseGroupsApiFactory = function (configuration?: Configuration, f return CourseGroupsApiFp(configuration).apiCourseGroupsByCourseIdGetGet(courseId, options)(fetch, basePath); }, /** - * - * @param {number} courseId - * @param {number} groupId - * @param {string} [userId] + * + * @param {number} courseId + * @param {number} groupId + * @param {string} [userId] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -2426,10 +2426,10 @@ export const CourseGroupsApiFactory = function (configuration?: Configuration, f return CourseGroupsApiFp(configuration).apiCourseGroupsByCourseIdRemoveStudentFromGroupByGroupIdPost(courseId, groupId, userId, options)(fetch, basePath); }, /** - * - * @param {number} courseId - * @param {number} groupId - * @param {UpdateGroupViewModel} [model] + * + * @param {number} courseId + * @param {number} groupId + * @param {UpdateGroupViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -2437,8 +2437,8 @@ export const CourseGroupsApiFactory = function (configuration?: Configuration, f return CourseGroupsApiFp(configuration).apiCourseGroupsByCourseIdUpdateByGroupIdPost(courseId, groupId, model, options)(fetch, basePath); }, /** - * - * @param {number} groupId + * + * @param {number} groupId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -2446,8 +2446,8 @@ export const CourseGroupsApiFactory = function (configuration?: Configuration, f return CourseGroupsApiFp(configuration).apiCourseGroupsGetByGroupIdGet(groupId, options)(fetch, basePath); }, /** - * - * @param {number} groupId + * + * @param {number} groupId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -2465,10 +2465,10 @@ export const CourseGroupsApiFactory = function (configuration?: Configuration, f */ export class CourseGroupsApi extends BaseAPI { /** - * - * @param {number} courseId - * @param {number} groupId - * @param {string} [userId] + * + * @param {number} courseId + * @param {number} groupId + * @param {string} [userId] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof CourseGroupsApi @@ -2478,9 +2478,9 @@ export class CourseGroupsApi extends BaseAPI { } /** - * - * @param {number} courseId - * @param {CreateGroupViewModel} [model] + * + * @param {number} courseId + * @param {CreateGroupViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof CourseGroupsApi @@ -2490,9 +2490,9 @@ export class CourseGroupsApi extends BaseAPI { } /** - * - * @param {number} courseId - * @param {number} groupId + * + * @param {number} courseId + * @param {number} groupId * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof CourseGroupsApi @@ -2502,8 +2502,8 @@ export class CourseGroupsApi extends BaseAPI { } /** - * - * @param {number} courseId + * + * @param {number} courseId * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof CourseGroupsApi @@ -2513,8 +2513,8 @@ export class CourseGroupsApi extends BaseAPI { } /** - * - * @param {number} courseId + * + * @param {number} courseId * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof CourseGroupsApi @@ -2524,10 +2524,10 @@ export class CourseGroupsApi extends BaseAPI { } /** - * - * @param {number} courseId - * @param {number} groupId - * @param {string} [userId] + * + * @param {number} courseId + * @param {number} groupId + * @param {string} [userId] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof CourseGroupsApi @@ -2537,10 +2537,10 @@ export class CourseGroupsApi extends BaseAPI { } /** - * - * @param {number} courseId - * @param {number} groupId - * @param {UpdateGroupViewModel} [model] + * + * @param {number} courseId + * @param {number} groupId + * @param {UpdateGroupViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof CourseGroupsApi @@ -2550,8 +2550,8 @@ export class CourseGroupsApi extends BaseAPI { } /** - * - * @param {number} groupId + * + * @param {number} groupId * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof CourseGroupsApi @@ -2561,8 +2561,8 @@ export class CourseGroupsApi extends BaseAPI { } /** - * - * @param {number} groupId + * + * @param {number} groupId * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof CourseGroupsApi @@ -2580,9 +2580,9 @@ export class CourseGroupsApi extends BaseAPI { export const CoursesApiFetchParamCreator = function (configuration?: Configuration) { return { /** - * - * @param {number} courseId - * @param {string} lecturerEmail + * + * @param {number} courseId + * @param {string} lecturerEmail * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -2606,8 +2606,8 @@ export const CoursesApiFetchParamCreator = function (configuration?: Configurati // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -2622,9 +2622,9 @@ export const CoursesApiFetchParamCreator = function (configuration?: Configurati }; }, /** - * - * @param {number} courseId - * @param {string} studentId + * + * @param {number} courseId + * @param {string} studentId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -2648,8 +2648,8 @@ export const CoursesApiFetchParamCreator = function (configuration?: Configurati // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -2664,8 +2664,8 @@ export const CoursesApiFetchParamCreator = function (configuration?: Configurati }; }, /** - * - * @param {number} courseId + * + * @param {number} courseId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -2684,8 +2684,8 @@ export const CoursesApiFetchParamCreator = function (configuration?: Configurati // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -2700,8 +2700,8 @@ export const CoursesApiFetchParamCreator = function (configuration?: Configurati }; }, /** - * - * @param {number} courseId + * + * @param {number} courseId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -2720,8 +2720,8 @@ export const CoursesApiFetchParamCreator = function (configuration?: Configurati // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -2736,8 +2736,8 @@ export const CoursesApiFetchParamCreator = function (configuration?: Configurati }; }, /** - * - * @param {CreateCourseViewModel} [model] + * + * @param {CreateCourseViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -2751,8 +2751,8 @@ export const CoursesApiFetchParamCreator = function (configuration?: Configurati // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -2771,7 +2771,7 @@ export const CoursesApiFetchParamCreator = function (configuration?: Configurati }; }, /** - * + * * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -2785,8 +2785,8 @@ export const CoursesApiFetchParamCreator = function (configuration?: Configurati // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -2801,9 +2801,9 @@ export const CoursesApiFetchParamCreator = function (configuration?: Configurati }; }, /** - * - * @param {number} courseId - * @param {string} studentId + * + * @param {number} courseId + * @param {string} studentId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -2827,8 +2827,8 @@ export const CoursesApiFetchParamCreator = function (configuration?: Configurati // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -2843,8 +2843,8 @@ export const CoursesApiFetchParamCreator = function (configuration?: Configurati }; }, /** - * - * @param {number} courseId + * + * @param {number} courseId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -2863,8 +2863,8 @@ export const CoursesApiFetchParamCreator = function (configuration?: Configurati // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -2879,9 +2879,9 @@ export const CoursesApiFetchParamCreator = function (configuration?: Configurati }; }, /** - * - * @param {number} courseId - * @param {UpdateCourseViewModel} [model] + * + * @param {number} courseId + * @param {UpdateCourseViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -2900,8 +2900,8 @@ export const CoursesApiFetchParamCreator = function (configuration?: Configurati // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -2920,7 +2920,7 @@ export const CoursesApiFetchParamCreator = function (configuration?: Configurati }; }, /** - * + * * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -2934,8 +2934,8 @@ export const CoursesApiFetchParamCreator = function (configuration?: Configurati // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -2959,9 +2959,9 @@ export const CoursesApiFetchParamCreator = function (configuration?: Configurati export const CoursesApiFp = function(configuration?: Configuration) { return { /** - * - * @param {number} courseId - * @param {string} lecturerEmail + * + * @param {number} courseId + * @param {string} lecturerEmail * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -2978,9 +2978,9 @@ export const CoursesApiFp = function(configuration?: Configuration) { }; }, /** - * - * @param {number} courseId - * @param {string} studentId + * + * @param {number} courseId + * @param {string} studentId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -2997,8 +2997,8 @@ export const CoursesApiFp = function(configuration?: Configuration) { }; }, /** - * - * @param {number} courseId + * + * @param {number} courseId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -3015,8 +3015,8 @@ export const CoursesApiFp = function(configuration?: Configuration) { }; }, /** - * - * @param {number} courseId + * + * @param {number} courseId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -3033,8 +3033,8 @@ export const CoursesApiFp = function(configuration?: Configuration) { }; }, /** - * - * @param {CreateCourseViewModel} [model] + * + * @param {CreateCourseViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -3051,7 +3051,7 @@ export const CoursesApiFp = function(configuration?: Configuration) { }; }, /** - * + * * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -3068,9 +3068,9 @@ export const CoursesApiFp = function(configuration?: Configuration) { }; }, /** - * - * @param {number} courseId - * @param {string} studentId + * + * @param {number} courseId + * @param {string} studentId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -3087,8 +3087,8 @@ export const CoursesApiFp = function(configuration?: Configuration) { }; }, /** - * - * @param {number} courseId + * + * @param {number} courseId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -3105,9 +3105,9 @@ export const CoursesApiFp = function(configuration?: Configuration) { }; }, /** - * - * @param {number} courseId - * @param {UpdateCourseViewModel} [model] + * + * @param {number} courseId + * @param {UpdateCourseViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -3124,7 +3124,7 @@ export const CoursesApiFp = function(configuration?: Configuration) { }; }, /** - * + * * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -3150,9 +3150,9 @@ export const CoursesApiFp = function(configuration?: Configuration) { export const CoursesApiFactory = function (configuration?: Configuration, fetch?: FetchAPI, basePath?: string) { return { /** - * - * @param {number} courseId - * @param {string} lecturerEmail + * + * @param {number} courseId + * @param {string} lecturerEmail * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -3160,9 +3160,9 @@ export const CoursesApiFactory = function (configuration?: Configuration, fetch? return CoursesApiFp(configuration).apiCoursesAcceptLecturerByCourseIdByLecturerEmailGet(courseId, lecturerEmail, options)(fetch, basePath); }, /** - * - * @param {number} courseId - * @param {string} studentId + * + * @param {number} courseId + * @param {string} studentId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -3170,8 +3170,8 @@ export const CoursesApiFactory = function (configuration?: Configuration, fetch? return CoursesApiFp(configuration).apiCoursesAcceptStudentByCourseIdByStudentIdPost(courseId, studentId, options)(fetch, basePath); }, /** - * - * @param {number} courseId + * + * @param {number} courseId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -3179,8 +3179,8 @@ export const CoursesApiFactory = function (configuration?: Configuration, fetch? return CoursesApiFp(configuration).apiCoursesByCourseIdDelete(courseId, options)(fetch, basePath); }, /** - * - * @param {number} courseId + * + * @param {number} courseId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -3188,8 +3188,8 @@ export const CoursesApiFactory = function (configuration?: Configuration, fetch? return CoursesApiFp(configuration).apiCoursesByCourseIdGet(courseId, options)(fetch, basePath); }, /** - * - * @param {CreateCourseViewModel} [model] + * + * @param {CreateCourseViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -3197,7 +3197,7 @@ export const CoursesApiFactory = function (configuration?: Configuration, fetch? return CoursesApiFp(configuration).apiCoursesCreatePost(model, options)(fetch, basePath); }, /** - * + * * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -3205,9 +3205,9 @@ export const CoursesApiFactory = function (configuration?: Configuration, fetch? return CoursesApiFp(configuration).apiCoursesGet(options)(fetch, basePath); }, /** - * - * @param {number} courseId - * @param {string} studentId + * + * @param {number} courseId + * @param {string} studentId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -3215,8 +3215,8 @@ export const CoursesApiFactory = function (configuration?: Configuration, fetch? return CoursesApiFp(configuration).apiCoursesRejectStudentByCourseIdByStudentIdPost(courseId, studentId, options)(fetch, basePath); }, /** - * - * @param {number} courseId + * + * @param {number} courseId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -3224,9 +3224,9 @@ export const CoursesApiFactory = function (configuration?: Configuration, fetch? return CoursesApiFp(configuration).apiCoursesSignInCourseByCourseIdPost(courseId, options)(fetch, basePath); }, /** - * - * @param {number} courseId - * @param {UpdateCourseViewModel} [model] + * + * @param {number} courseId + * @param {UpdateCourseViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -3234,7 +3234,7 @@ export const CoursesApiFactory = function (configuration?: Configuration, fetch? return CoursesApiFp(configuration).apiCoursesUpdateByCourseIdPost(courseId, model, options)(fetch, basePath); }, /** - * + * * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -3252,9 +3252,9 @@ export const CoursesApiFactory = function (configuration?: Configuration, fetch? */ export class CoursesApi extends BaseAPI { /** - * - * @param {number} courseId - * @param {string} lecturerEmail + * + * @param {number} courseId + * @param {string} lecturerEmail * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof CoursesApi @@ -3264,9 +3264,9 @@ export class CoursesApi extends BaseAPI { } /** - * - * @param {number} courseId - * @param {string} studentId + * + * @param {number} courseId + * @param {string} studentId * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof CoursesApi @@ -3276,8 +3276,8 @@ export class CoursesApi extends BaseAPI { } /** - * - * @param {number} courseId + * + * @param {number} courseId * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof CoursesApi @@ -3287,8 +3287,8 @@ export class CoursesApi extends BaseAPI { } /** - * - * @param {number} courseId + * + * @param {number} courseId * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof CoursesApi @@ -3298,8 +3298,8 @@ export class CoursesApi extends BaseAPI { } /** - * - * @param {CreateCourseViewModel} [model] + * + * @param {CreateCourseViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof CoursesApi @@ -3309,7 +3309,7 @@ export class CoursesApi extends BaseAPI { } /** - * + * * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof CoursesApi @@ -3319,9 +3319,9 @@ export class CoursesApi extends BaseAPI { } /** - * - * @param {number} courseId - * @param {string} studentId + * + * @param {number} courseId + * @param {string} studentId * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof CoursesApi @@ -3331,8 +3331,8 @@ export class CoursesApi extends BaseAPI { } /** - * - * @param {number} courseId + * + * @param {number} courseId * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof CoursesApi @@ -3342,9 +3342,9 @@ export class CoursesApi extends BaseAPI { } /** - * - * @param {number} courseId - * @param {UpdateCourseViewModel} [model] + * + * @param {number} courseId + * @param {UpdateCourseViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof CoursesApi @@ -3354,7 +3354,7 @@ export class CoursesApi extends BaseAPI { } /** - * + * * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof CoursesApi @@ -3372,9 +3372,9 @@ export class CoursesApi extends BaseAPI { export const HomeworksApiFetchParamCreator = function (configuration?: Configuration) { return { /** - * - * @param {number} courseId - * @param {CreateHomeworkViewModel} [homeworkViewModel] + * + * @param {number} courseId + * @param {CreateHomeworkViewModel} [homeworkViewModel] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -3393,8 +3393,8 @@ export const HomeworksApiFetchParamCreator = function (configuration?: Configura // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -3413,8 +3413,8 @@ export const HomeworksApiFetchParamCreator = function (configuration?: Configura }; }, /** - * - * @param {number} homeworkId + * + * @param {number} homeworkId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -3433,8 +3433,8 @@ export const HomeworksApiFetchParamCreator = function (configuration?: Configura // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -3449,8 +3449,8 @@ export const HomeworksApiFetchParamCreator = function (configuration?: Configura }; }, /** - * - * @param {number} homeworkId + * + * @param {number} homeworkId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -3469,8 +3469,8 @@ export const HomeworksApiFetchParamCreator = function (configuration?: Configura // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -3485,9 +3485,9 @@ export const HomeworksApiFetchParamCreator = function (configuration?: Configura }; }, /** - * - * @param {number} homeworkId - * @param {CreateHomeworkViewModel} [homeworkViewModel] + * + * @param {number} homeworkId + * @param {CreateHomeworkViewModel} [homeworkViewModel] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -3506,8 +3506,8 @@ export const HomeworksApiFetchParamCreator = function (configuration?: Configura // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -3535,9 +3535,9 @@ export const HomeworksApiFetchParamCreator = function (configuration?: Configura export const HomeworksApiFp = function(configuration?: Configuration) { return { /** - * - * @param {number} courseId - * @param {CreateHomeworkViewModel} [homeworkViewModel] + * + * @param {number} courseId + * @param {CreateHomeworkViewModel} [homeworkViewModel] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -3554,8 +3554,8 @@ export const HomeworksApiFp = function(configuration?: Configuration) { }; }, /** - * - * @param {number} homeworkId + * + * @param {number} homeworkId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -3572,8 +3572,8 @@ export const HomeworksApiFp = function(configuration?: Configuration) { }; }, /** - * - * @param {number} homeworkId + * + * @param {number} homeworkId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -3590,9 +3590,9 @@ export const HomeworksApiFp = function(configuration?: Configuration) { }; }, /** - * - * @param {number} homeworkId - * @param {CreateHomeworkViewModel} [homeworkViewModel] + * + * @param {number} homeworkId + * @param {CreateHomeworkViewModel} [homeworkViewModel] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -3618,9 +3618,9 @@ export const HomeworksApiFp = function(configuration?: Configuration) { export const HomeworksApiFactory = function (configuration?: Configuration, fetch?: FetchAPI, basePath?: string) { return { /** - * - * @param {number} courseId - * @param {CreateHomeworkViewModel} [homeworkViewModel] + * + * @param {number} courseId + * @param {CreateHomeworkViewModel} [homeworkViewModel] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -3628,8 +3628,8 @@ export const HomeworksApiFactory = function (configuration?: Configuration, fetc return HomeworksApiFp(configuration).apiHomeworksByCourseIdAddPost(courseId, homeworkViewModel, options)(fetch, basePath); }, /** - * - * @param {number} homeworkId + * + * @param {number} homeworkId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -3637,8 +3637,8 @@ export const HomeworksApiFactory = function (configuration?: Configuration, fetc return HomeworksApiFp(configuration).apiHomeworksDeleteByHomeworkIdDelete(homeworkId, options)(fetch, basePath); }, /** - * - * @param {number} homeworkId + * + * @param {number} homeworkId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -3646,9 +3646,9 @@ export const HomeworksApiFactory = function (configuration?: Configuration, fetc return HomeworksApiFp(configuration).apiHomeworksGetByHomeworkIdGet(homeworkId, options)(fetch, basePath); }, /** - * - * @param {number} homeworkId - * @param {CreateHomeworkViewModel} [homeworkViewModel] + * + * @param {number} homeworkId + * @param {CreateHomeworkViewModel} [homeworkViewModel] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -3666,9 +3666,9 @@ export const HomeworksApiFactory = function (configuration?: Configuration, fetc */ export class HomeworksApi extends BaseAPI { /** - * - * @param {number} courseId - * @param {CreateHomeworkViewModel} [homeworkViewModel] + * + * @param {number} courseId + * @param {CreateHomeworkViewModel} [homeworkViewModel] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof HomeworksApi @@ -3678,8 +3678,8 @@ export class HomeworksApi extends BaseAPI { } /** - * - * @param {number} homeworkId + * + * @param {number} homeworkId * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof HomeworksApi @@ -3689,8 +3689,8 @@ export class HomeworksApi extends BaseAPI { } /** - * - * @param {number} homeworkId + * + * @param {number} homeworkId * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof HomeworksApi @@ -3700,9 +3700,9 @@ export class HomeworksApi extends BaseAPI { } /** - * - * @param {number} homeworkId - * @param {CreateHomeworkViewModel} [homeworkViewModel] + * + * @param {number} homeworkId + * @param {CreateHomeworkViewModel} [homeworkViewModel] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof HomeworksApi @@ -3720,7 +3720,7 @@ export class HomeworksApi extends BaseAPI { export const NotificationsApiFetchParamCreator = function (configuration?: Configuration) { return { /** - * + * * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -3734,8 +3734,8 @@ export const NotificationsApiFetchParamCreator = function (configuration?: Confi // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -3750,8 +3750,8 @@ export const NotificationsApiFetchParamCreator = function (configuration?: Confi }; }, /** - * - * @param {Array} [notificationIds] + * + * @param {Array} [notificationIds] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -3765,8 +3765,8 @@ export const NotificationsApiFetchParamCreator = function (configuration?: Confi // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -3794,7 +3794,7 @@ export const NotificationsApiFetchParamCreator = function (configuration?: Confi export const NotificationsApiFp = function(configuration?: Configuration) { return { /** - * + * * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -3811,8 +3811,8 @@ export const NotificationsApiFp = function(configuration?: Configuration) { }; }, /** - * - * @param {Array} [notificationIds] + * + * @param {Array} [notificationIds] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -3838,7 +3838,7 @@ export const NotificationsApiFp = function(configuration?: Configuration) { export const NotificationsApiFactory = function (configuration?: Configuration, fetch?: FetchAPI, basePath?: string) { return { /** - * + * * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -3846,8 +3846,8 @@ export const NotificationsApiFactory = function (configuration?: Configuration, return NotificationsApiFp(configuration).apiNotificationsGetGet(options)(fetch, basePath); }, /** - * - * @param {Array} [notificationIds] + * + * @param {Array} [notificationIds] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -3865,7 +3865,7 @@ export const NotificationsApiFactory = function (configuration?: Configuration, */ export class NotificationsApi extends BaseAPI { /** - * + * * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof NotificationsApi @@ -3875,8 +3875,8 @@ export class NotificationsApi extends BaseAPI { } /** - * - * @param {Array} [notificationIds] + * + * @param {Array} [notificationIds] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof NotificationsApi @@ -3894,10 +3894,10 @@ export class NotificationsApi extends BaseAPI { export const SolutionsApiFetchParamCreator = function (configuration?: Configuration) { return { /** - * - * @param {number} taskId - * @param {number} groupId - * @param {SolutionViewModel} [model] + * + * @param {number} taskId + * @param {number} groupId + * @param {SolutionViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -3921,8 +3921,8 @@ export const SolutionsApiFetchParamCreator = function (configuration?: Configura // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -3941,9 +3941,9 @@ export const SolutionsApiFetchParamCreator = function (configuration?: Configura }; }, /** - * - * @param {number} groupId - * @param {number} taskId + * + * @param {number} groupId + * @param {number} taskId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -3967,8 +3967,8 @@ export const SolutionsApiFetchParamCreator = function (configuration?: Configura // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -3983,8 +3983,8 @@ export const SolutionsApiFetchParamCreator = function (configuration?: Configura }; }, /** - * - * @param {number} solutionId + * + * @param {number} solutionId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -4003,8 +4003,8 @@ export const SolutionsApiFetchParamCreator = function (configuration?: Configura // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -4019,9 +4019,9 @@ export const SolutionsApiFetchParamCreator = function (configuration?: Configura }; }, /** - * - * @param {number} taskId - * @param {SolutionViewModel} [model] + * + * @param {number} taskId + * @param {SolutionViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -4040,8 +4040,8 @@ export const SolutionsApiFetchParamCreator = function (configuration?: Configura // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -4060,8 +4060,8 @@ export const SolutionsApiFetchParamCreator = function (configuration?: Configura }; }, /** - * - * @param {number} solutionId + * + * @param {number} solutionId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -4080,8 +4080,8 @@ export const SolutionsApiFetchParamCreator = function (configuration?: Configura // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -4096,7 +4096,7 @@ export const SolutionsApiFetchParamCreator = function (configuration?: Configura }; }, /** - * + * * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -4110,8 +4110,8 @@ export const SolutionsApiFetchParamCreator = function (configuration?: Configura // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -4126,8 +4126,8 @@ export const SolutionsApiFetchParamCreator = function (configuration?: Configura }; }, /** - * - * @param {number} solutionId + * + * @param {number} solutionId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -4146,8 +4146,8 @@ export const SolutionsApiFetchParamCreator = function (configuration?: Configura // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -4162,10 +4162,10 @@ export const SolutionsApiFetchParamCreator = function (configuration?: Configura }; }, /** - * - * @param {number} solutionId - * @param {number} newRating - * @param {string} [lecturerComment] + * + * @param {number} solutionId + * @param {number} newRating + * @param {string} [lecturerComment] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -4189,8 +4189,8 @@ export const SolutionsApiFetchParamCreator = function (configuration?: Configura // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -4209,9 +4209,9 @@ export const SolutionsApiFetchParamCreator = function (configuration?: Configura }; }, /** - * - * @param {number} taskId - * @param {string} studentId + * + * @param {number} taskId + * @param {string} studentId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -4235,8 +4235,8 @@ export const SolutionsApiFetchParamCreator = function (configuration?: Configura // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -4260,10 +4260,10 @@ export const SolutionsApiFetchParamCreator = function (configuration?: Configura export const SolutionsApiFp = function(configuration?: Configuration) { return { /** - * - * @param {number} taskId - * @param {number} groupId - * @param {SolutionViewModel} [model] + * + * @param {number} taskId + * @param {number} groupId + * @param {SolutionViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -4280,9 +4280,9 @@ export const SolutionsApiFp = function(configuration?: Configuration) { }; }, /** - * - * @param {number} groupId - * @param {number} taskId + * + * @param {number} groupId + * @param {number} taskId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -4299,8 +4299,8 @@ export const SolutionsApiFp = function(configuration?: Configuration) { }; }, /** - * - * @param {number} solutionId + * + * @param {number} solutionId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -4317,9 +4317,9 @@ export const SolutionsApiFp = function(configuration?: Configuration) { }; }, /** - * - * @param {number} taskId - * @param {SolutionViewModel} [model] + * + * @param {number} taskId + * @param {SolutionViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -4336,8 +4336,8 @@ export const SolutionsApiFp = function(configuration?: Configuration) { }; }, /** - * - * @param {number} solutionId + * + * @param {number} solutionId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -4354,7 +4354,7 @@ export const SolutionsApiFp = function(configuration?: Configuration) { }; }, /** - * + * * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -4371,8 +4371,8 @@ export const SolutionsApiFp = function(configuration?: Configuration) { }; }, /** - * - * @param {number} solutionId + * + * @param {number} solutionId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -4389,10 +4389,10 @@ export const SolutionsApiFp = function(configuration?: Configuration) { }; }, /** - * - * @param {number} solutionId - * @param {number} newRating - * @param {string} [lecturerComment] + * + * @param {number} solutionId + * @param {number} newRating + * @param {string} [lecturerComment] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -4409,9 +4409,9 @@ export const SolutionsApiFp = function(configuration?: Configuration) { }; }, /** - * - * @param {number} taskId - * @param {string} studentId + * + * @param {number} taskId + * @param {string} studentId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -4437,10 +4437,10 @@ export const SolutionsApiFp = function(configuration?: Configuration) { export const SolutionsApiFactory = function (configuration?: Configuration, fetch?: FetchAPI, basePath?: string) { return { /** - * - * @param {number} taskId - * @param {number} groupId - * @param {SolutionViewModel} [model] + * + * @param {number} taskId + * @param {number} groupId + * @param {SolutionViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -4448,9 +4448,9 @@ export const SolutionsApiFactory = function (configuration?: Configuration, fetc return SolutionsApiFp(configuration).apiSolutionsByGroupIdByTaskIdPost(taskId, groupId, model, options)(fetch, basePath); }, /** - * - * @param {number} groupId - * @param {number} taskId + * + * @param {number} groupId + * @param {number} taskId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -4458,8 +4458,8 @@ export const SolutionsApiFactory = function (configuration?: Configuration, fetc return SolutionsApiFp(configuration).apiSolutionsByGroupIdTaskSolutionsByTaskIdGet(groupId, taskId, options)(fetch, basePath); }, /** - * - * @param {number} solutionId + * + * @param {number} solutionId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -4467,9 +4467,9 @@ export const SolutionsApiFactory = function (configuration?: Configuration, fetc return SolutionsApiFp(configuration).apiSolutionsBySolutionIdGet(solutionId, options)(fetch, basePath); }, /** - * - * @param {number} taskId - * @param {SolutionViewModel} [model] + * + * @param {number} taskId + * @param {SolutionViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -4477,8 +4477,8 @@ export const SolutionsApiFactory = function (configuration?: Configuration, fetc return SolutionsApiFp(configuration).apiSolutionsByTaskIdPost(taskId, model, options)(fetch, basePath); }, /** - * - * @param {number} solutionId + * + * @param {number} solutionId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -4486,7 +4486,7 @@ export const SolutionsApiFactory = function (configuration?: Configuration, fetc return SolutionsApiFp(configuration).apiSolutionsDeleteBySolutionIdDelete(solutionId, options)(fetch, basePath); }, /** - * + * * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -4494,8 +4494,8 @@ export const SolutionsApiFactory = function (configuration?: Configuration, fetc return SolutionsApiFp(configuration).apiSolutionsGet(options)(fetch, basePath); }, /** - * - * @param {number} solutionId + * + * @param {number} solutionId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -4503,10 +4503,10 @@ export const SolutionsApiFactory = function (configuration?: Configuration, fetc return SolutionsApiFp(configuration).apiSolutionsMarkSolutionFinalBySolutionIdPost(solutionId, options)(fetch, basePath); }, /** - * - * @param {number} solutionId - * @param {number} newRating - * @param {string} [lecturerComment] + * + * @param {number} solutionId + * @param {number} newRating + * @param {string} [lecturerComment] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -4514,9 +4514,9 @@ export const SolutionsApiFactory = function (configuration?: Configuration, fetc return SolutionsApiFp(configuration).apiSolutionsRateSolutionBySolutionIdByNewRatingPost(solutionId, newRating, lecturerComment, options)(fetch, basePath); }, /** - * - * @param {number} taskId - * @param {string} studentId + * + * @param {number} taskId + * @param {string} studentId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -4534,10 +4534,10 @@ export const SolutionsApiFactory = function (configuration?: Configuration, fetc */ export class SolutionsApi extends BaseAPI { /** - * - * @param {number} taskId - * @param {number} groupId - * @param {SolutionViewModel} [model] + * + * @param {number} taskId + * @param {number} groupId + * @param {SolutionViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof SolutionsApi @@ -4547,9 +4547,9 @@ export class SolutionsApi extends BaseAPI { } /** - * - * @param {number} groupId - * @param {number} taskId + * + * @param {number} groupId + * @param {number} taskId * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof SolutionsApi @@ -4559,8 +4559,8 @@ export class SolutionsApi extends BaseAPI { } /** - * - * @param {number} solutionId + * + * @param {number} solutionId * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof SolutionsApi @@ -4570,9 +4570,9 @@ export class SolutionsApi extends BaseAPI { } /** - * - * @param {number} taskId - * @param {SolutionViewModel} [model] + * + * @param {number} taskId + * @param {SolutionViewModel} [model] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof SolutionsApi @@ -4582,8 +4582,8 @@ export class SolutionsApi extends BaseAPI { } /** - * - * @param {number} solutionId + * + * @param {number} solutionId * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof SolutionsApi @@ -4593,7 +4593,7 @@ export class SolutionsApi extends BaseAPI { } /** - * + * * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof SolutionsApi @@ -4603,8 +4603,8 @@ export class SolutionsApi extends BaseAPI { } /** - * - * @param {number} solutionId + * + * @param {number} solutionId * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof SolutionsApi @@ -4614,10 +4614,10 @@ export class SolutionsApi extends BaseAPI { } /** - * - * @param {number} solutionId - * @param {number} newRating - * @param {string} [lecturerComment] + * + * @param {number} solutionId + * @param {number} newRating + * @param {string} [lecturerComment] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof SolutionsApi @@ -4627,9 +4627,9 @@ export class SolutionsApi extends BaseAPI { } /** - * - * @param {number} taskId - * @param {string} studentId + * + * @param {number} taskId + * @param {string} studentId * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof SolutionsApi @@ -4647,8 +4647,8 @@ export class SolutionsApi extends BaseAPI { export const StatisticsApiFetchParamCreator = function (configuration?: Configuration) { return { /** - * - * @param {number} courseId + * + * @param {number} courseId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -4667,8 +4667,8 @@ export const StatisticsApiFetchParamCreator = function (configuration?: Configur // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -4692,8 +4692,8 @@ export const StatisticsApiFetchParamCreator = function (configuration?: Configur export const StatisticsApiFp = function(configuration?: Configuration) { return { /** - * - * @param {number} courseId + * + * @param {number} courseId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -4719,8 +4719,8 @@ export const StatisticsApiFp = function(configuration?: Configuration) { export const StatisticsApiFactory = function (configuration?: Configuration, fetch?: FetchAPI, basePath?: string) { return { /** - * - * @param {number} courseId + * + * @param {number} courseId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -4738,8 +4738,8 @@ export const StatisticsApiFactory = function (configuration?: Configuration, fet */ export class StatisticsApi extends BaseAPI { /** - * - * @param {number} courseId + * + * @param {number} courseId * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof StatisticsApi @@ -4757,9 +4757,9 @@ export class StatisticsApi extends BaseAPI { export const TasksApiFetchParamCreator = function (configuration?: Configuration) { return { /** - * - * @param {number} homeworkId - * @param {CreateTaskViewModel} [taskViewModel] + * + * @param {number} homeworkId + * @param {CreateTaskViewModel} [taskViewModel] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -4778,8 +4778,8 @@ export const TasksApiFetchParamCreator = function (configuration?: Configuration // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -4798,8 +4798,8 @@ export const TasksApiFetchParamCreator = function (configuration?: Configuration }; }, /** - * - * @param {number} taskId + * + * @param {number} taskId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -4818,8 +4818,8 @@ export const TasksApiFetchParamCreator = function (configuration?: Configuration // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -4834,8 +4834,8 @@ export const TasksApiFetchParamCreator = function (configuration?: Configuration }; }, /** - * - * @param {number} taskId + * + * @param {number} taskId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -4854,8 +4854,8 @@ export const TasksApiFetchParamCreator = function (configuration?: Configuration // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -4870,9 +4870,9 @@ export const TasksApiFetchParamCreator = function (configuration?: Configuration }; }, /** - * - * @param {number} taskId - * @param {CreateTaskViewModel} [taskViewModel] + * + * @param {number} taskId + * @param {CreateTaskViewModel} [taskViewModel] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -4891,8 +4891,8 @@ export const TasksApiFetchParamCreator = function (configuration?: Configuration // authentication Bearer required if (configuration && configuration.apiKey) { const localVarApiKeyValue = typeof configuration.apiKey === 'function' - ? configuration.apiKey("Authorization") - : configuration.apiKey; + ? configuration.apiKey("Authorization") + : configuration.apiKey; localVarHeaderParameter["Authorization"] = localVarApiKeyValue; } @@ -4920,9 +4920,9 @@ export const TasksApiFetchParamCreator = function (configuration?: Configuration export const TasksApiFp = function(configuration?: Configuration) { return { /** - * - * @param {number} homeworkId - * @param {CreateTaskViewModel} [taskViewModel] + * + * @param {number} homeworkId + * @param {CreateTaskViewModel} [taskViewModel] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -4939,8 +4939,8 @@ export const TasksApiFp = function(configuration?: Configuration) { }; }, /** - * - * @param {number} taskId + * + * @param {number} taskId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -4957,8 +4957,8 @@ export const TasksApiFp = function(configuration?: Configuration) { }; }, /** - * - * @param {number} taskId + * + * @param {number} taskId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -4975,9 +4975,9 @@ export const TasksApiFp = function(configuration?: Configuration) { }; }, /** - * - * @param {number} taskId - * @param {CreateTaskViewModel} [taskViewModel] + * + * @param {number} taskId + * @param {CreateTaskViewModel} [taskViewModel] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -5003,9 +5003,9 @@ export const TasksApiFp = function(configuration?: Configuration) { export const TasksApiFactory = function (configuration?: Configuration, fetch?: FetchAPI, basePath?: string) { return { /** - * - * @param {number} homeworkId - * @param {CreateTaskViewModel} [taskViewModel] + * + * @param {number} homeworkId + * @param {CreateTaskViewModel} [taskViewModel] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -5013,8 +5013,8 @@ export const TasksApiFactory = function (configuration?: Configuration, fetch?: return TasksApiFp(configuration).apiTasksAddByHomeworkIdPost(homeworkId, taskViewModel, options)(fetch, basePath); }, /** - * - * @param {number} taskId + * + * @param {number} taskId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -5022,8 +5022,8 @@ export const TasksApiFactory = function (configuration?: Configuration, fetch?: return TasksApiFp(configuration).apiTasksDeleteByTaskIdDelete(taskId, options)(fetch, basePath); }, /** - * - * @param {number} taskId + * + * @param {number} taskId * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -5031,9 +5031,9 @@ export const TasksApiFactory = function (configuration?: Configuration, fetch?: return TasksApiFp(configuration).apiTasksGetByTaskIdGet(taskId, options)(fetch, basePath); }, /** - * - * @param {number} taskId - * @param {CreateTaskViewModel} [taskViewModel] + * + * @param {number} taskId + * @param {CreateTaskViewModel} [taskViewModel] * @param {*} [options] Override http request option. * @throws {RequiredError} */ @@ -5051,9 +5051,9 @@ export const TasksApiFactory = function (configuration?: Configuration, fetch?: */ export class TasksApi extends BaseAPI { /** - * - * @param {number} homeworkId - * @param {CreateTaskViewModel} [taskViewModel] + * + * @param {number} homeworkId + * @param {CreateTaskViewModel} [taskViewModel] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof TasksApi @@ -5063,8 +5063,8 @@ export class TasksApi extends BaseAPI { } /** - * - * @param {number} taskId + * + * @param {number} taskId * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof TasksApi @@ -5074,8 +5074,8 @@ export class TasksApi extends BaseAPI { } /** - * - * @param {number} taskId + * + * @param {number} taskId * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof TasksApi @@ -5085,9 +5085,9 @@ export class TasksApi extends BaseAPI { } /** - * - * @param {number} taskId - * @param {CreateTaskViewModel} [taskViewModel] + * + * @param {number} taskId + * @param {CreateTaskViewModel} [taskViewModel] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof TasksApi diff --git a/hwproj.front/src/components/Auth/Login.tsx b/hwproj.front/src/components/Auth/Login.tsx index f53d8c72b..569c2ffa8 100644 --- a/hwproj.front/src/components/Auth/Login.tsx +++ b/hwproj.front/src/components/Auth/Login.tsx @@ -207,4 +207,4 @@ const Login: FC = (props) => { ) } -export default Login +export default Login \ No newline at end of file diff --git a/hwproj.front/src/components/Profile.tsx b/hwproj.front/src/components/Profile.tsx index 936d88e82..82ba333f3 100644 --- a/hwproj.front/src/components/Profile.tsx +++ b/hwproj.front/src/components/Profile.tsx @@ -11,9 +11,10 @@ import ApiSingleton from "api/ApiSingleton"; import { AccountDataDto, NotificationViewModel } from "../api/"; import "./Styles/Profile.css"; import parse from 'html-react-parser'; -import {ChangeEvent, FC, useEffect, useState} from "react"; +import {ChangeEvent, Component, FC, useEffect, useState} from "react"; import {Redirect} from "react-router-dom"; import {makeStyles} from "@material-ui/styles"; +import Button from "@material-ui/core/Button"; interface IProfileState { isLoaded: boolean; @@ -116,6 +117,7 @@ const Profile: FC> = (props) => { } if (profileState.isLoaded) { + const hrefLink = "https://t.me/HwProjBot?start=>"; const fullName = accountState.middleName && accountState.surname ? accountState.name + ' ' + accountState.middleName + ' ' + accountState.surname : accountState.surname @@ -128,6 +130,14 @@ const Profile: FC> = (props) => { {fullName} + {accountState.email} @@ -172,4 +182,4 @@ const Profile: FC> = (props) => { ) } -export default Profile +export default Profile; \ No newline at end of file