Merge pull request #1 from darkstack/Dev

Dev
This commit is contained in:
2019-03-16 13:09:17 +01:00
committed by GitHub
83 changed files with 12912 additions and 214 deletions

0
LaDOSE.Src/ApiLaunch.bat Normal file
View File

View File

@@ -23,41 +23,6 @@ namespace LaDOSE.Api.Controllers
this._gameService = gameService;
}
[HttpGet("GetUsers/{eventId}/{wpEventId}/{gameId}")]
public List<WPUser> GetUsers(int eventId, int wpEventId,int gameId)
{
var game = _gameService.GetById(gameId);
return _service.GetBooking(eventId, wpEventId,game);
}
[HttpGet("Generate/{eventId}/{wpEventId}")]
public bool GenerateChallonge(int eventId, int wpEventId)
{
return _service.CreateChallonge(eventId, wpEventId);
}
}
[Authorize]
[Produces("application/json")]
[Route("api/[controller]")]
public class UtilController : Controller
{
private IUtilService _service;
public UtilController(IUtilService service)
{
_service = service;
}
[HttpGet("UpdateBooking")]
public bool UpdateBooking()
{
return _service.UpdateBooking();
}
}
}

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using LaDOSE.Business.Interface;
using LaDOSE.DTO;
using LaDOSE.Entity;
using LaDOSE.Entity.Context;
using Microsoft.AspNetCore.Authorization;
@@ -13,7 +14,7 @@ namespace LaDOSE.Api.Controllers
[Authorize]
[Route("api/[controller]")]
[Produces("application/json")]
public class GameController : GenericController<IGameService, Game>
public class GameController : GenericControllerDTO<IGameService, Game, GameDTO>
{
public GameController(IGameService service) : base(service)
{

View File

@@ -1,12 +1,14 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using LaDOSE.Business.Interface;
using LaDOSE.Entity;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace LaDOSE.Api.Controllers
{
public class GenericController<T,TU> :Controller where TU : Entity.Context.Entity where T : IBaseService<TU>
public class GenericController<T, TU> : Controller where TU : Entity.Context.Entity where T : IBaseService<TU>
{
protected T _service;
@@ -16,10 +18,11 @@ namespace LaDOSE.Api.Controllers
}
[HttpPost]
public TU Post([FromBody]TU dto)
public TU Post([FromBody] TU dto)
{
return _service.Create(dto);
return _service.AddOrUpdate(dto);
}
[HttpGet]
public List<TU> Get()
{
@@ -27,11 +30,27 @@ namespace LaDOSE.Api.Controllers
return _service.GetAll().ToList();
}
[HttpGet("{id}")]
public TU Get(int id)
{
return _service.GetById(id);
}
[HttpDelete("{id}")]
public IActionResult Delete(int id)
{
try
{
return _service.Delete((int) id) ? (IActionResult) NoContent() : NotFound();
}
catch (Exception)
{
return BadRequest();
}
}
}
}

View File

@@ -0,0 +1,50 @@
using System;
using System.Collections.Generic;
using System.Linq;
using LaDOSE.Business.Interface;
using Microsoft.AspNetCore.Mvc;
namespace LaDOSE.Api.Controllers
{
public class GenericControllerDTO<T, TU, D> : Controller where TU : Entity.Context.Entity where T : IBaseService<TU>
{
protected T _service;
public GenericControllerDTO(T service)
{
_service = service;
}
[HttpPost]
public D Post([FromBody]D dto)
{
TU entity = AutoMapper.Mapper.Map<TU>(dto);
return AutoMapper.Mapper.Map<D>(_service.AddOrUpdate(entity));
}
[HttpGet]
public List<D> Get()
{
return AutoMapper.Mapper.Map<List<D>>(_service.GetAll().ToList());
}
[HttpGet("{id}")]
public D Get(int id)
{
return AutoMapper.Mapper.Map<D>(_service.GetById(id));
}
[HttpDelete("{id}")]
public IActionResult Delete(int id)
{
try
{
return _service.Delete((int)id) ? (IActionResult)NoContent() : NotFound();
}
catch (Exception)
{
return BadRequest();
}
}
}
}

View File

@@ -68,24 +68,24 @@ namespace LaDOSE.Api.Controllers
}
//[AllowAnonymous]
//[HttpPost("register")]
//public IActionResult Register([FromBody]ApplicationUser userDto)
//{
// // map dto to entity
[HttpPost("register")]
public IActionResult Register([FromBody]ApplicationUser userDto)
{
// map dto to entity
// try
// {
// // save
// _userService.Create(userDto, userDto.Password);
// return Ok();
// }
// catch (Exception ex)
// {
// // return error message if there was an exception
// return BadRequest(new { message = ex.Message });
// }
//}
try
{
// save
_userService.Create(userDto, userDto.Password);
return Ok();
}
catch (Exception ex)
{
// return error message if there was an exception
return BadRequest(new { message = ex.Message });
}
}
}

View File

@@ -0,0 +1,93 @@
using System.Collections.Generic;
using AutoMapper;
using LaDOSE.Business.Interface;
using LaDOSE.DTO;
using LaDOSE.Entity.Wordpress;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace LaDOSE.Api.Controllers
{
[Authorize]
[Produces("application/json")]
[Route("api/[controller]")]
public class WordPressController : Controller
{
public IGameService GameService { get; }
private IWordPressService _service;
// GET
public WordPressController(IWordPressService service, IGameService gameService)
{
GameService = gameService;
_service = service;
}
[HttpGet("WPEvent")]
public List<WPEventDTO> Event()
{
var wpEvents = _service.GetWpEvent();
foreach (var wpEvent in wpEvents)
{
foreach (var wpEventWpBooking in wpEvent.WPBookings)
{
wpEventWpBooking.WPEvent = null;
wpEventWpBooking.WPUser.WPBookings = null;
}
}
return Mapper.Map<List<WPEventDTO>>(wpEvents);
}
[HttpGet("NextEvent")]
public WPEventDTO NextEvent()
{
var wpEvents = _service.GetNextWpEvent();
foreach (var wpEventWpBooking in wpEvents.WPBookings)
{
wpEventWpBooking.WPEvent = null;
wpEventWpBooking.WPUser.WPBookings = null;
}
return Mapper.Map<WPEventDTO>(wpEvents);
}
[HttpGet("GetUsers/{wpEventId}/{gameId}")]
public List<WPUserDTO> GetUsers(int wpEventId, int gameId)
{
var game = GameService.GetById(gameId);
return Mapper.Map<List<WPUserDTO>>(_service.GetBooking(wpEventId, game));
}
[HttpGet("GetUsersOptions/{wpEventId}/{gameId}")]
public List<WPUserDTO> GetUsersOptions(int wpEventId, int gameId)
{
var game = GameService.GetById(gameId);
return Mapper.Map<List<WPUserDTO>>(_service.GetBookingOptions(wpEventId, game));
}
[HttpGet("UpdateDb")]
public bool UpdateDb()
{
return _service.UpdateBooking();
}
[HttpGet("CreateChallonge/{gameId:int}/{wpEventId:int}")]
public string CreateChallonge(int gameId, int wpEventId)
{
return _service.CreateChallonge(gameId, wpEventId, null);
}
[HttpPost("CreateChallonge/{gameId:int}/{wpEventId:int}")]
public string CreateChallonge(int gameId, int wpEventId, [FromBody] List<WPUser> additionalPlayer)
{
return _service.CreateChallonge(gameId, wpEventId, additionalPlayer);
}
}
}

View File

@@ -0,0 +1,15 @@
using AutoMapper;
using AutoMapper.Configuration;
namespace LaDOSE.Api.Helpers
{
public static class AutoMapperTwoWay
{
public static void CreateMapTwoWay<TSource, TDestination>(this IMapperConfigurationExpression mapper)
{
mapper.CreateMap<TSource, TDestination>().IgnoreAllPropertiesWithAnInaccessibleSetter().IgnoreAllSourcePropertiesWithAnInaccessibleSetter();
mapper.CreateMap<TDestination, TSource>().IgnoreAllPropertiesWithAnInaccessibleSetter().IgnoreAllSourcePropertiesWithAnInaccessibleSetter();
}
}
}

View File

@@ -5,21 +5,29 @@
</PropertyGroup>
<ItemGroup>
<Folder Include="Services\" />
<Folder Include="wwwroot\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="8.0.0" />
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.9" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.0.4" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="2.1.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LaDOSE.DTO\LaDOSE.DTO.csproj" />
<ProjectReference Include="..\LaDOSE.Entity\LaDOSE.Entity.csproj" />
<ProjectReference Include="..\LaDOSE.Service\LaDOSE.Business.csproj" />
</ItemGroup>
<ItemGroup>
<Reference Include="ChallongeCSharpDriver">
<HintPath>..\..\Library\ChallongeCSharpDriver.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Content Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using LaDOSE.Business.Interface;
@@ -22,6 +23,10 @@ using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using Pomelo.EntityFrameworkCore.MySql;
using Pomelo.EntityFrameworkCore.MySql.Infrastructure;
using AutoMapper;
using LaDOSE.Api.Helpers;
using LaDOSE.Business.Helper;
using LaDOSE.Entity.Wordpress;
namespace LaDOSE.Api
{
@@ -37,14 +42,31 @@ namespace LaDOSE.Api
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
//Fix Gentoo Issue.
var MySqlServer = this.Configuration["MySql:Server"];
var MySqlDatabase = this.Configuration["MySql:Database"];
var MySqlUser = this.Configuration["MySql:User"];
var MySqlPassword = this.Configuration["MySql:Password"];
if (Convert.ToBoolean(this.Configuration["FixGentoo"]))
{
try
{
var loadFrom = Assembly.LoadFrom("ChallongeCSharpDriver.dll");
Console.WriteLine($"Fix Gentoo Ok : {loadFrom.FullName}");
}
catch(Exception exception)
{
Console.WriteLine($"Fix Gentoo NOK : {exception.Message}");
}
}
services.AddCors();
services.AddMvc().AddJsonOptions(x => x.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
services.AddMvc().AddJsonOptions(x =>
{
x.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
x.SerializerSettings.MaxDepth= 4;
});
services.AddDbContextPool<LaDOSEDbContext>( // replace "YourDbContext" with the class name of your DbContext
options => options.UseMySql($"Server={MySqlServer};Database={MySqlDatabase};User={MySqlUser};Password={MySqlPassword};", // replace with your Connection String
mysqlOptions =>
@@ -87,20 +109,31 @@ namespace LaDOSE.Api
ValidateAudience = false
};
});
// configure DI for application services
AddDIConfig(services);
Mapper.Initialize(cfg =>
{
cfg.CreateMap<WPUser, LaDOSE.DTO.WPUserDTO>();
cfg.CreateMap<WPUser, LaDOSE.DTO.WPUserDTO>();
cfg.CreateMap<WPEvent, LaDOSE.DTO.WPEventDTO>();
cfg.CreateMap<ApplicationUser, LaDOSE.DTO.ApplicationUser>();
cfg.CreateMap<WPBooking, LaDOSE.DTO.WPBookingDTO>().ForMember(e=>e.Meta,opt=>opt.MapFrom(s=>s.Meta.CleanWpMeta()));
cfg.CreateMapTwoWay<Game, LaDOSE.DTO.GameDTO>();
});
}
private void AddDIConfig(IServiceCollection services)
{
services.AddTransient<IChallongeProvider>(p => new ChallongeProvider(this.Configuration["ApiKey:ChallongeApiKey"]));
services.AddScoped<IUserService, UserService>();
services.AddScoped<IGameService, GameService>();
services.AddScoped<IEventService, EventService>();
services.AddScoped<ISeasonService, SeasonService>();
services.AddScoped<IUtilService, UtilService>();
services.AddTransient<IChallongeProvider>(p => new ChallongeProvider(this.Configuration["ApiKey:ChallongeApiKey"]));
services.AddScoped<IWordPressService, WordPressService>();
}

View File

@@ -0,0 +1,15 @@

namespace LaDOSE.DTO
{
public class ApplicationUser
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string Token { get; set; }
}
}

View File

@@ -0,0 +1,12 @@
namespace LaDOSE.DTO
{
public class GameDTO
{
public int Id { get; set; }
public string Name { get; set; }
public int Order { get; set; }
public string ImgUrl { get; set; }
public string WordPressTag { get; set; }
public string WordPressTagOs { get; set; }
}
}

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,11 @@
namespace LaDOSE.DTO
{
public class WPBookingDTO
{
public WPUserDTO WpUser { get; set; }
public string Message { get; set; }
public string Meta { get; set; }
}
}

View File

@@ -0,0 +1,17 @@

using System;
using System.Collections.Generic;
namespace LaDOSE.DTO
{
public class WPEventDTO
{
// Id, Name, Slug, Date
public int Id { get; set; }
public string Name { get; set; }
public string Slug { get; set; }
public DateTime? Date { get; set; }
public List<WPBookingDTO> WpBookings { get; set; }
}
}

