Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
LocalEmojiFiles.cs
1using System;
2using System.IO;
3using System.IO.Compression;
4using System.Collections.Generic;
5using System.Text;
6using System.Threading;
7using System.Threading.Tasks;
10using Waher.Events;
11
13{
18 {
22 Png64,
23
27 Png128,
28
32 Png512,
33
37 Svg
38 }
39
45 public delegate bool FileExistsHandler(string path);
46
52 public delegate byte[] ReadAllBytesHandler(string path);
53
57 public class Emoji1LocalFiles : IEmojiSource, IDisposable
58 {
59 private readonly Emoji1SourceFileType sourceFileType;
60 private ManualResetEvent initialized = new ManualResetEvent(false);
61 private readonly string zipFileName;
62 private readonly string programDataFolder;
63 private readonly string imageUrl;
64 private readonly int width;
65 private readonly int height;
66
76 string ZipFileName, string ProgramDataFolder)
77 : this(SourceFileType, Width, Height, string.Empty, ZipFileName, ProgramDataFolder)
78 {
79 }
80
92 string ZipFileName, string ProgramDataFolder)
93 {
94 this.sourceFileType = SourceFileType;
95 this.width = Width;
96 this.height = Height;
97 this.imageUrl = ImageURL;
98 this.zipFileName = ZipFileName;
99 this.programDataFolder = ProgramDataFolder;
100
101 try
102 {
103 DateTime TP = File.GetLastWriteTime(this.zipFileName);
104
105 if (File.Exists(this.zipFileName) && RuntimeSettings.Get(this.zipFileName, DateTime.MinValue) != TP)
106 {
107 if (!Directory.Exists(ProgramDataFolder))
108 Directory.CreateDirectory(ProgramDataFolder);
109 else
110 {
111 string Folder = Path.Combine(ProgramDataFolder, "Emoji1");
112
113 if (Directory.Exists(Folder))
114 Directory.Delete(Folder, true);
115 }
116
117 this.initialized = new ManualResetEvent(false);
118
119 Task.Run(this.Unpack);
120 }
121 else
122 this.initialized = new ManualResetEvent(true);
123 }
124 catch (Exception ex)
125 {
126 Log.Exception(ex);
127 }
128 }
129
130 private async Task Unpack()
131 {
132 try
133 {
134 Log.Informational("Starting unpacking file.",
135 new KeyValuePair<string, object>("FileName", this.zipFileName),
136 new KeyValuePair<string, object>("Destination", this.programDataFolder));
137
138 ZipFile.ExtractToDirectory(this.zipFileName, this.programDataFolder);
139
140 DateTime TP = File.GetLastWriteTime(this.zipFileName);
141 await RuntimeSettings.SetAsync(this.zipFileName, TP);
142
143 try
144 {
145 File.Delete(this.zipFileName);
146 Log.Informational("File unpacked and deleted.", new KeyValuePair<string, object>("FileName", this.zipFileName));
147 }
148 catch (Exception)
149 {
150 Log.Informational("File unpacked.", new KeyValuePair<string, object>("FileName", this.zipFileName));
151 }
152 }
153 catch (Exception ex)
154 {
155 Log.Exception(ex);
156 }
157 finally
158 {
159 this.initialized.Set();
160 }
161 }
162
168 public bool WaitUntilInitialized(int TimeoutMilliseconds)
169 {
170 return this.initialized.WaitOne(TimeoutMilliseconds);
171 }
172
176 public Emoji1SourceFileType SourceFileType => this.sourceFileType;
177
181 public int Width => this.width;
182
186 public int Height => this.height;
187
193 public bool EmojiSupported(EmojiInfo Emoji)
194 {
195 string FileName = this.GetFileName(Emoji);
196 return File.Exists(FileName);
197 }
198
204 public string GetFileName(EmojiInfo Emoji)
205 {
206 switch (this.sourceFileType)
207 {
208 case Emoji1SourceFileType.Png64: return Path.Combine(this.programDataFolder, "Emoji1", ImageCodec.FileExtensionPng, "64x64", Emoji.FileName);
209 case Emoji1SourceFileType.Png128: return Path.Combine(this.programDataFolder, "Emoji1", ImageCodec.FileExtensionPng, "128x128", Emoji.FileName);
210 case Emoji1SourceFileType.Png512: return Path.Combine(this.programDataFolder, "Emoji1", ImageCodec.FileExtensionPng, "512x512", Emoji.FileName);
211 case Emoji1SourceFileType.Svg:
212 default:
213 string s = Emoji.FileName;
214 if (s.EndsWith("." + ImageCodec.FileExtensionPng))
215 s = s.Substring(0, s.Length - 3) + ImageCodec.FileExtensionSvg;
216
217 return Path.Combine(this.programDataFolder, "Emoji1", ImageCodec.FileExtensionSvg, s);
218 }
219 }
220
227 public Task GenerateHTML(StringBuilder Output, EmojiInfo Emoji, bool EmbedImage)
228 {
229 return this.GenerateHTML(Output, Emoji, 1, EmbedImage);
230 }
231
239 public async Task GenerateHTML(StringBuilder Output, EmojiInfo Emoji, int Level, bool EmbedImage)
240 {
241 Output.Append("<img alt=\":");
242 Output.Append(Encode(Emoji.Description));
243 Output.Append(":\" title=\"");
244 Output.Append(Encode(Emoji.ShortName));
245 Output.Append("\" width=\"");
246 Output.Append(this.CalcSize(this.width, Level).ToString());
247 Output.Append("\" height=\"");
248 Output.Append(this.CalcSize(this.height, Level).ToString());
249 Output.Append("\" src=\"");
250 Output.Append(Encode(await this.GetUrl(Emoji, EmbedImage)));
251 Output.Append("\"/>");
252 }
253
260 public int CalcSize(int OrgSize, int Level)
261 {
262 while (Level > 1)
263 {
264 OrgSize = (OrgSize * 4) / 3;
265 if (--Level == 1)
266 return OrgSize;
267
268 OrgSize = (OrgSize * 3) / 2;
269 Level--;
270 }
271
272 return OrgSize;
273 }
274
275 private static string Encode(string s)
276 {
277 if (s is null || s.IndexOfAny(specialCharacters) < 0)
278 return s;
279
280 return s.
281 Replace("&", "&amp;").
282 Replace("<", "&lt;").
283 Replace(">", "&gt;").
284 Replace("\"", "&quot;").
285 Replace("'", "&apos;");
286 }
287
288 private static readonly char[] specialCharacters = new char[] { '<', '>', '&', '"', '\'' };
289
296 public async Task<string> GetUrl(EmojiInfo Emoji, bool Embed)
297 {
298 if (Embed || string.IsNullOrEmpty(this.imageUrl))
299 {
300 StringBuilder Output = new StringBuilder();
301
302 Output.Append("data:");
303
304 if (this.sourceFileType == Emoji1SourceFileType.Svg)
305 Output.Append(ImageCodec.ContentTypeSvg);
306 else
307 Output.Append(ImageCodec.ContentTypePng);
308
309 Output.Append(";base64,");
310
311 string FileName = this.GetFileName(Emoji);
312 byte[] Data = await Resources.ReadAllBytesAsync(FileName);
313
314 Output.Append(Convert.ToBase64String(Data));
315
316 return Output.ToString();
317 }
318 else
319 {
320 string s = Emoji.FileName;
321 if (this.sourceFileType == Emoji1SourceFileType.Svg && s.EndsWith("." + ImageCodec.FileExtensionPng))
322 s = s.Substring(0, s.Length - 3) + ImageCodec.FileExtensionSvg;
323
324 return this.imageUrl.Replace("%FILENAME%", s);
325 }
326 }
327
333 public Task<IImageSource> GetImageSource(EmojiInfo Emoji)
334 {
335 return this.GetImageSource(Emoji, 1);
336 }
337
344 public async Task<IImageSource> GetImageSource(EmojiInfo Emoji, int Level)
345 {
346 return new ImageSource()
347 {
348 Url = await this.GetUrl(Emoji, false),
349 Width = this.CalcSize(this.width, Level),
350 Height = this.CalcSize(this.height, Level)
351 };
352 }
353
357 public void Dispose()
358 {
359 this.initialized?.Dispose();
360 this.initialized = null;
361 }
362 }
363}
Provides emojis from Emoji One (http://emojione.com/) stored as local files.
Emoji1LocalFiles(Emoji1SourceFileType SourceFileType, int Width, int Height, string ImageURL, string ZipFileName, string ProgramDataFolder)
Provides emojis from Emoji One (http://emojione.com/) stored as local files.
Emoji1LocalFiles(Emoji1SourceFileType SourceFileType, int Width, int Height, string ZipFileName, string ProgramDataFolder)
Provides emojis from Emoji One (http://emojione.com/) stored as local files.
Task GenerateHTML(StringBuilder Output, EmojiInfo Emoji, bool EmbedImage)
Generates HTML for a given Emoji.
string GetFileName(EmojiInfo Emoji)
Gets the local file name for a given emoji.
Task< IImageSource > GetImageSource(EmojiInfo Emoji)
Gets the image source of an emoji.
bool WaitUntilInitialized(int TimeoutMilliseconds)
Waits until initialization is completed.
async Task< IImageSource > GetImageSource(EmojiInfo Emoji, int Level)
Gets the image source of an emoji.
bool EmojiSupported(EmojiInfo Emoji)
If the emoji is supported by the emoji source.
Emoji1SourceFileType SourceFileType
Type of files to use.
async Task GenerateHTML(StringBuilder Output, EmojiInfo Emoji, int Level, bool EmbedImage)
Generates HTML for a given Emoji.
async Task< string > GetUrl(EmojiInfo Emoji, bool Embed)
Gets an URL for the emoji.
int CalcSize(int OrgSize, int Level)
Calculates the size of an emoji.
Contains information about an emoji.
string FileName
Emoji file name.
string ShortName
Emoji short name.
string Description
Short description of emoji.
Contains information about an emoji image.
Definition: ImageSource.cs:9
Image encoder/decoder.
Definition: ImageCodec.cs:14
const string FileExtensionPng
png
Definition: ImageCodec.cs:75
const string ContentTypePng
image/png
Definition: ImageCodec.cs:30
const string FileExtensionSvg
svg
Definition: ImageCodec.cs:120
const string ContentTypeSvg
image/svg+xml
Definition: ImageCodec.cs:45
Static class managing loading of resources stored as embedded resources or in content files.
Definition: Resources.cs:15
static async Task< byte[]> ReadAllBytesAsync(string FileName)
Reads a binary file asynchronously.
Definition: Resources.cs:183
Static class managing the application event log. Applications and services log events on this static ...
Definition: Log.cs:13
static void Exception(Exception Exception, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, params KeyValuePair< string, object >[] Tags)
Logs an exception. Event type will be determined by the severity of the exception.
Definition: Log.cs:1647
static void Informational(string Message, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, string StackTrace, params KeyValuePair< string, object >[] Tags)
Logs an informational event.
Definition: Log.cs:334
Static class managing persistent settings.
static string Get(string Key, string DefaultValue)
Gets a string-valued setting.
static async Task< bool > SetAsync(string Key, string Value)
Sets a string-valued setting.
Interface for Emoji sources. Emoji sources provide emojis to content providers.
Definition: IEmojiSource.cs:12
Emoji1SourceFileType
What source files to use when displaying emoji.
delegate bool FileExistsHandler(string path)
Delegate to a FileExists method.
delegate byte[] ReadAllBytesHandler(string path)
Delegate to a ReadAllBytes method.
delegate string ToString(IElement Element)
Delegate for callback methods that convert an element value to a string.