using HtmlAgilityPack;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net.Http;
using System.Runtime.Serialization.Json;
using System.Threading.Tasks;
using System.Linq;
using System.Runtime.Serialization;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
MainAsync(args).GetAwaiter().GetResult();
}
static async Task MainAsync(string[] args)
{
await GetItemsAsync();
Console.WriteLine("Hello World!");
}
public static async Task GetItemsAsync(bool forceRefresh = false)
{
var client = new HttpClient();
//client.DefaultRequestHeaders.UserAgent.Add(new System.Net.Http.Headers.ProductInfoHeaderValue(new System.Net.Http.Headers.ProductHeaderValue("Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0")));
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.DefaultRequestHeaders.AcceptEncoding.Add(new System.Net.Http.Headers.StringWithQualityHeaderValue("gzip"));
//client.DefaultRequestHeaders.AcceptEncoding.Add(new System.Net.Http.Headers.StringWithQualityHeaderValue("deflate"));
//client.DefaultRequestHeaders.AcceptEncoding.Add(new System.Net.Http.Headers.StringWithQualityHeaderValue("br"));
var content = new MultipartFormDataContent();
//content.Add(new StringContent("Afficher+%28FR%29"), "displayFR");
content.Add(new StringContent("card"), "format");
//content.Add(new StringContent("%27amis%27"), "select_sorts%5B%5D");
//content.Add(new StringContent("\"amis\""), "select_sorts[]");
//var bod = await content.ReadAsStringAsync();
//Debug.WriteLine(bod);
// 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 htmlSpellBook = await client.GetStringAsync("https://www.aidedd.org/adj/livre-sorts/?c=w&min=10&max=19");
var pack = new HtmlDocument();
pack.LoadHtml(htmlSpellBook);
var selectSorts = pack.DocumentNode.SelectNodes("//input[@name='select_sorts[]']").ToList();
foreach (var selectSort in selectSorts)
{
content.Add(new StringContent(selectSort.GetAttributeValue("value", "")), "select_sorts[]");
}
var response = await client.PostAsync("http://www.aidedd.org/dnd/sorts.php", content);
var htmlSpell = await response.Content.ReadAsStringAsync();
pack.LoadHtml(htmlSpell);
var newSpells = new List();
var cardDatas = new List();
var spells = pack.DocumentNode.SelectNodes("//div[contains(@class,'blocCarte')]").ToList();
foreach (var spell in spells)
{
var newSpell = new Spell();
newSpell.Title = spell.SelectSingleNode("h1").InnerText;
newSpell.TitleUS = spell.SelectSingleNode("div[@class='trad']").InnerText;
newSpell.LevelType = spell.SelectSingleNode("h2/em").InnerText;
newSpell.Level = newSpell.LevelType.Split(new string[] { " - " }, StringSplitOptions.None)[0].Split(' ')[1];
newSpell.Type = newSpell.LevelType.Split(new string[] { " - " }, StringSplitOptions.None)[1];
newSpell.CastingTime = spell.SelectSingleNode("div[@class='paragraphe']").InnerText.Split(new string[] { " : " }, StringSplitOptions.None)[1];
newSpell.Range = spell.SelectSingleNode("div[strong/text()='Portée']").InnerText.Split(new string[] { " : " }, StringSplitOptions.None)[1];
newSpell.Components = spell.SelectSingleNode("div[strong/text()='Composantes']").InnerText.Split(new string[] { " : " }, StringSplitOptions.None)[1];
newSpell.Duration = spell.SelectSingleNode("div[strong/text()='Durée']").InnerText.Split(new string[] { " : " }, StringSplitOptions.None)[1];
newSpell.DescriptionDiv = spell.SelectSingleNode("div[contains(@class,'description')]");
newSpell.Description = newSpell.DescriptionDiv.InnerHtml;
newSpell.Overflow = spell.SelectSingleNode("div[@class='overflow']")?.InnerText;
newSpell.NoOverflow = spell.SelectSingleNode("div[@class='nooverflow']")?.InnerText;
newSpell.Source = spell.SelectSingleNode("div[@class='source']").InnerText;
newSpells.Add(newSpell);
cardDatas.AddRange(ToCardDatas(newSpell));
}
//Debug.WriteLine(htmlSpell);
var sampleCardDatas = cardDatas.Take(4).ToArray();
foreach (var scd in sampleCardDatas)
{
int totalHeight = 0;
foreach (var cc in scd.Contents)
{
totalHeight += cc.Height;
Debug.WriteLine(string.Format("{0} - {1} => {2}", cc.Height, totalHeight, cc.ToString()));
}
}
//var own = new CardDataOwner() { CardDatas = cardDatas.ToArray() };
MemoryStream stream = new MemoryStream();
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(CardData[]));
serializer.WriteObject(stream, cardDatas.ToArray());
stream.Seek(0, SeekOrigin.Begin);
StreamReader sr = new StreamReader(stream);
var result = await sr.ReadToEndAsync();
//Debug.WriteLine(result);
using (var file = new FileStream(@"out.js", FileMode.Create, FileAccess.ReadWrite, FileShare.Read))
{
var bytes = System.Text.Encoding.UTF8.GetBytes(result);
await file.WriteAsync(bytes, 0, bytes.Length);
}
}
public static CardContent TextToCardContent(string text)
{
if (text.StartsWith("•"))
{
return new BulletCardContent(text.Substring(1));
}
else if (text.Trim(new char[] { ' ', '\n' }) == ".")
{
return new EmptyCardContent();
}
else
{
return new TextCardContent(text);
}
}
public static string[] SplitText(string text)
{
var texts = new List();
string str = "";
bool autoreturn = true;
foreach(var car in text)
{
if(car == '\n')
{
texts.Add(str);
str = "";
autoreturn = true;
}
else if(car == '.')
{
if (autoreturn)
{
texts.Add(str + '.');
str = "";
}
else
{
str += car;
}
}
else if(car == '•')
{
texts.Add(str);
str = "•";
autoreturn = false;
}
else
{
str += car;
}
}
if (str.Length > 0)
{
texts.Add(str);
}
return texts.ToArray();
}
public static CardContent[] ToContents(HtmlNode description)
{
var contents = new List();
string currentText = "";
foreach (var content in description.ChildNodes)
{
//Debug.WriteLine(content.NodeType + " " + content.Name + " " + content.InnerText);
if (content.NodeType == HtmlNodeType.Element && content.Name == "strong")
{
if (currentText.Length > 0)
{
contents.Add(TextToCardContent(currentText));
currentText = "";
}
contents.Add(new SectionCardContent(content.InnerText));
}
else if (content.NodeType == HtmlNodeType.Element && content.Name == "em")
{
currentText += "" + content.InnerText + "";
}
else if (content.NodeType == HtmlNodeType.Text)
{
var texts = SplitText(content.InnerText);
for (int i = 0; i < texts.Length - 1; i++)
{
contents.Add(TextToCardContent(currentText + texts[i]));
currentText = "";
}
currentText += texts[texts.Length - 1];
}
}
if (currentText.Length > 0)
{
contents.Add(TextToCardContent(currentText));
currentText = "";
}
return contents.ToArray();
}
public static CardData ToBaseCardData(Spell spell)
{
var cardData = new CardData();
cardData.Count = 1;
cardData.Color = "maroon";
cardData.Title = spell.Title;
cardData.TitleSize = "10";
cardData.Icon = "white-book-" + spell.Level;
cardData.IconBack = "robe";
cardData.Tags = new string[]
{
"sort",
"magicien",
};
return cardData;
}
public static CardData[] ToCardDatas(Spell spell)
{
var cardDatas = new List();
var cardData = ToBaseCardData(spell);
var contents = new List();
contents.AddRange(new CardContent[]
{
new SubtitleCardContent(spell.LevelType),
new RuleCardContent(),
new PropertyCardContent("Temps d'incantation", spell.CastingTime),
new PropertyCardContent("Portée", spell.Range),
new PropertyCardContent("Composants", spell.Components),
new RuleCardContent(),
//new FillCardContent(1),
//new TextCardContent(spell.Description),
});
var description = ToContents(spell.DescriptionDiv);
foreach(var line in description)
{
int size = contents.Sum(cc => cc.Height);
if(line.Height == 0)
{
}
else if (size + line.Height <= 295)
{
contents.Add(line);
}
else
{
CardContent section = null;
if(contents.LastOrDefault() is SectionCardContent)
{
section = contents.LastOrDefault();
contents.RemoveAt(contents.Count - 1);
}
cardData.Contents = contents.ToArray();
cardDatas.Add(cardData);
cardData = ToBaseCardData(spell);
contents = new List();
if(section != null)
{
contents.Add(section);
}
contents.Add(line);
}
}
cardData.Contents = contents.ToArray();
cardDatas.Add(cardData);
if (cardDatas.Count > 1)
{
for(int i = 0; i < cardDatas.Count; i++)
{
cardDatas[i].Title += string.Format(" ({0}/{1})", i + 1, cardDatas.Count);
}
}
return cardDatas.ToArray();
}
public class Spell
{
public string Title { get; set; }
public string TitleUS { get; set; }
public string LevelType { get; set; }
public string Level { get; set; }
public string Type { get; set; }
public string CastingTime { get; set; }
public string Range { get; set; }
public string Components { get; set; }
public string Duration { get; set; }
public string Description { get; set; }
public HtmlNode DescriptionDiv { get; set; }
public string Overflow { get; set; }
public string NoOverflow { get; set; }
public string Source { get; set; }
}
/*public class CardDataOwner
{
public CardData[] CardDatas { get; set; }
}*/
[DataContract]
public class CardData
{
[DataMember(Name = "count")]
public int Count { get; set; }
[DataMember(Name = "color")]
public string Color { get; set; }
[DataMember(Name = "title")]
public string Title { get; set; }
[DataMember(Name = "title_size")]
public string TitleSize { get; set; }
[DataMember(Name = "icon")]
public string Icon { get; set; }
[DataMember(Name = "icon_back")]
public string IconBack { get; set; }
[DataMember(Name = "contents")]
public string[] ContentsToString { get { return Contents.Select(cc => cc.ToString()).ToArray(); } }
[IgnoreDataMember]
public CardContent[] Contents { get; set; }
[DataMember(Name = "tags")]
public string[] Tags { get; set; }
}
public interface CardContent
{
int Height { get; }
}
public class SubtitleCardContent : CardContent
{
public string Subtitle { get; set; }
public SubtitleCardContent(string subtitle)
{
Subtitle = subtitle;
}
public override string ToString()
{
return "subtitle | " + Subtitle;
}
public int Height { get { return 12; } }
}
public class RuleCardContent : CardContent
{
public override string ToString()
{
return "rule";
}
public int Height { get { return 15; } }
}
public class PropertyCardContent : CardContent
{
public string Name { get; set; }
public string Value { get; set; }
public PropertyCardContent(string name, string value)
{
Name = name;
Value = value;
}
public override string ToString()
{
return "property | " + Name + " | " + Value;
}
public int Height { get { return ((Name.Length + Value.Length) / 35 + 1) * 15; } }
}
public class FillCardContent : CardContent
{
public int Fill { get; set; }
public FillCardContent(int fill)
{
Fill = fill;
}
public override string ToString()
{
return "fill | " + Fill;
}
public int Height { get { return 1; } }
}
public class TextCardContent : CardContent
{
public string Text { get; set; }
public TextCardContent(string text)
{
Text = text;
}
public override string ToString()
{
return "text | " + Text;
}
public int Height { get { return (Text.Length / 35 + 1) * 15 + 6; } }
}
public class SectionCardContent : CardContent
{
public string Section { get; set; }
public SectionCardContent(string section)
{
Section = section;
}
public override string ToString()
{
return "section | " + Section;
}
public int Height { get { return 20; } }
}
public class DescriptionCardContent : CardContent
{
public string Quality { get; set; }
public string Text { get; set; }
public DescriptionCardContent(string quality, string text)
{
Quality = quality;
Text = text;
}
public override string ToString()
{
return "description | " + Quality + " | " + Text;
}
public int Height { get { return ((Quality.Length + Text.Length) / 35 + 1) * 15 + 6; } }
}
public class BulletCardContent : CardContent
{
public string Text { get; set; }
public BulletCardContent(string text)
{
Text = text;
}
public override string ToString()
{
return "bullet | " + Text;
}
public int Height { get { return (Text.Length / 30 + 1) * 15; } }
}
public class BoxesCardContent : CardContent
{
public int Count { get; set; }
public int Size { get; set; }
public BoxesCardContent(int count, int size)
{
Count = count;
Size = size;
}
public override string ToString()
{
return "boxes | " + Count + " | " + Size;
}
public int Height { get { return 16; } }
}
public class DndstatsCardContent : CardContent
{
public int Strength { get; set; }
public int Dexterity { get; set; }
public int Constitution { get; set; }
public int Intelligence { get; set; }
public int Wisdom { get; set; }
public int Charisma { get; set; }
public override string ToString()
{
return "dndstats | " + Strength + " | " + Dexterity + " | " + Constitution + " | " + Intelligence + " | " + Wisdom + " | " + Charisma;
}
public int Height { get { return 20; } }
}
public class EmptyCardContent : CardContent
{
public override string ToString()
{
return "";
}
public int Height { get { return 0; } }
}
}
}