├── src ├── FilterLists.Web │ ├── Views │ │ ├── _ViewStart.cshtml │ │ ├── _ViewImports.cshtml │ │ ├── Home │ │ │ └── Index.cshtml │ │ └── Shared │ │ │ ├── Error.cshtml │ │ │ └── _Layout.cshtml │ ├── wwwroot │ │ ├── icon_filterlists.png │ │ └── logo_filterlists.png │ ├── ClientApp │ │ ├── routes.tsx │ │ ├── css │ │ │ └── site.css │ │ ├── boot.tsx │ │ └── components │ │ │ ├── Layout.tsx │ │ │ └── Home.tsx │ ├── tsconfig.json │ ├── Controllers │ │ └── HomeController.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Program.cs │ ├── DependencyInjection │ │ └── Extensions │ │ │ └── ConfigureServicesCollection.cs │ ├── package.json │ ├── Startup.cs │ ├── webpack.config.vendor.js │ ├── webpack.config.js │ └── FilterLists.Web.csproj ├── FilterLists.Data │ ├── Entities │ │ ├── Junctions │ │ │ ├── BaseJunction.cs │ │ │ ├── SoftwareSyntax.cs │ │ │ ├── FilterListLanguage.cs │ │ │ ├── Fork.cs │ │ │ ├── Merge.cs │ │ │ ├── FilterListMaintainer.cs │ │ │ └── SnapshotRule.cs │ │ ├── BaseEntity.cs │ │ ├── Rule.cs │ │ ├── Software.cs │ │ ├── License.cs │ │ ├── Syntax.cs │ │ ├── Maintainer.cs │ │ ├── Snapshot.cs │ │ ├── Language.cs │ │ └── FilterList.cs │ ├── EntityTypeConfigurations │ │ ├── Junctions │ │ │ ├── BaseJunctionTypeConfiguration.cs │ │ │ ├── SoftwareSyntaxTypeConfiguration.cs │ │ │ ├── ForkTypeConfiguration.cs │ │ │ ├── MergeTypeConfiguration.cs │ │ │ ├── FilterListLanguageTypeConfiguration.cs │ │ │ ├── FilterListMaintainerTypeConfiguration.cs │ │ │ └── SnapshotRuleTypeConfiguration.cs │ │ ├── RuleTypeConfiguration.cs │ │ ├── SyntaxTypeConfiguration.cs │ │ ├── LicenseTypeConfiguration.cs │ │ ├── SnapshotTypeConfiguration.cs │ │ ├── BaseEntityTypeConfiguration.cs │ │ ├── SoftwareTypeConfiguration.cs │ │ ├── MaintainerTypeConfiguration.cs │ │ ├── LanguageTypeConfiguration.cs │ │ └── FilterListTypeConfiguration.cs │ ├── FilterLists.Data.csproj │ ├── FilterListsDbContext.cs │ └── Seed │ │ └── Extensions │ │ └── SeedFilterListsDbContext.cs ├── FilterLists.Services │ ├── FilterList │ │ ├── ListLanguagesDto.cs │ │ ├── ListLicenseDto.cs │ │ ├── MaintainerAdditionalListsDto.cs │ │ ├── SyntaxSupportedSoftwareDto.cs │ │ ├── ListSyntaxDto.cs │ │ ├── ListSummaryDto.cs │ │ ├── ListMaintainerDto.cs │ │ ├── FilterListServiceExtensions.cs │ │ ├── ListDetailsDto.cs │ │ ├── MappingProfiles.cs │ │ └── FilterListService.cs │ ├── Snapshot │ │ ├── FilterListViewUrlDto.cs │ │ ├── RawRuleLinterExtensions.cs │ │ ├── SnapshotBatchDe.cs │ │ ├── SnapshotService.cs │ │ └── SnapshotDe.cs │ ├── Seed │ │ ├── Models │ │ │ ├── Junctions │ │ │ │ ├── ForkSeedDto.cs │ │ │ │ ├── SoftwareSyntaxSeedDto.cs │ │ │ │ ├── MergeSeedDto.cs │ │ │ │ ├── FilterListLanguageSeedDto.cs │ │ │ │ └── FilterListMaintainerSeedDto.cs │ │ │ ├── SyntaxSeedDto.cs │ │ │ ├── SoftwareSeedDto.cs │ │ │ ├── MaintainerSeedDto.cs │ │ │ ├── LicenseSeedDto.cs │ │ │ ├── LanguageSeedDto.cs │ │ │ └── FilterListSeedDto.cs │ │ └── SeedService.cs │ ├── Service.cs │ ├── RuleService.cs │ ├── Extensions │ │ └── EnumerableExtensions.cs │ ├── DependencyInjection │ │ └── Extensions │ │ │ └── ConfigureServicesCollection.cs │ └── FilterLists.Services.csproj ├── FilterLists.Api │ ├── Properties │ │ └── launchSettings.json │ ├── V1 │ │ └── Controllers │ │ │ ├── RulesController.cs │ │ │ ├── LicensesController.cs │ │ │ ├── SoftwareController.cs │ │ │ ├── SyntaxesController.cs │ │ │ ├── LanguagesController.cs │ │ │ ├── MaintainersController.cs │ │ │ ├── BaseController.cs │ │ │ ├── ForksController.cs │ │ │ ├── MergesController.cs │ │ │ ├── SoftwareSyntaxesController.cs │ │ │ ├── ListsLanguagesController.cs │ │ │ ├── ListsMaintainersController.cs │ │ │ └── ListsController.cs │ ├── Migrations │ │ ├── 20180324001253_addChatUrl.cs │ │ ├── 20180210204923_AddIsCompletedFlagToSnapshot.cs │ │ ├── 20180210234702_AddSnapshotModifiedDateUtc.cs │ │ ├── 20180214152734_AddPublishedDate.cs │ │ ├── 20180213171240_AddDefaultLicenseId.cs │ │ └── 20180214153140_DefaultOptionalDatesToNull.cs │ ├── Program.cs │ ├── appsettings.json │ ├── FilterLists.Api.csproj │ ├── DependencyInjection │ │ └── Extensions │ │ │ └── ConfigureServicesCollection.cs │ └── Startup.cs └── FilterLists.Agent │ ├── FilterLists.Agent.csproj │ └── Program.cs ├── scripts ├── build.sh ├── cron ├── sql │ ├── createDb.sql │ └── snapshotTimeAnalysis.sql └── deploy.sh ├── imgs ├── icon_filterlists.png ├── icon_filterlists.psd ├── logo_filterlists.png ├── logo_filterlists.psd └── logo_lg_filterlists.png ├── .github ├── PULL_REQUEST_TEMPLATE.md ├── ISSUE_TEMPLATE.md ├── CONTRIBUTING.md ├── CODE_OF_CONDUCT.md └── README.md ├── data ├── README.md ├── SoftwareSyntax.json ├── Fork.json ├── Syntax.json ├── Software.json ├── License.json ├── Merge.json └── FilterListLanguage.json ├── LICENSE ├── FilterLists.sln.DotSettings ├── .gitattributes ├── FilterLists.sln ├── .travis.yml └── .gitignore /src/FilterLists.Web/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "_Layout"; 3 | } -------------------------------------------------------------------------------- /scripts/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | dotnet restore 3 | dotnet publish -c release -r ubuntu.16.04-x64 -------------------------------------------------------------------------------- /imgs/icon_filterlists.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DandelionSprout/FilterLists/HEAD/imgs/icon_filterlists.png -------------------------------------------------------------------------------- /imgs/icon_filterlists.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DandelionSprout/FilterLists/HEAD/imgs/icon_filterlists.psd -------------------------------------------------------------------------------- /imgs/logo_filterlists.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DandelionSprout/FilterLists/HEAD/imgs/logo_filterlists.png -------------------------------------------------------------------------------- /imgs/logo_filterlists.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DandelionSprout/FilterLists/HEAD/imgs/logo_filterlists.psd -------------------------------------------------------------------------------- /imgs/logo_lg_filterlists.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DandelionSprout/FilterLists/HEAD/imgs/logo_lg_filterlists.png -------------------------------------------------------------------------------- /src/FilterLists.Web/wwwroot/icon_filterlists.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DandelionSprout/FilterLists/HEAD/src/FilterLists.Web/wwwroot/icon_filterlists.png -------------------------------------------------------------------------------- /src/FilterLists.Web/wwwroot/logo_filterlists.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DandelionSprout/FilterLists/HEAD/src/FilterLists.Web/wwwroot/logo_filterlists.png -------------------------------------------------------------------------------- /src/FilterLists.Web/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @using FilterLists.Web 2 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 3 | @addTagHelper *, Microsoft.AspNetCore.SpaServices -------------------------------------------------------------------------------- /scripts/cron: -------------------------------------------------------------------------------- 1 | # FilterLists Capture Snapshots 2 | */1 * * * * nice -n 19 /usr/bin/flock -n /tmp/filterlistsagent.lockfile /var/www/api.filterlists/FilterLists.Agent > /dev/null 2>&1 -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Adding or Updating Data? 2 | 3 | Please use the the [data model documentation](https://github.com/collinbarrett/FilterLists/wiki/Data-Model_sidebar) to verify your updates conform to project standards. 4 | -------------------------------------------------------------------------------- /src/FilterLists.Data/Entities/Junctions/BaseJunction.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace FilterLists.Data.Entities.Junctions 4 | { 5 | public class BaseJunction 6 | { 7 | public DateTime CreatedDateUtc { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /scripts/sql/createDb.sql: -------------------------------------------------------------------------------- 1 | CREATE USER 'filterlists'@'localhost' IDENTIFIED BY 'password'; 2 | CREATE DATABASE filterlistsdata CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; 3 | GRANT ALL PRIVILEGES ON filterlistsdata.* TO 'filterlists'@'localhost'; 4 | FLUSH PRIVILEGES; -------------------------------------------------------------------------------- /src/FilterLists.Web/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewData["Title"] = "Subscriptions for uBlock Origin, Adblock Plus, AdGuard, ..."; 3 | } 4 |
Loading...
5 | @section scripts { 6 | 7 | } -------------------------------------------------------------------------------- /scripts/sql/snapshotTimeAnalysis.sql: -------------------------------------------------------------------------------- 1 | SELECT 2 | FilterListId, 3 | ModifiedDateUtc - CreatedDateUtc As ProcessingTimeSecs, 4 | CreatedDateUtc, 5 | ModifiedDateUtc, 6 | IsCompleted 7 | FROM snapshots 8 | WHERE ModifiedDateUtc - CreatedDateUtc > 30 OR IsCompleted = 0 9 | ORDER BY ProcessingTimeSecs DESC -------------------------------------------------------------------------------- /src/FilterLists.Data/Entities/BaseEntity.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace FilterLists.Data.Entities 4 | { 5 | public class BaseEntity 6 | { 7 | public uint Id { get; set; } 8 | public DateTime CreatedDateUtc { get; set; } 9 | public DateTime ModifiedDateUtc { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /src/FilterLists.Services/FilterList/ListLanguagesDto.cs: -------------------------------------------------------------------------------- 1 | using JetBrains.Annotations; 2 | 3 | namespace FilterLists.Services.FilterList 4 | { 5 | [UsedImplicitly] 6 | public class ListLanguagesDto 7 | { 8 | public string Name { get; set; } 9 | public string Iso6391 { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /src/FilterLists.Services/Snapshot/FilterListViewUrlDto.cs: -------------------------------------------------------------------------------- 1 | using JetBrains.Annotations; 2 | 3 | namespace FilterLists.Services.Snapshot 4 | { 5 | [UsedImplicitly] 6 | public class FilterListViewUrlDto 7 | { 8 | public uint Id { get; set; } 9 | public string ViewUrl { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Bug or Feature Request? 2 | 3 | No rules, just let us know what's up in your issue providing all the relevant details. 4 | 5 | ## Adding or Updating Lists? 6 | 7 | Please provide information for all of the fields described here: 8 | https://github.com/collinbarrett/FilterLists/wiki/Data-Model_sidebar 9 | -------------------------------------------------------------------------------- /src/FilterLists.Services/FilterList/ListLicenseDto.cs: -------------------------------------------------------------------------------- 1 | using JetBrains.Annotations; 2 | 3 | namespace FilterLists.Services.FilterList 4 | { 5 | [UsedImplicitly] 6 | public class ListLicenseDto 7 | { 8 | public string DescriptionUrl { get; set; } 9 | public string Name { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /src/FilterLists.Services/FilterList/MaintainerAdditionalListsDto.cs: -------------------------------------------------------------------------------- 1 | using JetBrains.Annotations; 2 | 3 | namespace FilterLists.Services.FilterList 4 | { 5 | [UsedImplicitly] 6 | public class MaintainerAdditionalListsDto 7 | { 8 | public uint Id { get; set; } 9 | public string Name { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /src/FilterLists.Services/FilterList/SyntaxSupportedSoftwareDto.cs: -------------------------------------------------------------------------------- 1 | using JetBrains.Annotations; 2 | 3 | namespace FilterLists.Services.FilterList 4 | { 5 | [UsedImplicitly] 6 | public class SyntaxSupportedSoftwareDto 7 | { 8 | public string HomeUrl { get; set; } 9 | public string Name { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /src/FilterLists.Data/Entities/Rule.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using FilterLists.Data.Entities.Junctions; 3 | 4 | namespace FilterLists.Data.Entities 5 | { 6 | public class Rule : BaseEntity 7 | { 8 | public string Raw { get; set; } 9 | public ICollection SnapshotRules { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /src/FilterLists.Web/ClientApp/routes.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { Route } from "react-router-dom"; 3 | import { Layout } from "./components/Layout"; 4 | import { Home } from "./components/Home"; 5 | 6 | export const routes = 7 | 8 | ; -------------------------------------------------------------------------------- /src/FilterLists.Services/Seed/Models/Junctions/ForkSeedDto.cs: -------------------------------------------------------------------------------- 1 | using JetBrains.Annotations; 2 | 3 | namespace FilterLists.Services.Seed.Models.Junctions 4 | { 5 | [UsedImplicitly] 6 | public class ForkSeedDto 7 | { 8 | public uint ForkFilterListId { get; set; } 9 | public uint UpstreamFilterListId { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /src/FilterLists.Services/Seed/Models/Junctions/SoftwareSyntaxSeedDto.cs: -------------------------------------------------------------------------------- 1 | using JetBrains.Annotations; 2 | 3 | namespace FilterLists.Services.Seed.Models.Junctions 4 | { 5 | [UsedImplicitly] 6 | public class SoftwareSyntaxSeedDto 7 | { 8 | public uint SoftwareId { get; set; } 9 | public uint SyntaxId { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /src/FilterLists.Services/Seed/Models/Junctions/MergeSeedDto.cs: -------------------------------------------------------------------------------- 1 | using JetBrains.Annotations; 2 | 3 | namespace FilterLists.Services.Seed.Models.Junctions 4 | { 5 | [UsedImplicitly] 6 | public class MergeSeedDto 7 | { 8 | public uint MergeFilterListId { get; set; } 9 | public uint UpstreamFilterListId { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /src/FilterLists.Services/Seed/Models/SyntaxSeedDto.cs: -------------------------------------------------------------------------------- 1 | using JetBrains.Annotations; 2 | 3 | namespace FilterLists.Services.Seed.Models 4 | { 5 | [UsedImplicitly] 6 | public class SyntaxSeedDto 7 | { 8 | public uint Id { get; set; } 9 | public string DefinitionUrl { get; set; } 10 | public string Name { get; set; } 11 | } 12 | } -------------------------------------------------------------------------------- /src/FilterLists.Services/Seed/Models/Junctions/FilterListLanguageSeedDto.cs: -------------------------------------------------------------------------------- 1 | using JetBrains.Annotations; 2 | 3 | namespace FilterLists.Services.Seed.Models.Junctions 4 | { 5 | [UsedImplicitly] 6 | public class FilterListLanguageSeedDto 7 | { 8 | public uint FilterListId { get; set; } 9 | public uint LanguageId { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /src/FilterLists.Services/Seed/Models/Junctions/FilterListMaintainerSeedDto.cs: -------------------------------------------------------------------------------- 1 | using JetBrains.Annotations; 2 | 3 | namespace FilterLists.Services.Seed.Models.Junctions 4 | { 5 | [UsedImplicitly] 6 | public class FilterListMaintainerSeedDto 7 | { 8 | public uint FilterListId { get; set; } 9 | public uint MaintainerId { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /src/FilterLists.Data/Entities/Junctions/SoftwareSyntax.cs: -------------------------------------------------------------------------------- 1 | namespace FilterLists.Data.Entities.Junctions 2 | { 3 | public class SoftwareSyntax : BaseJunction 4 | { 5 | public uint SoftwareId { get; set; } 6 | public Software Software { get; set; } 7 | public uint SyntaxId { get; set; } 8 | public Syntax Syntax { get; set; } 9 | } 10 | } -------------------------------------------------------------------------------- /src/FilterLists.Data/Entities/Junctions/FilterListLanguage.cs: -------------------------------------------------------------------------------- 1 | namespace FilterLists.Data.Entities.Junctions 2 | { 3 | public class FilterListLanguage : BaseJunction 4 | { 5 | public uint FilterListId { get; set; } 6 | public FilterList FilterList { get; set; } 7 | public uint LanguageId { get; set; } 8 | public Language Language { get; set; } 9 | } 10 | } -------------------------------------------------------------------------------- /src/FilterLists.Data/Entities/Junctions/Fork.cs: -------------------------------------------------------------------------------- 1 | namespace FilterLists.Data.Entities.Junctions 2 | { 3 | public class Fork : BaseJunction 4 | { 5 | public uint ForkFilterListId { get; set; } 6 | public FilterList ForkFilterList { get; set; } 7 | public uint UpstreamFilterListId { get; set; } 8 | public FilterList UpstreamFilterList { get; set; } 9 | } 10 | } -------------------------------------------------------------------------------- /src/FilterLists.Data/Entities/Junctions/Merge.cs: -------------------------------------------------------------------------------- 1 | namespace FilterLists.Data.Entities.Junctions 2 | { 3 | public class Merge : BaseJunction 4 | { 5 | public uint MergeFilterListId { get; set; } 6 | public FilterList MergeFilterList { get; set; } 7 | public uint UpstreamFilterListId { get; set; } 8 | public FilterList UpstreamFilterList { get; set; } 9 | } 10 | } -------------------------------------------------------------------------------- /src/FilterLists.Services/Service.cs: -------------------------------------------------------------------------------- 1 | using FilterLists.Data; 2 | using JetBrains.Annotations; 3 | 4 | namespace FilterLists.Services 5 | { 6 | [UsedImplicitly] 7 | public class Service 8 | { 9 | protected FilterListsDbContext DbContext; 10 | 11 | public Service(FilterListsDbContext dbContext) 12 | { 13 | DbContext = dbContext; 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/FilterLists.Web/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "module": "es2015", 5 | "moduleResolution": "node", 6 | "target": "es5", 7 | "jsx": "react", 8 | "sourceMap": true, 9 | "skipDefaultLibCheck": true, 10 | "strict": true, 11 | "types": ["webpack-env"] 12 | }, 13 | "exclude": [ 14 | "bin", 15 | "node_modules" 16 | ] 17 | } -------------------------------------------------------------------------------- /src/FilterLists.Data/Entities/Junctions/FilterListMaintainer.cs: -------------------------------------------------------------------------------- 1 | namespace FilterLists.Data.Entities.Junctions 2 | { 3 | public class FilterListMaintainer : BaseJunction 4 | { 5 | public uint FilterListId { get; set; } 6 | public FilterList FilterList { get; set; } 7 | public uint MaintainerId { get; set; } 8 | public Maintainer Maintainer { get; set; } 9 | } 10 | } -------------------------------------------------------------------------------- /src/FilterLists.Services/Seed/Models/SoftwareSeedDto.cs: -------------------------------------------------------------------------------- 1 | using JetBrains.Annotations; 2 | 3 | namespace FilterLists.Services.Seed.Models 4 | { 5 | [UsedImplicitly] 6 | public class SoftwareSeedDto 7 | { 8 | public uint Id { get; set; } 9 | public string DownloadUrl { get; set; } 10 | public string HomeUrl { get; set; } 11 | public string Name { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /src/FilterLists.Web/ClientApp/css/site.css: -------------------------------------------------------------------------------- 1 | body, h2, h3, h4, h5, blockquote { 2 | font-size: 16px; 3 | } 4 | 5 | .rt-tr { 6 | -ms-align-items: center; 7 | -o-align-items: center; 8 | -webkit-align-items: center; 9 | align-items: center; 10 | } 11 | 12 | .fl-btn-details-action { 13 | margin-bottom: .2rem; 14 | max-width: 90px; 15 | } 16 | 17 | .fl-description { 18 | margin: 0 0 .5rem; 19 | } -------------------------------------------------------------------------------- /src/FilterLists.Api/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "FilterLists.Api": { 4 | "commandName": "Project", 5 | "launchBrowser": true, 6 | "launchUrl": "http://localhost:5000/docs/index.html", 7 | "environmentVariables": { 8 | "ASPNETCORE_ENVIRONMENT": "Development" 9 | }, 10 | "applicationUrl": "http://localhost:5000/docs/index.html" 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /src/FilterLists.Services/FilterList/ListSyntaxDto.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using JetBrains.Annotations; 3 | 4 | namespace FilterLists.Services.FilterList 5 | { 6 | [UsedImplicitly] 7 | public class ListSyntaxDto 8 | { 9 | public string DefinitionUrl { get; set; } 10 | public string Name { get; set; } 11 | public IEnumerable SupportedSoftware { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /src/FilterLists.Services/Seed/Models/MaintainerSeedDto.cs: -------------------------------------------------------------------------------- 1 | using JetBrains.Annotations; 2 | 3 | namespace FilterLists.Services.Seed.Models 4 | { 5 | [UsedImplicitly] 6 | public class MaintainerSeedDto 7 | { 8 | public uint Id { get; set; } 9 | public string EmailAddress { get; set; } 10 | public string HomeUrl { get; set; } 11 | public string Name { get; set; } 12 | public string TwitterHandle { get; set; } 13 | } 14 | } -------------------------------------------------------------------------------- /src/FilterLists.Services/Seed/Models/LicenseSeedDto.cs: -------------------------------------------------------------------------------- 1 | using JetBrains.Annotations; 2 | 3 | namespace FilterLists.Services.Seed.Models 4 | { 5 | [UsedImplicitly] 6 | public class LicenseSeedDto 7 | { 8 | public uint Id { get; set; } 9 | public string DescriptionUrl { get; set; } 10 | public string Name { get; set; } 11 | public bool PermissiveAdaptation { get; set; } 12 | public bool PermissiveCommercial { get; set; } 13 | } 14 | } -------------------------------------------------------------------------------- /data/README.md: -------------------------------------------------------------------------------- 1 | ## Adding or Updating Lists 2 | 3 | To submit a new list or update data about an existing list, please submit a pull request to this directory in conjunction with the data model described [here](https://github.com/collinbarrett/FilterLists/wiki/Data-Model_sidebar). Alternatively, you can [open a new issue](https://github.com/collinbarrett/FilterLists/issues/new) providing information for all of the fields described in the [data model](https://github.com/collinbarrett/FilterLists/wiki/Data-Model_sidebar). -------------------------------------------------------------------------------- /src/FilterLists.Data/Entities/Software.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using FilterLists.Data.Entities.Junctions; 3 | using JetBrains.Annotations; 4 | 5 | namespace FilterLists.Data.Entities 6 | { 7 | [UsedImplicitly] 8 | public class Software : BaseEntity 9 | { 10 | public string DownloadUrl { get; set; } 11 | public string HomeUrl { get; set; } 12 | public string Name { get; set; } 13 | public ICollection SoftwareSyntaxes { get; set; } 14 | } 15 | } -------------------------------------------------------------------------------- /src/FilterLists.Data/Entities/License.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using JetBrains.Annotations; 3 | 4 | namespace FilterLists.Data.Entities 5 | { 6 | [UsedImplicitly] 7 | public class License : BaseEntity 8 | { 9 | public string DescriptionUrl { get; set; } 10 | public ICollection FilterLists { get; set; } 11 | public string Name { get; set; } 12 | public bool PermissiveAdaptation { get; set; } 13 | public bool PermissiveCommercial { get; set; } 14 | } 15 | } -------------------------------------------------------------------------------- /src/FilterLists.Data/Entities/Syntax.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using FilterLists.Data.Entities.Junctions; 3 | using JetBrains.Annotations; 4 | 5 | namespace FilterLists.Data.Entities 6 | { 7 | [UsedImplicitly] 8 | public class Syntax : BaseEntity 9 | { 10 | public string DefinitionUrl { get; set; } 11 | public ICollection FilterLists { get; set; } 12 | public string Name { get; set; } 13 | public ICollection SoftwareSyntaxes { get; set; } 14 | } 15 | } -------------------------------------------------------------------------------- /src/FilterLists.Web/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | using Microsoft.AspNetCore.Mvc; 3 | 4 | namespace FilterLists.Web.Controllers 5 | { 6 | public class HomeController : Controller 7 | { 8 | public IActionResult Index() 9 | { 10 | return View(); 11 | } 12 | 13 | public IActionResult Error() 14 | { 15 | ViewData["RequestId"] = Activity.Current?.Id ?? HttpContext.TraceIdentifier; 16 | return View(); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /src/FilterLists.Web/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "FilterLists.Web": { 3 | "commandName": "Project", 4 | "launchBrowser": true, 5 | "environmentVariables": { 6 | "ASPNETCORE_ENVIRONMENT": "Development" 7 | }, 8 | "applicationUrl": "http://localhost:5001/" 9 | }, 10 | "profiles": { 11 | "FilterLists.Web": { 12 | "commandName": "Project", 13 | "launchBrowser": true, 14 | "launchUrl": "http://localhost:5001/", 15 | "applicationUrl": "http://localhost:5001/" 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Adding or Updating Lists 2 | 3 | To submit a new list or update data about an existing list, please submit a pull request to [data](https://github.com/collinbarrett/FilterLists/tree/master/data) in conjunction with the data model described [here](https://github.com/collinbarrett/FilterLists/wiki/Data-Model_sidebar). Alternatively, you can [open a new issue](https://github.com/collinbarrett/FilterLists/issues/new) providing information for all of the fields described in the [data model](https://github.com/collinbarrett/FilterLists/wiki/Data-Model_sidebar). 4 | -------------------------------------------------------------------------------- /src/FilterLists.Data/Entities/Junctions/SnapshotRule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace FilterLists.Data.Entities.Junctions 4 | { 5 | public class SnapshotRule : BaseJunction 6 | { 7 | public DateTime ModifiedDateUtc { get; set; } 8 | public uint AddedBySnapshotId { get; set; } 9 | public Snapshot AddedBySnapshot { get; set; } 10 | public uint? RemovedBySnapshotId { get; set; } 11 | public Snapshot RemovedBySnapshot { get; set; } 12 | public uint RuleId { get; set; } 13 | public Rule Rule { get; set; } 14 | } 15 | } -------------------------------------------------------------------------------- /src/FilterLists.Data/Entities/Maintainer.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using FilterLists.Data.Entities.Junctions; 3 | using JetBrains.Annotations; 4 | 5 | namespace FilterLists.Data.Entities 6 | { 7 | [UsedImplicitly] 8 | public class Maintainer : BaseEntity 9 | { 10 | public string EmailAddress { get; set; } 11 | public ICollection FilterListMaintainers { get; set; } 12 | public string HomeUrl { get; set; } 13 | public string Name { get; set; } 14 | public string TwitterHandle { get; set; } 15 | } 16 | } -------------------------------------------------------------------------------- /src/FilterLists.Services/FilterList/ListSummaryDto.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using JetBrains.Annotations; 4 | 5 | namespace FilterLists.Services.FilterList 6 | { 7 | [UsedImplicitly] 8 | public class ListSummaryDto 9 | { 10 | public uint Id { get; set; } 11 | public DateTime AddedDate { get; set; } 12 | public IEnumerable Languages { get; set; } 13 | public string Name { get; set; } 14 | public DateTime? UpdatedDate { get; set; } 15 | public string ViewUrl { get; set; } 16 | } 17 | } -------------------------------------------------------------------------------- /src/FilterLists.Services/FilterList/ListMaintainerDto.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using JetBrains.Annotations; 3 | 4 | namespace FilterLists.Services.FilterList 5 | { 6 | [UsedImplicitly] 7 | public class ListMaintainerDto 8 | { 9 | public uint Id { get; set; } 10 | public string EmailAddress { get; set; } 11 | public string HomeUrl { get; set; } 12 | public string Name { get; set; } 13 | public string TwitterHandle { get; set; } 14 | public IEnumerable AdditionalLists { get; set; } 15 | } 16 | } -------------------------------------------------------------------------------- /src/FilterLists.Api/V1/Controllers/RulesController.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using FilterLists.Services; 3 | using Microsoft.AspNetCore.Mvc; 4 | 5 | namespace FilterLists.Api.V1.Controllers 6 | { 7 | public class RulesController : BaseController 8 | { 9 | private readonly RuleService _ruleService; 10 | 11 | public RulesController(RuleService ruleService) 12 | { 13 | _ruleService = ruleService; 14 | } 15 | 16 | [HttpGet] 17 | public async Task Index() => Json(await _ruleService.GetCountAll()); 18 | } 19 | } -------------------------------------------------------------------------------- /src/FilterLists.Data/Entities/Snapshot.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using FilterLists.Data.Entities.Junctions; 3 | 4 | namespace FilterLists.Data.Entities 5 | { 6 | public class Snapshot : BaseEntity 7 | { 8 | public uint FilterListId { get; set; } 9 | public FilterList FilterList { get; set; } 10 | public string HttpStatusCode { get; set; } 11 | public bool IsCompleted { get; set; } 12 | public ICollection AddedSnapshotRules { get; set; } 13 | public ICollection RemovedSnapshotRules { get; set; } 14 | } 15 | } -------------------------------------------------------------------------------- /src/FilterLists.Services/Seed/Models/LanguageSeedDto.cs: -------------------------------------------------------------------------------- 1 | using JetBrains.Annotations; 2 | 3 | namespace FilterLists.Services.Seed.Models 4 | { 5 | [UsedImplicitly] 6 | public class LanguageSeedDto 7 | { 8 | public uint Id { get; set; } 9 | public string Iso6391 { get; set; } 10 | public string Iso6392 { get; set; } 11 | public string Iso6392B { get; set; } 12 | public string Iso6392T { get; set; } 13 | public string Iso6393 { get; set; } 14 | public string LocalName { get; set; } 15 | public string Name { get; set; } 16 | } 17 | } -------------------------------------------------------------------------------- /src/FilterLists.Api/V1/Controllers/LicensesController.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using FilterLists.Data.Entities; 3 | using FilterLists.Services.Seed; 4 | using FilterLists.Services.Seed.Models; 5 | using Microsoft.AspNetCore.Mvc; 6 | 7 | namespace FilterLists.Api.V1.Controllers 8 | { 9 | public class LicensesController : BaseController 10 | { 11 | public LicensesController(SeedService seedService) : base(seedService) 12 | { 13 | } 14 | 15 | [HttpGet("seed")] 16 | public async Task Seed() => Json(await SeedService.GetAllAsync()); 17 | } 18 | } -------------------------------------------------------------------------------- /src/FilterLists.Api/V1/Controllers/SoftwareController.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using FilterLists.Data.Entities; 3 | using FilterLists.Services.Seed; 4 | using FilterLists.Services.Seed.Models; 5 | using Microsoft.AspNetCore.Mvc; 6 | 7 | namespace FilterLists.Api.V1.Controllers 8 | { 9 | public class SoftwareController : BaseController 10 | { 11 | public SoftwareController(SeedService seedService) : base(seedService) 12 | { 13 | } 14 | 15 | [HttpGet("seed")] 16 | public async Task Seed() => Json(await SeedService.GetAllAsync()); 17 | } 18 | } -------------------------------------------------------------------------------- /src/FilterLists.Api/V1/Controllers/SyntaxesController.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using FilterLists.Data.Entities; 3 | using FilterLists.Services.Seed; 4 | using FilterLists.Services.Seed.Models; 5 | using Microsoft.AspNetCore.Mvc; 6 | 7 | namespace FilterLists.Api.V1.Controllers 8 | { 9 | public class SyntaxesController : BaseController 10 | { 11 | public SyntaxesController(SeedService seedService) : base(seedService) 12 | { 13 | } 14 | 15 | [HttpGet("seed")] 16 | public async Task Seed() => Json(await SeedService.GetAllAsync()); 17 | } 18 | } -------------------------------------------------------------------------------- /src/FilterLists.Api/V1/Controllers/LanguagesController.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using FilterLists.Data.Entities; 3 | using FilterLists.Services.Seed; 4 | using FilterLists.Services.Seed.Models; 5 | using Microsoft.AspNetCore.Mvc; 6 | 7 | namespace FilterLists.Api.V1.Controllers 8 | { 9 | public class LanguagesController : BaseController 10 | { 11 | public LanguagesController(SeedService seedService) : base(seedService) 12 | { 13 | } 14 | 15 | [HttpGet("seed")] 16 | public async Task Seed() => Json(await SeedService.GetAllAsync()); 17 | } 18 | } -------------------------------------------------------------------------------- /src/FilterLists.Api/V1/Controllers/MaintainersController.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using FilterLists.Data.Entities; 3 | using FilterLists.Services.Seed; 4 | using FilterLists.Services.Seed.Models; 5 | using Microsoft.AspNetCore.Mvc; 6 | 7 | namespace FilterLists.Api.V1.Controllers 8 | { 9 | public class MaintainersController : BaseController 10 | { 11 | public MaintainersController(SeedService seedService) : base(seedService) 12 | { 13 | } 14 | 15 | [HttpGet("seed")] 16 | public async Task Seed() => Json(await SeedService.GetAllAsync()); 17 | } 18 | } -------------------------------------------------------------------------------- /src/FilterLists.Services/RuleService.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using FilterLists.Data; 3 | using JetBrains.Annotations; 4 | using Microsoft.EntityFrameworkCore; 5 | 6 | namespace FilterLists.Services 7 | { 8 | [UsedImplicitly] 9 | public class RuleService : Service 10 | { 11 | public RuleService(FilterListsDbContext dbContext) : base(dbContext) 12 | { 13 | DbContext = dbContext; 14 | } 15 | 16 | public async Task GetCountAll() => await DbContext 17 | .Rules.AsNoTracking() 18 | .CountAsync(); 19 | } 20 | } -------------------------------------------------------------------------------- /src/FilterLists.Data/Entities/Language.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using FilterLists.Data.Entities.Junctions; 3 | using JetBrains.Annotations; 4 | 5 | namespace FilterLists.Data.Entities 6 | { 7 | [UsedImplicitly] 8 | public class Language : BaseEntity 9 | { 10 | public ICollection FilterListLanguages { get; set; } 11 | public string Iso6391 { get; set; } 12 | public string Iso6392 { get; set; } 13 | public string Iso6392B { get; set; } 14 | public string Iso6392T { get; set; } 15 | public string Iso6393 { get; set; } 16 | public string LocalName { get; set; } 17 | public string Name { get; set; } 18 | } 19 | } -------------------------------------------------------------------------------- /src/FilterLists.Api/Migrations/20180324001253_addChatUrl.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | namespace FilterLists.Api.Migrations 4 | { 5 | public partial class addChatUrl : Migration 6 | { 7 | protected override void Up(MigrationBuilder migrationBuilder) 8 | { 9 | migrationBuilder.AddColumn( 10 | "ChatUrl", 11 | "filterlists", 12 | "TEXT", 13 | nullable: true); 14 | } 15 | 16 | protected override void Down(MigrationBuilder migrationBuilder) 17 | { 18 | migrationBuilder.DropColumn( 19 | "ChatUrl", 20 | "filterlists"); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /src/FilterLists.Api/V1/Controllers/BaseController.cs: -------------------------------------------------------------------------------- 1 | using FilterLists.Services.Seed; 2 | using Microsoft.AspNetCore.Mvc; 3 | 4 | namespace FilterLists.Api.V1.Controllers 5 | { 6 | [ApiVersion("1.0")] 7 | //TODO: use versioning without needing to manually specify in swagger-ui (https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/370) 8 | [Route("v{version:apiVersion}/[controller]")] 9 | public class BaseController : Controller 10 | { 11 | protected readonly SeedService SeedService; 12 | 13 | public BaseController() 14 | { 15 | } 16 | 17 | protected BaseController(SeedService seedService) 18 | { 19 | SeedService = seedService; 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /src/FilterLists.Api/V1/Controllers/ForksController.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using FilterLists.Data.Entities.Junctions; 3 | using FilterLists.Services.Seed; 4 | using FilterLists.Services.Seed.Models.Junctions; 5 | using Microsoft.AspNetCore.Mvc; 6 | 7 | namespace FilterLists.Api.V1.Controllers 8 | { 9 | public class ForksController : BaseController 10 | { 11 | public ForksController(SeedService seedService) : base(seedService) 12 | { 13 | } 14 | 15 | [HttpGet("seed")] 16 | public async Task Seed() => Json(await SeedService.GetAllAsync( 17 | typeof(Fork).GetProperty("UpstreamFilterListId"), typeof(Fork).GetProperty("ForkFilterListId"))); 18 | } 19 | } -------------------------------------------------------------------------------- /src/FilterLists.Web/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore; 2 | using Microsoft.AspNetCore.Hosting; 3 | 4 | namespace FilterLists.Web 5 | { 6 | public static class Program 7 | { 8 | public static void Main(string[] args) 9 | { 10 | CreateWebHostBuilder(args).Build().Run(); 11 | } 12 | 13 | private static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost 14 | .CreateDefaultBuilder(args) 15 | .UseUrls("http://localhost:5001;") 16 | .UseStartup(); 17 | } 18 | } -------------------------------------------------------------------------------- /src/FilterLists.Api/V1/Controllers/MergesController.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using FilterLists.Data.Entities.Junctions; 3 | using FilterLists.Services.Seed; 4 | using FilterLists.Services.Seed.Models.Junctions; 5 | using Microsoft.AspNetCore.Mvc; 6 | 7 | namespace FilterLists.Api.V1.Controllers 8 | { 9 | public class MergesController : BaseController 10 | { 11 | public MergesController(SeedService seedService) : base(seedService) 12 | { 13 | } 14 | 15 | [HttpGet("seed")] 16 | public async Task Seed() => Json(await SeedService.GetAllAsync( 17 | typeof(Merge).GetProperty("MergeFilterListId"), typeof(Merge).GetProperty("UpstreamFilterListId"))); 18 | } 19 | } -------------------------------------------------------------------------------- /src/FilterLists.Data/EntityTypeConfigurations/Junctions/BaseJunctionTypeConfiguration.cs: -------------------------------------------------------------------------------- 1 | using FilterLists.Data.Entities.Junctions; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace FilterLists.Data.EntityTypeConfigurations.Junctions 6 | { 7 | public class BaseJunctionTypeConfiguration : IEntityTypeConfiguration 8 | where TJunction : BaseJunction 9 | { 10 | public virtual void Configure(EntityTypeBuilder entityTypeBuilder) 11 | { 12 | entityTypeBuilder.Property(x => x.CreatedDateUtc) 13 | .HasColumnType("TIMESTAMP") 14 | .ValueGeneratedOnAdd(); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/FilterLists.Api/Migrations/20180210204923_AddIsCompletedFlagToSnapshot.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | namespace FilterLists.Api.Migrations 4 | { 5 | public partial class AddIsCompletedFlagToSnapshot : Migration 6 | { 7 | protected override void Up(MigrationBuilder migrationBuilder) 8 | { 9 | migrationBuilder.AddColumn( 10 | "IsCompleted", 11 | "snapshots", 12 | nullable: false, 13 | defaultValue: false); 14 | } 15 | 16 | protected override void Down(MigrationBuilder migrationBuilder) 17 | { 18 | migrationBuilder.DropColumn( 19 | "IsCompleted", 20 | "snapshots"); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /src/FilterLists.Api/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore; 2 | using Microsoft.AspNetCore.Hosting; 3 | 4 | namespace FilterLists.Api 5 | { 6 | public static class Program 7 | { 8 | public static void Main(string[] args) 9 | { 10 | CreateWebHostBuilder(args).Build().Run(); 11 | } 12 | 13 | private static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) 14 | .UseUrls("http://localhost:5000") 15 | .UseApplicationInsights() 16 | .UseStartup(); 17 | } 18 | } -------------------------------------------------------------------------------- /src/FilterLists.Api/appsettings.json: -------------------------------------------------------------------------------- 1 | /* 2 | WARNING - This file will be checked into source control. Do not change this file. 3 | Use this as an example file only. 4 | Use {env.EnvironmentName}.json as your configuration file as it will not be checked into source control. 5 | {env.EnvironmentName} values : development, staging, production 6 | */ 7 | { 8 | "ApplicationInsights": { 9 | "InstrumentationKey": "InstrumentationKeyValue" 10 | }, 11 | "ConnectionStrings": { 12 | "FilterListsConnection": "FilterListsConnectionValue" 13 | }, 14 | "DataDirectory": { 15 | "Path": "..\\..\\data" 16 | }, 17 | "Logging": { 18 | "IncludeScopes": false, 19 | "LogLevel": { 20 | "Default": "Debug", 21 | "System": "Information", 22 | "Microsoft": "Information" 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /data/SoftwareSyntax.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "softwareId": 1, 4 | "syntaxId": 4 5 | }, 6 | { 7 | "softwareId": 2, 8 | "syntaxId": 3 9 | }, 10 | { 11 | "softwareId": 3, 12 | "syntaxId": 6 13 | }, 14 | { 15 | "softwareId": 4, 16 | "syntaxId": 3 17 | }, 18 | { 19 | "softwareId": 5, 20 | "syntaxId": 4 21 | }, 22 | { 23 | "softwareId": 6, 24 | "syntaxId": 3 25 | }, 26 | { 27 | "softwareId": 7, 28 | "syntaxId": 1 29 | }, 30 | { 31 | "softwareId": 8, 32 | "syntaxId": 2 33 | }, 34 | { 35 | "softwareId": 9, 36 | "syntaxId": 2 37 | }, 38 | { 39 | "softwareId": 10, 40 | "syntaxId": 11 41 | }, 42 | { 43 | "softwareId": 11, 44 | "syntaxId": 1 45 | }, 46 | { 47 | "softwareId": 12, 48 | "syntaxId": 1 49 | } 50 | ] 51 | -------------------------------------------------------------------------------- /src/FilterLists.Api/V1/Controllers/SoftwareSyntaxesController.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using FilterLists.Data.Entities.Junctions; 3 | using FilterLists.Services.Seed; 4 | using FilterLists.Services.Seed.Models.Junctions; 5 | using Microsoft.AspNetCore.Mvc; 6 | 7 | namespace FilterLists.Api.V1.Controllers 8 | { 9 | public class SoftwareSyntaxesController : BaseController 10 | { 11 | public SoftwareSyntaxesController(SeedService seedService) : base(seedService) 12 | { 13 | } 14 | 15 | [HttpGet("seed")] 16 | public async Task Seed() => 17 | Json(await SeedService.GetAllAsync( 18 | typeof(SoftwareSyntax).GetProperty("SyntaxId"), typeof(SoftwareSyntax).GetProperty("SoftwareId"))); 19 | } 20 | } -------------------------------------------------------------------------------- /src/FilterLists.Api/V1/Controllers/ListsLanguagesController.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using FilterLists.Data.Entities.Junctions; 3 | using FilterLists.Services.Seed; 4 | using FilterLists.Services.Seed.Models.Junctions; 5 | using Microsoft.AspNetCore.Mvc; 6 | 7 | namespace FilterLists.Api.V1.Controllers 8 | { 9 | public class ListsLanguagesController : BaseController 10 | { 11 | public ListsLanguagesController(SeedService seedService) : base(seedService) 12 | { 13 | } 14 | 15 | [HttpGet("seed")] 16 | public async Task Seed() => 17 | Json(await SeedService.GetAllAsync( 18 | typeof(FilterListLanguage).GetProperty("FilterListId"), 19 | typeof(FilterListLanguage).GetProperty("LanguageId"))); 20 | } 21 | } -------------------------------------------------------------------------------- /src/FilterLists.Api/Migrations/20180210234702_AddSnapshotModifiedDateUtc.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.EntityFrameworkCore.Migrations; 3 | 4 | namespace FilterLists.Api.Migrations 5 | { 6 | public partial class AddSnapshotModifiedDateUtc : Migration 7 | { 8 | protected override void Up(MigrationBuilder migrationBuilder) 9 | { 10 | migrationBuilder.AddColumn( 11 | "ModifiedDateUtc", 12 | "snapshots", 13 | "TIMESTAMP", 14 | nullable: false, 15 | defaultValueSql: "CURRENT_TIMESTAMP()"); 16 | } 17 | 18 | protected override void Down(MigrationBuilder migrationBuilder) 19 | { 20 | migrationBuilder.DropColumn( 21 | "ModifiedDateUtc", 22 | "snapshots"); 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /src/FilterLists.Services/FilterList/FilterListServiceExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Threading.Tasks; 3 | 4 | namespace FilterLists.Services.FilterList 5 | { 6 | public static class FilterListServiceExtensions 7 | { 8 | public static async Task FilterParentListFromMaintainerAdditionalLists( 9 | this Task listDetailsDtos) 10 | { 11 | foreach (var maintainer in listDetailsDtos.Result.Maintainers) 12 | maintainer.AdditionalLists = maintainer 13 | .AdditionalLists.Where(additionalList => 14 | additionalList.Id != listDetailsDtos.Result.Id) 15 | .ToList(); 16 | return await listDetailsDtos; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /src/FilterLists.Api/V1/Controllers/ListsMaintainersController.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using FilterLists.Data.Entities.Junctions; 3 | using FilterLists.Services.Seed; 4 | using FilterLists.Services.Seed.Models.Junctions; 5 | using Microsoft.AspNetCore.Mvc; 6 | 7 | namespace FilterLists.Api.V1.Controllers 8 | { 9 | public class ListsMaintainersController : BaseController 10 | { 11 | public ListsMaintainersController(SeedService seedService) : base(seedService) 12 | { 13 | } 14 | 15 | [HttpGet("seed")] 16 | public async Task Seed() => Json( 17 | await SeedService.GetAllAsync( 18 | typeof(FilterListMaintainer).GetProperty("MaintainerId"), 19 | typeof(FilterListMaintainer).GetProperty("FilterListId"))); 20 | } 21 | } -------------------------------------------------------------------------------- /src/FilterLists.Web/ClientApp/boot.tsx: -------------------------------------------------------------------------------- 1 | import "./css/site.css"; 2 | import "bootstrap"; 3 | import * as React from "react"; 4 | import * as ReactDOM from "react-dom"; 5 | import { AppContainer } from "react-hot-loader"; 6 | import { BrowserRouter } from "react-router-dom"; 7 | import * as RoutesModule from "./routes"; 8 | let routes = RoutesModule.routes; 9 | 10 | function renderApp() { 11 | const baseUrl = document.getElementsByTagName("base")[0].getAttribute("href")!; 12 | ReactDOM.render( 13 | 14 | 15 | , 16 | document.getElementById("react-app") 17 | ); 18 | } 19 | 20 | renderApp(); 21 | 22 | if (module.hot) { 23 | module.hot.accept("./routes", 24 | () => { 25 | routes = require("./routes").routes; 26 | renderApp(); 27 | }); 28 | } -------------------------------------------------------------------------------- /src/FilterLists.Data/EntityTypeConfigurations/RuleTypeConfiguration.cs: -------------------------------------------------------------------------------- 1 | using FilterLists.Data.Entities; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace FilterLists.Data.EntityTypeConfigurations 6 | { 7 | public class RuleTypeConfiguration : BaseEntityTypeConfiguration 8 | { 9 | public override void Configure(EntityTypeBuilder entityTypeBuilder) 10 | { 11 | base.Configure(entityTypeBuilder); 12 | entityTypeBuilder.ToTable("rules"); 13 | entityTypeBuilder.Property(x => x.Id) 14 | .HasColumnType("INT UNSIGNED"); 15 | entityTypeBuilder.Ignore(x => x.ModifiedDateUtc); 16 | entityTypeBuilder.Property(x => x.Raw) 17 | .HasColumnType("VARCHAR(8192)") 18 | .IsRequired(); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /src/FilterLists.Web/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewData["Title"] = "Error"; 3 | } 4 | 5 |

Error.

6 |

An error occurred while processing your request.

7 | 8 | @if (!string.IsNullOrEmpty((string)ViewData["RequestId"])) 9 | { 10 |

11 | Request ID: @ViewData["RequestId"] 12 |

13 | } 14 | 15 |

Development Mode

16 |

17 | Swapping to Development environment will display more detailed information about the error that occurred. 18 |

19 |

20 | Development environment should not be enabled in deployed applications, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the ASPNETCORE_ENVIRONMENT environment variable to Development, and restarting the application. 21 |

-------------------------------------------------------------------------------- /src/FilterLists.Data/EntityTypeConfigurations/SyntaxTypeConfiguration.cs: -------------------------------------------------------------------------------- 1 | using FilterLists.Data.Entities; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace FilterLists.Data.EntityTypeConfigurations 6 | { 7 | public class SyntaxTypeConfiguration : BaseEntityTypeConfiguration 8 | { 9 | public override void Configure(EntityTypeBuilder entityTypeBuilder) 10 | { 11 | base.Configure(entityTypeBuilder); 12 | entityTypeBuilder.ToTable("syntaxes"); 13 | entityTypeBuilder.Property(x => x.Id) 14 | .HasColumnType("TINYINT UNSIGNED"); 15 | entityTypeBuilder.Property(x => x.DefinitionUrl) 16 | .HasColumnType("TEXT"); 17 | entityTypeBuilder.Property(x => x.Name) 18 | .HasColumnType("VARCHAR(126)") 19 | .IsRequired(); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /src/FilterLists.Data/EntityTypeConfigurations/LicenseTypeConfiguration.cs: -------------------------------------------------------------------------------- 1 | using FilterLists.Data.Entities; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace FilterLists.Data.EntityTypeConfigurations 6 | { 7 | public class LicenseTypeConfiguration : BaseEntityTypeConfiguration 8 | { 9 | public override void Configure(EntityTypeBuilder entityTypeBuilder) 10 | { 11 | base.Configure(entityTypeBuilder); 12 | entityTypeBuilder.ToTable("licenses"); 13 | entityTypeBuilder.Property(x => x.Id) 14 | .HasColumnType("TINYINT UNSIGNED"); 15 | entityTypeBuilder.Property(x => x.DescriptionUrl) 16 | .HasColumnType("TEXT"); 17 | entityTypeBuilder.Property(x => x.Name) 18 | .HasColumnType("VARCHAR(126)") 19 | .IsRequired(); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /src/FilterLists.Services/Extensions/EnumerableExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace FilterLists.Services.Extensions 4 | { 5 | public static class EnumerableExtensions 6 | { 7 | public static void AddRange(this ICollection destination, IEnumerable source) 8 | { 9 | foreach (var item in source) 10 | destination.Add(item); 11 | } 12 | 13 | public static IEnumerable> Batch(this IEnumerable source, int batchSize) 14 | { 15 | var batches = new List(batchSize); 16 | foreach (var item in source) 17 | { 18 | batches.Add(item); 19 | if (batches.Count != batchSize) 20 | continue; 21 | yield return batches.AsReadOnly(); 22 | batches = new List(batchSize); 23 | } 24 | 25 | if (batches.Count > 0) 26 | yield return batches.AsReadOnly(); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/FilterLists.Data/EntityTypeConfigurations/SnapshotTypeConfiguration.cs: -------------------------------------------------------------------------------- 1 | using FilterLists.Data.Entities; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace FilterLists.Data.EntityTypeConfigurations 6 | { 7 | public class SnapshotTypeConfiguration : BaseEntityTypeConfiguration 8 | { 9 | public override void Configure(EntityTypeBuilder entityTypeBuilder) 10 | { 11 | base.Configure(entityTypeBuilder); 12 | entityTypeBuilder.ToTable("snapshots"); 13 | entityTypeBuilder.Property(x => x.Id) 14 | .HasColumnType("MEDIUMINT UNSIGNED"); 15 | entityTypeBuilder.Property(x => x.ModifiedDateUtc) 16 | .HasDefaultValueSql("CURRENT_TIMESTAMP()"); 17 | entityTypeBuilder.Property(x => x.HttpStatusCode) 18 | .HasColumnType("VARCHAR(3)") 19 | .HasDefaultValueSql("NULL"); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /src/FilterLists.Data/EntityTypeConfigurations/BaseEntityTypeConfiguration.cs: -------------------------------------------------------------------------------- 1 | using FilterLists.Data.Entities; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace FilterLists.Data.EntityTypeConfigurations 6 | { 7 | public class BaseEntityTypeConfiguration : IEntityTypeConfiguration where TEntity : BaseEntity 8 | { 9 | public virtual void Configure(EntityTypeBuilder entityTypeBuilder) 10 | { 11 | entityTypeBuilder.Property(x => x.Id) 12 | .UseMySqlIdentityColumn() 13 | .HasColumnType("SMALLINT UNSIGNED"); 14 | entityTypeBuilder.Property(x => x.CreatedDateUtc) 15 | .HasColumnType("TIMESTAMP") 16 | .ValueGeneratedOnAdd(); 17 | entityTypeBuilder.Property(x => x.ModifiedDateUtc) 18 | .HasColumnType("TIMESTAMP") 19 | .ValueGeneratedOnAddOrUpdate(); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /src/FilterLists.Services/Seed/Models/FilterListSeedDto.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using JetBrains.Annotations; 3 | 4 | namespace FilterLists.Services.Seed.Models 5 | { 6 | [UsedImplicitly] 7 | public class FilterListSeedDto 8 | { 9 | public uint Id { get; set; } 10 | public string ChatUrl { get; set; } 11 | public string Description { get; set; } 12 | public string DescriptionSourceUrl { get; set; } 13 | public DateTime? DiscontinuedDate { get; set; } 14 | public string DonateUrl { get; set; } 15 | public string EmailAddress { get; set; } 16 | public string ForumUrl { get; set; } 17 | public string HomeUrl { get; set; } 18 | public string IssuesUrl { get; set; } 19 | public uint? LicenseId { get; set; } 20 | public string Name { get; set; } 21 | public string PolicyUrl { get; set; } 22 | public DateTime? PublishedDate { get; set; } 23 | public string SubmissionUrl { get; set; } 24 | public uint? SyntaxId { get; set; } 25 | public string ViewUrl { get; set; } 26 | } 27 | } -------------------------------------------------------------------------------- /src/FilterLists.Data/EntityTypeConfigurations/Junctions/SoftwareSyntaxTypeConfiguration.cs: -------------------------------------------------------------------------------- 1 | using FilterLists.Data.Entities.Junctions; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace FilterLists.Data.EntityTypeConfigurations.Junctions 6 | { 7 | public class SoftwareSyntaxTypeConfiguration : BaseJunctionTypeConfiguration 8 | { 9 | public override void Configure(EntityTypeBuilder entityTypeBuilder) 10 | { 11 | base.Configure(entityTypeBuilder); 12 | entityTypeBuilder.ToTable("software_syntaxes"); 13 | entityTypeBuilder.HasKey(x => new {x.SyntaxId, x.SoftwareId}); 14 | entityTypeBuilder.HasOne(x => x.Software) 15 | .WithMany(x => x.SoftwareSyntaxes) 16 | .HasForeignKey(x => x.SoftwareId); 17 | entityTypeBuilder.HasOne(x => x.Syntax) 18 | .WithMany(x => x.SoftwareSyntaxes) 19 | .HasForeignKey(x => x.SyntaxId); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /src/FilterLists.Data/EntityTypeConfigurations/SoftwareTypeConfiguration.cs: -------------------------------------------------------------------------------- 1 | using FilterLists.Data.Entities; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace FilterLists.Data.EntityTypeConfigurations 6 | { 7 | public class SoftwareTypeConfiguration : BaseEntityTypeConfiguration 8 | { 9 | public override void Configure(EntityTypeBuilder entityTypeBuilder) 10 | { 11 | base.Configure(entityTypeBuilder); 12 | entityTypeBuilder.ToTable("software"); 13 | entityTypeBuilder.Property(x => x.Id) 14 | .HasColumnType("TINYINT UNSIGNED"); 15 | entityTypeBuilder.Property(x => x.DownloadUrl) 16 | .HasColumnType("TEXT"); 17 | entityTypeBuilder.Property(x => x.HomeUrl) 18 | .HasColumnType("TEXT"); 19 | entityTypeBuilder.Property(x => x.Name) 20 | .HasColumnType("VARCHAR(126)") 21 | .IsRequired(); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /src/FilterLists.Data/EntityTypeConfigurations/Junctions/ForkTypeConfiguration.cs: -------------------------------------------------------------------------------- 1 | using FilterLists.Data.Entities.Junctions; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace FilterLists.Data.EntityTypeConfigurations.Junctions 6 | { 7 | public class ForkTypeConfiguration : BaseJunctionTypeConfiguration 8 | { 9 | public override void Configure(EntityTypeBuilder entityTypeBuilder) 10 | { 11 | base.Configure(entityTypeBuilder); 12 | entityTypeBuilder.ToTable("forks"); 13 | entityTypeBuilder.HasKey(x => new {x.ForkFilterListId, x.UpstreamFilterListId}); 14 | entityTypeBuilder.HasOne(x => x.ForkFilterList) 15 | .WithMany(x => x.ForkFilterLists) 16 | .HasForeignKey(x => x.ForkFilterListId); 17 | entityTypeBuilder.HasOne(x => x.UpstreamFilterList) 18 | .WithMany(x => x.UpstreamForkFilterLists) 19 | .HasForeignKey(x => x.UpstreamFilterListId); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /data/Fork.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "forkFilterListId": 7, 4 | "upstreamFilterListId": 9 5 | }, 6 | { 7 | "forkFilterListId": 8, 8 | "upstreamFilterListId": 9 9 | }, 10 | { 11 | "forkFilterListId": 16, 12 | "upstreamFilterListId": 59 13 | }, 14 | { 15 | "forkFilterListId": 16, 16 | "upstreamFilterListId": 99 17 | }, 18 | { 19 | "forkFilterListId": 16, 20 | "upstreamFilterListId": 278 21 | }, 22 | { 23 | "forkFilterListId": 158, 24 | "upstreamFilterListId": 258 25 | }, 26 | { 27 | "forkFilterListId": 163, 28 | "upstreamFilterListId": 262 29 | }, 30 | { 31 | "forkFilterListId": 164, 32 | "upstreamFilterListId": 293 33 | }, 34 | { 35 | "forkFilterListId": 166, 36 | "upstreamFilterListId": 301 37 | }, 38 | { 39 | "forkFilterListId": 167, 40 | "upstreamFilterListId": 295 41 | }, 42 | { 43 | "forkFilterListId": 312, 44 | "upstreamFilterListId": 311 45 | }, 46 | { 47 | "forkFilterListId": 313, 48 | "upstreamFilterListId": 311 49 | }, 50 | { 51 | "forkFilterListId": 350, 52 | "upstreamFilterListId": 12 53 | } 54 | ] -------------------------------------------------------------------------------- /src/FilterLists.Data/EntityTypeConfigurations/Junctions/MergeTypeConfiguration.cs: -------------------------------------------------------------------------------- 1 | using FilterLists.Data.Entities.Junctions; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace FilterLists.Data.EntityTypeConfigurations.Junctions 6 | { 7 | public class MergeTypeConfiguration : BaseJunctionTypeConfiguration 8 | { 9 | public override void Configure(EntityTypeBuilder entityTypeBuilder) 10 | { 11 | base.Configure(entityTypeBuilder); 12 | entityTypeBuilder.ToTable("merges"); 13 | entityTypeBuilder.HasKey(x => new {x.MergeFilterListId, x.UpstreamFilterListId}); 14 | entityTypeBuilder.HasOne(x => x.MergeFilterList) 15 | .WithMany(x => x.MergeFilterLists) 16 | .HasForeignKey(x => x.MergeFilterListId); 17 | entityTypeBuilder.HasOne(x => x.UpstreamFilterList) 18 | .WithMany(x => x.UpstreamMergeFilterLists) 19 | .HasForeignKey(x => x.UpstreamFilterListId); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Collin M. Barrett 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 | -------------------------------------------------------------------------------- /src/FilterLists.Data/EntityTypeConfigurations/Junctions/FilterListLanguageTypeConfiguration.cs: -------------------------------------------------------------------------------- 1 | using FilterLists.Data.Entities.Junctions; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace FilterLists.Data.EntityTypeConfigurations.Junctions 6 | { 7 | public class FilterListLanguageTypeConfiguration : BaseJunctionTypeConfiguration 8 | { 9 | public override void Configure(EntityTypeBuilder entityTypeBuilder) 10 | { 11 | base.Configure(entityTypeBuilder); 12 | entityTypeBuilder.ToTable("filterlists_languages"); 13 | entityTypeBuilder.HasKey(x => new {x.FilterListId, x.LanguageId}); 14 | entityTypeBuilder.HasOne(x => x.FilterList) 15 | .WithMany(x => x.FilterListLanguages) 16 | .HasForeignKey(x => x.FilterListId); 17 | entityTypeBuilder.HasOne(x => x.Language) 18 | .WithMany(x => x.FilterListLanguages) 19 | .HasForeignKey(x => x.LanguageId); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /src/FilterLists.Web/DependencyInjection/Extensions/ConfigureServicesCollection.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Builder; 2 | using Microsoft.AspNetCore.Http; 3 | using Microsoft.AspNetCore.Mvc; 4 | using Microsoft.Extensions.DependencyInjection; 5 | 6 | namespace FilterLists.Web.DependencyInjection.Extensions 7 | { 8 | public static class ConfigureServicesCollection 9 | { 10 | public static void AddFilterListsWeb(this IServiceCollection services) 11 | { 12 | services.ConfigureCookiePolicy(); 13 | services.AddMvcCustom(); 14 | } 15 | 16 | private static void ConfigureCookiePolicy(this IServiceCollection services) 17 | { 18 | services.Configure(options => 19 | { 20 | options.CheckConsentNeeded = context => true; 21 | options.MinimumSameSitePolicy = SameSiteMode.None; 22 | }); 23 | } 24 | 25 | private static void AddMvcCustom(this IServiceCollection services) 26 | { 27 | services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /src/FilterLists.Data/EntityTypeConfigurations/Junctions/FilterListMaintainerTypeConfiguration.cs: -------------------------------------------------------------------------------- 1 | using FilterLists.Data.Entities.Junctions; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace FilterLists.Data.EntityTypeConfigurations.Junctions 6 | { 7 | public class FilterListMaintainerTypeConfiguration : BaseJunctionTypeConfiguration 8 | { 9 | public override void Configure(EntityTypeBuilder entityTypeBuilder) 10 | { 11 | base.Configure(entityTypeBuilder); 12 | entityTypeBuilder.ToTable("filterlists_maintainers"); 13 | entityTypeBuilder.HasKey(x => new {x.FilterListId, x.MaintainerId}); 14 | entityTypeBuilder.HasOne(x => x.FilterList) 15 | .WithMany(x => x.FilterListMaintainers) 16 | .HasForeignKey(x => x.FilterListId); 17 | entityTypeBuilder.HasOne(x => x.Maintainer) 18 | .WithMany(x => x.FilterListMaintainers) 19 | .HasForeignKey(x => x.MaintainerId); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /src/FilterLists.Api/V1/Controllers/ListsController.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using FilterLists.Data.Entities; 3 | using FilterLists.Services.FilterList; 4 | using FilterLists.Services.Seed; 5 | using FilterLists.Services.Seed.Models; 6 | using Microsoft.AspNetCore.Mvc; 7 | 8 | namespace FilterLists.Api.V1.Controllers 9 | { 10 | public class ListsController : BaseController 11 | { 12 | private readonly FilterListService _filterListService; 13 | 14 | public ListsController(SeedService seedService, FilterListService filterListService) : base(seedService) 15 | { 16 | _filterListService = filterListService; 17 | } 18 | 19 | [HttpGet] 20 | public async Task Index() => Json(await _filterListService.GetAllSummariesAsync()); 21 | 22 | [HttpGet] 23 | [Route("{id}")] 24 | //TODO: respond with appropriate exception if negative id queried 25 | public async Task GetById(int id) => Json(await _filterListService.GetDetailsAsync((uint)id)); 26 | 27 | [HttpGet("seed")] 28 | public async Task Seed() => Json(await SeedService.GetAllAsync()); 29 | } 30 | } -------------------------------------------------------------------------------- /src/FilterLists.Data/EntityTypeConfigurations/MaintainerTypeConfiguration.cs: -------------------------------------------------------------------------------- 1 | using FilterLists.Data.Entities; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace FilterLists.Data.EntityTypeConfigurations 6 | { 7 | public class MaintainerTypeConfiguration : BaseEntityTypeConfiguration 8 | { 9 | public override void Configure(EntityTypeBuilder entityTypeBuilder) 10 | { 11 | base.Configure(entityTypeBuilder); 12 | entityTypeBuilder.ToTable("maintainers"); 13 | entityTypeBuilder.Property(x => x.EmailAddress) 14 | .HasColumnType("VARCHAR(126)") 15 | .HasDefaultValueSql("NULL"); 16 | entityTypeBuilder.Property(x => x.HomeUrl) 17 | .HasColumnType("TEXT"); 18 | entityTypeBuilder.Property(x => x.Name) 19 | .HasColumnType("VARCHAR(126)") 20 | .IsRequired(); 21 | entityTypeBuilder.Property(x => x.TwitterHandle) 22 | .HasColumnType("VARCHAR(126)") 23 | .HasDefaultValueSql("NULL"); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /src/FilterLists.Web/ClientApp/components/Layout.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | export interface ILayoutProps { 4 | children?: React.ReactNode; 5 | } 6 | 7 | export class Layout extends React.Component { 8 | render() { 9 | return
10 |
11 |

12 | 13 | FilterLists 14 | 15 |

16 |
17 |
18 |
19 | { this.props.children } 20 |
21 |
22 |
23 |

24 | API | GitHub | By Collin M. Barrett 25 |

26 |
27 |
; 28 | }; 29 | } -------------------------------------------------------------------------------- /src/FilterLists.Web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "filterlists", 3 | "private": true, 4 | "version": "0.0.0", 5 | "devDependencies": { 6 | "@types/history": "^4.6.2", 7 | "@types/react": "^16.4.6", 8 | "@types/react-dom": "^16.0.6", 9 | "@types/react-hot-loader": "^3.0.6", 10 | "@types/react-router": "^4.0.27", 11 | "@types/react-router-dom": "^4.2.7", 12 | "@types/webpack-env": "^1.13.6", 13 | "aspnet-webpack": "^2.0.3", 14 | "aspnet-webpack-react": "^3.0.0", 15 | "awesome-typescript-loader": "^4.0.1", 16 | "bootstrap": "^4.1.1", 17 | "css-loader": "^0.28.11", 18 | "event-source-polyfill": "0.0.12", 19 | "extract-text-webpack-plugin": "^3.0.2", 20 | "file-loader": "^1.1.11", 21 | "isomorphic-fetch": "2.2.1", 22 | "jquery": "^3.3.1", 23 | "json-loader": "^0.5.7", 24 | "react": "^16.4.1", 25 | "react-dom": "^16.4.1", 26 | "react-hot-loader": "^3.1.3", 27 | "react-router-dom": "^4.3.1", 28 | "style-loader": "^0.21.0", 29 | "typescript": "^2.9.2", 30 | "url-loader": "^1.0.1", 31 | "webpack": "^3.11.0", 32 | "webpack-hot-middleware": "^2.22.2" 33 | }, 34 | "dependencies": { 35 | "@types/react-table": "^6.7.11", 36 | "moment": "^2.22.2", 37 | "popper.js": "^1.14.3", 38 | "react-table": "^6.8.6" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/FilterLists.Web/Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | FilterLists | @ViewData["Title"] 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | @RenderBody() 17 | 18 | @RenderSection("scripts", false) 19 | 22 | 23 | -------------------------------------------------------------------------------- /src/FilterLists.Api/Migrations/20180214152734_AddPublishedDate.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.EntityFrameworkCore.Migrations; 3 | 4 | namespace FilterLists.Api.Migrations 5 | { 6 | public partial class AddPublishedDate : Migration 7 | { 8 | protected override void Up(MigrationBuilder migrationBuilder) 9 | { 10 | migrationBuilder.AlterColumn( 11 | "DiscontinuedDate", 12 | "filterlists", 13 | "DATE", 14 | nullable: true, 15 | oldClrType: typeof(DateTime), 16 | oldNullable: true); 17 | 18 | migrationBuilder.AddColumn( 19 | "PublishedDate", 20 | "filterlists", 21 | "DATE", 22 | nullable: true); 23 | } 24 | 25 | protected override void Down(MigrationBuilder migrationBuilder) 26 | { 27 | migrationBuilder.DropColumn( 28 | "PublishedDate", 29 | "filterlists"); 30 | 31 | migrationBuilder.AlterColumn( 32 | "DiscontinuedDate", 33 | "filterlists", 34 | nullable: true, 35 | oldClrType: typeof(DateTime), 36 | oldType: "DATE", 37 | oldNullable: true); 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /src/FilterLists.Services/FilterList/ListDetailsDto.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using JetBrains.Annotations; 4 | 5 | namespace FilterLists.Services.FilterList 6 | { 7 | [UsedImplicitly] 8 | public class ListDetailsDto 9 | { 10 | public uint Id { get; set; } 11 | public DateTime AddedDate { get; set; } 12 | public string ChatUrl { get; set; } 13 | public string Description { get; set; } 14 | public string DescriptionSourceUrl { get; set; } 15 | public DateTime? DiscontinuedDate { get; set; } 16 | public string DonateUrl { get; set; } 17 | public string EmailAddress { get; set; } 18 | public string ForumUrl { get; set; } 19 | public string HomeUrl { get; set; } 20 | public string IssuesUrl { get; set; } 21 | public IEnumerable Languages { get; set; } 22 | public ListLicenseDto License { get; set; } 23 | public IEnumerable Maintainers { get; set; } 24 | public string Name { get; set; } 25 | public string PolicyUrl { get; set; } 26 | public DateTime? PublishedDate { get; set; } 27 | public int RuleCount { get; set; } 28 | public string SubmissionUrl { get; set; } 29 | public ListSyntaxDto Syntax { get; set; } 30 | public DateTime? UpdatedDate { get; set; } 31 | public string ViewUrl { get; set; } 32 | } 33 | } -------------------------------------------------------------------------------- /src/FilterLists.Services/DependencyInjection/Extensions/ConfigureServicesCollection.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | using FilterLists.Data; 3 | using FilterLists.Services.FilterList; 4 | using FilterLists.Services.Seed; 5 | using FilterLists.Services.Snapshot; 6 | using Microsoft.EntityFrameworkCore; 7 | using Microsoft.Extensions.Configuration; 8 | using Microsoft.Extensions.DependencyInjection; 9 | using Microsoft.Extensions.DependencyInjection.Extensions; 10 | 11 | namespace FilterLists.Services.DependencyInjection.Extensions 12 | { 13 | public static class ConfigureServicesCollection 14 | { 15 | public static void AddFilterListsServices(this IServiceCollection services, IConfiguration configuration) 16 | { 17 | services.AddSingleton(c => configuration); 18 | services.AddEntityFrameworkMySql() 19 | .AddDbContextPool(options => 20 | options.UseMySql(configuration.GetConnectionString("FilterListsConnection"), 21 | b => b.MigrationsAssembly("FilterLists.Api")) 22 | .EnableSensitiveDataLogging()); 23 | services.TryAddScoped(); 24 | services.TryAddScoped(); 25 | services.TryAddScoped(); 26 | services.TryAddScoped(); 27 | services.AddAutoMapper(); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /src/FilterLists.Data/FilterLists.Data.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | ubuntu.16.04-x64 6 | Collin M. Barrett 7 | FilterLists 8 | The independent, comprehensive directory of filter and host lists for advertisements, trackers, malware, and annoyances. 9 | Copyright (c) 2018 Collin M. Barrett 10 | https://github.com/collinbarrett/FilterLists/blob/master/LICENSE 11 | https://filterlists.com/ 12 | https://github.com/collinbarrett/FilterLists/raw/master/imgs/icon_filterlists.png 13 | https://github.com/collinbarrett/FilterLists 14 | git 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /data/Syntax.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": 1, 4 | "definitionUrl": "https://en.wikipedia.org/wiki/Hosts_(file)", 5 | "name": "Hosts" 6 | }, 7 | { 8 | "id": 2, 9 | "definitionUrl": null, 10 | "name": "Domains" 11 | }, 12 | { 13 | "id": 3, 14 | "definitionUrl": "https://adblockplus.org/filters", 15 | "name": "Adblock Plus (Latest/Unspecified Version)" 16 | }, 17 | { 18 | "id": 4, 19 | "definitionUrl": "https://github.com/gorhill/uBlock/wiki/Static-filter-syntax", 20 | "name": "uBlock Origin Static" 21 | }, 22 | { 23 | "id": 6, 24 | "definitionUrl": "https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters", 25 | "name": "AdGuard" 26 | }, 27 | { 28 | "id": 7, 29 | "definitionUrl": "https://github.com/gorhill/uBlock/wiki/Dynamic-filtering:-quick-guide", 30 | "name": "uBlock Origin/uMatrix Dynamic" 31 | }, 32 | { 33 | "id": 8, 34 | "definitionUrl": null, 35 | "name": "URLs" 36 | }, 37 | { 38 | "id": 9, 39 | "definitionUrl": null, 40 | "name": "IPs" 41 | }, 42 | { 43 | "id": 10, 44 | "definitionUrl": "https://blogs.msdn.microsoft.com/ie/2010/12/07/ie9-and-privacy-introducing-tracking-protection/", 45 | "name": "Tracking Protection List (IE)" 46 | }, 47 | { 48 | "id": 11, 49 | "definitionUrl": null, 50 | "name": "JavaScript (Non-Safari)" 51 | }, 52 | { 53 | "id": 12, 54 | "definitionUrl": "https://github.com/NanoAdblocker/NanoCore/tree/master/notes", 55 | "name": "Nano Adblocker Static" 56 | } 57 | ] -------------------------------------------------------------------------------- /src/FilterLists.Services/Snapshot/RawRuleLinterExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace FilterLists.Services.Snapshot 2 | { 3 | public static class RawRuleLinterExtensions 4 | { 5 | public static string LintRawRule(this string rule) 6 | { 7 | rule = rule?.TrimLeadingAndTrailingWhitespace(); 8 | rule = rule?.DropIfEmpty(); 9 | rule = rule?.DropIfComment(); 10 | rule = rule?.DropIfTooLong(); 11 | rule = rule?.DropIfContainsBackslashSingleQuote(); 12 | rule = rule?.TrimSingleBackslashFromEnd(); 13 | return rule; 14 | } 15 | 16 | private static string TrimLeadingAndTrailingWhitespace(this string rule) 17 | { 18 | char[] charsToTrim = {' ', '\t'}; 19 | return rule.Trim(charsToTrim); 20 | } 21 | 22 | private static string DropIfEmpty(this string rule) => rule == "" ? null : rule; 23 | 24 | private static string DropIfComment(this string rule) => 25 | rule.StartsWith(@"!") && !rule.StartsWith(@"!#") || rule.StartsWith(@"!##") ? null : rule; 26 | 27 | private static string DropIfTooLong(this string rule) => rule.Length > 8192 ? null : rule; 28 | 29 | private static string DropIfContainsBackslashSingleQuote(this string rule) => 30 | rule.Contains(@"\'") ? null : rule; 31 | 32 | private static string TrimSingleBackslashFromEnd(this string rule) => 33 | rule.EndsWith(@"\") && !rule.EndsWith(@"\\") ? rule.Remove(rule.Length - 1) : rule; 34 | } 35 | } -------------------------------------------------------------------------------- /src/FilterLists.Data/EntityTypeConfigurations/Junctions/SnapshotRuleTypeConfiguration.cs: -------------------------------------------------------------------------------- 1 | using FilterLists.Data.Entities.Junctions; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace FilterLists.Data.EntityTypeConfigurations.Junctions 6 | { 7 | public class SnapshotRuleTypeConfiguration : BaseJunctionTypeConfiguration 8 | { 9 | public override void Configure(EntityTypeBuilder entityTypeBuilder) 10 | { 11 | base.Configure(entityTypeBuilder); 12 | entityTypeBuilder.ToTable("snapshots_rules"); 13 | entityTypeBuilder.HasKey(x => new {x.AddedBySnapshotId, x.RuleId}); 14 | entityTypeBuilder.Property(x => x.ModifiedDateUtc) 15 | .HasColumnType("TIMESTAMP") 16 | .ValueGeneratedOnAddOrUpdate(); 17 | entityTypeBuilder.HasOne(x => x.AddedBySnapshot) 18 | .WithMany(x => x.AddedSnapshotRules) 19 | .HasForeignKey(x => x.AddedBySnapshotId); 20 | entityTypeBuilder.HasOne(x => x.RemovedBySnapshot) 21 | .WithMany(x => x.RemovedSnapshotRules) 22 | .HasForeignKey(x => x.RemovedBySnapshotId) 23 | .OnDelete(DeleteBehavior.Cascade); 24 | entityTypeBuilder.HasOne(x => x.Rule) 25 | .WithMany(x => x.SnapshotRules) 26 | .HasForeignKey(x => x.RuleId); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/FilterLists.Web/Startup.cs: -------------------------------------------------------------------------------- 1 | using FilterLists.Web.DependencyInjection.Extensions; 2 | using JetBrains.Annotations; 3 | using Microsoft.AspNetCore.Builder; 4 | using Microsoft.AspNetCore.Hosting; 5 | using Microsoft.AspNetCore.SpaServices.Webpack; 6 | using Microsoft.Extensions.DependencyInjection; 7 | 8 | namespace FilterLists.Web 9 | { 10 | [UsedImplicitly] 11 | public class Startup 12 | { 13 | public void ConfigureServices(IServiceCollection services) 14 | { 15 | services.AddFilterListsWeb(); 16 | } 17 | 18 | public void Configure(IApplicationBuilder app, IHostingEnvironment env) 19 | { 20 | if (env.IsDevelopment()) 21 | { 22 | app.UseDeveloperExceptionPage(); 23 | app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions 24 | { 25 | HotModuleReplacement = true, 26 | ReactHotModuleReplacement = true 27 | }); 28 | } 29 | else 30 | { 31 | app.UseExceptionHandler("/Home/Error"); 32 | app.UseHsts(); 33 | } 34 | 35 | app.UseHttpsRedirection(); 36 | app.UseStaticFiles(); 37 | app.UseCookiePolicy(); 38 | app.UseMvc(routes => 39 | { 40 | routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}"); 41 | routes.MapSpaFallbackRoute("spa-fallback", new {controller = "Home", action = "Index"}); 42 | }); 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /src/FilterLists.Services/FilterLists.Services.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | ubuntu.16.04-x64 6 | Collin M. Barrett 7 | FilterLists 8 | The independent, comprehensive directory of filter and host lists for advertisements, trackers, malware, and annoyances. 9 | Copyright (c) 2018 Collin M. Barrett 10 | https://github.com/collinbarrett/FilterLists/blob/master/LICENSE 11 | https://github.com/collinbarrett/FilterLists/raw/master/imgs/icon_filterlists.png 12 | https://filterlists.com/ 13 | git 14 | https://github.com/collinbarrett/FilterLists 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /FilterLists.sln.DotSettings: -------------------------------------------------------------------------------- 1 | 5 | ExplicitlyExcluded 6 | 7 | True 8 | SOLUTION 9 | ECMAScript 2015 10 | Built-in: Full Cleanup 11 | ExpressionBody 12 | True 13 | CHOP_IF_LONG 14 | -------------------------------------------------------------------------------- /src/FilterLists.Services/FilterList/MappingProfiles.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using AutoMapper; 3 | using FilterLists.Data.Entities; 4 | 5 | namespace FilterLists.Services.FilterList 6 | { 7 | public class MappingProfiles : Profile 8 | { 9 | public MappingProfiles() 10 | { 11 | CreateMap() 12 | .ForMember(dto => dto.Languages, 13 | conf => conf.MapFrom(list => list.FilterListLanguages.Select(listLangs => listLangs.Language))) 14 | .ForMember(dto => dto.AddedDate, conf => conf.MapFrom(list => list.CreatedDateUtc)); 15 | CreateMap() 16 | .ForMember(dto => dto.Languages, 17 | conf => conf.MapFrom(list => list.FilterListLanguages.Select(listLangs => listLangs.Language.Name))) 18 | .ForMember(dto => dto.Maintainers, 19 | conf => conf.MapFrom(list => 20 | list.FilterListMaintainers.Select(listMaints => listMaints.Maintainer))) 21 | .ForMember(dto => dto.AddedDate, conf => conf.MapFrom(list => list.CreatedDateUtc)); 22 | CreateMap() 23 | .ForMember(dto => dto.AdditionalLists, 24 | conf => conf.MapFrom(maint => 25 | maint.FilterListMaintainers.Select(listMaints => listMaints.FilterList))); 26 | CreateMap() 27 | .ForMember(dto => dto.SupportedSoftware, 28 | conf => conf.MapFrom(syntax => syntax.SoftwareSyntaxes.Select(softSyn => softSyn.Software))); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /src/FilterLists.Data/Entities/FilterList.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using FilterLists.Data.Entities.Junctions; 4 | using JetBrains.Annotations; 5 | 6 | namespace FilterLists.Data.Entities 7 | { 8 | [UsedImplicitly] 9 | public class FilterList : BaseEntity 10 | { 11 | public string ChatUrl { get; set; } 12 | public string Description { get; set; } 13 | public string DescriptionSourceUrl { get; set; } 14 | public DateTime? DiscontinuedDate { get; set; } 15 | public string DonateUrl { get; set; } 16 | public string EmailAddress { get; set; } 17 | public ICollection ForkFilterLists { get; set; } 18 | public ICollection UpstreamForkFilterLists { get; set; } 19 | public string ForumUrl { get; set; } 20 | public string HomeUrl { get; set; } 21 | public string IssuesUrl { get; set; } 22 | public ICollection FilterListLanguages { get; set; } 23 | public uint? LicenseId { get; set; } 24 | public License License { get; set; } 25 | public ICollection FilterListMaintainers { get; set; } 26 | public ICollection MergeFilterLists { get; set; } 27 | public ICollection UpstreamMergeFilterLists { get; set; } 28 | public string Name { get; set; } 29 | public string PolicyUrl { get; set; } 30 | public DateTime? PublishedDate { get; set; } 31 | public ICollection Snapshots { get; set; } 32 | public string SubmissionUrl { get; set; } 33 | public uint? SyntaxId { get; set; } 34 | public Syntax Syntax { get; set; } 35 | public string ViewUrl { get; set; } 36 | } 37 | } -------------------------------------------------------------------------------- /src/FilterLists.Agent/FilterLists.Agent.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp2.1 6 | Collin M. Barrett 7 | Collin M. Barrett 8 | FilterLists 9 | The independent, comprehensive directory of filter and host lists for advertisements, trackers, malware, and annoyances. 10 | Copyright (c) 2018 Collin M. Barrett 11 | https://github.com/collinbarrett/FilterLists/blob/master/LICENSE 12 | https://github.com/collinbarrett/FilterLists/raw/master/imgs/icon_filterlists.png 13 | https://github.com/collinbarrett/FilterLists 14 | git 15 | https://filterlists.com/ 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/FilterLists.Data/EntityTypeConfigurations/LanguageTypeConfiguration.cs: -------------------------------------------------------------------------------- 1 | using FilterLists.Data.Entities; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace FilterLists.Data.EntityTypeConfigurations 6 | { 7 | public class LanguageTypeConfiguration : BaseEntityTypeConfiguration 8 | { 9 | public override void Configure(EntityTypeBuilder entityTypeBuilder) 10 | { 11 | base.Configure(entityTypeBuilder); 12 | entityTypeBuilder.ToTable("languages"); 13 | entityTypeBuilder.Property(x => x.Iso6391) 14 | .HasColumnType("VARCHAR(2)") 15 | .HasDefaultValueSql("NULL"); 16 | entityTypeBuilder.Property(x => x.Iso6392) 17 | .HasColumnType("VARCHAR(3)") 18 | .HasDefaultValueSql("NULL"); 19 | entityTypeBuilder.Property(x => x.Iso6392B) 20 | .HasColumnType("VARCHAR(3)") 21 | .HasDefaultValueSql("NULL"); 22 | entityTypeBuilder.Property(x => x.Iso6392T) 23 | .HasColumnType("VARCHAR(3)") 24 | .HasDefaultValueSql("NULL"); 25 | entityTypeBuilder.Property(x => x.Iso6393) 26 | .HasColumnType("VARCHAR(3)") 27 | .HasDefaultValueSql("NULL"); 28 | entityTypeBuilder.Property(x => x.LocalName) 29 | .HasColumnType("VARCHAR(126)") 30 | .HasDefaultValueSql("NULL"); 31 | entityTypeBuilder.Property(x => x.Name) 32 | .HasColumnType("VARCHAR(126)") 33 | .HasDefaultValueSql("NULL"); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /src/FilterLists.Services/Seed/SeedService.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using System.Reflection; 4 | using System.Threading.Tasks; 5 | using AutoMapper.QueryableExtensions; 6 | using FilterLists.Data; 7 | using JetBrains.Annotations; 8 | using Microsoft.EntityFrameworkCore; 9 | 10 | namespace FilterLists.Services.Seed 11 | { 12 | [UsedImplicitly] 13 | public class SeedService : Service 14 | { 15 | public SeedService(FilterListsDbContext dbContext) : base(dbContext) 16 | { 17 | DbContext = dbContext; 18 | } 19 | 20 | public async Task> GetAllAsync() where TEntity : class => 21 | await DbContext.Set().AsNoTracking().ProjectTo().ToArrayAsync(); 22 | 23 | public async Task> GetAllAsync(PropertyInfo primarySort) 24 | where TEntity : class 25 | { 26 | return await DbContext.Set() 27 | .OrderBy(x => primarySort.GetValue(x, null)) 28 | .AsNoTracking() 29 | .ProjectTo() 30 | .ToArrayAsync(); 31 | } 32 | 33 | public async Task> GetAllAsync(PropertyInfo primarySort, 34 | PropertyInfo secondarySort) where TEntity : class 35 | { 36 | return await DbContext.Set() 37 | .OrderBy(x => primarySort.GetValue(x, null)) 38 | .ThenBy(x => secondarySort.GetValue(x, null)) 39 | .AsNoTracking() 40 | .ProjectTo() 41 | .ToArrayAsync(); 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /src/FilterLists.Api/Migrations/20180213171240_AddDefaultLicenseId.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | namespace FilterLists.Api.Migrations 4 | { 5 | public partial class AddDefaultLicenseId : Migration 6 | { 7 | protected override void Up(MigrationBuilder migrationBuilder) 8 | { 9 | migrationBuilder.DropForeignKey( 10 | "FK_filterlists_licenses_LicenseId", 11 | "filterlists"); 12 | 13 | migrationBuilder.AlterColumn( 14 | "LicenseId", 15 | "filterlists", 16 | nullable: false, 17 | defaultValue: 5, 18 | oldClrType: typeof(int), 19 | oldNullable: true); 20 | 21 | migrationBuilder.AddForeignKey( 22 | "FK_filterlists_licenses_LicenseId", 23 | "filterlists", 24 | "LicenseId", 25 | "licenses", 26 | principalColumn: "Id", 27 | onDelete: ReferentialAction.Cascade); 28 | } 29 | 30 | protected override void Down(MigrationBuilder migrationBuilder) 31 | { 32 | migrationBuilder.DropForeignKey( 33 | "FK_filterlists_licenses_LicenseId", 34 | "filterlists"); 35 | 36 | migrationBuilder.AlterColumn( 37 | "LicenseId", 38 | "filterlists", 39 | nullable: true, 40 | oldClrType: typeof(int), 41 | oldDefaultValue: 5); 42 | 43 | migrationBuilder.AddForeignKey( 44 | "FK_filterlists_licenses_LicenseId", 45 | "filterlists", 46 | "LicenseId", 47 | "licenses", 48 | principalColumn: "Id", 49 | onDelete: ReferentialAction.Restrict); 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /src/FilterLists.Api/Migrations/20180214153140_DefaultOptionalDatesToNull.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.EntityFrameworkCore.Migrations; 3 | 4 | namespace FilterLists.Api.Migrations 5 | { 6 | public partial class DefaultOptionalDatesToNull : Migration 7 | { 8 | protected override void Up(MigrationBuilder migrationBuilder) 9 | { 10 | migrationBuilder.AlterColumn( 11 | "PublishedDate", 12 | "filterlists", 13 | "DATE", 14 | nullable: true, 15 | defaultValueSql: "NULL", 16 | oldClrType: typeof(DateTime), 17 | oldType: "DATE", 18 | oldNullable: true); 19 | 20 | migrationBuilder.AlterColumn( 21 | "DiscontinuedDate", 22 | "filterlists", 23 | "DATE", 24 | nullable: true, 25 | defaultValueSql: "NULL", 26 | oldClrType: typeof(DateTime), 27 | oldType: "DATE", 28 | oldNullable: true); 29 | } 30 | 31 | protected override void Down(MigrationBuilder migrationBuilder) 32 | { 33 | migrationBuilder.AlterColumn( 34 | "PublishedDate", 35 | "filterlists", 36 | "DATE", 37 | nullable: true, 38 | oldClrType: typeof(DateTime), 39 | oldType: "DATE", 40 | oldNullable: true, 41 | oldDefaultValueSql: "NULL"); 42 | 43 | migrationBuilder.AlterColumn( 44 | "DiscontinuedDate", 45 | "filterlists", 46 | "DATE", 47 | nullable: true, 48 | oldClrType: typeof(DateTime), 49 | oldType: "DATE", 50 | oldNullable: true, 51 | oldDefaultValueSql: "NULL"); 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /scripts/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | #TODO: purge target directory 4 | #https://github.com/collinbarrett/FilterLists/issues/135 5 | #rm -rf !(appsettings.json) 6 | 7 | #deploy seed data 8 | sshpass -p $FTP_PASSWORD scp -o StrictHostKeyChecking=no -r /home/travis/build/collinbarrett/FilterLists/data/ $FTP_USER@$FTP_HOST:$FTP_DIR 9 | 10 | #deploy Agent 11 | chmod 777 /home/travis/build/collinbarrett/FilterLists/src/FilterLists.Agent/bin/Release/netcoreapp2.1/ubuntu.16.04-x64/publish/FilterLists.Agent 12 | sshpass -p $FTP_PASSWORD scp -o StrictHostKeyChecking=no -r /home/travis/build/collinbarrett/FilterLists/src/FilterLists.Agent/bin/Release/netcoreapp2.1/ubuntu.16.04-x64/publish/* $FTP_USER@$FTP_HOST:$FTP_DIR 13 | 14 | #deploy API 15 | chmod a+x /home/travis/build/collinbarrett/FilterLists/src/FilterLists.Api/bin/Release/netcoreapp2.1/ubuntu.16.04-x64/publish/FilterLists.Api.dll 16 | sshpass -p $FTP_PASSWORD scp -o StrictHostKeyChecking=no -r /home/travis/build/collinbarrett/FilterLists/src/FilterLists.Api/bin/Release/netcoreapp2.1/ubuntu.16.04-x64/publish/* $FTP_USER@$FTP_HOST:$FTP_DIR 17 | sshpass -p $FTP_PASSWORD ssh -o StrictHostKeyChecking=no $FTP_USER@$FTP_HOST 'sudo systemctl restart filterlists.api.service' 18 | 19 | #deploy Web 20 | chmod a+x /home/travis/build/collinbarrett/FilterLists/src/FilterLists.Web/bin/Release/netcoreapp2.1/ubuntu.16.04-x64/publish/FilterLists.Web.dll 21 | sshpass -p $FTP_PASSWORD scp -o StrictHostKeyChecking=no -r /home/travis/build/collinbarrett/FilterLists/src/FilterLists.Web/bin/Release/netcoreapp2.1/ubuntu.16.04-x64/publish/* $FTP_USER@$FTP_HOST:$FTP_DIR 22 | sshpass -p $FTP_PASSWORD ssh -o StrictHostKeyChecking=no $FTP_USER@$FTP_HOST 'sudo systemctl restart filterlists.web.service' 23 | 24 | #purge CDN 25 | curl -X DELETE "https://api.cloudflare.com/client/v4/zones/$CF_FILTERLISTS_ZONE/purge_cache" -H "X-Auth-Email: $CF_EMAIL" -H "X-Auth-Key: $CF_GLOBAL_API_KEY" -H "Content-Type: application/json" --data '{"purge_everything":true}' 26 | sleep 30 27 | 28 | #prime app 29 | curl https://filterlists.com/ -------------------------------------------------------------------------------- /src/FilterLists.Services/Snapshot/SnapshotBatchDe.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using System.Threading.Tasks; 4 | using FilterLists.Data; 5 | using FilterLists.Data.Entities; 6 | using FilterLists.Data.Entities.Junctions; 7 | using FilterLists.Services.Extensions; 8 | 9 | namespace FilterLists.Services.Snapshot 10 | { 11 | public class SnapshotBatchDe 12 | { 13 | private readonly FilterListsDbContext _dbContext; 14 | private readonly IEnumerable _rawRules; 15 | private readonly Data.Entities.Snapshot _snapshot; 16 | private IQueryable _rules; 17 | 18 | public SnapshotBatchDe(FilterListsDbContext dbContext, Data.Entities.Snapshot snapshot, 19 | IEnumerable rawRules) 20 | { 21 | _dbContext = dbContext; 22 | _snapshot = snapshot; 23 | _rawRules = rawRules; 24 | } 25 | 26 | public async Task SaveSnapshotBatchAsync() 27 | { 28 | AddRules(); 29 | AddSnapshotRules(); 30 | await _dbContext.SaveChangesAsync(); 31 | } 32 | 33 | private void AddRules() 34 | { 35 | var existingRules = _dbContext.Rules.Where(rule => _rawRules.Contains(rule.Raw)); 36 | var newRawRules = _rawRules.Except(existingRules.Select(r => r.Raw)); 37 | var newRules = newRawRules.Select(newRawRule => new Rule {Raw = newRawRule}).ToList(); 38 | _dbContext.Rules.AddRange(newRules); 39 | _rules = existingRules.Concat(newRules); 40 | } 41 | 42 | private void AddSnapshotRules() 43 | { 44 | var snapshotRules = new List(); 45 | foreach (var rule in _rules) 46 | snapshotRules.Add(new SnapshotRule {Rule = rule}); 47 | if (_snapshot.AddedSnapshotRules == null) 48 | _snapshot.AddedSnapshotRules = new List(); 49 | _snapshot.AddedSnapshotRules.AddRange(snapshotRules); 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /src/FilterLists.Web/webpack.config.vendor.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const webpack = require("webpack"); 3 | const ExtractTextPlugin = require("extract-text-webpack-plugin"); 4 | 5 | module.exports = (env) => { 6 | const extractCSS = new ExtractTextPlugin("vendor.css"); 7 | const isDevBuild = !(env && env.prod); 8 | return [ 9 | { 10 | stats: { modules: false }, 11 | resolve: { 12 | extensions: [".js"] 13 | }, 14 | module: { 15 | rules: [ 16 | { test: /\.(png|woff|woff2|eot|ttf|svg)(\?|$)/, use: "url-loader?limit=100000" }, 17 | { 18 | test: /\.css(\?|$)/, 19 | use: extractCSS.extract([isDevBuild ? "css-loader" : "css-loader?minimize"]) 20 | } 21 | ] 22 | }, 23 | entry: { 24 | vendor: [ 25 | "bootstrap", "bootstrap/dist/css/bootstrap.css", "event-source-polyfill", "isomorphic-fetch", 26 | "react", "react-dom", "react-router-dom", "jquery" 27 | ], 28 | }, 29 | output: { 30 | path: path.join(__dirname, "wwwroot", "dist"), 31 | publicPath: "dist/", 32 | filename: "[name].js", 33 | library: "[name]_[hash]", 34 | }, 35 | plugins: [ 36 | extractCSS, 37 | new webpack.ProvidePlugin({ 38 | $: "jquery", 39 | jQuery: "jquery" 40 | }), // Maps these identifiers to the jQuery package (because Bootstrap expects it to be a global variable) 41 | new webpack.DllPlugin({ 42 | path: path.join(__dirname, "wwwroot", "dist", "[name]-manifest.json"), 43 | name: "[name]_[hash]" 44 | }), 45 | new webpack.DefinePlugin({ 46 | 'process.env.NODE_ENV': isDevBuild ? '"development"' : '"production"' 47 | }) 48 | ].concat(isDevBuild 49 | ? [] 50 | : [ 51 | new webpack.optimize.UglifyJsPlugin() 52 | ]) 53 | } 54 | ]; 55 | }; -------------------------------------------------------------------------------- /data/Software.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": 1, 4 | "downloadUrl": "https://github.com/gorhill/uBlock#installation", 5 | "homeUrl": "https://github.com/gorhill/uBlock", 6 | "name": "uBlock Origin" 7 | }, 8 | { 9 | "id": 2, 10 | "downloadUrl": "https://adblockplus.org/", 11 | "homeUrl": "https://adblockplus.org/", 12 | "name": "Adblock Plus" 13 | }, 14 | { 15 | "id": 3, 16 | "downloadUrl": "https://adguard.com/en/download.html", 17 | "homeUrl": "https://adguard.com/", 18 | "name": "AdGuard" 19 | }, 20 | { 21 | "id": 4, 22 | "downloadUrl": "https://f-droid.org/packages/org.jak_linux.dns66/", 23 | "homeUrl": "https://github.com/julian-klode/dns66", 24 | "name": "DNS66" 25 | }, 26 | { 27 | "id": 5, 28 | "downloadUrl": "https://github.com/NanoAdblocker/NanoCore#nano-adblocker-core", 29 | "homeUrl": "https://github.com/NanoAdblocker/NanoCore", 30 | "name": "Nano Adblocker" 31 | }, 32 | { 33 | "id": 6, 34 | "downloadUrl": "https://getadblock.com/", 35 | "homeUrl": "https://getadblock.com/", 36 | "name": "AdBlock" 37 | }, 38 | { 39 | "id": 7, 40 | "downloadUrl": "https://f-droid.org/packages/org.adaway/", 41 | "homeUrl": "https://adaway.org/", 42 | "name": "AdAway" 43 | }, 44 | { 45 | "id": 8, 46 | "downloadUrl": "https://chrome.google.com/webstore/detail/personal-blocklist-by-goo/nolijncfnkgaikbjbdaogikpmpbdcdef", 47 | "homeUrl": "https://chrome.google.com/webstore/detail/personal-blocklist-by-goo/nolijncfnkgaikbjbdaogikpmpbdcdef", 48 | "name": "Personal Blocklist (Chrome)" 49 | }, 50 | { 51 | "id": 9, 52 | "downloadUrl": "https://addons.mozilla.org/firefox/addon/personal-blocklist/", 53 | "homeUrl": "https://github.com/wildskyf/personal-blocklist", 54 | "name": "Personal Blocklist (Firefox)" 55 | }, 56 | { 57 | "id": 10, 58 | "downloadUrl": "http://einaregilsson.com/redirector/", 59 | "homeUrl": "http://einaregilsson.com/redirector/", 60 | "name": "Redirector" 61 | }, 62 | { 63 | "id": 11, 64 | "downloadUrl": "https://github.com/scottlerch/HostsFileEditor/releases", 65 | "homeUrl": "https://scottlerch.github.io/HostsFileEditor/", 66 | "name": "Hosts File Editor" 67 | }, 68 | { 69 | "id": 12, 70 | "downloadUrl": "https://github.com/2ndalpha/gasmask/releases", 71 | "homeUrl": "https://github.com/2ndalpha/gasmask", 72 | "name": "Gas Mask" 73 | } 74 | ] 75 | -------------------------------------------------------------------------------- /src/FilterLists.Data/EntityTypeConfigurations/FilterListTypeConfiguration.cs: -------------------------------------------------------------------------------- 1 | using FilterLists.Data.Entities; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace FilterLists.Data.EntityTypeConfigurations 6 | { 7 | public class FilterListTypeConfiguration : BaseEntityTypeConfiguration 8 | { 9 | public override void Configure(EntityTypeBuilder entityTypeBuilder) 10 | { 11 | base.Configure(entityTypeBuilder); 12 | entityTypeBuilder.ToTable("filterlists"); 13 | entityTypeBuilder.Property(x => x.ChatUrl) 14 | .HasColumnType("TEXT"); 15 | entityTypeBuilder.Property(x => x.Description) 16 | .HasColumnType("TEXT"); 17 | entityTypeBuilder.Property(x => x.DescriptionSourceUrl) 18 | .HasColumnType("TEXT"); 19 | entityTypeBuilder.Property(x => x.DiscontinuedDate) 20 | .HasColumnType("DATE") 21 | .HasDefaultValueSql("NULL"); ; 22 | entityTypeBuilder.Property(x => x.DonateUrl) 23 | .HasColumnType("TEXT"); 24 | entityTypeBuilder.Property(x => x.EmailAddress) 25 | .HasColumnType("VARCHAR(126)") 26 | .HasDefaultValueSql("NULL"); 27 | entityTypeBuilder.Property(x => x.ForumUrl) 28 | .HasColumnType("TEXT"); 29 | entityTypeBuilder.Property(x => x.HomeUrl) 30 | .HasColumnType("TEXT"); 31 | entityTypeBuilder.Property(x => x.IssuesUrl) 32 | .HasColumnType("TEXT"); 33 | entityTypeBuilder.Property(x => x.LicenseId) 34 | .HasDefaultValue((uint)5) 35 | .IsRequired(); 36 | entityTypeBuilder.Property(x => x.Name) 37 | .HasColumnType("VARCHAR(126)") 38 | .IsRequired(); 39 | entityTypeBuilder.Property(x => x.PolicyUrl) 40 | .HasColumnType("TEXT"); 41 | entityTypeBuilder.Property(x => x.PublishedDate) 42 | .HasColumnType("DATE") 43 | .HasDefaultValueSql("NULL"); ; 44 | entityTypeBuilder.Property(x => x.SubmissionUrl) 45 | .HasColumnType("TEXT"); 46 | entityTypeBuilder.Property(x => x.ViewUrl) 47 | .HasColumnType("TEXT"); 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /src/FilterLists.Agent/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using FilterLists.Services.DependencyInjection.Extensions; 4 | using FilterLists.Services.Snapshot; 5 | using Microsoft.ApplicationInsights; 6 | using Microsoft.ApplicationInsights.Extensibility; 7 | using Microsoft.Extensions.Configuration; 8 | using Microsoft.Extensions.DependencyInjection; 9 | 10 | namespace FilterLists.Agent 11 | { 12 | public static class Program 13 | { 14 | private const int BatchSize = 1; 15 | private static TelemetryClient _telemetryClient; 16 | private static ServiceProvider _serviceProvider; 17 | private static IConfigurationRoot _configurationRoot; 18 | 19 | public static int Main() 20 | { 21 | InstantiateConfigurationRoot(); 22 | InstantiateTelemetryClient(); 23 | InstantiateServiceProvider(); 24 | CaptureSnapshots(BatchSize); 25 | return 0; 26 | } 27 | 28 | private static void InstantiateConfigurationRoot() 29 | { 30 | _configurationRoot = new ConfigurationBuilder() 31 | .SetBasePath(Directory.GetCurrentDirectory()) 32 | .AddJsonFile("appsettings.json", false, true) 33 | .Build(); 34 | } 35 | 36 | private static void InstantiateTelemetryClient() 37 | { 38 | TelemetryConfiguration.Active.InstrumentationKey = 39 | _configurationRoot["ApplicationInsights:InstrumentationKey"]; 40 | _telemetryClient = new TelemetryClient(); 41 | } 42 | 43 | private static void InstantiateServiceProvider() 44 | { 45 | var serviceCollection = new ServiceCollection(); 46 | ConfigureServices(serviceCollection); 47 | _serviceProvider = serviceCollection.BuildServiceProvider(); 48 | } 49 | 50 | private static void ConfigureServices(IServiceCollection serviceCollection) 51 | { 52 | serviceCollection.AddFilterListsServices(_configurationRoot); 53 | } 54 | 55 | private static void CaptureSnapshots(int batchSize) 56 | { 57 | var snapshotService = _serviceProvider.GetService(); 58 | Log("Capturing FilterList snapshots..."); 59 | snapshotService.CaptureAsync(batchSize).Wait(); 60 | Log("\nSnapshots captured."); 61 | _telemetryClient.Flush(); 62 | } 63 | 64 | private static void Log(string message) 65 | { 66 | Console.WriteLine(message); 67 | _telemetryClient.TrackTrace(message); 68 | } 69 | } 70 | } -------------------------------------------------------------------------------- /src/FilterLists.Api/FilterLists.Api.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.1 5 | ubuntu.16.04-x64 6 | /subscriptions/4bcbdfe1-6c65-4c02-820f-7c0e7ec5614f/resourcegroups/FilterLists/providers/microsoft.insights/components/FilterLists 7 | /subscriptions/4bcbdfe1-6c65-4c02-820f-7c0e7ec5614f/resourcegroups/FilterLists/providers/microsoft.insights/components/FilterLists 8 | Collin M. Barrett 9 | Collin M. Barrett 10 | FilterLists 11 | The independent, comprehensive directory of filter and host lists for advertisements, trackers, malware, and annoyances. 12 | Copyright (c) 2018 Collin M. Barrett 13 | https://github.com/collinbarrett/FilterLists/blob/master/LICENSE 14 | https://filterlists.com/ 15 | https://github.com/collinbarrett/FilterLists/raw/master/imgs/icon_filterlists.png 16 | git 17 | https://github.com/collinbarrett/FilterLists 18 | 19 | 20 | 21 | bin\Debug\netcoreapp2.0\FilterLists.Api.xml 22 | 1701;1702;1705;1591 23 | 24 | 25 | 26 | bin\Release\netcoreapp2.0\FilterLists.Api.xml 27 | 1701;1702;1705;1591 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /src/FilterLists.Web/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const webpack = require("webpack"); 3 | const ExtractTextPlugin = require("extract-text-webpack-plugin"); 4 | const CheckerPlugin = require("awesome-typescript-loader").CheckerPlugin; 5 | const bundleOutputDir = "./wwwroot/dist"; 6 | 7 | module.exports = (env) => { 8 | const isDevBuild = !(env && env.prod); 9 | return [ 10 | { 11 | stats: { modules: false }, 12 | entry: { 'main': "./ClientApp/boot.tsx" }, 13 | resolve: { extensions: [".js", ".jsx", ".ts", ".tsx"] }, 14 | output: { 15 | path: path.join(__dirname, bundleOutputDir), 16 | filename: "[name].js", 17 | publicPath: "dist/" 18 | }, 19 | module: { 20 | rules: [ 21 | { test: /\.tsx?$/, include: /ClientApp/, use: "awesome-typescript-loader?silent=true" }, 22 | { 23 | test: /\.css$/, 24 | use: isDevBuild 25 | ? ["style-loader", "css-loader"] 26 | : ExtractTextPlugin.extract({ 27 | use: [ 28 | { 29 | loader: "css-loader", 30 | options: { 31 | minimize: { discardComments: { removeAll: true } } 32 | } 33 | } 34 | ] 35 | }) 36 | }, 37 | { test: /\.(png|jpg|jpeg|gif|svg)$/, use: "url-loader?limit=25000" } 38 | ] 39 | }, 40 | plugins: [ 41 | new CheckerPlugin(), 42 | new webpack.DllReferencePlugin({ 43 | context: __dirname, 44 | manifest: require("./wwwroot/dist/vendor-manifest.json") 45 | }) 46 | ].concat(isDevBuild 47 | ? [ 48 | new webpack.SourceMapDevToolPlugin({ 49 | filename: "[file].map", 50 | moduleFilenameTemplate: 51 | path.relative(bundleOutputDir, 52 | "[resourcePath]") 53 | }) 54 | ] 55 | : [ 56 | new webpack.optimize.UglifyJsPlugin({ 57 | output: { 58 | comments: false 59 | } 60 | }), 61 | new ExtractTextPlugin("site.css") 62 | ]) 63 | } 64 | ]; 65 | }; -------------------------------------------------------------------------------- /src/FilterLists.Services/Snapshot/SnapshotService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using AutoMapper.QueryableExtensions; 6 | using FilterLists.Data; 7 | using JetBrains.Annotations; 8 | using Microsoft.EntityFrameworkCore; 9 | 10 | namespace FilterLists.Services.Snapshot 11 | { 12 | [UsedImplicitly] 13 | public class SnapshotService : Service 14 | { 15 | //TODO: update algorithm to support non-standard list sizes and formats (#200, #201) 16 | private readonly List _ignoreLists = new List {48, 149, 173, 185, 186, 187, 188, 189, 352}; 17 | 18 | public SnapshotService(FilterListsDbContext dbContext) : base(dbContext) 19 | { 20 | DbContext = dbContext; 21 | } 22 | 23 | public async Task CaptureAsync(int batchSize) 24 | { 25 | RollbackIncompletedSnapshots(); 26 | var lists = await GetListsToCapture(batchSize); 27 | var snapshots = GetSnapshots(lists); 28 | await SaveSnapshots(snapshots); 29 | } 30 | 31 | private void RollbackIncompletedSnapshots() 32 | { 33 | var incompleteSnapshots = DbContext.Snapshots.Where(ss => ss.IsCompleted == false); 34 | DbContext.Snapshots.RemoveRange(incompleteSnapshots); 35 | //TODO: don't assume that SnapshotDe.DedupSnapshotRules() didn't partially complete 36 | } 37 | 38 | private async Task> GetListsToCapture(int batchSize) 39 | { 40 | return await DbContext 41 | .FilterLists 42 | .Where(list => 43 | (!list.Snapshots.Any() || 44 | list.Snapshots.Select(ss => ss.CreatedDateUtc) 45 | .OrderByDescending(sscd => sscd) 46 | .FirstOrDefault() < DateTime.UtcNow.AddDays(-1)) && !_ignoreLists.Contains(list.Id)) 47 | .OrderBy(list => list.Snapshots.Any()) 48 | .ThenBy(list => 49 | list.Snapshots.Select(ss => ss.CreatedDateUtc) 50 | .OrderByDescending(sscd => sscd) 51 | .FirstOrDefault()) 52 | .Take(batchSize) 53 | .AsNoTracking() 54 | .ProjectTo() 55 | .ToListAsync(); 56 | } 57 | 58 | private IEnumerable GetSnapshots(IEnumerable lists) 59 | { 60 | return lists.Select(list => new SnapshotDe(DbContext, list)); 61 | } 62 | 63 | private static async Task SaveSnapshots(IEnumerable snapshots) 64 | { 65 | foreach (var snapshot in snapshots) 66 | await snapshot.SaveSnapshotAsync(); 67 | } 68 | } 69 | } -------------------------------------------------------------------------------- /src/FilterLists.Data/FilterListsDbContext.cs: -------------------------------------------------------------------------------- 1 | using FilterLists.Data.Entities; 2 | using FilterLists.Data.Entities.Junctions; 3 | using FilterLists.Data.EntityTypeConfigurations; 4 | using FilterLists.Data.EntityTypeConfigurations.Junctions; 5 | using Microsoft.EntityFrameworkCore; 6 | 7 | namespace FilterLists.Data 8 | { 9 | public class FilterListsDbContext : DbContext 10 | { 11 | public FilterListsDbContext(DbContextOptions options) : base(options) 12 | { 13 | } 14 | 15 | protected override void OnModelCreating(ModelBuilder modelBuilder) 16 | { 17 | base.OnModelCreating(modelBuilder); 18 | ApplyConfigurationsEntities(modelBuilder); 19 | ApplyConfigurationsJunctions(modelBuilder); 20 | } 21 | 22 | #region Entities 23 | 24 | private static void ApplyConfigurationsEntities(ModelBuilder modelBuilder) 25 | { 26 | modelBuilder.ApplyConfiguration(new FilterListTypeConfiguration()); 27 | modelBuilder.ApplyConfiguration(new LanguageTypeConfiguration()); 28 | modelBuilder.ApplyConfiguration(new LicenseTypeConfiguration()); 29 | modelBuilder.ApplyConfiguration(new MaintainerTypeConfiguration()); 30 | modelBuilder.ApplyConfiguration(new RuleTypeConfiguration()); 31 | modelBuilder.ApplyConfiguration(new SnapshotTypeConfiguration()); 32 | modelBuilder.ApplyConfiguration(new SoftwareTypeConfiguration()); 33 | modelBuilder.ApplyConfiguration(new SyntaxTypeConfiguration()); 34 | } 35 | 36 | public DbSet FilterLists { get; set; } 37 | public DbSet Languages { get; set; } 38 | public DbSet Licenses { get; set; } 39 | public DbSet Maintainers { get; set; } 40 | public DbSet Rules { get; set; } 41 | public DbSet Snapshots { get; set; } 42 | public DbSet Software { get; set; } 43 | public DbSet Syntaxes { get; set; } 44 | 45 | #endregion 46 | 47 | #region Junctions 48 | 49 | private static void ApplyConfigurationsJunctions(ModelBuilder modelBuilder) 50 | { 51 | modelBuilder.ApplyConfiguration(new FilterListLanguageTypeConfiguration()); 52 | modelBuilder.ApplyConfiguration(new FilterListMaintainerTypeConfiguration()); 53 | modelBuilder.ApplyConfiguration(new ForkTypeConfiguration()); 54 | modelBuilder.ApplyConfiguration(new MergeTypeConfiguration()); 55 | modelBuilder.ApplyConfiguration(new SnapshotRuleTypeConfiguration()); 56 | modelBuilder.ApplyConfiguration(new SoftwareSyntaxTypeConfiguration()); 57 | } 58 | 59 | public DbSet FilterListLanguages { get; set; } 60 | public DbSet FilterListMaintainers { get; set; } 61 | public DbSet Forks { get; set; } 62 | public DbSet Merges { get; set; } 63 | public DbSet SnapshotRules { get; set; } 64 | public DbSet SoftwareSyntaxes { get; set; } 65 | 66 | #endregion 67 | } 68 | } -------------------------------------------------------------------------------- /src/FilterLists.Api/DependencyInjection/Extensions/ConfigureServicesCollection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using Microsoft.ApplicationInsights.Extensibility.Implementation; 4 | using Microsoft.AspNetCore.Builder; 5 | using Microsoft.AspNetCore.Http; 6 | using Microsoft.AspNetCore.Mvc; 7 | using Microsoft.Extensions.DependencyInjection; 8 | using Microsoft.Extensions.PlatformAbstractions; 9 | using Swashbuckle.AspNetCore.Swagger; 10 | 11 | namespace FilterLists.Api.DependencyInjection.Extensions 12 | { 13 | public static class ConfigureServicesCollection 14 | { 15 | public static void AddFilterListsApi(this IServiceCollection services) 16 | { 17 | services.ConfigureCookiePolicy(); 18 | services.AddMvcCustom(); 19 | services.AddRoutingCustom(); 20 | services.AddApiVersioning(); 21 | services.AddSwaggerGenCustom(); 22 | TelemetryDebugWriter.IsTracingDisabled = true; 23 | } 24 | 25 | private static void ConfigureCookiePolicy(this IServiceCollection services) 26 | { 27 | services.Configure(options => 28 | { 29 | options.CheckConsentNeeded = context => true; 30 | options.MinimumSameSitePolicy = SameSiteMode.None; 31 | }); 32 | } 33 | 34 | private static void AddMvcCustom(this IServiceCollection services) 35 | { 36 | services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); 37 | } 38 | 39 | private static void AddRoutingCustom(this IServiceCollection services) 40 | { 41 | services.AddRouting(options => options.LowercaseUrls = true); 42 | } 43 | 44 | private static void AddSwaggerGenCustom(this IServiceCollection services) 45 | { 46 | services.AddSwaggerGen(c => 47 | { 48 | c.SwaggerDoc("v1", 49 | new Info 50 | { 51 | Title = "FilterLists API", 52 | Version = "v1", 53 | Description = 54 | "A REST-ish API for FilterLists, the independent, comprehensive directory of all public filter and hosts lists for advertisements, trackers, malware, and annoyances." + 55 | Environment.NewLine + 56 | " - {version} has to be specified manually (to \"1\") in Swagger playground below due to https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/370", 57 | Contact = new Contact 58 | { 59 | Url = "https://github.com/collinbarrett/FilterLists/", 60 | Name = "FilterLists - GitHub" 61 | }, 62 | License = new License 63 | { 64 | Name = "MIT License", 65 | Url = "https://github.com/collinbarrett/FilterLists/blob/master/LICENSE" 66 | } 67 | }); 68 | c.IncludeXmlComments(Path.Combine(PlatformServices.Default.Application.ApplicationBasePath, 69 | "FilterLists.Api.xml")); 70 | }); 71 | } 72 | } 73 | } -------------------------------------------------------------------------------- /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at cb@collinmbarrett.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /src/FilterLists.Api/Startup.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using FilterLists.Api.DependencyInjection.Extensions; 3 | using FilterLists.Data; 4 | using FilterLists.Data.Seed.Extensions; 5 | using FilterLists.Services.DependencyInjection.Extensions; 6 | using JetBrains.Annotations; 7 | using Microsoft.AspNetCore.Builder; 8 | using Microsoft.AspNetCore.Hosting; 9 | using Microsoft.AspNetCore.HttpOverrides; 10 | using Microsoft.EntityFrameworkCore; 11 | using Microsoft.Extensions.Configuration; 12 | using Microsoft.Extensions.DependencyInjection; 13 | using Swashbuckle.AspNetCore.Swagger; 14 | 15 | namespace FilterLists.Api 16 | { 17 | [UsedImplicitly] 18 | public class Startup 19 | { 20 | public Startup(IConfiguration configuration) 21 | { 22 | Configuration = configuration; 23 | } 24 | 25 | private IConfiguration Configuration { get; } 26 | 27 | public void ConfigureServices(IServiceCollection services) 28 | { 29 | services.AddFilterListsServices(Configuration); 30 | services.AddFilterListsApi(); 31 | } 32 | 33 | public void Configure(IApplicationBuilder app, IHostingEnvironment env) 34 | { 35 | if (env.IsDevelopment()) 36 | { 37 | app.UseDeveloperExceptionPage(); 38 | } 39 | else 40 | { 41 | app.UseExceptionHandler("/Error"); 42 | app.UseHsts(); 43 | } 44 | 45 | app.UseForwardedHeaders(new ForwardedHeadersOptions 46 | { 47 | ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto 48 | }); 49 | app.UseHttpsRedirection(); 50 | app.UseStaticFiles(); 51 | app.UseCookiePolicy(); 52 | app.UseMvc(); 53 | app.UseSwagger(c => 54 | { 55 | c.PreSerializeFilters.Add((swaggerDoc, httpReq) => swaggerDoc.Host = httpReq.Host.Value); 56 | //TODO: remove preprocessor directives 57 | #if RELEASE 58 | c.PreSerializeFilters.Add((swaggerDoc, httpReq) => swaggerDoc.BasePath = "/api"); 59 | #endif 60 | c.RouteTemplate = "docs/{documentName}/swagger.json"; 61 | UseLowercaseControllerNameInSwaggerHack(c); 62 | }); 63 | app.UseSwaggerUI(c => 64 | { 65 | c.SwaggerEndpoint("v1/swagger.json", "FilterLists API v1"); 66 | c.DocumentTitle = "FilterLists API v1"; 67 | c.RoutePrefix = "docs"; 68 | }); 69 | MigrateAndSeedDatabase(app); 70 | } 71 | 72 | //TODO: remove hack (https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/74#issuecomment-386762178) 73 | private static void UseLowercaseControllerNameInSwaggerHack(SwaggerOptions c) 74 | { 75 | c.PreSerializeFilters.Add((document, request) => 76 | { 77 | var paths = document.Paths.ToDictionary(item => item.Key.ToLowerInvariant(), item => item.Value); 78 | document.Paths.Clear(); 79 | foreach (var pathItem in paths) document.Paths.Add(pathItem.Key, pathItem.Value); 80 | }); 81 | } 82 | 83 | private void MigrateAndSeedDatabase(IApplicationBuilder app) 84 | { 85 | var dataPath = Configuration.GetSection("DataDirectory").GetValue("Path"); 86 | using (var serviceScope = app.ApplicationServices.GetRequiredService().CreateScope()) 87 | { 88 | serviceScope.ServiceProvider.GetService().Database.Migrate(); 89 | serviceScope.ServiceProvider.GetService().SeedOrUpdate(dataPath); 90 | } 91 | } 92 | } 93 | } -------------------------------------------------------------------------------- /src/FilterLists.Web/FilterLists.Web.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.1 5 | true 6 | Latest 7 | false 8 | Collin M. Barrett 9 | FilterLists 10 | https://github.com/collinbarrett/FilterLists/blob/master/LICENSE 11 | Copyright (c) 2018 Collin M. Barrett 12 | The independent, comprehensive directory of filter and host lists for advertisements, trackers, malware, and annoyances. 13 | https://filterlists.com/ 14 | https://github.com/collinbarrett/FilterLists/raw/master/imgs/icon_filterlists.png 15 | https://github.com/collinbarrett/FilterLists 16 | git 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | Always 34 | 35 | 36 | Always 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | %(DistFiles.Identity) 65 | PreserveNewest 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /src/FilterLists.Services/FilterList/FilterListService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using AutoMapper.QueryableExtensions; 6 | using FilterLists.Data; 7 | using JetBrains.Annotations; 8 | using Microsoft.EntityFrameworkCore; 9 | 10 | namespace FilterLists.Services.FilterList 11 | { 12 | [UsedImplicitly] 13 | public class FilterListService : Service 14 | { 15 | public FilterListService(FilterListsDbContext dbContext) : base(dbContext) 16 | { 17 | DbContext = dbContext; 18 | } 19 | 20 | public async Task> GetAllSummariesAsync() 21 | { 22 | var summaries = await GetSummaryDtos(); 23 | var latestSnapshots = await GetLatestSnapshots(); 24 | return summaries.GroupJoin(latestSnapshots, summary => summary.Id, snap => snap.FilterListId, 25 | (summary, snap) => 26 | { 27 | snap = snap as Data.Entities.Snapshot[] ?? snap.ToArray(); 28 | var updatedDate = snap.Any() ? snap.Single().CreatedDateUtc : (DateTime?) null; 29 | return new ListSummaryDto 30 | { 31 | Id = summary.Id, 32 | AddedDate = summary.AddedDate, 33 | Languages = summary.Languages, 34 | Name = summary.Name, 35 | UpdatedDate = updatedDate, 36 | ViewUrl = summary.ViewUrl 37 | }; 38 | }); 39 | } 40 | 41 | private async Task> GetSummaryDtos() 42 | { 43 | return await DbContext.FilterLists.AsNoTracking() 44 | .OrderBy(l => l.Name) 45 | .ProjectTo() 46 | .ToListAsync(); 47 | } 48 | 49 | private async Task> GetLatestSnapshots() 50 | { 51 | return await DbContext.Snapshots.AsNoTracking() 52 | .Where(s => s.IsCompleted && 53 | s.HttpStatusCode == "200" && 54 | (s.AddedSnapshotRules.Count > 0 || s.RemovedSnapshotRules.Count > 0)) 55 | .GroupBy(s => s.FilterListId, 56 | (key, x) => x.OrderByDescending(y => y.CreatedDateUtc).First()) 57 | .ToListAsync(); 58 | } 59 | 60 | public async Task GetDetailsAsync(uint id) 61 | { 62 | var details = await DbContext.FilterLists.AsNoTracking() 63 | .ProjectTo() 64 | .FirstAsync(x => x.Id == id) 65 | .FilterParentListFromMaintainerAdditionalLists(); 66 | details.RuleCount = await GetActiveRuleCount(details); 67 | details.UpdatedDate = await GetUpdatedDate(details); 68 | return details; 69 | } 70 | 71 | private async Task GetActiveRuleCount(ListDetailsDto details) 72 | { 73 | var listSnapshots = DbContext.Snapshots.AsNoTracking() 74 | .Where(s => s.FilterListId == details.Id && s.IsCompleted); 75 | return await listSnapshots.SelectMany(sr => sr.AddedSnapshotRules).CountAsync() - 76 | await listSnapshots.SelectMany(sr => sr.RemovedSnapshotRules).CountAsync(); 77 | } 78 | 79 | private async Task GetUpdatedDate(ListDetailsDto details) 80 | { 81 | var snapshotDates = DbContext.Snapshots.AsNoTracking() 82 | .Where(s => s.FilterListId == details.Id && 83 | s.IsCompleted && 84 | s.HttpStatusCode == "200" && 85 | (s.AddedSnapshotRules.Count > 0 || 86 | s.RemovedSnapshotRules.Count > 0)) 87 | .Select(s => s.CreatedDateUtc) 88 | .OrderByDescending(s => s.Date); 89 | return snapshotDates.Any() ? (DateTime?) await snapshotDates.FirstAsync() : null; 90 | } 91 | } 92 | } -------------------------------------------------------------------------------- /data/License.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": 1, 4 | "descriptionUrl": "https://creativecommons.org/licenses/by-nc-nd/4.0/", 5 | "name": "CC BY-NC-ND 4.0", 6 | "permissiveAdaptation": false, 7 | "permissiveCommercial": false 8 | }, 9 | { 10 | "id": 2, 11 | "descriptionUrl": "https://opensource.org/licenses/MIT", 12 | "name": "The MIT License", 13 | "permissiveAdaptation": true, 14 | "permissiveCommercial": true 15 | }, 16 | { 17 | "id": 3, 18 | "descriptionUrl": null, 19 | "name": "Restricted", 20 | "permissiveAdaptation": false, 21 | "permissiveCommercial": false 22 | }, 23 | { 24 | "id": 4, 25 | "descriptionUrl": "https://www.gnu.org/licenses/gpl-3.0.en.html", 26 | "name": "GPLv3", 27 | "permissiveAdaptation": true, 28 | "permissiveCommercial": true 29 | }, 30 | { 31 | "id": 5, 32 | "descriptionUrl": "https://en.wikipedia.org/wiki/All_rights_reserved", 33 | "name": "All Rights Reserved", 34 | "permissiveAdaptation": false, 35 | "permissiveCommercial": false 36 | }, 37 | { 38 | "id": 6, 39 | "descriptionUrl": "https://creativecommons.org/licenses/by-nc-sa/3.0/", 40 | "name": "CC BY-NC-SA 3.0", 41 | "permissiveAdaptation": true, 42 | "permissiveCommercial": false 43 | }, 44 | { 45 | "id": 7, 46 | "descriptionUrl": null, 47 | "name": "Permissive", 48 | "permissiveAdaptation": true, 49 | "permissiveCommercial": true 50 | }, 51 | { 52 | "id": 8, 53 | "descriptionUrl": "https://creativecommons.org/licenses/by-sa/4.0/", 54 | "name": "CC BY-SA 4.0", 55 | "permissiveAdaptation": true, 56 | "permissiveCommercial": true 57 | }, 58 | { 59 | "id": 9, 60 | "descriptionUrl": "https://creativecommons.org/licenses/by-nc-sa/4.0/", 61 | "name": "CC BY-NC-SA 4.0", 62 | "permissiveAdaptation": true, 63 | "permissiveCommercial": false 64 | }, 65 | { 66 | "id": 10, 67 | "descriptionUrl": "https://opensource.org/licenses/BSD-3-Clause", 68 | "name": "BSD-3-Clause", 69 | "permissiveAdaptation": true, 70 | "permissiveCommercial": true 71 | }, 72 | { 73 | "id": 11, 74 | "descriptionUrl": "https://unlicense.org/", 75 | "name": "The Unlicense", 76 | "permissiveAdaptation": true, 77 | "permissiveCommercial": true 78 | }, 79 | { 80 | "id": 12, 81 | "descriptionUrl": "https://creativecommons.org/licenses/by-sa/3.0/", 82 | "name": "CC BY-SA 3.0", 83 | "permissiveAdaptation": true, 84 | "permissiveCommercial": true 85 | }, 86 | { 87 | "id": 13, 88 | "descriptionUrl": "https://creativecommons.org/licenses/by-nc/4.0/", 89 | "name": "CC BY-NC 4.0", 90 | "permissiveAdaptation": true, 91 | "permissiveCommercial": false 92 | }, 93 | { 94 | "id": 14, 95 | "descriptionUrl": "http://www.wtfpl.net/", 96 | "name": "Do What The Fuck You Want To Public License (WTFPL)", 97 | "permissiveAdaptation": true, 98 | "permissiveCommercial": true 99 | }, 100 | { 101 | "id": 15, 102 | "descriptionUrl": "https://creativecommons.org/licenses/by-nd/4.0/", 103 | "name": "CC BY-ND 4.0", 104 | "permissiveAdaptation": false, 105 | "permissiveCommercial": true 106 | }, 107 | { 108 | "id": 16, 109 | "descriptionUrl": "https://creativecommons.org/licenses/by/3.0/", 110 | "name": "CC BY 3.0", 111 | "permissiveAdaptation": true, 112 | "permissiveCommercial": true 113 | }, 114 | { 115 | "id": 17, 116 | "descriptionUrl": "https://opensource.org/licenses/ISC", 117 | "name": "ISC", 118 | "permissiveAdaptation": true, 119 | "permissiveCommercial": true 120 | }, 121 | { 122 | "id": 18, 123 | "descriptionUrl": "https://www.apache.org/licenses/LICENSE-2.0", 124 | "name": "Apache 2.0", 125 | "permissiveAdaptation": true, 126 | "permissiveCommercial": true 127 | }, 128 | { 129 | "id": 19, 130 | "descriptionUrl": "https://www.gnu.org/licenses/old-licenses/gpl-2.0.html", 131 | "name": "GPLv2", 132 | "permissiveAdaptation": true, 133 | "permissiveCommercial": true 134 | }, 135 | { 136 | "id": 20, 137 | "descriptionUrl": null, 138 | "name": "Public Domain", 139 | "permissiveAdaptation": true, 140 | "permissiveCommercial": true 141 | }, 142 | { 143 | "id": 21, 144 | "descriptionUrl": "https://osint.bambenekconsulting.com/license.txt", 145 | "name": "OSINT", 146 | "permissiveAdaptation": true, 147 | "permissiveCommercial": true 148 | } 149 | ] -------------------------------------------------------------------------------- /FilterLists.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio 15 3 | VisualStudioVersion = 15.0.27130.2026 4 | MinimumVisualStudioVersion = 10.0.40219.1 5 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FilterLists.Api", "src\FilterLists.Api\FilterLists.Api.csproj", "{57E4CE18-41F3-48F6-B142-12947FFBA86C}" 6 | EndProject 7 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FilterLists.Data", "src\FilterLists.Data\FilterLists.Data.csproj", "{944ADE8F-18E3-4DB8-9098-6A55E026EAC1}" 8 | EndProject 9 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FilterLists.Services", "src\FilterLists.Services\FilterLists.Services.csproj", "{9F296ECF-97C9-47E6-A794-5AD900ECFE6C}" 10 | EndProject 11 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FilterLists.Web", "src\FilterLists.Web\FilterLists.Web.csproj", "{6B3E6765-5B8B-4A23-AD12-7E2BC5F4D2E6}" 12 | EndProject 13 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "data", "data", "{8C3C7C63-F5EF-4E4E-B9BF-47F6EA7D2CBD}" 14 | ProjectSection(SolutionItems) = preProject 15 | data\FilterList.json = data\FilterList.json 16 | data\FilterListLanguage.json = data\FilterListLanguage.json 17 | data\FilterListMaintainer.json = data\FilterListMaintainer.json 18 | data\Fork.json = data\Fork.json 19 | data\Language.json = data\Language.json 20 | data\License.json = data\License.json 21 | data\Maintainer.json = data\Maintainer.json 22 | data\Merge.json = data\Merge.json 23 | data\README.md = data\README.md 24 | data\Software.json = data\Software.json 25 | data\SoftwareSyntax.json = data\SoftwareSyntax.json 26 | data\Syntax.json = data\Syntax.json 27 | EndProjectSection 28 | EndProject 29 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{FCA7F77A-9EC6-4C6D-A80E-7DD27FF95673}" 30 | ProjectSection(SolutionItems) = preProject 31 | scripts\build.sh = scripts\build.sh 32 | scripts\cron = scripts\cron 33 | scripts\deploy.sh = scripts\deploy.sh 34 | EndProjectSection 35 | EndProject 36 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FilterLists.Agent", "src\FilterLists.Agent\FilterLists.Agent.csproj", "{4F39D132-498D-4A93-9F6C-1C604718300D}" 37 | EndProject 38 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "sql", "sql", "{A4BB2C81-5232-4162-B410-704D123D2C01}" 39 | ProjectSection(SolutionItems) = preProject 40 | scripts\sql\createDb.sql = scripts\sql\createDb.sql 41 | scripts\sql\snapshotTimeAnalysis.sql = scripts\sql\snapshotTimeAnalysis.sql 42 | EndProjectSection 43 | EndProject 44 | Global 45 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 46 | Debug|Any CPU = Debug|Any CPU 47 | Release|Any CPU = Release|Any CPU 48 | EndGlobalSection 49 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 50 | {57E4CE18-41F3-48F6-B142-12947FFBA86C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 51 | {57E4CE18-41F3-48F6-B142-12947FFBA86C}.Debug|Any CPU.Build.0 = Debug|Any CPU 52 | {57E4CE18-41F3-48F6-B142-12947FFBA86C}.Release|Any CPU.ActiveCfg = Release|Any CPU 53 | {57E4CE18-41F3-48F6-B142-12947FFBA86C}.Release|Any CPU.Build.0 = Release|Any CPU 54 | {944ADE8F-18E3-4DB8-9098-6A55E026EAC1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 55 | {944ADE8F-18E3-4DB8-9098-6A55E026EAC1}.Debug|Any CPU.Build.0 = Debug|Any CPU 56 | {944ADE8F-18E3-4DB8-9098-6A55E026EAC1}.Release|Any CPU.ActiveCfg = Release|Any CPU 57 | {944ADE8F-18E3-4DB8-9098-6A55E026EAC1}.Release|Any CPU.Build.0 = Release|Any CPU 58 | {9F296ECF-97C9-47E6-A794-5AD900ECFE6C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 59 | {9F296ECF-97C9-47E6-A794-5AD900ECFE6C}.Debug|Any CPU.Build.0 = Debug|Any CPU 60 | {9F296ECF-97C9-47E6-A794-5AD900ECFE6C}.Release|Any CPU.ActiveCfg = Release|Any CPU 61 | {9F296ECF-97C9-47E6-A794-5AD900ECFE6C}.Release|Any CPU.Build.0 = Release|Any CPU 62 | {6B3E6765-5B8B-4A23-AD12-7E2BC5F4D2E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 63 | {6B3E6765-5B8B-4A23-AD12-7E2BC5F4D2E6}.Debug|Any CPU.Build.0 = Debug|Any CPU 64 | {6B3E6765-5B8B-4A23-AD12-7E2BC5F4D2E6}.Release|Any CPU.ActiveCfg = Release|Any CPU 65 | {6B3E6765-5B8B-4A23-AD12-7E2BC5F4D2E6}.Release|Any CPU.Build.0 = Release|Any CPU 66 | {4F39D132-498D-4A93-9F6C-1C604718300D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 67 | {4F39D132-498D-4A93-9F6C-1C604718300D}.Debug|Any CPU.Build.0 = Debug|Any CPU 68 | {4F39D132-498D-4A93-9F6C-1C604718300D}.Release|Any CPU.ActiveCfg = Release|Any CPU 69 | {4F39D132-498D-4A93-9F6C-1C604718300D}.Release|Any CPU.Build.0 = Release|Any CPU 70 | EndGlobalSection 71 | GlobalSection(SolutionProperties) = preSolution 72 | HideSolutionNode = FALSE 73 | EndGlobalSection 74 | GlobalSection(NestedProjects) = preSolution 75 | {A4BB2C81-5232-4162-B410-704D123D2C01} = {FCA7F77A-9EC6-4C6D-A80E-7DD27FF95673} 76 | EndGlobalSection 77 | GlobalSection(ExtensibilityGlobals) = postSolution 78 | SolutionGuid = {8A31B449-52DD-4445-A9C4-033A24E25308} 79 | EndGlobalSection 80 | GlobalSection(NDepend) = preSolution 81 | Project = ".\FilterLists.ndproj" 82 | EndGlobalSection 83 | EndGlobal 84 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | dist: trusty 2 | sudo: false 3 | language: csharp 4 | dotnet: 2.1.300 5 | mono: none 6 | solution: FilterLists.sln 7 | addons: 8 | apt: 9 | packages: 10 | - sshpass 11 | script: 12 | - scripts/build.sh 13 | env: 14 | global: 15 | - secure: bAVsm4H5Kh2/ac/reztswoM81rg6hF38KPvk5MwO6pBPImbyRlrTr00RiPc5dDK/EubxpKjjSpypLEycRrj0xks2GIrOA1irnBaRWRHNZOJpJl2yNDMmJ49VlfAyHwpydWRrfJ6siwHoHjJ5OoXRMthPc+O00lO2YMN0jmuZ2QVtJLiBWVxE/3EnGl1glyjsHdmhEH0JsZXJgYxyn2nXrExWjA5C0tO0P0LMrqiCuZiRzPO0O4VnnQMjMD40wtS82f1Dkjj4CefwrOc/88eP3bYRhkeIoBwiYuuO5R+PTVauHfuoT31v1y05AfbpY6w+2XzCndIJ+3q0yya9PsB8PoSUteUgIRRm5cBNxg/4bvlXDsJniRMyLsd0+Y3UXDF61N1Jo2RmOHUqBjx/QzjAjzYjQp9vUm8OVSfpFieLMp5KK6k6bVF5fds1aBpMMHrRjnbdYd9mzWXCJchdrWgLegcYQd4L/UbfXatetomPRvuBz4aLAZdz0PEAVtwwR2eG8Uvy7pYU6hUdp3xCq4/INExMwDPdyaxmV9k8yvhDpgBmu18qP1VhD0/aaiCMXQqdLizLt6P34YRO85rayaS0bX314XJhRrhGy2PhMe19lV0VK3JyAniMQSl2s5bmLsMJyeGQaIj3KBI28y1U9EiOVGcWZwdfMCzSJ6LX/8uQPjc= 16 | - secure: k90KInQN+VNnBhlq6L058G/0uz0AQp3U1LJeEF/6+VAxSeqVUBnw3lcmAUWEXc1woshZj1f8Ru2aXHVhzZzBIOFMKX/O+BL4zSym8pmniNBI8nbnMLJ5nsfEp5DgFgi5Gkq3yyPzAe08heiilyJY4OE1hvyiTvZwYM8YOrbJnzu4ZT86cunA/gQrlqhxawWxNfC6dvuci6OLeQILHHQzAVv+1ujuSy+4k9iW6EbPgfjNHFGAVREU7H8fzTfcxWKXhNl8H0XKkctzPGKyZ4OrhxU1zWBb6qzoN/Tcf14XKZdymvU4RVAUDjSyfbt3To/2EK1INClOXNNxm1u/Ern4GqVsgSDRW/AyTBQDl7hnjEZpc1ha2Yg5RBPPQD1cM03/viuGexYSOs4cZQEP68jI3/vZgVuzxfaMG1qwtkeoWci0H0jAyGj3rnQ11mN1248XytPyrpHrZQ5AqD0+i9Lo1oFmVnF+uPNXNO0XrmE13emrO1C+tC6XFsqlDhf6YUOiKoAk38OTjWhaAfDh0cgh3D0Lrj7gSisGTzhxyfYJK5bENojLzDqFQNKUQ2TznT9QGJAXW6bvvvC72ce3yFVVOL6DAHeZBXrbXJTW8+cvTqt1VxRItRHbbQOAmi5B//WmOzVV+r+Z6fG2Mxq7QQFrqFcUWE20GYRK5zyHRP8Jzyg= 17 | - secure: OGj1TmURHb/aG2VapirLPy9z++m1nWKyCPxv+2ifsth3mjM+2xr3zr81XGSNvhNLgxg1XMlXYPHSkv9h9/8gJ1cuO27sKmP4tggdwRBQey1N0qk/9+pfFaNxalOkM0W/0VT4jIYRGfLYUox0nPl4S2MVpZTS7Vinb7+5N/fH+OlkeUr+DA7dNtdkYKX+0S1ScKhTnaY4GtmhL+nr1RBiz1tUUle4cscRpzs8ft6RZpxnkEEIQIppo1QGyxMvTd/+anjk+ANAQ0SuZ2klkAWORMbZWD2e9v964lYg7GDNUQD1vgaVho44R5J6+azTuu5emGSWfDXdgGg2veVz5LkxPA8YEIAeXfWd46TDyjVEnXuwHo+nxKr0VSWzPk2XV6haqtIBUertn9ASCEBmipDCsYjqTk1+WEgJpbfI3jN/7kOCR8pTRiF2Ha8KSn3domBtkKtkhRk5DllfzJ3nTP11mUXIh0ZDDSQI0cLJF4gvY1qsXTeuioq1PHqsnzl+aCEyxwpZwVxa1k1GyyL63uRO7jjV0slydKwETSNQemuQeKdW3JMTxs2MQ9jaGDkHdbL3SS/ogP1+Z7lXbt3WWmQP90ZYN+2skQATBd1+JiwU+qwyIZ+C5lxbABeeP96pOyI7p+aiCamoCVZ1N8l7R7yhy+tB59fUBQ2JP5mps30aQqM= 18 | - secure: R3coFui0kkQ72gwxStgicvs4aMR41pGQ6quTCeJGNVxI0Rx1viU6sgOK+5PJbte37fOGmgyf7WEZLO9RVncfd2UcChV4/UrHy1bYZsOMqA32fH8VRnQ4hd196cGzlX3TOpifnwu5iQ3UlamLcAb51wSENQJWUs6FiZHNYfp/c0jmJ2lSKFciVQh097ZdTaSd/ecRbVSCTxpcPKB7y8kSOlEQJjSN5LLcgQf8nqgrsCyIxNnazCipVjn6n/1M1ZKaDRj2fuAJ4JYGtI8bmbjcLYK9Xgz3kkUqAz0A/2VVodzngbtji6c0ZaJu4a+C/+J82divuAITV7XLjjpDTB8JZYIoH1u2kgZKivOE1smCnkvCQMbNk9zWe7fZCoHHDq4illrckeWfRgN5qBT3YkF4I1e+ruhpA142fI15fryvA+L4Nasmg8ILsKqpiN6zknOfo+PIgBPgXLX/TPmn8b3GMndCyPlB8tx+iBVQQ2+0CD1IiA3jmBQJ6Bnd5YS0TztQ7+TuHumNujCP8p8PZ6PQIx1YRoZM6cXJ/8rF4u8VnEa7QioaomLb7XcVg9KUyL3IU/rK2Jr5EK9IEAX5Whcxyy5l8zG+lDvdCoA9/7gSjOL7P90lTgxl/qiluO9HNRuHuOWoXGmQSp/3IVghI2vYLjHl0K3XXDAkfrvzlTAlndw= 19 | - secure: FekWrBXOq95uCkavSLbUM1J8TAnLQ+5axni3DPVTKcpnGKhn8Qc69Ru5UaI+560sDadz8Qn4C1X+m6qJdWOnJ50fXhrirgoG5Ew+c0keirjVTan7VbMvKDZFt+5aNjMf28mkjJjPsWsIfr5SxFo2oPMRjVYljW09qbYv+C31U4iO6Fcw4oqNnYlBBMd8ulK62uE/enoDMHe9W831guopo6KDmNPdFftoOLrs9xeOY8lVOWti1HAHXMaEVP3zhJCUXHr0SU0wt46acb0LYSCaz6QNiVdu3zo2rOzbPOwNf8dYt5TCb8W2B96SOFkfKwj/cuKa6BF09eeq5rohmC2vvTWGf4ekmrlA3et5B58rTY3UbRukOa8qq39h2AFAY4+gvQ4plSFAM1nWOviUFybwIwpMP7lbMlCJ708zEl3OFVRlMJ8uVM1kP0eXkr9tXH+Xe3Cb7QBPk5dIPDrr7CjXQsp5rfhColeoRAPnuawQHukdIwFC6hHAIhAJy7FlkUXTU7CdFaNFZ7ANCEzmasrDC57s3HkLWOoX6nLIQR0gWI1pc0YnF3XPhzhgJLZE4dobYeSB3lu9bLb2DkWBkEHAFZ8eWNHpTbajC3WIz0mOrw4/fXLc4xsB+B5yVYZWv21fHOzOVVX2RNjc9pMSiRWpJ4QqtddLmg+T1dr3j9XMOvs= 20 | - secure: C0ygjEE57HqWxBe86iFDt/Rb1rBp1LAe0dLzchaf2rx8HaGYp/UwIeh3pERPoYMaCd7y0r3chM1qGG45kpprsqFxs/wt3QGXLOJ8DYy0XaD8rLHrN0N8xnzcsbp2aars+CKWkUTJSajzj6ZqmaDDaga6pQDRM3lw6H81I9uu7yVh/AUo8WRk4fd9K5pfAYl6B7QIdRnwk6F4Oa19vmHTVTtwIeWVF3T5FxHkNtrelQYBAsms+lf82IN4Y7FVqZX/heNWzqs0GXu34hWMh+fo1orQ7PjpGHYuXiEXrUjphXdxRbQksTCBQkva/DyP5IJYetEMX81VxrRA8lp/zFHWFGFWqU2Kv3560bFt6Y8jnS1+8qqTjoz+3a02lqSiYoQHtoNqPghYoM12ZuTMKkHUWyQOnFTTI2PjwdDv9Fh8wJtr2BWdViBoMSBhg97C5sC9Af6mobGqgujsNuNUZt+cw3UnDjC6o0Wgcmo3zdaSHD9RVET6EuGSmlSD2CRHfAmtTRNoNM0oavT4t+6c8B7ljOrhElnN6HuSKA7OGB69AiFUuiJ70r/g6KO1ACwTkO23kiGGpZMAqFh7uwPx21nmNPxF5NjNWPR+JdkAxN9ARBzmLrXOu8XzkTY1+qaM7tF5Zqnd7tOWxhnuJlU6+RBRLHfyedkqEx6+mQgv51KV1G4= 21 | - secure: GSy3BfyiJPjHJh6VZ0WLPSHsjCbjVVVPsPEJiGANO919js+AhAAl7kL9GqQZZ4BDawcWDsHxIrhYClSmbDCpoIxcUF4x/Gqh8z1oBRvAvm77STfkEN61Prrqu69F0DAgRdunaEx845D/0CLCryD3clQnNeYZ0CfIraX7vM9PqwFY/AlEf22Ij/q2ypHiIAst2Fu6TBl24j3O1L6CWp1kGT7Zs1W4mjG2HmglJwwAgetfxGG0lRv7DyECE8o1G/kwaXLJ1hzalkJktPfyZgNyAMRjnyvjk0FjvVRuOK4FDvoj6cHQBSrccaaHC9Is2SriFpUUeo5TrdXuq76bCmuhR4u7/X3gOz4eAJsC5510CFdBIcjTXeLQ1ZUJNVKfouw3e1Pq4t/fO4n4VjJe5m+0O+aCmkQmqhlzcR3yfdZtXmr1XegVi+cRAbUFsB+L7+Br5Pko0o9LySwQqdVewY6FFOh/ea6mFqAnT0oh4oD/tTa1L5yT2gvwPz7lM4NOQH3qW74OZ2Zb5PfLMN6p0YIsqQPVPn9o689rnXELHQAiHpt08ZzkVwkeWEa3KR/Vgy078T343Bt39eI3LLGsor+a6/wNOL1CHDXsoLMMXVQn9lbTxlvWxErgNNpQkt/7xgbzN5Wv7Zjn5dosAf8hC6x9d6cOrzFKu8JaC1T//DClQqE= 22 | deploy: 23 | skip_cleanup: true 24 | provider: script 25 | script: scripts/deploy.sh 26 | on: 27 | branch: master -------------------------------------------------------------------------------- /.github/README.md: -------------------------------------------------------------------------------- 1 | ![FilterLists](https://github.com/collinbarrett/FilterLists/blob/master/imgs/logo_filterlists.png) 2 | 3 | [![Website](https://img.shields.io/website-up-down-green-red/http/shields.io.svg)](https://filterlists.com/) 4 | [![Travis](https://img.shields.io/travis/collinbarrett/FilterLists.svg?label=travis)](https://travis-ci.org/collinbarrett/FilterLists) 5 | [![License](https://img.shields.io/badge/License-MIT-green.svg)](https://github.com/collinbarrett/FilterLists/blob/master/LICENSE) 6 | 7 | FilterLists is the independent, comprehensive directory of filter and host lists for advertisements, trackers, malware, and annoyances. 8 | 9 | ## Links 10 | | Site | API | 11 | | --------------------------------------------------- | -------------------------------------------------------------- | 12 | | [v3 (Live, Beta)](https://filterlists.com/) | [v1 (Live, Beta)](https://filterlists.com/api/docs/index.html) | 13 | | [v2 (Legacy, Frozen)](https://v2.filterlists.com/) | | 14 | | [v1 (Legacy, Frozen)](https://v1.filterlists.com/) | | 15 | 16 | ## Adding or Updating Lists 17 | 18 | To submit a new list or update data about an existing list, please submit a pull request to [data](https://github.com/collinbarrett/FilterLists/tree/master/data) in conjunction with the data model described [here](https://github.com/collinbarrett/FilterLists/wiki/Data-Model_sidebar). Alternatively, you can [open a new issue](https://github.com/collinbarrett/FilterLists/issues/new) providing information for all of the fields described in the [data model](https://github.com/collinbarrett/FilterLists/wiki/Data-Model_sidebar). 19 | 20 | ## Adding or Updating Rules 21 | 22 | FilterLists does not maintain any of these lists. It serves only as a discovery tool to direct users to lists that they may want to use. If you want to request addition, modification, or removal of a rule from a list, you will need to contact the maintainers of that list directly. FilterLists provides a variety of ways you can get in contact with the maintainers to do so. 23 | 24 | ## Background 25 | 26 | FilterLists helps to protect your privacy and security when using the internet. It provides a comprehensive directory of subscription lists to block advertisements, malware, trackers, and other general annoyances. First, install one of the tools mentioned below under "Software Support." Then, you can subscribe to a set of these lists inside of that software. If you need help or have a comment/question, open an [Issue](https://github.com/collinbarrett/FilterLists/issues). 27 | 28 | Using a software firewall or adblocker has become a key tool in protecting one's privacy online. While the current business model of the "free" internet relies upon advertising revenue, publishers have become too flippant about tracking users without their consent. Advertising networks track users' browsing habits around the internet building lucrative profiles to exploit for targeted marketing or big data research. Until internet publishers develop more transparency or a new business model, we must continue to take the protection of our privacy into our hands. 29 | 30 | Typical adblockers run as an extension in popular web browsers. As we browse the internet, they compare HTTP requests to their list of hosts and filters to selectively block advertisements, trackers, and malware. This filtering helps to protect the surfer's privacy, prevents [malvertising attacks](http://www.wired.com/insights/2014/11/malvertising-is-cybercriminals-latest-sweet-spot/ "Why Malvertising Is Cybercriminals' Latest Sweet Spot - Wired"), and [reduces bandwidth requirements](http://venturebeat.com/2015/07/08/blocking-ads-can-cut-network-traffic-25-to-40-study-shows/ "Blocking Ads Can Cut Network Traffic 25% to 40%, Study Shows - VentureBeat"). Thousands of contributors work hard to maintain these FilterLists for anyone to use. Locating and selecting these lists, however, has not historically been very easy. This project aims to solve that problem. 31 | 32 | ## Software Support 33 | 34 | One can use FilterLists in the following software tools. Software support of any given list varies by the list's syntax. 35 | 36 | * [1Blocker](https://1blocker.com/) 37 | * [AdAway](https://adaway.org/) 38 | * [AdBlock](https://getadblock.com/) 39 | * [Adblock Plus](https://adblockplus.org/) 40 | * [AdGuard](https://adguard.com/) 41 | * [DNS66](https://github.com/julian-klode/dns66) 42 | * [Nano Adblocker](https://github.com/NanoAdblocker/NanoCore) 43 | * [uBlock Origin](https://github.com/gorhill/uBlock) 44 | * ...[Did we forget one?](https://github.com/collinbarrett/FilterLists/issues) 45 | 46 | ## Miscellany 47 | 48 | ### Disclaimer 49 | 50 | FilterLists does not condone or endorse implementing any particular FilterList or blocking any particular advertisement network. Make sure to financially support your favorite sites in some way if you choose to block their advertisements. FilterLists is also in no way officially affiliated with any of the software vendors or list maintainers referenced on this site. 51 | 52 | ### Privacy 53 | 54 | We respect your privacy. That is the whole point of this site. The only minor data we collect about visitors is what [CloudFlare](https://www.cloudflare.com/analytics/) and [GitHub](https://help.github.com/articles/github-privacy-statement/) captures. -------------------------------------------------------------------------------- /src/FilterLists.Data/Seed/Extensions/SeedFilterListsDbContext.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using FilterLists.Data.Entities; 6 | using FilterLists.Data.Entities.Junctions; 7 | using Microsoft.EntityFrameworkCore; 8 | using Microsoft.EntityFrameworkCore.Metadata; 9 | using Newtonsoft.Json; 10 | 11 | namespace FilterLists.Data.Seed.Extensions 12 | { 13 | public static class SeedFilterListsDbContext 14 | { 15 | public static void SeedOrUpdate(this FilterListsDbContext dbContext, string dataPath) 16 | { 17 | dbContext.InsertOnDuplicateKeyUpdate(dataPath); 18 | dbContext.InsertOnDuplicateKeyUpdate(dataPath); 19 | dbContext.InsertOnDuplicateKeyUpdate(dataPath); 20 | dbContext.InsertOnDuplicateKeyUpdate(dataPath); 21 | dbContext.InsertOnDuplicateKeyUpdate(dataPath); 22 | dbContext.InsertOnDuplicateKeyUpdate(dataPath); 23 | dbContext.InsertOnDuplicateKeyUpdate(dataPath); 24 | dbContext.InsertOnDuplicateKeyUpdate(dataPath); 25 | dbContext.InsertOnDuplicateKeyUpdate(dataPath); 26 | dbContext.InsertOnDuplicateKeyUpdate(dataPath); 27 | dbContext.InsertOnDuplicateKeyUpdate(dataPath); 28 | } 29 | 30 | private static void InsertOnDuplicateKeyUpdate(this DbContext dbContext, string dataPath) 31 | where TEntityType : class 32 | { 33 | var entityType = dbContext.Model.FindEntityType(typeof(TEntityType)); 34 | var properties = GetPropertiesLessValueGeneratedTimestamps(entityType); 35 | var values = CreateValues(properties, dataPath); 36 | if (values == "") return; 37 | var columns = string.Join(", ", properties.Select(x => x.Name)); 38 | var updates = CreateUpdates(properties); 39 | var rawSqlString = "INSERT INTO " + entityType.Relational().TableName + " (" + columns + ") VALUES " + 40 | values + " ON DUPLICATE KEY UPDATE " + updates; 41 | dbContext.Database.ExecuteSqlCommand(rawSqlString); 42 | dbContext.SaveChanges(); 43 | } 44 | 45 | private static List GetPropertiesLessValueGeneratedTimestamps(IEntityType entityType) 46 | { 47 | //TODO: get seed properties dynamically from JSON 48 | return entityType.GetProperties() 49 | .Where(x => !new List {"CreatedDateUtc", "ModifiedDateUtc"}.Contains(x.Name)) 50 | .ToList(); 51 | } 52 | 53 | private static string CreateValues(IReadOnlyCollection properties, string dataPath) 54 | { 55 | return GetSeedRows(dataPath) 56 | .Select(row => CreateRowValues(properties, row)) 57 | .Aggregate("", (current, rowValues) => current == "" ? rowValues : current + ", " + rowValues); 58 | } 59 | 60 | private static List GetSeedRows(string dataPath) 61 | { 62 | try 63 | { 64 | return JsonConvert.DeserializeObject>( 65 | File.ReadAllText(dataPath + Path.DirectorySeparatorChar + typeof(TEntityType).Name + ".json")); 66 | } 67 | catch (FileNotFoundException e) 68 | { 69 | Console.WriteLine(e.Message); 70 | return new List(); 71 | } 72 | } 73 | 74 | private static string CreateRowValues(IEnumerable properties, TEntityType row) 75 | { 76 | return (from property in properties 77 | let value = row.GetType().GetProperty(property.Name)?.GetValue(row) 78 | select FormatDataForMySql(property, value)).Aggregate("", 79 | (rowValues, value) => rowValues == "" ? "(" + value : rowValues + ", " + value) + ")"; 80 | } 81 | 82 | private static object FormatDataForMySql(IProperty property, object value) 83 | { 84 | if (value == null) return "NULL"; 85 | if (property.ClrType == typeof(string)) 86 | return "'" + value.ToString().Replace("'", "''") + "'"; 87 | if (property.ClrType == typeof(bool)) 88 | return Convert.ToInt32(value); 89 | if (property.ClrType == typeof(DateTime?)) 90 | return "'" + ((DateTime) value).ToString("yyyy-MM-dd HH:mm:ss") + "'"; 91 | return value; 92 | } 93 | 94 | private static string CreateUpdates(IReadOnlyCollection properties) 95 | { 96 | var update = 97 | (from property in properties 98 | where !property.IsPrimaryKey() 99 | select property.Name + " = VALUES(" + property.Name + ")").Aggregate("", 100 | (updates, columnUpdates) => updates == "" ? columnUpdates : updates + ", " + columnUpdates); 101 | if (update == "") update = GetUpdateUnchangedColumnHack(properties); 102 | return update; 103 | } 104 | 105 | private static string GetUpdateUnchangedColumnHack(IEnumerable properties) 106 | { 107 | var firstId = properties.First(x => x.IsPrimaryKey()).Name; 108 | return firstId + " = VALUES(" + firstId + ")"; 109 | } 110 | } 111 | } -------------------------------------------------------------------------------- /src/FilterLists.Services/Snapshot/SnapshotDe.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Net; 5 | using System.Net.Http; 6 | using System.Threading.Tasks; 7 | using FilterLists.Data; 8 | using FilterLists.Data.Entities.Junctions; 9 | using FilterLists.Services.Extensions; 10 | 11 | namespace FilterLists.Services.Snapshot 12 | { 13 | public class SnapshotDe 14 | { 15 | private const string UserAgentString = 16 | @"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"; 17 | 18 | private const int BatchSize = 1000; 19 | private readonly FilterListsDbContext _dbContext; 20 | private readonly FilterListViewUrlDto _list; 21 | private Data.Entities.Snapshot _snapshot; 22 | 23 | public SnapshotDe(FilterListsDbContext dbContext, FilterListViewUrlDto list) 24 | { 25 | _dbContext = dbContext; 26 | _list = list; 27 | } 28 | 29 | public async Task SaveSnapshotAsync() 30 | { 31 | var content = await CaptureSnapshot(); 32 | if (content != null) 33 | { 34 | await SaveSnapshotInBatches(content); 35 | await DedupSnapshotRules(); 36 | } 37 | 38 | await SetCompleted(); 39 | } 40 | 41 | private async Task CaptureSnapshot() 42 | { 43 | await AddSnapshot(); 44 | var content = await TryGetContent(); 45 | await _dbContext.SaveChangesAsync(); 46 | return content; 47 | } 48 | 49 | private async Task AddSnapshot() 50 | { 51 | _snapshot = new Data.Entities.Snapshot {FilterListId = _list.Id}; 52 | await _dbContext.Snapshots.AddAsync(_snapshot); 53 | } 54 | 55 | private async Task TryGetContent() 56 | { 57 | try 58 | { 59 | return await GetContent(); 60 | } 61 | catch (WebException we) 62 | { 63 | _snapshot.HttpStatusCode = ((int) ((HttpWebResponse) we.Response).StatusCode).ToString(); 64 | return null; 65 | } 66 | catch (Exception) 67 | { 68 | //TODO: log exception (#148) 69 | _snapshot.HttpStatusCode = null; 70 | return null; 71 | } 72 | } 73 | 74 | private async Task GetContent() 75 | { 76 | using (var httpClient = new HttpClient()) 77 | { 78 | httpClient.DefaultRequestHeaders.UserAgent.ParseAdd(UserAgentString); 79 | using (var httpResponseMessage = await httpClient.GetAsync(_list.ViewUrl)) 80 | { 81 | _snapshot.HttpStatusCode = ((int) httpResponseMessage.StatusCode).ToString(); 82 | if (httpResponseMessage.IsSuccessStatusCode) 83 | return await httpResponseMessage.Content.ReadAsStringAsync(); 84 | } 85 | } 86 | 87 | return null; 88 | } 89 | 90 | private async Task SaveSnapshotInBatches(string content) 91 | { 92 | var rawRules = GetRawRules(content); 93 | var snapshotBatches = GetSnapshotBatches(rawRules); 94 | await SaveSnapshotBatches(snapshotBatches); 95 | } 96 | 97 | private static IEnumerable GetRawRules(string content) 98 | { 99 | var rawRules = content.Split(new[] {"\r\n", "\r", "\n"}, StringSplitOptions.RemoveEmptyEntries); 100 | for (var i = 0; i < rawRules.Length; i++) 101 | rawRules[i] = rawRules[i].LintRawRule(); 102 | return new HashSet(rawRules.Where(rr => rr != null)); 103 | } 104 | 105 | private IEnumerable GetSnapshotBatches(IEnumerable rawRules) 106 | { 107 | return rawRules.Batch(BatchSize) 108 | .Select(rawRuleBatch => new SnapshotBatchDe(_dbContext, _snapshot, rawRuleBatch)); 109 | } 110 | 111 | private static async Task SaveSnapshotBatches(IEnumerable snapshotBatches) 112 | { 113 | foreach (var snapshotBatch in snapshotBatches) 114 | await snapshotBatch.SaveSnapshotBatchAsync(); 115 | } 116 | 117 | private async Task DedupSnapshotRules() 118 | { 119 | var existingSnapshotRules = GetExistingSnapshotRules(); 120 | UpdateRemovedSnapshotRules(existingSnapshotRules); 121 | RemoveDuplicateSnapshotRules(existingSnapshotRules); 122 | await _dbContext.SaveChangesAsync(); 123 | } 124 | 125 | private IQueryable GetExistingSnapshotRules() 126 | { 127 | return _dbContext.SnapshotRules.Where(sr => 128 | sr.AddedBySnapshot.FilterListId == _list.Id && sr.AddedBySnapshot != _snapshot && 129 | sr.RemovedBySnapshot == null); 130 | } 131 | 132 | private void UpdateRemovedSnapshotRules(IQueryable existingSnapshotRules) 133 | { 134 | var newSnapshotRules = _dbContext.SnapshotRules.Where(sr => sr.AddedBySnapshot == _snapshot); 135 | var removedSnapshotRules = 136 | existingSnapshotRules.Where(sr => !newSnapshotRules.Any(nsr => nsr.Rule == sr.Rule)); 137 | removedSnapshotRules.ToList().ForEach(sr => sr.RemovedBySnapshot = _snapshot); 138 | } 139 | 140 | private void RemoveDuplicateSnapshotRules(IQueryable existingSnapshotRules) 141 | { 142 | var duplicateSnapshotRules = _dbContext.SnapshotRules.Where(sr => 143 | sr.AddedBySnapshot == _snapshot && 144 | existingSnapshotRules.Any(esr => esr.Rule == sr.Rule)); 145 | _dbContext.SnapshotRules.RemoveRange(duplicateSnapshotRules); 146 | } 147 | 148 | private async Task SetCompleted() 149 | { 150 | _snapshot.IsCompleted = true; 151 | await _dbContext.SaveChangesAsync(); 152 | } 153 | } 154 | } -------------------------------------------------------------------------------- /data/Merge.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "mergeFilterListId": 11, 4 | "upstreamFilterListId": 12 5 | }, 6 | { 7 | "mergeFilterListId": 11, 8 | "upstreamFilterListId": 301 9 | }, 10 | { 11 | "mergeFilterListId": 13, 12 | "upstreamFilterListId": 12 13 | }, 14 | { 15 | "mergeFilterListId": 13, 16 | "upstreamFilterListId": 14 17 | }, 18 | { 19 | "mergeFilterListId": 13, 20 | "upstreamFilterListId": 301 21 | }, 22 | { 23 | "mergeFilterListId": 21, 24 | "upstreamFilterListId": 23 25 | }, 26 | { 27 | "mergeFilterListId": 21, 28 | "upstreamFilterListId": 75 29 | }, 30 | { 31 | "mergeFilterListId": 21, 32 | "upstreamFilterListId": 121 33 | }, 34 | { 35 | "mergeFilterListId": 21, 36 | "upstreamFilterListId": 123 37 | }, 38 | { 39 | "mergeFilterListId": 21, 40 | "upstreamFilterListId": 125 41 | }, 42 | { 43 | "mergeFilterListId": 21, 44 | "upstreamFilterListId": 130 45 | }, 46 | { 47 | "mergeFilterListId": 22, 48 | "upstreamFilterListId": 24 49 | }, 50 | { 51 | "mergeFilterListId": 22, 52 | "upstreamFilterListId": 26 53 | }, 54 | { 55 | "mergeFilterListId": 22, 56 | "upstreamFilterListId": 37 57 | }, 58 | { 59 | "mergeFilterListId": 22, 60 | "upstreamFilterListId": 77 61 | }, 62 | { 63 | "mergeFilterListId": 22, 64 | "upstreamFilterListId": 122 65 | }, 66 | { 67 | "mergeFilterListId": 22, 68 | "upstreamFilterListId": 124 69 | }, 70 | { 71 | "mergeFilterListId": 22, 72 | "upstreamFilterListId": 126 73 | }, 74 | { 75 | "mergeFilterListId": 22, 76 | "upstreamFilterListId": 129 77 | }, 78 | { 79 | "mergeFilterListId": 120, 80 | "upstreamFilterListId": 25 81 | }, 82 | { 83 | "mergeFilterListId": 120, 84 | "upstreamFilterListId": 76 85 | }, 86 | { 87 | "mergeFilterListId": 120, 88 | "upstreamFilterListId": 127 89 | }, 90 | { 91 | "mergeFilterListId": 120, 92 | "upstreamFilterListId": 128 93 | }, 94 | { 95 | "mergeFilterListId": 168, 96 | "upstreamFilterListId": 157 97 | }, 98 | { 99 | "mergeFilterListId": 168, 100 | "upstreamFilterListId": 159 101 | }, 102 | { 103 | "mergeFilterListId": 168, 104 | "upstreamFilterListId": 162 105 | }, 106 | { 107 | "mergeFilterListId": 168, 108 | "upstreamFilterListId": 166 109 | }, 110 | { 111 | "mergeFilterListId": 168, 112 | "upstreamFilterListId": 242 113 | }, 114 | { 115 | "mergeFilterListId": 168, 116 | "upstreamFilterListId": 301 117 | }, 118 | { 119 | "mergeFilterListId": 271, 120 | "upstreamFilterListId": 338 121 | }, 122 | { 123 | "mergeFilterListId": 274, 124 | "upstreamFilterListId": 273 125 | }, 126 | { 127 | "mergeFilterListId": 274, 128 | "upstreamFilterListId": 275 129 | }, 130 | { 131 | "mergeFilterListId": 309, 132 | "upstreamFilterListId": 17 133 | }, 134 | { 135 | "mergeFilterListId": 309, 136 | "upstreamFilterListId": 32 137 | }, 138 | { 139 | "mergeFilterListId": 309, 140 | "upstreamFilterListId": 35 141 | }, 142 | { 143 | "mergeFilterListId": 309, 144 | "upstreamFilterListId": 47 145 | }, 146 | { 147 | "mergeFilterListId": 309, 148 | "upstreamFilterListId": 54 149 | }, 150 | { 151 | "mergeFilterListId": 309, 152 | "upstreamFilterListId": 80 153 | }, 154 | { 155 | "mergeFilterListId": 309, 156 | "upstreamFilterListId": 81 157 | }, 158 | { 159 | "mergeFilterListId": 309, 160 | "upstreamFilterListId": 99 161 | }, 162 | { 163 | "mergeFilterListId": 309, 164 | "upstreamFilterListId": 138 165 | }, 166 | { 167 | "mergeFilterListId": 309, 168 | "upstreamFilterListId": 170 169 | }, 170 | { 171 | "mergeFilterListId": 309, 172 | "upstreamFilterListId": 177 173 | }, 174 | { 175 | "mergeFilterListId": 309, 176 | "upstreamFilterListId": 179 177 | }, 178 | { 179 | "mergeFilterListId": 309, 180 | "upstreamFilterListId": 206 181 | }, 182 | { 183 | "mergeFilterListId": 309, 184 | "upstreamFilterListId": 226 185 | }, 186 | { 187 | "mergeFilterListId": 309, 188 | "upstreamFilterListId": 255 189 | }, 190 | { 191 | "mergeFilterListId": 309, 192 | "upstreamFilterListId": 276 193 | }, 194 | { 195 | "mergeFilterListId": 309, 196 | "upstreamFilterListId": 282 197 | }, 198 | { 199 | "mergeFilterListId": 309, 200 | "upstreamFilterListId": 316 201 | }, 202 | { 203 | "mergeFilterListId": 309, 204 | "upstreamFilterListId": 317 205 | }, 206 | { 207 | "mergeFilterListId": 309, 208 | "upstreamFilterListId": 324 209 | }, 210 | { 211 | "mergeFilterListId": 309, 212 | "upstreamFilterListId": 325 213 | }, 214 | { 215 | "mergeFilterListId": 309, 216 | "upstreamFilterListId": 326 217 | }, 218 | { 219 | "mergeFilterListId": 309, 220 | "upstreamFilterListId": 329 221 | }, 222 | { 223 | "mergeFilterListId": 309, 224 | "upstreamFilterListId": 340 225 | }, 226 | { 227 | "mergeFilterListId": 331, 228 | "upstreamFilterListId": 199 229 | }, 230 | { 231 | "mergeFilterListId": 331, 232 | "upstreamFilterListId": 330 233 | }, 234 | { 235 | "mergeFilterListId": 331, 236 | "upstreamFilterListId": 332 237 | }, 238 | { 239 | "mergeFilterListId": 331, 240 | "upstreamFilterListId": 333 241 | }, 242 | { 243 | "mergeFilterListId": 371, 244 | "upstreamFilterListId": 110 245 | }, 246 | { 247 | "mergeFilterListId": 371, 248 | "upstreamFilterListId": 232 249 | }, 250 | { 251 | "mergeFilterListId": 375, 252 | "upstreamFilterListId": 2 253 | }, 254 | { 255 | "mergeFilterListId": 375, 256 | "upstreamFilterListId": 18 257 | }, 258 | { 259 | "mergeFilterListId": 375, 260 | "upstreamFilterListId": 19 261 | }, 262 | { 263 | "mergeFilterListId": 375, 264 | "upstreamFilterListId": 27 265 | }, 266 | { 267 | "mergeFilterListId": 375, 268 | "upstreamFilterListId": 38 269 | }, 270 | { 271 | "mergeFilterListId": 375, 272 | "upstreamFilterListId": 70 273 | }, 274 | { 275 | "mergeFilterListId": 375, 276 | "upstreamFilterListId": 71 277 | }, 278 | { 279 | "mergeFilterListId": 375, 280 | "upstreamFilterListId": 97 281 | }, 282 | { 283 | "mergeFilterListId": 375, 284 | "upstreamFilterListId": 99 285 | }, 286 | { 287 | "mergeFilterListId": 375, 288 | "upstreamFilterListId": 148 289 | }, 290 | { 291 | "mergeFilterListId": 375, 292 | "upstreamFilterListId": 174 293 | }, 294 | { 295 | "mergeFilterListId": 375, 296 | "upstreamFilterListId": 183 297 | }, 298 | { 299 | "mergeFilterListId": 375, 300 | "upstreamFilterListId": 184 301 | }, 302 | { 303 | "mergeFilterListId": 375, 304 | "upstreamFilterListId": 214 305 | }, 306 | { 307 | "mergeFilterListId": 375, 308 | "upstreamFilterListId": 232 309 | }, 310 | { 311 | "mergeFilterListId": 375, 312 | "upstreamFilterListId": 247 313 | }, 314 | { 315 | "mergeFilterListId": 375, 316 | "upstreamFilterListId": 279 317 | }, 318 | { 319 | "mergeFilterListId": 375, 320 | "upstreamFilterListId": 307 321 | } 322 | ] -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | 27 | # Visual Studio 2015/2017 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # Visual Studio 2017 auto generated files 33 | Generated\ Files/ 34 | 35 | # MSTest test Results 36 | [Tt]est[Rr]esult*/ 37 | [Bb]uild[Ll]og.* 38 | 39 | # NUNIT 40 | *.VisualState.xml 41 | TestResult.xml 42 | 43 | # Build Results of an ATL Project 44 | [Dd]ebugPS/ 45 | [Rr]eleasePS/ 46 | dlldata.c 47 | 48 | # Benchmark Results 49 | BenchmarkDotNet.Artifacts/ 50 | 51 | # .NET Core 52 | project.lock.json 53 | project.fragment.lock.json 54 | artifacts/ 55 | **/Properties/launchSettings.json 56 | 57 | # StyleCop 58 | StyleCopReport.xml 59 | 60 | # Files built by Visual Studio 61 | *_i.c 62 | *_p.c 63 | *_i.h 64 | *.ilk 65 | *.meta 66 | *.obj 67 | *.iobj 68 | *.pch 69 | *.pdb 70 | *.ipdb 71 | *.pgc 72 | *.pgd 73 | *.rsp 74 | *.sbr 75 | *.tlb 76 | *.tli 77 | *.tlh 78 | *.tmp 79 | *.tmp_proj 80 | *.log 81 | *.vspscc 82 | *.vssscc 83 | .builds 84 | *.pidb 85 | *.svclog 86 | *.scc 87 | 88 | # Chutzpah Test files 89 | _Chutzpah* 90 | 91 | # Visual C++ cache files 92 | ipch/ 93 | *.aps 94 | *.ncb 95 | *.opendb 96 | *.opensdf 97 | *.sdf 98 | *.cachefile 99 | *.VC.db 100 | *.VC.VC.opendb 101 | 102 | # Visual Studio profiler 103 | *.psess 104 | *.vsp 105 | *.vspx 106 | *.sap 107 | 108 | # Visual Studio Trace Files 109 | *.e2e 110 | 111 | # TFS 2012 Local Workspace 112 | $tf/ 113 | 114 | # Guidance Automation Toolkit 115 | *.gpState 116 | 117 | # ReSharper is a .NET coding add-in 118 | _ReSharper*/ 119 | *.[Rr]e[Ss]harper 120 | *.DotSettings.user 121 | 122 | # JustCode is a .NET coding add-in 123 | .JustCode 124 | 125 | # TeamCity is a build add-in 126 | _TeamCity* 127 | 128 | # DotCover is a Code Coverage Tool 129 | *.dotCover 130 | 131 | # AxoCover is a Code Coverage Tool 132 | .axoCover/* 133 | !.axoCover/settings.json 134 | 135 | # Visual Studio code coverage results 136 | *.coverage 137 | *.coveragexml 138 | 139 | # NCrunch 140 | _NCrunch_* 141 | .*crunch*.local.xml 142 | nCrunchTemp_* 143 | 144 | # MightyMoose 145 | *.mm.* 146 | AutoTest.Net/ 147 | 148 | # Web workbench (sass) 149 | .sass-cache/ 150 | 151 | # Installshield output folder 152 | [Ee]xpress/ 153 | 154 | # DocProject is a documentation generator add-in 155 | DocProject/buildhelp/ 156 | DocProject/Help/*.HxT 157 | DocProject/Help/*.HxC 158 | DocProject/Help/*.hhc 159 | DocProject/Help/*.hhk 160 | DocProject/Help/*.hhp 161 | DocProject/Help/Html2 162 | DocProject/Help/html 163 | 164 | # Click-Once directory 165 | publish/ 166 | 167 | # Publish Web Output 168 | *.[Pp]ublish.xml 169 | *.azurePubxml 170 | # Note: Comment the next line if you want to checkin your web deploy settings, 171 | # but database connection strings (with potential passwords) will be unencrypted 172 | *.pubxml 173 | *.publishproj 174 | 175 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 176 | # checkin your Azure Web App publish settings, but sensitive information contained 177 | # in these scripts will be unencrypted 178 | PublishScripts/ 179 | 180 | # NuGet Packages 181 | *.nupkg 182 | # The packages folder can be ignored because of Package Restore 183 | **/[Pp]ackages/* 184 | # except build/, which is used as an MSBuild target. 185 | !**/[Pp]ackages/build/ 186 | # Uncomment if necessary however generally it will be regenerated when needed 187 | #!**/[Pp]ackages/repositories.config 188 | # NuGet v3's project.json files produces more ignorable files 189 | *.nuget.props 190 | *.nuget.targets 191 | 192 | # Microsoft Azure Build Output 193 | csx/ 194 | *.build.csdef 195 | 196 | # Microsoft Azure Emulator 197 | ecf/ 198 | rcf/ 199 | 200 | # Windows Store app package directories and files 201 | AppPackages/ 202 | BundleArtifacts/ 203 | Package.StoreAssociation.xml 204 | _pkginfo.txt 205 | *.appx 206 | 207 | # Visual Studio cache files 208 | # files ending in .cache can be ignored 209 | *.[Cc]ache 210 | # but keep track of directories ending in .cache 211 | !*.[Cc]ache/ 212 | 213 | # Others 214 | ClientBin/ 215 | ~$* 216 | *~ 217 | *.dbmdl 218 | *.dbproj.schemaview 219 | *.jfm 220 | *.pfx 221 | *.publishsettings 222 | orleans.codegen.cs 223 | 224 | # Including strong name files can present a security risk 225 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 226 | #*.snk 227 | 228 | # Since there are multiple workflows, uncomment next line to ignore bower_components 229 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 230 | #bower_components/ 231 | 232 | # RIA/Silverlight projects 233 | Generated_Code/ 234 | 235 | # Backup & report files from converting an old project file 236 | # to a newer Visual Studio version. Backup files are not needed, 237 | # because we have git ;-) 238 | _UpgradeReport_Files/ 239 | Backup*/ 240 | UpgradeLog*.XML 241 | UpgradeLog*.htm 242 | ServiceFabricBackup/ 243 | 244 | # SQL Server files 245 | *.mdf 246 | *.ldf 247 | *.ndf 248 | 249 | # Business Intelligence projects 250 | *.rdl.data 251 | *.bim.layout 252 | *.bim_*.settings 253 | *.rptproj.rsuser 254 | 255 | # Microsoft Fakes 256 | FakesAssemblies/ 257 | 258 | # GhostDoc plugin setting file 259 | *.GhostDoc.xml 260 | 261 | # Node.js Tools for Visual Studio 262 | .ntvs_analysis.dat 263 | node_modules/ 264 | 265 | # Visual Studio 6 build log 266 | *.plg 267 | 268 | # Visual Studio 6 workspace options file 269 | *.opt 270 | 271 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 272 | *.vbw 273 | 274 | # Visual Studio LightSwitch build output 275 | **/*.HTMLClient/GeneratedArtifacts 276 | **/*.DesktopClient/GeneratedArtifacts 277 | **/*.DesktopClient/ModelManifest.xml 278 | **/*.Server/GeneratedArtifacts 279 | **/*.Server/ModelManifest.xml 280 | _Pvt_Extensions 281 | 282 | # Paket dependency manager 283 | .paket/paket.exe 284 | paket-files/ 285 | 286 | # FAKE - F# Make 287 | .fake/ 288 | 289 | # JetBrains Rider 290 | .idea/ 291 | *.sln.iml 292 | 293 | # CodeRush 294 | .cr/ 295 | 296 | # Python Tools for Visual Studio (PTVS) 297 | __pycache__/ 298 | *.pyc 299 | 300 | # Cake - Uncomment if you are using it 301 | # tools/** 302 | # !tools/packages.config 303 | 304 | # Tabs Studio 305 | *.tss 306 | 307 | # Telerik's JustMock configuration file 308 | *.jmconfig 309 | 310 | # BizTalk build output 311 | *.btp.cs 312 | *.btm.cs 313 | *.odx.cs 314 | *.xsd.cs 315 | 316 | # OpenCover UI analysis results 317 | OpenCover/ 318 | 319 | # Azure Stream Analytics local run output 320 | ASALocalRun/ 321 | 322 | # MSBuild Binary and Structured Log 323 | *.binlog 324 | 325 | # NVidia Nsight GPU debugger configuration file 326 | *.nvuser 327 | 328 | # MFractors (Xamarin productivity tool) working folder 329 | .mfractor/ 330 | 331 | # FilterLists Custom Ignores 332 | gs/Private.gs 333 | appsettings.development.json 334 | appsettings.production.json 335 | src/FilterLists.Agent/appsettings.json 336 | src/FilterLists.Web/wwwroot/dist -------------------------------------------------------------------------------- /src/FilterLists.Web/ClientApp/components/Home.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { RouteComponentProps } from "react-router"; 3 | import "isomorphic-fetch"; 4 | import ReactTable from "react-table" 5 | import "react-table/react-table.css" 6 | import ListDetails from "./ListDetails"; 7 | import * as moment from "moment"; 8 | 9 | interface IHomeState { 10 | lists: IListDto[]; 11 | loadingLists: boolean; 12 | ruleCount: number; 13 | loadingRuleCount: boolean; 14 | } 15 | 16 | export class Home extends React.Component, IHomeState> { 17 | constructor(props: any) { 18 | super(props); 19 | this.state = { 20 | lists: [], 21 | loadingLists: true, 22 | ruleCount: 0, 23 | loadingRuleCount: true 24 | }; 25 | } 26 | 27 | render() { 28 | const contents = this.state.loadingLists || this.state.loadingRuleCount 29 | ?

30 | Loading... 31 |

32 | :
33 | {Home.renderTagline(this.state)} 34 | {Home.renderFilterListsTable(this.state.lists)} 35 |
; 36 | return
37 | {contents} 38 |
; 39 | } 40 | 41 | componentDidMount() { 42 | fetch("https://filterlists.com/api/v1/lists") 43 | .then(response => response.json() as Promise) 44 | .then(data => { 45 | this.setState({ 46 | lists: data, 47 | loadingLists: false 48 | }); 49 | }); 50 | fetch("https://filterlists.com/api/v1/rules") 51 | .then(response => response.json() as Promise) 52 | .then(data => { 53 | this.setState({ 54 | ruleCount: data, 55 | loadingRuleCount: false 56 | }); 57 | }); 58 | } 59 | 60 | private static renderTagline(state: IHomeState) { 61 | return

62 | The independent, comprehensive directory of {state.ruleCount.toLocaleString() 63 | } unique rules across {state.lists.length 64 | } filter and host lists for advertisements, trackers, malware, and annoyances. 65 |

; 66 | } 67 | 68 | private static renderFilterListsTable(filterLists: IListDto[]) { 69 | return row[filter.id].toUpperCase() 78 | .includes(filter.value.toUpperCase()), 79 | sortMethod: (a: any, b: any) => a.toUpperCase() > b.toUpperCase() ? 1 : -1, 80 | Cell: (cell: any) =>

{cell.value}

81 | }, 82 | { 83 | Header: "Langs.", 84 | accessor: "languages", 85 | filterable: true, 86 | filterMethod: (filter: any, row: any) => row[filter.id] 87 | .map((e: any) => e.name.concat(e.iso6391)).join().toUpperCase() 88 | .includes(filter.value.toUpperCase()), 89 | sortMethod: (a: any, b: any) => a.join().toUpperCase() > b.join().toUpperCase() ? 1 : -1, 90 | Cell: (cell: any) =>
{cell.value.map((e: any) => e.iso6391).join(", ")}
, 91 | style: { whiteSpace: "inherit" }, 92 | width: 60, 93 | headerClassName: "d-none d-lg-block", 94 | className: "d-none d-lg-block" 95 | }, 96 | { 97 | Header: "Updated", 98 | accessor: "updatedDate", 99 | filterable: true, 100 | filterMethod: (filter: any, row: any) => row[filter.id].includes(filter.value), 101 | sortMethod: (a: any, b: any) => moment(a).isValid() 102 | ? (moment(b).isValid() ? (moment(a).isBefore(b) ? -1 : 1) : 1) 103 | : -1, 104 | Cell: (cell: any) =>
{moment(cell.value).isValid() 105 | ? moment(cell.value).format(moment.HTML5_FMT.DATE) 106 | : "N/A"}
, 107 | style: { whiteSpace: "inherit" }, 108 | width: 100, 109 | headerClassName: "d-none d-lg-block", 110 | className: "d-none d-lg-block" 111 | }, 112 | { 113 | Header: "Added", 114 | accessor: "addedDate", 115 | filterable: true, 116 | filterMethod: (filter: any, row: any) => row[filter.id].includes(filter.value), 117 | sortMethod: (a: any, b: any) => a > b ? 1 : -1, 118 | Cell: (cell: any) =>
{moment(cell.value).isValid() 119 | ? moment(cell.value).format(moment.HTML5_FMT.DATE) 120 | : "N/A"}
, 121 | style: { whiteSpace: "inherit" }, 122 | width: 100, 123 | headerClassName: "d-none d-lg-block", 124 | className: "d-none d-lg-block" 125 | }, 126 | { 127 | Header: "Details", 128 | accessor: "id", 129 | sortable: false, 130 | expander: true, 131 | Expander: ({ isExpanded, row }) => 132 |
133 | {isExpanded 134 | ? 138 | : } 142 |
, 143 | style: { textAlign: "center" }, 144 | width: 100 145 | }, 146 | { 147 | Header: "Subscribe", 148 | accessor: "viewUrl", 149 | sortable: false, 150 | Cell: (cell: any) => , 151 | style: { textAlign: "center" }, 152 | width: 100, 153 | headerClassName: "d-none d-lg-block", 154 | className: "d-none d-lg-block" 155 | } 156 | ]} 157 | SubComponent={(row: any) => { 158 | return ( 159 | 160 | ); 161 | }} 162 | className="-striped -highlight"/>; 163 | } 164 | } 165 | 166 | interface IListDto { 167 | id: number; 168 | addedDate: string; 169 | name: string; 170 | languages: IListLanguageDto[]; 171 | updatedDate: string; 172 | viewUrl: string; 173 | } 174 | 175 | interface IListLanguageDto { 176 | name: string; 177 | iso6391: string; 178 | } 179 | 180 | function SubscribeUrl(props: any) { 181 | return 184 | Subscribe 185 | ; 186 | } -------------------------------------------------------------------------------- /data/FilterListLanguage.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "filterListId": 1, 4 | "languageId": 141 5 | }, 6 | { 7 | "filterListId": 6, 8 | "languageId": 141 9 | }, 10 | { 11 | "filterListId": 11, 12 | "languageId": 163 13 | }, 14 | { 15 | "filterListId": 12, 16 | "languageId": 163 17 | }, 18 | { 19 | "filterListId": 13, 20 | "languageId": 122 21 | }, 22 | { 23 | "filterListId": 13, 24 | "languageId": 163 25 | }, 26 | { 27 | "filterListId": 14, 28 | "languageId": 122 29 | }, 30 | { 31 | "filterListId": 15, 32 | "languageId": 154 33 | }, 34 | { 35 | "filterListId": 16, 36 | "languageId": 154 37 | }, 38 | { 39 | "filterListId": 20, 40 | "languageId": 44 41 | }, 42 | { 43 | "filterListId": 30, 44 | "languageId": 11 45 | }, 46 | { 47 | "filterListId": 31, 48 | "languageId": 11 49 | }, 50 | { 51 | "filterListId": 39, 52 | "languageId": 27 53 | }, 54 | { 55 | "filterListId": 49, 56 | "languageId": 141 57 | }, 58 | { 59 | "filterListId": 51, 60 | "languageId": 168 61 | }, 62 | { 63 | "filterListId": 53, 64 | "languageId": 141 65 | }, 66 | { 67 | "filterListId": 56, 68 | "languageId": 27 69 | }, 70 | { 71 | "filterListId": 59, 72 | "languageId": 154 73 | }, 74 | { 75 | "filterListId": 60, 76 | "languageId": 11 77 | }, 78 | { 79 | "filterListId": 61, 80 | "languageId": 11 81 | }, 82 | { 83 | "filterListId": 62, 84 | "languageId": 141 85 | }, 86 | { 87 | "filterListId": 63, 88 | "languageId": 141 89 | }, 90 | { 91 | "filterListId": 69, 92 | "languageId": 160 93 | }, 94 | { 95 | "filterListId": 72, 96 | "languageId": 177 97 | }, 98 | { 99 | "filterListId": 84, 100 | "languageId": 11 101 | }, 102 | { 103 | "filterListId": 92, 104 | "languageId": 48 105 | }, 106 | { 107 | "filterListId": 99, 108 | "languageId": 154 109 | }, 110 | { 111 | "filterListId": 100, 112 | "languageId": 139 113 | }, 114 | { 115 | "filterListId": 101, 116 | "languageId": 139 117 | }, 118 | { 119 | "filterListId": 113, 120 | "languageId": 141 121 | }, 122 | { 123 | "filterListId": 116, 124 | "languageId": 17 125 | }, 126 | { 127 | "filterListId": 117, 128 | "languageId": 17 129 | }, 130 | { 131 | "filterListId": 118, 132 | "languageId": 17 133 | }, 134 | { 135 | "filterListId": 119, 136 | "languageId": 17 137 | }, 138 | { 139 | "filterListId": 131, 140 | "languageId": 18 141 | }, 142 | { 143 | "filterListId": 132, 144 | "languageId": 18 145 | }, 146 | { 147 | "filterListId": 133, 148 | "languageId": 18 149 | }, 150 | { 151 | "filterListId": 134, 152 | "languageId": 18 153 | }, 154 | { 155 | "filterListId": 136, 156 | "languageId": 76 157 | }, 158 | { 159 | "filterListId": 146, 160 | "languageId": 141 161 | }, 162 | { 163 | "filterListId": 147, 164 | "languageId": 106 165 | }, 166 | { 167 | "filterListId": 150, 168 | "languageId": 18 169 | }, 170 | { 171 | "filterListId": 153, 172 | "languageId": 139 173 | }, 174 | { 175 | "filterListId": 154, 176 | "languageId": 79 177 | }, 178 | { 179 | "filterListId": 156, 180 | "languageId": 48 181 | }, 182 | { 183 | "filterListId": 158, 184 | "languageId": 13 185 | }, 186 | { 187 | "filterListId": 158, 188 | "languageId": 79 189 | }, 190 | { 191 | "filterListId": 161, 192 | "languageId": 18 193 | }, 194 | { 195 | "filterListId": 163, 196 | "languageId": 141 197 | }, 198 | { 199 | "filterListId": 164, 200 | "languageId": 167 201 | }, 202 | { 203 | "filterListId": 166, 204 | "languageId": 110 205 | }, 206 | { 207 | "filterListId": 167, 208 | "languageId": 108 209 | }, 210 | { 211 | "filterListId": 171, 212 | "languageId": 139 213 | }, 214 | { 215 | "filterListId": 171, 216 | "languageId": 110 217 | }, 218 | { 219 | "filterListId": 178, 220 | "languageId": 18 221 | }, 222 | { 223 | "filterListId": 181, 224 | "languageId": 141 225 | }, 226 | { 227 | "filterListId": 182, 228 | "languageId": 163 229 | }, 230 | { 231 | "filterListId": 197, 232 | "languageId": 179 233 | }, 234 | { 235 | "filterListId": 198, 236 | "languageId": 179 237 | }, 238 | { 239 | "filterListId": 199, 240 | "languageId": 159 241 | }, 242 | { 243 | "filterListId": 200, 244 | "languageId": 159 245 | }, 246 | { 247 | "filterListId": 201, 248 | "languageId": 159 249 | }, 250 | { 251 | "filterListId": 202, 252 | "languageId": 141 253 | }, 254 | { 255 | "filterListId": 203, 256 | "languageId": 141 257 | }, 258 | { 259 | "filterListId": 204, 260 | "languageId": 141 261 | }, 262 | { 263 | "filterListId": 205, 264 | "languageId": 141 265 | }, 266 | { 267 | "filterListId": 206, 268 | "languageId": 58 269 | }, 270 | { 271 | "filterListId": 215, 272 | "languageId": 11 273 | }, 274 | { 275 | "filterListId": 216, 276 | "languageId": 11 277 | }, 278 | { 279 | "filterListId": 217, 280 | "languageId": 10 281 | }, 282 | { 283 | "filterListId": 218, 284 | "languageId": 139 285 | }, 286 | { 287 | "filterListId": 219, 288 | "languageId": 141 289 | }, 290 | { 291 | "filterListId": 220, 292 | "languageId": 154 293 | }, 294 | { 295 | "filterListId": 221, 296 | "languageId": 112 297 | }, 298 | { 299 | "filterListId": 222, 300 | "languageId": 10 301 | }, 302 | { 303 | "filterListId": 223, 304 | "languageId": 11 305 | }, 306 | { 307 | "filterListId": 224, 308 | "languageId": 11 309 | }, 310 | { 311 | "filterListId": 225, 312 | "languageId": 141 313 | }, 314 | { 315 | "filterListId": 228, 316 | "languageId": 10 317 | }, 318 | { 319 | "filterListId": 230, 320 | "languageId": 141 321 | }, 322 | { 323 | "filterListId": 231, 324 | "languageId": 141 325 | }, 326 | { 327 | "filterListId": 237, 328 | "languageId": 112 329 | }, 330 | { 331 | "filterListId": 240, 332 | "languageId": 110 333 | }, 334 | { 335 | "filterListId": 245, 336 | "languageId": 87 337 | }, 338 | { 339 | "filterListId": 246, 340 | "languageId": 79 341 | }, 342 | { 343 | "filterListId": 248, 344 | "languageId": 25 345 | }, 346 | { 347 | "filterListId": 251, 348 | "languageId": 79 349 | }, 350 | { 351 | "filterListId": 251, 352 | "languageId": 110 353 | }, 354 | { 355 | "filterListId": 252, 356 | "languageId": 159 357 | }, 358 | { 359 | "filterListId": 253, 360 | "languageId": 18 361 | }, 362 | { 363 | "filterListId": 254, 364 | "languageId": 58 365 | }, 366 | { 367 | "filterListId": 256, 368 | "languageId": 48 369 | }, 370 | { 371 | "filterListId": 257, 372 | "languageId": 83 373 | }, 374 | { 375 | "filterListId": 258, 376 | "languageId": 13 377 | }, 378 | { 379 | "filterListId": 258, 380 | "languageId": 79 381 | }, 382 | { 383 | "filterListId": 260, 384 | "languageId": 11 385 | }, 386 | { 387 | "filterListId": 261, 388 | "languageId": 154 389 | }, 390 | { 391 | "filterListId": 262, 392 | "languageId": 141 393 | }, 394 | { 395 | "filterListId": 263, 396 | "languageId": 183 397 | }, 398 | { 399 | "filterListId": 264, 400 | "languageId": 175 401 | }, 402 | { 403 | "filterListId": 267, 404 | "languageId": 25 405 | }, 406 | { 407 | "filterListId": 268, 408 | "languageId": 99 409 | }, 410 | { 411 | "filterListId": 269, 412 | "languageId": 159 413 | }, 414 | { 415 | "filterListId": 277, 416 | "languageId": 105 417 | }, 418 | { 419 | "filterListId": 278, 420 | "languageId": 154 421 | }, 422 | { 423 | "filterListId": 281, 424 | "languageId": 99 425 | }, 426 | { 427 | "filterListId": 283, 428 | "languageId": 113 429 | }, 430 | { 431 | "filterListId": 284, 432 | "languageId": 113 433 | }, 434 | { 435 | "filterListId": 289, 436 | "languageId": 159 437 | }, 438 | { 439 | "filterListId": 290, 440 | "languageId": 183 441 | }, 442 | { 443 | "filterListId": 291, 444 | "languageId": 183 445 | }, 446 | { 447 | "filterListId": 292, 448 | "languageId": 167 449 | }, 450 | { 451 | "filterListId": 293, 452 | "languageId": 167 453 | }, 454 | { 455 | "filterListId": 294, 456 | "languageId": 108 457 | }, 458 | { 459 | "filterListId": 295, 460 | "languageId": 108 461 | }, 462 | { 463 | "filterListId": 296, 464 | "languageId": 141 465 | }, 466 | { 467 | "filterListId": 297, 468 | "languageId": 75 469 | }, 470 | { 471 | "filterListId": 297, 472 | "languageId": 105 473 | }, 474 | { 475 | "filterListId": 298, 476 | "languageId": 99 477 | }, 478 | { 479 | "filterListId": 299, 480 | "languageId": 99 481 | }, 482 | { 483 | "filterListId": 300, 484 | "languageId": 99 485 | }, 486 | { 487 | "filterListId": 305, 488 | "languageId": 75 489 | }, 490 | { 491 | "filterListId": 305, 492 | "languageId": 105 493 | }, 494 | { 495 | "filterListId": 315, 496 | "languageId": 11 497 | }, 498 | { 499 | "filterListId": 316, 500 | "languageId": 48 501 | }, 502 | { 503 | "filterListId": 326, 504 | "languageId": 141 505 | }, 506 | { 507 | "filterListId": 328, 508 | "languageId": 44 509 | }, 510 | { 511 | "filterListId": 329, 512 | "languageId": 99 513 | }, 514 | { 515 | "filterListId": 330, 516 | "languageId": 87 517 | }, 518 | { 519 | "filterListId": 330, 520 | "languageId": 110 521 | }, 522 | { 523 | "filterListId": 331, 524 | "languageId": 87 525 | }, 526 | { 527 | "filterListId": 331, 528 | "languageId": 110 529 | }, 530 | { 531 | "filterListId": 332, 532 | "languageId": 87 533 | }, 534 | { 535 | "filterListId": 333, 536 | "languageId": 87 537 | }, 538 | { 539 | "filterListId": 334, 540 | "languageId": 141 541 | }, 542 | { 543 | "filterListId": 335, 544 | "languageId": 141 545 | }, 546 | { 547 | "filterListId": 336, 548 | "languageId": 141 549 | }, 550 | { 551 | "filterListId": 337, 552 | "languageId": 141 553 | }, 554 | { 555 | "filterListId": 338, 556 | "languageId": 141 557 | }, 558 | { 559 | "filterListId": 339, 560 | "languageId": 99 561 | }, 562 | { 563 | "filterListId": 340, 564 | "languageId": 99 565 | }, 566 | { 567 | "filterListId": 341, 568 | "languageId": 11 569 | }, 570 | { 571 | "filterListId": 342, 572 | "languageId": 11 573 | }, 574 | { 575 | "filterListId": 343, 576 | "languageId": 11 577 | }, 578 | { 579 | "filterListId": 344, 580 | "languageId": 11 581 | }, 582 | { 583 | "filterListId": 345, 584 | "languageId": 11 585 | }, 586 | { 587 | "filterListId": 346, 588 | "languageId": 11 589 | }, 590 | { 591 | "filterListId": 347, 592 | "languageId": 11 593 | }, 594 | { 595 | "filterListId": 349, 596 | "languageId": 11 597 | }, 598 | { 599 | "filterListId": 350, 600 | "languageId": 163 601 | }, 602 | { 603 | "filterListId": 351, 604 | "languageId": 11 605 | }, 606 | { 607 | "filterListId": 369, 608 | "languageId": 75 609 | }, 610 | { 611 | "filterListId": 369, 612 | "languageId": 105 613 | }, 614 | { 615 | "filterListId": 370, 616 | "languageId": 75 617 | }, 618 | { 619 | "filterListId": 370, 620 | "languageId": 105 621 | }, 622 | { 623 | "filterListId": 384, 624 | "languageId": 44 625 | }, 626 | { 627 | "filterListId": 386, 628 | "languageId": 46 629 | }, 630 | { 631 | "filterListId": 387, 632 | "languageId": 44 633 | }, 634 | { 635 | "filterListID": 388, 636 | "languageId": 44 637 | }, 638 | { 639 | "filterListID": 390, 640 | "languageId": 11 641 | }, 642 | { 643 | "filterListID": 399, 644 | "languageId": 83 645 | }, 646 | { 647 | "filterListID": 402, 648 | "languageId": 44 649 | }, 650 | { 651 | "filterListID": 416, 652 | "languageId": 167 653 | }, 654 | { 655 | "filterListID": 422, 656 | "languageId": 110 657 | }, 658 | { 659 | "filterListID": 422, 660 | "languageId": 99 661 | }, 662 | { 663 | "filterListID": 429, 664 | "languageId": 110 665 | }, 666 | { 667 | "filterListID": 429, 668 | "languageId": 167 669 | }, 670 | { 671 | "filterListID": 430, 672 | "languageId": 44 673 | } 674 | ] 675 | --------------------------------------------------------------------------------