Files
TrackTrends/Test_Merge/F1TVEmulator.cs
T
2023-04-27 15:59:52 +02:00

263 lines
10 KiB
C#

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Interactions;
using OpenQA.Selenium.Support.UI;
namespace Test_Merge
{
public class F1TVEmulator
{
public const string COOKIE_HOST = ".formula1.com";
public const string PYTHON_COOKIE_RETRIEVAL_FILENAME = "recoverCookiesCSV.py";
public const string GECKODRIVER_FILENAME = @"geckodriver-v0.27.0-win32\geckodriver.exe";
//BE CAREFULL IF YOU CHANGE IT HERE YOU NEED TO CHANGE IT IN THE PYTHON SCRIPT TOO
public const string COOKIES_CSV_FILENAME = "cookies.csv";
private FirefoxDriver Driver;
private bool _ready;
private string _grandPrixUrl;
public string GrandPrixUrl { get => _grandPrixUrl; private set => _grandPrixUrl = value; }
public bool Ready { get => _ready; set => _ready = value; }
public F1TVEmulator(string grandPrixUrl)
{
GrandPrixUrl = grandPrixUrl;
Ready = false;
}
private void StartCookieRecovering()
{
string scriptPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), PYTHON_COOKIE_RETRIEVAL_FILENAME);
Process process = new Process();
process.StartInfo.FileName = "python.exe";
process.StartInfo.Arguments = scriptPath;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.Start();
string output = process.StandardOutput.ReadToEnd();
process.WaitForExit();
}
public async Task<int> Start()
{
//SETUP
//Those values can be changed to alter the way that the selenium driver looks and behaves in general
Ready = false;
string loginCookieName = "login";
string loginSessionCookieName = "login-session";
string loginCookieValue = GetCookie(COOKIE_HOST, loginCookieName);
string loginSessionValue = GetCookie(COOKIE_HOST, loginSessionCookieName);
int windowWidth = 1920;
int windowHeight = 1080;
var service = FirefoxDriverService.CreateDefaultService(AppDomain.CurrentDomain.BaseDirectory + GECKODRIVER_FILENAME);
service.Host = "127.0.0.1";
service.Port = 5555;
FirefoxOptions options = new FirefoxOptions();
options.SetPreference("media.peerconnection.enabled", false);
//FirefoxProfile profile = new FirefoxProfile();
//profile.SetPreference("layout.css.devPixelsPerPx", "2.0");
//options.Profile = profile;
FirefoxProfile profile = new FirefoxProfile();
profile.SetPreference("media.navigator.video.default_width", 1920);
profile.SetPreference("media.navigator.video.default_height", 1080);
options.Profile = profile;
options.AddArgument("--window-size=" + windowWidth + "," + windowHeight + "");
options.AddArgument("--disable-web-security");
options.AddArgument("--same-site-none-secure");
options.AcceptInsecureCertificates = true;
//Headless part
options.AddArgument("--headless");
options.AddArgument("--silent-launch");
options.AddArgument("--no-startup-window");
//ACTUAL STARTUP
try
{
Driver = new FirefoxDriver(service, options);
}
catch
{
//Could not start the driver, could be because an other instance is running. make sure its closed before re attempting
return 101;
}
var loginCookie = new Cookie(loginCookieName, loginCookieValue, COOKIE_HOST, "/", DateTime.Now.AddDays(5));
var loginSessionCookie = new Cookie(loginSessionCookieName, loginSessionValue, COOKIE_HOST, "/", DateTime.Now.AddDays(5));
Actions actions = new Actions(Driver);
Driver.Navigate().GoToUrl("https://f1tv.formula1.com/");
//TEST
//Driver.Manage().Window.Position = new Point(0, 0);
//Driver.Manage().Window.Size = new Size(1920, 1080);
Screenshot screenshot = ((ITakesScreenshot)Driver).GetScreenshot();
screenshot.SaveAsFile(@"C:\Users\Moi\Desktop\imgDump\Decode\FirstTest.png", ScreenshotImageFormat.Png);
//TEST
Driver.Manage().Cookies.AddCookie(loginCookie);
Driver.Manage().Cookies.AddCookie(loginSessionCookie);
try
{
Driver.Navigate().GoToUrl(GrandPrixUrl);
}
catch
{
//The url is not a valid url
Driver.Dispose();
return 103;
}
//Waits for the page to fully load
Driver.Manage().Timeouts().PageLoad = TimeSpan.FromSeconds(30);
//Removes the cookie prompt
try
{
IWebElement conscentButton = Driver.FindElement(By.Id("truste-consent-button"));
conscentButton.Click();
}
catch
{
Driver.Dispose();
return 104;
}
//Again waits for the page to fully load (when you accept cookies it takes a little time for the page to load)
//Cannot use The timeout because the feed loading is not really loading so there is not event or anything
Thread.Sleep(5000);
//Switches to the Data channel
try
{
IWebElement dataChannelButton = Driver.FindElement(By.ClassName("data-button"));
dataChannelButton.Click();
}
catch
{
//If the data button does not exists its because the user is not connected
Driver.Dispose();
return 102;
}
//Open settings
// Press the space key, this should make the setting button visible
// It does not matter if the feed is paused because when changing channel it autoplays
actions.SendKeys(OpenQA.Selenium.Keys.Space).Perform();
Thread.Sleep(1000);
//Clicks on the settings Icon
try
{
IWebElement settingsButton = Driver.FindElement(By.ClassName("bmpui-ui-settingstogglebutton"));
settingsButton.Click();
IWebElement selectElement = Driver.FindElement(By.ClassName("bmpui-ui-videoqualityselectbox"));
SelectElement select = new SelectElement(selectElement);
IWebElement selectOption = selectElement.FindElement(By.CssSelector("option[value^='1080_']"));
selectOption.Click();
}
catch
{
//Sometimes it can crash because it could not get the options to show up in time. When it happens just retry
Driver.Dispose();
return 105;
}
//Makes the feed fullscreen
WebDriverWait wait = new WebDriverWait(Driver, TimeSpan.FromSeconds(10));
IWebElement fullScreenButton = Driver.FindElement(By.ClassName("bmpui-ui-fullscreentogglebutton"));
fullScreenButton.Click();
//STARTUP FINISHED READY TO SCREENSHOT
Ready = true;
return 0;
}
public void Stop()
{
Ready = false;
Driver.Dispose();
}
public Bitmap Screenshot()
{
//bitmovinplayer-video-slave-embeddedPlayer
Bitmap result = new Bitmap(100, 100);
if (Ready)
{
/*
Screenshot scrsht = ((ITakesScreenshot)Driver).GetScreenshot();
// Get the raw bytes of the screenshot
*/
//Driver.Manage().Window.Position = new Point(0, 0);
//Driver.Manage().Window.Size = new Size(1920, 1080);
IWebElement element = Driver.FindElement(By.Id("bitmovinplayer-video-slave-embeddedPlayer"));
Screenshot scrsht = ((ITakesScreenshot)element).GetScreenshot();
byte[] screenshotBytes = Convert.FromBase64String(scrsht.AsBase64EncodedString);
// Create a new MemoryStream from the bytes
MemoryStream stream = new MemoryStream(screenshotBytes);
// Create a new Bitmap object from the MemoryStream
result = new Bitmap(stream);
}
result.Save(@"C:\Users\Moi\Desktop\imgDump\Decode\Test.png");
return result;
}
public string GetCookie(string host, string name)
{
StartCookieRecovering();
string value = "";
List<Cookie> cookies = new List<Cookie>();
using (var reader = new StreamReader(COOKIES_CSV_FILENAME))
{
// Read the header row and validate column order
string header = reader.ReadLine();
string[] expectedColumns = { "host_key", "name", "value", "path", "expires_utc", "is_secure", "is_httponly" };
string[] actualColumns = header.Split(',');
for (int i = 0; i < expectedColumns.Length; i++)
{
if (expectedColumns[i] != actualColumns[i])
{
throw new InvalidOperationException($"Expected column '{expectedColumns[i]}' at index {i} but found '{actualColumns[i]}'");
}
}
// Read each data row and parse values into a Cookie object
while (!reader.EndOfStream)
{
string line = reader.ReadLine();
string[] fields = line.Split(',');
string hostname = fields[0];
string cookieName = fields[1];
if (hostname == host && cookieName == name)
{
value = fields[2];
}
}
}
return value;
}
}
}