View File

@@ -0,0 +1,8 @@
namespace LaDOSE.DTO
{
public class WPUserDTO
{
public string Id { get; set; }
public string Name { get; set; }
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="ApiUri" value="http://localhost:5000"/>
<add key="ApiUser" value="User"/>
<add key="ApiPassword" value="Password"/>
</appSettings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
</configuration>

View File

@@ -0,0 +1,17 @@
<Application x:Class="LaDOSE.DesktopApp.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:LaDOSE.DesktopApp"
>
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary>
<local:Bootstrapper x:Key="Bootstrapper" />
</ResourceDictionary>
<ResourceDictionary Source="Themes\Styles.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>

View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
namespace LaDOSE.DesktopApp
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
}
}

View File

@@ -0,0 +1,418 @@
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
namespace LaDOSE.DesktopApp.Behaviors
{
/// <summary>
/// A sync behaviour for a multiselector.
/// </summary>
public static class MultiSelectorBehaviours
{
public static readonly DependencyProperty SynchronizedSelectedItems = DependencyProperty.RegisterAttached(
"SynchronizedSelectedItems", typeof(IList), typeof(MultiSelectorBehaviours), new PropertyMetadata(null, OnSynchronizedSelectedItemsChanged));
private static readonly DependencyProperty SynchronizationManagerProperty = DependencyProperty.RegisterAttached(
"SynchronizationManager", typeof(SynchronizationManager), typeof(MultiSelectorBehaviours), new PropertyMetadata(null));
/// <summary>
/// Gets the synchronized selected items.
/// </summary>
/// <param name="dependencyObject">The dependency object.</param>
/// <returns>The list that is acting as the sync list.</returns>
public static IList GetSynchronizedSelectedItems(DependencyObject dependencyObject)
{
return (IList)dependencyObject.GetValue(SynchronizedSelectedItems);
}
/// <summary>
/// Sets the synchronized selected items.
/// </summary>
/// <param name="dependencyObject">The dependency object.</param>
/// <param name="value">The value to be set as synchronized items.</param>
public static void SetSynchronizedSelectedItems(DependencyObject dependencyObject, IList value)
{
dependencyObject.SetValue(SynchronizedSelectedItems, value);
}
private static SynchronizationManager GetSynchronizationManager(DependencyObject dependencyObject)
{
return (SynchronizationManager)dependencyObject.GetValue(SynchronizationManagerProperty);
}
private static void SetSynchronizationManager(DependencyObject dependencyObject, SynchronizationManager value)
{
dependencyObject.SetValue(SynchronizationManagerProperty, value);
}
private static void OnSynchronizedSelectedItemsChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
if (e.OldValue != null)
{
SynchronizationManager synchronizer = GetSynchronizationManager(dependencyObject);
synchronizer.StopSynchronizing();
SetSynchronizationManager(dependencyObject, null);
}
IList list = e.NewValue as IList;
Selector selector = dependencyObject as Selector;
// check that this property is an IList, and that it is being set on a ListBox
if (list != null && selector != null)
{
SynchronizationManager synchronizer = GetSynchronizationManager(dependencyObject);
if (synchronizer == null)
{
synchronizer = new SynchronizationManager(selector);
SetSynchronizationManager(dependencyObject, synchronizer);
}
synchronizer.StartSynchronizingList();
}
}
/// <summary>
/// A synchronization manager.
/// </summary>
private class SynchronizationManager
{
private readonly Selector _multiSelector;
private TwoListSynchronizer _synchronizer;
/// <summary>
/// Initializes a new instance of the <see cref="SynchronizationManager"/> class.
/// </summary>
/// <param name="selector">The selector.</param>
internal SynchronizationManager(Selector selector)
{
_multiSelector = selector;
}
/// <summary>
/// Starts synchronizing the list.
/// </summary>
public void StartSynchronizingList()
{
IList list = GetSynchronizedSelectedItems(_multiSelector);
if (list != null)
{
_synchronizer = new TwoListSynchronizer(GetSelectedItemsCollection(_multiSelector), list);
_synchronizer.StartSynchronizing();
}
}
/// <summary>
/// Stops synchronizing the list.
/// </summary>
public void StopSynchronizing()
{
_synchronizer.StopSynchronizing();
}
public static IList GetSelectedItemsCollection(Selector selector)
{
if (selector is MultiSelector)
{
return (selector as MultiSelector).SelectedItems;
}
else if (selector is ListBox)
{
return (selector as ListBox).SelectedItems;
}
else
{
throw new InvalidOperationException("Target object has no SelectedItems property to bind.");
}
}
}
}
public class TwoListSynchronizer : IWeakEventListener
{
private static readonly IListItemConverter DefaultConverter = new DoNothingListItemConverter();
private readonly IList _masterList;
private readonly IListItemConverter _masterTargetConverter;
private readonly IList _targetList;
/// <summary>
/// Initializes a new instance of the <see cref="TwoListSynchronizer"/> class.
/// </summary>
/// <param name="masterList">The master list.</param>
/// <param name="targetList">The target list.</param>
/// <param name="masterTargetConverter">The master-target converter.</param>
public TwoListSynchronizer(IList masterList, IList targetList, IListItemConverter masterTargetConverter)
{
_masterList = masterList;
_targetList = targetList;
_masterTargetConverter = masterTargetConverter;
}
/// <summary>
/// Initializes a new instance of the <see cref="TwoListSynchronizer"/> class.
/// </summary>
/// <param name="masterList">The master list.</param>
/// <param name="targetList">The target list.</param>
public TwoListSynchronizer(IList masterList, IList targetList)
: this(masterList, targetList, DefaultConverter)
{
}
private delegate void ChangeListAction(IList list, NotifyCollectionChangedEventArgs e, Converter<object, object> converter);
/// <summary>
/// Starts synchronizing the lists.
/// </summary>
public void StartSynchronizing()
{
ListenForChangeEvents(_masterList);
ListenForChangeEvents(_targetList);
// Update the Target list from the Master list
SetListValuesFromSource(_masterList, _targetList, ConvertFromMasterToTarget);
// In some cases the target list might have its own view on which items should included:
// so update the master list from the target list
// (This is the case with a ListBox SelectedItems collection: only items from the ItemsSource can be included in SelectedItems)
if (!TargetAndMasterCollectionsAreEqual())
{
SetListValuesFromSource(_targetList, _masterList, ConvertFromTargetToMaster);
}
}
/// <summary>
/// Stop synchronizing the lists.
/// </summary>
public void StopSynchronizing()
{
StopListeningForChangeEvents(_masterList);
StopListeningForChangeEvents(_targetList);
}
/// <summary>
/// Receives events from the centralized event manager.
/// </summary>
/// <param name="managerType">The type of the <see cref="T:System.Windows.WeakEventManager"/> calling this method.</param>
/// <param name="sender">Object that originated the event.</param>
/// <param name="e">Event data.</param>
/// <returns>
/// true if the listener handled the event. It is considered an error by the <see cref="T:System.Windows.WeakEventManager"/> handling in WPF to register a listener for an event that the listener does not handle. Regardless, the method should return false if it receives an event that it does not recognize or handle.
/// </returns>
public bool ReceiveWeakEvent(Type managerType, object sender, EventArgs e)
{
HandleCollectionChanged(sender as IList, e as NotifyCollectionChangedEventArgs);
return true;
}
/// <summary>
/// Listens for change events on a list.
/// </summary>
/// <param name="list">The list to listen to.</param>
protected void ListenForChangeEvents(IList list)
{
if (list is INotifyCollectionChanged)
{
CollectionChangedEventManager.AddListener(list as INotifyCollectionChanged, this);
}
}
/// <summary>
/// Stops listening for change events.
/// </summary>
/// <param name="list">The list to stop listening to.</param>
protected void StopListeningForChangeEvents(IList list)
{
if (list is INotifyCollectionChanged)
{
CollectionChangedEventManager.RemoveListener(list as INotifyCollectionChanged, this);
}
}
private void AddItems(IList list, NotifyCollectionChangedEventArgs e, Converter<object, object> converter)
{
int itemCount = e.NewItems.Count;
for (int i = 0; i < itemCount; i++)
{
int insertionPoint = e.NewStartingIndex + i;
if (insertionPoint > list.Count)
{
list.Add(converter(e.NewItems[i]));
}
else
{
list.Insert(insertionPoint, converter(e.NewItems[i]));
}
}
}
private object ConvertFromMasterToTarget(object masterListItem)
{
return _masterTargetConverter == null ? masterListItem : _masterTargetConverter.Convert(masterListItem);
}
private object ConvertFromTargetToMaster(object targetListItem)
{
return _masterTargetConverter == null ? targetListItem : _masterTargetConverter.ConvertBack(targetListItem);
}
private void HandleCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
IList sourceList = sender as IList;
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
PerformActionOnAllLists(AddItems, sourceList, e);
break;
case NotifyCollectionChangedAction.Move:
PerformActionOnAllLists(MoveItems, sourceList, e);
break;
case NotifyCollectionChangedAction.Remove:
PerformActionOnAllLists(RemoveItems, sourceList, e);
break;
case NotifyCollectionChangedAction.Replace:
PerformActionOnAllLists(ReplaceItems, sourceList, e);
break;
case NotifyCollectionChangedAction.Reset:
UpdateListsFromSource(sender as IList);
break;
default:
break;
}
}
private void MoveItems(IList list, NotifyCollectionChangedEventArgs e, Converter<object, object> converter)
{
RemoveItems(list, e, converter);
AddItems(list, e, converter);
}
private void PerformActionOnAllLists(ChangeListAction action, IList sourceList, NotifyCollectionChangedEventArgs collectionChangedArgs)
{
if (sourceList == _masterList)
{
PerformActionOnList(_targetList, action, collectionChangedArgs, ConvertFromMasterToTarget);
}
else
{
PerformActionOnList(_masterList, action, collectionChangedArgs, ConvertFromTargetToMaster);
}
}
private void PerformActionOnList(IList list, ChangeListAction action, NotifyCollectionChangedEventArgs collectionChangedArgs, Converter<object, object> converter)
{
StopListeningForChangeEvents(list);
action(list, collectionChangedArgs, converter);
ListenForChangeEvents(list);
}
private void RemoveItems(IList list, NotifyCollectionChangedEventArgs e, Converter<object, object> converter)
{
int itemCount = e.OldItems.Count;
// for the number of items being removed, remove the item from the Old Starting Index
// (this will cause following items to be shifted down to fill the hole).
for (int i = 0; i < itemCount; i++)
{
list.RemoveAt(e.OldStartingIndex);
}
}
private void ReplaceItems(IList list, NotifyCollectionChangedEventArgs e, Converter<object, object> converter)
{
RemoveItems(list, e, converter);
AddItems(list, e, converter);
}
private void SetListValuesFromSource(IList sourceList, IList targetList, Converter<object, object> converter)
{
StopListeningForChangeEvents(targetList);
targetList.Clear();
foreach (object o in sourceList)
{
targetList.Add(converter(o));
}
ListenForChangeEvents(targetList);
}
private bool TargetAndMasterCollectionsAreEqual()
{
return _masterList.Cast<object>().SequenceEqual(_targetList.Cast<object>().Select(item => ConvertFromTargetToMaster(item)));
}
/// <summary>
/// Makes sure that all synchronized lists have the same values as the source list.
/// </summary>
/// <param name="sourceList">The source list.</param>
private void UpdateListsFromSource(IList sourceList)
{
if (sourceList == _masterList)
{
SetListValuesFromSource(_masterList, _targetList, ConvertFromMasterToTarget);
}
else
{
SetListValuesFromSource(_targetList, _masterList, ConvertFromTargetToMaster);
}
}
/// <summary>
/// An implementation that does nothing in the conversions.
/// </summary>
internal class DoNothingListItemConverter : IListItemConverter
{
/// <summary>
/// Converts the specified master list item.
/// </summary>
/// <param name="masterListItem">The master list item.</param>
/// <returns>The result of the conversion.</returns>
public object Convert(object masterListItem)
{
return masterListItem;
}
/// <summary>
/// Converts the specified target list item.
/// </summary>
/// <param name="targetListItem">The target list item.</param>
/// <returns>The result of the conversion.</returns>
public object ConvertBack(object targetListItem)
{
return targetListItem;
}
}
public interface IListItemConverter
{
/// <summary>
/// Converts the specified master list item.
/// </summary>
/// <param name="masterListItem">The master list item.</param>
/// <returns>The result of the conversion.</returns>
object Convert(object masterListItem);
/// <summary>
/// Converts the specified target list item.
/// </summary>
/// <param name="targetListItem">The target list item.</param>
/// <returns>The result of the conversion.</returns>
object ConvertBack(object targetListItem);
}
}
}

View File

