From f81fb656e8ff983db40e324e6e123098894bfa23 Mon Sep 17 00:00:00 2001 From: Michael Nolan Date: Wed, 3 Jan 2024 20:53:13 -0600 Subject: [PATCH] Shows almost done --- .gitignore | 1 + Dockerfile | 13 + Tesses.CMS.Cli/Program.cs | 11 +- Tesses.CMS.Client/Class1.cs | 55 + Tesses.CMS.Client/Movie.cs | 52 + Tesses.CMS.Providers.Dapper/Class1.cs | 298 ++++ .../Tesses.CMS.Providers.Dapper.csproj | 15 + Tesses.CMS.Providers.LiteDb/Class1.cs | 283 ++++ .../Tesses.CMS.Providers.LiteDb.csproj | 15 + Tesses.CMS.Server/Program.cs | 1 + Tesses.CMS.Server/Tesses.CMS.Server.csproj | 13 +- Tesses.CMS/Assets/AboutUser.html | 4 + Tesses.CMS/Assets/AccountEditor.html | 19 + Tesses.CMS/Assets/EditMovieDetails.html | 8 +- Tesses.CMS/Assets/EditSeasonDetails.html | 55 + Tesses.CMS/Assets/EditShowDetails.html | 49 + Tesses.CMS/Assets/EmailHtml.html | 3 + Tesses.CMS/Assets/ExtrasViewer.html | 29 + Tesses.CMS/Assets/ManageHtml.html | 37 + Tesses.CMS/Assets/MoviePage.html | 9 + Tesses.CMS/Assets/PageShell.html | 13 +- Tesses.CMS/Assets/SeasonPage.html | 71 + Tesses.CMS/Assets/ShowPage.html | 77 + Tesses.CMS/Assets/ShowsPage.html | 24 + Tesses.CMS/Assets/SubtitleEditor.html | 135 ++ Tesses.CMS/Assets/SubtitleLangList.html | 11 + Tesses.CMS/Assets/Upload.html | 8 +- Tesses.CMS/Assets/UserPage.html | 3 +- Tesses.CMS/Assets/VerifyEmail.html | 2 + Tesses.CMS/Assets/VerifyEmailWeb.html | 1 + Tesses.CMS/Assets/WatchMovie.html | 10 +- Tesses.CMS/Bencode.cs | 1 - Tesses.CMS/CMSConfiguration.cs | 18 + Tesses.CMS/Class1.cs | 1410 ++++++++++++++++- Tesses.CMS/Episode.cs | 45 + Tesses.CMS/IContentProvider.cs | 44 +- Tesses.CMS/LiteDbContentProvider.cs | 132 -- Tesses.CMS/MockContentProvier.cs | 149 -- Tesses.CMS/Season.cs | 39 + Tesses.CMS/Show.cs | 36 + Tesses.CMS/Tesses.CMS.csproj | 14 +- Tesses.CMS/UserAccount.cs | 1 + 42 files changed, 2856 insertions(+), 358 deletions(-) create mode 100644 Dockerfile create mode 100644 Tesses.CMS.Providers.Dapper/Class1.cs create mode 100644 Tesses.CMS.Providers.Dapper/Tesses.CMS.Providers.Dapper.csproj create mode 100644 Tesses.CMS.Providers.LiteDb/Class1.cs create mode 100644 Tesses.CMS.Providers.LiteDb/Tesses.CMS.Providers.LiteDb.csproj create mode 100644 Tesses.CMS/Assets/AboutUser.html create mode 100644 Tesses.CMS/Assets/AccountEditor.html create mode 100644 Tesses.CMS/Assets/EditSeasonDetails.html create mode 100644 Tesses.CMS/Assets/EditShowDetails.html create mode 100644 Tesses.CMS/Assets/EmailHtml.html create mode 100644 Tesses.CMS/Assets/ExtrasViewer.html create mode 100644 Tesses.CMS/Assets/ManageHtml.html create mode 100644 Tesses.CMS/Assets/SeasonPage.html create mode 100644 Tesses.CMS/Assets/ShowPage.html create mode 100644 Tesses.CMS/Assets/ShowsPage.html create mode 100644 Tesses.CMS/Assets/SubtitleEditor.html create mode 100644 Tesses.CMS/Assets/SubtitleLangList.html create mode 100644 Tesses.CMS/Assets/VerifyEmail.html create mode 100644 Tesses.CMS/Assets/VerifyEmailWeb.html create mode 100644 Tesses.CMS/Episode.cs delete mode 100644 Tesses.CMS/LiteDbContentProvider.cs delete mode 100644 Tesses.CMS/MockContentProvier.cs create mode 100644 Tesses.CMS/Season.cs create mode 100644 Tesses.CMS/Show.cs diff --git a/.gitignore b/.gitignore index 09dff5a..d721b24 100644 --- a/.gitignore +++ b/.gitignore @@ -482,3 +482,4 @@ $RECYCLE.BIN/ # Vim temporary swap files *.swp +help.txt \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..dfc6bd6 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,13 @@ +FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build + +WORKDIR /src +COPY . . +WORKDIR /src/Tesses.CMS.Server +RUN dotnet publish -c Release -o /app + +FROM mcr.microsoft.com/dotnet/runtime:7.0 AS runner +RUN apt update && apt install -y ffmpeg +WORKDIR /app +COPY --from=build /app . +EXPOSE 62444 +ENTRYPOINT ["dotnet", "Tesses.CMS.Server.dll", "/data"] diff --git a/Tesses.CMS.Cli/Program.cs b/Tesses.CMS.Cli/Program.cs index 45ec932..c382861 100644 --- a/Tesses.CMS.Cli/Program.cs +++ b/Tesses.CMS.Cli/Program.cs @@ -1,17 +1,14 @@ using Tesses.CMS.Client; -TessesCMSClient client = new TessesCMSClient("http://192.168.0.155:62444/"); +TessesCMSClient client = new TessesCMSClient("http://192.168.0.158:62444/"); -await foreach(var item in client.Movies.GetMoviesAsync("Blender")) +await foreach(var item in client.Movies.GetMoviesAsync("tesses")) { + var res=await client.Movies.GetMovieContentMetadataAsync("tesses",item.Name); Console.WriteLine(item.ProperName); + Console.WriteLine($"\t{res.PosterUrl}"); } -bool success=await client.Users.LoginAsync("johndoe@example.com","Se7enMovie"); -if(success) -{ - Console.WriteLine("Logged in successfully"); -} //await client.Movies.CreateAsync("HolyLoop","Holy Loop"); diff --git a/Tesses.CMS.Client/Class1.cs b/Tesses.CMS.Client/Class1.cs index e550799..3166003 100644 --- a/Tesses.CMS.Client/Class1.cs +++ b/Tesses.CMS.Client/Class1.cs @@ -1,8 +1,10 @@ using System; using System.Collections; using System.Collections.Generic; +using System.IO; using System.Net.Http; using System.Security.Cryptography; +using System.Threading; using System.Threading.Tasks; using System.Web; using Newtonsoft.Json; @@ -41,6 +43,46 @@ namespace Tesses.CMS.Client { } + public async Task DownloadFileAsync(string url,string dest,CancellationToken token=default,IProgress progress=null) + { + using(var f = File.Create(dest)) + await DownloadFileAsync(url,f,token,progress); + } + public async Task DownloadFileAsync(string url,Stream dest,CancellationToken token=default,IProgress progress=null) + { + + long offset=0; + long total=0; + if(dest.CanSeek) + { + offset=dest.Length; + dest.Seek(offset,SeekOrigin.Begin); + } + HttpRequestMessage message=new HttpRequestMessage(HttpMethod.Get,url); + if(offset > 0) + { + message.Headers.Range=new System.Net.Http.Headers.RangeHeaderValue(offset,null); + + } + var resp=await client.SendAsync(message); + if(resp.StatusCode == System.Net.HttpStatusCode.RequestedRangeNotSatisfiable) return; + resp.EnsureSuccessStatusCode(); + total = resp.StatusCode == System.Net.HttpStatusCode.PartialContent ? resp.Content.Headers.ContentLength.GetValueOrDefault() + offset : resp.Content.Headers.ContentLength.GetValueOrDefault(); + int read=0; + byte[] buffer=new byte[1024]; + + using(var srcStrm = await resp.Content.ReadAsStreamAsync()) + do { + if(token.IsCancellationRequested) return; + read = await srcStrm.ReadAsync(buffer,0,buffer.Length,token); + if(token.IsCancellationRequested) return; + await dest.WriteAsync(buffer,0,read,token); + offset += read; + if(total > 0) + progress?.Report((double)offset / (double)read); + } while(read>0); + resp.Dispose(); + } public MovieClient Movies => new MovieClient(this); @@ -81,5 +123,18 @@ namespace Tesses.CMS.Client yield return item; } } + public async Task GetMovieContentMetadataAsync(string user,string movie) + { + return JsonConvert.DeserializeObject(await client.client.GetStringAsync($"{client.rooturl.TrimEnd('/')}/api/v1/MovieFile?movie={movie}&user={user}&type=json")); + } + + public async Task DownloadMovieAsync(string user,string movie,string dest,CancellationToken token=default,IProgress progress=null) + { + await client.DownloadFileAsync($"{client.rooturl.TrimEnd('/')}/content/{user}/movie/{movie}/{movie}.mp4",dest,token,progress); + } + public async Task DownloadMovieAsync(string user,string movie,Stream dest,CancellationToken token=default,IProgress progress=null) + { + await client.DownloadFileAsync($"{client.rooturl.TrimEnd('/')}/content/{user}/movie/{movie}/{movie}.mp4",dest,token,progress); + } } } diff --git a/Tesses.CMS.Client/Movie.cs b/Tesses.CMS.Client/Movie.cs index a2d726d..a9d8e1e 100644 --- a/Tesses.CMS.Client/Movie.cs +++ b/Tesses.CMS.Client/Movie.cs @@ -1,7 +1,59 @@ using System; +using System.Collections.Generic; +using Newtonsoft.Json; namespace Tesses.CMS.Client { + public class MovieContentMetaData + { + [JsonProperty("movie_torrent_url")] + public string MovieTorrentUrl {get;set;} + + [JsonProperty("movie_with_extras_torrent_url")] + public string MovieWithExtrasTorrentUrl {get;set;} + + [JsonProperty("browser_stream")] + public string BrowserStream {get;set;} + + [JsonProperty("download_stream")] + public string DownloadStream {get;set;} + + [JsonProperty("poster_url")] + public string PosterUrl {get;set;} + + [JsonProperty("thumbnail_url")] + + public string ThumbnailUrl {get;set;} + + [JsonProperty("subtitle_streams")] + public List SubtitlesStreams {get;set;}=new List(); + + [JsonProperty("extra_streams")] + public List ExtraStreams {get;set;}=new List(); + } + public class ExtraDataStream + { + [JsonProperty("is_dir")] + public bool IsDir {get;set;} + [JsonProperty("name")] + public string Name {get;set;} + + [JsonProperty("items")] + + public List Items {get;set;}=new List(); + [JsonProperty("url")] + public string Url {get;set;} + } + public class SubtitleStream + { + [JsonProperty("language_code")] + public string LanguageCode {get;set;}=""; + + [JsonProperty("url")] + + public string SubtitleUrl {get;set;} + } + public class Movie { public string ProperName {get;set;} diff --git a/Tesses.CMS.Providers.Dapper/Class1.cs b/Tesses.CMS.Providers.Dapper/Class1.cs new file mode 100644 index 0000000..24883ca --- /dev/null +++ b/Tesses.CMS.Providers.Dapper/Class1.cs @@ -0,0 +1,298 @@ +using System; +using System.Collections.Generic; +using Tesses.CMS; +using Dapper; +using System.Data.Common; +using System.Linq; +using Newtonsoft.Json; +namespace Tesses.CMS.Providers +{ + public class MysqlDapperContentProvider : IContentProvider + { + DbConnection con; + public MysqlDapperContentProvider(DbConnection connection) + { + this.con = connection; + + con.Execute("CREATE TABLE IF NOT EXISTS Users (Id bigint NOT NULL PRIMARY KEY AUTOINCREMENT,AboutMe text,AccountsToMail text,Email text,IsAdmin bool,IsInvited bool,IsVerified bool,PasswordHash text,ProperName text,Salt text,Username text,Webhooks text);"); + con.Execute("CREATE TABLE IF NOT EXISTS Sessions (Id bigint NOT NULL PRIMARY KEY AUTOINCREMENT,Session text,Account bigint);"); + con.Execute("CREATE TABLE IF NOT EXISTS VerificationCodes (Id bigint NOT NULL PRIMARY KEY AUTOINCREMENT,Session text,Account bigint,Expires bigint);"); + con.Execute("CREATE TABLE IF NOT EXISTS Movies (Id bigint NOT NULL PRIMARY KEY AUTOINCREMENT,UserId bigint,CreationTime bigint,LastUpdated bigint,Description text,Name text,ProperName text);"); + + } + public void ChangeSession(string session, long account) + { + con.Execute("UPDATE Sessions set Account = @account WHERE Session = @session;",new{session,account}); + } + + public bool ContainsSession(string cookie) + { + return con.QueryFirstOrDefault("SELECT * FROM Sessions WHERE Session = @cookie;",new{cookie})!=null; + } + + public bool ContainsVerificationCode(string code) + { + var res=con.QueryFirstOrDefault("SELECT * FROM VerificationCodes WHERE Session = @code;",new{code}); + if(res != null) + { + long expires = res.Expires; + if(DateTimeOffset.Now>= DateTimeOffset.FromUnixTimeSeconds(expires)) + { + con.Execute("DELETE FROM VerificationCodes WHERE Session = @code;",new{code}); + return false; + } + return true; + } + return false; + } + + public Movie CreateMovie(string user, string movie, string properName, string description) + { + var userId=GetUserAccount(user).Id; + Movie movie1=new Movie(); + movie1.UserId = userId; + movie1.Name = movie; + movie1.ProperName=properName; + movie1.Description=description; + + con.Execute("INSERT INTO Movies(movie) values (@movie);",new{movie=new DapperMovie(movie1)}); + return GetMovie(user,movie); + } + + public void CreateSession(string session, long account) + { + con.Execute("INSERT INTO Sessions(Session,Account) values (@session,@account);",new{session,account}); + } + + public void CreateUser(CMSConfiguration configuration, string user, string properName, string email, string password) + { + bool first=con.QueryFirstOrDefault("SELECT * FROM Users LIMIT 0, 1;") == null; + + UserAccount account=new UserAccount(); + account.IsAdmin = first; + account.IsVerified = first; + account.Email =email; + account.ProperName = properName; + account.Username = user; + account.NewSalt(); + account.PasswordHash = account.GetPasswordHash(password); + + + DapperUserAccount account1=new DapperUserAccount(account); + + con.Execute("INSERT INTO Users(user) values (@user);",new{user=account1}); + } + + public void CreateVerificationCode(string code, long account) + { + long expires=DateTimeOffset.Now.AddDays(1).ToUnixTimeSeconds(); + con.Execute("INSERT INTO VerificationCodes(Session,Account,Expires) values (@code,@account,@expires);",new{code,account,expires}); + } + + public void DeleteSession(string session) + { + con.Execute("DELETE FROM Sessions WHERE Session = @session;",new{session}); + } + + public void DeleteVerificationCode(string code) + { + con.Execute("DELETE FROM VerificationCodes WHERE Session = @code;",new{code}); + } + + public UserAccount GetFirstUser() + { + return con.QueryFirstOrDefault("SELECT * FROM Users LIMIT 0, 1;")?.Account; + } + + public Movie GetMovie(string user, string movie) + { + long? id =GetUserAccount(user)?.Id; + if(!id.HasValue) return null; + return con.QueryFirstOrDefault("SELECT * FROM Users WHERE UserId=@id; AND Name=@movie",new{movie,id})?.MovieObject; + } + + + + public IEnumerable GetMovies(string user) + { + long? id =GetUserAccount(user)?.Id; + if(!id.HasValue) yield break; + foreach(var item in GetMovies(id.Value)) + { + yield return item; + } + } + + public IEnumerable GetMovies(long user) + { + foreach(var item in con.Query("SELECT * FROM Movies;")) + { + yield return item.MovieObject; + } + } + + public long? GetSession(string session) + { + return con.QueryFirstOrDefault("SELECT * FROM Sessions WHERE Session = @session;",new{session})?.Id; + } + + public UserAccount GetUserAccount(string user) + { + return con.QueryFirstOrDefault("SELECT * FROM Users WHERE Username=@user;",new{user})?.Account; + } + + public UserAccount GetUserById(long account) + { + return con.QueryFirstOrDefault("SELECT * FROM Users WHERE Id=@id;",new{id=account})?.Account; + } + + public IEnumerable GetUsers() + { + foreach(var user in con.Query("SELECT * FROM Users;")) + { + yield return user.Account; + } + } + + public long? GetVerificationAccount(string code) + { + var res=con.QueryFirstOrDefault("SELECT * FROM VerificationCodes WHERE Session = @code;",new{code}); + if(res != null) + { + long expires = res.Expires; + if(DateTimeOffset.Now>= DateTimeOffset.FromUnixTimeSeconds(expires)) + { + con.Execute("DELETE FROM VerificationCodes WHERE Session = @code;",new{code}); + return null; + } + return res.Account; + } + return null; + } + + public void UpdateMovie(Movie movie) + { + DapperMovie dapperMovie=new DapperMovie(movie); + con.Execute("UPDATE Users set movie = @movie WHERE Id = @id;",new{movie=dapperMovie,id=movie.Id}); + } + + public void UpdateUser(UserAccount account) + { + DapperUserAccount account1=new DapperUserAccount(account); + con.Execute("UPDATE Users set user = @user WHERE Id = @id;",new{user=account1,id=account1.Id}); + } + } + + internal class DapperMovie + { + public long Id {get;set;} + public long UserId {get;set;} + + public long CreationTime {get;set;} + + public long LastUpdated {get;set;} + + public string Description {get;set;} + + public string Name {get;set;} + + public string ProperName {get;set;} + + + public Movie MovieObject { + get{ + return new Movie(){ + UserId = UserId, + CreationTime=DateTimeOffset.FromUnixTimeSeconds(CreationTime).DateTime, + LastUpdated=DateTimeOffset.FromUnixTimeSeconds(LastUpdated).DateTime, + Description=Description, + Id=Id, + Name=Name, + ProperName=ProperName + }; + } + set{ + UserId=value.UserId; + CreationTime=new DateTimeOffset(value.CreationTime).ToUnixTimeSeconds(); + LastUpdated=new DateTimeOffset(value.LastUpdated).ToUnixTimeSeconds(); + Description=value.Description; + Id=value.Id; + Name=value.Name; + ProperName=value.ProperName; + } + } + + public DapperMovie(Movie movie1) + { + MovieObject = movie1; + } + public DapperMovie() + { + + } + } + + internal class DapperUserAccount + { + public DapperUserAccount() + { + + } + public DapperUserAccount(UserAccount account) + { + Account =account; + } + public long Id {get;set;} + + public string AboutMe {get;set;} + public string AccountsToMail { get; set; } + public string Email { get; set; } + + public bool IsAdmin {get;set;} + public bool IsInvited {get;set;} + + public bool IsVerified {get;set;} + + public string PasswordHash {get;set;} + public string ProperName {get;set;} + public string Salt {get;set;} + public string Username {get;set;} + + public string Webhooks {get;set;} + + public UserAccount Account { + get { + + return new UserAccount(){ + Id = Id, + AboutMe = AboutMe, + AccountsToMail=JsonConvert.DeserializeObject>(AccountsToMail), + Email=Email, + IsAdmin=IsAdmin, + IsInvited=IsInvited, + IsVerified=IsVerified, + PasswordHash=PasswordHash, + ProperName=ProperName, + Salt=Salt, + Username=Username, + Webhooks = JsonConvert.DeserializeObject>(Webhooks) + }; + } + set{ + Id = value.Id; + AboutMe = value.AboutMe; + AccountsToMail = JsonConvert.SerializeObject(value.AccountsToMail); + Email=value.Email; + IsAdmin = value.IsAdmin; + IsInvited = value.IsInvited; + IsVerified = value.IsVerified; + PasswordHash = value.PasswordHash; + ProperName = value.ProperName; + Salt = value.Salt; + Username = value.Username; + Webhooks = JsonConvert.SerializeObject(value.Webhooks); + + } + } + } +} diff --git a/Tesses.CMS.Providers.Dapper/Tesses.CMS.Providers.Dapper.csproj b/Tesses.CMS.Providers.Dapper/Tesses.CMS.Providers.Dapper.csproj new file mode 100644 index 0000000..af352f4 --- /dev/null +++ b/Tesses.CMS.Providers.Dapper/Tesses.CMS.Providers.Dapper.csproj @@ -0,0 +1,15 @@ + + + + netstandard2.0 + + + + + + + + + + + diff --git a/Tesses.CMS.Providers.LiteDb/Class1.cs b/Tesses.CMS.Providers.LiteDb/Class1.cs new file mode 100644 index 0000000..96bc27e --- /dev/null +++ b/Tesses.CMS.Providers.LiteDb/Class1.cs @@ -0,0 +1,283 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using LiteDB; +using Tesses.CMS; +namespace Tesses.CMS.Providers { +public class LiteDBContentProvider : IContentProvider +{ + string dir; + ILiteDatabase db; + public LiteDBContentProvider(string dir) + { + this.dir = dir; + db=new LiteDatabase(Path.Combine(dir,"tesses-cms.db")); + } + public Movie CreateMovie(string user, string movie, string properName, string description) + { + var userId=GetUserAccount(user).Id; + + Movie _movie = new Movie(){UserId = userId,Name = movie,ProperName=properName,Description = description}; + _movie.Id=Movies.Insert(_movie); + return _movie; + } + public Show CreateShow(string user, string show, string properName, string description) + { + var userId=GetUserAccount(user).Id; + + Show _show = new Show(){UserId = userId,Name = show,ProperName=properName,Description = description}; + _show.Id=Shows.Insert(_show); + return _show; + } + private ILiteCollection UserAccounts => db.GetCollection("users"); + private ILiteCollection Movies => db.GetCollection("movies"); + + private ILiteCollection Shows => db.GetCollection("shows"); + private ILiteCollection Seasons => db.GetCollection("seasons"); + private ILiteCollection Episodes => db.GetCollection("episodes"); + + private ILiteCollection Sessions => db.GetCollection("sessions"); + private ILiteCollection VerificationCodes => db.GetCollection("verificationcodes"); + + public UserAccount GetFirstUser() + { + return GetUsers().First(); + } + + public Movie GetMovie(string user, string movie) + { + var userId=GetUserAccount(user).Id; + return Movies.FindOne(e=>e.Name == movie && e.UserId == userId); + } + + public Show GetShow(string user,string show) + { + var userId=GetUserAccount(user).Id; + return Shows.FindOne(e=>e.Name == show && e.UserId == userId); + } + + public IEnumerable GetMovies(string user) + { + var userId = GetUserAccount(user).Id; + return GetMovies(userId); + } + + public IEnumerable GetMovies(long user) + { + return Movies.Find(e=>e.UserId==user); + } + + public IEnumerable GetShows(long user) + { + return Shows.Find(e=>e.UserId==user); + } + + public IEnumerable GetShows(string user) + { + var userId = GetUserAccount(user).Id; + return GetShows(userId); + } + + public UserAccount GetUserAccount(string user) + { + return UserAccounts.FindOne(e=>e.Username == user); + } + + public IEnumerable GetUsers() + { + return UserAccounts.FindAll(); + } + + public void CreateUser(CMSConfiguration configuration,string user,string properName,string email,string password) + { + bool isOwner = UserAccounts.Count() == 0; + UserAccount account=new UserAccount(); + account.IsAdmin=isOwner; + account.IsVerified = isOwner; + account.Username = user; + account.ProperName= properName; + account.NewSalt(); + account.PasswordHash=account.GetPasswordHash(password); + account.Email = email; + UserAccounts.Insert(account); + } + + public void UpdateMovie(Movie movie) + { + Movies.Update(movie); + } + public void UpdateShow(Show show) + { + Shows.Update(show); + } + + + public void UpdateUser(UserAccount account) + { + UserAccounts.Update(account); + } + + public UserAccount GetUserById(long account) + { + return UserAccounts.FindById(account); + } + + public class LiteDbSession + { + public long Id {get;set;} + + public string Session {get;set;} + + public long Account {get;set;} + } + + public class LiteDbVerificationToken + { + public long Id {get;set;} + + public string Code {get;set;} + + public long Account {get;set;} + + public DateTime Expires {get;set;} + } + + public void CreateSession(string session, long account) + { + LiteDbSession _session=new LiteDbSession(); + _session.Account = account; + _session.Session = session; + Sessions.Insert(_session); + } + public void ChangeSession(string session, long account) + { + var s=Sessions.FindOne(e=>e.Session == session); + if(s!=null){s.Account = account; Sessions.Update(s);} + } + + public void DeleteSession(string session) + { + var s=Sessions.FindOne(e=>e.Session == session); + if(s!=null){ Sessions.Delete(s.Id);} + } + + public long? GetSession(string session) + { + var s=Sessions.FindOne(e=>e.Session == session); + return s != null ? s.Account : (long?)null; + } + + public bool ContainsSession(string cookie) + { + return Sessions.Exists(e=>e.Session == cookie); + } + + public void CreateVerificationCode(string code, long account) + { + LiteDbVerificationToken liteDbVerificationToken=new LiteDbVerificationToken(); + liteDbVerificationToken.Account = account; + liteDbVerificationToken.Code = code; + liteDbVerificationToken.Expires=DateTime.Now.AddDays(1); + VerificationCodes.Insert(liteDbVerificationToken); + } + + public void DeleteVerificationCode(string code) + { + var c = VerificationCodes.FindOne(e=>e.Code==code); + if(c != null){VerificationCodes.Delete(c.Id);} + } + + public long? GetVerificationAccount(string code) + { + var c = VerificationCodes.FindOne(e=>e.Code==code); + if(c != null){ + if(DateTime.Now > c.Expires) + VerificationCodes.Delete(c.Id); + else + return c.Account; + } + return null; + } + + public bool ContainsVerificationCode(string code) + { + return VerificationCodes.Exists(e=>e.Code==code); + } + + public int SeasonCount(string user, string show) + { + var myShow = GetShow(user,show); + var userId = myShow.UserId; + var showId = myShow.Id; + int seasonLargest=0; + foreach(var item in Seasons.Find(e=>e.ShowId==showId && e.UserId == userId)) + { + if(item.SeasonNumber > seasonLargest) + seasonLargest = item.SeasonNumber; + } + return seasonLargest; + } + + public Season GetSeason(string user, string show, int season) + { + var myShow = GetShow(user,show); + var userId = myShow.UserId; + var showId = myShow.Id; + return Seasons.FindOne(e=>e.ShowId == showId && e.UserId == userId && e.SeasonNumber == season); + } + + public Season CreateSeason(string user, string show, int season, string properName, string description) + { + var myShow = GetShow(user,show); + var userId = myShow.UserId; + var showId = myShow.Id; + Season _season = new Season(){UserId = userId,ShowId = showId,ProperName=properName,Description = description, SeasonNumber=season}; + _season.Id=Seasons.Insert(_season); + return _season; + } + + public int EpisodeCount(string user, string show, int season) + { + var myShow = GetShow(user,show); + var userId = myShow.UserId; + var showId = myShow.Id; + int episodeLargest=0; + foreach(var item in Episodes.Find(e=>e.ShowId==showId && e.UserId == userId && e.SeasonNumber == season)) + { + if(item.EpisodeNumber > episodeLargest) + episodeLargest = item.EpisodeNumber; + } + return episodeLargest; + } + + public Episode GetEpisode(string user, string show, int season, int episode) + { + var myShow = GetShow(user,show); + var userId = myShow.UserId; + var showId = myShow.Id; + return Episodes.FindOne(e=>e.ShowId == showId && e.UserId == userId && e.SeasonNumber == season && e.EpisodeNumber == episode); + + } + + public Episode CreateEpisode(string user, string show, int season, int episode, string episodename, string properName, string description) + { + var myShow = GetShow(user,show); + var userId = myShow.UserId; + var showId = myShow.Id; + Episode _episode = new Episode(){UserId = userId,ShowId = showId,ProperName=properName,Description = description, SeasonNumber=season, EpisodeNumber = episode,EpisodeName=episodename}; + _episode.Id=Episodes.Insert(_episode); + return _episode; + } + + public void UpdateEpisode(Episode episode) + { + Episodes.Update(episode); + } + + public void UpdateSeason(Season season) + { + Seasons.Update(season); + } + } +} diff --git a/Tesses.CMS.Providers.LiteDb/Tesses.CMS.Providers.LiteDb.csproj b/Tesses.CMS.Providers.LiteDb/Tesses.CMS.Providers.LiteDb.csproj new file mode 100644 index 0000000..e31510e --- /dev/null +++ b/Tesses.CMS.Providers.LiteDb/Tesses.CMS.Providers.LiteDb.csproj @@ -0,0 +1,15 @@ + + + + netstandard2.0 + + + + + + + + + + + diff --git a/Tesses.CMS.Server/Program.cs b/Tesses.CMS.Server/Program.cs index 2f34353..f72f50c 100644 --- a/Tesses.CMS.Server/Program.cs +++ b/Tesses.CMS.Server/Program.cs @@ -1,4 +1,5 @@ using Tesses.WebServer; +using Tesses.CMS.Providers; using Tesses.CMS; string path = args.Length > 0 ? args[0] : "data"; CMSServer server=new CMSServer(path,new LiteDBContentProvider(path)); diff --git a/Tesses.CMS.Server/Tesses.CMS.Server.csproj b/Tesses.CMS.Server/Tesses.CMS.Server.csproj index cc5febd..40a5032 100644 --- a/Tesses.CMS.Server/Tesses.CMS.Server.csproj +++ b/Tesses.CMS.Server/Tesses.CMS.Server.csproj @@ -7,14 +7,15 @@ enable - - - - + + + + - - + + + diff --git a/Tesses.CMS/Assets/AboutUser.html b/Tesses.CMS/Assets/AboutUser.html new file mode 100644 index 0000000..d5f188a --- /dev/null +++ b/Tesses.CMS/Assets/AboutUser.html @@ -0,0 +1,4 @@ +

