4using System.Threading.Tasks;
25 private DirectoryInfo dirInfo;
26 private string folderName;
27 private string folderLocalName;
28 private DateTime? created;
29 private DateTime? updated;
35 : this(string.Empty, null, null, null)
50 this.created = Created;
51 this.updated = Updated;
53 if (
string.IsNullOrEmpty(this.folderName))
56 this.folderLocalName =
null;
60 this.dirInfo =
new DirectoryInfo(this.folderName);
61 this.folderLocalName = Path.GetFileName(this.folderName);
68 [Page(7,
"File System", 100)]
69 [Header(8,
"Folder:")]
70 [ToolTip(9,
"Local path to folder.")]
74 get => this.folderLocalName;
77 if (this.folderLocalName != value)
79 if (this.parent is
null)
80 throw new Exception(
"You are not allowed to change the folder name.");
82 string FullPath = Path.Combine(this.parent.folderName, value);
83 if (!FullPath.StartsWith(
this.parent.FolderName, StringComparison.CurrentCultureIgnoreCase))
84 throw new Exception(
"Invalid local folder name.");
86 if (!
string.IsNullOrEmpty(this.folderName))
88 if (Directory.Exists(FullPath) || File.Exists(FullPath))
89 throw new Exception(
"Folder or file already exists.");
91 Directory.Move(this.folderName, FullPath);
94 this.folderLocalName = value;
95 this.folderName = FullPath;
96 this.dirInfo =
new DirectoryInfo(FullPath);
104 [Page(7,
"File System", 100)]
105 [Header(10,
"Full Path:")]
106 [ToolTip(11,
"Full path to folder.")]
128 public string LocalId => this.folderLocalName;
133 public string LogId => this.folderName;
151 if (this.dirInfo is
null || !this.dirInfo.Exists)
154 DirectoryInfo[] Directories = this.dirInfo.GetDirectories();
155 if (Directories.Length > 0)
158 FileInfo[] Files = this.dirInfo.GetFiles();
159 if (Files.Length > 0)
194 public DateTime
LastChanged => File.GetLastWriteTimeUtc(this.folderName);
243 if (this.parent is
null)
244 return Task.FromResult(
false);
249 internal void FolderUpdated()
263 LinkedList<Parameter> Parameters =
new LinkedList<Parameter>();
265 if (this.created is
null)
269 this.created = Directory.GetCreationTimeUtc(this.folderName);
277 if (this.updated is
null)
281 this.updated = Directory.GetLastWriteTimeUtc(this.folderName);
289 if (this.created.HasValue)
292 this.created.Value));
294 if (this.updated.HasValue &&
this.updated.Value >
this.created.Value)
297 this.updated.Value));
310 return Task.FromResult<IEnumerable<Message>>(
null);
335 return Task.FromResult(
true);
338 return Task.FromResult(
false);
340 if (this.parent is
null &&
string.IsNullOrEmpty(this.folderName))
341 this.parent = ParentFolder;
343 return Task.FromResult(
true);
353 return Task.FromResult(
366 if (
string.IsNullOrEmpty(ChildFolder.FolderName))
367 throw new Exception(
"Folder name is empty.");
369 if (!ChildFolder.FolderName.StartsWith(
this.folderName))
370 throw new Exception(
"Invalid parent folder.");
372 if (!Directory.Exists(ChildFolder.FolderName))
373 Directory.CreateDirectory(ChildFolder.FolderName);
377 if (
string.IsNullOrEmpty(ChildFile.FileName))
378 throw new Exception(
"File name is empty.");
380 if (!ChildFile.FileName.StartsWith(
this.folderName))
381 throw new Exception(
"Invalid parent folder.");
383 if (!File.Exists(ChildFile.FileName))
385 FileStream fs = File.Create(ChildFile.FileName);
390 throw new Exception(
"Unable to add child node.");
392 return Task.CompletedTask;
412 if (this.parent is
null)
413 throw new UnauthorizedAccessException(
"Folder is protected against deletion.");
415 if (Directory.Exists(
this.folderName))
416 Directory.Delete(this.folderName,
true);
418 return Task.CompletedTask;
428 return Task.FromResult<IEnumerable<ICommand>>(
new ICommand[]
436 new CreateTextFileCommand(
this,
"text/cssx",
".cssx", 41,
"Create CSSX File...",
"CreateCssxFile",
"6"),
438 new CreateTextFileCommand(
this,
"application/x-webscript",
".ws", 39,
"Create Webscript File...",
"CreateWsFile",
"8")
449 List<ControlParameter> Parameters =
new List<ControlParameter>();
450 DirectoryInfo Info =
new DirectoryInfo(this.FolderName);
451 FileAttributes Attributes = Info.Attributes;
459 GetReadOnly, SetReadOnly));
464 GetHidden, SetHidden));
469 GetSystem, SetSystem));
474 GetArchive, SetArchive));
476 return Parameters.ToArray();
481 return GetAttribute(Node, FileAttributes.ReadOnly);
486 return SetAttribute(Node, Value, FileAttributes.ReadOnly);
491 return GetAttribute(Node, FileAttributes.Hidden);
496 return SetAttribute(Node, Value, FileAttributes.Hidden);
501 return GetAttribute(Node, FileAttributes.System);
506 return SetAttribute(Node, Value, FileAttributes.System);
511 return GetAttribute(Node, FileAttributes.Archive);
516 return SetAttribute(Node, Value, FileAttributes.Archive);
519 private static Task<bool?> GetAttribute(
IThingReference Node, FileAttributes Attribute)
522 return Task.FromResult<
bool?>(
null);
524 FileAttributes Attr = FolderNode.dirInfo.Attributes;
526 return Task.FromResult<
bool?>(Attr.HasFlag(Attribute));
529 private static Task SetAttribute(
IThingReference Node,
bool Value, FileAttributes Attribute)
532 throw new ArgumentException(
"Unexpected node type.", nameof(Node));
534 FileAttributes Attr = FolderNode.dirInfo.Attributes;
535 FileAttributes Bak = Attr;
543 FolderNode.dirInfo.Attributes = Attr;
545 return Task.CompletedTask;
const string DefaultContentType
Content-Type for CSS files.
const string DefaultContentType
Default Content-Type for HTML: text/html
JavaScript encoder/decoder.
const string DefaultContentType
application/javascript
const string ContentType
Markdown content type.
Plain text encoder/decoder.
const string DefaultContentType
text/plain
const string DefaultContentType
Default content type for XML documents.
Contains information about a language.
Task< string > GetStringAsync(Type Type, int Id, string Default)
Gets the string value of a string ID. If no such string exists, a string is created with the default ...
async Task< Namespace > GetNamespaceAsync(string Name)
Gets the namespace object, given its name, if available.
Contains information about a namespace in a language.
Task< LanguageString > GetStringAsync(int Id)
Gets the string object, given its ID, if available.
Basic access point for runtime language localization.
static async Task< Language > GetDefaultLanguageAsync()
Gets the default language.
Creates a subfolder in a folder.
Creates a text file in a folder.
Reference to a file in the ProgramData folder of the broker.
Reference to a folder in the ProgramData folder of the broker.
Task< bool > RemoveAsync(INode Child)
Removes a child from the node.
bool HasChildren
If the source has any child sources.
bool ChildrenOrdered
If the children of the node have an intrinsic order (true), or if the order is not important (false).
string FolderLocalName
Local folder name
Task DestroyAsync()
Destroys the node. If it is a child to a parent node, it is removed from the parent first.
NodeState State
Current overall state of the node.
ProgramDataFolder()
Reference to a folder in the ProgramData folder of the broker.
ProgramDataFolder(string FolderName, ProgramDataFolder Parent, DateTime? Created, DateTime? Updated)
Reference to a folder in the ProgramData folder of the broker.
Task< string > GetTypeNameAsync(Language Language)
Gets the type name of the node.
string LogId
If provided, an ID for the node, as it would appear or be used in system logs. Can be null,...
string LocalId
If provided, an ID for the node, but unique locally between siblings. Can be null,...
async Task< IEnumerable< Parameter > > GetDisplayableParametersAsync(Language Language, RequestOrigin Caller)
Gets displayable parameters.
bool HasCommands
If the node has registered commands or not.
async Task< ControlParameter[]> GetControlParameters()
Get control parameters for the actuator.
Task< bool > CanAddAsync(RequestOrigin Caller)
If the node can be added to by the caller.
Task< bool > CanViewAsync(RequestOrigin Caller)
If the node is visible to the caller.
string SourceId
Optional ID of source containing node.
DateTime LastChanged
When the node was last updated.
Task AddAsync(INode Child)
Adds a new child to the node.
Task< bool > CanEditAsync(RequestOrigin Caller)
If the node can be edited by the caller.
Task< bool > MoveDownAsync(RequestOrigin Caller)
Tries to move the node down.
Task UpdateAsync()
Updates the node (in persisted storage).
Task< IEnumerable< Message > > GetMessagesAsync(RequestOrigin Caller)
Gets messages logged on the node.
string FolderName
Full Folder name.
string Partition
Optional partition in which the Node ID is unique.
Task< bool > AcceptsChildAsync(INode Child)
If the node accepts a presumptive child, i.e. can receive as a child (if that child accepts the node ...
Task< IEnumerable< INode > > ChildNodes
Child nodes. If no child nodes are available, null is returned.
Task< bool > AcceptsParentAsync(INode Parent)
If the node accepts a presumptive parent, i.e. can be added to that parent (if that parent accepts th...
Task< bool > MoveUpAsync(RequestOrigin Caller)
Tries to move the node up.
Task< IEnumerable< ICommand > > Commands
Available command objects. If no commands are available, null is returned.
Task< bool > CanDestroyAsync(RequestOrigin Caller)
If the node can be destroyed to by the caller.
bool IsReadable
If the node can be read.
INode Parent
Parent Node, or null if a root node.
bool IsControllable
If the node can be controlled.
Data source mirroring the ProgramData folder for the broker.
static IEnumerable< INode > GetChildNodes(ProgramDataFolder FolderNode, string FolderPath)
Gets a set of program data child nodes, for a folder.
const string SourceID
Data Source ID for the ProgramData source.
Boolean control parameter.
DateTime-valued parameter.
Tokens available in request.
bool HasPrivilege(string Privilege)
If the origin has a given privilege.
Interface for actuator nodes.
Interface for nodes that are published through the concentrator interface.
Interface for thing references.
NodeState
State of a node.