@@ -0,0 +1,173 @@
using System;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interactivity;
namespace LaDOSE.DesktopApp.Behaviors
{
public class TextBoxInputRegExBehaviour : Behavior<TextBox>
{
#region DependencyProperties
public static readonly DependencyProperty RegularExpressionProperty =
DependencyProperty.Register("RegularExpression", typeof(string), typeof(TextBoxInputRegExBehaviour), new FrameworkPropertyMetadata(".*"));
public string RegularExpression
{
get { return (string)GetValue(RegularExpressionProperty); }
set { SetValue(RegularExpressionProperty, value); }
}
public static readonly DependencyProperty MaxLengthProperty =
DependencyProperty.Register("MaxLength", typeof(int), typeof(TextBoxInputRegExBehaviour),
new FrameworkPropertyMetadata(int.MinValue));
public int MaxLength
{
get { return (int)GetValue(MaxLengthProperty); }
set { SetValue(MaxLengthProperty, value); }
}
public static readonly DependencyProperty EmptyValueProperty =
DependencyProperty.Register("EmptyValue", typeof(string), typeof(TextBoxInputRegExBehaviour), null);
public string EmptyValue
{
get { return (string)GetValue(EmptyValueProperty); }
set { SetValue(EmptyValueProperty, value); }
}
#endregion
/// <summary>
/// Attach our behaviour. Add event handlers
/// </summary>
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.PreviewTextInput += PreviewTextInputHandler;
AssociatedObject.PreviewKeyDown += PreviewKeyDownHandler;
DataObject.AddPastingHandler(AssociatedObject, PastingHandler);
}
/// <summary>
/// Deattach our behaviour. remove event handlers
/// </summary>
protected override void OnDetaching()
{
base.OnDetaching();
AssociatedObject.PreviewTextInput -= PreviewTextInputHandler;
AssociatedObject.PreviewKeyDown -= PreviewKeyDownHandler;
DataObject.RemovePastingHandler(AssociatedObject, PastingHandler);
}
#region Event handlers [PRIVATE] --------------------------------------
void PreviewTextInputHandler(object sender, TextCompositionEventArgs e)
{
string text;
if (this.AssociatedObject.Text.Length < this.AssociatedObject.CaretIndex)
text = this.AssociatedObject.Text;
else
{
// Remaining text after removing selected text.
string remainingTextAfterRemoveSelection;
text = TreatSelectedText(out remainingTextAfterRemoveSelection)
? remainingTextAfterRemoveSelection.Insert(AssociatedObject.SelectionStart, e.Text)
: AssociatedObject.Text.Insert(this.AssociatedObject.CaretIndex, e.Text);
}
e.Handled = !ValidateText(text);
}
/// <summary>
/// PreviewKeyDown event handler
/// </summary>
void PreviewKeyDownHandler(object sender, KeyEventArgs e)
{
if (string.IsNullOrEmpty(this.EmptyValue))
return;
string text = null;
// Handle the Backspace key
if (e.Key == Key.Back)
{
if (!this.TreatSelectedText(out text))
{
if (AssociatedObject.SelectionStart > 0)
text = this.AssociatedObject.Text.Remove(AssociatedObject.SelectionStart - 1, 1);
}
}
// Handle the Delete key
else if (e.Key == Key.Delete)
{
// If text was selected, delete it
if (!this.TreatSelectedText(out text) && this.AssociatedObject.Text.Length > AssociatedObject.SelectionStart)
{
// Otherwise delete next symbol
text = this.AssociatedObject.Text.Remove(AssociatedObject.SelectionStart, 1);
}
}
if (text == string.Empty)
{
this.AssociatedObject.Text = this.EmptyValue;
if (e.Key == Key.Back)
AssociatedObject.SelectionStart++;
e.Handled = true;
}
}
private void PastingHandler(object sender, DataObjectPastingEventArgs e)
{
if (e.DataObject.GetDataPresent(DataFormats.Text))
{
string text = Convert.ToString(e.DataObject.GetData(DataFormats.Text));
if (!ValidateText(text))
e.CancelCommand();
}
else
e.CancelCommand();
}
#endregion Event handlers [PRIVATE] -----------------------------------
#region Auxiliary methods [PRIVATE] -----------------------------------
/// <summary>
/// Validate certain text by our regular expression and text length conditions
/// </summary>
/// <param name="text"> Text for validation </param>
/// <returns> True - valid, False - invalid </returns>
private bool ValidateText(string text)
{
return (new Regex(this.RegularExpression, RegexOptions.IgnoreCase)).IsMatch(text) && (MaxLength == int.MinValue || text.Length <= MaxLength);
}
/// <summary>
/// Handle text selection
/// </summary>
/// <returns>true if the character was successfully removed; otherwise, false. </returns>
private bool TreatSelectedText(out string text)
{
text = null;
if (AssociatedObject.SelectionLength <= 0)
return false;
var length = this.AssociatedObject.Text.Length;
if (AssociatedObject.SelectionStart >= length)
return true;
if (AssociatedObject.SelectionStart + AssociatedObject.SelectionLength >= length)
AssociatedObject.SelectionLength = length - AssociatedObject.SelectionStart;
text = this.AssociatedObject.Text.Remove(AssociatedObject.SelectionStart, AssociatedObject.SelectionLength);
return true;
}
#endregion Auxiliary methods [PRIVATE] --------------------------------
}
}

View File

@@ -0,0 +1,57 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Windows;
using Caliburn.Micro;
using LaDOSE.DesktopApp.ViewModels;
using LaDOSE.REST;
namespace LaDOSE.DesktopApp
{
public class Bootstrapper : BootstrapperBase
{
private SimpleContainer container;
public Bootstrapper()
{
Initialize();
}
protected override void Configure()
{
container = new SimpleContainer();
container.Singleton<IWindowManager, WindowManager>();
container.Singleton<RestService>();
container.PerRequest<ShellViewModel>();
}
protected override void OnStartup(object sender, StartupEventArgs e)
{
DisplayRootViewFor<ShellViewModel>();
}
protected override object GetInstance(Type service, string key)
{
return container.GetInstance(service, key);
}
protected override IEnumerable<object> GetAllInstances(Type service)
{
return container.GetAllInstances(service);
}
protected override void BuildUp(object instance)
{
container.BuildUp(instance);
}
}
}

View File

@@ -0,0 +1,219 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{A76AC851-4D43-4BF9-9034-F496888ADAFD}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>LaDOSE.DesktopApp</RootNamespace>
<AssemblyName>LaDOSE.DesktopApp</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
<TargetFrameworkProfile />
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>2</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>64x64.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup>
<NoWin32Manifest>true</NoWin32Manifest>
</PropertyGroup>
<ItemGroup>
<Reference Include="Caliburn.Micro, Version=3.2.0.0, Culture=neutral, PublicKeyToken=8e5891231f2ed21f, processorArchitecture=MSIL">
<HintPath>..\packages\Caliburn.Micro.Core.3.2.0\lib\net45\Caliburn.Micro.dll</HintPath>
</Reference>
<Reference Include="Caliburn.Micro.Platform, Version=3.2.0.0, Culture=neutral, PublicKeyToken=8e5891231f2ed21f, processorArchitecture=MSIL">
<HintPath>..\packages\Caliburn.Micro.3.2.0\lib\net45\Caliburn.Micro.Platform.dll</HintPath>
</Reference>
<Reference Include="Caliburn.Micro.Platform.Core, Version=3.2.0.0, Culture=neutral, PublicKeyToken=8e5891231f2ed21f, processorArchitecture=MSIL">
<HintPath>..\packages\Caliburn.Micro.3.2.0\lib\net45\Caliburn.Micro.Platform.Core.dll</HintPath>
</Reference>
<Reference Include="RestSharp, Version=106.6.9.0, Culture=neutral, PublicKeyToken=598062e77f915f75, processorArchitecture=MSIL">
<HintPath>..\packages\RestSharp.106.6.9\lib\net452\RestSharp.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Data" />
<Reference Include="System.Design" />
<Reference Include="System.Drawing" />
<Reference Include="System.Net" />
<Reference Include="System.Web" />
<Reference Include="System.Web.Extensions" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Windows.Interactivity, Version=4.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Caliburn.Micro.3.2.0\lib\net45\System.Windows.Interactivity.dll</HintPath>
</Reference>
<Reference Include="System.Xml" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xaml">
<RequiredTargetFramework>4.0</RequiredTargetFramework>
</Reference>
<Reference Include="WindowsBase" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="App.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Compile Include="Behaviors\TextBoxInputRegExBehaviour.cs" />
<Compile Include="Behaviors\MultiSelectorBehaviours.cs" />
<Compile Include="Bootstrapper.cs" />
<Compile Include="Themes\LeftMarginMultiplierConverter.cs" />
<Compile Include="Themes\TreeViewItemExtensions.cs" />
<Compile Include="Utils\PhpSerialize.cs" />
<Compile Include="UserControls\BookingUserControl.xaml.cs">
<DependentUpon>BookingUserControl.xaml</DependentUpon>
</Compile>
<Compile Include="Utils\WpEventDeserialize.cs" />
<Compile Include="Utils\WpfUtil.cs" />
<Compile Include="ViewModels\ShellViewModel.cs" />
<Compile Include="ViewModels\GameViewModel.cs" />
<Compile Include="ViewModels\WebNavigationViewModel.cs" />
<Compile Include="ViewModels\WordPressViewModel.cs" />
<Compile Include="Views\WebNavigationView.xaml.cs">
<DependentUpon>WebNavigationView.xaml</DependentUpon>
</Compile>
<Compile Include="Views\ShellView.xaml.cs">
<DependentUpon>ShellView.xaml</DependentUpon>
</Compile>
<Compile Include="Views\GameView.xaml.cs">
<DependentUpon>GameView.xaml</DependentUpon>
</Compile>
<Compile Include="Views\WordPressView.xaml.cs">
<DependentUpon>WordPressView.xaml</DependentUpon>
</Compile>
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Page Include="Themes\Styles.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="UserControls\BookingUserControl.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\WebNavigationView.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Views\ShellView.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Views\GameView.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Views\WordPressView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<None Include="App.config">
<SubType>Designer</SubType>
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LaDOSE.DTO\LaDOSE.DTO.csproj">
<Project>{61201da6-1bc9-4ba1-ac45-70104d391ecd}</Project>
<Name>LaDOSE.DTO</Name>
</ProjectReference>
<ProjectReference Include="..\LaDOSE.REST\LaDOSE.REST.csproj">
<Project>{692c2a72-ab7e-4502-bed8-aa2afa1761cb}</Project>
<Name>LaDOSE.REST</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Resource Include="64x64.ico" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\64x64.png" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.6.1">
<Visible>False</Visible>
<ProductName>Microsoft .NET Framework 4.6.1 %28x86 and x64%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>false</Install>
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<Folder Include="Services\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -0,0 +1,55 @@
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Windows;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("LaDOSE")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("LaDOSE")]
[assembly: AssemblyCopyright("Copyright © 2019")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
//In order to begin building localizable applications, set
//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file
//inside a <PropertyGroup>. For example, if you are using US english
//in your source files, set the <UICulture> to en-US. Then uncomment
//the NeutralResourceLanguage attribute below. Update the "en-US" in
//the line below to match the UICulture setting in the project file.
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,63 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace LaDOSE.DesktopApp.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("LaDOSE.DesktopApp.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}

View File

@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -0,0 +1,26 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace LaDOSE.DesktopApp.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
}
}

View File

@@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
namespace DarkBlendTheme
{
public class LeftMarginMultiplierConverter : IValueConverter
{
public double Length { get; set; }
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var item = value as TreeViewItem;
if (item == null)
return new Thickness(0);
return new Thickness(Length * item.GetDepth(), 0, 0, 0);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new System.NotImplementedException();
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
namespace DarkBlendTheme
{
public static class TreeViewItemExtensions
{
public static int GetDepth(this TreeViewItem item)
{
TreeViewItem parent;
while ((parent = GetParent(item)) != null)
{
return GetDepth(parent) + 1;
}
return 0;
}
private static TreeViewItem GetParent(TreeViewItem item)
{
var parent = VisualTreeHelper.GetParent(item);
while (!(parent is TreeViewItem || parent is TreeView))
{
if (parent == null) return null;
parent = VisualTreeHelper.GetParent(parent);
}
return parent as TreeViewItem;
}
}
}

View File

@@ -0,0 +1,33 @@
<UserControl x:Class="LaDOSE.DesktopApp.UserControls.BookingUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:LaDOSE.DesktopApp.UserControls"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
>
<UserControl.Resources>
</UserControl.Resources>
<Grid>
<ListView Grid.Row ="1" Margin="2" ItemsSource="{Binding Path=Reservation}" TextSearch.TextPath="Name">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" x:Name="Panel" VerticalAlignment="Stretch" >
<TextBlock x:Name="Name" Text="{Binding Name}">
</TextBlock>
</StackPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Valid}" Value="True">
<Setter TargetName="Name" Property="Foreground" Value="Green" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</UserControl>

View File

@@ -0,0 +1,75 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using LaDOSE.DesktopApp.Utils;
using LaDOSE.DTO;
namespace LaDOSE.DesktopApp.UserControls
{
/// <summary>
/// Interaction logic for BookingUserControl.xaml
/// </summary>
public partial class BookingUserControl : UserControl
{
public readonly String[] EventManagerField = new[] {"HR3", "HR2", "COMMENT", "BOOKING_COMMENT"};
public String Current
{
get { return (String)GetValue(CurrentProperty); }
set { SetValue(CurrentProperty, value); }
}
// Using a DependencyProperty as the backing store for Current. This enables animation, styling, binding, etc...
public static readonly DependencyProperty CurrentProperty =
DependencyProperty.Register("Current", typeof(String), typeof(BookingUserControl), new PropertyMetadata("",PropertyChangedCallback));
private static void PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
BookingUserControl uc = d as BookingUserControl;
if (uc != null)
{
uc.Parse((string) e.NewValue);
}
}
public ObservableCollection<Reservation> Reservation { get; set; }
private void Parse(string value)
{
Reservation.Clear();
var games = WpEventDeserialize.Parse(value);
if (games != null) games.OrderBy(e => e.Name).ToList().ForEach(res => Reservation.Add(res));
}
public BookingUserControl()
{
InitializeComponent();
Reservation = new ObservableCollection<Reservation>();
this.DataContext = this;
}
}
}

