using System;
using API.Entities.Enums;
namespace API.Helpers;
///
/// Handles all things around Parsing Headers
///
public static class BrowserHelper
{
public static ClientDeviceType DetermineClientType(string userAgent, string? endpoint = null)
{
if (string.IsNullOrEmpty(userAgent))
{
return ClientDeviceType.Unknown;
}
var ua = userAgent.ToLowerInvariant();
// ua contains "web-app" keyword, it's Kavita web app
if (ua.Contains("web-app")) return ClientDeviceType.WebApp;
if (ua.Contains("koreader") || ua.Contains("kobo touch")) return ClientDeviceType.KoReader;
if (ua.Contains("panels")) return ClientDeviceType.Panels;
if (ua.Contains("librera")) return ClientDeviceType.Librera;
// Ensure we test everything else before web browsers, as all UAs will have web browser info
// If this is an opds url, and it's not a custom server, then return as generic
if (!string.IsNullOrEmpty(endpoint) && endpoint.Contains("/opds/"))
{
return ClientDeviceType.OpdsClient;
}
// Web browsers
if (ua.Contains("chrome") || ua.Contains("firefox") ||
ua.Contains("safari") || ua.Contains("edge"))
{
return ClientDeviceType.WebBrowser;
}
return ClientDeviceType.Unknown;
}
public static ClientDevicePlatform DetectPlatform(string userAgent)
{
if (string.IsNullOrEmpty(userAgent))
{
return ClientDevicePlatform.Unknown;
}
var ua = userAgent.ToLowerInvariant();
if (ua.Contains("windows") || ua.Contains("win32") || ua.Contains("win64"))
return ClientDevicePlatform.Windows;
if (ua.Contains("macintosh"))
return ClientDevicePlatform.MacOs;
if (ua.Contains("iphone") || ua.Contains("ipad") || ua.Contains("ipod") || ua.Contains("mac os"))
return ClientDevicePlatform.Ios;
// Linux and Android are easy to mix-up, we need to use some extra logic
if (ua.Contains("android"))
return ClientDevicePlatform.Android;
if (ua.Contains("linux") && ua.Contains("ubuntu"))
return ClientDevicePlatform.Linux;
if (ua.Contains("linux") && !ua.Contains("android"))
return ClientDevicePlatform.Linux;
return ClientDevicePlatform.Unknown;
}
///
/// Attempts to derive DeviceType based on Platform and ClientType
///
///
///
///
public static string CoaxDeviceType(ClientDeviceType type, ClientDevicePlatform platform)
{
return type switch
{
ClientDeviceType.KoReader or ClientDeviceType.Panels or ClientDeviceType.Librera =>
platform is ClientDevicePlatform.Android or ClientDevicePlatform.Ios ? "Mobile" : "Desktop",
_ => string.Empty
};
}
}