mirror of
https://github.com/revenz/FileFlowsPlugins.git
synced 2025-12-20 10:19:29 -06:00
FF-1354 - added push bullet
This commit is contained in:
@@ -35,6 +35,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SiteScraping", "SiteScrapin
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Pushover", "Pushover\Pushover.csproj", "{1F236585-E866-4048-B89E-294156EB8614}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Pushover", "Pushover\Pushover.csproj", "{1F236585-E866-4048-B89E-294156EB8614}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Pushbullet", "Pushbullet\Pushbullet.csproj", "{EA10FED1-7710-4A40-A45E-209357D40839}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@@ -105,6 +107,10 @@ Global
|
|||||||
{1F236585-E866-4048-B89E-294156EB8614}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{1F236585-E866-4048-B89E-294156EB8614}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{1F236585-E866-4048-B89E-294156EB8614}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{1F236585-E866-4048-B89E-294156EB8614}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{1F236585-E866-4048-B89E-294156EB8614}.Release|Any CPU.Build.0 = Release|Any CPU
|
{1F236585-E866-4048-B89E-294156EB8614}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{EA10FED1-7710-4A40-A45E-209357D40839}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{EA10FED1-7710-4A40-A45E-209357D40839}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{EA10FED1-7710-4A40-A45E-209357D40839}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{EA10FED1-7710-4A40-A45E-209357D40839}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
143
Pushbullet/Communication/Pushbullet.cs
Normal file
143
Pushbullet/Communication/Pushbullet.cs
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
|
namespace FileFlows.Pushbullet.Communication;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A Pushbullet flow element that sends a message
|
||||||
|
/// </summary>
|
||||||
|
public class Pushbullet: Node
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the number of inputs to this flow element
|
||||||
|
/// </summary>
|
||||||
|
public override int Inputs => 1;
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the number of outputs to this flow element
|
||||||
|
/// </summary>
|
||||||
|
public override int Outputs => 2;
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the type of flow element
|
||||||
|
/// </summary>
|
||||||
|
public override FlowElementType Type => FlowElementType.Communication;
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the icon for this flow element
|
||||||
|
/// </summary>
|
||||||
|
public override string Icon => "svg:pushbullet";
|
||||||
|
/// <summary>
|
||||||
|
/// Gets if this can be used in a failure flow
|
||||||
|
/// </summary>
|
||||||
|
public override bool FailureNode => true;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override string CustomColor => "#3b8f52";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the Help URL
|
||||||
|
/// </summary>
|
||||||
|
public override string HelpUrl => "https://fileflows.com/docs/plugins/pushbullet";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the title of the message
|
||||||
|
/// </summary>
|
||||||
|
[TextVariable(1)]
|
||||||
|
[Required]
|
||||||
|
public string Title { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the message
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
[Template(2, nameof(MessageTemplates))]
|
||||||
|
public string Message { get; set; }
|
||||||
|
|
||||||
|
private static List<ListOption> _MessageTemplates;
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a list of message templates
|
||||||
|
/// </summary>
|
||||||
|
public static List<ListOption> MessageTemplates
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_MessageTemplates == null)
|
||||||
|
{
|
||||||
|
_MessageTemplates = new List<ListOption>
|
||||||
|
{
|
||||||
|
new () { Label = "Basic", Value = @"File: {{ file.Orig.FullName }}
|
||||||
|
Size: {{ file.Size }}" },
|
||||||
|
new () { Label = "File Size Changes", Value = @"
|
||||||
|
{{ difference = file.Size - file.Orig.Size }}
|
||||||
|
{{ percent = (difference / file.Orig.Size) * 100 | math.round 2 }}
|
||||||
|
|
||||||
|
Input File: {{ file.Orig.FullName }}
|
||||||
|
Output File: {{ file.FullName }}
|
||||||
|
Original Size: {{ file.Orig.Size | file_size }}
|
||||||
|
Final Size: {{ file.Size | file_size }}
|
||||||
|
|
||||||
|
{{- if difference < 0 }}
|
||||||
|
File grew in size: {{ difference | math.abs | file_size }}
|
||||||
|
{{ else }}
|
||||||
|
File shrunk in size by: {{ difference | file_size }} / {{ percent }}%
|
||||||
|
{{ end }}"}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return _MessageTemplates;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Executes the flow element
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="args">the node parameters</param>
|
||||||
|
/// <returns>the output to call next</returns>
|
||||||
|
public override int Execute(NodeParameters args)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var settings = args.GetPluginSettings<PluginSettings>();
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(settings?.ApiToken))
|
||||||
|
{
|
||||||
|
args.Logger?.WLog("No API Token set");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
string body = args.RenderTemplate!(this.Message);
|
||||||
|
if (string.IsNullOrWhiteSpace(body))
|
||||||
|
{
|
||||||
|
args.Logger?.WLog("No message to send");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
using var httpClient = new HttpClient();
|
||||||
|
|
||||||
|
string title = args.ReplaceVariables(this.Title, stripMissing: true);
|
||||||
|
|
||||||
|
// Set the authorization header with the Access Token
|
||||||
|
httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", settings.ApiToken);
|
||||||
|
|
||||||
|
// Create the request content
|
||||||
|
var content = new StringContent(JsonSerializer.Serialize(
|
||||||
|
new {
|
||||||
|
type = "note",
|
||||||
|
title,
|
||||||
|
body
|
||||||
|
}), Encoding.UTF8, "application/json");
|
||||||
|
|
||||||
|
|
||||||
|
var response = httpClient.PostAsync("https://api.pushbullet.com/v2/pushes", content).Result;
|
||||||
|
|
||||||
|
if (response.IsSuccessStatusCode)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
string error = response.Content.ReadAsStringAsync().Result;
|
||||||
|
args.Logger?.WLog("Error from Pushbullet: " + error);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
args.Logger?.WLog("Error sending message: " + ex.Message);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
14
Pushbullet/ExtensionMethods.cs
Normal file
14
Pushbullet/ExtensionMethods.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
namespace FileFlows.Pushbullet;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Extension methods
|
||||||
|
/// </summary>
|
||||||
|
internal static class ExtensionMethods
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Returns an empty string as null, otherwise returns the original string
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="str">the input string</param>
|
||||||
|
/// <returns>the string or null if empty</returns>
|
||||||
|
public static string? EmptyAsNull(this string str) => str == string.Empty ? null : str;
|
||||||
|
}
|
||||||
5
Pushbullet/GlobalUsings.cs
Normal file
5
Pushbullet/GlobalUsings.cs
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
global using System;
|
||||||
|
global using System.Text;
|
||||||
|
global using System.ComponentModel.DataAnnotations;
|
||||||
|
global using FileFlows.Plugin;
|
||||||
|
global using FileFlows.Plugin.Attributes;
|
||||||
29
Pushbullet/Plugin.cs
Normal file
29
Pushbullet/Plugin.cs
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
namespace FileFlows.Pushbullet;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A Pushbullet Plugin
|
||||||
|
/// </summary>
|
||||||
|
public class Plugin : FileFlows.Plugin.IPlugin
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the UID for this plugin
|
||||||
|
/// </summary>
|
||||||
|
public Guid Uid => new Guid("3016f2b9-41cb-45cf-b4f9-a8d9a30dc385");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the name of this plugin
|
||||||
|
/// </summary>
|
||||||
|
public string Name => "Pushbullet";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the minimum version of FileFlows required for this plugin
|
||||||
|
/// </summary>
|
||||||
|
public string MinimumVersion => "1.0.4.2019";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes this plugin
|
||||||
|
/// </summary>
|
||||||
|
public void Init()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
14
Pushbullet/PluginSettings.cs
Normal file
14
Pushbullet/PluginSettings.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
namespace FileFlows.Pushbullet;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The plugin settings for this plugin
|
||||||
|
/// </summary>
|
||||||
|
public class PluginSettings : IPluginSettings
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the API Token
|
||||||
|
/// </summary>
|
||||||
|
[Text(2)]
|
||||||
|
[Required]
|
||||||
|
public string ApiToken { get; set; }
|
||||||
|
}
|
||||||
41
Pushbullet/Pushbullet.csproj
Normal file
41
Pushbullet/Pushbullet.csproj
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<RootNamespace>FileFlows.$(MSBuildProjectName.Replace(" ", "_"))</RootNamespace>
|
||||||
|
<FileVersion>1.1.1.528</FileVersion>
|
||||||
|
<ProductVersion>1.1.1.528</ProductVersion>
|
||||||
|
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||||
|
<PublishTrimmed>true</PublishTrimmed>
|
||||||
|
<Company>FileFlows</Company>
|
||||||
|
<Authors>John Andrews</Authors>
|
||||||
|
<Product>Pushbullet</Product>
|
||||||
|
<PackageProjectUrl>https://fileflows.com/</PackageProjectUrl>
|
||||||
|
<Description>Lets you send Pushbullet messages to a server</Description>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Remove="Pushbullet.en.json" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="Pushbullet.en.json">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup Condition=" '$(Configuration)' == 'Debug'">
|
||||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.1" />
|
||||||
|
<PackageReference Include="MSTest.TestAdapter" Version="3.0.4" />
|
||||||
|
<PackageReference Include="MSTest.TestFramework" Version="3.0.4" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="FileFlows.Plugin">
|
||||||
|
<HintPath>..\FileFlows.Plugin.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
31
Pushbullet/Pushbullet.en.json
Normal file
31
Pushbullet/Pushbullet.en.json
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"Plugins": {
|
||||||
|
"Pushbullet": {
|
||||||
|
"Description": "A plugin that allows you to send messages to a Pushbullet server.",
|
||||||
|
"Fields": {
|
||||||
|
"UserKey": "User Key",
|
||||||
|
"UserKey-Help":"Your personal user key for receiving notifications.",
|
||||||
|
"ApiToken": "API Token",
|
||||||
|
"ApiToken-Help":"The application API token use for sending notifications."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Flow": {
|
||||||
|
"Parts": {
|
||||||
|
"Pushbullet": {
|
||||||
|
"Outputs": {
|
||||||
|
"1": "Pushbullet message sent",
|
||||||
|
"2": "Pushbullet message failed to send"
|
||||||
|
},
|
||||||
|
"Description": "Sends a message via Pushbullet.",
|
||||||
|
"Fields": {
|
||||||
|
"Title": "Title",
|
||||||
|
"Message": "Message",
|
||||||
|
"Message-Help": "The message to send to the Pushbullet server",
|
||||||
|
"Priority": "Priority",
|
||||||
|
"Priority-Help": "The priority of the message being sent"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
26
Pushbullet/Tests/PushbulletTests.cs
Normal file
26
Pushbullet/Tests/PushbulletTests.cs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#if(DEBUG)
|
||||||
|
|
||||||
|
using FileFlows.Pushbullet.Communication;
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
|
||||||
|
namespace FileFlows.Pushbullet.Tests;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class PushbulletTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void Pushbullet_Basic_Message()
|
||||||
|
{
|
||||||
|
var args = new NodeParameters("test.file", new TestLogger(), false, string.Empty, null);
|
||||||
|
args.GetPluginSettingsJson = (string input) =>
|
||||||
|
{
|
||||||
|
return File.ReadAllText("../../../../../Pushbullet.json");
|
||||||
|
};
|
||||||
|
|
||||||
|
var node = new FileFlows.Pushbullet.Communication.Pushbullet();
|
||||||
|
node.Message = "a message";
|
||||||
|
Assert.AreEqual(1, node.Execute(args));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
59
Pushbullet/Tests/TestLogger.cs
Normal file
59
Pushbullet/Tests/TestLogger.cs
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
#if(DEBUG)
|
||||||
|
|
||||||
|
namespace FileFlows.Pushbullet.Tests;
|
||||||
|
|
||||||
|
using FileFlows.Plugin;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
internal class TestLogger : ILogger
|
||||||
|
{
|
||||||
|
private List<string> Messages = new List<string>();
|
||||||
|
|
||||||
|
public void DLog(params object[] args) => Log("DBUG", args);
|
||||||
|
|
||||||
|
public void ELog(params object[] args) => Log("ERRR", args);
|
||||||
|
|
||||||
|
public void ILog(params object[] args) => Log("INFO", args);
|
||||||
|
|
||||||
|
public void WLog(params object[] args) => Log("WARN", args);
|
||||||
|
private void Log(string type, object[] args)
|
||||||
|
{
|
||||||
|
if (args == null || args.Length == 0)
|
||||||
|
return;
|
||||||
|
string message = type + " -> " +
|
||||||
|
string.Join(", ", args.Select(x =>
|
||||||
|
x == null ? "null" :
|
||||||
|
x.GetType().IsPrimitive || x is string ? x.ToString() :
|
||||||
|
System.Text.Json.JsonSerializer.Serialize(x)));
|
||||||
|
Messages.Add(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Contains(string message)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(message))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
string log = string.Join(Environment.NewLine, Messages);
|
||||||
|
return log.Contains(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return String.Join(Environment.NewLine, this.Messages.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetTail(int length = 50)
|
||||||
|
{
|
||||||
|
if (length <= 0)
|
||||||
|
length = 50;
|
||||||
|
if (Messages.Count <= length)
|
||||||
|
return string.Join(Environment.NewLine, Messages);
|
||||||
|
return string.Join(Environment.NewLine, Messages.TakeLast(length));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -23,7 +23,7 @@ public class Pushover: Node
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the icon for this flow element
|
/// Gets the icon for this flow element
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public override string Icon => "fab fa-product-hunt";
|
public override string Icon => "svg:pushover";
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets if this can be used in a failure flow
|
/// Gets if this can be used in a failure flow
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
Reference in New Issue
Block a user