View File

@@ -0,0 +1,214 @@
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
namespace LaDOSE.DesktopApp.Utils
{
/// <summary>
/// PhpSerializer Class.
/// </summary>
public class PhpSerializer
{
private readonly NumberFormatInfo nfi;
private int pos; //for unserialize
private Dictionary<ArrayList, bool> seenArrayLists; //for serialize (to infinte prevent loops) lol
//types:
// N = null
// s = string
// i = int
// d = double
// a = array (hashtable)
private Dictionary<Hashtable, bool> seenHashtables; //for serialize (to infinte prevent loops)
//http://www.w3.org/TR/REC-xml/#sec-line-ends
public Encoding StringEncoding = new UTF8Encoding();
public bool
XMLSafe = true; //This member tells the serializer wether or not to strip carriage returns from strings when serializing and adding them back in when deserializing
public PhpSerializer()
{
nfi = new NumberFormatInfo();
nfi.NumberGroupSeparator = "";
nfi.NumberDecimalSeparator = ".";
}
public string Serialize(object obj)
{
seenArrayLists = new Dictionary<ArrayList, bool>();
seenHashtables = new Dictionary<Hashtable, bool>();
return Serialize(obj, new StringBuilder()).ToString();
} //Serialize(object obj)
private StringBuilder Serialize(object obj, StringBuilder sb)
{
if (obj == null) return sb.Append("N;");
if (obj is string)
{
var str = (string) obj;
if (XMLSafe)
{
str = str.Replace("\r\n", "\n"); //replace \r\n with \n
str = str.Replace("\r", "\n"); //replace \r not followed by \n with a single \n Should we do this?
}
return sb.Append("s:" + StringEncoding.GetByteCount(str) + ":\"" + str + "\";");
}
if (obj is bool) return sb.Append("b:" + ((bool) obj ? "1" : "0") + ";");
if (obj is int)
{
var i = (int) obj;
return sb.Append("i:" + i.ToString(nfi) + ";");
}
if (obj is double)
{
var d = (double) obj;
return sb.Append("d:" + d.ToString(nfi) + ";");
}
if (obj is ArrayList)
{
if (seenArrayLists.ContainsKey((ArrayList) obj))
return sb.Append("N;"); //cycle detected
seenArrayLists.Add((ArrayList) obj, true);
var a = (ArrayList) obj;
sb.Append("a:" + a.Count + ":{");
for (var i = 0; i < a.Count; i++)
{
Serialize(i, sb);
Serialize(a[i], sb);
}
sb.Append("}");
return sb;
}
if (obj is Hashtable)
{
if (seenHashtables.ContainsKey((Hashtable) obj))
return sb.Append("N;"); //cycle detected
seenHashtables.Add((Hashtable) obj, true);
var a = (Hashtable) obj;
sb.Append("a:" + a.Count + ":{");
foreach (DictionaryEntry entry in a)
{
Serialize(entry.Key, sb);
Serialize(entry.Value, sb);
}
sb.Append("}");
return sb;
}
return sb;
} //Serialize(object obj)
public object Deserialize(string str)
{
pos = 0;
return this.deserialize(str);
} //Deserialize(string str)
private object deserialize(string str)
{
if (str == null || str.Length <= pos)
return new object();
int start, end, length;
string stLen;
switch (str[pos])
{
case 'N':
pos += 2;
return null;
case 'b':
char chBool;
chBool = str[pos + 2];
pos += 4;
return chBool == '1';
case 'i':
string stInt;
start = str.IndexOf(":", pos) + 1;
end = str.IndexOf(";", start);
stInt = str.Substring(start, end - start);
pos += 3 + stInt.Length;
return int.Parse(stInt, nfi);
case 'd':
string stDouble;
start = str.IndexOf(":", pos) + 1;
end = str.IndexOf(";", start);
stDouble = str.Substring(start, end - start);
pos += 3 + stDouble.Length;
return double.Parse(stDouble, nfi);
case 's':
start = str.IndexOf(":", pos) + 1;
end = str.IndexOf(":", start);
stLen = str.Substring(start, end - start);
var bytelen = int.Parse(stLen);
length = bytelen;
//This is the byte length, not the character length - so we migth
//need to shorten it before usage. This also implies bounds checking
if (end + 2 + length >= str.Length) length = str.Length - 2 - end;
var stRet = str.Substring(end + 2, length);
while (StringEncoding.GetByteCount(stRet) > bytelen)
{
length--;
stRet = str.Substring(end + 2, length);
}
pos += 6 + stLen.Length + length;
if (XMLSafe) stRet = stRet.Replace("\n", "\r\n");
return stRet;
case 'a':
//if keys are ints 0 through N, returns an ArrayList, else returns Hashtable
start = str.IndexOf(":", pos) + 1;
end = str.IndexOf(":", start);
stLen = str.Substring(start, end - start);
length = int.Parse(stLen);
var htRet = new Hashtable(length);
var alRet = new ArrayList(length);
pos += 4 + stLen.Length; //a:Len:{
for (var i = 0; i < length; i++)
{
//read key
var key = deserialize(str);
//read value
var val = deserialize(str);
if (alRet != null)
{
if (key is int && (int) key == alRet.Count)
alRet.Add(val);
else
alRet = null;
}
htRet[key] = val;
}
pos++; //skip the }
if (pos < str.Length && str[pos] == ';'
) //skipping our old extra array semi-colon bug (er... php's weirdness)
pos++;
if (alRet != null)
return alRet;
else
return htRet;
default:
return "";
} //switch
} //unserialzie(object)
}
} //class PhpSerializer

View File

@@ -0,0 +1,44 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using LaDOSE.DesktopApp.UserControls;
namespace LaDOSE.DesktopApp.Utils
{
public class Reservation
{
public string Name { get; set; }
public bool Valid { get; set; }
}
public class WpEventDeserialize
{
public static readonly string[] EventManagerField = new[] { "HR3", "HR2", "COMMENT", "BOOKING_COMMENT" };
public static List<Reservation> Parse(string meta)
{
if (meta == null) return new List<Reservation>();
PhpSerializer p = new PhpSerializer();
var b = p.Deserialize(meta);
Hashtable Wpbook = b as Hashtable;
var games = new List<Reservation>();
if (Wpbook != null)
{
Hashtable reg2 = Wpbook["booking"] as Hashtable;
foreach (string reg2Key in reg2.Keys)
{
if (!EventManagerField.Contains(reg2Key.ToUpperInvariant()))
games.Add(new Reservation()
{
Name = reg2Key,
Valid = (string)reg2[reg2Key] == "1"
});
}
return games;
}
return null;
}
}
}

View File

@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Windows;
namespace LaDOSE.DesktopApp.Utils
{
public static class WpfUtil
{
public static void AddUI<T>(this ICollection<T> collection, T item, Action action = null)
{
Action<T> addMethod = collection.Add;
Application.Current.Dispatcher.BeginInvoke(addMethod, item);
if(action!=null)
Application.Current.Dispatcher.BeginInvoke(action);
}
}
}

View File

@@ -0,0 +1,79 @@
using System.Collections.Generic;
using System.Linq;
using Caliburn.Micro;
using LaDOSE.DTO;
using LaDOSE.REST;
namespace LaDOSE.DesktopApp.ViewModels
{
public class GameViewModel : Screen
{
public override string DisplayName => "Games";
private GameDTO _currentGame;
private List<GameDTO> _games;
private RestService RestService { get; set; }
public GameViewModel(RestService restService)
{
this.RestService = restService;
this.Games=new List<GameDTO>();
}
protected override void OnInitialize()
{
LoadGames();
this.CurrentGame = Games.First();
base.OnInitialize();
}
public void LoadGames()
{
var gameDtos = this.RestService.GetGames().OrderBy(e=>e.Order).ToList();
this.Games = gameDtos;
NotifyOfPropertyChange("Games");
}
public List<GameDTO> Games
{
get => _games;
set
{
_games = value;
NotifyOfPropertyChange(()=>this.Games);
}
}
public GameDTO CurrentGame
{
get => _currentGame;
set
{
_currentGame = value;
NotifyOfPropertyChange(()=>CurrentGame);
NotifyOfPropertyChange(() => CanDeleteGame);
}
}
public void Update()
{
this.RestService.UpdateGame(this.CurrentGame);
LoadGames();
}
public void AddGame()
{
var item = new GameDTO();
this.RestService.UpdateGame(item);
LoadGames();
}
public void DeleteGame()
{
this.RestService.DeleteGame(this.CurrentGame.Id);
LoadGames();
}
public bool CanDeleteGame => CurrentGame != null;
}
}

View File

@@ -0,0 +1,52 @@
using System;
using System.Configuration;
using System.Windows;
using System.Windows.Media.Imaging;
using Caliburn.Micro;
using LaDOSE.REST;
namespace LaDOSE.DesktopApp.ViewModels
{
public class ShellViewModel : Conductor<IScreen>.Collection.AllActive
{
protected override void OnInitialize()
{
this.DisplayName = "LaDOSE";
this.AppIcon = BitmapFrame.Create(Application.GetResourceStream(new Uri("/LaDOSE.DesktopApp;component/Resources/64x64.png",
UriKind.RelativeOrAbsolute)).Stream);
var appSettings = ConfigurationManager.AppSettings;
string url = (string)appSettings["ApiUri"];
string user = (string)appSettings["ApiUser"];
string password = (string)appSettings["ApiPassword"];
Uri uri = new Uri(url);
var restService = IoC.Get<RestService>();
restService.Connect(uri, user, password);
var wordPressViewModel = new WordPressViewModel(IoC.Get<RestService>());
ActivateItem(wordPressViewModel);
base.OnInitialize();
}
public BitmapFrame AppIcon { get; set; }
public void LoadEvent()
{
ActivateItem(new WordPressViewModel(IoC.Get<RestService>()));
}
public void LoadGames()
{
ActivateItem(new GameViewModel(IoC.Get<RestService>()));
}
public void OpenWeb()
{
ActivateItem(new WebNavigationViewModel("www.google.com"));
}
}
}

View File

@@ -0,0 +1,15 @@
using Caliburn.Micro;
namespace LaDOSE.DesktopApp.ViewModels
{
public class WebNavigationViewModel : Screen
{
public WebNavigationViewModel(string uri)
{
Uri = uri;
this.DisplayName = Uri;
}
public string Uri { get; set; }
}
}

View File

