diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..5771a184e --- /dev/null +++ b/.dockerignore @@ -0,0 +1,19 @@ +.env +**/.git +.gitattributes +.gitignore +**/.github +**/.vs +**/.vscode +.dockerignore +docker-compose.yml +docker-compose.*.yml +docker-compose.dcproj +**/bin +**/obj +**/.sln +**/node_modules +*.DotSettings* +LICENSE +**/images +**/ops \ No newline at end of file diff --git a/.env b/.env new file mode 100644 index 000000000..b21c4d35a --- /dev/null +++ b/.env @@ -0,0 +1,5 @@ +FILTERLISTS_CONNECTION_STRING=Server=mariadb;Database=filterlists;Uid=filterlists;Pwd=filterlists; +FILTERLISTS_MYSQL_ROOT_PASSWORD=filterlists +FILTERLISTS_MYSQL_DATABASE=filterlists +FILTERLISTS_MYSQL_USER=filterlists +FILTERLISTS_MYSQL_PASSWORD=filterlists \ No newline at end of file diff --git a/.github/README.md b/.github/README.md index 226816de3..29f5d098f 100644 --- a/.github/README.md +++ b/.github/README.md @@ -2,6 +2,8 @@ [![Website](https://img.shields.io/website-up-down-green-red/http/shields.io.svg)](https://filterlists.com/) [![API](https://img.shields.io/website-up-down-green-red/http/shields.io.svg?label=API)](https://filterlists.com/api/v1/lists) +[![Build status](https://dev.azure.com/collinbarrett/FilterLists/_apis/build/status/FilterLists.Api-CI)](https://dev.azure.com/collinbarrett/FilterLists/_build/latest?definitionId=3) +[![Build status](https://dev.azure.com/collinbarrett/FilterLists/_apis/build/status/FilterLists.Web-CI)](https://dev.azure.com/collinbarrett/FilterLists/_build/latest?definitionId=12) [![License](https://img.shields.io/badge/License-MIT-green.svg)](https://github.com/collinbarrett/FilterLists/blob/master/LICENSE) [![BuiltWithDot.Net shield](https://builtwithdot.net/project/125/filterlists/badge)](https://builtwithdot.net/project/125/filterlists) [![Beerpay](https://beerpay.io/collinbarrett/FilterLists/badge.svg?style=beer-square)](https://beerpay.io/collinbarrett/FilterLists) @@ -9,6 +11,16 @@ FilterLists is the independent, comprehensive directory of filter and host lists for advertisements, trackers, malware, and annoyances. +# Background + +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 [software tools](https://github.com/collinbarrett/FilterLists/blob/master/data/Software.json) that supports these lists. 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). + +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. + +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. + +# Contributing + ## Adding or Updating Lists 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). @@ -17,31 +29,77 @@ To submit a new list or update data about an existing list, please submit a pull 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. -## Background +## Building and Running Locally -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 [software tools](https://github.com/collinbarrett/FilterLists/blob/master/data/Software.json) that supports these lists. 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). +We have containerized FilterLists to make it as easy as possible for contributers to get the project up and running locally. -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. +### Up and Running -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. +1. Install Docker CE for your computer's operating system. [Docs](https://docs.docker.com/install/) +2. Clone the FilterLists git repository to your computer. [Docs](https://help.github.com/en/articles/cloning-a-repository) +3. Navigate to the root directory of your locally cloned FilterLists git repository in a command-line interface. +4. Execute `docker-compose up -d`. +5. Visit the locally running version of FilterLists in a web browser at `http://localhost/`. -## Acknowledgements +### Testing changes to the data (.json files) + +#### Automated + +Execute: + +`docker-compose -f docker-compose.data.tests.yml down -v && docker-compose -f docker-compose.data.tests.yml build api && docker-compose -f docker-compose.data.tests.yml run api` + +#### Manual + +1. Execute `docker container ls` to find the `CONTAINER ID` of the `filterlists.api` container. +2. Execute `docker-compose up -d --build [CONTAINER ID]` replacing `[CONTAINER ID]` with the hash from step 1. +3. Verify your changes are properly reflected at `http://localhost/`. + +### Testing changes to the `Api`, `Services`, or `Data` projects + +#### Automated + +- For `Services`, execute: + + `docker-compose -f docker-compose.services.tests.yml build api && docker-compose -f docker-compose.services.tests.yml run --rm api` + +- For `Data`, execute: + + `docker-compose -f docker-compose.data.tests.yml down -v && docker-compose -f docker-compose.data.tests.yml build api && docker-compose -f docker-compose.data.tests.yml run api` + +#### Manual + +1. Execute `docker container ls` to find the `CONTAINER ID` of the `filterlists.api` container. +2. Execute `docker-compose up -d --build [CONTAINER ID]` replacing `[CONTAINER ID]` with the hash from step 1. +3. Verify your changes are properly reflected at `http://localhost/api`. + +### Testing changes to the `Web` project + +1. Execute `docker container ls` to find the `CONTAINER ID` of the `filterlists.web` container. +2. Execute `docker-compose up -d --build [CONTAINER ID]` replacing `[CONTAINER ID]` with the hash from step 1. + +### Debugging + +1. Execute `docker container ls -a` to find the `CONTAINER ID` of the container in question. +2. Execute `docker logs [CONTAINER ID]` replacing `[CONTAINER ID]` with the hash from step 1 to view the logs from that container. + +# Acknowledgements - Imre Kristoffer Eilertsen [@DandelionSprout](https://github.com/DandelionSprout) : major contributor - Raymond Hill [@gorhill](https://github.com/gorhill) : uBlock Origin owner, advised on some technical aspects of FilterLists - Andrey Meshkov [@ameshkov](https://github.com/ameshkov) : AdGuard CTO, advised on some technical aspects of FilterLists - [More contributors](https://github.com/collinbarrett/FilterLists/graphs/contributors) -## Miscellany +# Miscellany -### Disclaimer +## Disclaimer 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. -### Privacy +## Privacy 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/), [Application Insights](https://docs.microsoft.com/en-us/azure/application-insights/app-insights-data-retention-privacy), and [GitHub](https://help.github.com/articles/github-privacy-statement/) capture. -### Internet Explorer TPL users +## Internet Explorer TPL users The FilterLists.com website returns a blank page in Internet Explorer, mostly due to problems with both polyfill and JavaScript elements, in addition to IE being considered by us to be an outdated browser. To help alleviate this, a makeshift archive has been set up. To view a smaller TPL-only archive with subscribable links, right-click on [this link](https://raw.githubusercontent.com/collinbarrett/FilterLists/master/data/TPLSubscriptionAssistant.html), choose to save it as an HTML file, and open it in Internet Explorer ≥9. diff --git a/.gitignore b/.gitignore index e17f6427f..bd381b8cd 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore # User-specific files +*.rsuser *.suo *.user *.userosscache @@ -12,6 +13,9 @@ # User-specific files (MonoDevelop/Xamarin Studio) *.userprefs +# Mono auto generated files +mono_crash.* + # Build results [Dd]ebug/ [Dd]ebugPublic/ @@ -19,6 +23,8 @@ [Rr]eleases/ x64/ x86/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ bld/ [Bb]in/ [Oo]bj/ @@ -76,6 +82,7 @@ StyleCopReport.xml *.tlh *.tmp *.tmp_proj +*_wpftmp.csproj *.log *.vspscc *.vssscc @@ -178,6 +185,8 @@ PublishScripts/ # NuGet Packages *.nupkg +# NuGet Symbol Packages +*.snupkg # The packages folder can be ignored because of Package Restore **/[Pp]ackages/* # except build/, which is used as an MSBuild target. @@ -202,12 +211,14 @@ BundleArtifacts/ Package.StoreAssociation.xml _pkginfo.txt *.appx +*.appxbundle +*.appxupload # Visual Studio cache files # files ending in .cache can be ignored *.[Cc]ache # but keep track of directories ending in .cache -!*.[Cc]ache/ +!?*.[Cc]ache/ # Others ClientBin/ @@ -251,6 +262,9 @@ ServiceFabricBackup/ *.bim.layout *.bim_*.settings *.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl # Microsoft Fakes FakesAssemblies/ @@ -286,12 +300,8 @@ paket-files/ # FAKE - F# Make .fake/ -# JetBrains Rider -.idea/ -*.sln.iml - -# CodeRush -.cr/ +# CodeRush personal settings +.cr/personal # Python Tools for Visual Studio (PTVS) __pycache__/ @@ -331,7 +341,12 @@ ASALocalRun/ # Local History for Visual Studio .localhistory/ +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + # FilterLists Custom Ignores -appsettings.development.json -appsettings.production.json +appsettings*.json src/FilterLists.Web/wwwroot/dist \ No newline at end of file diff --git a/FilterLists.Api.sln b/FilterLists.Api.sln new file mode 100644 index 000000000..734be577b --- /dev/null +++ b/FilterLists.Api.sln @@ -0,0 +1,81 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.28803.202 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FilterLists.Api", "src\FilterLists.Api\FilterLists.Api.csproj", "{57E4CE18-41F3-48F6-B142-12947FFBA86C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FilterLists.Data", "src\FilterLists.Data\FilterLists.Data.csproj", "{944ADE8F-18E3-4DB8-9098-6A55E026EAC1}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FilterLists.Services", "src\FilterLists.Services\FilterLists.Services.csproj", "{9F296ECF-97C9-47E6-A794-5AD900ECFE6C}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "data", "data", "{8C3C7C63-F5EF-4E4E-B9BF-47F6EA7D2CBD}" + ProjectSection(SolutionItems) = preProject + data\Dependent.json = data\Dependent.json + data\FilterList.json = data\FilterList.json + data\FilterListLanguage.json = data\FilterListLanguage.json + data\FilterListMaintainer.json = data\FilterListMaintainer.json + data\FilterListTag.json = data\FilterListTag.json + data\Fork.json = data\Fork.json + data\Language.json = data\Language.json + data\License.json = data\License.json + data\Maintainer.json = data\Maintainer.json + data\Merge.json = data\Merge.json + data\README.md = data\README.md + data\Software.json = data\Software.json + data\SoftwareSyntax.json = data\SoftwareSyntax.json + data\Syntax.json = data\Syntax.json + data\Tag.json = data\Tag.json + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FilterLists.Services.Tests", "tests\FilterLists.Services.Tests\FilterLists.Services.Tests.csproj", "{7D9F0D85-E906-401A-BDAD-724440B34567}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FilterLists.Data.Tests", "tests\FilterLists.Data.Tests\FilterLists.Data.Tests.csproj", "{DA34DED7-B352-4855-9C7B-9E3D983DBE2E}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{CE4AB25B-5501-42E9-B8B4-87B9C20472AC}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{041F9CFA-B6F7-4DEB-9441-829DE697B1BB}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {57E4CE18-41F3-48F6-B142-12947FFBA86C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {57E4CE18-41F3-48F6-B142-12947FFBA86C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {57E4CE18-41F3-48F6-B142-12947FFBA86C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {57E4CE18-41F3-48F6-B142-12947FFBA86C}.Release|Any CPU.Build.0 = Release|Any CPU + {944ADE8F-18E3-4DB8-9098-6A55E026EAC1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {944ADE8F-18E3-4DB8-9098-6A55E026EAC1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {944ADE8F-18E3-4DB8-9098-6A55E026EAC1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {944ADE8F-18E3-4DB8-9098-6A55E026EAC1}.Release|Any CPU.Build.0 = Release|Any CPU + {9F296ECF-97C9-47E6-A794-5AD900ECFE6C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9F296ECF-97C9-47E6-A794-5AD900ECFE6C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9F296ECF-97C9-47E6-A794-5AD900ECFE6C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9F296ECF-97C9-47E6-A794-5AD900ECFE6C}.Release|Any CPU.Build.0 = Release|Any CPU + {7D9F0D85-E906-401A-BDAD-724440B34567}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7D9F0D85-E906-401A-BDAD-724440B34567}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7D9F0D85-E906-401A-BDAD-724440B34567}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7D9F0D85-E906-401A-BDAD-724440B34567}.Release|Any CPU.Build.0 = Release|Any CPU + {DA34DED7-B352-4855-9C7B-9E3D983DBE2E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DA34DED7-B352-4855-9C7B-9E3D983DBE2E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DA34DED7-B352-4855-9C7B-9E3D983DBE2E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DA34DED7-B352-4855-9C7B-9E3D983DBE2E}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {57E4CE18-41F3-48F6-B142-12947FFBA86C} = {CE4AB25B-5501-42E9-B8B4-87B9C20472AC} + {944ADE8F-18E3-4DB8-9098-6A55E026EAC1} = {CE4AB25B-5501-42E9-B8B4-87B9C20472AC} + {9F296ECF-97C9-47E6-A794-5AD900ECFE6C} = {CE4AB25B-5501-42E9-B8B4-87B9C20472AC} + {7D9F0D85-E906-401A-BDAD-724440B34567} = {041F9CFA-B6F7-4DEB-9441-829DE697B1BB} + {DA34DED7-B352-4855-9C7B-9E3D983DBE2E} = {041F9CFA-B6F7-4DEB-9441-829DE697B1BB} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {8A31B449-52DD-4445-A9C4-033A24E25308} + EndGlobalSection + GlobalSection(NDepend) = preSolution + Project = ".\FilterLists.ndproj" + EndGlobalSection +EndGlobal diff --git a/FilterLists.Web.sln b/FilterLists.Web.sln new file mode 100644 index 000000000..9a2220756 --- /dev/null +++ b/FilterLists.Web.sln @@ -0,0 +1,30 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.28803.202 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{6F70E166-BB98-41BE-A137-CB8C7E559174}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FilterLists.Web", "src\FilterLists.Web\FilterLists.Web.csproj", "{FD17DF1D-4D60-454F-8FC7-73DF1B51E9B3}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {FD17DF1D-4D60-454F-8FC7-73DF1B51E9B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FD17DF1D-4D60-454F-8FC7-73DF1B51E9B3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FD17DF1D-4D60-454F-8FC7-73DF1B51E9B3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FD17DF1D-4D60-454F-8FC7-73DF1B51E9B3}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {FD17DF1D-4D60-454F-8FC7-73DF1B51E9B3} = {6F70E166-BB98-41BE-A137-CB8C7E559174} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {925C18D5-4B82-4EA2-B45F-FD7D8F01A80F} + EndGlobalSection +EndGlobal diff --git a/FilterLists.sln b/FilterLists.sln index 8a4a4abb6..4bcdb338e 100644 --- a/FilterLists.sln +++ b/FilterLists.sln @@ -1,6 +1,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.27130.2026 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.28803.202 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FilterLists.Api", "src\FilterLists.Api\FilterLists.Api.csproj", "{57E4CE18-41F3-48F6-B142-12947FFBA86C}" EndProject @@ -29,29 +29,18 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "data", "data", "{8C3C7C63-F data\Tag.json = data\Tag.json EndProjectSection EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{FCA7F77A-9EC6-4C6D-A80E-7DD27FF95673}" - ProjectSection(SolutionItems) = preProject - scripts\build.sh = scripts\build.sh - scripts\cron = scripts\cron - scripts\deploy.sh = scripts\deploy.sh - EndProjectSection -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FilterLists.Agent", "src\FilterLists.Agent\FilterLists.Agent.csproj", "{4F39D132-498D-4A93-9F6C-1C604718300D}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "sql", "sql", "{A4BB2C81-5232-4162-B410-704D123D2C01}" - ProjectSection(SolutionItems) = preProject - scripts\sql\createDb.sql = scripts\sql\createDb.sql - scripts\sql\duplicateRules.sql = scripts\sql\duplicateRules.sql - scripts\sql\orphanedSnapshotsRules.sql = scripts\sql\orphanedSnapshotsRules.sql - scripts\sql\resetSnapshotsRules.sql = scripts\sql\resetSnapshotsRules.sql - scripts\sql\snapshotMetrics.sql = scripts\sql\snapshotMetrics.sql - scripts\sql\snapshotTimeAnalysis.sql = scripts\sql\snapshotTimeAnalysis.sql - EndProjectSection -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FilterLists.Services.Tests", "tests\FilterLists.Services.Tests\FilterLists.Services.Tests.csproj", "{7D9F0D85-E906-401A-BDAD-724440B34567}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FilterLists.Data.Tests", "tests\FilterLists.Data.Tests\FilterLists.Data.Tests.csproj", "{DA34DED7-B352-4855-9C7B-9E3D983DBE2E}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{CE4AB25B-5501-42E9-B8B4-87B9C20472AC}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{041F9CFA-B6F7-4DEB-9441-829DE697B1BB}" +EndProject +Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{B94A5BCD-3BE3-4FE4-AE48-ADCF904A22A4}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -86,12 +75,22 @@ Global {DA34DED7-B352-4855-9C7B-9E3D983DBE2E}.Debug|Any CPU.Build.0 = Debug|Any CPU {DA34DED7-B352-4855-9C7B-9E3D983DBE2E}.Release|Any CPU.ActiveCfg = Release|Any CPU {DA34DED7-B352-4855-9C7B-9E3D983DBE2E}.Release|Any CPU.Build.0 = Release|Any CPU + {B94A5BCD-3BE3-4FE4-AE48-ADCF904A22A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B94A5BCD-3BE3-4FE4-AE48-ADCF904A22A4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B94A5BCD-3BE3-4FE4-AE48-ADCF904A22A4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B94A5BCD-3BE3-4FE4-AE48-ADCF904A22A4}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {A4BB2C81-5232-4162-B410-704D123D2C01} = {FCA7F77A-9EC6-4C6D-A80E-7DD27FF95673} + {57E4CE18-41F3-48F6-B142-12947FFBA86C} = {CE4AB25B-5501-42E9-B8B4-87B9C20472AC} + {944ADE8F-18E3-4DB8-9098-6A55E026EAC1} = {CE4AB25B-5501-42E9-B8B4-87B9C20472AC} + {9F296ECF-97C9-47E6-A794-5AD900ECFE6C} = {CE4AB25B-5501-42E9-B8B4-87B9C20472AC} + {6B3E6765-5B8B-4A23-AD12-7E2BC5F4D2E6} = {CE4AB25B-5501-42E9-B8B4-87B9C20472AC} + {4F39D132-498D-4A93-9F6C-1C604718300D} = {CE4AB25B-5501-42E9-B8B4-87B9C20472AC} + {7D9F0D85-E906-401A-BDAD-724440B34567} = {041F9CFA-B6F7-4DEB-9441-829DE697B1BB} + {DA34DED7-B352-4855-9C7B-9E3D983DBE2E} = {041F9CFA-B6F7-4DEB-9441-829DE697B1BB} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {8A31B449-52DD-4445-A9C4-033A24E25308} diff --git a/codecov.yml b/codecov.yml deleted file mode 100644 index 507fc9694..000000000 --- a/codecov.yml +++ /dev/null @@ -1,8 +0,0 @@ -coverage: - status: - project: - default: - enabled: no - patch: - default: - enabled: no \ No newline at end of file diff --git a/docker-compose.data.tests.yml b/docker-compose.data.tests.yml new file mode 100644 index 000000000..12bedece0 --- /dev/null +++ b/docker-compose.data.tests.yml @@ -0,0 +1,32 @@ +version: "3.7" + +services: + api: + image: collinbarrett/filterlists.api:test-data + build: + context: . + dockerfile: src/FilterLists.Api/Dockerfile + target: test-data + networks: + - test-data + depends_on: + - mariadb + + mariadb: + image: mariadb:10 + networks: + - test-data + environment: + - MYSQL_ROOT_PASSWORD=filterlists + - MYSQL_DATABASE=filterlists + - MYSQL_USER=filterlists + - MYSQL_PASSWORD=filterlists + command: + [ + "mysqld", + "--character-set-server=utf8mb4", + "--collation-server=utf8mb4_unicode_520_ci" + ] + +networks: + test-data: diff --git a/docker-compose.dcproj b/docker-compose.dcproj new file mode 100644 index 000000000..511d1c5d2 --- /dev/null +++ b/docker-compose.dcproj @@ -0,0 +1,20 @@ + + + + 2.1 + Linux + b94a5bcd-3be3-4fe4-ae48-adcf904a22a4 + LaunchBrowser + {Scheme}://localhost:{ServicePort} + filterlists + + + + + + docker-compose.yml + + + + + \ No newline at end of file diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml new file mode 100644 index 000000000..8481650ea --- /dev/null +++ b/docker-compose.prod.yml @@ -0,0 +1,16 @@ +version: "3.7" + +services: + web: + volumes: + - web-static:/app/wwwroot + +networks: + # https://github.com/collinbarrett/wp-host-on-containers/blob/master/docker-compose.nginx.yml + reverse-proxy: + external: + name: wp-host_reverse-proxy + +volumes: + web-static: + \ No newline at end of file diff --git a/docker-compose.services.tests.yml b/docker-compose.services.tests.yml new file mode 100644 index 000000000..cbc23fda8 --- /dev/null +++ b/docker-compose.services.tests.yml @@ -0,0 +1,15 @@ +version: "3.7" + +services: + api: + image: collinbarrett/filterlists.api:test-services + build: + context: . + dockerfile: src/FilterLists.Api/Dockerfile + target: test-services + networks: + - test-services + +networks: + test-services: + \ No newline at end of file diff --git a/docker-compose.vs.debug.yml b/docker-compose.vs.debug.yml new file mode 100644 index 000000000..cf173a8fd --- /dev/null +++ b/docker-compose.vs.debug.yml @@ -0,0 +1,10 @@ +version: "3.7" + +services: + api: + build: + target: build + + web: + build: + target: build diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..1887df5d7 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,63 @@ +version: "3.7" + +services: + nginx: + image: nginx:alpine + restart: always + ports: + - "80:80" + networks: + - reverse-proxy + volumes: + - ./ops/nginx/conf.d:/etc/nginx/conf.d:ro + + web: + image: collinbarrett/filterlists.web:latest + restart: always + build: + context: . + dockerfile: src/FilterLists.Web/Dockerfile + target: final + networks: + - reverse-proxy + + api: + image: collinbarrett/filterlists.api:latest + restart: always + build: + context: . + dockerfile: src/FilterLists.Api/Dockerfile + target: final + networks: + - reverse-proxy + - api + depends_on: + - mariadb + environment: + ConnectionStrings__FilterListsConnection: ${FILTERLISTS_CONNECTION_STRING} + + mariadb: + image: mariadb:10 + restart: always + networks: + - api + volumes: + - data:/var/lib/mysql + environment: + MYSQL_ROOT_PASSWORD: ${FILTERLISTS_MYSQL_ROOT_PASSWORD} + MYSQL_DATABASE: ${FILTERLISTS_MYSQL_DATABASE} + MYSQL_USER: ${FILTERLISTS_MYSQL_USER} + MYSQL_PASSWORD: ${FILTERLISTS_MYSQL_PASSWORD} + command: + [ + "mysqld", + "--character-set-server=utf8mb4", + "--collation-server=utf8mb4_unicode_520_ci" + ] + +networks: + reverse-proxy: + api: + +volumes: + data: diff --git a/FilterLists.postman_collection.json b/ops/FilterLists.postman_collection.json similarity index 100% rename from FilterLists.postman_collection.json rename to ops/FilterLists.postman_collection.json diff --git a/ops/nginx/conf.d/filterlists.conf b/ops/nginx/conf.d/filterlists.conf new file mode 100644 index 000000000..4a92743d3 --- /dev/null +++ b/ops/nginx/conf.d/filterlists.conf @@ -0,0 +1,26 @@ +server { + listen 80 default_server; + + location ^~ /api { + rewrite ^/api/(.*)$ /$1 break; + proxy_pass http://api:5000; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection keep-alive; + proxy_set_header Host $host; + proxy_cache_bypass $http_upgrade; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + location / { + proxy_pass http://web:5000; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection keep-alive; + proxy_set_header Host $host; + proxy_cache_bypass $http_upgrade; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } +} \ No newline at end of file diff --git a/scripts/cron b/ops/scripts/cron similarity index 100% rename from scripts/cron rename to ops/scripts/cron diff --git a/scripts/sql/createDb.sql b/ops/scripts/sql/createDb.sql similarity index 100% rename from scripts/sql/createDb.sql rename to ops/scripts/sql/createDb.sql diff --git a/scripts/sql/duplicateRules.sql b/ops/scripts/sql/duplicateRules.sql similarity index 100% rename from scripts/sql/duplicateRules.sql rename to ops/scripts/sql/duplicateRules.sql diff --git a/scripts/sql/orphanedSnapshotsRules.sql b/ops/scripts/sql/orphanedSnapshotsRules.sql similarity index 100% rename from scripts/sql/orphanedSnapshotsRules.sql rename to ops/scripts/sql/orphanedSnapshotsRules.sql diff --git a/scripts/sql/resetSnapshotsRules.sql b/ops/scripts/sql/resetSnapshotsRules.sql similarity index 100% rename from scripts/sql/resetSnapshotsRules.sql rename to ops/scripts/sql/resetSnapshotsRules.sql diff --git a/scripts/sql/snapshotMetrics.sql b/ops/scripts/sql/snapshotMetrics.sql similarity index 100% rename from scripts/sql/snapshotMetrics.sql rename to ops/scripts/sql/snapshotMetrics.sql diff --git a/scripts/sql/snapshotTimeAnalysis.sql b/ops/scripts/sql/snapshotTimeAnalysis.sql similarity index 100% rename from scripts/sql/snapshotTimeAnalysis.sql rename to ops/scripts/sql/snapshotTimeAnalysis.sql diff --git a/src/FilterLists.Agent/FilterLists.Agent.csproj b/src/FilterLists.Agent/FilterLists.Agent.csproj index b1c5d2c77..f8e7dd8e9 100644 --- a/src/FilterLists.Agent/FilterLists.Agent.csproj +++ b/src/FilterLists.Agent/FilterLists.Agent.csproj @@ -2,15 +2,14 @@ Exe - netcoreapp2.1 + netcoreapp2.2 true latest - ubuntu.18.04-x64 Collin M. Barrett Collin M. Barrett FilterLists The independent, comprehensive directory of filter and host lists for advertisements, trackers, malware, and annoyances. - Copyright (c) 2018 Collin M. Barrett + Copyright (c) 2019 Collin M. Barrett https://github.com/collinbarrett/FilterLists/blob/master/LICENSE https://github.com/collinbarrett/FilterLists/raw/master/imgs/icon_filterlists.png https://github.com/collinbarrett/FilterLists @@ -20,12 +19,12 @@ - + - - - - + + + + diff --git a/src/FilterLists.Api/Dockerfile b/src/FilterLists.Api/Dockerfile new file mode 100644 index 000000000..aac6363fc --- /dev/null +++ b/src/FilterLists.Api/Dockerfile @@ -0,0 +1,65 @@ +# Context: . +# Command: docker build -f src/FilterLists.Api/Dockerfile . + +# init base +FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-alpine as base +WORKDIR /app +ENV DataDirectory__Path "data" +ENV ASPNETCORE_URLS "http://*:5000" +EXPOSE 5000 +ENTRYPOINT ["dotnet", "FilterLists.Api.dll"] + +# init build +FROM mcr.microsoft.com/dotnet/core/sdk:2.2-alpine AS build + +# restore +WORKDIR /app/src +COPY src/FilterLists.Data/FilterLists.Data.csproj FilterLists.Data/ +COPY src/FilterLists.Services/FilterLists.Services.csproj FilterLists.Services/ +WORKDIR /app/src/FilterLists.Api +COPY src/FilterLists.Api/FilterLists.Api.csproj . +RUN dotnet restore + +# build +WORKDIR /app/src +COPY src/FilterLists.Data/. FilterLists.Data/ +COPY src/FilterLists.Services/. FilterLists.Services/ +WORKDIR /app/src/FilterLists.Api +COPY src/FilterLists.Api/. . +RUN dotnet build -c Release --no-restore + +# init Data.Tests +FROM build AS test-data +ENTRYPOINT ["dotnet", "test"] + +# restore Data.Tests +WORKDIR /app/tests/FilterLists.Data.Tests +COPY tests/FilterLists.Data.Tests/FilterLists.Data.Tests.csproj . +RUN dotnet restore + +# build Data.Tests +COPY tests/FilterLists.Data.Tests/. . +RUN dotnet build -c Release --no-restore +COPY data/. data/ + +# init Services.Tests +FROM build AS test-services +ENTRYPOINT ["dotnet", "test"] + +# restore Services.Tests +WORKDIR /app/tests/FilterLists.Services.Tests +COPY tests/FilterLists.Services.Tests/FilterLists.Services.Tests.csproj . +RUN dotnet restore + +# build Services.Tests +COPY tests/FilterLists.Services.Tests/. . +RUN dotnet build -c Release --no-restore + +# publish +FROM build AS publish +RUN dotnet publish -c Release -o out --no-restore --no-build + +# final +FROM base as final +COPY --from=publish /app/src/FilterLists.Api/out . +COPY data/. data/ diff --git a/src/FilterLists.Api/FilterLists.Api.csproj b/src/FilterLists.Api/FilterLists.Api.csproj index fa985d570..a9246a9e1 100644 --- a/src/FilterLists.Api/FilterLists.Api.csproj +++ b/src/FilterLists.Api/FilterLists.Api.csproj @@ -1,33 +1,25 @@  - netcoreapp2.1 + netcoreapp2.2 + InProcess true latest - ubuntu.18.04-x64 /subscriptions/4bcbdfe1-6c65-4c02-820f-7c0e7ec5614f/resourcegroups/FilterLists/providers/microsoft.insights/components/FilterLists /subscriptions/4bcbdfe1-6c65-4c02-820f-7c0e7ec5614f/resourcegroups/FilterLists/providers/microsoft.insights/components/FilterLists Collin M. Barrett Collin M. Barrett FilterLists The independent, comprehensive directory of filter and host lists for advertisements, trackers, malware, and annoyances. - Copyright (c) 2018 Collin M. Barrett + Copyright (c) 2019 Collin M. Barrett https://github.com/collinbarrett/FilterLists/blob/master/LICENSE https://filterlists.com/ https://github.com/collinbarrett/FilterLists/raw/master/imgs/icon_filterlists.png git https://github.com/collinbarrett/FilterLists false - - - - bin\Debug\netcoreapp2.0\FilterLists.Api.xml - 1701;1702;1705;1591 - - - - bin\Release\netcoreapp2.0\FilterLists.Api.xml - 1701;1702;1705;1591 + Exe + ..\..\docker-compose.dcproj @@ -36,12 +28,13 @@ - - - - - + + + + + + diff --git a/src/FilterLists.Api/Migrations/20181019141708_AddRuleRawIndex.Designer.cs b/src/FilterLists.Api/Migrations/20181019141708_AddRuleRawIndex.Designer.cs deleted file mode 100644 index 98d2bc03f..000000000 --- a/src/FilterLists.Api/Migrations/20181019141708_AddRuleRawIndex.Designer.cs +++ /dev/null @@ -1,686 +0,0 @@ -// - -using System; -using FilterLists.Data; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Migrations; - -namespace FilterLists.Api.Migrations -{ - [DbContext(typeof(FilterListsDbContext))] - [Migration("20181019141708_AddRuleRawIndex")] - partial class AddRuleRawIndex - { - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "2.1.4-rtm-31024") - .HasAnnotation("Relational:MaxIdentifierLength", 64); - - modelBuilder.Entity("FilterLists.Data.Entities.FilterList", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("SMALLINT") - .HasAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); - - b.Property("ChatUrl") - .HasColumnType("TEXT"); - - b.Property("CreatedDateUtc") - .IsRequired() - .ValueGeneratedOnAdd() - .HasColumnType("TIMESTAMP") - .HasDefaultValueSql("current_timestamp()"); - - b.Property("Description") - .HasColumnType("TEXT"); - - b.Property("DescriptionSourceUrl") - .HasColumnType("TEXT"); - - b.Property("DonateUrl") - .HasColumnType("TEXT"); - - b.Property("EmailAddress") - .ValueGeneratedOnAdd() - .HasColumnType("VARCHAR(126)") - .HasDefaultValueSql("NULL"); - - b.Property("ForumUrl") - .HasColumnType("TEXT"); - - b.Property("HomeUrl") - .HasColumnType("TEXT"); - - b.Property("IssuesUrl") - .HasColumnType("TEXT"); - - b.Property("LicenseId") - .ValueGeneratedOnAdd() - .HasDefaultValue((short)5); - - b.Property("ModifiedDateUtc") - .IsRequired() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("TIMESTAMP") - .HasDefaultValueSql("current_timestamp() ON UPDATE current_timestamp()"); - - b.Property("Name") - .IsRequired() - .HasColumnType("VARCHAR(126)"); - - b.Property("PolicyUrl") - .HasColumnType("TEXT"); - - b.Property("PublishedDate") - .ValueGeneratedOnAdd() - .HasColumnType("DATETIME") - .HasDefaultValueSql("NULL"); - - b.Property("SubmissionUrl") - .HasColumnType("TEXT"); - - b.Property("SyntaxId"); - - b.Property("UpdatedDate") - .ValueGeneratedOnAdd() - .HasColumnType("DATETIME") - .HasDefaultValueSql("NULL"); - - b.Property("ViewUrl") - .HasColumnType("TEXT"); - - b.Property("ViewUrlMirror1") - .HasColumnType("TEXT"); - - b.Property("ViewUrlMirror2") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("LicenseId"); - - b.HasIndex("SyntaxId"); - - b.ToTable("filterlists"); - }); - - modelBuilder.Entity("FilterLists.Data.Entities.Junctions.Dependent", b => - { - b.Property("DependentFilterListId"); - - b.Property("DependencyFilterListId"); - - b.Property("CreatedDateUtc") - .IsRequired() - .ValueGeneratedOnAdd() - .HasColumnType("TIMESTAMP") - .HasDefaultValueSql("current_timestamp()"); - - b.HasKey("DependentFilterListId", "DependencyFilterListId"); - - b.HasIndex("DependencyFilterListId"); - - b.ToTable("dependents"); - }); - - modelBuilder.Entity("FilterLists.Data.Entities.Junctions.FilterListLanguage", b => - { - b.Property("FilterListId"); - - b.Property("LanguageId"); - - b.Property("CreatedDateUtc") - .IsRequired() - .ValueGeneratedOnAdd() - .HasColumnType("TIMESTAMP") - .HasDefaultValueSql("current_timestamp()"); - - b.HasKey("FilterListId", "LanguageId"); - - b.HasIndex("LanguageId"); - - b.ToTable("filterlists_languages"); - }); - - modelBuilder.Entity("FilterLists.Data.Entities.Junctions.FilterListMaintainer", b => - { - b.Property("FilterListId"); - - b.Property("MaintainerId"); - - b.Property("CreatedDateUtc") - .IsRequired() - .ValueGeneratedOnAdd() - .HasColumnType("TIMESTAMP") - .HasDefaultValueSql("current_timestamp()"); - - b.HasKey("FilterListId", "MaintainerId"); - - b.HasIndex("MaintainerId"); - - b.ToTable("filterlists_maintainers"); - }); - - modelBuilder.Entity("FilterLists.Data.Entities.Junctions.FilterListTag", b => - { - b.Property("FilterListId"); - - b.Property("TagId"); - - b.Property("CreatedDateUtc") - .IsRequired() - .ValueGeneratedOnAdd() - .HasColumnType("TIMESTAMP") - .HasDefaultValueSql("current_timestamp()"); - - b.HasKey("FilterListId", "TagId"); - - b.HasIndex("TagId"); - - b.ToTable("filterlists_tags"); - }); - - modelBuilder.Entity("FilterLists.Data.Entities.Junctions.Fork", b => - { - b.Property("ForkFilterListId"); - - b.Property("UpstreamFilterListId"); - - b.Property("CreatedDateUtc") - .IsRequired() - .ValueGeneratedOnAdd() - .HasColumnType("TIMESTAMP") - .HasDefaultValueSql("current_timestamp()"); - - b.HasKey("ForkFilterListId", "UpstreamFilterListId"); - - b.HasIndex("UpstreamFilterListId"); - - b.ToTable("forks"); - }); - - modelBuilder.Entity("FilterLists.Data.Entities.Junctions.Merge", b => - { - b.Property("MergeFilterListId"); - - b.Property("UpstreamFilterListId"); - - b.Property("CreatedDateUtc") - .IsRequired() - .ValueGeneratedOnAdd() - .HasColumnType("TIMESTAMP") - .HasDefaultValueSql("current_timestamp()"); - - b.HasKey("MergeFilterListId", "UpstreamFilterListId"); - - b.HasIndex("UpstreamFilterListId"); - - b.ToTable("merges"); - }); - - modelBuilder.Entity("FilterLists.Data.Entities.Junctions.SnapshotRule", b => - { - b.Property("SnapshotId"); - - b.Property("RuleId"); - - b.HasKey("SnapshotId", "RuleId"); - - b.HasIndex("RuleId"); - - b.ToTable("snapshots_rules"); - }); - - modelBuilder.Entity("FilterLists.Data.Entities.Junctions.SoftwareSyntax", b => - { - b.Property("SyntaxId"); - - b.Property("SoftwareId"); - - b.Property("CreatedDateUtc") - .IsRequired() - .ValueGeneratedOnAdd() - .HasColumnType("TIMESTAMP") - .HasDefaultValueSql("current_timestamp()"); - - b.HasKey("SyntaxId", "SoftwareId"); - - b.HasIndex("SoftwareId"); - - b.ToTable("software_syntaxes"); - }); - - modelBuilder.Entity("FilterLists.Data.Entities.Language", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("SMALLINT") - .HasAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); - - b.Property("CreatedDateUtc") - .IsRequired() - .ValueGeneratedOnAdd() - .HasColumnType("TIMESTAMP") - .HasDefaultValueSql("current_timestamp()"); - - b.Property("Iso6391") - .ValueGeneratedOnAdd() - .HasColumnType("VARCHAR(2)") - .HasDefaultValueSql("NULL"); - - b.Property("Iso6392") - .ValueGeneratedOnAdd() - .HasColumnType("VARCHAR(3)") - .HasDefaultValueSql("NULL"); - - b.Property("Iso6392B") - .ValueGeneratedOnAdd() - .HasColumnType("VARCHAR(3)") - .HasDefaultValueSql("NULL"); - - b.Property("Iso6392T") - .ValueGeneratedOnAdd() - .HasColumnType("VARCHAR(3)") - .HasDefaultValueSql("NULL"); - - b.Property("Iso6393") - .ValueGeneratedOnAdd() - .HasColumnType("VARCHAR(3)") - .HasDefaultValueSql("NULL"); - - b.Property("LocalName") - .ValueGeneratedOnAdd() - .HasColumnType("VARCHAR(126)") - .HasDefaultValueSql("NULL"); - - b.Property("ModifiedDateUtc") - .IsRequired() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("TIMESTAMP") - .HasDefaultValueSql("current_timestamp() ON UPDATE current_timestamp()"); - - b.Property("Name") - .ValueGeneratedOnAdd() - .HasColumnType("VARCHAR(126)") - .HasDefaultValueSql("NULL"); - - b.HasKey("Id"); - - b.ToTable("languages"); - }); - - modelBuilder.Entity("FilterLists.Data.Entities.License", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("SMALLINT") - .HasAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); - - b.Property("CreatedDateUtc") - .IsRequired() - .ValueGeneratedOnAdd() - .HasColumnType("TIMESTAMP") - .HasDefaultValueSql("current_timestamp()"); - - b.Property("DescriptionUrl") - .HasColumnType("TEXT"); - - b.Property("ModifiedDateUtc") - .IsRequired() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("TIMESTAMP") - .HasDefaultValueSql("current_timestamp() ON UPDATE current_timestamp()"); - - b.Property("Name") - .IsRequired() - .HasColumnType("VARCHAR(126)"); - - b.Property("PermissiveAdaptation"); - - b.Property("PermissiveCommercial"); - - b.HasKey("Id"); - - b.ToTable("licenses"); - }); - - modelBuilder.Entity("FilterLists.Data.Entities.Maintainer", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("SMALLINT") - .HasAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); - - b.Property("CreatedDateUtc") - .IsRequired() - .ValueGeneratedOnAdd() - .HasColumnType("TIMESTAMP") - .HasDefaultValueSql("current_timestamp()"); - - b.Property("EmailAddress") - .ValueGeneratedOnAdd() - .HasColumnType("VARCHAR(126)") - .HasDefaultValueSql("NULL"); - - b.Property("HomeUrl") - .HasColumnType("TEXT"); - - b.Property("ModifiedDateUtc") - .IsRequired() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("TIMESTAMP") - .HasDefaultValueSql("current_timestamp() ON UPDATE current_timestamp()"); - - b.Property("Name") - .IsRequired() - .HasColumnType("VARCHAR(126)"); - - b.Property("TwitterHandle") - .ValueGeneratedOnAdd() - .HasColumnType("VARCHAR(126)") - .HasDefaultValueSql("NULL"); - - b.HasKey("Id"); - - b.ToTable("maintainers"); - }); - - modelBuilder.Entity("FilterLists.Data.Entities.Rule", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INT") - .HasAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); - - b.Property("CreatedDateUtc") - .IsRequired() - .ValueGeneratedOnAdd() - .HasColumnType("TIMESTAMP") - .HasDefaultValueSql("current_timestamp()"); - - b.Property("Raw") - .IsRequired() - .HasColumnType("LONGTEXT"); - - b.HasKey("Id"); - - b.HasIndex("Raw"); - - b.ToTable("rules"); - }); - - modelBuilder.Entity("FilterLists.Data.Entities.Snapshot", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("MEDIUMINT") - .HasAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); - - b.Property("CreatedDateUtc") - .IsRequired() - .ValueGeneratedOnAdd() - .HasColumnType("TIMESTAMP") - .HasDefaultValueSql("current_timestamp()"); - - b.Property("FilterListId"); - - b.Property("HttpStatusCode") - .ValueGeneratedOnAdd() - .HasColumnType("SMALLINT") - .HasDefaultValueSql("NULL"); - - b.Property("Md5Checksum") - .HasColumnType("BINARY(16)"); - - b.Property("ModifiedDateUtc") - .IsRequired() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("TIMESTAMP") - .HasDefaultValueSql("current_timestamp() ON UPDATE current_timestamp()"); - - b.Property("WasSuccessful"); - - b.Property("WasUpdated"); - - b.Property("WaybackTimestamp") - .HasColumnType("TIMESTAMP"); - - b.Property("WaybackUrl") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("FilterListId"); - - b.ToTable("snapshots"); - }); - - modelBuilder.Entity("FilterLists.Data.Entities.Software", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("SMALLINT") - .HasAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); - - b.Property("CreatedDateUtc") - .IsRequired() - .ValueGeneratedOnAdd() - .HasColumnType("TIMESTAMP") - .HasDefaultValueSql("current_timestamp()"); - - b.Property("DownloadUrl") - .HasColumnType("TEXT"); - - b.Property("HomeUrl") - .HasColumnType("TEXT"); - - b.Property("IsAbpSubscribable"); - - b.Property("ModifiedDateUtc") - .IsRequired() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("TIMESTAMP") - .HasDefaultValueSql("current_timestamp() ON UPDATE current_timestamp()"); - - b.Property("Name") - .IsRequired() - .HasColumnType("VARCHAR(126)"); - - b.HasKey("Id"); - - b.ToTable("software"); - }); - - modelBuilder.Entity("FilterLists.Data.Entities.Syntax", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("SMALLINT") - .HasAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); - - b.Property("CreatedDateUtc") - .IsRequired() - .ValueGeneratedOnAdd() - .HasColumnType("TIMESTAMP") - .HasDefaultValueSql("current_timestamp()"); - - b.Property("DefinitionUrl") - .HasColumnType("TEXT"); - - b.Property("ModifiedDateUtc") - .IsRequired() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("TIMESTAMP") - .HasDefaultValueSql("current_timestamp() ON UPDATE current_timestamp()"); - - b.Property("Name") - .IsRequired() - .HasColumnType("VARCHAR(126)"); - - b.HasKey("Id"); - - b.ToTable("syntaxes"); - }); - - modelBuilder.Entity("FilterLists.Data.Entities.Tag", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("SMALLINT") - .HasAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); - - b.Property("CreatedDateUtc") - .IsRequired() - .ValueGeneratedOnAdd() - .HasColumnType("TIMESTAMP") - .HasDefaultValueSql("current_timestamp()"); - - b.Property("Description") - .HasColumnType("TEXT"); - - b.Property("ModifiedDateUtc") - .IsRequired() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("TIMESTAMP") - .HasDefaultValueSql("current_timestamp() ON UPDATE current_timestamp()"); - - b.Property("Name") - .IsRequired() - .HasColumnType("VARCHAR(126)"); - - b.HasKey("Id"); - - b.ToTable("tags"); - }); - - modelBuilder.Entity("FilterLists.Data.Entities.FilterList", b => - { - b.HasOne("FilterLists.Data.Entities.License", "License") - .WithMany("FilterLists") - .HasForeignKey("LicenseId"); - - b.HasOne("FilterLists.Data.Entities.Syntax", "Syntax") - .WithMany("FilterLists") - .HasForeignKey("SyntaxId"); - }); - - modelBuilder.Entity("FilterLists.Data.Entities.Junctions.Dependent", b => - { - b.HasOne("FilterLists.Data.Entities.FilterList", "DependencyFilterList") - .WithMany("DependencyFilterLists") - .HasForeignKey("DependencyFilterListId") - .OnDelete(DeleteBehavior.Cascade); - - b.HasOne("FilterLists.Data.Entities.FilterList", "DependentFilterList") - .WithMany("DependentFilterLists") - .HasForeignKey("DependentFilterListId") - .OnDelete(DeleteBehavior.Cascade); - }); - - modelBuilder.Entity("FilterLists.Data.Entities.Junctions.FilterListLanguage", b => - { - b.HasOne("FilterLists.Data.Entities.FilterList", "FilterList") - .WithMany("FilterListLanguages") - .HasForeignKey("FilterListId") - .OnDelete(DeleteBehavior.Cascade); - - b.HasOne("FilterLists.Data.Entities.Language", "Language") - .WithMany("FilterListLanguages") - .HasForeignKey("LanguageId") - .OnDelete(DeleteBehavior.Cascade); - }); - - modelBuilder.Entity("FilterLists.Data.Entities.Junctions.FilterListMaintainer", b => - { - b.HasOne("FilterLists.Data.Entities.FilterList", "FilterList") - .WithMany("FilterListMaintainers") - .HasForeignKey("FilterListId") - .OnDelete(DeleteBehavior.Cascade); - - b.HasOne("FilterLists.Data.Entities.Maintainer", "Maintainer") - .WithMany("FilterListMaintainers") - .HasForeignKey("MaintainerId") - .OnDelete(DeleteBehavior.Cascade); - }); - - modelBuilder.Entity("FilterLists.Data.Entities.Junctions.FilterListTag", b => - { - b.HasOne("FilterLists.Data.Entities.FilterList", "FilterList") - .WithMany("FilterListTags") - .HasForeignKey("FilterListId") - .OnDelete(DeleteBehavior.Cascade); - - b.HasOne("FilterLists.Data.Entities.Tag", "Tag") - .WithMany("FilterListTags") - .HasForeignKey("TagId") - .OnDelete(DeleteBehavior.Cascade); - }); - - modelBuilder.Entity("FilterLists.Data.Entities.Junctions.Fork", b => - { - b.HasOne("FilterLists.Data.Entities.FilterList", "ForkFilterList") - .WithMany("ForkFilterLists") - .HasForeignKey("ForkFilterListId") - .OnDelete(DeleteBehavior.Cascade); - - b.HasOne("FilterLists.Data.Entities.FilterList", "UpstreamFilterList") - .WithMany("UpstreamForkFilterLists") - .HasForeignKey("UpstreamFilterListId") - .OnDelete(DeleteBehavior.Cascade); - }); - - modelBuilder.Entity("FilterLists.Data.Entities.Junctions.Merge", b => - { - b.HasOne("FilterLists.Data.Entities.FilterList", "MergeFilterList") - .WithMany("MergeFilterLists") - .HasForeignKey("MergeFilterListId") - .OnDelete(DeleteBehavior.Cascade); - - b.HasOne("FilterLists.Data.Entities.FilterList", "UpstreamFilterList") - .WithMany("UpstreamMergeFilterLists") - .HasForeignKey("UpstreamFilterListId") - .OnDelete(DeleteBehavior.Cascade); - }); - - modelBuilder.Entity("FilterLists.Data.Entities.Junctions.SnapshotRule", b => - { - b.HasOne("FilterLists.Data.Entities.Rule", "Rule") - .WithMany("SnapshotRules") - .HasForeignKey("RuleId") - .OnDelete(DeleteBehavior.Cascade); - - b.HasOne("FilterLists.Data.Entities.Snapshot", "Snapshot") - .WithMany("SnapshotRules") - .HasForeignKey("SnapshotId") - .OnDelete(DeleteBehavior.Cascade); - }); - - modelBuilder.Entity("FilterLists.Data.Entities.Junctions.SoftwareSyntax", b => - { - b.HasOne("FilterLists.Data.Entities.Software", "Software") - .WithMany("SoftwareSyntaxes") - .HasForeignKey("SoftwareId") - .OnDelete(DeleteBehavior.Cascade); - - b.HasOne("FilterLists.Data.Entities.Syntax", "Syntax") - .WithMany("SoftwareSyntaxes") - .HasForeignKey("SyntaxId") - .OnDelete(DeleteBehavior.Cascade); - }); - - modelBuilder.Entity("FilterLists.Data.Entities.Snapshot", b => - { - b.HasOne("FilterLists.Data.Entities.FilterList", "FilterList") - .WithMany("Snapshots") - .HasForeignKey("FilterListId") - .OnDelete(DeleteBehavior.Cascade); - }); -#pragma warning restore 612, 618 - } - } -} \ No newline at end of file diff --git a/src/FilterLists.Api/Migrations/20181019141708_AddRuleRawIndex.cs b/src/FilterLists.Api/Migrations/20181019141708_AddRuleRawIndex.cs deleted file mode 100644 index 78c6524b5..000000000 --- a/src/FilterLists.Api/Migrations/20181019141708_AddRuleRawIndex.cs +++ /dev/null @@ -1,24 +0,0 @@ -using FilterLists.Api.Migrations.Extensions; -using Microsoft.EntityFrameworkCore.Migrations; - -namespace FilterLists.Api.Migrations -{ - public partial class AddRuleRawIndex : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateIndex( - "IX_rules_Raw", - "rules", - "Raw", - 3072); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropIndex( - "IX_rules_Raw", - "rules"); - } - } -} \ No newline at end of file diff --git a/src/FilterLists.Api/Migrations/FilterListsDbContextModelSnapshot.cs b/src/FilterLists.Api/Migrations/FilterListsDbContextModelSnapshot.cs index 83cf8ebac..4ea06d109 100644 --- a/src/FilterLists.Api/Migrations/FilterListsDbContextModelSnapshot.cs +++ b/src/FilterLists.Api/Migrations/FilterListsDbContextModelSnapshot.cs @@ -407,8 +407,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id"); - b.HasIndex("Raw"); - b.ToTable("rules"); }); diff --git a/src/FilterLists.Api/Program.cs b/src/FilterLists.Api/Program.cs index 57fa7f2b1..c293ba200 100644 --- a/src/FilterLists.Api/Program.cs +++ b/src/FilterLists.Api/Program.cs @@ -24,7 +24,6 @@ public static void Main(string[] args) private static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) - .UseUrls("http://localhost:5000") .UseApplicationInsights() .UseStartup(); } diff --git a/src/FilterLists.Api/Properties/launchSettings.json b/src/FilterLists.Api/Properties/launchSettings.json index 27a7f46de..99003596b 100644 --- a/src/FilterLists.Api/Properties/launchSettings.json +++ b/src/FilterLists.Api/Properties/launchSettings.json @@ -1,13 +1,10 @@ { + "$schema": "http://json.schemastore.org/launchsettings.json", "profiles": { - "FilterLists.Api": { - "commandName": "Project", + "Docker": { + "commandName": "Docker", "launchBrowser": true, - "launchUrl": "http://localhost:5000/docs/index.html", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - }, - "applicationUrl": "http://localhost:5000/docs/index.html" + "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/docs/index.html" } } } \ No newline at end of file diff --git a/src/FilterLists.Api/appsettings.json b/src/FilterLists.Api/appsettings.json deleted file mode 100644 index 40219fe34..000000000 --- a/src/FilterLists.Api/appsettings.json +++ /dev/null @@ -1,36 +0,0 @@ -/* - WARNING - This file will be checked into source control. Do not change this file. - Use this as an example file only. - Use {env.EnvironmentName}.json as your configuration file as it will not be checked into source control. - {env.EnvironmentName} values : development, staging, production -*/ -{ - "ApplicationInsights": { - "InstrumentationKey": "" - }, - "ConnectionStrings": { - "FilterListsConnection": "" - }, - "DataDirectory": { - "Path": "..\\..\\data" - }, - "Logging": { - "IncludeScopes": false, - "LogLevel": { - "Default": "Debug", - "System": "Information", - "Microsoft": "Information" - } - }, - "SendGrid": { - "ApiKey": "", - "From": { - "Name": "", - "EmailAddress": "" - }, - "To": { - "Name": "", - "EmailAddress": "" - } - } -} \ No newline at end of file diff --git a/src/FilterLists.Data/FilterLists.Data.csproj b/src/FilterLists.Data/FilterLists.Data.csproj index 9720df115..6ddcd79c0 100644 --- a/src/FilterLists.Data/FilterLists.Data.csproj +++ b/src/FilterLists.Data/FilterLists.Data.csproj @@ -4,11 +4,10 @@ netstandard2.0 true latest - ubuntu.18.04-x64 Collin M. Barrett FilterLists The independent, comprehensive directory of filter and host lists for advertisements, trackers, malware, and annoyances. - Copyright (c) 2018 Collin M. Barrett + Copyright (c) 2019 Collin M. Barrett https://github.com/collinbarrett/FilterLists/blob/master/LICENSE https://filterlists.com/ https://github.com/collinbarrett/FilterLists/raw/master/imgs/icon_filterlists.png @@ -18,14 +17,14 @@ - - + + - + all runtime; build; native; contentfiles; analyzers - + \ No newline at end of file diff --git a/src/FilterLists.Data/FilterListsDbContext.cs b/src/FilterLists.Data/FilterListsDbContext.cs index 02c120a38..4970f6443 100644 --- a/src/FilterLists.Data/FilterListsDbContext.cs +++ b/src/FilterLists.Data/FilterListsDbContext.cs @@ -35,7 +35,6 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); ApplyConfigurations(modelBuilder); - modelBuilder.Entity().HasIndex(r => r.Raw); } private static void ApplyConfigurations(ModelBuilder modelBuilder) diff --git a/src/FilterLists.Services/EmailService.cs b/src/FilterLists.Services/EmailService.cs deleted file mode 100644 index 3fffee25f..000000000 --- a/src/FilterLists.Services/EmailService.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System.Threading.Tasks; -using JetBrains.Annotations; -using Microsoft.Extensions.Configuration; -using SendGrid; -using SendGrid.Helpers.Mail; - -namespace FilterLists.Services -{ - [UsedImplicitly] - public class EmailService - { - private readonly SendGridClient sendGridClient; - private readonly EmailAddress fromEmailAddress; - private readonly EmailAddress toEmailAddress; - - public EmailService(IConfiguration configuration) - { - var sendGridConfig = configuration.GetSection("SendGrid"); - sendGridClient = new SendGridClient(sendGridConfig.GetValue("ApiKey")); - fromEmailAddress = new EmailAddress(sendGridConfig.GetSection("From").GetValue("EmailAddress"), - sendGridConfig.GetSection("From").GetValue("Name")); - toEmailAddress = new EmailAddress(sendGridConfig.GetSection("To").GetValue("EmailAddress"), - sendGridConfig.GetSection("To").GetValue("Name")); - } - - public async Task SendEmailAsync(string subjectBody, string message) - { - var msg = new SendGridMessage - { - From = fromEmailAddress, - Subject = "[FilterLists] " + subjectBody, - PlainTextContent = message - }; - msg.AddTo(toEmailAddress); - await sendGridClient.SendEmailAsync(msg); - } - } -} \ No newline at end of file diff --git a/src/FilterLists.Services/FilterLists.Services.csproj b/src/FilterLists.Services/FilterLists.Services.csproj index dec6e0be6..dbab4d666 100644 --- a/src/FilterLists.Services/FilterLists.Services.csproj +++ b/src/FilterLists.Services/FilterLists.Services.csproj @@ -4,11 +4,10 @@ netstandard2.0 true latest - ubuntu.18.04-x64 Collin M. Barrett FilterLists The independent, comprehensive directory of filter and host lists for advertisements, trackers, malware, and annoyances. - Copyright (c) 2018 Collin M. Barrett + Copyright (c) 2019 Collin M. Barrett https://github.com/collinbarrett/FilterLists/blob/master/LICENSE https://github.com/collinbarrett/FilterLists/raw/master/imgs/icon_filterlists.png https://filterlists.com/ @@ -18,15 +17,14 @@ - - - - + + + + - + - - + diff --git a/src/FilterLists.Web/ClientApp/Layout.tsx b/src/FilterLists.Web/ClientApp/Layout.tsx index 02c0e3c92..1f1736118 100644 --- a/src/FilterLists.Web/ClientApp/Layout.tsx +++ b/src/FilterLists.Web/ClientApp/Layout.tsx @@ -34,7 +34,7 @@ const Footer = () => ; const ApiLink = () => - API ; diff --git a/src/FilterLists.Web/ClientApp/modules/home/HomeContainer.tsx b/src/FilterLists.Web/ClientApp/modules/home/HomeContainer.tsx index ea15d3818..9e966e29f 100644 --- a/src/FilterLists.Web/ClientApp/modules/home/HomeContainer.tsx +++ b/src/FilterLists.Web/ClientApp/modules/home/HomeContainer.tsx @@ -41,49 +41,49 @@ export class HomeContainer extends React.Component<{}, IState> { }; fetchLanguages() { - fetch("https://filterlists.com/api/v1/languages") + fetch("/api/v1/languages") .then(r => r.json() as Promise) .then(p => { this.setState({ languages: p }); }); }; fetchLicenses() { - fetch("https://filterlists.com/api/v1/licenses") + fetch("/api/v1/licenses") .then(r => r.json() as Promise) .then(p => { this.setState({ licenses: p }); }); }; fetchLists() { - fetch("https://filterlists.com/api/v1/lists") + fetch("/api/v1/lists") .then(r => r.json() as Promise) .then(p => { this.setState({ lists: p }); }); }; fetchMaintainers() { - fetch("https://filterlists.com/api/v1/maintainers") + fetch("/api/v1/maintainers") .then(r => r.json() as Promise) .then(p => { this.setState({ maintainers: p }); }); }; fetchSoftware() { - fetch("https://filterlists.com/api/v1/software") + fetch("/api/v1/software") .then(r => r.json() as Promise) .then(p => { this.setState({ software: p }); }); }; fetchSyntaxes() { - fetch("https://filterlists.com/api/v1/syntaxes") + fetch("/api/v1/syntaxes") .then(r => r.json() as Promise) .then(p => { this.setState({ syntaxes: p }); }); }; fetchTags() { - fetch("https://filterlists.com/api/v1/tags") + fetch("/api/v1/tags") .then(r => r.json() as Promise) .then(p => { this.setState({ tags: p }); }); }; fetchRuleCount() { - fetch("https://filterlists.com/api/v1/rules") + fetch("/api/v1/rules") .then(r => r.json() as Promise) .then(p => { this.setState({ ruleCount: p }); }); }; diff --git a/src/FilterLists.Web/Dockerfile b/src/FilterLists.Web/Dockerfile new file mode 100644 index 000000000..bf7268737 --- /dev/null +++ b/src/FilterLists.Web/Dockerfile @@ -0,0 +1,31 @@ +# Context: . +# Command: docker build -f src/FilterLists.Web/Dockerfile . + +# init base +FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-alpine as runtime +WORKDIR /app +ENV ASPNETCORE_URLS "http://*:5000" +EXPOSE 5000 +ENTRYPOINT ["dotnet", "FilterLists.Web.dll"] + +# init build +FROM mcr.microsoft.com/dotnet/core/sdk:2.2-alpine AS build +WORKDIR /app +RUN apk add --update nodejs nodejs-npm + +# restore +COPY FilterLists.Web.sln ./ +WORKDIR /app/src/FilterLists.Web/ +COPY src/FilterLists.Web/FilterLists.Web.csproj ./ +WORKDIR /app +RUN dotnet restore + +# publish +WORKDIR /app/src/FilterLists.Web/ +COPY src/FilterLists.Web/. ./ +RUN dotnet publish -c Release -o out --no-restore + +# run +FROM runtime as final +COPY --from=build /app/src/FilterLists.Web/out ./ +VOLUME /app/wwwroot diff --git a/src/FilterLists.Web/FilterLists.Web.csproj b/src/FilterLists.Web/FilterLists.Web.csproj index 309f26f94..2a2a25d7b 100644 --- a/src/FilterLists.Web/FilterLists.Web.csproj +++ b/src/FilterLists.Web/FilterLists.Web.csproj @@ -1,17 +1,17 @@  - netcoreapp2.1 + netcoreapp2.2 + InProcess true latest - ubuntu.18.04-x64 true Latest false Collin M. Barrett FilterLists https://github.com/collinbarrett/FilterLists/blob/master/LICENSE - Copyright (c) 2018 Collin M. Barrett + Copyright (c) 2019 Collin M. Barrett The independent, comprehensive directory of filter and host lists for advertisements, trackers, malware, and annoyances. https://filterlists.com/ https://github.com/collinbarrett/FilterLists/raw/master/imgs/icon_filterlists.png @@ -19,13 +19,15 @@ git true false + ..\..\docker-compose.dcproj - - - + + + + diff --git a/src/FilterLists.Web/Program.cs b/src/FilterLists.Web/Program.cs index 6eefc54f8..82e198464 100644 --- a/src/FilterLists.Web/Program.cs +++ b/src/FilterLists.Web/Program.cs @@ -8,6 +8,6 @@ public static class Program public static void Main(string[] args) => CreateWebHostBuilder(args).Build().Run(); private static IWebHostBuilder CreateWebHostBuilder(string[] args) => - WebHost.CreateDefaultBuilder(args).UseUrls("http://localhost:5001;").UseStartup(); + WebHost.CreateDefaultBuilder(args).UseStartup(); } } \ No newline at end of file diff --git a/src/FilterLists.Web/Properties/launchSettings.json b/src/FilterLists.Web/Properties/launchSettings.json index 0db5cdf24..4fda38730 100644 --- a/src/FilterLists.Web/Properties/launchSettings.json +++ b/src/FilterLists.Web/Properties/launchSettings.json @@ -1,18 +1,10 @@ { - "FilterLists.Web": { - "commandName": "Project", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - }, - "applicationUrl": "http://localhost:5001/" - }, + "$schema": "http://json.schemastore.org/launchsettings.json", "profiles": { - "FilterLists.Web": { - "commandName": "Project", + "Docker": { + "commandName": "Docker", "launchBrowser": true, - "launchUrl": "http://localhost:5001/", - "applicationUrl": "http://localhost:5001/" + "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/" } } } \ No newline at end of file diff --git a/tests/FilterLists.Data.Tests/FilterLists.Data.Tests.csproj b/tests/FilterLists.Data.Tests/FilterLists.Data.Tests.csproj index a35662227..a927e8b19 100644 --- a/tests/FilterLists.Data.Tests/FilterLists.Data.Tests.csproj +++ b/tests/FilterLists.Data.Tests/FilterLists.Data.Tests.csproj @@ -1,14 +1,14 @@ - + - netcoreapp2.1 + netcoreapp2.2 true latest Collin M. Barrett Collin M. Barrett FilterLists The independent, comprehensive directory of filter and host lists for advertisements, trackers, malware, and annoyances. - Copyright (c) 2018 Collin M. Barrett + Copyright (c) 2019 Collin M. Barrett https://github.com/collinbarrett/FilterLists/blob/master/LICENSE https://filterlists.com/ https://github.com/collinbarrett/FilterLists/raw/master/imgs/icon_filterlists.png @@ -17,19 +17,15 @@ - - all - runtime; build; native; contentfiles; analyzers - all runtime; build; native; contentfiles; analyzers - + all runtime; build; native; contentfiles; analyzers - + all @@ -38,7 +34,6 @@ - diff --git a/tests/FilterLists.Data.Tests/SeedFilterListsDbContextTests.cs b/tests/FilterLists.Data.Tests/SeedFilterListsDbContextTests.cs index a90b1b4a6..244b3b17c 100644 --- a/tests/FilterLists.Data.Tests/SeedFilterListsDbContextTests.cs +++ b/tests/FilterLists.Data.Tests/SeedFilterListsDbContextTests.cs @@ -1,42 +1,22 @@ -using System.IO; using FilterLists.Data.Seed.Extensions; using Microsoft.EntityFrameworkCore; -using MySql.Data.MySqlClient; using Xunit; namespace FilterLists.Data.Tests { public class SeedFilterListsDbContextTests { - private const string CiTestServerConnString = "Server=localhost;Uid=travis;"; - private const string CiTestDatabaseConnString = CiTestServerConnString + "Database=filterlistsdatatest;"; - - /// - /// requires "CREATE USER 'travis'@'localhost';" on non-Travis mysql instance - /// [Fact] public async void SeedOrUpdateAsync_DoesNotThrowException() { + const string connString = "Server=mariadb;Database=filterlists;Uid=filterlists;Pwd=filterlists;"; var options = new DbContextOptionsBuilder() - .UseMySql(CiTestDatabaseConnString, m => m.MigrationsAssembly("FilterLists.Api")) + .UseMySql(connString, m => m.MigrationsAssembly("FilterLists.Api")) .Options; using (var context = new FilterListsDbContext(options)) { - await context.Database.EnsureDeletedAsync(); - using (var conn = new MySqlConnection(CiTestServerConnString)) - { - await conn.OpenAsync(); - var cmd = new MySqlCommand( - "CREATE DATABASE filterlistsdatatest CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci;", - conn); - await cmd.ExecuteNonQueryAsync(); - } - - await context.Database.MigrateAsync(); - if (Directory.Exists("../../../../../data")) - await SeedFilterListsDbContext.SeedOrUpdateAsync(context, "../../../../../data"); - else - await SeedFilterListsDbContext.SeedOrUpdateAsync(context, "../../../../../../../../data"); + await context.Database.EnsureCreatedAsync(); + await SeedFilterListsDbContext.SeedOrUpdateAsync(context, "../../../data"); } } } diff --git a/tests/FilterLists.Services.Tests/FilterLists.Services.Tests.csproj b/tests/FilterLists.Services.Tests/FilterLists.Services.Tests.csproj index 5bddc0fc6..a6d92658c 100644 --- a/tests/FilterLists.Services.Tests/FilterLists.Services.Tests.csproj +++ b/tests/FilterLists.Services.Tests/FilterLists.Services.Tests.csproj @@ -1,14 +1,14 @@ - + - netcoreapp2.1 + netcoreapp2.2 true latest Collin M. Barrett Collin M. Barrett FilterLists The independent, comprehensive directory of filter and host lists for advertisements, trackers, malware, and annoyances. - Copyright (c) 2018 Collin M. Barrett + Copyright (c) 2019 Collin M. Barrett https://github.com/collinbarrett/FilterLists/blob/master/LICENSE https://filterlists.com/ https://github.com/collinbarrett/FilterLists/raw/master/imgs/icon_filterlists.png @@ -17,15 +17,11 @@ - - all - runtime; build; native; contentfiles; analyzers - all runtime; build; native; contentfiles; analyzers - + all