Cleaning up the native code and the way subs are hundled

This commit is contained in:
Zoe Roux 2019-12-29 05:08:44 +01:00
parent 308967d743
commit 245ac08247
15 changed files with 2206 additions and 2088 deletions

View File

@ -4,9 +4,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00
VisualStudioVersion = 16.0.29123.88
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kyoo", "Kyoo\Kyoo.csproj", "{0F8275B6-C7DD-42DF-A168-755C81B1C329}"
ProjectSection(ProjectDependencies) = postProject
{E5EFA4B2-F09D-4C4F-83DD-A436CD60BB77} = {E5EFA4B2-F09D-4C4F-83DD-A436CD60BB77}
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Unit Tests", "Unit Tests\Unit Tests.csproj", "{CC8144B5-8868-4EA7-B171-4E47746ED003}"
EndProject

6
Kyoo.sln.DotSettings Normal file
View File

@ -0,0 +1,6 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/ForBuiltInTypes/@EntryValue">UseExplicitType</s:String>
<s:String x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/ForOtherTypes/@EntryValue">UseExplicitType</s:String>
<s:String x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/ForSimpleTypes/@EntryValue">UseExplicitType</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=API/@EntryIndexedValue">API</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=DB/@EntryIndexedValue">DB</s:String></wpf:ResourceDictionary>

35
Kyoo/.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,35 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Launch (web)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/bin/Debug/netcoreapp3.1/Kyoo.dll",
"args": [],
"cwd": "${workspaceFolder}",
"stopAtEntry": false,
"serverReadyAction": {
"action": "openExternally",
"pattern": "^\\s*Now listening on:\\s+(https?://\\S+)"
},
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"sourceFileMap": {
"/Views": "${workspaceFolder}/Views"
}
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach",
"processId": "${command:pickProcess}"
}
]
}

42
Kyoo/.vscode/tasks.json vendored Normal file
View File

@ -0,0 +1,42 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/Kyoo.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/Kyoo.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"${workspaceFolder}/Kyoo.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
}
]
}

File diff suppressed because it is too large Load Diff

View File

