mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-24 02:02:36 -04:00
Creating file crawler and the metadata provider interface.
This commit is contained in:
parent
f5811b9ce4
commit
054a2718b7
131
Kyoo/InternalAPI/Crawler/Crawler.cs
Normal file
131
Kyoo/InternalAPI/Crawler/Crawler.cs
Normal file
@ -0,0 +1,131 @@
|
||||
using Kyoo.Models;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Kyoo.InternalAPI
|
||||
{
|
||||
public class Crawler : IHostedService
|
||||
{
|
||||
private readonly IConfiguration config;
|
||||
private readonly ILibraryManager libraryManager;
|
||||
private readonly IMetadataProvider metadataProvider;
|
||||
|
||||
public Crawler(IConfiguration configuration, ILibraryManager libraryManager, IMetadataProvider metadataProvider)
|
||||
{
|
||||
config = configuration;
|
||||
this.libraryManager = libraryManager;
|
||||
this.metadataProvider = metadataProvider;
|
||||
}
|
||||
|
||||
public Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
Debug.WriteLine("&Crawler started");
|
||||
string[] paths = config.GetSection("libraryPaths").Get<string[]>();
|
||||
|
||||
foreach (string path in paths)
|
||||
{
|
||||
Scan(path);
|
||||
Watch(path, cancellationToken);
|
||||
}
|
||||
|
||||
while (!cancellationToken.IsCancellationRequested) ;
|
||||
|
||||
Debug.WriteLine("&Crawler stopped");
|
||||
return null;
|
||||
}
|
||||
|
||||
public void Scan(string folderPath)
|
||||
{
|
||||
string[] files = Directory.GetFiles(folderPath);
|
||||
|
||||
foreach (string file in files)
|
||||
{
|
||||
if(IsVideo(file) && !libraryManager.IsEpisodeRegistered(file))
|
||||
{
|
||||
Debug.WriteLine("&Should insert this: " + file);
|
||||
|
||||
string patern = @".*\\(?<ShowTitle>.+?) S(?<Season>\d+)E(?<Episode>\d+)";
|
||||
Regex regex = new Regex(patern, RegexOptions.IgnoreCase);
|
||||
Match match = regex.Match(file);
|
||||
|
||||
string ShowPath = Path.GetDirectoryName(file);
|
||||
string ShowTitle = match.Groups["ShowTitle"].Value;
|
||||
bool seasonSuccess = long.TryParse(match.Groups["Season"].Value, out long Season);
|
||||
bool episodeSucess = long.TryParse(match.Groups["Episode"].Value, out long Episode);
|
||||
|
||||
Debug.WriteLine("&ShowPath: " + ShowPath + " Show: " + ShowTitle + " season: " + Season + " episode: " + Episode);
|
||||
|
||||
if(!libraryManager.IsShowRegistered(ShowPath))
|
||||
{
|
||||
Show show = metadataProvider.GetShowFromName(ShowTitle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Watch(string folderPath, CancellationToken cancellationToken)
|
||||
{
|
||||
Debug.WriteLine("&Watching " + folderPath + " for changes");
|
||||
using (FileSystemWatcher watcher = new FileSystemWatcher())
|
||||
{
|
||||
watcher.Path = folderPath;
|
||||
watcher.IncludeSubdirectories = true;
|
||||
watcher.NotifyFilter = NotifyFilters.LastAccess
|
||||
| NotifyFilters.LastWrite
|
||||
| NotifyFilters.FileName
|
||||
| NotifyFilters.Size
|
||||
| NotifyFilters.DirectoryName;
|
||||
|
||||
watcher.Created += FileCreated;
|
||||
watcher.Changed += FileChanged;
|
||||
watcher.Renamed += FileRenamed;
|
||||
watcher.Deleted += FileDeleted;
|
||||
|
||||
|
||||
watcher.EnableRaisingEvents = true;
|
||||
|
||||
while (!cancellationToken.IsCancellationRequested) ;
|
||||
}
|
||||
}
|
||||
|
||||
private void FileCreated(object sender, FileSystemEventArgs e)
|
||||
{
|
||||
Debug.WriteLine("&File Created at " + e.FullPath);
|
||||
}
|
||||
|
||||
private void FileChanged(object sender, FileSystemEventArgs e)
|
||||
{
|
||||
Debug.WriteLine("&File Changed at " + e.FullPath);
|
||||
}
|
||||
|
||||
private void FileRenamed(object sender, RenamedEventArgs e)
|
||||
{
|
||||
Debug.WriteLine("&File Renamed at " + e.FullPath);
|
||||
}
|
||||
|
||||
private void FileDeleted(object sender, FileSystemEventArgs e)
|
||||
{
|
||||
Debug.WriteLine("&File Deleted at " + e.FullPath);
|
||||
}
|
||||
|
||||
|
||||
private static readonly string[] videoExtensions = { ".webm", ".mkv", ".flv", ".vob", ".ogg", ".ogv", ".avi", ".mts", ".m2ts", ".ts", ".mov", ".qt", ".asf", ".mp4", ".m4p", ".m4v", ".mpg", ".mp2", ".mpeg", ".mpe", ".mpv", ".m2v", ".3gp", ".3g2" };
|
||||
|
||||
private bool IsVideo(string filePath)
|
||||
{
|
||||
return videoExtensions.Contains(Path.GetExtension(filePath));
|
||||
}
|
||||
|
||||
|
||||
public Task StopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -6,5 +6,9 @@ namespace Kyoo.InternalAPI
|
||||
public interface ILibraryManager
|
||||
{
|
||||
IEnumerable<Show> QueryShows(string selection);
|
||||
|
||||
bool IsEpisodeRegistered(string episodePath);
|
||||
|
||||
bool IsShowRegistered(string showPath);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using Kyoo.Models;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SQLite;
|
||||
using System.Diagnostics;
|
||||
@ -11,13 +12,15 @@ namespace Kyoo.InternalAPI
|
||||
private readonly SQLiteConnection sqlConnection;
|
||||
|
||||
|
||||
public LibraryManager()
|
||||
public LibraryManager(IConfiguration configuration)
|
||||
{
|
||||
Debug.WriteLine("&Library Manager init");
|
||||
string databasePath = configuration.GetValue<string>("databasePath");
|
||||
|
||||
string databasePath = @"C://Projects/database.db";
|
||||
Debug.WriteLine("&Library Manager init, databasePath: " + databasePath);
|
||||
if (!File.Exists(databasePath))
|
||||
{
|
||||
Debug.WriteLine("&Database doesn't exist, creating one.");
|
||||
|
||||
SQLiteConnection.CreateFile(databasePath);
|
||||
sqlConnection = new SQLiteConnection(string.Format("Data Source={0};Version=3", databasePath));
|
||||
sqlConnection.Open();
|
||||
@ -27,6 +30,7 @@ namespace Kyoo.InternalAPI
|
||||
uri TEXT UNIQUE,
|
||||
title TEXT,
|
||||
aliases TEXT,
|
||||
path TEXT,
|
||||
overview TEXT,
|
||||
status TEXT,
|
||||
startYear INTEGER,
|
||||
@ -54,6 +58,7 @@ namespace Kyoo.InternalAPI
|
||||
showID INTEGER,
|
||||
seasonID INTEGER,
|
||||
episodeNumber INTEGER,
|
||||
path TEXT,
|
||||
title TEXT,
|
||||
overview TEXT,
|
||||
imgPrimary TEXT,
|
||||
@ -158,7 +163,7 @@ namespace Kyoo.InternalAPI
|
||||
|
||||
public IEnumerable<Show> QueryShows(string selection)
|
||||
{
|
||||
string query = "SELECT * FROM shows";
|
||||
string query = "SELECT * FROM shows;";
|
||||
|
||||
SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection);
|
||||
SQLiteDataReader reader = cmd.ExecuteReader();
|
||||
@ -170,5 +175,25 @@ namespace Kyoo.InternalAPI
|
||||
|
||||
return shows;
|
||||
}
|
||||
|
||||
public bool IsEpisodeRegistered(string episodePath)
|
||||
{
|
||||
string query = "SELECT 1 FROM episodes WHERE path = $path;";
|
||||
SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection);
|
||||
|
||||
cmd.Parameters.AddWithValue("$path", episodePath);
|
||||
|
||||
return cmd.ExecuteScalar() != null;
|
||||
}
|
||||
|
||||
public bool IsShowRegistered(string showPath)
|
||||
{
|
||||
string query = "SELECT 1 FROM shows WHERE path = $path;";
|
||||
SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection);
|
||||
|
||||
cmd.Parameters.AddWithValue("$path", showPath);
|
||||
|
||||
return cmd.ExecuteScalar() != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
9
Kyoo/InternalAPI/MetadataProvider/IMetadataProvider.cs
Normal file
9
Kyoo/InternalAPI/MetadataProvider/IMetadataProvider.cs
Normal file
@ -0,0 +1,9 @@
|
||||
using Kyoo.Models;
|
||||
|
||||
namespace Kyoo.InternalAPI
|
||||
{
|
||||
public interface IMetadataProvider
|
||||
{
|
||||
Show GetShowFromName(string showName);
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
using Kyoo.Models;
|
||||
|
||||
namespace Kyoo.InternalAPI.MetadataProvider
|
||||
{
|
||||
public class ProviderTheTvDB : IMetadataProvider
|
||||
{
|
||||
public Show GetShowFromName(string showName)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
29
Kyoo/Models/Episode.cs
Normal file
29
Kyoo/Models/Episode.cs
Normal file
@ -0,0 +1,29 @@
|
||||
using System;
|
||||
|
||||
namespace Kyoo.Models
|
||||
{
|
||||
public class Episode
|
||||
{
|
||||
public readonly long id;
|
||||
public readonly long ShowID;
|
||||
public readonly long SeasonID;
|
||||
|
||||
public long episodeNumber;
|
||||
public string Title;
|
||||
public string Overview;
|
||||
public DateTime ReleaseDate;
|
||||
|
||||
public long Runtime; //This runtime variable should be in seconds (used by the video manager so we need precisions)
|
||||
|
||||
public string ImgPrimary;
|
||||
public string ExternalIDs;
|
||||
|
||||
public long RuntimeInMinutes
|
||||
{
|
||||
get
|
||||
{
|
||||
return Runtime / 60;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +1,7 @@
|
||||
using Kyoo.InternalAPI;
|
||||
using Kyoo.Models;
|
||||
using Microsoft.AspNetCore;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System.IO;
|
||||
|
||||
namespace Kyoo
|
||||
{
|
||||
@ -15,6 +14,11 @@ namespace Kyoo
|
||||
|
||||
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
|
||||
WebHost.CreateDefaultBuilder(args)
|
||||
.ConfigureAppConfiguration((hostingContext, config) =>
|
||||
{
|
||||
config.SetBasePath(Directory.GetCurrentDirectory());
|
||||
config.AddJsonFile("config.json", false, true);
|
||||
})
|
||||
.UseStartup<Startup>();
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using Kyoo.InternalAPI;
|
||||
using Kyoo.InternalAPI.MetadataProvider;
|
||||
using Kyoo.Models;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
@ -30,6 +31,8 @@ namespace Kyoo
|
||||
});
|
||||
|
||||
services.AddSingleton<ILibraryManager, LibraryManager>();
|
||||
services.AddHostedService<Crawler>();
|
||||
services.AddSingleton<IMetadataProvider, ProviderTheTvDB>(); //Shouldn't use it like that, it won't work with multiple providers.
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
|
6
Kyoo/config.json
Normal file
6
Kyoo/config.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"databasePath": "C://Projects/database.db",
|
||||
"libraryPaths": [
|
||||
"D:\\Videos"
|
||||
]
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user