1
0
Fork 0
mirror of https://github.com/Nioux/AideDeJeu.git synced 2025-10-29 22:45:44 +00:00

Préparation création de la bdd + éviter de recréer des HttpClient à chaque fois

This commit is contained in:
Yan Maniez 2018-05-13 13:02:45 +02:00
parent 1ba7606b20
commit 28d833c94d
9 changed files with 279 additions and 80 deletions

View file

@ -151,23 +151,57 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ImageAsset Include="Media.xcassets\Contents.json" />
<ImageAsset Include="Media.xcassets\AppIcon.appiconset\Contents.json" />
<ImageAsset Include="Media.xcassets\AppIcon.appiconset\Icon-40.png" />
<ImageAsset Include="Media.xcassets\AppIcon.appiconset\Icon-60.png" />
<ImageAsset Include="Media.xcassets\AppIcon.appiconset\Icon-58.png" />
<ImageAsset Include="Media.xcassets\AppIcon.appiconset\Icon-87.png" />
<ImageAsset Include="Media.xcassets\AppIcon.appiconset\Icon-80.png" />
<ImageAsset Include="Media.xcassets\AppIcon.appiconset\Icon-120.png" />
<ImageAsset Include="Media.xcassets\AppIcon.appiconset\Icon-180.png" />
<ImageAsset Include="Media.xcassets\AppIcon.appiconset\Icon-20.png" />
<ImageAsset Include="Media.xcassets\AppIcon.appiconset\Icon-29.png" />
<ImageAsset Include="Media.xcassets\AppIcon.appiconset\Icon-76.png" />
<ImageAsset Include="Media.xcassets\AppIcon.appiconset\Icon-152.png" />
<ImageAsset Include="Media.xcassets\AppIcon.appiconset\Icon-167.png" />
<ImageAsset Include="Media.xcassets\AppIcon.appiconset\Icon-1024.png" />
<ImageAsset Include="Media.xcassets\icon.imageset\Contents.json" />
<ImageAsset Include="Media.xcassets\icon.imageset\black-book.pdf" />
<ImageAsset Include="Media.xcassets\Contents.json">
<Visible>false</Visible>
</ImageAsset>
<ImageAsset Include="Media.xcassets\AppIcon.appiconset\Contents.json">
<Visible>false</Visible>
</ImageAsset>
<ImageAsset Include="Media.xcassets\AppIcon.appiconset\Icon-40.png">
<Visible>false</Visible>
</ImageAsset>
<ImageAsset Include="Media.xcassets\AppIcon.appiconset\Icon-60.png">
<Visible>false</Visible>
</ImageAsset>
<ImageAsset Include="Media.xcassets\AppIcon.appiconset\Icon-58.png">
<Visible>false</Visible>
</ImageAsset>
<ImageAsset Include="Media.xcassets\AppIcon.appiconset\Icon-87.png">
<Visible>false</Visible>
</ImageAsset>
<ImageAsset Include="Media.xcassets\AppIcon.appiconset\Icon-80.png">
<Visible>false</Visible>
</ImageAsset>
<ImageAsset Include="Media.xcassets\AppIcon.appiconset\Icon-120.png">
<Visible>false</Visible>
</ImageAsset>
<ImageAsset Include="Media.xcassets\AppIcon.appiconset\Icon-180.png">
<Visible>false</Visible>
</ImageAsset>
<ImageAsset Include="Media.xcassets\AppIcon.appiconset\Icon-20.png">
<Visible>false</Visible>
</ImageAsset>
<ImageAsset Include="Media.xcassets\AppIcon.appiconset\Icon-29.png">
<Visible>false</Visible>
</ImageAsset>
<ImageAsset Include="Media.xcassets\AppIcon.appiconset\Icon-76.png">
<Visible>false</Visible>
</ImageAsset>
<ImageAsset Include="Media.xcassets\AppIcon.appiconset\Icon-152.png">
<Visible>false</Visible>
</ImageAsset>
<ImageAsset Include="Media.xcassets\AppIcon.appiconset\Icon-167.png">
<Visible>false</Visible>
</ImageAsset>
<ImageAsset Include="Media.xcassets\AppIcon.appiconset\Icon-1024.png">
<Visible>false</Visible>
</ImageAsset>
<ImageAsset Include="Media.xcassets\icon.imageset\Contents.json">
<Visible>false</Visible>
</ImageAsset>
<ImageAsset Include="Media.xcassets\icon.imageset\black-book.pdf">
<Visible>false</Visible>
</ImageAsset>
</ItemGroup>
<ItemGroup>
<Folder Include="Media.xcassets\icon.imageset\" />