@ -145,13 +145,11 @@ namespace Kyoo.InternalAPI
// Debug.WriteLine("&File Deleted at " + e.FullPath);
//}
private async Task ExtractEpisodeData(string episodePath, string libraryPath)
{
if (!libraryManager.IsEpisodeRegistered(episodePath))
{
string relativePath = episodePath.Substring(libraryPath.Length - 1);
string relativePath = episodePath.Substring(libraryPath.Length);
string patern = config.GetValue<string>("regex");
Regex regex = new Regex(patern, RegexOptions.IgnoreCase);
Match match = regex.Match(relativePath);

View File

@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using System.Data.SQLite;
using System.Diagnostics;
using System.IO;
namespace Kyoo.InternalAPI
{
@ -18,12 +19,14 @@ namespace Kyoo.InternalAPI
string databasePath = configuration.GetValue<string>("databasePath");
Debug.WriteLine("&Library Manager init, databasePath: " + databasePath);
if (!System.IO.File.Exists(databasePath))
if (!File.Exists(databasePath))
{
Debug.WriteLine("&Database doesn't exist, creating one.");
if (!Directory.Exists(Path.GetDirectoryName(databasePath)))
Directory.CreateDirectory(databasePath);
SQLiteConnection.CreateFile(databasePath);
sqlConnection = new SQLiteConnection(string.Format("Data Source={0};Version=3", databasePath));
sqlConnection = new SQLiteConnection($"Data Source={databasePath};Version=3");
sqlConnection.Open();
string createStatement = @"CREATE TABLE shows(
@ -154,14 +157,12 @@ namespace Kyoo.InternalAPI
FOREIGN KEY(showID) REFERENCES shows(id) ON DELETE CASCADE
);";
using (SQLiteCommand createCmd = new SQLiteCommand(createStatement, sqlConnection))
{
createCmd.ExecuteNonQuery();
}
using SQLiteCommand createCmd = new SQLiteCommand(createStatement, sqlConnection);
createCmd.ExecuteNonQuery();
}
else
{
sqlConnection = new SQLiteConnection(string.Format("Data Source={0};Version=3", databasePath));
sqlConnection = new SQLiteConnection($"Data Source={databasePath};Version=3");
sqlConnection.Open();
}
@ -176,24 +177,22 @@ namespace Kyoo.InternalAPI
#region Read the database
public IEnumerable<Library> GetLibraries()
{
string query = "SELECT * FROM libraries;";
const string query = "SELECT * FROM libraries;";
using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection))
{
SQLiteDataReader reader = cmd.ExecuteReader();
using SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection);
SQLiteDataReader reader = cmd.ExecuteReader();
List<Library> libraries = new List<Library>();
List<Library> libraries = new List<Library>();
while (reader.Read())
libraries.Add(Library.FromReader(reader));
while (reader.Read())
libraries.Add(Library.FromReader(reader));
return libraries;
}
return libraries;
}
public IEnumerable<string> GetLibrariesPath()
{
string query = "SELECT path FROM libraries;";
const string query = "SELECT path FROM libraries;";
using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection))
{
@ -241,11 +240,11 @@ namespace Kyoo.InternalAPI
{
Track track = Track.FromReader(reader).SetLink(episodeSlug);
if (track.type == StreamType.Video)
if (track.Type == StreamType.Video)
video = track;
else if (track.type == StreamType.Audio)
else if (track.Type == StreamType.Audio)
audios.Add(track);
else if (track.type == StreamType.Subtitle)
else if (track.Type == StreamType.Subtitle)
subtitles.Add(track);
}
@ -1091,7 +1090,7 @@ namespace Kyoo.InternalAPI
using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection))
{
cmd.Parameters.AddWithValue("$episodeID", track.episodeID);
cmd.Parameters.AddWithValue("$streamType", track.type);
cmd.Parameters.AddWithValue("$streamType", track.Type);
cmd.Parameters.AddWithValue("$title", track.Title);
cmd.Parameters.AddWithValue("$language", track.Language);
cmd.Parameters.AddWithValue("$codec", track.Codec);

View File

@ -2,8 +2,8 @@
using Newtonsoft.Json;
using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
@ -21,42 +21,23 @@ namespace Kyoo.InternalAPI.MetadataProvider.TheTvDB
if (DateTime.Now.Subtract(tokenDate) < TimeSpan.FromDays(1))
return token;
WebRequest request = WebRequest.Create("https://api.thetvdb.com/login");
request.Method = "POST";
request.Timeout = 12000;
request.ContentType = "application/json";
string json = "{ \"apikey\": \"IM2OXA8UHUIU0GH6\" }";
byte[] bytes = Encoding.ASCII.GetBytes(json);
request.ContentLength = bytes.Length;
await using (Stream stream = request.GetRequestStream())
{
stream.Write(bytes, 0, bytes.Length);
}
HttpClient client = new HttpClient();
HttpContent content = new StringContent("{ \"apikey\": \"IM2OXA8UHUIU0GH6\" }", Encoding.UTF8, "application/json");
try
{
HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync();
HttpResponseMessage response = await client.PostAsync("https://api.thetvdb.com/login", content);
if (response.StatusCode == HttpStatusCode.OK)
{
Stream stream = response.GetResponseStream();
if (stream != null)
{
using StreamReader reader = new StreamReader(stream);
string content = await reader.ReadToEndAsync();
stream.Close();
response.Close();
var obj = new {Token = ""};
token = JsonConvert.DeserializeAnonymousType(content, obj).Token;
tokenDate = DateTime.UtcNow;
return token;
}
string resp = await response.Content.ReadAsStringAsync();
var obj = new {Token = ""};
token = JsonConvert.DeserializeAnonymousType(resp, obj).Token;
tokenDate = DateTime.UtcNow;
return token;
}
Debug.WriteLine("&Couldn't authentificate in TheTvDB API.\nError status: " + response.StatusCode + " Message: " + response.StatusDescription);
Debug.WriteLine("&Couldn't authentificate in TheTvDB API.\nError status: " + response.StatusCode + " Message: " + response.RequestMessage);
}
catch (WebException ex)
{

View File

@ -3,30 +3,31 @@ using System.Diagnostics;
using System.Runtime.InteropServices;
using Kyoo.Models;
using Kyoo.Models.Watch;
// ReSharper disable InconsistentNaming
namespace Kyoo.InternalAPI.TranscoderLink
{
public class TranscoderAPI
public static class TranscoderAPI
{
private const string TranscoderPath = @"/home/anonymus-raccoon/Projects/Kyoo/transcoder/cmake-build-debug/libtranscoder.so";
[DllImport(TranscoderPath, CallingConvention = CallingConvention.Cdecl)]
public extern static int init();
public static extern int init();
[DllImport(TranscoderPath, CallingConvention = CallingConvention.Cdecl)]
public extern static int transmux(string path, string out_path, out float playableDuration);
public static extern int transmux(string path, string out_path, out float playableDuration);
[DllImport(TranscoderPath, CallingConvention = CallingConvention.Cdecl)]
public extern static int transcode(string path, string out_path, out float playableDuration);
public static extern int transcode(string path, string out_path, out float playableDuration);
[DllImport(TranscoderPath, CallingConvention = CallingConvention.Cdecl)]
private extern static IntPtr get_track_info(string path, out int array_length, out int track_count);
private static extern IntPtr get_track_info(string path, out int array_length, out int track_count);
[DllImport(TranscoderPath, CallingConvention = CallingConvention.Cdecl)]
private extern static IntPtr extract_subtitles(string path, string out_path, out int array_length, out int track_count);
private static extern IntPtr extract_subtitles(string path, string out_path, out int array_length, out int track_count);
[DllImport(TranscoderPath, CallingConvention = CallingConvention.Cdecl)]
private extern static void free_memory(IntPtr stream_ptr);
private static extern void free_streams(IntPtr stream_ptr);
public static void GetTrackInfo(string path, out Track[] tracks)
@ -43,9 +44,9 @@ namespace Kyoo.InternalAPI.TranscoderLink
for (int i = 0; i < arrayLength; i++)
{
Stream stream = Marshal.PtrToStructure<Stream>(streamsPtr);
if (stream.Codec != null) //If the codec is null, the stream doesn't represent a usfull thing.
if (stream.Type != StreamType.Unknow)
{
tracks[j] = Track.From(stream, stream.Title == "VIDEO" ? StreamType.Video : StreamType.Audio);
tracks[j] = (Track)stream;
j++;
}
streamsPtr += size;
@ -54,7 +55,7 @@ namespace Kyoo.InternalAPI.TranscoderLink
else
tracks = null;
free_memory(ptr);
free_streams(ptr);
Debug.WriteLine("&" + tracks?.Length + " tracks got at: " + path);
}
@ -72,9 +73,9 @@ namespace Kyoo.InternalAPI.TranscoderLink
for (int i = 0; i < arrayLength; i++)
{
Stream stream = Marshal.PtrToStructure<Stream>(streamsPtr);
if (stream.Codec != null) //If the codec is null, the stream doesn't represent a subtitle.
if (stream.Type != StreamType.Unknow)
{
tracks[j] = Track.From(stream, StreamType.Subtitle);
tracks[j] = (Track)stream;
j++;
}
streamsPtr += size;
@ -83,7 +84,7 @@ namespace Kyoo.InternalAPI.TranscoderLink
else
tracks = null;
free_memory(ptr);
free_streams(ptr);
Debug.WriteLine("&" + tracks?.Length + " tracks got at: " + path);
}
}

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>netcoreapp3.0</TargetFramework>
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
<TypeScriptToolsVersion>Latest</TypeScriptToolsVersion>
<IsPackable>false</IsPackable>
@ -73,9 +73,9 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.0" />
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="3.1.0" />
<PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="3.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.0.0" />
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="3.0.0" />
<PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="3.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="System.Data.SQLite.Core" Version="1.0.112" />
</ItemGroup>

View File

@ -1,5 +1,6 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=internalapi_005Ccrawler/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=internalapi_005Clibrarymanager/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=internalapi_005Cmetadataprovider_005Cimplementations/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=internalapi_005Cmetadataprovider_005Cimplementations_005Cthetvdb/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=internalapi_005Ctranscoder/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

View File

@ -11,7 +11,10 @@ namespace Kyoo.Models
{
public enum StreamType
{
Video, Audio, Subtitle, Unknow
Unknow = 0,
Video = 1,
Audio = 2,
Subtitle = 3
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
@ -23,6 +26,7 @@ namespace Kyoo.Models
[MarshalAs(UnmanagedType.I1)] public bool IsDefault;
[MarshalAs(UnmanagedType.I1)] public bool IsForced;
[JsonIgnore] public string Path;
[JsonIgnore] public StreamType Type;
}
}
@ -31,14 +35,12 @@ namespace Kyoo.Models
public string DisplayName;
public string Link;
[JsonIgnore] public readonly long id;
[JsonIgnore] public long episodeID;
[JsonIgnore] public StreamType type;
[JsonIgnore] public bool IsExternal;
public Track(StreamType type, string title, string language, bool isDefault, bool isForced, string codec, bool isExternal, string path)
{
this.type = type;
this.Type = type;
Title = title;
Language = language;
IsDefault = isDefault;
@ -60,32 +62,16 @@ namespace Kyoo.Models
reader["path"] as string);
}
public static Track From(Stream stream)
{
if (stream == null)
return null;
return new Track(StreamType.Unknow, stream.Title, stream.Language, stream.IsDefault, stream.IsForced, stream.Codec, false, stream.Path);
}
public static Track From(Stream stream, StreamType type)
{
if (stream == null)
return null;
return new Track(type, stream.Title, stream.Language, stream.IsDefault, stream.IsForced, stream.Codec, false, stream.Path);
}
public Track SetLink(string episodeSlug)
{
if (type == StreamType.Subtitle)
if (Type == StreamType.Subtitle)
{
string language = Language;
//Converting mkv track language to c# system language tag.
if (language == "fre")
language = "fra";
DisplayName = CultureInfo.GetCultures(CultureTypes.NeutralCultures).Where(x => x.ThreeLetterISOLanguageName == language).FirstOrDefault()?.DisplayName ?? language;
DisplayName = CultureInfo.GetCultures(CultureTypes.NeutralCultures).FirstOrDefault(x => x.ThreeLetterISOLanguageName == language)?.DisplayName ?? language;
Link = "/subtitle/" + episodeSlug + "." + Language;
if (IsForced)
@ -97,10 +83,15 @@ namespace Kyoo.Models
if (Title != null && Title.Length > 1)
DisplayName += " - " + Title;
if (Codec == "ass")
Link += ".ass";
else if (Codec == "subrip")
Link += ".srt";
switch (Codec)
{
case "ass":
Link += ".ass";
break;
case "subrip":
Link += ".srt";
break;
}
}
else
Link = null;

View File

@ -6,6 +6,8 @@ using Microsoft.AspNetCore.SpaServices.AngularCli;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedAutoPropertyAccessor.Global
namespace Kyoo
{

View File

@ -8,12 +8,11 @@
},
"AllowedHosts": "*",
"databasePath": "/home/anonymus-raccoon/kyoo/database.db",
"transmuxTempPath": "/home/anonymus-raccoon/kyoo/temp/transmux",
"transcodeTempPath": "/home/anonymus-raccoon/kyoo/temp/transcode",
"peoplePath": "/home/anonymus-raccoon/kyoo/People",
"plugins": "~/kyoo/Debug",
"providerPlugins": "C://Projects/Plugins/Providers",
"databasePath": "/var/lib/kyoo/database.db",
"transmuxTempPath": "/var/cached/kyoo/transmux",
"transcodeTempPath": "/var/cached/kyoo//transcode",
"peoplePath": "/var/lib/kyoo/people",
"plugins": "/var/lib/kyoo/plugins",
"regex": "^(\\/(?<Collection>.+?))?\\/.*\\/(?<ShowTitle>.+?) S(?<Season>\\d+)E(?<Episode>\\d+)",
"absoluteRegex": ".*\\/(?<ShowTitle>.+?) (?<AbsoluteNumber>\\d+)"
}

@ -1 +1 @@
Subproject commit 95721ab85935c9c0e76540ed5cdff3d9c5e8a837
Subproject commit 3f3ce1d88e1a146bc304892a7621cf7eb30df29b