{{propername}}

+
+

About me

+

{{aboutme}}

\ No newline at end of file diff --git a/Tesses.CMS/Assets/AccountEditor.html b/Tesses.CMS/Assets/AccountEditor.html new file mode 100644 index 0000000..9312883 --- /dev/null +++ b/Tesses.CMS/Assets/AccountEditor.html @@ -0,0 +1,19 @@ +
+
+ + +
+ +
+ + +
+ + {{if notverified}} +Resend Verification Link +{{end}} +{{if admin}} +Manage Accounts +{{end}} +Logout +
diff --git a/Tesses.CMS/Assets/EditMovieDetails.html b/Tesses.CMS/Assets/EditMovieDetails.html index 5926069..ff4614c 100644 --- a/Tesses.CMS/Assets/EditMovieDetails.html +++ b/Tesses.CMS/Assets/EditMovieDetails.html @@ -4,10 +4,10 @@ -
- - -
+
+ + +
diff --git a/Tesses.CMS/Assets/EditSeasonDetails.html b/Tesses.CMS/Assets/EditSeasonDetails.html new file mode 100644 index 0000000..b8e9f5b --- /dev/null +++ b/Tesses.CMS/Assets/EditSeasonDetails.html @@ -0,0 +1,55 @@ +

Change season metadata