View file

@ -1,4 +1,5 @@
using AideDeJeuLib.Spells;
using AideDeJeuLib.Monsters;
using AideDeJeuLib.Spells;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
@ -42,5 +43,30 @@ namespace AideDeJeu.Services
await context.SaveChangesAsync();
}
}
public async Task<IEnumerable<Monster>> GetMonstersAsync()
{
using (var context = CreateContext())
{
//We use OrderByDescending because Posts are generally displayed from most recent to oldest
return await context.Monsters
.AsNoTracking()
.OrderByDescending(monster => monster.Id)
.ToListAsync();
}
}
public async Task AddOrUpdateMonstersAsync(IEnumerable<Monster> monsters)
{
using (var context = CreateContext())
{
// add posts that do not exist in the database
var newMonsters = monsters.Where(
monster => context.Monsters.Any(dbMonster => dbMonster.Id == monster.Id) == false
);
await context.Monsters.AddRangeAsync(newMonsters);
await context.SaveChangesAsync();
}
}
}
}

View file

@ -1,5 +1,10 @@
using AideDeJeu.Tools;
using AideDeJeu.Services;
using AideDeJeu.Tools;
using AideDeJeuLib.Monsters;
using AideDeJeuLib.Spells;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;
@ -13,9 +18,11 @@ namespace AideDeJeu.ViewModels
Title = "À propos de ...";
OpenWebCommand = new Command(() => Device.OpenUri(new Uri("https://nioux.github.io/AideDeJeu/")));
UpdateDataCommand = new Command(async() => await ExecuteUpdateDataCommandAsync());
}
public ICommand OpenWebCommand { get; }
public ICommand UpdateDataCommand { get; }
public string Version {
get
@ -23,5 +30,40 @@ namespace AideDeJeu.ViewModels
return DependencyService.Get<INativeAPI>().GetVersion();
}
}
private int countUpdateData = 0;
private async Task ExecuteUpdateDataCommandAsync()
{
if (countUpdateData++ != 5) return;
IsBusy = true;
var helper = new ItemDatabaseHelper<ItemDatabaseContext>();
using (var spellsScrappers = new SpellsScrappers())
{
var partialSpells = await spellsScrappers.GetSpells();
var spells = new List<Spell>();
foreach (var partialSpell in partialSpells)
{
var spell = await spellsScrappers.GetSpell(partialSpell.Id);
spells.Add(spell);
}
await helper.AddOrUpdateSpellsAsync(spells);
}
using (var monstersScrappers = new MonstersScrappers())
{
var partialMonsters = await monstersScrappers.GetMonsters();
var monsters = new List<Monster>();
foreach (var partialMonster in partialMonsters)
{
var monster = await monstersScrappers.GetMonster(partialMonster.Id);
monsters.Add(monster);
}
await helper.AddOrUpdateMonstersAsync(monsters);
}
IsBusy = false;
}
}
}

View file