@@ -0,0 +1,251 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Threading;
using Caliburn.Micro;
using LaDOSE.DesktopApp.Utils;
using LaDOSE.DTO;
using LaDOSE.REST;
using Action = System.Action;
namespace LaDOSE.DesktopApp.ViewModels
{
public class WordPressViewModel : Screen
{
public override string DisplayName => "Events";
private WPEventDTO _selectedWpEvent;
private GameDTO _selectedGame;
private ObservableCollection<WPUserDTO> _players;
private ObservableCollection<WPUserDTO> _playersOptions;
private ObservableCollection<WPUserDTO> _optionalPlayers;
private RestService RestService { get; set; }
public WordPressViewModel(RestService restService)
{
this.RestService = restService;
Players = new ObservableCollection<WPUserDTO>();
PlayersOptions = new ObservableCollection<WPUserDTO>();
OptionalPlayers = new ObservableCollection<WPUserDTO>();
}
#region Auto Property
protected override void OnInitialize()
{
base.OnInitialize();
Task.Factory.StartNew(new Action(this.Load), TaskCreationOptions.LongRunning).ContinueWith(t => { },
CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted,
TaskScheduler.FromCurrentSynchronizationContext());
}
public bool CanGenerate
{
get { return SelectedWpEvent != null && SelectedGame != null && Players?.Count() > 0; }
}
public List<WPEventDTO> Events { get; set; }
public WPEventDTO SelectedWpEvent
{
get => _selectedWpEvent;
set
{
_selectedWpEvent = value;
SelectedGame = null;
ParseGame(_selectedWpEvent);
}
}
public GameDTO SelectedGame
{
get => _selectedGame;
set
{
_selectedGame = value;
Players.Clear();
PlayersOptions.Clear();
Task.Factory.StartNew(LoadPlayers, TaskCreationOptions.LongRunning).ContinueWith(
t => { NotifyOfPropertyChange(() => this.CanGenerate); },
CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion,
TaskScheduler.FromCurrentSynchronizationContext());
NotifyOfPropertyChange(() => SelectedGame);
NotifyOfPropertyChange(() => Players);
NotifyOfPropertyChange(() => PlayersOptions);
NotifyOfPropertyChange(() => this.CanGenerate);
}
}
public ObservableCollection<WPUserDTO> Players
{
get => _players;
set
{
_players = value;
NotifyOfPropertyChange(() => Players);
}
}
public ObservableCollection<WPUserDTO> PlayersOptions
{
get => _playersOptions;
set
{
_playersOptions = value;
NotifyOfPropertyChange(() => PlayersOptions);
}
}
public ObservableCollection<WPUserDTO> OptionalPlayers
{
get => _optionalPlayers;
set
{
_optionalPlayers = value;
NotifyOfPropertyChange(() => OptionalPlayers);
}
}
public ObservableCollection<GameDTO> GamesFound { get; set; }
public List<GameDTO> Games { get; set; }
#endregion
#region Commands
public void UpdateDb()
{
Mouse.OverrideCursor = System.Windows.Input.Cursors.Wait;
var tsk = Task.Factory.StartNew(new Action(()=>this.RestService.RefreshDb()));
tsk.ContinueWith(t =>
{
MessageBox.Show(t.Exception.InnerException.Message);
},
CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted,
TaskScheduler.FromCurrentSynchronizationContext());
MessageBox.Show("Database updated");
}
public void Generate()
{
List<WPUserDTO> test = new List<WPUserDTO>();
test = OptionalPlayers.ToList();
var messageBoxText = this.RestService.CreateChallonge2(SelectedGame.Id, SelectedWpEvent.Id, test);
if (messageBoxText != null && messageBoxText.Length > 0 && !messageBoxText.Contains("error"))
{
System.Diagnostics.Process.Start($"https://challonge.com/{messageBoxText}");
}
else
MessageBox.Show("Didn't work :(");
}
public void LoadEvents()
{
Mouse.OverrideCursor = System.Windows.Input.Cursors.Wait;
var tsk = Task.Factory.StartNew(Load);
tsk.ContinueWith(t =>
{
MessageBox.Show(t.Exception.InnerException.Message);
Mouse.OverrideCursor = System.Windows.Input.Cursors.Arrow;
},
CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted,
TaskScheduler.FromCurrentSynchronizationContext());
}
#endregion
//TODO : Remove the Meta of WPEvent (parse it in Update DB)
private void ParseGame(WPEventDTO selectedWpEvent)
{
var reservation = SelectedWpEvent.WpBookings.FirstOrDefault();
var games = WpEventDeserialize.Parse(reservation.Meta);
GamesFound.Clear();
var foundGames = new List<GameDTO>();
if (games != null)
{
foreach (string wpTag in games.Select(e => e.Name))
{
var foundGame = Games.FirstOrDefault(e =>
e.WordPressTag != null && e.WordPressTag.Split(';').Contains(wpTag));
if (foundGame != null)
{
if (!foundGames.Contains(foundGame))
{
foundGames.Add(foundGame);
}
}
}
}
var orderedEnumerable = foundGames.OrderBy(e => e.Order);
foreach (var gameDto in orderedEnumerable)
{
GamesFound.Add(gameDto);
}
NotifyOfPropertyChange(() => GamesFound);
}
private void LoadPlayers()
{
if (SelectedWpEvent != null)
if (SelectedGame != null)
{
var findUser = FindUser(SelectedWpEvent.Id, SelectedGame);
var findUser2 = FindUser(SelectedWpEvent.Id, SelectedGame,true);
findUser.OrderBy(e=>e.Name).ToList().ForEach((e) => this.Players.AddUI(e,()=>NotifyOfPropertyChange(() => this.CanGenerate)));
findUser2.OrderBy(e => e.Name).ToList().ForEach((e) => this.PlayersOptions.AddUI(e,null));
}
}
private void Load()
{
Application.Current.Dispatcher.Invoke(() =>
System.Windows.Input.Mouse.OverrideCursor = Cursors.Wait);
GamesFound = new ObservableCollection<GameDTO>();
this.Games = this.RestService.GetGames();
var events = this.RestService.GetEvents();
events.ForEach(e => e.WpBookings = e.WpBookings.OrderBy(x => x.WpUser.Name).ToList());
this.Events = events;
NotifyOfPropertyChange("Events");
Application.Current.Dispatcher.Invoke(() =>
System.Windows.Input.Mouse.OverrideCursor = null);
}
public List<WPUserDTO> FindUser(int wpEventId, GameDTO game,bool optional = false)
{
string[] selectedGameWpId;
selectedGameWpId = !optional ? game.WordPressTag.Split(';') : game.WordPressTagOs.Split(';');
var currentWpEvent = this.Events.Where(e => e.Id == wpEventId).ToList();
List<WPBookingDTO> bookings = currentWpEvent.SelectMany(e => e.WpBookings).ToList();
List<WPUserDTO> users = new List<WPUserDTO>();
foreach (var booking in bookings)
{
var reservations = WpEventDeserialize.Parse(booking.Meta);
if (reservations != null)
{
var gamesReservation = reservations.Where(e => e.Valid).Select(e => e.Name);
if (selectedGameWpId.Any(e => gamesReservation.Contains(e)))
{
users.Add(booking.WpUser);
}
}
}
return users;
}
}
}

View File

@@ -0,0 +1,74 @@
<UserControl x:Class="LaDOSE.DesktopApp.Views.GameView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:LaDOSE.DesktopApp.Views"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:behaviors="clr-namespace:LaDOSE.DesktopApp.Behaviors"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid Row="4" Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Button Grid.Row="0" x:Name="LoadGames">Load Games</Button>
<ListView Grid.Row="1" ItemsSource="{Binding Games}" x:Name="GamesListView" SelectedItem="{Binding CurrentGame}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Label Content="{Binding Order}"></Label>
<Label> - </Label>
<Label Content="{Binding Name}"></Label>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Grid Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Button Grid.Row="0" Grid.Column="0" x:Name="AddGame">Add Game</Button>
<Button Grid.Row="0" Grid.Column="1" x:Name="DeleteGame">Delete Game</Button>
<Label Grid.Row="1" Grid.Column="0">Id</Label>
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Path=CurrentGame.Id,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" IsReadOnly="True"></TextBox>
<Label Grid.Row="2" Grid.Column="0">Name</Label>
<TextBox Grid.Row="2" Grid.Column="1" Text="{Binding Path=CurrentGame.Name,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" ></TextBox>
<Label Grid.Row="3" Grid.Column="0">Order</Label>
<TextBox Grid.Row="3" Grid.Column="1" Text="{Binding Path=CurrentGame.Order,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">
<i:Interaction.Behaviors>
<behaviors:TextBoxInputRegExBehaviour RegularExpression="^\d+$" MaxLength="9" EmptyValue="0">
</behaviors:TextBoxInputRegExBehaviour>
</i:Interaction.Behaviors>
</TextBox>
<Label Grid.Row="4" Grid.Column="0">WpTag</Label>
<TextBox Grid.Row="5" Grid.ColumnSpan="2" Text="{Binding Path=CurrentGame.WordPressTag,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" ></TextBox>
<Label Grid.Row="6" Grid.Column="0">WpTagOs</Label>
<TextBox Grid.Row="7" Grid.ColumnSpan="2" Text="{Binding Path=CurrentGame.WordPressTagOs,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" ></TextBox>
<Button Grid.Row="8" Grid.ColumnSpan="2" x:Name="Update">Update</Button>
</Grid>
</Grid>
</UserControl>

View File

@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace LaDOSE.DesktopApp.Views
{
/// <summary>
/// Interaction logic for ShellView.xaml
/// </summary>
public partial class GameView : UserControl
{
public GameView()
{
InitializeComponent();
}
}
}

View File

@@ -0,0 +1,80 @@
<Window x:Class="LaDOSE.DesktopApp.Views.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:LaDOSE.DesktopApp.Views"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:cal="http://www.caliburnproject.org"
Icon="{Binding Path=AppIcon}"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
Style="{StaticResource {x:Type Window}}">
<Window.Resources>
</Window.Resources>
<Grid Row="4" Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Menu Grid.Row="0" DockPanel.Dock="Top">
<MenuItem Header="_File">
<MenuItem Header="_Events">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<cal:ActionMessage MethodName="LoadEvent">
</cal:ActionMessage>
</i:EventTrigger>
</i:Interaction.Triggers>
</MenuItem>
<MenuItem Header="_Games">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<cal:ActionMessage MethodName="LoadGames">
</cal:ActionMessage>
</i:EventTrigger>
</i:Interaction.Triggers>
</MenuItem>
<MenuItem Header="_Web">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<cal:ActionMessage MethodName="OpenWeb">
</cal:ActionMessage>
</i:EventTrigger>
</i:Interaction.Triggers>
</MenuItem>
<MenuItem Header="_Close" />
</MenuItem>
</Menu>
<TabControl Grid.Row="1" x:Name="Items">
<TabControl.ItemTemplate>
<DataTemplate>
<DockPanel>
<TextBlock HorizontalAlignment="Right" Text="{Binding DisplayName}" />
<Button Margin="5,0,0,0"
cal:Message.Attach="DeactivateItem($dataContext,'true')" >
<Grid>
<Canvas Width='8' Height='8'>
<Line X1='2' X2='6' Y1='2' Y2='6'
Stroke='Red' StrokeThickness='1'/>
<Line X1='6' X2='2' Y1='2' Y2='6'
Stroke='Red' StrokeThickness='1'/>
</Canvas>
</Grid>
</Button>
</DockPanel>
</DataTemplate>
</TabControl.ItemTemplate>
</TabControl>
<StatusBar Grid.Row="2">
</StatusBar>
</Grid>
</Window>

View File

@@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace LaDOSE.DesktopApp.Views
{
/// <summary>
/// Interaction logic for ShellView.xaml
/// </summary>
public partial class ShellView : Window
{
public ShellView()
{
InitializeComponent();
}
}
}

View File

@@ -0,0 +1,17 @@
<UserControl x:Class="LaDOSE.DesktopApp.Views.WebNavigationView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:LaDOSE.DesktopApp.Views"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid Row="4" Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
</Grid>
</UserControl>

View File

@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using LaDOSE.DesktopApp.ViewModels;
namespace LaDOSE.DesktopApp.Views
{
/// <summary>
/// Interaction logic for ShellView.xaml
/// </summary>
public partial class WebNavigationView : UserControl
{
public WebNavigationView()
{
InitializeComponent();
}
}
}

View File

@@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace LaDOSE.DesktopApp.Views
{
/// <summary>
/// Interaction logic for ShellView.xaml
/// </summary>
public partial class WebNavigationView : UserControl
{
public WebNavigationView()
{
InitializeComponent();
}
}
}

View File

