From 5719138a8ae3a84d90fc78ff994a7c11e989e04e Mon Sep 17 00:00:00 2001 From: "Collin M. Barrett" Date: Thu, 26 Oct 2017 15:38:03 -0500 Subject: [PATCH] data model updates --- .github/ISSUE_TEMPLATE.md | 2 +- .github/PULL_REQUEST_TEMPLATE.md | 2 +- .github/README.md | 2 +- data/DataSample.json | 30 ++++ data/DataSchema.json | 155 ++++++++++++++++++ data/ListSample.json | 12 -- data/ListSchema.json | 107 ------------ .../Json/JsonSampleGenerator.cs | 55 +++++-- .../Json/JsonSchemaGenerator.cs | 2 +- .../Models/Contracts/IMaintainer.cs | 4 +- .../Models/Implementations/FilterList.cs | 20 +-- .../Models/Implementations/Maintainer.cs | 23 ++- 12 files changed, 246 insertions(+), 168 deletions(-) create mode 100644 data/DataSample.json create mode 100644 data/DataSchema.json delete mode 100644 data/ListSample.json delete mode 100644 data/ListSchema.json diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index a0a611ae3..837f1b2ba 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -17,7 +17,7 @@ Before submitting a new issue, please review the checklist below. * [ ] Have you ensured all URLs point to HTTPS if supported? ## Properties -[Source](https://github.com/collinbarrett/FilterLists/blob/master/data/ListSample.json) | [Schema](https://github.com/collinbarrett/FilterLists/blob/master/data/ListSchema.json) +[Source](https://github.com/collinbarrett/FilterLists/blob/master/data/DataSample.json) | [Schema](https://github.com/collinbarrett/FilterLists/blob/master/data/DataSchema.json) | Property | Description | | -------------- | ---------------------------------------- | diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 3354ef9f4..16a794442 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -17,7 +17,7 @@ Before submitting a new pull request, please review the checklist below. * [ ] Have you ensured all URLs point to HTTPS if supported? ### Sample List JSON Object: -[Source](https://github.com/collinbarrett/FilterLists/blob/master/data/ListSample.json) | [Schema](https://github.com/collinbarrett/FilterLists/blob/master/data/ListSchema.json) +[Source](https://github.com/collinbarrett/FilterLists/blob/master/data/DataSample.json) | [Schema](https://github.com/collinbarrett/FilterLists/blob/master/data/DataSchema.json) ``` { diff --git a/.github/README.md b/.github/README.md index 955eacabc..1f0dc9f2b 100644 --- a/.github/README.md +++ b/.github/README.md @@ -12,7 +12,7 @@ FilterLists is the independent and comprehensive directory of all public filter FilterLists improvements are slow and tend to be in spurts. I care about this project as both a resource for the community and a learning tool for me. However, my day job comes first which often results in little to no work on the project at times. I happily welcome anyone that wants to contribute. The immediate projects are converting the data to an actual database (rather than a Google Sheet) and then exposing the data via a [.Net Core API](https://github.com/collinbarrett/FilterLists/projects/3). I would also love to build a more responsive front-end, but I am not a front-end developer and would welcome help on [this](https://github.com/collinbarrett/FilterLists/projects/4). ## Properties -[Source](https://github.com/collinbarrett/FilterLists/blob/master/data/ListSample.json) | [Schema](https://github.com/collinbarrett/FilterLists/blob/master/data/ListSchema.json) +[Source](https://github.com/collinbarrett/FilterLists/blob/master/data/DataSample.json) | [Schema](https://github.com/collinbarrett/FilterLists/blob/master/data/DataSchema.json) | Property | Description | | -------------- | ---------------------------------------- | diff --git a/data/DataSample.json b/data/DataSample.json new file mode 100644 index 000000000..5170130f0 --- /dev/null +++ b/data/DataSample.json @@ -0,0 +1,30 @@ +{ + "FilterLists": [ + { + "Description": "A sample list to filter out advertisements.", + "DescriptionSourceUrl": "https://mysample.list/advertisements", + "DonateUrl": "https://mysample.list/donate/", + "Email": "contact@mysample.list", + "ForumUrl": "https://mysample.list/forum/", + "HomeUrl": "https://mysample.list/", + "IssuesUrl": "https://github.com/johnsmith/mysamplelist/issues", + "Name": "My Sample Advertisement Filter List", + "ViewUrl": "https://mysample.list/list.txt" + }, + { + "Description": "A sample list to filter out malware.", + "DescriptionSourceUrl": "https://mysample.list/malware", + "DonateUrl": "https://mysample.list/donate/", + "Email": "contact@mysample.list", + "ForumUrl": "https://mysample.list/forum/", + "HomeUrl": "https://mysample.list/", + "IssuesUrl": "https://github.com/johnsmith/mysamplelist/issues", + "Name": "My Sample Malware Filter List", + "ViewUrl": "https://mysample.list/list.txt" + } + ], + "Email": "john.smith@protonmail.com", + "HomeUrl": "https://johnsmith.com", + "Name": "John Smith", + "TwitterHandle": "@johnsmith" +} \ No newline at end of file diff --git a/data/DataSchema.json b/data/DataSchema.json new file mode 100644 index 000000000..7bb98cfad --- /dev/null +++ b/data/DataSchema.json @@ -0,0 +1,155 @@ +{ + "definitions": { + "FilterList": { + "type": [ + "object", + "null" + ], + "properties": { + "Description": { + "description": "A brief description of the list's functionality. Preferably, this is quoted (if non-English, translate to English via translator or Google Translate for consistency) from the list's documentation or composed by a maintainer of the list. If neither are available, a generic description should be composed by the FilterLists contributor.", + "type": [ + "string", + "null" + ], + "maxLength": 1022 + }, + "DescriptionSourceUrl": { + "description": "The URL to the list's documentation page from which the description was quoted if applicable.", + "type": [ + "string", + "null" + ], + "minLength": 6, + "maxLength": 2083, + "format": "uri" + }, + "DonateUrl": { + "description": "The URL to the list's donation page. This could be a custom PayPal or similar link, or a link to a web page discussing various donation options. Pull requests that include changes to this link will undergo further verification to prevent fraud.", + "type": [ + "string", + "null" + ], + "minLength": 6, + "maxLength": 2083, + "format": "uri" + }, + "Email": { + "description": "The email address of the list's maintainer(s) if publicly available.", + "type": [ + "string", + "null" + ], + "minLength": 7, + "maxLength": 126, + "format": "email" + }, + "ForumUrl": { + "description": "The URL to the list's forum where issues, change requests, etc. are discussed.", + "type": [ + "string", + "null" + ], + "minLength": 6, + "maxLength": 2083, + "format": "uri" + }, + "HomeUrl": { + "description": "The URL to the list's home page. Preferably, this is stated in the header of the list. Alternatively, it could be a custom domain, GitHub page, blog post, forum post, etc. that serves as a primary source of information for the list.", + "type": [ + "string", + "null" + ], + "minLength": 6, + "maxLength": 2083, + "format": "uri" + }, + "IssuesUrl": { + "description": "The URL to the list's GitHub Issues.", + "type": [ + "string", + "null" + ], + "minLength": 6, + "maxLength": 2083, + "format": "uri" + }, + "Name": { + "description": "The name of the list as stated by the list maintainer(s) in title case.", + "type": "string", + "maxLength": 126 + }, + "ViewUrl": { + "description": "The URL to the list in raw text format. zip files and other formats are acceptable if no text format is available.", + "type": "string", + "minLength": 6, + "maxLength": 2083, + "format": "uri" + } + }, + "required": [ + "Description", + "DescriptionSourceUrl", + "DonateUrl", + "Email", + "ForumUrl", + "HomeUrl", + "IssuesUrl", + "Name", + "ViewUrl" + ] + } + }, + "type": "object", + "properties": { + "FilterLists": { + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/definitions/FilterList" + } + }, + "Email": { + "description": "The email address of the list maintainer.", + "type": [ + "string", + "null" + ], + "minLength": 7, + "maxLength": 126, + "format": "email" + }, + "HomeUrl": { + "description": "The URL to the list maintainer's home page.", + "type": [ + "string", + "null" + ], + "minLength": 6, + "maxLength": 2083, + "format": "uri" + }, + "Name": { + "description": "The name of the list maintainer.", + "type": "string", + "maxLength": 126 + }, + "TwitterHandle": { + "description": "The Twitter handle of the list maintainer.", + "type": [ + "string", + "null" + ], + "maxLength": 126 + } + }, + "required": [ + "FilterLists", + "Email", + "HomeUrl", + "Name", + "TwitterHandle" + ] +} \ No newline at end of file diff --git a/data/ListSample.json b/data/ListSample.json deleted file mode 100644 index cb9fa457e..000000000 --- a/data/ListSample.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "Author": "John Doe", - "Description": "A sample list to filter out advertisements.", - "DescriptionSourceUrl": "https://mysample.list", - "DonateUrl": "https://mysample.list/donate/", - "Email": "contact@mysample.list", - "ForumUrl": "https://mysample.list/forum/", - "HomeUrl": "https://mysample.list/", - "IssuesUrl": "https://github.com/mysamplelist/issues", - "Name": "My Sample Filter List", - "ViewUrl": "https://mysample.list/list.txt" -} \ No newline at end of file diff --git a/data/ListSchema.json b/data/ListSchema.json deleted file mode 100644 index 48e797983..000000000 --- a/data/ListSchema.json +++ /dev/null @@ -1,107 +0,0 @@ -{ - "type": "object", - "properties": { - "Author": { - "description": "The author (person or group) who maintains the list.", - "type": [ - "string", - "null" - ], - "maxLength": 126 - }, - "Description": { - "description": "A brief description of the list's functionality. Preferably, this is quoted (if non-English, translate to English via translator or Google Translate for consistency) from the list's documentation or composed by a maintainer of the list. If neither are available, a generic description should be composed by the FilterLists contributor.", - "type": [ - "string", - "null" - ], - "maxLength": 1022 - }, - "DescriptionSourceUrl": { - "description": "The URL to the list's documentation page from which the description was quoted if applicable.", - "type": [ - "string", - "null" - ], - "minLength": 6, - "maxLength": 2083, - "format": "uri" - }, - "DonateUrl": { - "description": "The URL to the list's donation page. This could be a custom PayPal or similar link, or a link to a web page discussing various donation options. Pull requests that include changes to this link will undergo further verification to prevent fraud.", - "type": [ - "string", - "null" - ], - "minLength": 6, - "maxLength": 2083, - "format": "uri" - }, - "Email": { - "description": "The email address of the list's maintainer(s) if publicly available.", - "type": [ - "string", - "null" - ], - "minLength": 7, - "maxLength": 126 - }, - "ForumUrl": { - "description": "The URL to the list's forum where issues, change requests, etc. are discussed.", - "type": [ - "string", - "null" - ], - "minLength": 6, - "maxLength": 2083, - "format": "uri" - }, - "HomeUrl": { - "description": "The URL to the list's home page. Preferably, this is stated in the header of the list. Alternatively, it could be a custom domain, GitHub page, blog post, forum post, etc. that serves as a primary source of information for the list.", - "type": [ - "string", - "null" - ], - "minLength": 6, - "maxLength": 2083, - "format": "uri" - }, - "IssuesUrl": { - "description": "The URL to the list's GitHub Issues.", - "type": [ - "string", - "null" - ], - "minLength": 6, - "maxLength": 2083, - "format": "uri" - }, - "Name": { - "description": "The name of the list as stated by the list maintainer(s) in title case.", - "type": [ - "string", - "null" - ], - "maxLength": 126 - }, - "ViewUrl": { - "description": "The URL to the list in raw text format. zip files and other formats are acceptable if no text format is available.", - "type": "string", - "minLength": 6, - "maxLength": 2083, - "format": "uri" - } - }, - "required": [ - "Author", - "Description", - "DescriptionSourceUrl", - "DonateUrl", - "Email", - "ForumUrl", - "HomeUrl", - "IssuesUrl", - "Name", - "ViewUrl" - ] -} \ No newline at end of file diff --git a/src/FilterLists.Data/Json/JsonSampleGenerator.cs b/src/FilterLists.Data/Json/JsonSampleGenerator.cs index 69bbd6653..b41cc79ca 100644 --- a/src/FilterLists.Data/Json/JsonSampleGenerator.cs +++ b/src/FilterLists.Data/Json/JsonSampleGenerator.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Diagnostics; using System.IO; using FilterLists.Data.Models.Implementations; @@ -8,29 +9,47 @@ namespace FilterLists.Data.Json { public static class JsonSampleGenerator { + private static JObject DataSample => (JObject) JToken.FromObject(new Maintainer + { + Email = "john.smith@protonmail.com", + HomeUrl = "https://johnsmith.com", + TwitterHandle = "@johnsmith", + Name = "John Smith", + FilterLists = new List + { + new FilterList + { + Description = "A sample list to filter out advertisements.", + DescriptionSourceUrl = "https://mysample.list/advertisements", + DonateUrl = "https://mysample.list/donate/", + Email = "contact@mysample.list", + ForumUrl = "https://mysample.list/forum/", + HomeUrl = "https://mysample.list/", + IssuesUrl = "https://github.com/johnsmith/mysamplelist/issues", + Name = "My Sample Advertisement Filter List", + ViewUrl = "https://mysample.list/list.txt" + }, + new FilterList + { + Description = "A sample list to filter out malware.", + DescriptionSourceUrl = "https://mysample.list/malware", + DonateUrl = "https://mysample.list/donate/", + Email = "contact@mysample.list", + ForumUrl = "https://mysample.list/forum/", + HomeUrl = "https://mysample.list/", + IssuesUrl = "https://github.com/johnsmith/mysamplelist/issues", + Name = "My Sample Malware Filter List", + ViewUrl = "https://mysample.list/list.txt" + } + } + }); + [Conditional("DEBUG")] public static void WriteSampleToFile() { File.WriteAllText( Path.GetFullPath(Path.Combine(AppContext.BaseDirectory + @"\", @"..\..\..\..\..\data\")) + - "ListSample.json", GetSampleList().ToString()); - } - - private static JObject GetSampleList() - { - return (JObject) JToken.FromObject(new FilterList - { - Author = "John Doe", - Description = "A sample list to filter out advertisements.", - DescriptionSourceUrl = "https://mysample.list", - DonateUrl = "https://mysample.list/donate/", - Email = "contact@mysample.list", - ForumUrl = "https://mysample.list/forum/", - HomeUrl = "https://mysample.list/", - IssuesUrl = "https://github.com/mysamplelist/issues", - Name = "My Sample Filter List", - ViewUrl = "https://mysample.list/list.txt" - }); + "DataSample.json", DataSample.ToString()); } } } \ No newline at end of file diff --git a/src/FilterLists.Data/Json/JsonSchemaGenerator.cs b/src/FilterLists.Data/Json/JsonSchemaGenerator.cs index 5a75e72ed..1c5e7f92b 100644 --- a/src/FilterLists.Data/Json/JsonSchemaGenerator.cs +++ b/src/FilterLists.Data/Json/JsonSchemaGenerator.cs @@ -13,7 +13,7 @@ public static void WriteSchemaToFile() { File.WriteAllText( Path.GetFullPath(Path.Combine(AppContext.BaseDirectory + @"\", @"..\..\..\..\..\data\")) + - "ListSchema.json", new JSchemaGenerator().Generate(typeof(FilterList)).ToString()); + "DataSchema.json", new JSchemaGenerator().Generate(typeof(Maintainer)).ToString()); } } } \ No newline at end of file diff --git a/src/FilterLists.Data/Models/Contracts/IMaintainer.cs b/src/FilterLists.Data/Models/Contracts/IMaintainer.cs index 71add610d..8287e7bc1 100644 --- a/src/FilterLists.Data/Models/Contracts/IMaintainer.cs +++ b/src/FilterLists.Data/Models/Contracts/IMaintainer.cs @@ -2,9 +2,9 @@ { public interface IMaintainer { - string Name { get; set; } string Email { get; set; } - string TwitterHandle { get; set; } string HomeUrl { get; set; } + string Name { get; set; } + string TwitterHandle { get; set; } } } \ No newline at end of file diff --git a/src/FilterLists.Data/Models/Implementations/FilterList.cs b/src/FilterLists.Data/Models/Implementations/FilterList.cs index 4c32a5a39..5905d051c 100644 --- a/src/FilterLists.Data/Models/Implementations/FilterList.cs +++ b/src/FilterLists.Data/Models/Implementations/FilterList.cs @@ -1,19 +1,16 @@ using System.ComponentModel; using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; using FilterLists.Data.Models.Contracts; +using Newtonsoft.Json; namespace FilterLists.Data.Models.Implementations { public class FilterList : BaseEntity, IFilterList { - public long MaintainerId { get; set; } + [JsonIgnore] + public virtual Maintainer Maintainer { get; set; } - [ForeignKey("MaintainerForeignKey")] - public Maintainer Maintainer { get; set; } - - [Description( - @"A brief description of the list's functionality. Preferably, this is quoted (if non-English, translate to English via translator or Google Translate for consistency) from the list's documentation or composed by a maintainer of the list. If neither are available, a generic description should be composed by the FilterLists contributor.")] + [Description(@"A brief description of the list's functionality. Preferably, this is quoted (if non-English, translate to English via translator or Google Translate for consistency) from the list's documentation or composed by a maintainer of the list. If neither are available, a generic description should be composed by the FilterLists contributor.")] [MaxLength(1022)] public string Description { get; set; } @@ -23,8 +20,7 @@ public class FilterList : BaseEntity, IFilterList [MinLength(6)] public string DescriptionSourceUrl { get; set; } - [Description( - @"The URL to the list's donation page. This could be a custom PayPal or similar link, or a link to a web page discussing various donation options. Pull requests that include changes to this link will undergo further verification to prevent fraud.")] + [Description(@"The URL to the list's donation page. This could be a custom PayPal or similar link, or a link to a web page discussing various donation options. Pull requests that include changes to this link will undergo further verification to prevent fraud.")] [Url] [MaxLength(2083)] [MinLength(6)] @@ -42,8 +38,7 @@ public class FilterList : BaseEntity, IFilterList [MinLength(6)] public string ForumUrl { get; set; } - [Description( - @"The URL to the list's home page. Preferably, this is stated in the header of the list. Alternatively, it could be a custom domain, GitHub page, blog post, forum post, etc. that serves as a primary source of information for the list.")] + [Description(@"The URL to the list's home page. Preferably, this is stated in the header of the list. Alternatively, it could be a custom domain, GitHub page, blog post, forum post, etc. that serves as a primary source of information for the list.")] [Url] [MaxLength(2083)] [MinLength(6)] @@ -60,8 +55,7 @@ public class FilterList : BaseEntity, IFilterList [MaxLength(126)] public string Name { get; set; } - [Description( - @"The URL to the list in raw text format. zip files and other formats are acceptable if no text format is available.")] + [Description(@"The URL to the list in raw text format. zip files and other formats are acceptable if no text format is available.")] [Required] [Url] [MaxLength(2083)] diff --git a/src/FilterLists.Data/Models/Implementations/Maintainer.cs b/src/FilterLists.Data/Models/Implementations/Maintainer.cs index 56057cd7e..1301ec337 100644 --- a/src/FilterLists.Data/Models/Implementations/Maintainer.cs +++ b/src/FilterLists.Data/Models/Implementations/Maintainer.cs @@ -9,26 +9,25 @@ public class Maintainer : BaseEntity, IMaintainer { public List FilterLists { get; set; } - [Description(@"The author (person or group) who maintains the list.")] - [Required] - [MaxLength(126)] - public string Name { get; set; } - - [Description(@"The email address of the list's maintainer(s) if publicly available.")] + [Description(@"The email address of the list maintainer.")] [EmailAddress] [MaxLength(126)] [MinLength(7)] public string Email { get; set; } - [Description(@"The email address of the list's maintainer(s) if publicly available.")] - [MaxLength(126)] - public string TwitterHandle { get; set; } - - [Description( - @"The URL to the list's home page. Preferably, this is stated in the header of the list. Alternatively, it could be a custom domain, GitHub page, blog post, forum post, etc. that serves as a primary source of information for the list.")] + [Description(@"The URL to the list maintainer's home page.")] [Url] [MaxLength(2083)] [MinLength(6)] public string HomeUrl { get; set; } + + [Description(@"The name of the list maintainer.")] + [Required] + [MaxLength(126)] + public string Name { get; set; } + + [Description(@"The Twitter handle of the list maintainer.")] + [MaxLength(126)] + public string TwitterHandle { get; set; } } } \ No newline at end of file