/// <summary> /// Retrieve the Genres from a list of TMDb genre-ids /// </summary> /// <param name="genreids">list of TMDb genre-ids</param> /// <param name="adult">Set if it is a movie for adults</param> /// <returns>Genres as array of string</returns> public async Task <string[]> GetGenresAsync(List <int> genreids, bool adult = false) { if (GenresLUTLanguage != _Language || GenresLUT == null) { // Retrieve LUT Genres Id --> Description LimeMsg.Debug("LimeMetaSearch: GetGenresAsync: {0}", _Language); GenresLUTLanguage = _Language; Connect(); GenresLUT = await TmdbClient.GetMovieGenresAsync(_Language); } List <string> ret = new List <string>(genreids.Count); if (adult) { ret.Add(LimeLanguage.Translate(IniLanguageSection, "GenreAdult", "GenreAdult")); } foreach (var id in genreids) { foreach (var genre in GenresLUT) { if (genre.Id == id) { ret.Add(genre.Name); break; } } } return(ret.ToArray()); }
/// <summary> /// Add a Label /// </summary> /// <param name="key">Label Key</param> /// <returns>The created LimeProperty</returns> public LimeProperty Add(string key) { const string LanguageSection = "Translator"; var prop = new LimeProperty(); prop.Ident = key; prop.Name = LimeLanguage.Translate(LanguageSection, key, key); Add(prop); return(prop); }
// -------------------------------------------------------------------------------------------------- #region Methods /// <summary> /// Build the Tooltip string /// </summary> /// <returns>Tooltip</returns> public string BuildToolTip() { string ret = ""; ret += Title; if (!string.IsNullOrEmpty(OriginalTitle) && OriginalTitle != Title) { ret += Environment.NewLine + OriginalTitle; } if (Released != 0 && (Genres != null && Genres.Length > 0 || Score != 0.0)) { string sep = LimeLanguage.Translate(IniLanguageSection, "ListSeparator", ", "); var format = LimeLanguage.Translate(IniLanguageSection, "FormatReleasedGenresScore", "FormatReleasedGenresScore"); var msg = string.Format(format, Released, GenresString, Score); ret += Environment.NewLine + msg; } else { if (Released != 0) { ret += Environment.NewLine + Released.ToString(); } if (Genres != null && Genres.Length > 0) { ret += Environment.NewLine + GenresString; } if (Score != 0) { ret += Environment.NewLine + Score.ToString(); } } if (!string.IsNullOrEmpty(Description)) { ret += Environment.NewLine + Description; } return(Tooltip = ret); }
/// <summary> /// Compose a property value defined by its Translate key. /// </summary> /// <param name="key">Key of the message to expend</param> /// <param name="args">arguments to be expanded (using String.Format) in the value.</param> /// <returns>the constructed message</returns> private string FormatValue(string key, params object[] args) { string msg = LimeLanguage.Translate(IniLanguageSection, key, key); if (args != null && args.Length > 0) { try { msg = string.Format(msg, args); } catch { // Fallback return(null); } } return(msg); }
/// <summary> /// Compose a message defined by its Translate key. /// </summary> /// <param name="title">title of the message to expend</param> /// <param name="value">object to be displayed in the message.</param> /// <param name="translate">Translate the key if true.</param> /// <returns>the constructed message</returns> private string FormatProp(string title, object value, bool translate = true) { string msg = translate ? LimeLanguage.Translate(IniLanguageSection, title, title) : title; if (value != null) { if (value is LimeProperty prop) { value = prop.Content; } if (FormatProperty == null) { FormatProperty = LimeLanguage.Translate(IniLanguageSection, "FormatProperty", "FormatProperty"); } if (value == null || string.IsNullOrEmpty(value.ToString())) { return(null); } var val = value; if (value.GetType().IsArray&& typeof(string).IsAssignableFrom(value.GetType().GetElementType())) { string sep = LimeLanguage.Translate(IniLanguageSection, "ListSeparator", ", "); val = string.Join(sep, (string[])value); } try { msg = String.Format(FormatProperty, msg, val); } catch { // Fallback return(null); } } return(msg); }
// -------------------------------------------------------------------------------------------------- #region ctors /// <summary> /// Construct a reference to a property in a class /// </summary> /// <param name="ident">identifier of the LimeProperty</param> /// <param name="source">Parent object of the class where the property belongs</param> /// <param name="pi">PropertyInfo of the property (null if not referenced)</param> /// <param name="attr">Configuration attributes attached to this property</param> /// <param name="name">User-friendly name of the object. Automatically taken from translation by default.</param> /// <param name="readOnly">Define readOnly attribute</param> /// <param name="visible">Define visibility to the user</param> private void Factory(string ident, object source, PropertyInfo pi, LimePropertyAttribute attr, string name = null, bool?readOnly = null, bool?visible = null) { LimeLib.LifeTrace(this); Source = source; string languageSection = IniLanguageSection; if (pi != null) { // Referenced source PInfo = pi; var vobj = pi.GetValue(Source); Type = vobj != null?vobj.GetType() : pi.PropertyType; Ident = ident ?? pi.Name; } else { // Unreferenced source Type = source.GetType(); Ident = ident; } // Implied attributes if (source is System.Windows.Input.ICommand) { ReadOnly = true; languageSection = IniLanguageCommand; } // Copy attribute if (attr != null) { if (attr.GetType() != typeof(LimePropertyAttribute)) { attr = new LimePropertyAttribute(attr); } LimeLib.CopyPropertyValues(attr, this); } // Forced attributes if (readOnly != null) { ReadOnly = readOnly == true; } if (visible != null) { Visible = visible == true; } // Bind the object if (source is INotifyPropertyChanged src) { //LimeMsg.Debug("LimeProperty Factory: Subscribe {0} / {1}", Ident, src); src.PropertyChanged += SourcePropertyChanged; } if (Ident == null || name != null || !Visible) { Name = name ?? ident; Desc = null; } else { // Retrieve properties from LimeLanguage Name = LimeLanguage.Translate(languageSection, Ident + ".name", Ident); Desc = LimeLanguage.Translate(languageSection, Ident + ".desc", Name); } }
/// <summary> /// Build the Tooltip string /// </summary> /// <returns>Tooltip</returns> public string BuildToolTip() { string ret = ""; bool isVideo = Type == MediaType.Video; ret += FormatProp("Title"); var origin = Get("OriginalTitle"); var title = Get("Title"); if (origin != null && (title == null || title.Value != origin.Value)) { ret += FormatProp("OriginalTitle"); } var collec = FormatProp(isVideo ? "Collection" : "Album"); if (collec != "") { collec = collec.TrimEnd(); var sn = Get(isVideo ? "Season" : "Disc"); var sc = Get(isVideo ? "SeasonCount" : "DiscCount"); var en = Get(isVideo ? "Episode" : "Track"); var ec = Get(isVideo ? "EpisodeCount" : "TrackCount"); if (sn != null && (uint)sn.Content > 0) { collec += " - "; if (sc != null && (uint)sc.Content > 0) { collec += FormatValue("FormatRatio", sn, sc); } else { collec += sn.Value; } } if (en != null && (uint)en.Content > 0) { collec += " - "; if (ec != null && (uint)ec.Content > 0) { collec += FormatValue("FormatRatio", en, ec); } else { collec += en.Value; } } ret += collec + Environment.NewLine; } ret += FormatProp("Date"); ret += FormatProp("DeviceModel"); ret += FormatProp("ISO"); ret += FormatProp("Duration"); var genres = Get("Genres")?.Content as StringComposite <string>; var scoreo = Get("Score"); double score = 0; if (scoreo != null) { score = (double)scoreo.Content; } var releaseo = Get("Released"); uint release = 0; if (releaseo != null) { release = (uint)releaseo.Content; } string sep = LimeLanguage.Translate(IniLanguageSection, "ListSeparator", ", "); var relgenre = Get("ReleasedGenresScore"); if (relgenre == null) { try { if (release != 0 && (genres != null && genres.Collection != null && genres.Collection.Count > 0 || score != 0.0)) { var format = LimeLanguage.Translate(IniLanguageSection, "FormatReleasedGenresScore", "FormatReleasedGenresScore"); var msg = string.Format(format, release, string.Join(sep, genres.Collection), score); Add("ReleasedGenresScore", msg, true, false); relgenre = Get("ReleasedGenresScore"); } } catch {} } if (relgenre != null) { ret += relgenre.Value + Environment.NewLine; } else { if (release != 0) { ret += FormatProp("Released"); } if (genres != null && genres.Collection != null && genres.Collection.Count > 0) { ret += FormatProp("Genres", string.Join(sep, genres.Collection)); } if (score != 0) { ret += FormatProp("Score"); } } ret += FormatProp("Director"); ret += FormatProp("Conductor"); string performer = isVideo ? "Actors" : "Artists"; var perf = Get(performer); if (perf != null && perf.Content is StringComposite <LimePerson> perfcomp && perfcomp.Collection != null) { var performers = perfcomp.Collection; string str = ""; var maxPerf = performers.Count < MaxPerformersTip ? performers.Count : MaxPerformersTip; for (int i = 0; i < maxPerf; i++) { if (i > 0) { str += ", "; } str += performers[i].Name; } if (performers.Count > MaxPerformersTip) { str += "..."; } ret += FormatProp(performer, str) + Environment.NewLine; } ret += FormatProp("Comment"); if (!string.IsNullOrEmpty(ret)) { ret = ret.TrimEnd(); } return(Tooltip = ret); }
/// <summary> /// Add the content of any object to the collection. /// </summary> /// <param name="source">source object, class, collection...</param> /// <param name="attr">Default LimePropertyAttribute to apply to the items in the collection</param> /// <param name="all">Take all public objects if true, only Xml or LimePropertyAttribute visible elements is false</param> public void AddContent(object source, LimePropertyAttribute attr = null, bool all = true) { var field = source as Type; MemberInfo[] miSource; if (field != null) { miSource = field.GetFields(); } else { miSource = source.GetType().GetProperties(); } // Populate list foreach (var mi in miSource) { object[] attributes = mi.GetCustomAttributes(true); bool visible = all; LimePropertyAttribute cfgAttr = null; foreach (object attrib in attributes) { XmlElementAttribute xmlAttr = attrib as XmlElementAttribute; if (xmlAttr != null) { visible = true; } cfgAttr = attrib as LimePropertyAttribute; if (cfgAttr != null) { visible = cfgAttr.Visible; break; } } if (cfgAttr == null) { cfgAttr = attr; } if (visible) { if (all && (attr == null || attr.Visible) && mi is PropertyInfo pi) { string ident = string.Format("{0}.{1}", source.GetType().Name, mi.Name); string name = LimeLanguage.Translate(IniLanguageSection, ident + ".name", mi.Name); var prop = new LimeProperty(null, source, pi, cfgAttr, name); prop.Desc = LimeLanguage.Translate(IniLanguageSection, ident + ".desc", name); Add(prop); } else if (mi is PropertyInfo pi2) { Add(new LimeProperty(null, source, pi2, cfgAttr)); } else if (mi is FieldInfo fi) { var obj = fi.GetValue(field); Add(new LimeProperty(mi.Name, obj)); } else { throw new Exception("LimePropertyCollection AddContent: Unuspported type"); } } } }
/// <summary> /// Update a Person data from TMDb /// </summary> /// <param name="person">Person to be updated</param> /// <returns>true if updated</returns> public async Task <bool> GetPersonAsync(LimePerson person) { Connect(); // Retrieve person-ID by name if (person.TmdbId == 0) { var search = await TmdbClient.SearchPersonAsync(person.Name, 0, Adult); if (search.Results != null && search.Results.Count > 0 && string.Equals(search.Results[0].Name, person.Name, StringComparison.InvariantCultureIgnoreCase)) { person.TmdbId = search.Results[0].Id; } } // Retrieve person by ID if (person.TmdbId != 0) { var db = await TmdbClient.GetPersonAsync( person.TmdbId, TMDbLib.Objects.People.PersonMethods.Images | TMDbLib.Objects.People.PersonMethods.MovieCredits ); if (db == null) { return(false); } var pics = new List <LimePicture>(10); foreach (var img in db.Images.Profiles) { DownloadPic(ref pics, img.FilePath, PictureType.Artist); } person.Pictures = pics.ToArray(); person.ImdbId = db.ImdbId; person.TmdbPage = db.ProfilePath; person.Name = db.Name; person.Alias = db.AlsoKnownAs?.ToArray(); person.Gender = (LimePerson.PersonGender)db.Gender; person.Adult = db.Adult; person.Birthday = db.Birthday; person.Deathday = db.Deathday; person.Biography = CleanupDescription.Replace(db.Biography).Trim(); person.Homepage = db.Homepage; // Build Opus var opus = new List <LimeOpus>(); if (db.MovieCredits?.Cast != null) { foreach (var cast in db.MovieCredits.Cast) { // Avoid duplicates var op = opus.Find(o => o.TmdbId == cast.Id); if (op != null) { if (!op.Roles.Contains(cast.Character)) { op.Roles.Add(cast.Character); } } else { op = new LimeOpus(LimeOpusType.Movie, cast.Id, cast.Title, cast.Character) { OriginalTitle = cast.OriginalTitle, Adult = cast.Adult, Released = cast.ReleaseDate != null ? (uint)cast.ReleaseDate.Value.Year : 0 }; if (cast.PosterPath != null) { op.PosterUrl = TmdbClient.GetImageUrl(TmdbClient.Config.Images.PosterSizes.Last(), cast.PosterPath)?.AbsoluteUri; } opus.Add(op); } } } if (db.TvCredits?.Cast != null) { foreach (var cast in db.TvCredits.Cast) { // Avoid duplicates var op = opus.Find(o => o.TmdbId == cast.Id); if (op != null) { if (!op.Roles.Contains(cast.Character)) { op.Roles.Add(cast.Character); } } else { op = new LimeOpus(LimeOpusType.TvShow, cast.Id, cast.Name, cast.Character) { OriginalTitle = cast.OriginalName, Released = cast.FirstAirDate != null ? (uint)cast.FirstAirDate.Value.Year : 0 }; if (cast.PosterPath != null) { op.PosterUrl = TmdbClient.GetImageUrl(TmdbClient.Config.Images.PosterSizes.Last(), cast.PosterPath)?.AbsoluteUri; } opus.Add(op); } } } if (db.MovieCredits?.Crew != null) { foreach (var cast in db.MovieCredits.Crew) { // Avoid duplicates var op = opus.Find(o => o.TmdbId == cast.Id); if (op != null) { if (!op.Roles.Contains(cast.Department)) { op.Roles.Add(cast.Department); } } else { op = new LimeOpus(LimeOpusType.Movie, cast.Id, cast.Title, cast.Department) { OriginalTitle = cast.OriginalTitle, Adult = cast.Adult, Released = cast.ReleaseDate != null ? (uint)cast.ReleaseDate.Value.Year : 0 }; if (cast.PosterPath != null) { op.PosterUrl = TmdbClient.GetImageUrl(TmdbClient.Config.Images.PosterSizes.Last(), cast.PosterPath)?.AbsoluteUri; } opus.Add(op); } } } if (db.TvCredits?.Crew != null) { foreach (var cast in db.TvCredits.Crew) { // Avoid duplicates var op = opus.Find(o => o.TmdbId == cast.Id); if (op != null) { if (!op.Roles.Contains(cast.Department)) { op.Roles.Add(cast.Department); } } else { op = new LimeOpus(LimeOpusType.TvShow, cast.Id, cast.Name, cast.Department) { OriginalTitle = cast.OriginalName, Released = cast.FirstAirDate != null ? (uint)cast.FirstAirDate.Value.Year : 0 }; if (cast.PosterPath != null) { op.PosterUrl = TmdbClient.GetImageUrl(TmdbClient.Config.Images.PosterSizes.Last(), cast.PosterPath)?.AbsoluteUri; } opus.Add(op); } } } // Set genres foreach (var op in opus) { if (op.Adult) { op.Genres = new string[] { LimeLanguage.Translate(IniLanguageSection, "GenreAdult", "GenreAdult") } } ; op.BuildToolTip(); } person.Opus = opus.ToArray(); return(true); } return(false); }