@@ -0,0 +1,138 @@
<UserControl x:Class="LaDOSE.DesktopApp.Views.WordPressView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:LaDOSE.DesktopApp.Views"
xmlns:userControls="clr-namespace:LaDOSE.DesktopApp.UserControls"
xmlns:cal="http://www.caliburnproject.org"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:behaviors="clr-namespace:LaDOSE.DesktopApp.Behaviors"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid Row="4" Column="2">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="2*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<DockPanel Grid.Row="0">
<Button Margin="2" x:Name="UpdateDb">Update DB</Button>
<Button Margin="2" x:Name="LoadEvents">Load Events</Button>
</DockPanel>
<ListView Grid.Row="1" ItemsSource="{Binding Events}" x:Name="EventsList" Margin="0,0,0,5"
SelectedItem="{Binding SelectedWpEvent, Mode=TwoWay}" >
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Id}" />
<TextBlock Margin="5,0,0,0" Text="{Binding Name}" />
<TextBlock Margin="5,0,0,0" Text="{Binding Date, StringFormat=dd/MM/yyyy}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Grid Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="2*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<ListView Grid.Column="0" ItemsSource="{Binding ElementName=EventsList,Path=SelectedItem.WpBookings}"
x:Name="BookingList" IsTextSearchEnabled="True" TextSearch.TextPath="WpUser.Name" Margin="2" KeyUp="Copy">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<TextBlock Text="{Binding WpUser.Name}">
</TextBlock>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Grid Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="30" />
<RowDefinition Height="60" />
</Grid.RowDefinitions>
<userControls:BookingUserControl Grid.Row="0"
Current="{Binding ElementName=BookingList,Path=SelectedItem.Meta,UpdateSourceTrigger=PropertyChanged}" />
<Label Grid.Row="1">Message</Label>
<TextBox Grid.Row="2" Margin="2" IsReadOnly="True" Text="{Binding ElementName=BookingList,Path=SelectedItem.Message}" TextWrapping="Wrap" AcceptsReturn="False" VerticalScrollBarVisibility="Auto" />
</Grid>
<Grid Grid.Column="2">
<Grid.RowDefinitions>
<RowDefinition Height="30"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Button Grid.Row="0" cal:Message.Attach="Generate">Generate</Button>
<ListView Grid.Row="1" x:Name="GameFoundListView" ItemsSource="{Binding GamesFound}"
SelectedItem="{Binding SelectedGame,UpdateSourceTrigger=PropertyChanged}" IsTextSearchEnabled="True" TextSearch.TextPath="Name" Margin="2">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Name}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Grid Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Grid.Column="0" Orientation="Horizontal">
<Label>Registred Players (</Label>
<Label Content="{Binding Players.Count,UpdateSourceTrigger=PropertyChanged}"></Label>
<Label>)</Label>
</StackPanel>
<ListView Grid.Row="1" Grid.Column="0" Margin="2" x:Name="PlayersList" ItemsSource="{Binding Players,UpdateSourceTrigger=PropertyChanged}" IsTextSearchEnabled="True" TextSearch.TextPath="Name">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Name}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<StackPanel Grid.Row="0" Grid.Column="1" Orientation="Horizontal">
<Label>Optional Players (</Label>
<Label Content="{Binding PlayersOptions.Count,UpdateSourceTrigger=PropertyChanged}"></Label>
<Label>)</Label>
</StackPanel>
<ListView Grid.Row="1" Grid.Column="1" Margin="2" x:Name="PlayersOptionsList" ItemsSource="{Binding PlayersOptions,UpdateSourceTrigger=PropertyChanged}"
IsTextSearchEnabled="True" TextSearch.TextPath="Name" behaviors:MultiSelectorBehaviours.SynchronizedSelectedItems="{Binding OptionalPlayers}"
SelectionMode="Multiple">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Name}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</Grid>
</Grid>
</Grid>
</UserControl>

View File

@@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using LaDOSE.DTO;
using Clipboard = System.Windows.Clipboard;
using KeyEventArgs = System.Windows.Input.KeyEventArgs;
using ListViewItem = System.Windows.Controls.ListViewItem;
using UserControl = System.Windows.Controls.UserControl;
namespace LaDOSE.DesktopApp.Views
{
/// <summary>
/// Interaction logic for ShellView.xaml
/// </summary>
public partial class WordPressView : UserControl
{
public WordPressView()
{
InitializeComponent();
}
private void Copy(object sender, KeyEventArgs e)
{
if (sender != BookingList) return;
if (e.Key == Key.C && (Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
CopySelectedValuesToClipboard();
}
private void CopySelectedValuesToClipboard()
{
var builder = new StringBuilder();
foreach (WPBookingDTO item in BookingList.SelectedItems)
builder.AppendLine(item.WpUser.Name);
Clipboard.SetText(builder.ToString());
}
}
}

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Caliburn.Micro" version="3.2.0" targetFramework="net461" />
<package id="Caliburn.Micro.Core" version="3.2.0" targetFramework="net461" />
<package id="RestSharp" version="106.6.9" targetFramework="net461" />
<package id="WPFThemes.DarkBlend" version="1.0.8" targetFramework="net461" />
</packages>

View File

@@ -4,32 +4,50 @@ using DSharpPlus.CommandsNext.Attributes;
namespace LaDOSE.DiscordBot.Command
{
internal class Result
{
Dependencies dep;
internal class Result
public Result(Dependencies d)
{
Dependencies dep;
public Result(Dependencies d)
{
this.dep = d;
}
[RequireRolesAttribute("Staff")]
[Command("update")]
public async Task UpdateAsync(CommandContext ctx)
{
var tournament = await dep.ChallongeService.GetLastTournament();
await ctx.RespondAsync($"Mise à jour effectuée");
}
[Command("last")]
public async Task LastAsync(CommandContext ctx)
{
var lastTournamentMessage = dep.ChallongeService.GetLastTournamentMessage();
await ctx.RespondAsync(lastTournamentMessage);
}
this.dep = d;
}
[RequireRolesAttribute("Staff")]
[Command("update")]
public async Task UpdateAsync(CommandContext ctx)
{
var tournament = await dep.ChallongeService.GetLastTournament();
await ctx.RespondAsync($"Mise à jour effectuée");
}
[Command("last")]
public async Task LastAsync(CommandContext ctx)
{
var lastTournamentMessage = dep.ChallongeService.GetLastTournamentMessage();
await ctx.RespondAsync(lastTournamentMessage);
}
[RequireRolesAttribute("Staff")]
[Command("inscriptions")]
public async Task InscriptionsAsync(CommandContext ctx)
{
await ctx.TriggerTypingAsync();
var inscrits = dep.WebService.GetInscrits();
await ctx.RespondAsync(inscrits);
}
[RequireRolesAttribute("Staff")]
[Command("UpdateDb")]
public async Task UpdateDbAsync(CommandContext ctx)
{
await ctx.RespondAsync("Mise à jour des inscriptions en cours...");
await ctx.TriggerTypingAsync();
var status = dep.WebService.RefreshDb() ? "Ok" : "erreur";
await ctx.RespondAsync($"Status: {status}");
}
}
}

View File

@@ -14,7 +14,7 @@ namespace LaDOSE.DiscordBot.Command
}
[Command("todo")]
public async Task TwitchAsync(CommandContext ctx, string command,params string[] todo)
public async Task TodoAsync(CommandContext ctx, string command,params string[] todo)
{
await ctx.TriggerTypingAsync();
switch (command.ToUpperInvariant())
@@ -34,6 +34,7 @@ namespace LaDOSE.DiscordBot.Command
};
await ctx.RespondAsync($"invalid id");
break;
}
//await ctx.RespondAsync($"command : {command}, todo: {todo} ");
}

View File

@@ -10,6 +10,6 @@ namespace LaDOSE.DiscordBot
internal CancellationTokenSource Cts { get; set; }
public ChallongeService ChallongeService { get; set; }
public TodoService TodoService { get; set; }
public WebService WebService { get; set; }
}
}

View File

@@ -13,6 +13,10 @@
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.1.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LaDOSE.REST\LaDOSE.REST.csproj" />
</ItemGroup>
<ItemGroup>
<Reference Include="ChallongeCSharpDriver">
<HintPath>..\..\Library\ChallongeCSharpDriver.dll</HintPath>

View File

@@ -31,7 +31,9 @@ namespace LaDOSE.DiscordBot
var discordToken = builder["Discord:Token"].ToString();
var challongeToken = builder["Challonge:Token"].ToString();
var restUrl = builder["REST:Url"].ToString();
var restUser = builder["REST:User"].ToString();
var restPassword = builder["REST:Password"].ToString();
Console.WriteLine($"LaDOSE.Net Discord Bot");
@@ -42,7 +44,7 @@ namespace LaDOSE.DiscordBot
TokenType = TokenType.Bot
});
var webService = new WebService(new Uri(restUrl),restUser,restPassword);
var challongeService = new ChallongeService(challongeToken);
var todoService = new TodoService();
var cts = new CancellationTokenSource();
@@ -56,6 +58,7 @@ namespace LaDOSE.DiscordBot
Cts = cts,
ChallongeService = challongeService,
TodoService = todoService,
WebService = webService
});
dep = d.Build();
}

View File

@@ -1,4 +1,5 @@
using System.IO;
using System;
using System.IO;
namespace LaDOSE.DiscordBot.Service
{
@@ -48,7 +49,7 @@ namespace LaDOSE.DiscordBot.Service
string returnText = "";
var text = File.ReadAllText(db);
var i = 0;
foreach (var line in text.Split('\n'))
foreach (var line in text.Split())
{
if(!string.IsNullOrEmpty(line))
returnText += $"{++i}. {line}";

View File

@@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ChallongeCSharpDriver;
using ChallongeCSharpDriver.Caller;
using ChallongeCSharpDriver.Core.Queries;
using ChallongeCSharpDriver.Core.Results;
using ChallongeCSharpDriver.Main;
using ChallongeCSharpDriver.Main.Objects;
using LaDOSE.DTO;
using LaDOSE.REST;
namespace LaDOSE.DiscordBot.Service
{
public class WebService
{
private RestService restService;
public WebService(Uri uri,string user,string password)
{
restService = new RestService();
restService.Connect(uri,user,password);
}
public String GetInscrits()
{
var wpEventDto = restService.GetNextEvent();
var wpBookingDtos = wpEventDto.WpBookings;
List<String> player= new List<string>();
wpBookingDtos.OrderBy(e=>e.WpUser.Name).ToList().ForEach(e=> player.Add(e.WpUser.Name));
return $"Les Joueurs inscrits pour {wpEventDto.Name} {string.Join(", ", player)}";
}
public bool RefreshDb()
{
return restService.RefreshDb();
}
}
}

View File

@@ -4,5 +4,10 @@
},
"Challonge": {
"Token": "CHALLONGE API TOKEN"
},
"REST": {
"Url": "http://localhost:5000",
"User": "user",
"Password": "password"
}
}

View File

@@ -8,7 +8,9 @@ namespace LaDOSE.Entity
{
public string Name { get; set; }
public string ImgUrl { get; set; }
public int Order { get; set; }
public string WordPressTag { get; set; }
public string WordPressTagOs { get; set; }
public virtual IEnumerable<SeasonGame> Seasons { get; set; }
public virtual IEnumerable<EventGame> Events { get; set; }

View File

@@ -10,6 +10,7 @@
public int WPUserId { get; set; }
public WPUser WPUser { get; set; }
public string Message { get; set; }
public string Meta { get; set; }
}

View File

@@ -11,7 +11,7 @@ namespace LaDOSE.Entity.Wordpress
public int Id { get; set; }
public string Name { get; set; }
public string Slug { get; set; }
public DateTime Date { get; set; }
public DateTime? Date { get; set; }
public virtual IEnumerable<WPBooking> WPBookings { get; set; }
}

View File

