/Application/Core/Utilities.cs
http://yet-another-music-application.googlecode.com/ · C# · 508 lines · 256 code · 60 blank · 192 comment · 65 complexity · a78cd2d0338adbdce236201135d4e911 MD5 · raw file
- /**
- * Utilities.cs
- *
- * The swiss armyknife of Stoffi containing, for example, the
- * log function.
- *
- * * * * * * * * *
- *
- * Copyright 2012 Simplare
- *
- * This code is part of the Stoffi Music Player Project.
- * Visit our website at: stoffiplayer.com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 3 of the License, or (at your option) any later version.
- *
- * See stoffiplayer.com/license for more information.
- **/
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Text;
- using System.Diagnostics;
- using System.Collections.ObjectModel;
- using System.Globalization;
- using Tomers.WPF.Localization;
-
- namespace Stoffi
- {
- /// <summary>
- /// This is the utility class containing all helper methods
- /// </summary>
- static partial class U
- {
- #region Members
-
- /// <summary>
- /// Contains the time when the class was first initialized
- /// </summary>
- private static DateTime initTime;
-
- #endregion
-
- #region Properties
-
- /// <summary>
- /// Gets or sets the path to the logfile
- /// </summary>
- public static string LogFile { get; set; }
-
- /// <summary>
- /// Gets or sets the minimum level of messages to print/write
- /// </summary>
- public static LogLevel Level { get; set; }
-
- /// <summary>
- /// Gets or sets whether the main window should listen for keyboard shortcuts
- /// </summary>
- public static bool ListenForShortcut { get; set; }
-
- #endregion
-
- #region Constructor
-
- /// <summary>
- /// Creates a utility class with a "Stoffi.log" logfile in the TEMP folder and a Level of Warning
- /// </summary>
- static U()
- {
- LogFile = Path.Combine(Environment.GetEnvironmentVariable("TEMP"), "Stoffi.log");
- Level = LogLevel.Warning;
- initTime = DateTime.Now;
- }
-
- #endregion
-
- #region Methods
-
- #region Public
-
- /// <summary>
- /// Logs a message to file and/or console.
- /// </summary>
- /// <param name="level">The level of the message (if this is lower than Level the message will be ignored)</param>
- /// <param name="caller">The caller of the message</param>
- /// <param name="message">The message</param>
- public static void L(LogLevel level, string caller, string message)
- {
- if (LevelToInt(level) < LevelToInt(Level)) return;
-
- TimeSpan ts = (DateTime.Now - initTime);
- string logLine = String.Format("{0} {1}:{2:00}:{3:00}.{4:000} ({5:G}) [{6}] {7}: {8}",
- ts.Days, ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds, DateTime.Now,
- LevelToString(level), // #7
- caller.ToUpper(),
- message);
-
- if (Level == LogLevel.Debug)
- Console.WriteLine(logLine);
-
- #if (!DEBUG)
- System.IO.StreamWriter sw = null;
- try
- {
- sw = System.IO.File.AppendText(LogFile);
- sw.WriteLine(logLine);
- }
- catch (Exception e)
- {
- Console.WriteLine("ERROR: Could not write to logfile: " + e.Message);
- }
- if (sw != null)
- sw.Close();
- #endif
- }
-
- /// <summary>
- /// Logs a HttpWebResponse to file and/or console.
- /// </summary>
- /// <param name="level">The level of the message (if this is lower than Level the message will be ignored)</param>
- /// <param name="caller">The caller of the message</param>
- /// <param name="response">The HttpWebResponse object.</param>
- public static void L(LogLevel level, string caller, System.Net.HttpWebResponse response)
- {
- if (response == null)
- U.L(level, caller, "Response was empty.");
- else
- {
- U.L(level, caller, String.Format("Content Encoding: {0}", response.ContentEncoding));
- U.L(level, caller, String.Format("Content Type: {0}", response.ContentType));
- U.L(level, caller, String.Format("Status Description: {0}", response.StatusDescription));
- StreamReader sr = new StreamReader(response.GetResponseStream());
- string str;
- while ((str = sr.ReadLine()) != null)
- U.L(level, caller, str);
- U.L(level, caller, String.Format("-- End of response. Total bytes: {0} --", response.ContentLength));
- }
- }
-
- /// <summary>
- /// Looks for a track with a specific path in a collection
- /// </summary>
- /// <param name="collection">A collection of tracks</param>
- /// <param name="path">A path to look for</param>
- /// <returns>True if any track has a path with <paramref name="path"/> as prefix, otherwise false.</returns>
- public static bool ContainsPath(ObservableCollection<TrackData> collection, string path)
- {
- foreach (TrackData t in collection)
- if (t.Path.StartsWith(path))
- return true;
- return false;
- }
-
- /// <summary>
- /// Looks for all tracks with a specific path in a collection
- /// </summary>
- /// <param name="collection">A collection of tracks</param>
- /// <param name="path">A path to look for</param>
- /// <returns>Any track that has a path with <paramref name="path"/> as prefix</returns>
- public static List<TrackData> GetTracks(ObservableCollection<TrackData> collection, string path)
- {
- List<TrackData> ret = new List<TrackData>();
- foreach (TrackData t in collection)
- if (t.Path.StartsWith(path))
- ret.Add(t);
- return ret;
- }
-
- /// <summary>
- /// Turns a size in bytes into a human readable string
- /// </summary>
- /// <param name="size">The size</param>
- /// <returns>A localized string describing the size</returns>
- public static string HumanSize(long size)
- {
- if (size > Math.Pow(10,12))
- return String.Format(U.T("SizeTb"), Math.Round((double)(size / Math.Pow(10, 12)), 2));
-
- else if (size > Math.Pow(10, 9))
- return String.Format(U.T("SizeGb"), Math.Round((double)(size / Math.Pow(10, 9)), 2));
-
- else if (size > Math.Pow(10, 6))
- return String.Format(U.T("SizeMb"), Math.Round((double)(size / Math.Pow(10, 6)), 2));
-
- else if (size > Math.Pow(10, 3))
- return String.Format(U.T("SizeKb"), Math.Round((double)(size / Math.Pow(10, 3)), 2));
-
- else
- return String.Format(U.T("SizeBytes"), size);
- }
-
- /// <summary>
- /// Removes characters that are not valid for an XML file.
- /// </summary>
- /// <param name="str">The string to be parsed</param>
- /// <returns>A copy of the string <paramref name="str"/> but with all invalid characters removed</returns>
- public static string CleanXMLString(string str)
- {
- if (str == null) return null;
-
- string r = "";
- foreach (char c in str)
- {
- int n = (int)c;
- if ((n >= 9 && n <= 10) ||
- (n == 13) ||
- (n >= 32 && n <= 55295) ||
- (n >= 57344 && n <= 65533) ||
- (n >= 65536 && n <= 1114111))
- {
- r += c;
- }
- }
- return r;
- }
-
- /// <summary>
- /// Converts back an escaped string passed via Rails CGI.escapeHTML method.
- /// </summary>
- /// <param name="str">The escaped string</param>
- /// <returns>An unescaped version of str</returns>
- public static string UnescapeHTML(string str)
- {
- return str.Replace(""", "\"").Replace(">", ">").Replace("<", "<").Replace("&", "&");
- }
-
- /// <summary>
- /// Parses HTTP query parameters
- /// </summary>
- /// <param name="query">The HTTP query</param>
- /// <returns>A dictionary with key-value pairs</returns>
- public static Dictionary<string, string> GetParams(string query)
- {
- string[] parameters = query.Split('&');
- Dictionary<string, string> d = new Dictionary<string, string>();
- foreach (string parameter in parameters)
- {
- string[] p = parameter.Split(new char[] { '=' }, 2);
- d.Add(p[0], p[1]);
- }
- return d;
- }
-
- /// <summary>
- /// Retrieves the query from a HTTP URL.
- /// Will clean up multiple question marks.
- /// </summary>
- /// <param name="url">The HTTP URL</param>
- /// <returns>A query string without any question marks</returns>
- public static string GetQuery(string url)
- {
- string[] tokens = url.Split('?');
- string ret = "";
- for (int i = 1; i < tokens.Count(); i++)
- {
- ret += "&" + tokens[i];
- }
- return ret.Substring(1);
- }
-
- /// <summary>
- /// Creates a HTTP parameter string from a key and a value.
- /// If value is null then it will return null instead of an
- /// empty assignment.
- /// All values and parameters will be encoded
- /// </summary>
- /// <param name="key">The parameter name</param>
- /// <param name="value">The value of the parameter</param>
- /// <param name="prefix">A prefix to be set on all parameter names</param>
- /// <returns>key=value if value is not null, otherwise null</returns>
- public static string CreateParam(string key, string value, string prefix)
- {
- if (key == null || value == null)
- return null;
- else
- {
- if (prefix == null)
- return String.Format("{0}={1}",
- OAuth.Manager.UrlEncode(key),
- OAuth.Manager.UrlEncode(value));
- else
- return String.Format("{0}[{1}]={2}",
- prefix,
- OAuth.Manager.UrlEncode(key),
- OAuth.Manager.UrlEncode(value));
- }
- }
-
- /// <summary>
- /// Creates a HTTP parameter string from a key and a value.
- /// If value is null then it will return null instead of an
- /// empty assignment.
- /// All values and parameters will be encoded
- /// </summary>
- /// <param name="key">The parameter name</param>
- /// <param name="value">The value of the parameter</param>
- /// <param name="prefix">A prefix to be set on all parameter names</param>
- /// <returns>key=value if value is not null, otherwise null</returns>
- public static string CreateParam(string key, int value, string prefix)
- {
- return CreateParam(key, value.ToString(), prefix);
- }
-
- /// <summary>
- /// Creates a HTTP parameter string from a key and a value.
- /// If value is null then it will return null instead of an
- /// empty assignment.
- /// All values and parameters will be encoded
- /// </summary>
- /// <param name="key">The parameter name</param>
- /// <param name="value">The value of the parameter</param>
- /// <param name="prefix">A prefix to be set on all parameter names</param>
- /// <returns>key=value if value is not null, otherwise null</returns>
- public static string CreateParam(string key, uint value, string prefix)
- {
- return CreateParam(key, value.ToString(), prefix);
- }
-
- /// <summary>
- /// Creates a HTTP parameter string from a key and a value.
- /// If value is null then it will return null instead of an
- /// empty assignment.
- /// All values and parameters will be encoded
- /// </summary>
- /// <param name="key">The parameter name</param>
- /// <param name="value">The value of the parameter</param>
- /// <param name="prefix">A prefix to be set on all parameter names</param>
- /// <returns>key=value if value is not null, otherwise null</returns>
- public static string CreateParam(string key, double value, string prefix)
- {
- return CreateParam(key, Convert.ToString(value), prefix);
- }
-
- /// <summary>
- /// Turns the first letter into uppercase and the rest into lowercase.
- /// </summary>
- /// <param name="str">The string to modify.</param>
- /// <returns>The string str with its first letter in uppercase and the rest in lowercase.</returns>
- public static String Capitalize(String str)
- {
- if (str.Length == 0)
- return "";
- else
- {
- str = str.ToLower();
- char[] a = str.ToCharArray();
- a[0] = Char.ToUpper(a[0]);
- return new String(a);
- }
- }
-
- /// <summary>
- /// Turns a timespan into a string in the format:
- /// X days, X hours, X minutes, X seconds
- /// </summary>
- /// <param name="ts">The timespan to turn into a string</param>
- /// <returns>The timespan printed out to a string</returns>
- public static String TimeSpanToLongString(TimeSpan ts)
- {
- String ret = "";
-
- if (ts.Days > 0)
- ret += String.Format("{0} {1}, ", ts.Days, T("DateDays"));
-
- if (ts.Hours > 0)
- ret += String.Format("{0} {1}, ", ts.Hours, T("DateHours"));
-
- ret += String.Format("{0} {1}, ", ts.Minutes, T("DateMinutes"));
- ret += String.Format("{0} {1}", ts.Seconds, T("DateSeconds"));
-
- return ret;
- }
-
- /// <summary>
- /// Turns a timespan to a short and compact string in the format:
- /// DD HH:MM:SS (days, hours, minutes, seconds and leading zeroes)
- /// </summary>
- /// <param name="ts">The timespan to turn into a string</param>
- /// <returns>The timespan printed out to a short string</returns>
- public static String TimeSpanToString(TimeSpan ts)
- {
- String ret = "";
- if (ts.Days > 0)
- ret += String.Format("{0:00}:", ts.Days);
-
- if (ts.Hours > 0)
- ret += String.Format("{0:00}:", ts.Hours);
-
- ret += String.Format("{0:00}:", ts.Minutes);
- ret += String.Format("{0:00}", ts.Seconds);
-
- return ret;
- }
-
- /// <summary>
- /// Translates a string
- /// </summary>
- /// <param name="id">The id of the translation value</param>
- /// <param name="field">The field of the translation value</param>
- /// <param name="def">The default value (sets to field if empty)</param>
- /// <returns>The string associated with the translation value</returns>
- public static string T(string id, string field = "Text", string def = "")
- {
- if (def == "") def = field;
- LanguageDictionary dictionary = LanguageDictionary.GetDictionary(LanguageContext.Instance.Culture);
- return (string)dictionary.Translate(id, field, def, typeof(string));
- }
-
- /// <summary>
- /// Formats an integer using local culture
- /// </summary>
- /// <param name="n">The number to format</param>
- /// <returns>The number formatted according to localization</returns>
- public static string T(int n)
- {
- return n.ToString("N0", LanguageContext.Instance.Culture);
- }
-
- /// <summary>
- /// Formats a double using local culture
- /// </summary>
- /// <param name="n">The number to format</param>
- /// <returns>The number formatted according to localization</returns>
- public static string T(double n)
- {
- return n.ToString("N", LanguageContext.Instance.Culture);
- }
-
- /// <summary>
- /// Formats a date using local culture
- /// </summary>
- /// <param name="dt">The date to format</param>
- /// <returns>The date formatted according to localization</returns>
- public static string T(DateTime dt)
- {
- return dt.ToString(LanguageContext.Instance.Culture);
- }
-
- #endregion
-
- #region Private
-
- /// <summary>
- /// Converts a LogLevel to an integer
- /// </summary>
- /// <param name="level">The level to convert</param>
- /// <returns><paramref name="level"/> represented as an integer where Debug < PropertiesWindow < Warning < Error</returns>
- private static int LevelToInt(LogLevel level)
- {
- if (level == LogLevel.Debug) return 1;
- else if (level == LogLevel.Information) return 2;
- else if (level == LogLevel.Warning) return 3;
- else if (level == LogLevel.Error) return 4;
- else return 0;
- }
-
- /// <summary>
- /// Converts a LogLevel to a string
- /// </summary>
- /// <param name="level">The level to convert</param>
- /// <returns><paramref name="level"/> represented as a string</returns>
- private static string LevelToString(LogLevel level)
- {
- if (level == LogLevel.Debug) return "DEBUG";
- else if (level == LogLevel.Information) return "INFO";
- else if (level == LogLevel.Warning) return "OOPS";
- else if (level == LogLevel.Error) return "SHIT";
- else return "HUH?";
- }
-
- #endregion
-
- #endregion
- }
-
- #region Enum
-
- /// <summary>
- /// Describes the level of a log message
- /// </summary>
- public enum LogLevel
- {
- /// <summary>
- /// Messages that are useful when debugging the application
- /// </summary>
- Debug,
-
- /// <summary>
- /// Messages that show general information about the application's actions
- /// </summary>
- Information,
-
- /// <summary>
- /// Messages that informs about something that have gone wrong
- /// </summary>
- Warning,
-
- /// <summary>
- /// Messages informing that something fatal has happened to the application
- /// </summary>
- Error
- }
-
- #endregion
- }