+
+
+ + +
+
+ + +
+ + +
+
+

Add episode

+
+
+ + +
This is the name that is used in Download Name, no spaces or /\"&,?|:;*@!#
+ +
+
+ + + +
+
+ + +
+
+ + +
+ + +
+
+

Upload asset files

+
+

You should do these in order (not required but recomended because you can only upload one at a time, that is in one tab at least)

+ +
+ + +
+ + +
+
+View/Edit extras \ No newline at end of file diff --git a/Tesses.CMS/Assets/EditShowDetails.html b/Tesses.CMS/Assets/EditShowDetails.html new file mode 100644 index 0000000..c7a04f2 --- /dev/null +++ b/Tesses.CMS/Assets/EditShowDetails.html @@ -0,0 +1,49 @@ +

Change show metadata

+
+
+ + +
+
+ + +
+ + +
+
+

Add season

+
+
+ + + +
+
+ + +
+
+ + +
+ + +
+
+

Upload asset files

+
+

You should do these in order (not required but recomended because you can only upload one at a time, that is in one tab at least)

+ +
+ + +
+ + +
+
+View/Edit extras \ No newline at end of file diff --git a/Tesses.CMS/Assets/EmailHtml.html b/Tesses.CMS/Assets/EmailHtml.html new file mode 100644 index 0000000..5957e55 --- /dev/null +++ b/Tesses.CMS/Assets/EmailHtml.html @@ -0,0 +1,3 @@ +