@ -12,8 +12,8 @@ namespace AideDeJeu.ViewModels
{
public class BaseViewModel : INotifyPropertyChanged
{
public SpellsScrappers SpellsScrappers => DependencyService.Get<SpellsScrappers>() ?? new SpellsScrappers();
public MonstersScrappers MonsterScrappers => DependencyService.Get<MonstersScrappers>() ?? new MonstersScrappers();
//public SpellsScrappers SpellsScrappers => DependencyService.Get<SpellsScrappers>() ?? new SpellsScrappers();
//public MonstersScrappers MonstersScrappers => DependencyService.Get<MonstersScrappers>() ?? new MonstersScrappers();
bool isBusy = false;
public bool IsBusy

View file

@ -120,8 +120,11 @@ namespace AideDeJeu.ViewModels
try
{
var item = await SpellsScrappers.GetSpell(Item.Id);
Item = item;
using (var spellsScrappers = new SpellsScrappers())
{
var item = await spellsScrappers.GetSpell(Item.Id);
Item = item;
}
}
catch (Exception ex)
{

View file

@ -170,7 +170,11 @@ namespace AideDeJeu.ViewModels
try
{
AllItems.Clear();
var items = await SpellsScrappers.GetSpells(classe: Classes[Classe].Key, niveauMin: Niveaux[NiveauMin].Key, niveauMax: Niveaux[NiveauMax].Key, ecole: Ecoles[Ecole].Key, rituel: Rituels[Rituel].Key, source: Sources[Source].Key);
IEnumerable<Spell> items = null;
using (var spellsScrappers = new SpellsScrappers())
{
items = await spellsScrappers.GetSpells(classe: Classes[Classe].Key, niveauMin: Niveaux[NiveauMin].Key, niveauMax: Niveaux[NiveauMax].Key, ecole: Ecoles[Ecole].Key, rituel: Rituels[Rituel].Key, source: Sources[Source].Key);
}
//try
//{

View file

@ -3,7 +3,8 @@
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="AideDeJeu.Views.AboutPage"
xmlns:vm="clr-namespace:AideDeJeu.ViewModels;"
Title="{Binding Title}">
Title="{Binding Title}"
IsBusy="{Binding IsBusy}">
<ContentPage.BindingContext>
<vm:AboutViewModel />
</ContentPage.BindingContext>
@ -21,7 +22,11 @@
</StackLayout>
<ScrollView Grid.Row="1">
<StackLayout Orientation="Vertical" Padding="16,40,16,40" Spacing="10">
<Label Text="Aide de Jeu" FontSize="22" FontAttributes="Bold" />
<Label Text="Aide de Jeu" FontSize="22" FontAttributes="Bold">
<Label.GestureRecognizers>
<TapGestureRecognizer Command="{Binding UpdateDataCommand}" />
</Label.GestureRecognizers>
</Label>
<Label Text="{Binding Version}" FontAttributes="Bold" FontSize="22" />
<Label Text="Cette application est une aide de jeu pour le plus célèbre des jeux de rôle" />
<Label Text="Son contenu provient du site AideDD, et est traduit du SRD" />

View file

@ -9,28 +9,73 @@ using System.Threading.Tasks;
namespace AideDeJeuLib.Monsters
{
public class MonstersScrappers
public class MonstersScrappers : IDisposable
{
private HttpClient _Client = null;
public HttpClient GetHttpClient()
{
var client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("text/html"));
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/xhtml+xml"));
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/xml"));
client.DefaultRequestHeaders.AcceptLanguage.Add(new System.Net.Http.Headers.StringWithQualityHeaderValue("fr"));
client.DefaultRequestHeaders.AcceptLanguage.Add(new System.Net.Http.Headers.StringWithQualityHeaderValue("fr-FR"));
return client;
if (_Client == null)
{
var client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("text/html"));
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/xhtml+xml"));
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/xml"));
client.DefaultRequestHeaders.AcceptLanguage.Add(new System.Net.Http.Headers.StringWithQualityHeaderValue("fr"));
client.DefaultRequestHeaders.AcceptLanguage.Add(new System.Net.Http.Headers.StringWithQualityHeaderValue("fr-FR"));
_Client = client;
}
return _Client;
}
#region IDisposable Support
private bool disposedValue = false; // Pour détecter les appels redondants
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
// TODO: supprimer l'état managé (objets managés).
if (_Client != null)
{
_Client.Dispose();
_Client = null;
}
}
// TODO: libérer les ressources non managées (objets non managés) et remplacer un finaliseur ci-dessous.
// TODO: définir les champs de grande taille avec la valeur Null.
disposedValue = true;
}
}
// TODO: remplacer un finaliseur seulement si la fonction Dispose(bool disposing) ci-dessus a du code pour libérer les ressources non managées.
// ~SpellsScrappers() {
// // Ne modifiez pas ce code. Placez le code de nettoyage dans Dispose(bool disposing) ci-dessus.
// Dispose(false);
// }
// Ce code est ajouté pour implémenter correctement le modèle supprimable.
public void Dispose()
{
// Ne modifiez pas ce code. Placez le code de nettoyage dans Dispose(bool disposing) ci-dessus.
Dispose(true);
// TODO: supprimer les marques de commentaire pour la ligne suivante si le finaliseur est remplacé ci-dessus.
// GC.SuppressFinalize(this);
}
#endregion
public async Task<IEnumerable<Monster>> GetMonsters(string category = "", string type = "", string minPower = "", string maxPower = "", string size = "", string legendary = "", string source = "srd")
{
string html = null;
using (var client = GetHttpClient())
{
// https://www.aidedd.org/regles/monstres/?min=.25&max=20&c=M&sz=TP&lg=si&t=Humano%C3%AFde&s=srd
var client = GetHttpClient();
// https://www.aidedd.org/regles/monstres/?min=.25&max=20&c=M&sz=TP&lg=si&t=Humano%C3%AFde&s=srd
html = await client.GetStringAsync(string.Format($"https://www.aidedd.org/regles/monstres/?c={category}&t={type}&min={minPower}&max={maxPower}&sz={size}&lg={legendary}&s={source}", category, type, minPower, maxPower, size, legendary, source));
html = await client.GetStringAsync(string.Format($"https://www.aidedd.org/regles/monstres/?c={category}&t={type}&min={minPower}&max={maxPower}&sz={size}&lg={legendary}&s={source}", category, type, minPower, maxPower, size, legendary, source));
}
var pack = new HtmlDocument();
pack.LoadHtml(html);
var trs = pack.GetElementbyId("liste").Element("table").Elements("tr").ToList();
@ -72,12 +117,11 @@ namespace AideDeJeuLib.Monsters
public async Task<Monster> GetMonster(string id)
{
string html = null;
using (var client = GetHttpClient())
{
// https://www.aidedd.org/dnd/monstres.php?vf=aarakocra
var client = GetHttpClient();
// https://www.aidedd.org/dnd/monstres.php?vf=aarakocra
html = await client.GetStringAsync(string.Format($"https://www.aidedd.org/dnd/monstres.php?vf={id}", id));
html = await client.GetStringAsync(string.Format($"https://www.aidedd.org/dnd/monstres.php?vf={id}", id));
}
var pack = new HtmlDocument();
pack.LoadHtml(html);
var divBloc = pack.DocumentNode.SelectNodes("//div[contains(@class,'bloc')]").FirstOrDefault();

View file

@ -8,29 +8,73 @@ using System.Threading.Tasks;
namespace AideDeJeuLib.Spells
{
public class SpellsScrappers
public class SpellsScrappers : IDisposable
{
private HttpClient _Client = null;
public HttpClient GetHttpClient()
{
var client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("text/html"));
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/xhtml+xml"));
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/xml"));
client.DefaultRequestHeaders.AcceptLanguage.Add(new System.Net.Http.Headers.StringWithQualityHeaderValue("fr"));
client.DefaultRequestHeaders.AcceptLanguage.Add(new System.Net.Http.Headers.StringWithQualityHeaderValue("fr-FR"));
return client;
if (_Client == null)
{
var client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("text/html"));
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/xhtml+xml"));
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/xml"));
client.DefaultRequestHeaders.AcceptLanguage.Add(new System.Net.Http.Headers.StringWithQualityHeaderValue("fr"));
client.DefaultRequestHeaders.AcceptLanguage.Add(new System.Net.Http.Headers.StringWithQualityHeaderValue("fr-FR"));
_Client = client;
}
return _Client;
}
#region IDisposable Support
private bool disposedValue = false; // Pour détecter les appels redondants
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
// TODO: supprimer l'état managé (objets managés).
if (_Client != null)
{
_Client.Dispose();
_Client = null;
}
}
// TODO: libérer les ressources non managées (objets non managés) et remplacer un finaliseur ci-dessous.
// TODO: définir les champs de grande taille avec la valeur Null.
disposedValue = true;
}
}
// TODO: remplacer un finaliseur seulement si la fonction Dispose(bool disposing) ci-dessus a du code pour libérer les ressources non managées.
// ~SpellsScrappers() {
// // Ne modifiez pas ce code. Placez le code de nettoyage dans Dispose(bool disposing) ci-dessus.
// Dispose(false);
// }
// Ce code est ajouté pour implémenter correctement le modèle supprimable.
public void Dispose()
{
// Ne modifiez pas ce code. Placez le code de nettoyage dans Dispose(bool disposing) ci-dessus.
Dispose(true);
// TODO: supprimer les marques de commentaire pour la ligne suivante si le finaliseur est remplacé ci-dessus.
// GC.SuppressFinalize(this);
}
#endregion
public async Task<IEnumerable<Spell>> GetSpells(string classe = "", string niveauMin = "", string niveauMax = "", string ecole = "", string rituel = "", string source = "srd")
{
string html = null;
using (var client = GetHttpClient())
{
// https://www.aidedd.org/regles/sorts/
var client = GetHttpClient();
// https://www.aidedd.org/regles/sorts/
var url = string.Format("https://www.aidedd.org/regles/sorts/?c={0}&min={1}&max={2}&e={3}&r={4}&s={5}", classe, niveauMin, niveauMax, ecole, rituel, source);
html = await client.GetStringAsync(url);
var url = string.Format("https://www.aidedd.org/regles/sorts/?c={0}&min={1}&max={2}&e={3}&r={4}&s={5}", classe, niveauMin, niveauMax, ecole, rituel, source);
html = await client.GetStringAsync(url);
}
var pack = new HtmlDocument();
pack.LoadHtml(html);
var tdssort = pack.GetElementbyId("liste").Element("table").Elements("tr").ToList();
@ -71,13 +115,12 @@ namespace AideDeJeuLib.Spells
public async Task<Spell> GetSpell(string id)
{
string html = null;
using (var client = GetHttpClient())
{
// https://www.aidedd.org/dnd/sorts.php?vo=ray-of-frost
// https://www.aidedd.org/dnd/sorts.php?vf=rayon-de-givre
var client = GetHttpClient();
// https://www.aidedd.org/dnd/sorts.php?vo=ray-of-frost
// https://www.aidedd.org/dnd/sorts.php?vf=rayon-de-givre
html = await client.GetStringAsync(string.Format("https://www.aidedd.org/dnd/sorts.php?vf={0}", id));
html = await client.GetStringAsync(string.Format("https://www.aidedd.org/dnd/sorts.php?vf={0}", id));
}
var pack = new HtmlDocument();
pack.LoadHtml(html);
var divSpell = pack.DocumentNode.SelectNodes("//div[contains(@class,'bloc')]").FirstOrDefault();
@ -87,14 +130,13 @@ namespace AideDeJeuLib.Spells
public async Task<IEnumerable<string>> GetSpellIds(string classe, string niveauMin = "Z", string niveauMax = "9")
{
string html = null;
using (var client = GetHttpClient())
{
// https://www.aidedd.org/dnd/sorts.php?vo=ray-of-frost
// https://www.aidedd.org/dnd/sorts.php?vf=rayon-de-givre
// https://www.aidedd.org/regles/sorts/
var client = GetHttpClient();
// https://www.aidedd.org/dnd/sorts.php?vo=ray-of-frost
// https://www.aidedd.org/dnd/sorts.php?vf=rayon-de-givre
// https://www.aidedd.org/regles/sorts/
html = await client.GetStringAsync(string.Format("https://www.aidedd.org/adj/livre-sorts/?c={0}&min={1}&max={2}", classe, niveauMin, niveauMax));
html = await client.GetStringAsync(string.Format("https://www.aidedd.org/adj/livre-sorts/?c={0}&min={1}&max={2}", classe, niveauMin, niveauMax));
}
var pack = new HtmlDocument();
pack.LoadHtml(html);
return pack.DocumentNode.SelectNodes("//input[@name='select_sorts[]']").Select(node => node.GetAttributeValue("value", ""));
@ -103,17 +145,16 @@ namespace AideDeJeuLib.Spells
public async Task<IEnumerable<Spell>> GetSpells(IEnumerable<string> spellIds)
{
string html = null;
using (var client = GetHttpClient())
var client = GetHttpClient();
var content = new MultipartFormDataContent();
content.Add(new StringContent("card"), "format");
foreach (var spellId in spellIds)
{
var content = new MultipartFormDataContent();
content.Add(new StringContent("card"), "format");
foreach (var spellId in spellIds)
{
content.Add(new StringContent(spellId), "select_sorts[]");
}
var response = await client.PostAsync("http://www.aidedd.org/dnd/sorts.php", content);
html = await response.Content.ReadAsStringAsync();
content.Add(new StringContent(spellId), "select_sorts[]");
}
var response = await client.PostAsync("http://www.aidedd.org/dnd/sorts.php", content);
html = await response.Content.ReadAsStringAsync();
var pack = new HtmlDocument();
pack.LoadHtml(html);
var newSpells = new List<Spell>();