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;
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
43 public class Emoji1LocalFiles : IEmojiSource, IDisposable
44 {
45 private readonly Emoji1SourceFileType sourceFileType;
46 private ManualResetEvent initialized = new ManualResetEvent(false);
47 private readonly string zipFileName;
48 private readonly string programDataFolder;
49 private readonly string imageUrl;
50 private readonly int width;
51 private readonly int height;
52
62 string ZipFileName, string ProgramDataFolder)
63 : this(SourceFileType, Width, Height, string.Empty, ZipFileName, ProgramDataFolder)
64 {
65 }
66
78 string ZipFileName, string ProgramDataFolder)
79 {
80 this.sourceFileType = SourceFileType;
81 this.width = Width;
82 this.height = Height;
83 this.imageUrl = ImageURL;
84 this.zipFileName = ZipFileName;
85 this.programDataFolder = ProgramDataFolder;
86
87 try
88 {
89 DateTime TP = File.GetLastWriteTimeUtc(this.zipFileName);
90
91 if (File.Exists(this.zipFileName) && RuntimeSettings.Get(this.zipFileName, DateTime.MinValue) != TP)
92 {
93 if (!Directory.Exists(ProgramDataFolder))
94 Directory.CreateDirectory(ProgramDataFolder);
95 else
96 {
97 string Folder = Path.Combine(ProgramDataFolder, "Emoji1");
98
99 if (Directory.Exists(Folder))
100 Directory.Delete(Folder, true);
101 }
102
103 this.initialized = new ManualResetEvent(false);
104
105 Task.Run(this.Unpack);
106 }
107 else
108 this.initialized = new ManualResetEvent(true);
109 }
110 catch (Exception ex)
111 {
112 Log.Exception(ex);
113 }
114 }
115
116 private async Task Unpack()
117 {
118 try
119 {
120 Log.Informational("Starting unpacking file.",
121 new KeyValuePair<string, object>("FileName", this.zipFileName),
122 new KeyValuePair<string, object>("Destination", this.programDataFolder));
123
124 ZipFile.ExtractToDirectory(this.zipFileName, this.programDataFolder);
125
126 DateTime TP = File.GetLastWriteTimeUtc(this.zipFileName);
127 await RuntimeSettings.SetAsync(this.zipFileName, TP);
128
129 try
130 {
131 File.Delete(this.zipFileName);
132 Log.Informational("File unpacked and deleted.", new KeyValuePair<string, object>("FileName", this.zipFileName));
133 }
134 catch (Exception)
135 {
136 Log.Informational("File unpacked.", new KeyValuePair<string, object>("FileName", this.zipFileName));
137 }
138 }
139 catch (Exception ex)
140 {
141 Log.Exception(ex);
142 }
143 finally
144 {
145 this.initialized.Set();
146 }
147 }
148
154 public bool WaitUntilInitialized(int TimeoutMilliseconds)
155 {
156 return this.initialized.WaitOne(TimeoutMilliseconds);
157 }
158
162 public Emoji1SourceFileType SourceFileType => this.sourceFileType;
163
167 public int Width => this.width;
168
172 public int Height => this.height;
173
179 public bool EmojiSupported(EmojiInfo Emoji)
180 {
181 string FileName = this.GetFileName(Emoji);
182 return File.Exists(FileName);
183 }
184
190 public string GetFileName(EmojiInfo Emoji)
191 {
192 switch (this.sourceFileType)
193 {
194 case Emoji1SourceFileType.Png64: return Path.Combine(this.programDataFolder, "Emoji1", ImageCodec.FileExtensionPng, "64x64", Emoji.FileName);
195 case Emoji1SourceFileType.Png128: return Path.Combine(this.programDataFolder, "Emoji1", ImageCodec.FileExtensionPng, "128x128", Emoji.FileName);
196 case Emoji1SourceFileType.Png512: return Path.Combine(this.programDataFolder, "Emoji1", ImageCodec.FileExtensionPng, "512x512", Emoji.FileName);
197 case Emoji1SourceFileType.Svg:
198 default:
199 string s = Emoji.FileName;
200 if (s.EndsWith("." + ImageCodec.FileExtensionPng))
201 s = s.Substring(0, s.Length - 3) + ImageCodec.FileExtensionSvg;
202
203 return Path.Combine(this.programDataFolder, "Emoji1", ImageCodec.FileExtensionSvg, s);
204 }
205 }
206
213 public Task GenerateHTML(StringBuilder Output, EmojiInfo Emoji, bool EmbedImage)
214 {
215 return this.GenerateHTML(Output, Emoji, 1, EmbedImage);
216 }
217
225 public async Task GenerateHTML(StringBuilder Output, EmojiInfo Emoji, int Level, bool EmbedImage)
226 {
227 Output.Append("<img alt=\":");
228 Output.Append(Encode(Emoji.Description));
229 Output.Append(":\" title=\"");
230 Output.Append(Encode(Emoji.ShortName));
231 Output.Append("\" width=\"");
232 Output.Append(this.CalcSize(this.width, Level).ToString());
233 Output.Append("\" height=\"");
234 Output.Append(this.CalcSize(this.height, Level).ToString());
235 Output.Append("\" src=\"");
236 Output.Append(Encode(await this.GetUrl(Emoji, EmbedImage)));
237 Output.Append("\"/>");
238 }
239
246 public int CalcSize(int OrgSize, int Level)
247 {
248 while (Level > 1)
249 {
250 OrgSize = (OrgSize * 4) / 3;
251 if (--Level == 1)
252 return OrgSize;
253
254 OrgSize = (OrgSize * 3) / 2;
255 Level--;
256 }
257
258 return OrgSize;
259 }
260
261 private static string Encode(string s)
262 {
263 if (s is null || s.IndexOfAny(specialCharacters) < 0)
264 return s;
265
266 return s.
267 Replace("&", "&amp;").
268 Replace("<", "&lt;").
269 Replace(">", "&gt;").
270 Replace("\"", "&quot;").
271 Replace("'", "&apos;");
272 }
273
274 private static readonly char[] specialCharacters = new char[] { '<', '>', '&', '"', '\'' };
275
282 public async Task<string> GetUrl(EmojiInfo Emoji, bool Embed)
283 {
284 if (Embed || string.IsNullOrEmpty(this.imageUrl))
285 {
286 StringBuilder Output = new StringBuilder();
287
288 Output.Append("data:");
289
290 if (this.sourceFileType == Emoji1SourceFileType.Svg)
291 Output.Append(ImageCodec.ContentTypeSvg);
292 else
293 Output.Append(ImageCodec.ContentTypePng);
294
295 Output.Append(";base64,");
296
297 string FileName = this.GetFileName(Emoji);
298 byte[] Data = await Runtime.IO.Files.ReadAllBytesAsync(FileName);
299
300 Output.Append(Convert.ToBase64String(Data));
301
302 return Output.ToString();
303 }
304 else
305 {
306 string s = Emoji.FileName;
307 if (this.sourceFileType == Emoji1SourceFileType.Svg && s.EndsWith("." + ImageCodec.FileExtensionPng))
308 s = s.Substring(0, s.Length - 3) + ImageCodec.FileExtensionSvg;
309
310 return this.imageUrl.Replace("%FILENAME%", s);
311 }
312 }
313
319 public Task<IImageSource> GetImageSource(EmojiInfo Emoji)
320 {
321 return this.GetImageSource(Emoji, 1);
322 }
323
330 public async Task<IImageSource> GetImageSource(EmojiInfo Emoji, int Level)
331 {
332 return new ImageSource()
333 {
334 Url = await this.GetUrl(Emoji, false),
335 Width = this.CalcSize(this.width, Level),
336 Height = this.CalcSize(this.height, Level)
337 };
338 }
339
343 public void Dispose()
344 {
345 this.initialized?.Dispose();
346 this.initialized = null;
347 }
348 }
349}
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:7
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 the application event log. Applications and services log events on this static ...
Definition: Log.cs:14
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:1657
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:344
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:10
Emoji1SourceFileType
What source files to use when displaying emoji.
delegate string ToString(IElement Element)
Delegate for callback methods that convert an element value to a string.