{{websitename}}

+
+{{body}} \ No newline at end of file diff --git a/Tesses.CMS/Assets/ExtrasViewer.html b/Tesses.CMS/Assets/ExtrasViewer.html new file mode 100644 index 0000000..7e2c66a --- /dev/null +++ b/Tesses.CMS/Assets/ExtrasViewer.html @@ -0,0 +1,29 @@ +

Extras path: {{path}}

+{{if editable}} +

Create Directory

+
+ +
+ + + +
+
+

Upload File

+
+ +
+ + +
+ + +
+{{end}} + \ No newline at end of file diff --git a/Tesses.CMS/Assets/ManageHtml.html b/Tesses.CMS/Assets/ManageHtml.html new file mode 100644 index 0000000..5eed12b --- /dev/null +++ b/Tesses.CMS/Assets/ManageHtml.html @@ -0,0 +1,37 @@ + +
    +{{for user in users}} + +
  • + {{user.propername}} ({{user.name}}) +
    + +
    + + +
    +
    +
    + + +
    +
    +
    + + +
    + + + + Impersonate +
    + +
  • +{{end}} +
\ No newline at end of file diff --git a/Tesses.CMS/Assets/MoviePage.html b/Tesses.CMS/Assets/MoviePage.html index ec73c28..0d493f3 100644 --- a/Tesses.CMS/Assets/MoviePage.html +++ b/Tesses.CMS/Assets/MoviePage.html @@ -4,10 +4,18 @@