@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="RestSharp" Version="106.6.9" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LaDOSE.DTO\LaDOSE.DTO.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,172 @@
using System;
using System.Collections.Generic;
using LaDOSE.DTO;
using RestSharp;
using RestSharp.Authenticators;
using RestSharp.Serialization.Json;
namespace LaDOSE.REST
{
public class RestService
{
public RestClient Client { get; set; }
public RestService() { }
public void Connect(Uri url, string user, string password)
{
Client = new RestClient(url);
var restRequest = new RestRequest("users/auth", Method.POST);
restRequest.AddJsonBody(new {username = user, password = password});
var response = Client.Post(restRequest);
if (response.IsSuccessful)
{
JsonDeserializer d = new JsonDeserializer();
var applicationUser = d.Deserialize<ApplicationUser>(response);
Client.Authenticator = new JwtAuthenticator($"{applicationUser.Token}");
}
else
{
throw new Exception("unable to contact services");
}
}
#region PostFix
private T Post<T>(string resource,T entity)
{
var json = new RestSharp.Serialization.Json.JsonSerializer();
var jsonD = new RestSharp.Serialization.Json.JsonDeserializer();
var request = new RestRequest();
request.Method = Method.POST;
request.Resource = resource;
request.AddHeader("Accept", "application/json");
request.AddHeader("Content-type", "application/json");
request.Parameters.Clear();
request.AddParameter("application/json; charset=utf-8", json.Serialize(entity), ParameterType.RequestBody);
request.AddObject(entity);
var response = Client.Execute(request);
//var content = response.Content; // raw content as string
try
{
return jsonD.Deserialize<T>(response);
}
catch (Exception)
{
return default(T);
}
}
private R Post<P,R>(string resource, P entity)
{
var json = new RestSharp.Serialization.Json.JsonSerializer();
var jsonD = new RestSharp.Serialization.Json.JsonDeserializer();
var request = new RestRequest();
request.Method = Method.POST;
request.Resource = resource;
request.AddHeader("Accept", "application/json");
request.AddHeader("Content-type", "application/json");
request.Parameters.Clear();
request.AddParameter("application/json; charset=utf-8", json.Serialize(entity), ParameterType.RequestBody);
//request.AddObject(entity);
var response = Client.Execute(request);
//var content = response.Content; // raw content as string
try
{
return jsonD.Deserialize<R>(response);
}
catch (Exception)
{
return default(R);
}
}
#endregion
#region WordPress
public List<WPEventDTO> GetEvents()
{
var restRequest = new RestRequest("/api/wordpress/WPEvent", Method.GET);
var restResponse = Client.Get<List<WPEventDTO>>(restRequest);
return restResponse.Data;
}
public WPEventDTO GetNextEvent()
{
var restRequest = new RestRequest("/api/wordpress/NextEvent", Method.GET);
var restResponse = Client.Get<WPEventDTO>(restRequest);
return restResponse.Data;
}
public string CreateChallonge(int gameId, int eventId)
{
var restRequest = new RestRequest($"/api/wordpress/CreateChallonge/{gameId}/{eventId}", Method.GET);
var restResponse = Client.Get(restRequest);
return restResponse.Content;
}
public string CreateChallonge2(int gameId, int eventId, List<WPUserDTO> optionalPlayers)
{
var restResponse = Post<List<WPUserDTO>,string>($"/api/wordpress/CreateChallonge/{gameId}/{eventId}",optionalPlayers);
return restResponse;
}
public bool RefreshDb()
{
var restRequest = new RestRequest("/api/Wordpress/UpdateDb", Method.GET);
var restResponse = Client.Get<bool>(restRequest);
return restResponse.Data;
}
public List<WPUserDTO> GetUsers(int wpEventId, int gameId)
{
var restRequest = new RestRequest($"/api/Wordpress/GetUsers/{wpEventId}/{gameId}", Method.GET);
var restResponse = Client.Get<List<WPUserDTO>>(restRequest);
return restResponse.Data;
}
public List<WPUserDTO> GetUsersOptions(int wpEventId, int gameId)
{
var restRequest = new RestRequest($"/api/Wordpress/GetUsersOptions/{wpEventId}/{gameId}", Method.GET);
var restResponse = Client.Get<List<WPUserDTO>>(restRequest);
return restResponse.Data;
}
#endregion
#region Games
public List<GameDTO> GetGames()
{
var restRequest = new RestRequest("/api/Game", Method.GET);
var restResponse = Client.Get<List<GameDTO>>(restRequest);
return restResponse.Data;
}
public GameDTO UpdateGame(GameDTO game)
{
return Post("Api/Game", game);
}
public bool DeleteGame(int gameId)
{
var restRequest = new RestRequest($"/api/Game/{gameId}", Method.DELETE);
var restResponse = Client.Execute(restRequest);
return restResponse.IsSuccessful;
}
#endregion
#region Events
#endregion
}
}

View File

@@ -0,0 +1,8 @@
namespace LaDOSE.Business.Helper
{
public class Reservation
{
public string Name { get; set; }
public bool Valid { get; set; }
}
}

View File

@@ -0,0 +1,54 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace LaDOSE.Business.Helper
{
public static class WpEventDeserialize
{
public static readonly List<String> EventManagerField =new List<string>(new []{"HR3", "HR2", "COMMENT", "BOOKING_COMMENT"});
public static List<Reservation> Parse(string meta)
{
if (meta == null) return new List<Reservation>();
PhpSerializer p = new PhpSerializer();
var b = p.Deserialize(meta);
Hashtable Wpbook = b as Hashtable;
var games = new List<Reservation>();
if (Wpbook != null)
{
Hashtable reg2 = Wpbook["booking"] as Hashtable;
foreach (string reg2Key in reg2.Keys)
{
if (!EventManagerField.Contains(reg2Key.ToUpperInvariant()))
games.Add(new Reservation()
{
Name = reg2Key,
Valid = (string)reg2[reg2Key] == "1"
});
}
return games;
}
return null;
}
//Quick Fix to not leak Email.
//TODO : Parse this shit and put it in database (and git rid of it in the UI)
public static string CleanWpMeta(this string meta)
{
PhpSerializer p = new PhpSerializer();
var deserialize = p.Deserialize(meta);
Hashtable currentmeta = deserialize as Hashtable;
if (currentmeta != null)
{
currentmeta["registration"] = null;
}
return p.Serialize(currentmeta);
}
}
}

View File

@@ -9,5 +9,7 @@ namespace LaDOSE.Business.Interface
T Create(T entity);
bool Update(T entity);
bool Delete(int id);
T AddOrUpdate(T entity);
}
}

View File

@@ -0,0 +1,5 @@
using System.Collections.Generic;
namespace LaDOSE.Business.Interface
{
}

View File

@@ -6,7 +6,7 @@ namespace LaDOSE.Business.Interface
{
public interface IEventService : IBaseService<Event>
{
bool CreateChallonge(int eventId, int wpEventId);
List<WPUser> GetBooking(int eventId, int wpEventId, Game game);
}
}

View File

@@ -1,7 +0,0 @@
namespace LaDOSE.Business.Interface
{
public interface IUtilService
{
bool UpdateBooking();
}
}

View File

@@ -0,0 +1,16 @@
using System.Collections.Generic;
using LaDOSE.Entity;
using LaDOSE.Entity.Wordpress;
namespace LaDOSE.Business.Interface
{
public interface IWordPressService
{
WPEvent GetNextWpEvent();
List<WPEvent> GetWpEvent();
List<WPUser> GetBooking(int wpEventId, Game game);
List<WPUser> GetBookingOptions(int wpEventId, Game game);
bool UpdateBooking();
string CreateChallonge(int gameId, int wpEventId, IList<WPUser> additionPlayers);
}
}

View File

@@ -13,6 +13,7 @@
<ItemGroup>
<Reference Include="ChallongeCSharpDriver">
<HintPath>..\..\Library\ChallongeCSharpDriver.dll</HintPath>
<Private>true</Private>
</Reference>
</ItemGroup>

View File

@@ -3,42 +3,64 @@ using System.Linq;
using LaDOSE.Business.Interface;
using LaDOSE.Entity.Context;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
namespace LaDOSE.Business.Service
{
public class BaseService<T> : IBaseService<T> where T : class
public class BaseService<T> : IBaseService<T> where T : Entity.Context.Entity
{
protected LaDOSEDbContext _context;
public BaseService(LaDOSEDbContext context)
{
this._context = context;
_context = context;
}
public virtual IEnumerable<T> GetAll()
{
return _context.Set<T>().ToList();
}
public virtual T GetById(int id)
{
return _context.Find<T>(id);
}
public virtual T Create(T entity)
{
var added = _context.Add(entity);
return added.Entity;
}
public virtual bool Update(T entity)
{
var entityEntry = _context.Update(entity);
this._context.SaveChanges();
return _context.Entry(entityEntry).State == EntityState.Unchanged;
}
public virtual bool Delete(int id)
{
var find = _context.Find<T>(id);
_context.Remove(find);
this._context.SaveChanges();
return _context.Entry(find).State == EntityState.Deleted;
}
public virtual T AddOrUpdate(T entity)
{
EntityEntry<T> entityEntry;
if (entity.Id == 0)
{
entityEntry = this._context.Add(entity);
}
else
{
entityEntry = this._context.Update(entity);
}
this._context.SaveChanges();
return entityEntry.Entity;
}
}
}

View File

@@ -15,14 +15,15 @@ namespace LaDOSE.Business.Service
{
private IChallongeProvider _challongeProvider;
public EventService(LaDOSEDbContext context,IChallongeProvider challongeProvider) : base(context)
public EventService(LaDOSEDbContext context, IChallongeProvider challongeProvider) : base(context)
{
this._challongeProvider = challongeProvider;
}
public override Event GetById(int id)
{
return _context.Event.Include(e=>e.Season).Include(e=>e.Games).ThenInclude(e=>e.Game).FirstOrDefault(e=>e.Id == id);
return _context.Event.Include(e => e.Season).Include(e => e.Games).ThenInclude(e => e.Game)
.FirstOrDefault(e => e.Id == id);
}
public override Event Create(Event e)
@@ -37,71 +38,5 @@ namespace LaDOSE.Business.Service
return eventAdded.Entity;
}
public List<WPUser> GetBooking(int eventId, int wpEventId,Game game)
{
var currentEvent = _context.Event.Include(e => e.Games).ThenInclude(e => e.Game).FirstOrDefault(e => e.Id == eventId);
var currentWpEvent = _context.WPEvent.Include(e => e.WPBookings).ThenInclude(e => e.WPUser).Where(e => e.Id == wpEventId).ToList();
List<WPBooking> bookings = currentWpEvent.SelectMany(e => e.WPBookings).ToList();
List<WPUser> users = new List<WPUser>();
foreach (var booking in bookings)
{
PhpSerializer p = new PhpSerializer();
var b = p.Deserialize(booking.Meta);
Hashtable Wpbook = b as Hashtable;
Hashtable reg = Wpbook["registration"] as Hashtable;
Hashtable reg2 = Wpbook["booking"] as Hashtable;
if (reg2.ContainsKey(game.Name) && ((string)reg2[game.Name]) == "1")
{
booking.WPUser.WPBookings = null;
users.Add(booking.WPUser);
}
}
return users;
}
public bool CreateChallonge(int eventId,int wpEventId)
{
var currentEvent = _context.Event.Include(e=>e.Games).ThenInclude(e=>e.Game).FirstOrDefault(e=>e.Id == eventId);
var currentWpEvent = _context.WPEvent.Include(e => e.WPBookings).ThenInclude(e => e.WPUser).Where(e=>e.Id == wpEventId);
var users = currentWpEvent.SelectMany(e => e.WPBookings.Select(u => u.WPUser));
var userNames = users.Select(e => e.Name).Distinct().ToList();
if (currentEvent != null)
{
var games = currentEvent.Games.Select(e => e.Game);
var s = currentEvent.Date.ToString("MM/dd/yy");
foreach (var game in games)
{
var url = $"TestDev{game.Id}{game.Name}";
var name = $"[{s}]Ranking {currentEvent.Name}{game.Name}";
var tournament = _challongeProvider.CreateTournament(name,url).Result;
var eventGame = currentEvent.Games.FirstOrDefault(e => e.GameId == game.Id);
eventGame.ChallongeId = tournament.id;
eventGame.ChallongeUrl = tournament.url;
foreach (var userName in userNames)
{
try
{
_challongeProvider.AddPlayer(tournament.id, userName);
}
catch
{
Console.WriteLine($"Erreur d ajout sur {userName}" );
continue;
}
}
_context.Entry(eventGame).State = EntityState.Modified;
}
_context.SaveChanges();
return true;
}
return false;
}
}
}

View File

@@ -15,11 +15,25 @@ namespace LaDOSE.Business.Service
{
}
public override Game AddOrUpdate(Game entity)
{
if (entity.Order == 0)
{
entity.Order = GetNextFreeOrder();
}
return base.AddOrUpdate(entity);
}
public override IEnumerable<Game> GetAll()
{
return _context.Game.Include(e => e.Seasons).ThenInclude(e=>e.Season).ToList();
}
public int GetNextFreeOrder()
{
int nextFreeOrder = _context.Game.Max(e => e.Order);
return ++nextFreeOrder;
}
}
}

View File

@@ -1,24 +0,0 @@
using LaDOSE.Business.Interface;
using LaDOSE.Entity.Context;
using Microsoft.EntityFrameworkCore;
namespace LaDOSE.Business.Service
{
public class UtilService : IUtilService
{
private LaDOSEDbContext _context;
public UtilService(LaDOSEDbContext context)
{
_context = context;
}
public bool UpdateBooking()
{
_context.Database.SetCommandTimeout(60);
_context.Database.ExecuteSqlCommand("call ladoseapi.ImportEvent();");
_context.Database.SetCommandTimeout(30);
return true;
}
}
}

View File

