Fixed some stuff

This commit is contained in:
Mike Nolan 2021-12-29 22:07:31 -06:00
parent 24e220badc
commit 0cb21eb58c
10 changed files with 244 additions and 71 deletions

View File

@ -40,27 +40,41 @@ namespace Timelapse.Api
} }
public class Extensions public class Extensions
{ {
public static IReadOnlyDictionary<string,Type> Components {get {return _components;}}
internal static Dictionary<string,Type> _components = new Dictionary<string, Type>();
public static string GetId(TimelapseExtension e) public static string GetId(TimelapseExtension e)
{ {
return e.__id; return e.__id;
} }
public static async Task<IActionResult> OnGetPage(string extId,string subPage) /// <summary>
{ /// Callbacks back to TimelapseUI
foreach(var item in Attributes) /// </summary>
{ /// <value></value>
if(item.Key.Id == extId)
{
return await item.Value.OnHandleRequest(subPage);
}
}
return new NotFoundResult();
}
public static Callbacks Callbacks {get;set;} public static Callbacks Callbacks {get;set;}
public static string UserData =Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),".TimelapseNow"); /// <summary>
/// UserData
/// </summary>
/// <returns>TimelapseNow Folder for user</returns>
public static string UserData =Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),"TimelapseNow");
/// <summary>
/// UserExtensions
/// </summary>
/// <returns>Location for Extensions</returns>
public static string UserExtensions = Path.Combine(UserData,"Extensions"); public static string UserExtensions = Path.Combine(UserData,"Extensions");
/// <summary>
/// Global Data for app
/// </summary>
/// <returns>Timelapse Folder for all users</returns>
public static string GlobalData = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData),"TimelapseNow"); public static string GlobalData = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData),"TimelapseNow");
/// <summary>
/// GlobalExtensions
/// </summary>
/// <returns>Location for extensions for all users</returns>
public static string GlobalExtensions = Path.Combine(GlobalData,"Extensions"); public static string GlobalExtensions = Path.Combine(GlobalData,"Extensions");
/// <summary>
/// Dont call this
/// </summary>
public static void EnumerateExtensions() public static void EnumerateExtensions()
{ {
TimelapseExtensions = new List<TimelapseExtension>(); TimelapseExtensions = new List<TimelapseExtension>();
@ -89,6 +103,10 @@ namespace Timelapse.Api
} }
} }
} }
/// <summary>
/// Only call this to load extension manually
/// </summary>
/// <param name="dll">path to dll</param>
public static void LoadDll(string dll) public static void LoadDll(string dll)
{ {
Assembly asm=Assembly.LoadFrom(dll); Assembly asm=Assembly.LoadFrom(dll);
@ -113,9 +131,24 @@ namespace Timelapse.Api
} }
Assemblies.Add(asm,dll); Assemblies.Add(asm,dll);
} }
/// <summary>
/// Assemblies
/// </summary>
/// <value>Dictionary of assembly,string</value>
public static Dictionary<Assembly,string> Assemblies {get;set;} public static Dictionary<Assembly,string> Assemblies {get;set;}
/// <summary>
/// Stores Attributes for extension
/// </summary>
/// <value>returns timelapseExtension based on attribute</value>
public static Dictionary<ExtensionAttribute,TimelapseExtension> Attributes {get;set;} public static Dictionary<ExtensionAttribute,TimelapseExtension> Attributes {get;set;}
/// <summary>
/// List of extensions
/// </summary>
/// <value>List of extensions</value>
public static List<TimelapseExtension> TimelapseExtensions {get;set;} public static List<TimelapseExtension> TimelapseExtensions {get;set;}
/// <summary>
/// Dont call this (this gets called from The UI)
/// </summary>
public static async Task OnNewFrame(Image<Rgb24> image) public static async Task OnNewFrame(Image<Rgb24> image)
{ {
@ -124,6 +157,9 @@ namespace Timelapse.Api
await extension.OnNewFrame(image); await extension.OnNewFrame(image);
} }
} }
/// <summary>
/// Dont call this (this gets called from The UI)
/// </summary>
public static void OnLoadProject(TimelapseProject project) public static void OnLoadProject(TimelapseProject project)
{ {
foreach(var extension in TimelapseExtensions) foreach(var extension in TimelapseExtensions)
@ -131,6 +167,9 @@ namespace Timelapse.Api
extension.OnLoadProject(project); extension.OnLoadProject(project);
} }
} }
/// <summary>
/// Dont call this (this gets called from The UI)
/// </summary>
public static void OnStopRecording() public static void OnStopRecording()
{ {
foreach(var extension in TimelapseExtensions) foreach(var extension in TimelapseExtensions)
@ -138,6 +177,9 @@ namespace Timelapse.Api
extension.OnStopRecording(); extension.OnStopRecording();
} }
} }
/// <summary>
/// Dont call this (this gets called from The UI)
/// </summary>
public static void OnStartRecording() public static void OnStartRecording()
{ {
foreach(var extension in TimelapseExtensions) foreach(var extension in TimelapseExtensions)
@ -145,6 +187,9 @@ namespace Timelapse.Api
extension.OnStartRecording(); extension.OnStartRecording();
} }
} }
/// <summary>
/// Dont call this (this gets called from The UI)
/// </summary>
public static void OnEnableOneX() public static void OnEnableOneX()
{ {
foreach(var extension in TimelapseExtensions) foreach(var extension in TimelapseExtensions)
@ -153,6 +198,9 @@ namespace Timelapse.Api
extension.OnEnableOneX(); extension.OnEnableOneX();
} }
} }
/// <summary>
/// Dont call this (this gets called from The UI)
/// </summary>
public static void OnDisableOneX() public static void OnDisableOneX()
{ {
foreach(var extension in TimelapseExtensions) foreach(var extension in TimelapseExtensions)

View File

@ -9,41 +9,158 @@ using System.Net;
namespace Timelapse.Api namespace Timelapse.Api
{ {
public class ProjectUnloadedException : Exception
{
public ProjectUnloadedException() : base("Project not Loaded")
{
}
}
public abstract class TimelapseExtension public abstract class TimelapseExtension
{ {
internal string __id; internal string __id;
internal bool _recording; internal bool _recording;
internal bool _onex; internal bool _onex;
/// <summary>
/// Recording bit
/// </summary>
/// <returns>Whether project is recording</returns>
protected bool Recording {get {return _recording;}set{if(value){StartRecording();} else{StopRecording();}}} protected bool Recording {get {return _recording;}set{if(value){StartRecording();} else{StopRecording();}}}
protected bool OneX {get {return _onex;}set{if(value) {EnableOneX();} else {DisableOneX();} }} /// <summary>
/// OneX bit
/// </summary>
/// <returns>Whether project is recording</returns>
protected bool OneX {get {return _onex;}set{if(value) {EnableOneX();} else {DisableOneX();} }}
/// <summary>
/// Called when Extension is Loaded
/// </summary>
public abstract void OnInit(); public abstract void OnInit();
/// <summary>
/// Name of Extension (retreved from Attribute)
/// </summary>
/// <value>The Name</value>
public string Name {get;internal set;} public string Name {get;internal set;}
/// <summary>
/// When a frame is taken by webcam and is about to be saved (async)
/// </summary>
/// <param name="frame">a mutable SixLabors.ImageSharp object</param>
/// <returns>Task but no data</returns>
public virtual async Task OnNewFrame(Image<Rgb24> frame) public virtual async Task OnNewFrame(Image<Rgb24> frame)
{ {
} }
/// <summary>
/// You could manipulate the project and detect project load
/// </summary>
/// <param name="project">TimelapseProject object</param>
public virtual void OnLoadProject(TimelapseProject project) public virtual void OnLoadProject(TimelapseProject project)
{ {
} }
///<summary>
///URL for in html pages /// <summary>
/// Register Razor Component
/// </summary>
/// <param name="href">the url for the razor component</param>
/// <typeparam name="T">The type</typeparam>
public void RegisterComponentAsPage<T>(string href)
{
Type typ= typeof(T);
Extensions._components.Add(GET_URL(href),typ);
}
///<summary>
///URL for in razor pages
///</summary> ///</summary>
public string GET_URL(string href) public string GET_URL(string href)
{ {
return $"/api/Extension/GetExtensionPage?extId={WebUtility.UrlEncode(__id)}&subPage={WebUtility.UrlEncode(href)}"; return $"/ExtensionPage/{WebUtility.UrlEncode(__id)}/{WebUtility.UrlEncode(href)}";
} }
/// <summary>
/// Write Object (as json)
/// </summary>
/// <param name="key">Path to file (must use forward slash '/' and can start with '/'</param>
/// <param name="project">whether you want to get project specific path</param>
/// <param name="contents">data to be writen to file</param>
public void WriteObject(string key,object contents,bool project=false)
{
WriteAllText(key,Newtonsoft.Json.JsonConvert.SerializeObject(contents),project);
}
/// <summary>
/// Read Object (as json)
/// </summary>
/// <param name="key">Path to file (must use forward slash '/' and can start with '/'</param>
/// <param name="project">whether you want to get project specific path</param>
/// <typeparam name="T">object type</typeparam>
/// <returns>object filled with data</returns>
public T ReadObject<T>(string key,bool project)
{
return Newtonsoft.Json.JsonConvert.DeserializeObject<T>(ReadAllText(key,project));
}
/// <summary>
/// Write all text
/// </summary>
/// <param name="key">Path to file (must use forward slash '/' and can start with '/'</param>
/// <param name="project">whether you want to get project specific path</param>
/// <param name="contents">data to be writen to file</param>
public void WriteAllText(string key,string contents,bool project=false)
{
string file=GetPath(key,project);
File.WriteAllText(file,contents);
}
/// <summary>
/// Read all text
/// </summary>
/// <param name="key">Path to file (must use forward slash '/' and can start with '/'</param>
/// <param name="project">whether you want to get project specific path</param>
/// <returns>file contents</returns>
public string ReadAllText(string key,bool project=false)
{
string file=GetPath(key,project);
return File.ReadAllText(file);
}
/// <summary>
/// Get Path to data file for extension
/// </summary>
/// <param name="key">Path to file (must use forward slash '/' and can start with '/'</param>
/// <param name="project">whether you want to get project specific path</param>
/// <returns>Path to file</returns>
public string GetPath(string key,bool project=false)
{
string v = key.TrimStart('/');
if(Path.DirectorySeparatorChar == '\\')
{
v = v.Replace('/','\\');
}
if(project)
{
return Path.Combine(GetExtensionProjectData(),v);
}else{
return Path.Combine(GetExtensionData(),v);
}
}
///<summary>
/// Get Project Specific Data for extension (Directory Path)
///</summary>
/// <returns>Path</returns>
protected string GetExtensionProjectData() protected string GetExtensionProjectData()
{ {
if(!Extensions.Callbacks.ProjectLoaded()) if(!Extensions.Callbacks.ProjectLoaded())
{ {
return null; throw new ProjectUnloadedException();
} }
string p = Path.Combine(Extensions.Callbacks.GetProjectDirectoryLocation(),"ExtensionData",__id); string p = Path.Combine(Extensions.Callbacks.GetProjectDirectoryLocation(),"ExtensionData",__id);
Directory.CreateDirectory(p); Directory.CreateDirectory(p);
return p; return p;
} }
///<summary>
/// Get Data for extension (Directory Path)
///</summary>
/// <returns>Path</returns>
protected string GetExtensionData() protected string GetExtensionData()
{ {
@ -51,45 +168,69 @@ namespace Timelapse.Api
Directory.CreateDirectory(p); Directory.CreateDirectory(p);
return p; return p;
} }
/// <summary>
/// Project Loaded
/// </summary>
/// <returns>returns true if project is loaded otherwise false</returns>
public bool IsProjectLoaded() public bool IsProjectLoaded()
{ {
return Extensions.Callbacks.ProjectLoaded(); return Extensions.Callbacks.ProjectLoaded();
} }
/// <summary>
/// Triggered when timelapse starts recording
/// </summary>
public virtual void OnStartRecording() public virtual void OnStartRecording()
{ {
} }
/// <summary>
/// Triggered when timelapse stops recording
/// </summary>
public virtual void OnStopRecording() public virtual void OnStopRecording()
{ {
} }
/// <summary>
/// Call this to start recording
/// </summary>
protected void StartRecording() protected void StartRecording()
{ {
Extensions.Callbacks.StartRecording(); Extensions.Callbacks.StartRecording();
} }
/// <summary>
/// Call this to stop recording
/// </summary>
protected void StopRecording() protected void StopRecording()
{ {
Extensions.Callbacks.StopRecording(); Extensions.Callbacks.StopRecording();
} }
/// <summary>
/// Call this to Enable OneX (interval of 1)
/// </summary>
protected void EnableOneX() protected void EnableOneX()
{ {
Extensions.Callbacks.EnableOneX(); Extensions.Callbacks.EnableOneX();
} }
/// <summary>
/// Call this to Disable OneX (no longer the interval of 1)
/// </summary>
protected void DisableOneX() protected void DisableOneX()
{ {
Extensions.Callbacks.DisableOneX(); Extensions.Callbacks.DisableOneX();
} }
/// <summary>
/// Triggered when timelapse starts onex mode
/// </summary>
public virtual void OnEnableOneX() public virtual void OnEnableOneX()
{ {
} }
/// <summary>
/// Triggered when timelapse exits onex mode
/// </summary>
public virtual void OnDisableOneX() public virtual void OnDisableOneX()
{ {
} }
public virtual async Task<IActionResult> OnHandleRequest(string path)
{
return new NotFoundResult();
}
} }
} }

View File

@ -4,18 +4,40 @@ namespace Timelapse.Api
{ {
public class TimelapseProject public class TimelapseProject
{ {
/// <summary>
/// Estimated Video Length for project
/// </summary>
/// <value>Video Length of project (guess)</value>
public TimeSpan EstimatedVideoLength {get;set;} public TimeSpan EstimatedVideoLength {get;set;}
/// <summary>
/// Estimated length of project (time till complete)
/// </summary>
/// <value>Length of project (guess)</value>
public TimeSpan EstimatedProjectLength {get;set;} public TimeSpan EstimatedProjectLength {get;set;}
/// <summary>
/// Estimated or Interval
/// </summary>
/// <value>Estimated or Raw interval</value>
public bool Estimated {get;set;} public bool Estimated {get;set;}
/// <summary> /// <summary>
/// Only if Estimated is false /// Only if Estimated is false
/// </summary> /// </summary>
public TimeSpan Interval {get;set;} public TimeSpan Interval {get;set;}
/// <summary>
/// Width, Should not be changed after creation
/// </summary>
/// <value>width</value>
public int Width {get;set;} public int Width {get;set;}
/// <summary>
/// Height, Should not be changed after creation
/// </summary>
/// <value>height</value>
public int Height {get;set;} public int Height {get;set;}
// No Camera Needed /// <summary>
/// Section of project
/// </summary>
/// <value>name of section</value>
public string CurrentSection {get;set;} public string CurrentSection {get;set;}
} }

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework> <TargetFramework>net5.0</TargetFramework>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -1,40 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Timelapse.Api;
using System.Text;
using System.Net.Http.Headers;
using System.Net.Http;
using System.IO;
using System.Net;
using System.Text.RegularExpressions;
using System.Drawing;
using System.Runtime.InteropServices;
namespace Timelapse.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class ExtensionController : ControllerBase
{
[HttpGet]
public async Task<IActionResult> GetExtensionPage(string extId,string subPage)
{
return await Extensions.OnGetPage(WebUtility.UrlDecode(extId),WebUtility.UrlDecode(subPage));
}
}
}

View File

@ -15,6 +15,7 @@
@if(RecentFiles == null) @if(RecentFiles == null)
{ {
<p>Loading...</p> <p>Loading...</p>
}else{ }else{
<ul style="list-style-type:none"> <ul style="list-style-type:none">

View File

@ -62,6 +62,7 @@ namespace Timelapse
endpoints.MapFallbackToPage("/_Host"); endpoints.MapFallbackToPage("/_Host");
}); });
Electron.Tray.Show("/Assets/desktop.png"); Electron.Tray.Show("/Assets/desktop.png");
Electron.Menu.SetApplicationMenu(new ElectronNET.API.Entities.MenuItem[]{}); Electron.Menu.SetApplicationMenu(new ElectronNET.API.Entities.MenuItem[]{});
Task.Run(async () =>{ Task.Run(async () =>{

View File

@ -16,7 +16,7 @@
<ProjectReference Include="..\Timelapse.Api\Timelapse.Api.csproj" /> <ProjectReference Include="..\Timelapse.Api\Timelapse.Api.csproj" />
</ItemGroup> </ItemGroup>
<PropertyGroup> <PropertyGroup>
<PublishReadyToRun>false</PublishReadyToRun> <!--<PublishReadyToRun>false</PublishReadyToRun>-->
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<None Update="Assets\Stock-Person.png"> <None Update="Assets\Stock-Person.png">

View File

@ -3,12 +3,12 @@ export ARCHITECTURE=amd64
cd Timelapse cd Timelapse
electronize build /target win /p:PublishReadyToRun=false electronize build /target win /p:PublishReadyToRun=false
electronize build /target osx /p:PublishReadyToRun=false electronize build /target osx /p:PublishReadyToRun=false
electronize build /target linux /p:PublishReadyToRun=false electronize build /target linux
rm -rf ../deb/usr/share/TimelapseNow/bin/ rm -rf ../deb/usr/share/TimelapseNow/bin/
cp -r bin/Desktop/linux-unpacked/ ../deb/usr/share/TimelapseNow/bin/ cp -r bin/Desktop/linux-unpacked/ ../deb/usr/share/TimelapseNow/bin/
echo "Package: timelapsenow" > ../deb/DEBIAN/control echo "Package: timelapsenow" > ../deb/DEBIAN/control
echo "Version: 1.0" >> ../deb/DEBIAN/control echo "Version: 1.0.1" >> ../deb/DEBIAN/control
echo "Architecture: $ARCHITECTURE" >> ../deb/DEBIAN/control echo "Architecture: $ARCHITECTURE" >> ../deb/DEBIAN/control
echo "Maintainer: Michael Nolan <tesses50@tesses.cf>" >> ../deb/DEBIAN/control echo "Maintainer: Michael Nolan <tesses50@tesses.cf>" >> ../deb/DEBIAN/control
echo "Description: Record In Steps" >> ../deb/DEBIAN/control echo "Description: Record In Steps" >> ../deb/DEBIAN/control

View File

@ -1,5 +1,5 @@
Package: timelapsenow Package: timelapsenow
Version: 1.0 Version: 1.0.0
Architecture: amd64 Architecture: amd64
Maintainer: Michael Nolan <tesses50@tesses.cf> Maintainer: Michael Nolan <tesses50@tesses.cf>
Description: Record In Steps Description: Record In Steps