{{movieproper}}

{{userproper}}


+ {{if moviebrowserexists}} Watch Online + {{end}} + {{if movieexists}} Download + {{end}} {{if editable}} Edit + Edit Subtitles + {{end}} + {{if extrasexists}} + Extras {{end}} {{if torrentexists}} Torrent @@ -24,6 +32,7 @@ Description +

{{moviedescription}}

diff --git a/Tesses.CMS/Assets/PageShell.html b/Tesses.CMS/Assets/PageShell.html index 3ac8bd2..febdbc6 100644 --- a/Tesses.CMS/Assets/PageShell.html +++ b/Tesses.CMS/Assets/PageShell.html @@ -4,8 +4,16 @@ {{title}} - +
@@ -31,9 +39,8 @@
- {{body}} +{{body}}
- \ No newline at end of file diff --git a/Tesses.CMS/Assets/SeasonPage.html b/Tesses.CMS/Assets/SeasonPage.html new file mode 100644 index 0000000..467c12b --- /dev/null +++ b/Tesses.CMS/Assets/SeasonPage.html @@ -0,0 +1,71 @@ +
+
+ +
+
+
+ {{seasonproper}} +

{{seasonproper}}

+

{{showproper}}

+

{{userproper}}

+
+ {{if editable}} + Edit + + {{end}} + + +
+
+
+