@@ -0,0 +1,178 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using LaDOSE.Business.Helper;
using LaDOSE.Business.Interface;
using LaDOSE.Entity;
using LaDOSE.Entity.Context;
using LaDOSE.Entity.Wordpress;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
namespace LaDOSE.Business.Service
{
public class WordPressService : IWordPressService
{
private LaDOSEDbContext _context;
private IChallongeProvider _challongeProvider;
public WordPressService(LaDOSEDbContext context, IChallongeProvider challongeProvider)
{
this._context = context;
this._challongeProvider = challongeProvider;
}
public List<WPEvent> GetWpEvent()
{
var wpEvents = _context.Set<WPEvent>().OrderByDescending(e => e.Id).Include(e => e.WPBookings)
.ThenInclude(e => e.WPUser).Where(e => e.WPBookings.Count() != 0).Take(10).ToList();
return wpEvents;
}
public WPEvent GetNextWpEvent()
{
var wpEvents = _context.Set<WPEvent>().OrderByDescending(e=>e.Date).ThenByDescending(e => e.Id)
.Include(e => e.WPBookings).ThenInclude(e => e.WPUser).FirstOrDefault(e => Enumerable.Count<WPBooking>(e.WPBookings) != 0);
return wpEvents;
}
public bool UpdateBooking()
{
_context.Database.SetCommandTimeout(60);
_context.Database.ExecuteSqlCommand("call ladoseapi.ImportEvent();");
_context.Database.SetCommandTimeout(30);
return true;
}
public List<WPUser> GetBooking(int wpEventId, Game game)
{
var selectedGameWpId = game.WordPressTag.Split(';');
var currentWpEvent = _context.WPEvent.Include(e => e.WPBookings).ThenInclude(e => e.WPUser).Where(e => e.Id == wpEventId).ToList();
List<WPBooking> bookings = currentWpEvent.SelectMany(e => e.WPBookings).ToList();
List<WPUser> users = new List<WPUser>();
foreach (var booking in bookings)
{
var reservations = WpEventDeserialize.Parse(booking.Meta);
if (reservations != null)
{
var gamesReservation = reservations.Where(e => e.Valid).Select(e => e.Name);
if (selectedGameWpId.Any(e => gamesReservation.Contains(e)))
{
users.Add(booking.WPUser);
}
}
}
return users;
}
public List<WPUser> GetBookingOptions(int wpEventId, Game game)
{
var selectedGameWpId = game.WordPressTagOs.Split(';');
var currentWpEvent = _context.WPEvent.Include(e => e.WPBookings).ThenInclude(e => e.WPUser).Where(e => e.Id == wpEventId).ToList();
List<WPBooking> bookings = currentWpEvent.SelectMany(e => e.WPBookings).ToList();
List<WPUser> users = new List<WPUser>();
foreach (var booking in bookings)
{
var reservations = WpEventDeserialize.Parse(booking.Meta);
if (reservations != null)
{
var gamesReservation = reservations.Where(e => e.Valid).Select(e => e.Name);
if (selectedGameWpId.Any(e => gamesReservation.Contains(e)))
{
users.Add(booking.WPUser);
}
}
}
return users;
}
public string CreateChallonge(int gameId, int wpEventId, IList<WPUser> additionalPlayers)
{
var selectedGame = _context.Game.FirstOrDefault(e => e.Id == gameId);
var selectedGameWpId = selectedGame.WordPressTag.Split(';');
var currentWpEvent = _context.WPEvent.Include(e => e.WPBookings).ThenInclude(e => e.WPUser)
.Where(e => e.Id == wpEventId);
var users = currentWpEvent.SelectMany(e => e.WPBookings.Select(u => u.WPUser));
var useradded = new List<WPUser>();
if (selectedGame != null)
{
var currentEvent = currentWpEvent.FirstOrDefault();
var eventDate = currentEvent.Date?.ToString("dd/MM/yy");
var remove = currentEvent.Date?.ToString("Mdyy");
var url = $"{remove}{selectedGame.Id}";
var selectedEvent = FormatCurrentEventName(currentEvent.Name);
var name = $"[{eventDate}] LaDOSE.Net - {selectedEvent} - {selectedGame.Name}";
var tournament = _challongeProvider.CreateTournament(name, url).Result;
foreach (var booking in currentEvent.WPBookings)
{
var reservations = WpEventDeserialize.Parse(booking.Meta);
if (reservations != null)
{
var gamesReservation = reservations.Where(e=>e.Valid).Select(e=>e.Name);
if(selectedGameWpId.Any(e => gamesReservation.Contains(e)))
{
try
{
useradded.Add(booking.WPUser);
_challongeProvider.AddPlayer(tournament.id, booking.WPUser.Name);
}
catch
{
Console.WriteLine($"Erreur d ajout sur {booking.WPUser.Name}");
continue;
}
}
}
}
if (additionalPlayers != null && additionalPlayers.Count > 0)
{
foreach (var additionalPlayer in additionalPlayers)
{
if (useradded.All(e => e.Name != additionalPlayer.Name))
{
_challongeProvider.AddPlayer(tournament.id, additionalPlayer.Name);
}
}
}
return tournament.url;
}
return "error while creating challonge";
}
private string FormatCurrentEventName(string currentEventName)
{
if (currentEventName.Contains("-"))
{
var strings = currentEventName.Split('-');
var s = strings[strings.Length-1];
DateTime test;
if (DateTime.TryParse(s, out test))
{
var formatCurrentEventName = currentEventName.Replace(s, "");
formatCurrentEventName= formatCurrentEventName.Replace(" -", "");
return formatCurrentEventName;
}
}
return currentEventName;
}
}
}

View File

@@ -11,6 +11,22 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LaDOSE.Entity", "LaDOSE.Ent
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LaDOSE.Business", "LaDOSE.Service\LaDOSE.Business.csproj", "{952DE665-70B5-492B-BE91-D0111E3BD907}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LaDOSE.DesktopApp", "LaDOSE.DesktopApp\LaDOSE.DesktopApp.csproj", "{A76AC851-4D43-4BF9-9034-F496888ADAFD}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LaDOSE.DTO", "LaDOSE.DTO\LaDOSE.DTO.csproj", "{61201DA6-1BC9-4BA1-AC45-70104D391ECD}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Api", "Api", "{6FC9438E-D93E-4E63-9342-F8A966EE2D06}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Desktop", "Desktop", "{DD52FE00-B822-4DE3-B369-2BFB5F808130}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Bot", "Bot", "{8B9C38FB-2A83-482D-966C-06A5EA1749EB}"
EndProject
Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "Setup", "Setup\Setup.vdproj", "{6825F5F4-EBB5-469F-B935-5B916EA37ACC}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Utils", "Utils", "{2A0E1491-8E15-4062-ABE7-C04AE9655515}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LaDOSE.REST", "LaDOSE.REST\LaDOSE.REST.csproj", "{692C2A72-AB7E-4502-BED8-AA2AFA1761CB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -33,10 +49,34 @@ Global
{952DE665-70B5-492B-BE91-D0111E3BD907}.Debug|Any CPU.Build.0 = Debug|Any CPU
{952DE665-70B5-492B-BE91-D0111E3BD907}.Release|Any CPU.ActiveCfg = Release|Any CPU
{952DE665-70B5-492B-BE91-D0111E3BD907}.Release|Any CPU.Build.0 = Release|Any CPU
{A76AC851-4D43-4BF9-9034-F496888ADAFD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A76AC851-4D43-4BF9-9034-F496888ADAFD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A76AC851-4D43-4BF9-9034-F496888ADAFD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A76AC851-4D43-4BF9-9034-F496888ADAFD}.Release|Any CPU.Build.0 = Release|Any CPU
{61201DA6-1BC9-4BA1-AC45-70104D391ECD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{61201DA6-1BC9-4BA1-AC45-70104D391ECD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{61201DA6-1BC9-4BA1-AC45-70104D391ECD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{61201DA6-1BC9-4BA1-AC45-70104D391ECD}.Release|Any CPU.Build.0 = Release|Any CPU
{6825F5F4-EBB5-469F-B935-5B916EA37ACC}.Debug|Any CPU.ActiveCfg = Debug
{6825F5F4-EBB5-469F-B935-5B916EA37ACC}.Release|Any CPU.ActiveCfg = Release
{692C2A72-AB7E-4502-BED8-AA2AFA1761CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{692C2A72-AB7E-4502-BED8-AA2AFA1761CB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{692C2A72-AB7E-4502-BED8-AA2AFA1761CB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{692C2A72-AB7E-4502-BED8-AA2AFA1761CB}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{C1E8FAF6-3A75-44AC-938D-CA56A5322D1C} = {8B9C38FB-2A83-482D-966C-06A5EA1749EB}
{4D7ED4CC-F78F-4860-B8CE-DA01DCACCBB9} = {6FC9438E-D93E-4E63-9342-F8A966EE2D06}
{B32A4AD5-9A4B-4D12-AAD5-55541F170E2A} = {6FC9438E-D93E-4E63-9342-F8A966EE2D06}
{952DE665-70B5-492B-BE91-D0111E3BD907} = {6FC9438E-D93E-4E63-9342-F8A966EE2D06}
{A76AC851-4D43-4BF9-9034-F496888ADAFD} = {DD52FE00-B822-4DE3-B369-2BFB5F808130}
{61201DA6-1BC9-4BA1-AC45-70104D391ECD} = {6FC9438E-D93E-4E63-9342-F8A966EE2D06}
{6825F5F4-EBB5-469F-B935-5B916EA37ACC} = {DD52FE00-B822-4DE3-B369-2BFB5F808130}
{692C2A72-AB7E-4502-BED8-AA2AFA1761CB} = {2A0E1491-8E15-4062-ABE7-C04AE9655515}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D47DEDD0-C906-439D-81E4-D86BBE723B8C}
EndGlobalSection

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,41 @@
{
"runtimeTarget": {
"name": ".NETCoreApp,Version=v2.0",
"signature": "883f5ab0e357ef56d00e5851b3cee30b45ba651b"
},
"compilationOptions": {},
"targets": {
".NETCoreApp,Version=v2.0": {
"ChallongeCSharpDriver/1.0.0": {
"dependencies": {
"Newtonsoft.Json": "11.0.2"
},
"runtime": {
"ChallongeCSharpDriver.dll": {}
}
},
"Newtonsoft.Json/11.0.2": {
"runtime": {
"lib/netstandard2.0/Newtonsoft.Json.dll": {
"assemblyVersion": "11.0.0.0",
"fileVersion": "11.0.2.21924"
}
}
}
}
},
"libraries": {
"ChallongeCSharpDriver/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Newtonsoft.Json/11.0.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-znZGbws7E4BA9jxNZ7FuiIRI3C9hrgatVQSTKhIYZYNOud4M5VfGlTYi6RdYO5sQrebFuF/g9UEV3hOxDMXF6Q==",
"path": "newtonsoft.json/11.0.2",
"hashPath": "newtonsoft.json.11.0.2.nupkg.sha512"
}
}
}

View File

@@ -1,3 +1,27 @@
# LaDOSE
![Logo](https://www.ladose.net/wp-content/uploads/2016/04/header_small-1.jpg)
# Dependencies
## Server
.netcore 2
AutoMapper
Newtonsoft.Json
Pomelo.EF
## Discord
DSharpPlus
## Desktop
.Net Framework 4.6.1
Caliburn Micro
[Microsoft Visual Studio Installer Projects](https://marketplace.visualstudio.com/items?itemName=VisualStudioClient.MicrosoftVisualStudio2017InstallerProjects#overview)
## Challonge
[ChallongeCSharpDriver](https://github.com/francoislg/ChallongeCSharpDriver)
Modified to work with .net core

View File

@@ -1,6 +1,8 @@
CREATE DATABASE IF NOT EXISTS `ladoseapi` /*!40100 DEFAULT CHARACTER SET utf8 */;
USE `ladoseapi`;
-- MySQL dump 10.13 Distrib 5.7.12, for Win64 (x86_64)
--
-- Host: api.ladose.net Database: ladoseapi
-- Host: localhost Database: ladoseapi
-- ------------------------------------------------------
-- Server version 5.6.40-log
@@ -30,7 +32,7 @@ CREATE TABLE `ApplicationUser` (
`PasswordHash` blob,
`PasswordSalt` blob,
PRIMARY KEY (`Id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -82,9 +84,13 @@ CREATE TABLE `Game` (
`Id` int(11) NOT NULL AUTO_INCREMENT,
`Name` varchar(45) CHARACTER SET utf8 DEFAULT NULL,
`ImgUrl` varchar(255) CHARACTER SET utf8 DEFAULT NULL,
`WordPressTag` varchar(255) DEFAULT NULL,
`WordPressTagOs` varchar(255) DEFAULT NULL,
`Order` int(11) NOT NULL DEFAULT '0',
`Gamecol` varchar(45) DEFAULT NULL,
PRIMARY KEY (`Id`),
UNIQUE KEY `name_UNIQUE` (`Name`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -182,15 +188,15 @@ DELIMITER ;;
CREATE DEFINER=`ladoseapi`@`%` PROCEDURE `ImportEvent`()
BEGIN
INSERT INTO WPEvent (Id, Name,Slug,Date )
select event_id, event_name,event_slug, event_start_date from ladose.wp_em_events
select event_id, event_name,event_slug, event_start_date from wordpressdb.wp_em_events
where event_id not in (select Id from WPEvent);
INSERT INTO WPUser (Id, Name, WPUSerLogin, WPMail)
select ID, display_name, user_login , user_email from ladose.wp_users
select ID, display_name, user_login , user_email from wordpressdb.wp_users
where ID not in (select Id from WPUser);
INSERT INTO WPBooking (WPEventId, WPUserId, Message, Meta)
select event_id, person_id, booking_comment , booking_meta from ladose.wp_em_bookings
select event_id, person_id, booking_comment , booking_meta from wordpressdb.wp_em_bookings
where (event_id , person_id) not in (select WPEventId,WPUserId from WPBooking);
END ;;
DELIMITER ;
@@ -208,5 +214,4 @@ DELIMITER ;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2018-10-08 23:31:28
i
-- Dump completed on 2019-03-16 13:04:14