lampac/Catalog/ModInit.cs
lampac-talks f843f04fd4 chore: initial commit 154.3
Signed-off-by: lampac-talks <lampac-talks@users.noreply.github.com>
2026-01-30 16:23:09 +03:00

402 lines
15 KiB
C#

using System.Globalization;
using YamlDotNet.Serialization;
namespace Catalog
{
public class ModInit
{
public static void loaded()
{
}
#region goInit
public static CatalogSettings goInit(string site)
{
if (string.IsNullOrEmpty(site))
return null;
site = site.ToLowerAndTrim();
site = Regex.Replace(site, "[^a-z0-9\\-]", "", RegexOptions.IgnoreCase);
var hybridCache = IHybridCache.Get(null);
string memKey = $"catalog:goInit:{site}";
if (!hybridCache.TryGetValue(memKey, out CatalogSettings init))
{
// Если файл не найден по имени, пробуем найти по displayname в *.yaml
if (!File.Exists($"catalog/sites/{site}.yaml"))
{
string found = FindSiteByDisplayName(site);
if (string.IsNullOrEmpty(found))
return null;
site = found;
}
var deserializer = new DeserializerBuilder().Build();
// Чтение основного YAML-файла
string yaml = File.ReadAllText($"catalog/sites/{site}.yaml");
var target = deserializer.Deserialize<Dictionary<object, object>>(yaml);
foreach (string y in new string[] { "_", site })
{
if (File.Exists($"catalog/override/{y}.yaml"))
{
// Чтение пользовательского YAML-файла
string myYaml = File.ReadAllText($"catalog/override/{y}.yaml");
var mySource = deserializer.Deserialize<Dictionary<object, object>>(myYaml);
// Объединение словарей
foreach (var property in mySource)
{
if (!target.ContainsKey(property.Key))
{
target[property.Key] = property.Value;
continue;
}
if (property.Value is IDictionary<object, object> sourceDict &&
target[property.Key] is IDictionary<object, object> targetDict)
{
// Рекурсивное объединение вложенных словарей
foreach (var item in sourceDict)
targetDict[item.Key] = item.Value;
}
else
{
target[property.Key] = property.Value;
}
}
}
}
// Преобразование словаря в объект CatalogSettings
var serializer = new SerializerBuilder().Build();
var yamlResult = serializer.Serialize(target);
init = deserializer.Deserialize<CatalogSettings>(yamlResult);
if (string.IsNullOrEmpty(init.plugin))
init.plugin = init.displayname;
if (!init.debug || !AppInit.conf.multiaccess)
hybridCache.Set(memKey, init, DateTime.Now.AddMinutes(1), inmemory: true);
}
return init;
}
#endregion
#region FindSiteByDisplayName
static string FindSiteByDisplayName(string site)
{
var deserializer = new DeserializerBuilder().Build();
foreach (var folder in new[] { "catalog/sites", "catalog/override" })
{
if (!Directory.Exists(folder))
continue;
foreach (var file in Directory.EnumerateFiles(folder, "*.yaml"))
{
try
{
var yaml = File.ReadAllText(file);
var dict = deserializer.Deserialize<Dictionary<object, object>>(yaml);
if (dict != null && dict.TryGetValue("displayname", out var dnObj) && dnObj != null)
{
var dn = dnObj.ToString().ToLowerAndTrim();
if (dn == site)
return Path.GetFileNameWithoutExtension(file);
}
}
catch { }
}
}
return null;
}
#endregion
#region IsRhubFallback
public static bool IsRhubFallback(BaseSettings init)
{
if (init.rhub && init.rhub_fallback)
{
init.rhub = false;
return true;
}
return false;
}
#endregion
#region nodeValue - HtmlNode
public static object nodeValue(HtmlNode node, SingleNodeSettings nd, string host)
{
string value = null;
if (nd != null)
{
if (string.IsNullOrEmpty(nd.node) && (!string.IsNullOrEmpty(nd.attribute) || nd.attributes != null))
{
if (nd.attributes != null)
{
foreach (var attr in nd.attributes)
{
var attrValue = node.GetAttributeValue(attr, null);
if (!string.IsNullOrEmpty(attrValue))
{
value = attrValue;
break;
}
}
}
else
{
if ("innerhtml".Equals(nd.attribute, StringComparison.OrdinalIgnoreCase))
value = node.InnerHtml;
else if ("outerhtml".Equals(nd.attribute, StringComparison.OrdinalIgnoreCase))
value = node.OuterHtml;
else
value = node.GetAttributeValue(nd.attribute, null);
}
}
else
{
var inNode = node.SelectSingleNode(nd.node);
if (inNode != null)
{
if (nd.attributes != null)
{
foreach (var attr in nd.attributes)
{
var attrValue = inNode.GetAttributeValue(attr, null);
if (!string.IsNullOrEmpty(attrValue))
{
value = attrValue;
break;
}
}
}
else
{
if (!string.IsNullOrEmpty(nd.attribute))
{
if ("innerhtml".Equals(nd.attribute, StringComparison.OrdinalIgnoreCase))
value = inNode.InnerHtml;
else if ("outerhtml".Equals(nd.attribute, StringComparison.OrdinalIgnoreCase))
value = inNode.OuterHtml;
else
value = inNode.GetAttributeValue(nd.attribute, null)?.Trim();
}
else
{
value = inNode.InnerText?.Trim();
}
}
}
}
}
if (string.IsNullOrEmpty(value))
return null;
if (nd.format != null)
{
var options = ScriptOptions.Default
.AddReferences(CSharpEval.ReferenceFromFile("Shared.dll"))
.AddImports("Shared")
.AddImports("Shared.Engine")
.AddImports("Shared.Models")
.AddReferences(CSharpEval.ReferenceFromFile("Newtonsoft.Json.dll"))
.AddImports("Newtonsoft.Json")
.AddImports("Newtonsoft.Json.Linq");
return CSharpEval.Execute<object>(nd.format, new CatalogNodeValue(value, host), options);
}
return value?.Trim();
}
#endregion
#region nodeValue - JToken
public static object nodeValue(JToken node, SingleNodeSettings nd, string host)
{
if (node == null || nd == null)
return null;
var current = node is JProperty property ? property.Value : node;
JToken valueToken = null;
if (!string.IsNullOrEmpty(nd.node))
{
current = current.SelectToken(nd.node);
if (current == null)
return null;
}
if (nd.attributes != null)
{
foreach (var attr in nd.attributes)
{
valueToken = current[attr];
if (valueToken != null)
break;
}
}
if (valueToken == null && !string.IsNullOrEmpty(nd.attribute))
valueToken = current[nd.attribute];
if (valueToken == null)
return null;
string value = valueToken switch
{
JValue jValue => jValue.Value?.ToString(),
JProperty jProp => jProp.Value?.ToString(),
_ => valueToken.ToString(Formatting.None)
};
if (string.IsNullOrEmpty(value))
return null;
if (nd.format != null)
{
var options = ScriptOptions.Default
.AddReferences(CSharpEval.ReferenceFromFile("Shared.dll"))
.AddImports("Shared")
.AddImports("Shared.Engine")
.AddImports("Shared.Models")
.AddReferences(CSharpEval.ReferenceFromFile("Newtonsoft.Json.dll"))
.AddImports("Newtonsoft.Json")
.AddImports("Newtonsoft.Json.Linq");
return CSharpEval.Execute<object>(nd.format, new CatalogNodeValue(value, host), options);
}
if (valueToken is JValue)
return value?.Trim();
return valueToken;
}
#endregion
#region setArgsValue
public static void setArgsValue(SingleNodeSettings arg, object val, JObject jo)
{
if (val != null)
{
if (arg.name_arg is "kp_rating" or "imdb_rating")
{
string rating = val?.ToString()?.Trim();
if (!string.IsNullOrEmpty(rating) && rating != "0" && rating != "0.0" && double.TryParse(rating, NumberStyles.Any, CultureInfo.InvariantCulture, out _))
{
rating = rating.Length > 3 ? rating.Substring(0, 3) : rating;
if (rating.Length == 1)
rating = $"{rating}.0";
jo[arg.name_arg] = JToken.FromObject(rating.Replace(",", "."));
}
}
else if (arg.name_arg is "vote_average")
{
string value = val?.ToString()?.Trim();
if (!string.IsNullOrEmpty(value) && double.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out double _v) && _v > 0)
jo[arg.name_arg] = JToken.FromObject(_v);
}
else if (arg.name_arg is "runtime" or "PG")
{
string value = val?.ToString()?.Trim();
if (!string.IsNullOrEmpty(value) && long.TryParse(value, out long _v) && _v > 0)
jo[arg.name_arg] = JToken.FromObject(_v);
}
else if (arg.name_arg is "genres" or "created_by" or "production_countries" or "production_companies" or "networks" or "spoken_languages")
{
if (val is string)
{
string arrayStr = val?.ToString();
var array = new JArray();
if (!string.IsNullOrEmpty(arrayStr))
{
foreach (string str in arrayStr.Split(","))
{
if (string.IsNullOrWhiteSpace(str))
continue;
array.Add(new JObject() { ["name"] = clearText(str) });
}
jo[arg.name_arg] = array;
}
}
else if (IsStringList(val as JToken))
{
var array = new JArray();
foreach (var item in (JArray)val)
array.Add(new JObject() { ["name"] = clearText(item.ToString()) });
jo[arg.name_arg] = array;
}
else if (val is JToken token && token.Type == JTokenType.Array)
{
jo[arg.name_arg] = token;
}
}
else if (val is string && (arg.name_arg is "origin_country" or "languages"))
{
string arrayStr = val?.ToString();
var array = new JArray();
if (!string.IsNullOrEmpty(arrayStr))
{
foreach (string str in arrayStr.Split(","))
{
if (!string.IsNullOrWhiteSpace(str))
array.Add(str.Trim());
}
if (array.Count > 0)
jo[arg.name_arg] = array;
}
}
else
{
jo[arg.name_arg] = JToken.FromObject(val);
}
}
}
#endregion
#region IsStringList
static bool IsStringList(JToken token)
{
if (token?.Type != JTokenType.Array)
return false;
var array = token as JArray;
return array?.All(item => item.Type == JTokenType.String) == true;
}
#endregion
#region clearText
public static string clearText(string text)
{
if (string.IsNullOrEmpty(text))
return text;
text = text.Replace("&nbsp;", "");
text = Regex.Replace(text, "<[^>]+>", "");
text = HttpUtility.HtmlDecode(text);
return text.Trim();
}
#endregion
}
}