+ +

+
+
+
+

{{seasondescription}}

+
+
+
+
+
+
+
+ + +
+ +
+
+
+ +
\ No newline at end of file diff --git a/Tesses.CMS/Assets/ShowPage.html b/Tesses.CMS/Assets/ShowPage.html new file mode 100644 index 0000000..4026162 --- /dev/null +++ b/Tesses.CMS/Assets/ShowPage.html @@ -0,0 +1,77 @@ +
+
+ +
+
+
+ {{showproper}} +

{{showproper}}

+

{{userproper}}

+
+ {{if editable}} + Edit + + {{end}} + {{if extrasexists}} + Extras + {{end}} + {{if torrentexists}} + Torrent + {{end}} + {{if torrentwextraexists}} + Torrent With Extras + {{end}} +
+
+
+

+ +

+
+
+
+

{{showdescription}}

+
+
+
+
+
+
+
+ + +
+ +
+
+
+ +
\ No newline at end of file diff --git a/Tesses.CMS/Assets/ShowsPage.html b/Tesses.CMS/Assets/ShowsPage.html new file mode 100644 index 0000000..bfdc55a --- /dev/null +++ b/Tesses.CMS/Assets/ShowsPage.html @@ -0,0 +1,24 @@ +
+ + + +
\ No newline at end of file diff --git a/Tesses.CMS/Assets/SubtitleEditor.html b/Tesses.CMS/Assets/SubtitleEditor.html new file mode 100644 index 0000000..c7f0c1f --- /dev/null +++ b/Tesses.CMS/Assets/SubtitleEditor.html @@ -0,0 +1,135 @@ +
+
+
+
+

Current Subtitle

+

+

+

+ +
+ +
+ +
+

All Subtitles

+
    +
    +
    +
    + + + diff --git a/Tesses.CMS/Assets/SubtitleLangList.html b/Tesses.CMS/Assets/SubtitleLangList.html new file mode 100644 index 0000000..6a75b8d --- /dev/null +++ b/Tesses.CMS/Assets/SubtitleLangList.html @@ -0,0 +1,11 @@ +
    +
    + + +
    +
    \ No newline at end of file diff --git a/Tesses.CMS/Assets/Upload.html b/Tesses.CMS/Assets/Upload.html index 30b5640..c76f94a 100644 --- a/Tesses.CMS/Assets/Upload.html +++ b/Tesses.CMS/Assets/Upload.html @@ -10,10 +10,10 @@
    -
    - - -
    +
    + + +