├── PrintNodeRequestOptions.cs ├── PrintNodeContentType.cs ├── PrintNodeAuthenticationType.cs ├── PrintNodeDelegatedClientContextAuthenticationMode.cs ├── PrintNodeConfiguration.cs ├── PrintNodeCredentials.cs ├── PrintNodePrintJobAuthentication.cs ├── PrintNodeScaleMeasurement.cs ├── PrintNodeChildAccountCreationResponseConverter.cs ├── PrintNodeException.cs ├── PrintNodeDelegatedClientContext.cs ├── LICENSE ├── printnode-net.csproj ├── PrintNodePrinterCapabilities.cs ├── Util └── SetBuilder.cs ├── PrintNodePrintJobState.cs ├── PrintNodePrinter.cs ├── README.md ├── PrintNodeChildAccount.cs ├── PrintNodePrintJobOptions.cs ├── .gitignore ├── Http └── PrintNodeApiHelper.cs ├── PrintNodeComputer.cs ├── PrintNodeScale.cs └── PrintNodePrintJob.cs /PrintNodeRequestOptions.cs: -------------------------------------------------------------------------------- 1 | namespace PrintNodeNet 2 | { 3 | public class PrintNodeRequestOptions 4 | { 5 | public string ApiKey { get; set; } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /PrintNodeContentType.cs: -------------------------------------------------------------------------------- 1 | namespace PrintNodeNet 2 | { 3 | public enum PrintNodeContentType 4 | { 5 | pdf_uri, 6 | pdf_base64, 7 | raw_uri, 8 | raw_base64 9 | } 10 | } -------------------------------------------------------------------------------- /PrintNodeAuthenticationType.cs: -------------------------------------------------------------------------------- 1 | namespace PrintNodeNet 2 | { 3 | public enum PrintNodeAuthenticationType 4 | { 5 | BasicAuth, 6 | DigestAuth 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /PrintNodeDelegatedClientContextAuthenticationMode.cs: -------------------------------------------------------------------------------- 1 | namespace PrintNodeNet 2 | { 3 | internal enum PrintNodeDelegatedClientContextAuthenticationMode 4 | { 5 | Id, 6 | Email, 7 | CreatorRef 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /PrintNodeConfiguration.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace PrintNodeNet 4 | { 5 | public static class PrintNodeConfiguration 6 | { 7 | public static Uri BaseAddress { get; set; } = new Uri("https://api.printnode.com"); 8 | public static string ApiKey { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /PrintNodeCredentials.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace PrintNodeNet 4 | { 5 | public class PrintNodeCredentials 6 | { 7 | [JsonProperty("user")] 8 | public string User { get; set; } 9 | 10 | [JsonProperty("pass")] 11 | public string Pass { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /PrintNodePrintJobAuthentication.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using PrintNodeNet; 3 | 4 | namespace PrintNodeNet 5 | { 6 | public class PrintNodePrintJobAuthentication 7 | { 8 | [JsonProperty("type")] 9 | public string Type { get; set; } 10 | 11 | [JsonProperty("credentials")] 12 | public PrintNodeCredentials Credentials { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /PrintNodeScaleMeasurement.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace PrintNodeNet 4 | { 5 | public class PrintNodeScaleMeasurement 6 | { 7 | /// 8 | /// The measurement in kilos 9 | /// 10 | [JsonProperty("kg")] 11 | public long Kg { get; set; } 12 | 13 | /// 14 | /// The measurement in grams 15 | /// 16 | [JsonProperty("g")] 17 | public long G { get; set; } 18 | 19 | /// 20 | /// The measurement in pounds 21 | /// 22 | [JsonProperty("lb")] 23 | public long Lb { get; set; } 24 | 25 | /// 26 | /// The measurement in ounces 27 | /// 28 | [JsonProperty("oz")] 29 | public long Oz { get; set; } 30 | } 31 | } -------------------------------------------------------------------------------- /PrintNodeChildAccountCreationResponseConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Newtonsoft.Json; 3 | using Newtonsoft.Json.Linq; 4 | 5 | namespace PrintNodeNet 6 | { 7 | internal sealed class PrintNodeChildAccountCreationResponseConverter : JsonConverter 8 | { 9 | public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 10 | { 11 | throw new NotImplementedException(); 12 | } 13 | 14 | public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 15 | { 16 | var jObject = JObject.Load(reader); 17 | 18 | var childAccount = new PrintNodeChildAccount(); 19 | 20 | serializer.Populate(jObject["Account"].CreateReader(), childAccount); 21 | 22 | return childAccount; 23 | } 24 | 25 | public override bool CanConvert(Type objectType) 26 | { 27 | return (objectType == typeof (PrintNodeChildAccount)); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /PrintNodeException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | using System.Net.Http; 4 | using System.Threading.Tasks; 5 | using Newtonsoft.Json; 6 | 7 | namespace PrintNodeNet 8 | { 9 | public class PrintNodeException : Exception 10 | { 11 | public HttpStatusCode StatusCode { get; private set; } 12 | 13 | public PrintNodeException(HttpResponseMessage response) : base(GetErrorContent(response)) 14 | { 15 | StatusCode = response.StatusCode; 16 | } 17 | 18 | private static string GetErrorContent(HttpResponseMessage response) 19 | { 20 | var message = Task.Run(() => response.Content.ReadAsStringAsync()).Result; 21 | var content = JsonConvert.DeserializeObject(message); 22 | 23 | return content.Message; 24 | } 25 | } 26 | 27 | internal class PrintNodeErrorMessage 28 | { 29 | [JsonProperty(PropertyName = "message")] 30 | public string Message { get; set; } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /PrintNodeDelegatedClientContext.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace PrintNodeNet 4 | { 5 | public class PrintNodeDelegatedClientContext : IDisposable 6 | { 7 | public static PrintNodeDelegatedClientContext Current { get; private set; } 8 | 9 | internal PrintNodeDelegatedClientContextAuthenticationMode AuthenticationMode; 10 | 11 | internal string AuthenticationValue { get; private set; } 12 | 13 | public PrintNodeDelegatedClientContext(int accountId) 14 | { 15 | AuthenticationValue = accountId.ToString(); 16 | AuthenticationMode = PrintNodeDelegatedClientContextAuthenticationMode.Id; 17 | Current = this; 18 | } 19 | 20 | public PrintNodeDelegatedClientContext(string email) 21 | { 22 | AuthenticationValue = email; 23 | AuthenticationMode = PrintNodeDelegatedClientContextAuthenticationMode.Email; 24 | Current = this; 25 | } 26 | 27 | public void Dispose() 28 | { 29 | Current = null; 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Christian Zachariasen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /printnode-net.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0;net462 5 | PrintNodeNet 6 | PrintNodeNet 7 | true 8 | PrintNode.Net 9 | Christian Zachariasen 10 | io7 Software A/S 11 | PrintNode.Net 12 | A C# library for communicating with the PrintNode API 13 | io7 Software 2016-2021 14 | MIT 15 | https://github.com/christianz/printnode-net 16 | Git 17 | 1.1.2.0 18 | 1.1.2.0 19 | 1.1.5 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /PrintNodePrinterCapabilities.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Newtonsoft.Json; 3 | 4 | namespace PrintNodeNet 5 | { 6 | public class PrintNodePrinterCapabilities 7 | { 8 | [JsonProperty("bins")] 9 | public IEnumerable Bins { get; set; } 10 | 11 | [JsonProperty("collate")] 12 | public bool Collate { get; set; } 13 | 14 | [JsonProperty("copies")] 15 | public int Copies { get; set; } 16 | 17 | [JsonProperty("color")] 18 | public bool Color { get; set; } 19 | 20 | [JsonProperty("dpis")] 21 | public IEnumerable Dpis { get; set; } 22 | 23 | [JsonProperty("extent")] 24 | public int[][] Extent { get; set; } 25 | 26 | [JsonProperty("medias")] 27 | public IEnumerable Medias { get; set; } 28 | 29 | [JsonProperty("nup")] 30 | public IEnumerable Nup { get; set; } 31 | 32 | [JsonProperty("papers")] 33 | public Dictionary Papers { get; set; } 34 | 35 | [JsonProperty("printRate")] 36 | public Dictionary PrintRate { get; set; } 37 | 38 | [JsonProperty("supports_custom_paper_size")] 39 | public bool SupportsCustomPaperSize { get; set; } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Util/SetBuilder.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Text; 3 | 4 | namespace PrintNodeNet.Util 5 | { 6 | /// 7 | /// The SetBuilder class is a tool that helps mutualising the code for generating sets of any 8 | /// kind. 9 | /// To get the set as a string, use the Build method. 10 | /// 11 | public class SetBuilder 12 | { 13 | private StringBuilder Set; 14 | public int Size { get; private set; } 15 | 16 | /// 17 | /// This parameterless constructor simply instanciates a new StringBuilder and sets the 18 | /// Size to 0. Use the Add method to then add content to the set. 19 | /// 20 | public SetBuilder() 21 | { 22 | Set = new StringBuilder(); 23 | Size = 0; 24 | } 25 | 26 | /// 27 | /// This constructor creates a new instance of SetBuilder with an Enumerable of longs as 28 | /// template. 29 | /// 30 | /// The set of ids to add to the new SetBuilder 31 | public SetBuilder(IEnumerable set) 32 | { 33 | Size = 0; 34 | Set = new StringBuilder(); 35 | foreach (long item in set) 36 | { 37 | Set.Append(item); 38 | Set.Append(','); 39 | Size++; 40 | } 41 | } 42 | 43 | /// 44 | /// This method allows the addition of extra elements to the set if needed. 45 | /// 46 | /// The set of ids to add to the new SetBuilder 47 | public void Add(IEnumerable set) 48 | { 49 | foreach (long item in set) 50 | { 51 | Set.Append(item); 52 | Set.Append(','); 53 | Size++; 54 | } 55 | } 56 | 57 | /// 58 | /// The Build method returns the string built from the StringBuilder that has been edited 59 | /// throughout the SetBuilder lifetime. 60 | /// 61 | /// The set as a string, ready for querying the PrintNode API. 62 | public string Build() 63 | { 64 | if (Size > 0) 65 | { 66 | //We remove the last comma from the set 67 | Set.Remove(Set.Length -1, 1); 68 | } 69 | 70 | return Set.ToString(); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /PrintNodePrintJobState.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading.Tasks; 4 | using Newtonsoft.Json; 5 | using PrintNodeNet.Http; 6 | 7 | namespace PrintNodeNet 8 | { 9 | public sealed class PrintNodePrintJobState 10 | { 11 | /// 12 | /// The id of the PrintJob this state relates to. 13 | /// 14 | [JsonProperty("printJobId")] 15 | public long PrintJobId { get; set; } 16 | 17 | /// 18 | /// The PrintJob string. The allowed states are pending_confirmation, new, sent_to_client, deleted, 19 | /// done, error, in_progress, queued, disappeared, received, downloading, downloaded, 20 | /// preparing_to_print, queued_to_print and expired. 21 | /// 22 | [JsonProperty("state")] 23 | public string State { get; set; } 24 | 25 | /// 26 | /// Additional human readable information about the state. If a error has occoured this where to look 27 | /// to diagnose the problem. 28 | /// 29 | [JsonProperty("message")] 30 | public string Message { get; set; } 31 | 32 | /// 33 | /// A machine readable representation of the information contained in the property 'message'. Implmented 34 | /// shortly. Currently this is null. 35 | /// 36 | [JsonProperty("data")] 37 | public object Data { get; set; } 38 | 39 | /// 40 | /// The version of the client which reported this state. This will be null null if the state did 41 | /// not originate from the client. 42 | /// 43 | [JsonProperty("clientVersion")] 44 | public string ClientVersion { get; set; } 45 | 46 | /// 47 | /// The UTC date this state was reported to the server. 48 | /// 49 | [JsonProperty("createTimestamp")] 50 | public DateTime CreateTimeStamp { get; set; } 51 | 52 | /// 53 | /// The age of this state relative to the first state in milliseconds. 54 | /// 55 | [JsonProperty("age")] 56 | public int Age { get; set; } 57 | 58 | public static async Task>> ListAsync(PrintNodeRequestOptions options = null) 59 | { 60 | var response = await PrintNodeApiHelper.Get("/printjobs/states", options); 61 | 62 | return JsonConvert.DeserializeObject>>(response); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /PrintNodePrinter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Newtonsoft.Json; 6 | using PrintNodeNet.Http; 7 | using PrintNodeNet.Util; 8 | 9 | namespace PrintNodeNet 10 | { 11 | public sealed class PrintNodePrinter 12 | { 13 | [JsonProperty("id")] 14 | public long Id { get; set; } 15 | 16 | [JsonProperty("computer")] 17 | public PrintNodeComputer Computer { get; set; } 18 | 19 | [JsonProperty("name")] 20 | public string Name { get; set; } 21 | 22 | [JsonProperty("description")] 23 | public string Description { get; set; } 24 | 25 | [JsonProperty("capabilities")] 26 | public PrintNodePrinterCapabilities Capabilities { get; set; } 27 | 28 | [JsonProperty("default")] 29 | public string Default { get; set; } 30 | 31 | [JsonProperty("createTimeStamp")] 32 | public DateTime CreateTimeStamp { get; set; } 33 | 34 | [JsonProperty("state")] 35 | public string State { get; set; } 36 | 37 | public static async Task> ListAsync(PrintNodeRequestOptions options = null) 38 | { 39 | var response = await PrintNodeApiHelper.Get("/printers", options); 40 | 41 | return JsonConvert.DeserializeObject>(response); 42 | } 43 | 44 | public static async Task GetAsync(long id, PrintNodeRequestOptions options = null) 45 | { 46 | var response = await PrintNodeApiHelper.Get($"/printers/{id}", options); 47 | 48 | var list = JsonConvert.DeserializeObject>(response); 49 | 50 | return list.FirstOrDefault(); 51 | } 52 | 53 | /// 54 | /// Static method to retrieve a set of printers from the PrintNode API. 55 | /// 56 | /// The list of ids of the printers. 57 | /// The request options (allows API key modification). 58 | /// The list of matching to the given ids. 59 | public static async Task> GetSetAsync(IEnumerable printerSet, PrintNodeRequestOptions options = null) 60 | { 61 | string ids = new SetBuilder(printerSet).Build(); 62 | 63 | var response = await PrintNodeApiHelper.Get($"/printers/{ids}", options); 64 | 65 | return JsonConvert.DeserializeObject>(response); 66 | } 67 | 68 | public async Task AddPrintJob(PrintNodePrintJob job, PrintNodeRequestOptions options = null) 69 | { 70 | job.PrinterId = Id; 71 | 72 | var response = await PrintNodeApiHelper.Post("/printjobs", job, options); 73 | 74 | return JsonConvert.DeserializeObject(response); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # printnode-net 2 | A C# library for communicating with the PrintNode API 3 | 4 | ## Getting started 5 | Let's set up your account first. 6 | 7 | Create an API key at printnode.com. 8 | 9 | Install your PrintNode client to the computer of your choice. 10 | 11 | Open the PrintNode client and get the printer ID. Now let's "Hello, world!": 12 | 13 | ```csharp 14 | // Your PrintNode API key is stored in apiKey 15 | // Your PrintNode printer id is stored in printerId 16 | // Your awesome test PDF is stored as a byte[] in pdfDocumentBytes 17 | 18 | PrintNodeConfiguration.ApiKey = apiKey; 19 | var printer = await PrintNodePrinter.GetAsync(printerId); 20 | var printJob = new PrintNodePrintJob 21 | { 22 | Title = "Hello, world!", 23 | Content = Convert.ToBase64String(pdfDocumentBytes), 24 | ContentType = "pdf_base64" 25 | }; 26 | 27 | await printer.AddPrintJob(printJob); 28 | ``` 29 | 30 | ## The API base address can be changed if necessary 31 | #### The default is https://api.printnode.com 32 | ```csharp 33 | PrintNodeConfiguration.BaseAddress = new Uri("https://companyname-api.printnode.com"); 34 | ``` 35 | 36 | ## You can set up several computers each with their own PrintNode client, and register them to the same PrintNode account. 37 | 38 | ```csharp 39 | var computers = await PrintNodeComputer.ListAsync(); 40 | ``` 41 | 42 | ```json 43 | [ 44 | { 45 | "id": 11, 46 | "name": "AnalyticalEngine", 47 | "inet": null, 48 | "inet6": null, 49 | "hostname": null, 50 | "version": null, 51 | "jre": null, 52 | "createTimestamp": "2015-06-28T18:29:19.871Z", 53 | "state": "disconnected" 54 | } 55 | ] 56 | ``` 57 | 58 | ## To get a specific computer 59 | ```csharp 60 | var computerId = 12777; 61 | var computer = await PrintNodeComputer.GetAsync(computerId); 62 | ``` 63 | 64 | ## To get a list of printers connected to your current account 65 | ```csharp 66 | var printers = await PrintNodePrinter.ListAsync(); 67 | ``` 68 | 69 | ## To get a specific printer 70 | ```csharp 71 | var printerId = 38409; 72 | var printer = await PrintNodePrinter.GetAsync(printerId); 73 | ``` 74 | 75 | ## To add a job to a printer 76 | ```csharp 77 | byte[] pdfDocument = await DownloadPdf("http://test.com/test.pdf"); 78 | 79 | var printJob = new PrintNodePrintJob 80 | { 81 | Title = "My cool test print", 82 | Content = Convert.ToBase64String(pdfDocument), 83 | ContentType = "pdf_base64" 84 | }; 85 | 86 | var response = await printer.AddPrintJob(printJob); 87 | ``` 88 | 89 | ## To list print jobs for a printer 90 | ```csharp 91 | var printerId = 38409; 92 | var printJobs = await PrintNodePrintJob.ListForPrinterAsync(printerId); 93 | ``` 94 | 95 | ## To create a child account 96 | ```csharp 97 | var childAccount = new PrintNodeChildAccount 98 | { 99 | FirstName = "First name", 100 | LastName = "Last name", 101 | Email = "email@test.com", 102 | Password = "password", 103 | CreatorRef = "a cool ref" 104 | }; 105 | 106 | var response = await childAccount.CreateAsync(); 107 | 108 | var accountId = response.Id.Value; 109 | ``` 110 | 111 | ## To get a list of printers on behalf of a child account 112 | ```csharp 113 | using (new PrintNodeDelegatedClientContext(accountId)) 114 | { 115 | var printers = PrintNodePrinter.ListAsync(); 116 | } 117 | ``` 118 | 119 | ## To list scales for a specific computer 120 | ```csharp 121 | var computerId = 12777; 122 | var scales = await PrintNodeScale.ListForComputerAsync(computerId); 123 | ``` 124 | 125 | ## To list scales for a specific computer and scale name 126 | ```csharp 127 | var computerId = 12777; 128 | var deviceName = "Fairbanks Scales - Fairbanks Scales SCB-R9000"; 129 | var scales = await PrintNodeScale.ListForComputerDeviceAsync(computerId, deviceName); 130 | ``` 131 | 132 | ## To get a specific scale 133 | ```csharp 134 | var computerId = 12777; 135 | var deviceName = "Fairbanks Scales - Fairbanks Scales SCB-R9000"; 136 | var deviceNum = 0; 137 | var scale = await PrintNodeScale.GetAsync(computerId, deviceName, deviceNum); 138 | 139 | var massInMicrograms = scale.Mass[0]; 140 | ``` -------------------------------------------------------------------------------- /PrintNodeChildAccount.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading.Tasks; 3 | using Newtonsoft.Json; 4 | using PrintNodeNet.Http; 5 | 6 | namespace PrintNodeNet 7 | { 8 | public sealed class PrintNodeChildAccount 9 | { 10 | /// 11 | /// Assigned by API. Any value submitted here will be ignored. 12 | /// 13 | [JsonProperty("id")] 14 | public long? Id { get; set; } 15 | 16 | /// 17 | /// The child account user's first name 18 | /// 19 | [JsonProperty("firstname")] 20 | public string FirstName { get; set; } 21 | 22 | /// 23 | /// The child account user's last name 24 | /// 25 | [JsonProperty("lastname")] 26 | public string LastName { get; set; } 27 | 28 | /// 29 | /// A valid email address. This must be unique and would normally be the email address of your customer. 30 | /// This email is for actions like account password resets, informing customers of new versions of the 31 | /// client, etc. Your email will never be shared with any third party or used for marketing purposes. 32 | /// 33 | [JsonProperty("email")] 34 | public string Email { get; set; } 35 | 36 | /// 37 | /// The password should be plain text. It will be encoded in the PrintNode database and cannot be 38 | /// retrieved, only reset. 39 | /// 40 | [JsonProperty("password")] 41 | public string Password { get; set; } 42 | 43 | /// 44 | /// OPTIONAL 45 | /// 46 | /// A unique reference which you can use as a method to identify an account. 47 | /// 48 | [JsonProperty("creatorRef")] 49 | public string CreatorRef { get; set; } 50 | 51 | /// 52 | /// OPTIONAL 53 | /// 54 | /// A array of named API Keys you wish to create for this account. 55 | /// 56 | [JsonProperty("ApiKeys")] 57 | public string[] ApiKeys { get; set; } 58 | 59 | /// 60 | /// OPTIONAL 61 | /// 62 | /// A array of tag names and values to be associated with an account. 63 | /// 64 | [JsonProperty("Tags")] 65 | public Dictionary Tags { get; set; } 66 | 67 | public async Task CreateAsync(PrintNodeRequestOptions options = null) 68 | { 69 | var response = await PrintNodeApiHelper.Post("/account", new 70 | { 71 | Account = this, 72 | ApiKeys, 73 | Tags 74 | }, options); 75 | 76 | return JsonConvert.DeserializeObject(response, new PrintNodeChildAccountCreationResponseConverter()); 77 | } 78 | 79 | public static async Task GetKeyAsync(string clientId, PrintNodeRequestOptions options = null) 80 | { 81 | var response = await PrintNodeApiHelper.Get($"/client/key/{clientId}?version=4.7.1&edition=printnode", options); 82 | 83 | return JsonConvert.DeserializeObject(response); 84 | } 85 | 86 | public static async Task Exists(PrintNodeRequestOptions options = null) 87 | { 88 | try 89 | { 90 | var response = await PrintNodeApiHelper.Get("/whoami", options); 91 | 92 | return !string.IsNullOrEmpty(response); 93 | } 94 | catch 95 | { 96 | return false; 97 | } 98 | } 99 | 100 | public async Task UpdateAsync(PrintNodeRequestOptions options = null) 101 | { 102 | var response = await PrintNodeApiHelper.Patch("/account", this, options, new Dictionary 103 | { 104 | { "X-Child-Account-By-Id", Id.ToString() } 105 | }); 106 | 107 | return JsonConvert.DeserializeObject(response); 108 | } 109 | 110 | public static async Task DeleteAsync(long id, PrintNodeRequestOptions options = null) 111 | { 112 | var response = await PrintNodeApiHelper.Delete("/account", options, new Dictionary 113 | { 114 | { "X-Child-Account-By-Id", id.ToString() } 115 | }); 116 | 117 | return JsonConvert.DeserializeObject(response); 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /PrintNodePrintJobOptions.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace PrintNodeNet 4 | { 5 | public class PrintNodePrintJobOptions 6 | { 7 | /// 8 | /// The name of one of the paper trays or output bins reported by the printer capability property "bins". 9 | /// 10 | /// See Printer capabilities. 11 | /// 12 | [JsonProperty("bin")] 13 | public string Bin { get; set; } 14 | 15 | /// 16 | /// Enables print copy collation when printing multiple copies. If this option is not specified the printer default is used. 17 | /// 18 | [JsonProperty("collate")] 19 | public bool Collate { get; set; } 20 | 21 | /// 22 | /// Positive integer. Default 1. The number of copies to be printed. Maximum value as reported by the printer capability 23 | /// property "copies". 24 | /// 25 | /// See Printer capabilities. 26 | /// 27 | [JsonProperty("copies")] 28 | public int Copies { get; set; } = 1; 29 | 30 | /// 31 | /// The dpi setting to use for this PrintJob. Allowed values are those reported by the printer capability property "dpis". 32 | /// 33 | /// See Printer capabilities. 34 | /// 35 | [JsonProperty("dpi")] 36 | public string Dpi { get; set; } 37 | 38 | /// 39 | /// One of long-edge or short-edge for 2 sides printing along the long-edge (portrait) or the short edge (landscape) respectively. 40 | /// If this option is not specified the the printer default is used. 41 | /// 42 | [JsonProperty("duplex")] 43 | public string Duplex { get; set; } 44 | 45 | /// 46 | /// OSX only. Defaults true. If you wish to disable this option pass false here. 47 | /// 48 | [JsonProperty("fit_to_page")] 49 | public bool FitToPage { get; set; } 50 | 51 | /// 52 | /// The named media to use for this PrintJob. Allowed values are one of the values reported by the printer capability property "medias". 53 | /// We've found some printers on OSX ignore this setting unless a "bin" (paper tray) option is also set. 54 | /// 55 | /// See Printer capabilities. 56 | /// 57 | [JsonProperty("media")] 58 | public string Media { get; set; } 59 | 60 | /// 61 | /// OSX only. Allows support for printing muliple pages per physical sheet of paper. Default 1. Allowed values are those reported 62 | /// by the printer capability property "nup". 63 | /// 64 | /// See Printer capabilities. 65 | /// 66 | [JsonProperty("nup")] 67 | public int Nup { get; set; } = 1; 68 | 69 | /// 70 | /// A set of pages to print from a PDF. The format is described here. A few quick exampleE.g. 1,3 prints pages 1 and 3. -5 prints 71 | /// pages 1 through 5 inclusive. - prints all pages. Different components can be combined with a comma. 1,3- prints all pages except page 2. 72 | /// 73 | /// See Parameters. 74 | /// 75 | [JsonProperty("pages")] 76 | public string Pages { get; set; } = "-"; 77 | 78 | /// 79 | /// A named paper size to use. Allowed values are the keys in the object returned by the printer capability property "papers". 80 | /// 81 | /// See Printer capabilities. 82 | /// 83 | [JsonProperty("paper")] 84 | public string Paper { get; set; } 85 | 86 | /// 87 | /// One of 90, 180 or 270. Supports rotating all pages while printing. We've found support on OSX to be patchy. Support depends on both printer and driver. 88 | /// 89 | [JsonProperty("rotate")] 90 | public int Rotate { get; set; } 91 | 92 | 93 | /// 94 | /// Print in color or black and white. Ignored by Print Engine 4. 95 | /// 96 | [JsonProperty("color")] 97 | public bool Color { get; set; } = true; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # Don't include solution 5 | *.sln 6 | 7 | # User-specific files 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Build results 17 | [Dd]ebug/ 18 | [Dd]ebugPublic/ 19 | [Rr]elease/ 20 | [Rr]eleases/ 21 | x64/ 22 | x86/ 23 | bld/ 24 | [Bb]in/ 25 | [Oo]bj/ 26 | 27 | # Visual Studio 2015 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # MSTest test Results 33 | [Tt]est[Rr]esult*/ 34 | [Bb]uild[Ll]og.* 35 | 36 | # NUNIT 37 | *.VisualState.xml 38 | TestResult.xml 39 | 40 | # Build Results of an ATL Project 41 | [Dd]ebugPS/ 42 | [Rr]eleasePS/ 43 | dlldata.c 44 | 45 | # DNX 46 | project.lock.json 47 | artifacts/ 48 | 49 | *_i.c 50 | *_p.c 51 | *_i.h 52 | *.ilk 53 | *.meta 54 | *.obj 55 | *.pch 56 | *.pdb 57 | *.pgc 58 | *.pgd 59 | *.rsp 60 | *.sbr 61 | *.tlb 62 | *.tli 63 | *.tlh 64 | *.tmp 65 | *.tmp_proj 66 | *.log 67 | *.vspscc 68 | *.vssscc 69 | .builds 70 | *.pidb 71 | *.svclog 72 | *.scc 73 | 74 | # Chutzpah Test files 75 | _Chutzpah* 76 | 77 | # Visual C++ cache files 78 | ipch/ 79 | *.aps 80 | *.ncb 81 | *.opendb 82 | *.opensdf 83 | *.sdf 84 | *.cachefile 85 | 86 | # Visual Studio profiler 87 | *.psess 88 | *.vsp 89 | *.vspx 90 | *.sap 91 | 92 | # TFS 2012 Local Workspace 93 | $tf/ 94 | 95 | # Guidance Automation Toolkit 96 | *.gpState 97 | 98 | # ReSharper is a .NET coding add-in 99 | _ReSharper*/ 100 | *.[Rr]e[Ss]harper 101 | *.DotSettings.user 102 | 103 | # JustCode is a .NET coding add-in 104 | .JustCode 105 | 106 | # TeamCity is a build add-in 107 | _TeamCity* 108 | 109 | # DotCover is a Code Coverage Tool 110 | *.dotCover 111 | 112 | # NCrunch 113 | _NCrunch_* 114 | .*crunch*.local.xml 115 | nCrunchTemp_* 116 | 117 | # MightyMoose 118 | *.mm.* 119 | AutoTest.Net/ 120 | 121 | # Web workbench (sass) 122 | .sass-cache/ 123 | 124 | # Installshield output folder 125 | [Ee]xpress/ 126 | 127 | # DocProject is a documentation generator add-in 128 | DocProject/buildhelp/ 129 | DocProject/Help/*.HxT 130 | DocProject/Help/*.HxC 131 | DocProject/Help/*.hhc 132 | DocProject/Help/*.hhk 133 | DocProject/Help/*.hhp 134 | DocProject/Help/Html2 135 | DocProject/Help/html 136 | 137 | # Click-Once directory 138 | publish/ 139 | 140 | # Publish Web Output 141 | *.[Pp]ublish.xml 142 | *.azurePubxml 143 | # TODO: Comment the next line if you want to checkin your web deploy settings 144 | # but database connection strings (with potential passwords) will be unencrypted 145 | *.pubxml 146 | *.publishproj 147 | 148 | # NuGet Packages 149 | *.nupkg 150 | # The packages folder can be ignored because of Package Restore 151 | **/packages/* 152 | # except build/, which is used as an MSBuild target. 153 | !**/packages/build/ 154 | # Uncomment if necessary however generally it will be regenerated when needed 155 | #!**/packages/repositories.config 156 | # NuGet v3's project.json files produces more ignoreable files 157 | *.nuget.props 158 | *.nuget.targets 159 | 160 | # Microsoft Azure Build Output 161 | csx/ 162 | *.build.csdef 163 | 164 | # Microsoft Azure Emulator 165 | ecf/ 166 | rcf/ 167 | 168 | # Microsoft Azure ApplicationInsights config file 169 | ApplicationInsights.config 170 | 171 | # Windows Store app package directory 172 | AppPackages/ 173 | BundleArtifacts/ 174 | 175 | # Visual Studio cache files 176 | # files ending in .cache can be ignored 177 | *.[Cc]ache 178 | # but keep track of directories ending in .cache 179 | !*.[Cc]ache/ 180 | 181 | # Others 182 | ClientBin/ 183 | ~$* 184 | *~ 185 | *.dbmdl 186 | *.dbproj.schemaview 187 | *.pfx 188 | *.publishsettings 189 | node_modules/ 190 | orleans.codegen.cs 191 | 192 | # RIA/Silverlight projects 193 | Generated_Code/ 194 | 195 | # Backup & report files from converting an old project file 196 | # to a newer Visual Studio version. Backup files are not needed, 197 | # because we have git ;-) 198 | _UpgradeReport_Files/ 199 | Backup*/ 200 | UpgradeLog*.XML 201 | UpgradeLog*.htm 202 | 203 | # SQL Server files 204 | *.mdf 205 | *.ldf 206 | 207 | # Business Intelligence projects 208 | *.rdl.data 209 | *.bim.layout 210 | *.bim_*.settings 211 | 212 | # Microsoft Fakes 213 | FakesAssemblies/ 214 | 215 | # GhostDoc plugin setting file 216 | *.GhostDoc.xml 217 | 218 | # Node.js Tools for Visual Studio 219 | .ntvs_analysis.dat 220 | 221 | # Visual Studio 6 build log 222 | *.plg 223 | 224 | # Visual Studio 6 workspace options file 225 | *.opt 226 | 227 | # Visual Studio LightSwitch build output 228 | **/*.HTMLClient/GeneratedArtifacts 229 | **/*.DesktopClient/GeneratedArtifacts 230 | **/*.DesktopClient/ModelManifest.xml 231 | **/*.Server/GeneratedArtifacts 232 | **/*.Server/ModelManifest.xml 233 | _Pvt_Extensions 234 | 235 | # Paket dependency manager 236 | .paket/paket.exe 237 | 238 | # FAKE - F# Make 239 | .fake/ 240 | -------------------------------------------------------------------------------- /Http/PrintNodeApiHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Net.Http; 4 | using System.Net.Http.Headers; 5 | using System.Text; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | using Newtonsoft.Json; 9 | 10 | namespace PrintNodeNet.Http 11 | { 12 | internal static class PrintNodeApiHelper 13 | { 14 | private static readonly HttpClient Client = BuildHttpClient(); 15 | 16 | private static readonly JsonSerializerSettings DefaultSerializationSettings = new JsonSerializerSettings 17 | { 18 | NullValueHandling = NullValueHandling.Ignore 19 | }; 20 | 21 | internal static async Task Get(string relativeUri, PrintNodeRequestOptions options) 22 | { 23 | SetAuthenticationHeader(Client, options); 24 | 25 | var result = await Client.GetAsync(relativeUri, CancellationToken.None); 26 | 27 | if (!result.IsSuccessStatusCode) 28 | { 29 | throw new Exception(result.StatusCode.ToString()); 30 | } 31 | 32 | return await result.Content.ReadAsStringAsync(); 33 | } 34 | 35 | internal static async Task Post(string relativeUri, T parameters, PrintNodeRequestOptions options) 36 | { 37 | SetAuthenticationHeader(Client, options); 38 | 39 | var json = JsonConvert.SerializeObject(parameters, DefaultSerializationSettings); 40 | 41 | var response = await Client.PostAsync(relativeUri, new StringContent(json, Encoding.UTF8, "application/json"), CancellationToken.None); 42 | 43 | if (!response.IsSuccessStatusCode) 44 | { 45 | throw new PrintNodeException(response); 46 | } 47 | 48 | return await response.Content.ReadAsStringAsync(); 49 | } 50 | 51 | internal static async Task Patch(string relativeUri, T parameters, PrintNodeRequestOptions options, Dictionary headers) 52 | { 53 | SetAuthenticationHeader(Client, options); 54 | 55 | var json = JsonConvert.SerializeObject(parameters, DefaultSerializationSettings); 56 | var request = new HttpRequestMessage(new HttpMethod("PATCH"), relativeUri) { Content = new StringContent(json, Encoding.UTF8, "application/json") }; 57 | 58 | foreach (var h in headers) 59 | { 60 | request.Headers.Add(h.Key, h.Value); 61 | } 62 | 63 | var response = await Client.SendAsync(request); 64 | 65 | if (!response.IsSuccessStatusCode) 66 | { 67 | throw new PrintNodeException(response); 68 | } 69 | 70 | return await response.Content.ReadAsStringAsync(); 71 | } 72 | 73 | internal static async Task Delete(string relativeUri, PrintNodeRequestOptions options, Dictionary headers) 74 | { 75 | SetAuthenticationHeader(Client, options); 76 | 77 | var request = new HttpRequestMessage(new HttpMethod("DELETE"), relativeUri); 78 | 79 | foreach (var h in headers) 80 | { 81 | request.Headers.Add(h.Key, h.Value); 82 | } 83 | 84 | var response = await Client.SendAsync(request); 85 | 86 | if (!response.IsSuccessStatusCode) 87 | { 88 | throw new PrintNodeException(response); 89 | } 90 | 91 | return await response.Content.ReadAsStringAsync(); 92 | } 93 | 94 | private static void SetAuthenticationHeader(HttpClient client, PrintNodeRequestOptions options) 95 | { 96 | var apiKey = options?.ApiKey ?? PrintNodeConfiguration.ApiKey; 97 | 98 | if (string.IsNullOrEmpty(apiKey)) 99 | { 100 | throw new Exception("PrintNode API key not set! Please go to printnode.com and request an API key, and follow the instructions for configuring PrintNode.Net"); 101 | } 102 | 103 | client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes(apiKey))); 104 | } 105 | 106 | private static HttpClient BuildHttpClient() 107 | { 108 | var http = new HttpClient(); 109 | 110 | http.DefaultRequestHeaders.Add("Accept-Version", "~3"); 111 | http.BaseAddress = PrintNodeConfiguration.BaseAddress; 112 | 113 | var context = PrintNodeDelegatedClientContext.Current; 114 | 115 | if (context != null) 116 | { 117 | var headerName = ""; 118 | 119 | switch (context.AuthenticationMode) 120 | { 121 | case PrintNodeDelegatedClientContextAuthenticationMode.Id: 122 | headerName = "X-Child-Account-By-Id"; 123 | break; 124 | case PrintNodeDelegatedClientContextAuthenticationMode.Email: 125 | headerName = "X-Child-Account-By-Email"; 126 | break; 127 | case PrintNodeDelegatedClientContextAuthenticationMode.CreatorRef: 128 | headerName = "X-Child-Account-By-CreatorRef"; 129 | break; 130 | } 131 | 132 | http.DefaultRequestHeaders.Add(headerName, context.AuthenticationValue); 133 | } 134 | 135 | return http; 136 | } 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /PrintNodeComputer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Newtonsoft.Json; 6 | using PrintNodeNet.Http; 7 | using PrintNodeNet.Util; 8 | 9 | namespace PrintNodeNet 10 | { 11 | public sealed class PrintNodeComputer 12 | { 13 | [JsonProperty("id")] 14 | public long Id { get; set; } 15 | 16 | [JsonProperty("name")] 17 | public string Name { get; set; } 18 | 19 | [JsonProperty("inet")] 20 | public string Inet { get; set; } 21 | 22 | [JsonProperty("inet6")] 23 | public string Inet6 { get; set; } 24 | 25 | [JsonProperty("hostName")] 26 | public string HostName { get; set; } 27 | 28 | [JsonProperty("jre")] 29 | public string Jre { get; set; } 30 | 31 | [JsonProperty("createTimeStamp")] 32 | public DateTime CreateTimeStamp { get; set; } 33 | 34 | [JsonProperty("state")] 35 | public string State { get; set; } 36 | 37 | public static async Task> ListAsync(PrintNodeRequestOptions options = null) 38 | { 39 | var response = await PrintNodeApiHelper.Get("/computers", options); 40 | 41 | return JsonConvert.DeserializeObject>(response); 42 | } 43 | 44 | public static async Task GetAsync(long id, PrintNodeRequestOptions options = null) 45 | { 46 | var response = await PrintNodeApiHelper.Get($"/computers/{id}", options); 47 | 48 | var list = JsonConvert.DeserializeObject>(response); 49 | 50 | return list.FirstOrDefault(); 51 | } 52 | 53 | /// 54 | /// Static method to retrieve a set of computers from the PrintNode API. 55 | /// 56 | /// The list of ids of the computers. 57 | /// The request options (allows API key modification) 58 | /// The list of matching to the given ids 59 | public static async Task> GetSetAsync(IEnumerable computerSet, PrintNodeRequestOptions options = null) 60 | { 61 | string ids = new SetBuilder(computerSet).Build(); 62 | 63 | var response = await PrintNodeApiHelper.Get($"/computers/{ids}", options); 64 | 65 | return JsonConvert.DeserializeObject>(response); 66 | } 67 | 68 | public async Task> ListPrinters(PrintNodeRequestOptions options = null) 69 | { 70 | var response = await PrintNodeApiHelper.Get($"/computers/{Id}/printers", options); 71 | 72 | return JsonConvert.DeserializeObject>(response); 73 | 74 | } 75 | 76 | /// 77 | /// Static overwrite of the method 78 | /// to get the printers of the given computer. 79 | /// 80 | /// The id of the computer to get the printers from. 81 | /// The request options (allows API key modification) 82 | /// The list of that belongs to the given computer 83 | public static async Task> ListPrinters(long id, PrintNodeRequestOptions options = null) 84 | { 85 | var response = await PrintNodeApiHelper.Get($"/computers/{id}/printers", options); 86 | 87 | return JsonConvert.DeserializeObject>(response); 88 | 89 | } 90 | 91 | /// 92 | /// Static method to retrieve the list of that belongs 93 | /// to the given set of computers. 94 | /// 95 | /// The list of ids of the computers. 96 | /// The request options (allows API key modification). 97 | /// The list of that belongs to the given set of computers. 98 | public static async Task> ListComputerSetPrintersAsync(IEnumerable computerSet, PrintNodeRequestOptions options = null) 99 | { 100 | string ids = new SetBuilder(computerSet).Build(); 101 | 102 | var response = await PrintNodeApiHelper.Get($"/computers/{ids}/printers", options); 103 | 104 | return JsonConvert.DeserializeObject>(response); 105 | } 106 | 107 | /// 108 | /// Static method to retrieve the given set of if they 109 | /// belong to the given set of computers. 110 | /// 111 | /// The list of ids of the computers. 112 | /// The list of ids of the printers. 113 | /// The request options (allows API key modification). 114 | /// The set of that belongs to the given set of computers. 115 | public static async Task> ListComputerSetPrinterSetAsync(IEnumerable computerSet, IEnumerable printerSet, PrintNodeRequestOptions options = null) 116 | { 117 | string computerIds = new SetBuilder(computerSet).Build(); 118 | string printerIds = new SetBuilder(printerSet).Build(); 119 | 120 | var response = await PrintNodeApiHelper.Get($"/computers/{computerIds}/printers/{printerIds}", options); 121 | 122 | return JsonConvert.DeserializeObject>(response); 123 | } 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /PrintNodeScale.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading.Tasks; 4 | using Newtonsoft.Json; 5 | using PrintNodeNet.Http; 6 | 7 | namespace PrintNodeNet 8 | { 9 | public sealed class PrintNodeScale 10 | { 11 | /// 12 | /// The first element represents the mass returned by the scale in micrograms. If the scale has been unable to calculate a 13 | /// weight, this element is null. This most commonly happens when scales display a negative weight. Although many scales can 14 | /// display negative weights on their built-in displays, they are often unable to return negative weight readings over their 15 | /// USB interfaces. 16 | /// 17 | /// The second element represents the resolution of the scale in micrograms, where this is known, or null otherwise. 18 | /// 19 | /// For example, a reading of 125g with a resolution of 5g would be represented as [125000000, 5000000]. 20 | /// 21 | [JsonProperty("mass")] 22 | public long?[] Mass { get; set; } 23 | 24 | /// 25 | /// A string identifier for the scale. This is usually the scale's manufacturer and description, unless it has been renamed 26 | /// in the PrintNode Client. 27 | /// 28 | [JsonProperty("deviceName")] 29 | public string DeviceName { get; set; } 30 | 31 | /// 32 | /// If more than one scale with the same deviceName is connected to a computer, they will be assigned different deviceNum 33 | /// properties. This makes it possible to distinguish between them. 34 | /// 35 | /// deviceNum values start at 0 and when a scale is connected to a computer it is assigned the smallest unused deviceNum value 36 | /// for scales with the same deviceName.For example, if two scales with different deviceNames are connected they will both have 37 | /// deviceNum 0. If two scales with the same deviceName are connected they will be assigned deviceNums of 0 and 1. The scale 38 | /// which was connected first gets deviceNum 0. 39 | /// 40 | [JsonProperty("deviceNum")] 41 | public int DeviceNum { get; set; } 42 | 43 | /// 44 | /// A string representing the port to which the scale is connected, e.g. "USB1" or "COM0". 45 | /// 46 | [JsonProperty("port")] 47 | public string Port { get; set; } 48 | 49 | /// 50 | /// Reserved for future use. Currently null. 51 | /// 52 | [JsonProperty("count")] 53 | public int? Count { get; set; } 54 | 55 | /// 56 | /// Scales can usually display their readings in imperial or metric units. The keys in this object represent the units shown on the 57 | /// scale's built-in display at the time of measurement. Supported units are: g, kg, lb and oz. The value for each key is the reading 58 | /// in billionths of the corresponding unit. This information makes it easy to determine the reading being displayed on the scale 59 | /// itself. In terms of measurement, it provides the same information as the mass property. Use whichever one you find more convenient. 60 | /// 61 | /// For example, display values of "1.2 kg", "1200g" or "2lb 10.32oz" would result in measurement values of {"kg":1200000000}, 62 | /// {"g": 1200000000000} and {"lb": 2000000000, "oz": 10320000000} respectively, but in all three cases the first element of the 63 | /// mass array would be 1200000000. 64 | /// 65 | [JsonProperty("measurement")] 66 | public PrintNodeScaleMeasurement Measurement { get; set; } 67 | 68 | /// 69 | /// The time as reported by the computer the scale is attached to at the time of generation of the scale data. 70 | /// 71 | [JsonProperty("clientReportedCreateTimeStamp")] 72 | public DateTime ClientReportedCreateTimeStamp { get; set; } 73 | 74 | /// 75 | /// Inaccuracy of the system time of the client computer generating the scales data in milliseconds as determined via by NTP. 76 | /// Positive values represent a system clock running fast and a negative value represents a system clock running slow. Under normal 77 | /// conditions this offset is usually accurate to ± 10 milliseconds. It takes a short while to determine the ntpOffset after the 78 | /// client starts up. When this information is not available the value will be null. 79 | /// 80 | [JsonProperty("ntpOffset")] 81 | public int? NtpOffset { get; set; } 82 | 83 | /// 84 | /// Reserved for future use. Currently null. 85 | /// 86 | [JsonProperty("ageOfData")] 87 | public int AgeOfData { get; set; } 88 | 89 | /// 90 | /// The computer id. 91 | /// 92 | [JsonProperty("computerId")] 93 | public long ComputerId { get; set; } 94 | 95 | /// 96 | /// String description of the vendor or manufacturer of the scales device. 97 | /// 98 | [JsonProperty("vendor")] 99 | public string Vendor { get; set; } 100 | 101 | /// 102 | /// The product name. 103 | /// 104 | [JsonProperty("product")] 105 | public string Product { get; set; } 106 | 107 | /// 108 | /// The USB device vendor id. See here for a detailed description 109 | /// and see here for an up-to-date list of vendor and product ids. 110 | /// 111 | [JsonProperty("vendorId")] 112 | public int VendorId { get; set; } 113 | 114 | /// 115 | /// The USB device product id. See here for a detailed description and 116 | /// see here for an up-to-date list of vendor and product ids. 117 | /// 118 | [JsonProperty("productId")] 119 | public int ProductId { get; set; } 120 | 121 | public static async Task> ListForComputerAsync(long computerId, PrintNodeRequestOptions options = null) 122 | { 123 | var response = await PrintNodeApiHelper.Get($"/computer/{computerId}/scales", options); 124 | 125 | return JsonConvert.DeserializeObject>(response); 126 | } 127 | 128 | public static async Task> ListForComputerDeviceAsync(long computerId, string deviceName, PrintNodeRequestOptions options = null) 129 | { 130 | var response = await PrintNodeApiHelper.Get($"/computer/{computerId}/scales/{deviceName}", options); 131 | 132 | return JsonConvert.DeserializeObject>(response); 133 | } 134 | 135 | public static async Task GetAsync(long computerId, string deviceName, int deviceNum, PrintNodeRequestOptions options = null) 136 | { 137 | var response = await PrintNodeApiHelper.Get($"/computer/{computerId}/scale/{deviceName}/{deviceNum}", options); 138 | 139 | return JsonConvert.DeserializeObject(response); 140 | } 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /PrintNodePrintJob.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Newtonsoft.Json; 6 | using PrintNodeNet.Http; 7 | using PrintNodeNet.Util; 8 | 9 | namespace PrintNodeNet 10 | { 11 | public sealed class PrintNodePrintJob 12 | { 13 | /// 14 | /// Assigned by API. Any value submitted here will be ignored. 15 | /// 16 | [JsonProperty("id")] 17 | public long? Id { get; set; } 18 | 19 | /// 20 | /// The printer id associated with your account. 21 | /// 22 | [JsonProperty("printerId")] 23 | public long PrinterId { get; set; } 24 | 25 | [JsonProperty("printer")] 26 | public PrintNodePrinter Printer { get; set; } 27 | 28 | /// 29 | /// A title to give the PrintJob. This is the name which will appear in the operating system's print queue. 30 | /// 31 | [JsonProperty("title")] 32 | public string Title { get; set; } 33 | 34 | /// 35 | /// Either 'pdf_uri', 'pdf_base64', 'raw_uri', 'raw_base64'. 36 | /// 37 | /// See content. 38 | /// 39 | [JsonProperty("contentType")] 40 | public string ContentType { get; set; } 41 | 42 | /// 43 | /// A uri accessible by the client when contentType is 'pdf_uri'. 44 | /// or 45 | /// A base64 encoded representation of the pdf when contentType is 'pdf_base64'. 46 | /// 47 | [JsonProperty("content")] 48 | public string Content { get; set; } 49 | 50 | /// 51 | /// A text description of how the printjob was created or where the printjob originated. 52 | /// 53 | [JsonProperty("source")] 54 | public string Source { get; set; } = "printnode-net"; 55 | 56 | /// 57 | /// An object describing various options which can be set for this PrintJob. See options. Printing options have no effect when raw printing. 58 | /// 59 | [JsonProperty("options")] 60 | public PrintNodePrintJobOptions Options { get; set; } 61 | 62 | /// 63 | /// The maximum number of seconds PrintNode should retain this PrintJob for attempted printing in the event the PrintJob cannot be 64 | /// printed immediately. The current default is 14 days or 1,209,600 seconds. 65 | /// 66 | [JsonProperty("expireAfter")] 67 | public long? ExpireAfter { get; set; } 68 | 69 | /// 70 | /// The default value is 1. A positive integer representing the number of times this PrintJob should be delivered to the print queue. 71 | /// This differs from the "copies" option in that this will send a document to a printer multiple times and does not rely on print driver 72 | /// support. This is the only way to support multiple copies when raw printing. This also enables printing multiple copies even when a 73 | /// printer driver does not natively support this. 74 | /// 75 | [JsonProperty("qty")] 76 | public int Qty { get; set; } = 1; 77 | 78 | /// 79 | /// If a contentType of 'pdf_uri' or 'raw_uri' is used and the uri requires either HTTP Basic or Digest Authentication you can specify 80 | /// the username and password information here. Supported in clients v4.7.0 or newer. 81 | /// 82 | /// For Basic authentication 83 | /// { 84 | /// "type": "BasicAuth", 85 | /// "credentials": { 86 | /// "user": "username", 87 | /// "pass": "password" 88 | /// } 89 | /// } 90 | /// 91 | /// For Digest authentication 92 | /// 93 | /// { 94 | /// "type": "DigestAuth", 95 | /// "credentials": { 96 | /// "user": "username", 97 | /// "pass": "password" 98 | /// } 99 | /// } 100 | /// Just replace the "username" and "password" with your credentials as appropriate. 101 | /// 102 | [JsonProperty("authentication")] 103 | public PrintNodePrintJobAuthentication Authentication { get; set; } 104 | 105 | [JsonProperty("state")] 106 | public string State { get; set; } 107 | 108 | [JsonProperty("createTimeStamp")] 109 | public DateTime? CreateTimeStamp { get; set; } 110 | 111 | public PrintNodePrintJob() { } 112 | 113 | public PrintNodePrintJob(string title, PrintNodeContentType contentType, string content, long printerId) 114 | { 115 | Title = title; 116 | ContentType = contentType.ToString(); 117 | Content = content; 118 | PrinterId = printerId; 119 | } 120 | 121 | 122 | public static async Task> ListAsync(PrintNodeRequestOptions options = null) 123 | { 124 | var response = await PrintNodeApiHelper.Get("/printjobs", options); 125 | 126 | return JsonConvert.DeserializeObject>(response); 127 | } 128 | 129 | public static async Task> ListForPrinterAsync(long printerId, PrintNodeRequestOptions options = null) 130 | { 131 | var response = await PrintNodeApiHelper.Get($"/printers/{printerId}/printjobs", options); 132 | 133 | return JsonConvert.DeserializeObject>(response); 134 | } 135 | 136 | /// 137 | /// Static method that allows the retrieval of the list of 138 | /// for a set of . 139 | /// 140 | /// The ids of the printers 141 | /// The request options (allows API key modification). 142 | /// The print jobs of every printer that has its ID included in the set 143 | public static async Task> ListForPrinterSetAsync(IEnumerable set, PrintNodeRequestOptions options = null) 144 | { 145 | string ids = new SetBuilder(set).Build(); 146 | 147 | var response = await PrintNodeApiHelper.Get($"/printers/{ids}/printjobs", options); 148 | 149 | return JsonConvert.DeserializeObject>(response); 150 | } 151 | 152 | /// 153 | /// Static method that allows the retrieval of a set of 154 | /// for a set of . 155 | /// 156 | /// The ids of the printers 157 | /// The ids of the print jobs 158 | /// The request options (allows API key modification). 159 | /// The union between print jobs of the given ids and printjobs of the given printers. 160 | public static async Task> ListPrinjobSetForPrinterSetAsync(IEnumerable printerSet, IEnumerable printjobSet, PrintNodeRequestOptions options = null) 161 | { 162 | string printerIds = new SetBuilder(printerSet).Build(); 163 | string printjobsIds = new SetBuilder(printjobSet).Build(); 164 | 165 | var response = await PrintNodeApiHelper.Get($"/printers/{printerIds}/printjobs/{printjobsIds}", options); 166 | 167 | return JsonConvert.DeserializeObject>(response); 168 | } 169 | 170 | public static async Task GetAsync(long id, PrintNodeRequestOptions options = null) 171 | { 172 | var response = await PrintNodeApiHelper.Get($"/printjobs/{id}", options); 173 | 174 | var list = JsonConvert.DeserializeObject>(response); 175 | 176 | return list.FirstOrDefault(); 177 | } 178 | 179 | /// 180 | /// Static method that allows the retrieval of a set of , 181 | /// identified by their IDs. 182 | /// 183 | /// The ids of the print jobs 184 | /// The request options (allows API key modification). 185 | /// The print jobs as an enumerable. 186 | public static async Task> GetSetAsync(IEnumerable set, PrintNodeRequestOptions options = null) 187 | { 188 | string ids = new SetBuilder(set).Build(); 189 | 190 | var response = await PrintNodeApiHelper.Get($"/printjobs/{ids}", options); 191 | 192 | return JsonConvert.DeserializeObject>(response); 193 | } 194 | 195 | public async Task> GetStates(PrintNodeRequestOptions options = null) 196 | { 197 | var response = await PrintNodeApiHelper.Get($"/printjobs/{Id}/states", options); 198 | 199 | var list = JsonConvert.DeserializeObject>>(response); 200 | 201 | return list.FirstOrDefault(); 202 | } 203 | 204 | /// 205 | /// Static overwrite of the method. 206 | /// It retrieves all the history of states for the given printjob id. 207 | /// 208 | /// The print job ID to get the history from. 209 | /// The request options (allows API key modification). 210 | /// A list of that traces every state the printjob has been in since its creation. 211 | public static async Task> GetStates(long id, PrintNodeRequestOptions options = null) 212 | { 213 | var response = await PrintNodeApiHelper.Get($"/printjobs/{id}/states", options); 214 | 215 | var list = JsonConvert.DeserializeObject>>(response); 216 | 217 | return list.FirstOrDefault(); 218 | } 219 | 220 | /// 221 | /// This method retrieves all the history of states for the given set of print jobs. 222 | /// 223 | /// The ids of all the print jobs we want to get the states of. 224 | /// The request options (allows API key modification). 225 | /// A list of that traces every state the print job has been in since its creation, for every print job of the set. 226 | public static async Task>> GetPrintJobSetStatesAsync(IEnumerable set, PrintNodeRequestOptions options = null) 227 | { 228 | string ids = new SetBuilder(set).Build(); 229 | 230 | var response = await PrintNodeApiHelper.Get($"/printjobs/{ids}/states", options); 231 | 232 | return JsonConvert.DeserializeObject>>(response); 233 | } 234 | 235 | public async Task Print(PrintNodeRequestOptions options = null) 236 | { 237 | if (Printer == null && PrinterId == 0) 238 | { 239 | throw new Exception("Printer or PrinterId required"); 240 | } 241 | 242 | var response = await PrintNodeApiHelper.Post("/printjobs", this, options); 243 | 244 | return JsonConvert.DeserializeObject(response); 245 | } 246 | } 247 | } 248 | --------------------------------------------------------------------------------