diff --git a/NEWS b/NEWS index 3388b9ef..543fde60 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,15 @@ +* Version 2.1.0, March 15. 2019 + +New in this version: + - CPR rule is no longer located on the scannerjob model. + - Matches now have Windows friendly paths. + - Clicking a path in a filescan report will automatically copy it to the clipboard. + - Ordinary users can create domains again. + - Better handling of Libreoffice processes. + - Dead links found during webscan can be viewed properly in the report again. + - Interface for validating domains works again. + - A number of bug fixes: #27664, #27407 and #27037 + * Version 2.0.0, January 17. 2019 New in this version: diff --git a/VERSION b/VERSION index 227cea21..7ec1d6db 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.0.0 +2.1.0 diff --git a/django-os2webscanner/__init__.py b/django-os2webscanner/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/django-os2webscanner/os2webscanner/admin.py b/django-os2webscanner/os2webscanner/admin.py index e905ba95..b32dc6bc 100644 --- a/django-os2webscanner/os2webscanner/admin.py +++ b/django-os2webscanner/os2webscanner/admin.py @@ -15,37 +15,34 @@ # source municipalities ( http://www.os2web.dk/ ) """Admin form configuration.""" +from django.conf import settings from django.contrib import admin -from django.contrib.auth.models import User from django.contrib.auth.admin import UserAdmin - -from django.utils.translation import ugettext, ugettext_lazy as _ - -from django.conf import settings +from django.contrib.auth.models import User +from django.utils.translation import ugettext_lazy as _ from .models.authentication_model import Authentication +from .models.conversionqueueitem_model import ConversionQueueItem +from .models.domains.exchangedomain_model import ExchangeDomain +from .models.domains.filedomain_model import FileDomain +from .models.group_model import Group +from .models.match_model import Match from .models.organization_model import Organization -from .models.userprofile_model import UserProfile -from .models.webdomain_model import WebDomain -from .models.filedomain_model import FileDomain -from .models.exchangedomain_model import ExchangeDomain +from .models.referrerurl_model import ReferrerUrl +from .models.regexpattern_model import RegexPattern from .models.regexrule_model import RegexRule -from .models.scanner_model import Scanner -from .models.match_model import Match +from .models.scans.scan_model import Scan +from .models.scannerjobs.scanner_model import Scanner +from .models.statistic_model import Statistic from .models.url_model import Url -from .models.scan_model import Scan -from .models.conversionqueueitem_model import ConversionQueueItem -from .models.referrerurl_model import ReferrerUrl from .models.urllastmodified_model import UrlLastModified -from .models.group_model import Group -from .models.md5sum_model import Md5Sum -from .models.statistic_model import Statistic -from .models.regexpattern_model import RegexPattern +from .models.userprofile_model import UserProfile +from .models.domains.webdomain_model import WebDomain ar = admin.site.register classes = [Authentication, Organization, WebDomain, FileDomain, ExchangeDomain, RegexRule, Scanner, Scan, Match, Url, ConversionQueueItem, ReferrerUrl, - UrlLastModified, Group, Md5Sum, Statistic, RegexPattern] + UrlLastModified, Group, Statistic, RegexPattern] list(map(ar, classes)) diff --git a/django-os2webscanner/os2webscanner/locale/da/LC_MESSAGES/django.mo b/django-os2webscanner/os2webscanner/locale/da/LC_MESSAGES/django.mo deleted file mode 100644 index f8481bba..00000000 Binary files a/django-os2webscanner/os2webscanner/locale/da/LC_MESSAGES/django.mo and /dev/null differ diff --git a/django-os2webscanner/os2webscanner/locale/da/LC_MESSAGES/django.po b/django-os2webscanner/os2webscanner/locale/da/LC_MESSAGES/django.po index ee66ba97..71e53a45 100644 --- a/django-os2webscanner/os2webscanner/locale/da/LC_MESSAGES/django.po +++ b/django-os2webscanner/os2webscanner/locale/da/LC_MESSAGES/django.po @@ -8,390 +8,146 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-02-05 13:25-0600\n" +"POT-Creation-Date: 2019-02-15 15:02+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" +"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: base.py:871 -msgid "annually" -msgstr "årligt" - -#: base.py:871 -msgid "monthly" -msgstr "månedligt" - -#: base.py:871 -msgid "weekly" -msgstr "ugenligt" - -#: base.py:871 -msgid "daily" -msgstr "dagligt" - -#: base.py:872 -msgid "hourly" -msgstr "time" - -#: base.py:872 -msgid "minutely" -msgstr "pr. minut" - -#: base.py:872 -msgid "secondly" -msgstr "pr. sekund" - -#: base.py:875 -msgid "year" -msgstr "år" - -#: base.py:875 -msgid "month" -msgstr "måned" - -#: base.py:875 -msgid "week" -msgstr "uge" - -#: base.py:875 -msgid "day" -msgstr "dag" - -#: base.py:876 -msgid "hour" -msgstr "time" - -#: base.py:876 -msgid "minute" -msgstr "minut" - -#: base.py:876 -msgid "second" -msgstr "sekund" - -#: base.py:879 -msgid "years" -msgstr "år" - -#: base.py:879 -msgid "months" -msgstr "måneder" - -#: base.py:879 -msgid "weeks" -msgstr "uger" - -#: base.py:879 -msgid "days" -msgstr "dage" - -#: base.py:880 -msgid "hours" -msgstr "timer" - -#: base.py:880 -msgid "minutes" -msgstr "minutter" - -#: base.py:880 -msgid "seconds" -msgstr "sekunder" - -#: base.py:885 -#, python-format -msgid "1st %(weekday)s" -msgstr "1. %(weekday)s" - -#: base.py:886 -#, python-format -msgid "2nd %(weekday)s" -msgstr "2. %(weekday)s" - -#: base.py:887 -#, python-format -msgid "3rd %(weekday)s" -msgstr "3. %(weekday)s" - -#: base.py:888 base.py:907 -#, python-format -msgid "last %(weekday)s" -msgstr "sidste %(weekday)s" - -#: base.py:889 -#, python-format -msgid "2nd last %(weekday)s" -msgstr "2. sidste %(weekday)s" - -#: base.py:890 -#, python-format -msgid "3rd last %(weekday)s" -msgstr "3. sidste %(weekday)s" - -#: base.py:893 -msgid "Mon" -msgstr "Man" - -#: base.py:893 -msgid "Tue" -msgstr "Tir" - -#: base.py:893 -msgid "Wed" -msgstr "Ons" - -#: base.py:894 -msgid "Thu" -msgstr "Tor" - -#: base.py:894 -msgid "Fri" -msgstr "Fre" - -#: base.py:894 -msgid "Sat" -msgstr "Lør" - -#: base.py:894 -msgid "Sun" -msgstr "Søn" - -#: base.py:897 -msgid "Jan" -msgstr "Jan" - -#: base.py:897 -msgid "Feb" -msgstr "Feb" - -#: base.py:897 -msgid "Mar" -msgstr "Mar" - -#: base.py:897 -msgid "Apr" -msgstr "Apr" - -#: base.py:898 base.py:917 choices.py:31 -msgid "May" -msgstr "Maj" - -#: base.py:898 -msgid "Jun" -msgstr "Jun" - -#: base.py:898 -msgid "Jul" -msgstr "Jul" - -#: base.py:898 -msgid "Aug" -msgstr "Aug" - -#: base.py:899 -msgid "Sep" -msgstr "Sep" - -#: base.py:899 -msgid "Oct" -msgstr "Okt" - -#: base.py:899 -msgid "Nov" -msgstr "Nov" - -#: base.py:899 -msgid "Dec" -msgstr "Dec" - -#: base.py:904 -#, python-format -msgid "first %(weekday)s" -msgstr "første %(weekday)s" - -#: base.py:905 -#, python-format -msgid "second %(weekday)s" -msgstr "anden %(weekday)s" - -#: base.py:906 -#, python-format -msgid "third %(weekday)s" -msgstr "tredje %(weekday)s" - -#: base.py:908 -#, python-format -msgid "second last %(weekday)s" -msgstr "anden sidste %(weekday)s" - -#: base.py:909 -#, python-format -msgid "third last %(weekday)s" -msgstr "tredje sidste %(weekday)s" - -#: base.py:912 choices.py:17 -msgid "Monday" -msgstr "Mandag" - -#: base.py:912 choices.py:18 -msgid "Tuesday" -msgstr "Tirsdag" - -#: base.py:912 choices.py:19 -msgid "Wednesday" -msgstr "Onsdag" - -#: base.py:913 choices.py:20 -msgid "Thursday" -msgstr "Torsdag" - -#: base.py:913 choices.py:21 -msgid "Friday" -msgstr "Fredag" +#: django-os2webscanner/os2webscanner/admin.py:86 +msgid "Personal info" +msgstr "" -#: base.py:913 choices.py:22 -msgid "Saturday" -msgstr "Lørdag" +#: django-os2webscanner/os2webscanner/admin.py:88 +msgid "Important dates" +msgstr "" -#: base.py:913 choices.py:23 -msgid "Sunday" -msgstr "Søndag" +#: django-os2webscanner/os2webscanner/templates/os2webscanner/scanner_form.html:86 +msgid "Domæner og regler kan ikke ændres efter scannerjobbet er oprettet." +msgstr "Domæner og regler kan ikke ændres efter scannerjobbet er oprettet." -#: base.py:916 choices.py:27 -msgid "January" -msgstr "Januar" +#: django-os2webscanner/os2webscanner/templates/os2webscanner/scanner_form.html:230 +msgid "" +"Listen af domæner kan ikke redigeres. For at scanne andre domæner, opret da " +"et nyt scannerjob." +msgstr "" +"Listen af domæner kan ikke redigeres. For at scanne andre domæner, opret da " +"et nyt scannerjob." -#: base.py:916 choices.py:28 -msgid "February" -msgstr "Februar" +#: django-os2webscanner/os2webscanner/templates/os2webscanner/scanner_form.html:264 +msgid "" +"Listen af regler kan ikke redigeres. For at scanne med andre regler, opret " +"da et nyt scannerjob." +msgstr "" +"Listen af regler kan ikke redigeres. For at scanne med andre regler, opret " +"da et nyt scannerjob." -#: base.py:916 choices.py:29 -msgid "March" -msgstr "Marts" +#: django-os2webscanner/os2webscanner/templates/password_change_done.html:5 +#: django-os2webscanner/os2webscanner/templates/password_change_done.html:6 +msgid "Password change successful" +msgstr "Kodeord er blevet skiftet." -#: base.py:916 choices.py:30 -msgid "April" -msgstr "April" +#: django-os2webscanner/os2webscanner/templates/password_change_done.html:9 +msgid "Your password was changed." +msgstr "Dit kodeord er ændret" -#: base.py:917 choices.py:32 -msgid "June" -msgstr "Juni" +#: django-os2webscanner/os2webscanner/templates/password_reset_complete.html:10 +msgid "Your password has been set. You may go ahead and log in now." +msgstr "Dit kodeord er blevet gemt. Du kan nu logge ind." -#: base.py:917 choices.py:33 -msgid "July" -msgstr "Juli" +#: django-os2webscanner/os2webscanner/templates/password_reset_complete.html:12 +msgid "Log in" +msgstr "Log ind" -#: base.py:917 choices.py:34 -msgid "August" -msgstr "August" +#: django-os2webscanner/os2webscanner/templates/password_reset_confirm.html:10 +msgid "" +"Please enter your new password twice so we can verify you typed it in " +"correctly." +msgstr "" +"Vær venlig at indtaste dit nye kodeord to gange, så vi kan være sikre på at " +"det er indtastet korrekt." -#: base.py:918 choices.py:35 -msgid "September" -msgstr "September" +#: django-os2webscanner/os2webscanner/templates/password_reset_confirm.html:14 +msgid "New password:" +msgstr "Nyt kodeord:" -#: base.py:918 choices.py:36 -msgid "October" -msgstr "Oktober" +#: django-os2webscanner/os2webscanner/templates/password_reset_confirm.html:18 +msgid "Confirm password:" +msgstr "Gentag kodeord:" -#: base.py:918 choices.py:37 -msgid "November" -msgstr "November" +#: django-os2webscanner/os2webscanner/templates/password_reset_confirm.html:20 +msgid "Change my password" +msgstr "Ændre mit kodeord" -#: base.py:918 choices.py:38 -msgid "December" -msgstr "December" +#: django-os2webscanner/os2webscanner/templates/password_reset_confirm.html:25 +msgid "" +"The password reset link was invalid, possibly because it has already been " +"used. Please request a new password reset." +msgstr "" +"Nullstil kodeords-linket virker ikke. Dette skyldes sandsynligvis at det " +"allerede er blevet brugt.Vær venlig at nulstille dit kodeord igen." -#: base.py:936 base.py:951 base.py:974 base.py:992 -msgid ", " -msgstr "," +#: django-os2webscanner/os2webscanner/templates/password_reset_done.html:8 +msgid "" +"We've emailed you instructions for setting your password, if an account " +"exists with the email you entered. You should receive them shortly." +msgstr "" -#: base.py:942 -#, python-format -msgid "every %(number)s %(freq)s" -msgstr "hver %(number)s %(freq)s" +#: django-os2webscanner/os2webscanner/templates/password_reset_done.html:10 +msgid "" +"If you don't receive an email, please make sure you've entered the address " +"you registered with, and check your spam folder." +msgstr "" -#: base.py:953 base.py:977 +#: django-os2webscanner/os2webscanner/templates/password_reset_email.html:2 #, python-format -msgid "each %(items)s" -msgstr "alle %(items)s" +msgid "" +"You're receiving this email because you requested a password reset for your " +"user account at %(site_name)s." +msgstr "" -#: base.py:956 base.py:965 base.py:969 -#, python-format -msgid "on the %(items)s" -msgstr "på den %(items)s" +#: django-os2webscanner/os2webscanner/templates/password_reset_email.html:4 +msgid "Please go to the following page and choose a new password:" +msgstr "" -#: base.py:984 -msgid "occuring once" -msgstr "forekommende en gang" +#: django-os2webscanner/os2webscanner/templates/password_reset_email.html:8 +msgid "Your username, in case you've forgotten:" +msgstr "" -#: base.py:986 -#, python-format -msgid "occuring %(number)s times" -msgstr "forekommende %(number)s gange" +#: django-os2webscanner/os2webscanner/templates/password_reset_email.html:10 +msgid "Thanks for using our site!" +msgstr "" -#: base.py:989 +#: django-os2webscanner/os2webscanner/templates/password_reset_email.html:12 #, python-format -msgid "until %(date)s" -msgstr "indtil %(date)s" - -#: choices.py:7 -msgid "Secondly" -msgstr "Pr. sekund" - -#: choices.py:8 -msgid "Minutely" -msgstr "Pr. minut" - -#: choices.py:9 -msgid "Hourly" -msgstr "Pr. time" - -#: choices.py:10 -msgid "Daily" -msgstr "Daglig" - -#: choices.py:11 -msgid "Weekly" -msgstr "Ugenligt" - -#: choices.py:12 -msgid "Monthly" -msgstr "Månedligt" - -#: choices.py:13 -msgid "Yearly" -msgstr "Årlig" +msgid "The %(site_name)s team" +msgstr "" -#: choices.py:44 -msgid "Inclusion" -msgstr "Inkluderet" +#: django-os2webscanner/os2webscanner/templates/password_reset_form.html:8 +msgid "" +"Forgotten your password? Enter your email address below, and we'll email " +"instructions for setting a new one." +msgstr "" -#: choices.py:45 -msgid "Exclusion" -msgstr "Ekskluderet" +#: django-os2webscanner/os2webscanner/templates/password_reset_form.html:12 +msgid "Email address:" +msgstr "Email adresse" -#: forms.py:64 -msgid "Invalid frequency." -msgstr "Ugyldig frekvens" +#: django-os2webscanner/os2webscanner/templates/password_reset_form.html:12 +msgid "Reset my password" +msgstr "Nulstil mit kodeord." -#: forms.py:66 -#, python-format -msgid "Max rules exceeded. The limit is %(limit)s" -msgstr "Maks antal regler overskrevet. Græsen er %(limit)s" - -#: forms.py:68 -#, python-format -msgid "Max exclusion rules exceeded. The limit is %(limit)s" -msgstr "Maks antal eksklusion regler overskrevet. Græsen er %(limit)s" +#: webscanner_site/webscanner/settings.py:138 +msgid "Danish" +msgstr "" -#: forms.py:70 -#, python-format -msgid "Max dates exceeded. The limit is %(limit)s" -msgstr "Maks datoer overskredet. Grænsen er %(limit)s" +#: webscanner_site/webscanner/settings.py:139 +msgid "English" +msgstr "" -#: forms.py:72 -#, python-format -msgid "Max exclusion dates exceeded. The limit is %(limit)s" -msgstr "Maks eksklusion datoer overskrevet. Grænsen er %(limit)s" +#~ msgid "" +#~ "Domains and rules cannot be changed after a scanner job has been created." +#~ msgstr "Domæner og regler kan ikke ændres efter scannerjobbet er oprettet." diff --git a/django-os2webscanner/os2webscanner/locale/en/LC_MESSAGES/django.po b/django-os2webscanner/os2webscanner/locale/en/LC_MESSAGES/django.po new file mode 100644 index 00000000..45afdf13 --- /dev/null +++ b/django-os2webscanner/os2webscanner/locale/en/LC_MESSAGES/django.po @@ -0,0 +1,146 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-02-15 15:02+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: django-os2webscanner/os2webscanner/admin.py:86 +msgid "Personal info" +msgstr "" + +#: django-os2webscanner/os2webscanner/admin.py:88 +msgid "Important dates" +msgstr "" + +#: django-os2webscanner/os2webscanner/templates/os2webscanner/scanner_form.html:86 +msgid "Domæner og regler kan ikke ændres efter scannerjobbet er oprettet." +msgstr "" +"Domains and rules cannot be changed after a scanner job has been created." + +#: django-os2webscanner/os2webscanner/templates/os2webscanner/scanner_form.html:230 +msgid "" +"Listen af domæner kan ikke redigeres. For at scanne andre domæner, opret da " +"et nyt scannerjob." +msgstr "" +"The list of domains cannot be edited. To scan other domains, create a new " +"scanner job." + +#: django-os2webscanner/os2webscanner/templates/os2webscanner/scanner_form.html:264 +msgid "" +"Listen af regler kan ikke redigeres. For at scanne med andre regler, opret " +"da et nyt scannerjob." +msgstr "" +"The list of rules cannot be edited. To scan with other rules, create a new " +"scanner job." + +#: django-os2webscanner/os2webscanner/templates/password_change_done.html:5 +#: django-os2webscanner/os2webscanner/templates/password_change_done.html:6 +msgid "Password change successful" +msgstr "" + +#: django-os2webscanner/os2webscanner/templates/password_change_done.html:9 +msgid "Your password was changed." +msgstr "" + +#: django-os2webscanner/os2webscanner/templates/password_reset_complete.html:10 +msgid "Your password has been set. You may go ahead and log in now." +msgstr "" + +#: django-os2webscanner/os2webscanner/templates/password_reset_complete.html:12 +msgid "Log in" +msgstr "" + +#: django-os2webscanner/os2webscanner/templates/password_reset_confirm.html:10 +msgid "" +"Please enter your new password twice so we can verify you typed it in " +"correctly." +msgstr "" + +#: django-os2webscanner/os2webscanner/templates/password_reset_confirm.html:14 +msgid "New password:" +msgstr "" + +#: django-os2webscanner/os2webscanner/templates/password_reset_confirm.html:18 +msgid "Confirm password:" +msgstr "" + +#: django-os2webscanner/os2webscanner/templates/password_reset_confirm.html:20 +msgid "Change my password" +msgstr "" + +#: django-os2webscanner/os2webscanner/templates/password_reset_confirm.html:25 +msgid "" +"The password reset link was invalid, possibly because it has already been " +"used. Please request a new password reset." +msgstr "" + +#: django-os2webscanner/os2webscanner/templates/password_reset_done.html:8 +msgid "" +"We've emailed you instructions for setting your password, if an account " +"exists with the email you entered. You should receive them shortly." +msgstr "" + +#: django-os2webscanner/os2webscanner/templates/password_reset_done.html:10 +msgid "" +"If you don't receive an email, please make sure you've entered the address " +"you registered with, and check your spam folder." +msgstr "" + +#: django-os2webscanner/os2webscanner/templates/password_reset_email.html:2 +#, python-format +msgid "" +"You're receiving this email because you requested a password reset for your " +"user account at %(site_name)s." +msgstr "" + +#: django-os2webscanner/os2webscanner/templates/password_reset_email.html:4 +msgid "Please go to the following page and choose a new password:" +msgstr "" + +#: django-os2webscanner/os2webscanner/templates/password_reset_email.html:8 +msgid "Your username, in case you've forgotten:" +msgstr "" + +#: django-os2webscanner/os2webscanner/templates/password_reset_email.html:10 +msgid "Thanks for using our site!" +msgstr "" + +#: django-os2webscanner/os2webscanner/templates/password_reset_email.html:12 +#, python-format +msgid "The %(site_name)s team" +msgstr "" + +#: django-os2webscanner/os2webscanner/templates/password_reset_form.html:8 +msgid "" +"Forgotten your password? Enter your email address below, and we'll email " +"instructions for setting a new one." +msgstr "" + +#: django-os2webscanner/os2webscanner/templates/password_reset_form.html:12 +msgid "Email address:" +msgstr "" + +#: django-os2webscanner/os2webscanner/templates/password_reset_form.html:12 +msgid "Reset my password" +msgstr "" + +#: webscanner_site/webscanner/settings.py:138 +msgid "Danish" +msgstr "" + +#: webscanner_site/webscanner/settings.py:139 +msgid "English" +msgstr "" diff --git a/django-os2webscanner/os2webscanner/migrations/0053_auto_20190206_1333.py b/django-os2webscanner/os2webscanner/migrations/0053_auto_20190206_1333.py new file mode 100644 index 00000000..72bb6cae --- /dev/null +++ b/django-os2webscanner/os2webscanner/migrations/0053_auto_20190206_1333.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.14 on 2019-02-06 12:33 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('os2webscanner', '0052_auto_20181010_1633'), + ] + + operations = [ + migrations.AlterUniqueTogether( + name='md5sum', + unique_together=set([]), + ), + migrations.RemoveField( + model_name='md5sum', + name='organization', + ), + migrations.DeleteModel( + name='Md5Sum', + ), + ] diff --git a/django-os2webscanner/os2webscanner/migrations/0054_auto_20190213_1626.py b/django-os2webscanner/os2webscanner/migrations/0054_auto_20190213_1626.py new file mode 100644 index 00000000..890936f0 --- /dev/null +++ b/django-os2webscanner/os2webscanner/migrations/0054_auto_20190213_1626.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.14 on 2019-02-13 15:26 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('os2webscanner', '0053_auto_20190206_1333'), + ] + + operations = [ + migrations.RemoveField( + model_name='scanner', + name='do_cpr_ignore_irrelevant', + ), + migrations.RemoveField( + model_name='scanner', + name='do_cpr_modulus11', + ), + migrations.RemoveField( + model_name='scanner', + name='do_cpr_scan', + ), + ] diff --git a/django-os2webscanner/os2webscanner/migrations/0054_filedomain_alias.py b/django-os2webscanner/os2webscanner/migrations/0054_filedomain_alias.py new file mode 100644 index 00000000..ad5246d6 --- /dev/null +++ b/django-os2webscanner/os2webscanner/migrations/0054_filedomain_alias.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.14 on 2019-02-15 13:59 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('os2webscanner', '0053_auto_20190206_1333'), + ] + + operations = [ + migrations.AddField( + model_name='filedomain', + name='alias', + field=models.CharField(max_length=64, null=True, verbose_name='Drevbogstav'), + ), + ] diff --git a/django-os2webscanner/os2webscanner/migrations/0055_auto_20190214_1543.py b/django-os2webscanner/os2webscanner/migrations/0055_auto_20190214_1543.py new file mode 100644 index 00000000..214d821d --- /dev/null +++ b/django-os2webscanner/os2webscanner/migrations/0055_auto_20190214_1543.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.14 on 2019-02-14 14:43 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('os2webscanner', '0054_auto_20190213_1626'), + ] + + operations = [ + migrations.RemoveField( + model_name='scan', + name='do_cpr_ignore_irrelevant', + ), + migrations.RemoveField( + model_name='scan', + name='do_cpr_modulus11', + ), + migrations.RemoveField( + model_name='scan', + name='do_cpr_scan', + ), + ] diff --git a/django-os2webscanner/os2webscanner/migrations/0056_auto_20190219_1058.py b/django-os2webscanner/os2webscanner/migrations/0056_auto_20190219_1058.py new file mode 100644 index 00000000..69fd7a9c --- /dev/null +++ b/django-os2webscanner/os2webscanner/migrations/0056_auto_20190219_1058.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-02-19 09:58 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('os2webscanner', '0055_auto_20190214_1543'), + ] + + operations = [ + migrations.RemoveField( + model_name='exchangescan', + name='scan_ptr', + ), + migrations.RemoveField( + model_name='filescan', + name='scan_ptr', + ), + migrations.DeleteModel( + name='ExchangeScan', + ), + migrations.DeleteModel( + name='FileScan', + ), + ] diff --git a/django-os2webscanner/os2webscanner/migrations/0057_merge_20190307_1543.py b/django-os2webscanner/os2webscanner/migrations/0057_merge_20190307_1543.py new file mode 100644 index 00000000..631dd1fd --- /dev/null +++ b/django-os2webscanner/os2webscanner/migrations/0057_merge_20190307_1543.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-03-07 14:43 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('os2webscanner', '0056_auto_20190219_1058'), + ('os2webscanner', '0054_filedomain_alias'), + ] + + operations = [ + ] diff --git a/django-os2webscanner/os2webscanner/migrations/0058_auto_20190313_1244.py b/django-os2webscanner/os2webscanner/migrations/0058_auto_20190313_1244.py new file mode 100644 index 00000000..e9a99b89 --- /dev/null +++ b/django-os2webscanner/os2webscanner/migrations/0058_auto_20190313_1244.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-03-13 11:44 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('os2webscanner', '0057_merge_20190307_1543'), + ] + + operations = [ + migrations.AlterField( + model_name='match', + name='matched_data', + field=models.TextField(verbose_name='Data match'), + ), + ] diff --git a/django-os2webscanner/os2webscanner/models/__init__.py b/django-os2webscanner/os2webscanner/models/__init__.py index ab2200df..6b0ddfc9 100644 --- a/django-os2webscanner/os2webscanner/models/__init__.py +++ b/django-os2webscanner/os2webscanner/models/__init__.py @@ -1,3 +1,2 @@ # Import needed here for django models: -from os2webscanner.models.filescan_model import FileScan -from os2webscanner.models.exchangescan_model import ExchangeScan + diff --git a/django-os2webscanner/os2webscanner/models/domains/__init__.py b/django-os2webscanner/os2webscanner/models/domains/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/django-os2webscanner/os2webscanner/models/domain_model.py b/django-os2webscanner/os2webscanner/models/domains/domain_model.py similarity index 96% rename from django-os2webscanner/os2webscanner/models/domain_model.py rename to django-os2webscanner/os2webscanner/models/domains/domain_model.py index c6160b83..c608bff2 100644 --- a/django-os2webscanner/os2webscanner/models/domain_model.py +++ b/django-os2webscanner/os2webscanner/models/domains/domain_model.py @@ -20,9 +20,9 @@ from django.db import models -from .authentication_model import Authentication -from .group_model import Group -from .organization_model import Organization +from ..authentication_model import Authentication +from ..group_model import Group +from ..organization_model import Organization class Domain(models.Model): diff --git a/django-os2webscanner/os2webscanner/models/exchangedomain_model.py b/django-os2webscanner/os2webscanner/models/domains/exchangedomain_model.py similarity index 100% rename from django-os2webscanner/os2webscanner/models/exchangedomain_model.py rename to django-os2webscanner/os2webscanner/models/domains/exchangedomain_model.py diff --git a/django-os2webscanner/os2webscanner/models/filedomain_model.py b/django-os2webscanner/os2webscanner/models/domains/filedomain_model.py similarity index 92% rename from django-os2webscanner/os2webscanner/models/filedomain_model.py rename to django-os2webscanner/os2webscanner/models/domains/filedomain_model.py index f4a36c7c..ba45cb21 100644 --- a/django-os2webscanner/os2webscanner/models/filedomain_model.py +++ b/django-os2webscanner/os2webscanner/models/domains/filedomain_model.py @@ -34,6 +34,7 @@ class FileDomain(Domain): """Represents a file domain to be scanned.""" mountpath = models.CharField(max_length=2048, verbose_name='Folder sti', null=True) + alias = models.CharField(max_length=64, verbose_name='Drevbogstav', null=True) # Run error messages MOUNT_FAILED = ( @@ -68,6 +69,7 @@ def smb_mount(self): """Mounts networkdrive if not already mounted.""" if self.check_mountpoint() is 0: + logger.info('{} is already a mount point.'.format(self.mountpath)) return True # Make only one scanner able to scan mounted file directory. @@ -87,13 +89,14 @@ def smb_mount(self): if self.authentication.domain != '': command += ',domain=' + self.authentication.domain - logger.debug('Mount command: {0}'.format(command)) response = call(command, shell=True) if response is not 0: logger.error('Mount failed: {0}'.format(response)) return False + logger.info('{} is mounted.'.format(self.mountpath)) + return True def smb_umount(self): @@ -101,6 +104,7 @@ def smb_umount(self): if self.check_mountpoint() is 0: call('sudo umount -l ' + self.mountpath, shell=True) call('sudo umount -f ' + self.mountpath, shell=True) + logger.info('{} is unmounted.'.format(self.mountpath)) def __str__(self): """Return the URL for the domain.""" diff --git a/django-os2webscanner/os2webscanner/models/webdomain_model.py b/django-os2webscanner/os2webscanner/models/domains/webdomain_model.py similarity index 100% rename from django-os2webscanner/os2webscanner/models/webdomain_model.py rename to django-os2webscanner/os2webscanner/models/domains/webdomain_model.py diff --git a/django-os2webscanner/os2webscanner/models/exchangescan_model.py b/django-os2webscanner/os2webscanner/models/exchangescan_model.py deleted file mode 100644 index b53a418e..00000000 --- a/django-os2webscanner/os2webscanner/models/exchangescan_model.py +++ /dev/null @@ -1,55 +0,0 @@ -from django.db import models -from .scan_model import Scan - - -class ExchangeScan(Scan): - """An actual instance of the exchange scanning process done by a exchange scanner.""" - def __init__(self, *args, **kwargs): - """Initialize a new scan. - - Stores the old status of the scan for later use. - """ - super().__init__(*args, **kwargs) - self._old_status = self.status - -# Create method - copies fields from scanner - @classmethod - def create(scan_cls, scanner): - """ Create and copy fields from scanner. """ - scan = scan_cls( - is_visible=scanner.is_visible, - whitelisted_names=scanner.organization.name_whitelist, - blacklisted_names=scanner.organization.name_blacklist, - whitelisted_addresses=scanner.organization.address_whitelist, - blacklisted_addresses=scanner.organization.address_blacklist, - whitelisted_cprs=scanner.organization.cpr_whitelist, - do_cpr_scan=scanner.do_cpr_scan, - do_name_scan=scanner.do_name_scan, - do_address_scan=scanner.do_address_scan, - do_ocr=scanner.do_ocr, - do_cpr_modulus11=scanner.do_cpr_modulus11, - do_cpr_ignore_irrelevant=scanner.do_cpr_ignore_irrelevant, - do_last_modified_check=scanner.do_last_modified_check, - columns=scanner.columns, - output_spreadsheet_file=scanner.output_spreadsheet_file, - do_cpr_replace=scanner.do_cpr_replace, - cpr_replace_text=scanner.cpr_replace_text, - do_name_replace=scanner.do_name_replace, - name_replace_text=scanner.name_replace_text, - do_address_replace=scanner.do_address_replace, - address_replace_text=scanner.address_replace_text, - ) - # - scanner.is_running = True - scanner.save() - scan.status = Scan.NEW - scan.scanner = scanner - scan.save() - scan.domains.add(*scanner.domains.all()) - scan.regex_rules.add(*scanner.regex_rules.all()) - scan.recipients.add(*scanner.recipients.all()) - - return scan - - class Meta: - db_table = 'os2webscanner_exchangescan' diff --git a/django-os2webscanner/os2webscanner/models/filescan_model.py b/django-os2webscanner/os2webscanner/models/filescan_model.py deleted file mode 100644 index 17787a67..00000000 --- a/django-os2webscanner/os2webscanner/models/filescan_model.py +++ /dev/null @@ -1,77 +0,0 @@ -# -*- coding: UTF-8 -*- -# encoding: utf-8 -# The contents of this file are subject to the Mozilla Public License -# Version 2.0 (the "License"); you may not use this file except in -# compliance with the License. You may obtain a copy of the License at -# http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS IS"basis, -# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License -# for the specific language governing rights and limitations under the -# License. -# -# OS2Webscanner was developed by Magenta in collaboration with OS2 the -# Danish community of open source municipalities (http://www.os2web.dk/). -# -# The code is currently governed by OS2 the Danish community of open -# source municipalities ( http://www.os2web.dk/ ) - -from .scan_model import Scan - - -class FileScan(Scan): - - def __init__(self, *args, **kwargs): - """Initialize a new scan. - - Stores the old status of the scan for later use. - """ - super().__init__(*args, **kwargs) - self._old_status = self.status - - def cleanup_finished_scan(self, log=False): - """Delete pending conversion queue items and remove the scan dir.""" - if self.is_scan_dir_writable(): - self.delete_scan_dir(log) - - # Create method - copies fields from scanner - @classmethod - def create(scan_cls, scanner): - """ Create and copy fields from scanner. """ - scan = scan_cls( - is_visible=scanner.is_visible, - whitelisted_names=scanner.organization.name_whitelist, - blacklisted_names=scanner.organization.name_blacklist, - whitelisted_addresses=scanner.organization.address_whitelist, - blacklisted_addresses=scanner.organization.address_blacklist, - whitelisted_cprs=scanner.organization.cpr_whitelist, - do_cpr_scan=scanner.do_cpr_scan, - do_name_scan=scanner.do_name_scan, - do_address_scan=scanner.do_address_scan, - do_ocr=scanner.do_ocr, - do_cpr_modulus11=scanner.do_cpr_modulus11, - do_cpr_ignore_irrelevant=scanner.do_cpr_ignore_irrelevant, - do_last_modified_check=scanner.do_last_modified_check, - columns=scanner.columns, - output_spreadsheet_file=scanner.output_spreadsheet_file, - do_cpr_replace=scanner.do_cpr_replace, - cpr_replace_text=scanner.cpr_replace_text, - do_name_replace=scanner.do_name_replace, - name_replace_text=scanner.name_replace_text, - do_address_replace=scanner.do_address_replace, - address_replace_text=scanner.address_replace_text - ) - # - scanner.is_running = True - scanner.save() - scan.status = Scan.NEW - scan.scanner = scanner - scan.save() - scan.domains.add(*scanner.domains.all()) - scan.regex_rules.add(*scanner.regex_rules.all()) - scan.recipients.add(*scanner.recipients.all()) - - return scan - - class Meta: - db_table = 'os2webscanner_filescan' diff --git a/django-os2webscanner/os2webscanner/models/match_model.py b/django-os2webscanner/os2webscanner/models/match_model.py index 5099828d..dc703605 100644 --- a/django-os2webscanner/os2webscanner/models/match_model.py +++ b/django-os2webscanner/os2webscanner/models/match_model.py @@ -18,9 +18,9 @@ from django.db import models -from .url_model import Url -from .scan_model import Scan +from .scans.scan_model import Scan from .sensitivity_level import Sensitivity +from .url_model import Url class Match(models.Model): @@ -29,7 +29,7 @@ class Match(models.Model): url = models.ForeignKey(Url, null=False, verbose_name='Url') scan = models.ForeignKey(Scan, null=False, verbose_name='Scan', related_name='matches') - matched_data = models.CharField(max_length=4096, verbose_name='Data match') + matched_data = models.TextField(verbose_name='Data match') matched_rule = models.CharField(max_length=256, verbose_name='Regel match') sensitivity = models.IntegerField(choices=Sensitivity.choices, default=Sensitivity.HIGH, diff --git a/django-os2webscanner/os2webscanner/models/md5sum_model.py b/django-os2webscanner/os2webscanner/models/md5sum_model.py deleted file mode 100644 index 656d1c4d..00000000 --- a/django-os2webscanner/os2webscanner/models/md5sum_model.py +++ /dev/null @@ -1,26 +0,0 @@ -from django.db import models - -from .organization_model import Organization - - -class Md5Sum(models.Model): - - """"Store MD5 sums of binary files to avoid reprocessing.""" - - organization = models.ForeignKey(Organization, - null=False, - verbose_name='Organisation') - md5 = models.CharField(max_length=32, null=False, blank=False) - is_cpr_scan = models.BooleanField() - is_check_mod11 = models.BooleanField() - is_ignore_irrelevant = models.BooleanField() - - class Meta: - unique_together = ('md5', 'is_cpr_scan', 'is_check_mod11', - 'is_ignore_irrelevant', 'organization') - - def __unicode__(self): - return u"{0}: {1}".format(self.organization.name, self.md5) - - def __str__(self): - return u"{0}: {1}".format(self.organization.name, self.md5) \ No newline at end of file diff --git a/django-os2webscanner/os2webscanner/models/referrerurl_model.py b/django-os2webscanner/os2webscanner/models/referrerurl_model.py index 236cabe7..63463446 100644 --- a/django-os2webscanner/os2webscanner/models/referrerurl_model.py +++ b/django-os2webscanner/os2webscanner/models/referrerurl_model.py @@ -1,8 +1,7 @@ -from urllib.request import urlopen - from django.db import models +from urllib.request import urlopen -from .webscan_model import WebScan +from .scans.webscan_model import WebScan class ReferrerUrl(models.Model): diff --git a/django-os2webscanner/os2webscanner/models/scannerjobs/__init__.py b/django-os2webscanner/os2webscanner/models/scannerjobs/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/django-os2webscanner/os2webscanner/models/exchangescanner_model.py b/django-os2webscanner/os2webscanner/models/scannerjobs/exchangescanner_model.py similarity index 91% rename from django-os2webscanner/os2webscanner/models/exchangescanner_model.py rename to django-os2webscanner/os2webscanner/models/scannerjobs/exchangescanner_model.py index 7ce5ed67..6db12a20 100644 --- a/django-os2webscanner/os2webscanner/models/exchangescanner_model.py +++ b/django-os2webscanner/os2webscanner/models/scannerjobs/exchangescanner_model.py @@ -17,8 +17,8 @@ # source municipalities ( http://www.os2web.dk/ ) from django.db import models +from ..domains.exchangedomain_model import ExchangeDomain from .scanner_model import Scanner -from .exchangedomain_model import ExchangeDomain class ExchangeScanner(Scanner): @@ -41,8 +41,7 @@ def get_absolute_url(self): return '/exchangescanners/' def create_scan(self): - from .exchangescan_model import ExchangeScan - return ExchangeScan.create(self) + return super().create_scan() class Meta: db_table = 'os2webscanner_exchangescanner' diff --git a/django-os2webscanner/os2webscanner/models/filescanner_model.py b/django-os2webscanner/os2webscanner/models/scannerjobs/filescanner_model.py similarity index 78% rename from django-os2webscanner/os2webscanner/models/filescanner_model.py rename to django-os2webscanner/os2webscanner/models/scannerjobs/filescanner_model.py index f38b5fe4..91094102 100644 --- a/django-os2webscanner/os2webscanner/models/filescanner_model.py +++ b/django-os2webscanner/os2webscanner/models/scannerjobs/filescanner_model.py @@ -18,8 +18,8 @@ from django.db import models +from ..domains.filedomain_model import FileDomain from .scanner_model import Scanner -from .filedomain_model import FileDomain class FileScanner(Scanner): @@ -34,19 +34,15 @@ def create_scan(self): Creates a file scan. :return: A file scan object """ - # hvad kan gå galt: mount fejler, login er forkert, - # login mangler, login skal slet ikke være der, stien til netværksdrev er forkert. for domain in self.domains.all(): - if domain.url == "//sparketilhjørne": - pass - elif not domain.smb_mount(): + if not domain.smb_mount(): return FileDomain.MOUNT_FAILED - from .filescan_model import FileScan - return FileScan.create(self) + return super().create_scan() + def get_type(self): - return 'file' + return 'file' def get_absolute_url(self): """Get the absolute URL for scanners.""" diff --git a/django-os2webscanner/os2webscanner/models/scanner_model.py b/django-os2webscanner/os2webscanner/models/scannerjobs/scanner_model.py similarity index 90% rename from django-os2webscanner/os2webscanner/models/scanner_model.py rename to django-os2webscanner/os2webscanner/models/scannerjobs/scanner_model.py index dd0c3f61..4885a2a8 100644 --- a/django-os2webscanner/os2webscanner/models/scanner_model.py +++ b/django-os2webscanner/os2webscanner/models/scannerjobs/scanner_model.py @@ -28,10 +28,10 @@ from model_utils.managers import InheritanceManager from recurrence.fields import RecurrenceField -from .organization_model import Organization -from .group_model import Group -from .regexrule_model import RegexRule -from .userprofile_model import UserProfile +from ..organization_model import Organization +from ..group_model import Group +from ..regexrule_model import RegexRule +from ..userprofile_model import UserProfile base_dir = os.path.dirname( os.path.dirname(os.path.dirname(os.path.realpath(__file__)))) @@ -54,8 +54,6 @@ class Scanner(models.Model): schedule = RecurrenceField(max_length=1024, verbose_name='Planlagt afvikling') - do_cpr_scan = models.BooleanField(default=True, verbose_name='CPR') - do_name_scan = models.BooleanField(default=False, verbose_name='Navn') do_address_scan = models.BooleanField(default=False, @@ -66,13 +64,6 @@ class Scanner(models.Model): do_last_modified_check = models.BooleanField(default=True, verbose_name='Tjek sidst ændret dato') - do_cpr_modulus11 = models.BooleanField(default=True, - verbose_name='Tjek modulus-11') - - do_cpr_ignore_irrelevant = models.BooleanField( - default=True, - verbose_name='Ignorer ugyldige fødselsdatoer') - columns = models.CharField(validators=[validate_comma_separated_integer_list], max_length=128, null=True, @@ -236,13 +227,33 @@ def run(self, type, test_only=False, blocking=False, user=None): import json from os2webscanner.amqp_communication import amqp_connection_manager queue_name = 'datascanner' - message = {'type': type, 'id': scan.pk, 'logfile': scan.scan_log_file} + completed_scans = \ + self.webscans.all().filter(start_time__isnull=False, + end_time__isnull=False).order_by('pk') + last_scan_started_at = \ + completed_scans.last().start_time.isoformat() \ + if len(completed_scans) > 0 else None + message = { + 'type': type, + 'id': scan.pk, + 'logfile': scan.scan_log_file, + 'last_started': last_scan_started_at + } amqp_connection_manager.start_amqp(queue_name) amqp_connection_manager.send_message(queue_name, json.dumps(message)) amqp_connection_manager.close_connection() return scan + def create_scan(self): + """ + Creates a file scan. + :return: A file scan object + """ + from ..scans.scan_model import Scan + scan = Scan() + return scan.create(self) + class Meta: abstract = False ordering = ['name'] diff --git a/django-os2webscanner/os2webscanner/models/webscanner_model.py b/django-os2webscanner/os2webscanner/models/scannerjobs/webscanner_model.py similarity index 91% rename from django-os2webscanner/os2webscanner/models/webscanner_model.py rename to django-os2webscanner/os2webscanner/models/scannerjobs/webscanner_model.py index b5ea659d..de7ef06f 100644 --- a/django-os2webscanner/os2webscanner/models/webscanner_model.py +++ b/django-os2webscanner/os2webscanner/models/scannerjobs/webscanner_model.py @@ -19,7 +19,7 @@ from django.db import models from .scanner_model import Scanner -from .webdomain_model import WebDomain +from ..domains.webdomain_model import WebDomain class WebScanner(Scanner): @@ -45,8 +45,9 @@ class WebScanner(Scanner): ) def create_scan(self): - from .webscan_model import WebScan - return WebScan.create(self) + from ..scans.webscan_model import WebScan + webscan = WebScan() + return webscan.create(self) def get_type(self): return 'web' diff --git a/django-os2webscanner/os2webscanner/models/scans/__init__.py b/django-os2webscanner/os2webscanner/models/scans/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/django-os2webscanner/os2webscanner/models/scans/exchangescan_model.py b/django-os2webscanner/os2webscanner/models/scans/exchangescan_model.py new file mode 100644 index 00000000..7af48d93 --- /dev/null +++ b/django-os2webscanner/os2webscanner/models/scans/exchangescan_model.py @@ -0,0 +1,13 @@ +from .scan_model import Scan + + +class ExchangeScan(Scan): + """An actual instance of the exchange scanning process done by a exchange scanner.""" + def __init__(self, *args, **kwargs): + """Initialize a new scan. + + Stores the old status of the scan for later use. + """ + super().__init__(*args, **kwargs) + self._old_status = self.status + diff --git a/django-os2webscanner/os2webscanner/models/scans/filescan_model.py b/django-os2webscanner/os2webscanner/models/scans/filescan_model.py new file mode 100644 index 00000000..c3f0fac5 --- /dev/null +++ b/django-os2webscanner/os2webscanner/models/scans/filescan_model.py @@ -0,0 +1,30 @@ +# -*- coding: UTF-8 -*- +# encoding: utf-8 +# The contents of this file are subject to the Mozilla Public License +# Version 2.0 (the "License"); you may not use this file except in +# compliance with the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS"basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# OS2Webscanner was developed by Magenta in collaboration with OS2 the +# Danish community of open source municipalities (http://www.os2web.dk/). +# +# The code is currently governed by OS2 the Danish community of open +# source municipalities ( http://www.os2web.dk/ ) + +from .scan_model import Scan + + +class FileScan(Scan): + + def __init__(self, *args, **kwargs): + """Initialize a new scan. + + Stores the old status of the scan for later use. + """ + super().__init__(*args, **kwargs) + self._old_status = self.status diff --git a/django-os2webscanner/os2webscanner/models/scan_model.py b/django-os2webscanner/os2webscanner/models/scans/scan_model.py similarity index 87% rename from django-os2webscanner/os2webscanner/models/scan_model.py rename to django-os2webscanner/os2webscanner/models/scans/scan_model.py index 600a8188..53d21c7e 100644 --- a/django-os2webscanner/os2webscanner/models/scan_model.py +++ b/django-os2webscanner/os2webscanner/models/scans/scan_model.py @@ -16,22 +16,20 @@ # The code is currently governed by OS2 the Danish community of open # source municipalities ( http://www.os2web.dk/ ) +import datetime import os import shutil -import datetime - -from django.utils import timezone from django.conf import settings from django.core.validators import validate_comma_separated_integer_list - from django.db import models from django.db.models.aggregates import Count +from django.utils import timezone -from .regexrule_model import RegexRule -from .sensitivity_level import Sensitivity -from .userprofile_model import UserProfile -from .domain_model import Domain -from .scanner_model import Scanner +from ..domains.domain_model import Domain +from ..regexrule_model import RegexRule +from ..scannerjobs.scanner_model import Scanner +from ..sensitivity_level import Sensitivity +from ..userprofile_model import UserProfile timezone.activate(timezone.get_default_timezone()) @@ -78,17 +76,11 @@ def __init__(self, *args, **kwargs): whitelisted_cprs = models.TextField(max_length=4096, blank=True, default="", verbose_name='Godkendte CPR-numre') - - do_cpr_scan = models.BooleanField(default=True, verbose_name='CPR') do_name_scan = models.BooleanField(default=False, verbose_name='Navn') do_address_scan = models.BooleanField(default=False, verbose_name='Adresse') do_ocr = models.BooleanField(default=False, verbose_name='Scan billeder') - do_cpr_modulus11 = models.BooleanField(default=True, - verbose_name='Tjek modulus-11') - do_cpr_ignore_irrelevant = models.BooleanField( - default=True, - verbose_name='Ignorer ugyldige fødselsdatoer') + do_last_modified_check = models.BooleanField(default=True, verbose_name='Tjek sidst ændret dato') @@ -150,7 +142,7 @@ def __init__(self, *args, **kwargs): def get_number_of_failed_conversions(self): """The number conversions that has failed during this scan.""" - from .conversionqueueitem_model import ConversionQueueItem + from ..conversionqueueitem_model import ConversionQueueItem return ConversionQueueItem.objects.filter( url__scan=self, status=ConversionQueueItem.FAILED @@ -180,7 +172,10 @@ def scan_dir(self): @property def scan_log_dir(self): """Return the path to the scan log dir.""" - return os.path.join(settings.VAR_DIR, 'logs', 'scans') + log_dir = os.path.join(settings.VAR_DIR, 'logs', 'scans') + if not os.path.isdir(log_dir): + os.makedirs(log_dir) + return log_dir @property def scan_log_file(self): @@ -300,7 +295,7 @@ def cleanup_finished_scans(cls, scan_age, log=False): def delete_all_pending_conversionqueue_items(self, log): # Delete all pending conversionqueue items - from .conversionqueueitem_model import ConversionQueueItem + from ..conversionqueueitem_model import ConversionQueueItem pending_items = ConversionQueueItem.objects.filter( url__scan=self, status=ConversionQueueItem.NEW @@ -333,7 +328,7 @@ def pause_non_ocr_conversions_on_scans_with_too_many_ocr_items(cls): When the number of OCR items falls below the lower threshold (RESUME_NON_OCR_ITEMS_THRESHOLD), non-OCR conversions are resumed. """ - from .conversionqueueitem_model import ConversionQueueItem + from ..conversionqueueitem_model import ConversionQueueItem ocr_items_by_scan = ConversionQueueItem.objects.filter( status=ConversionQueueItem.NEW, type="ocr" @@ -407,6 +402,41 @@ def set_scanner_status(self, status=False): scanner.is_running = status scanner.save() + # Create method - copies fields from scanner + def create(self, scanner): + """ Create and copy fields from scanner. """ + self.is_visible = scanner.is_visible + self.whitelisted_names = scanner.organization.name_whitelist + self.blacklisted_names = scanner.organization.name_blacklist + self.whitelisted_addresses = scanner.organization.address_whitelist + self.blacklisted_addresses = scanner.organization.address_blacklist + self.whitelisted_cprs = scanner.organization.cpr_whitelist + self.do_name_scan = scanner.do_name_scan + self.do_address_scan = scanner.do_address_scan + self.do_ocr = scanner.do_ocr + self.do_last_modified_check = scanner.do_last_modified_check + self.columns = scanner.columns + self.output_spreadsheet_file = scanner.output_spreadsheet_file + self.do_cpr_replace = scanner.do_cpr_replace + self.cpr_replace_text = scanner.cpr_replace_text + self.do_name_replace = scanner.do_name_replace + self.name_replace_text = scanner.name_replace_text + self.do_address_replace = scanner.do_address_replace + self.address_replace_text = scanner.address_replace_text + self.set_status_new(scanner) + + return self + + def set_status_new(self, scanner): + scanner.is_running = True + scanner.save() + self.status = Scan.NEW + self.scanner = scanner + self.save() + self.domains.add(*scanner.domains.all()) + self.regex_rules.add(*scanner.regex_rules.all()) + self.recipients.add(*scanner.recipients.all()) + class Meta: abstract = False db_table = 'os2webscanner_scan' diff --git a/django-os2webscanner/os2webscanner/models/webscan_model.py b/django-os2webscanner/os2webscanner/models/scans/webscan_model.py similarity index 67% rename from django-os2webscanner/os2webscanner/models/webscan_model.py rename to django-os2webscanner/os2webscanner/models/scans/webscan_model.py index 2dcb69d2..c447dd63 100644 --- a/django-os2webscanner/os2webscanner/models/webscan_model.py +++ b/django-os2webscanner/os2webscanner/models/scans/webscan_model.py @@ -52,52 +52,14 @@ def __init__(self, *args, **kwargs): do_collect_cookies = models.BooleanField(default=False, verbose_name='Saml cookies') - # Statistics - # TODO: Add field for sitemap.xml url count - # Create method - copies fields from scanner - @classmethod - def create(scan_cls, scanner): + def create(self, scanner): """ Create and copy fields from scanner. """ - scan = scan_cls( - is_visible=scanner.is_visible, - whitelisted_names=scanner.organization.name_whitelist, - blacklisted_names=scanner.organization.name_blacklist, - whitelisted_addresses=scanner.organization.address_whitelist, - blacklisted_addresses=scanner.organization.address_blacklist, - whitelisted_cprs=scanner.organization.cpr_whitelist, - do_cpr_scan=scanner.do_cpr_scan, - do_name_scan=scanner.do_name_scan, - do_address_scan=scanner.do_address_scan, - do_ocr=scanner.do_ocr, - do_cpr_modulus11=scanner.do_cpr_modulus11, - do_cpr_ignore_irrelevant=scanner.do_cpr_ignore_irrelevant, - do_link_check=scanner.do_link_check, - do_external_link_check=scanner.do_external_link_check, - do_last_modified_check=scanner.do_last_modified_check, - do_last_modified_check_head_request= - scanner.do_last_modified_check_head_request, - do_collect_cookies=scanner.do_collect_cookies, - columns=scanner.columns, - output_spreadsheet_file=scanner.output_spreadsheet_file, - do_cpr_replace=scanner.do_cpr_replace, - cpr_replace_text=scanner.cpr_replace_text, - do_name_replace=scanner.do_name_replace, - name_replace_text=scanner.name_replace_text, - do_address_replace=scanner.do_address_replace, - address_replace_text=scanner.address_replace_text - ) - # - scanner.is_running = True - scanner.save() - scan.status = Scan.NEW - scan.scanner = scanner - scan.save() - scan.domains.add(*scanner.domains.all()) - scan.regex_rules.add(*scanner.regex_rules.all()) - scan.recipients.add(*scanner.recipients.all()) - - return scan + self.do_link_check = scanner.do_link_check + self.do_external_link_check = scanner.do_external_link_check + self.do_last_modified_check_head_request = scanner.do_last_modified_check_head_request + self.do_collect_cookies = scanner.do_collect_cookies + return super().create(scanner) # Cookie log - undigested cookie strings for inspection. def log_cookie(self, string): diff --git a/django-os2webscanner/os2webscanner/models/statistic_model.py b/django-os2webscanner/os2webscanner/models/statistic_model.py index 35e93e53..f3dffb31 100644 --- a/django-os2webscanner/os2webscanner/models/statistic_model.py +++ b/django-os2webscanner/os2webscanner/models/statistic_model.py @@ -1,6 +1,6 @@ from django.db import models -from .scan_model import Scan +from .scans.scan_model import Scan class Statistic(models.Model): diff --git a/django-os2webscanner/os2webscanner/models/summary_model.py b/django-os2webscanner/os2webscanner/models/summary_model.py index 367f11b0..55ea6a1c 100644 --- a/django-os2webscanner/os2webscanner/models/summary_model.py +++ b/django-os2webscanner/os2webscanner/models/summary_model.py @@ -15,14 +15,13 @@ # The code is currently governed by OS2 the Danish community of open # source municipalities ( http://www.os2web.dk/ ) -from recurrence.fields import RecurrenceField - from django.db import models +from recurrence.fields import RecurrenceField from .group_model import Group from .organization_model import Organization from .userprofile_model import UserProfile -from .webscanner_model import WebScanner +from .scannerjobs.webscanner_model import WebScanner class Summary(models.Model): diff --git a/django-os2webscanner/os2webscanner/models/url_model.py b/django-os2webscanner/os2webscanner/models/url_model.py index 0b25bb9c..1b873d2d 100644 --- a/django-os2webscanner/os2webscanner/models/url_model.py +++ b/django-os2webscanner/os2webscanner/models/url_model.py @@ -17,11 +17,10 @@ # source municipalities ( http://www.os2web.dk/ ) import os -from urllib.request import urlopen - from django.db import models +from urllib.request import urlopen -from .scan_model import Scan +from .scans.scan_model import Scan class Url(models.Model): diff --git a/django-os2webscanner/os2webscanner/models/urllastmodified_model.py b/django-os2webscanner/os2webscanner/models/urllastmodified_model.py index 2e11971c..26c254a6 100644 --- a/django-os2webscanner/os2webscanner/models/urllastmodified_model.py +++ b/django-os2webscanner/os2webscanner/models/urllastmodified_model.py @@ -1,6 +1,6 @@ from django.db import models -from .scanner_model import Scanner +from .scannerjobs.scanner_model import Scanner class UrlLastModified(models.Model): diff --git a/django-os2webscanner/os2webscanner/rpc.py b/django-os2webscanner/os2webscanner/rpc.py index 4a2e15f5..b1fac633 100644 --- a/django-os2webscanner/os2webscanner/rpc.py +++ b/django-os2webscanner/os2webscanner/rpc.py @@ -14,20 +14,18 @@ """ Web service functions, to be invoked over XML-RPC.""" +import csv import os import re -import csv import tempfile - -from django.contrib.auth import authenticate from django.conf import settings +from django.contrib.auth import authenticate from django.utils import six +from django_xmlrpc.decorators import xmlrpc_func -from .utils import do_scan from .models.match_model import Match -from .models.scan_model import Scan - -from django_xmlrpc.decorators import xmlrpc_func +from .models.scans.scan_model import Scan +from .utils import do_scan @xmlrpc_func(returns='string', args=['string', 'string', 'string', 'dict']) diff --git a/django-os2webscanner/os2webscanner/static/admin/js/SelectFilter2.js b/django-os2webscanner/os2webscanner/static/admin/js/SelectFilter2.js deleted file mode 100644 index a7ce6625..00000000 --- a/django-os2webscanner/os2webscanner/static/admin/js/SelectFilter2.js +++ /dev/null @@ -1,169 +0,0 @@ -/* -SelectFilter2 - Turns a multiple-select box into a filter interface. - -Requires core.js, SelectBox.js and addevent.js. -*/ -(function($) { -function findForm(node) { - // returns the node of the form containing the given node - if (node.tagName.toLowerCase() != 'form') { - return findForm(node.parentNode); - } - return node; -} - -window.SelectFilter = { - init: function(field_id, field_name, is_stacked, admin_static_prefix) { - if (field_id.match(/__prefix__/)){ - // Don't intialize on empty forms. - return; - } - var from_box = document.getElementById(field_id); - from_box.id += '_from'; // change its ID - from_box.className = 'filtered form-control'; - - var ps = from_box.parentNode.getElementsByTagName('p'); - for (var i=0; i, because it just gets in the way. - from_box.parentNode.removeChild(ps[i]); - } else if (ps[i].className.indexOf("help") != -1) { - // Move help text up to the top so it isn't below the select - // boxes or wrapped off on the side to the right of the add - // button: - from_box.parentNode.insertBefore(ps[i], from_box.parentNode.firstChild); - } - } - - //
or
- var selector_div = quickElement('div', from_box.parentNode); - selector_div.className = is_stacked ? 'selector stacked' : 'selector'; - - //
- var selector_available = quickElement('div', selector_div, ''); - selector_available.className = 'selector-available'; - var title_available = quickElement('h2', selector_available, interpolate(gettext('Available %s') + ' ', [field_name])); - quickElement('img', title_available, '', 'src', admin_static_prefix + 'img/icon-unknown.gif', 'width', '10', 'height', '10', 'class', 'help help-tooltip', 'title', interpolate(gettext('This is the list of available %s. You may choose some by selecting them in the box below and then clicking the "Choose" arrow between the two boxes.'), [field_name])); - - var filter_p = quickElement('p', selector_available, '', 'id', field_id + '_filter'); - filter_p.className = 'selector-filter'; - - var filter_input = quickElement('input', filter_p, '', 'type', 'text', 'placeholder', gettext("Filter")); - filter_input.id = field_id + '_input'; - filter_input.className = 'form-control'; - - var search_filter_label = quickElement('label', filter_p, '', 'for', field_id + "_input"); - - var search_selector_img = quickElement('img', search_filter_label, '', 'src', admin_static_prefix + 'img/selector-search.gif', 'class', 'help-tooltip', 'alt', '', 'title', interpolate(gettext("Type into this box to filter down the list of available %s."), [field_name])); - - filter_p.appendChild(document.createTextNode(' ')); - - selector_available.appendChild(from_box); - var choose_all = quickElement('a', selector_available, gettext('Choose all') + ' ', 'title', interpolate(gettext('Click to choose all %s at once.'), [field_name]), 'href', 'javascript: (function(){ SelectBox.move_all("' + field_id + '_from", "' + field_id + '_to"); SelectFilter.refresh_icons("' + field_id + '");})()', 'id', field_id + '_add_all_link'); - choose_all.className = 'btn btn-default btn-sm'; - var glyph = quickElement('span', choose_all, '', 'class', 'glyphicon glyphicon-arrow-right'); - - //
    - var selector_chooser = quickElement('ul', selector_div, ''); - selector_chooser.className = 'selector-chooser'; - var add_link = quickElement('a', quickElement('li', selector_chooser, ''), '', 'title', gettext('Choose'), 'href', 'javascript: (function(){ SelectBox.move("' + field_id + '_from","' + field_id + '_to"); SelectFilter.refresh_icons("' + field_id + '");})()', 'id', field_id + '_add_link'); - var add_sr = quickElement('span', add_link, gettext('Choose'), 'class', 'sr-only'); - var glyph_2 = quickElement('span', add_link, '', 'class', 'glyphicon glyphicon-arrow-right'); - add_link.className = ''; - var remove_link = quickElement('a', quickElement('li', selector_chooser, ''), '', 'title', gettext('Remove'), 'href', 'javascript: (function(){ SelectBox.move("' + field_id + '_to","' + field_id + '_from"); SelectFilter.refresh_icons("' + field_id + '");})()', 'id', field_id + '_remove_link'); - var remove_sr = quickElement('span', add_link, gettext('Remove'), 'class', 'sr-only'); - var glyph_3 = quickElement('span', remove_link, '', 'class', 'glyphicon glyphicon-arrow-left'); - remove_link.className = ''; - - //
    - var selector_chosen = quickElement('div', selector_div, ''); - selector_chosen.className = 'selector-chosen'; - var title_chosen = quickElement('h2', selector_chosen, interpolate(gettext('Chosen %s') + ' ', [field_name])); - quickElement('img', title_chosen, '', 'src', admin_static_prefix + 'img/icon-unknown.gif', 'width', '10', 'height', '10', 'class', 'help help-tooltip', 'title', interpolate(gettext('This is the list of chosen %s. You may remove some by selecting them in the box below and then clicking the "Remove" arrow between the two boxes.'), [field_name])); - - var to_box = quickElement('select', selector_chosen, '', 'id', field_id + '_to', 'multiple', 'multiple', 'size', from_box.size, 'name', from_box.getAttribute('name')); - to_box.className = 'filtered form-control'; - var clear_all = quickElement('a', selector_chosen, '', 'title', interpolate(gettext('Click to remove all chosen %s at once.'), [field_name]), 'href', 'javascript: (function() { SelectBox.move_all("' + field_id + '_to", "' + field_id + '_from"); SelectFilter.refresh_icons("' + field_id + '");})()', 'id', field_id + '_remove_all_link'); - var glyph_4 = quickElement('span', clear_all, '', 'class', 'glyphicon glyphicon-arrow-left'); - var remove_all_span = quickElement('span', clear_all, ' ' + gettext('Remove all')); - clear_all.className = 'btn btn-default btn-sm'; - - from_box.setAttribute('name', from_box.getAttribute('name') + '_old'); - - // Set up the JavaScript event handlers for the select box filter interface - addEvent(filter_input, 'keyup', function(e) { SelectFilter.filter_key_up(e, field_id); }); - addEvent(filter_input, 'keydown', function(e) { SelectFilter.filter_key_down(e, field_id); }); - addEvent(from_box, 'change', function(e) { SelectFilter.refresh_icons(field_id) }); - addEvent(to_box, 'change', function(e) { SelectFilter.refresh_icons(field_id) }); - addEvent(from_box, 'dblclick', function() { SelectBox.move(field_id + '_from', field_id + '_to'); SelectFilter.refresh_icons(field_id); }); - addEvent(to_box, 'dblclick', function() { SelectBox.move(field_id + '_to', field_id + '_from'); SelectFilter.refresh_icons(field_id); }); - addEvent(findForm(from_box), 'submit', function() { SelectBox.select_all(field_id + '_to'); }); - SelectBox.init(field_id + '_from'); - SelectBox.init(field_id + '_to'); - // Move selected from_box options to to_box - SelectBox.move(field_id + '_from', field_id + '_to'); - - if (!is_stacked) { - // In horizontal mode, give the same height to the two boxes. - var j_from_box = $(from_box); - var j_to_box = $(to_box); - var resize_filters = function() { j_to_box.height($(filter_p).outerHeight() + j_from_box.outerHeight()); } - if (j_from_box.outerHeight() > 0) { - resize_filters(); // This fieldset is already open. Resize now. - } else { - // This fieldset is probably collapsed. Wait for its 'show' event. - j_to_box.closest('fieldset').one('show.fieldset', resize_filters); - } - } - - // Initial icon refresh - SelectFilter.refresh_icons(field_id); - }, - refresh_icons: function(field_id) { - var from = $('#' + field_id + '_from'); - var to = $('#' + field_id + '_to'); - var is_from_selected = from.find('option:selected').length > 0; - var is_to_selected = to.find('option:selected').length > 0; - // Active if at least one item is selected - $('#' + field_id + '_add_link').toggleClass('active', is_from_selected); - $('#' + field_id + '_remove_link').toggleClass('active', is_to_selected); - // Active if the corresponding box isn't empty - $('#' + field_id + '_add_all_link').toggleClass('active', from.find('option').length > 0); - $('#' + field_id + '_remove_all_link').toggleClass('active', to.find('option').length > 0); - }, - filter_key_up: function(event, field_id) { - var from = document.getElementById(field_id + '_from'); - // don't submit form if user pressed Enter - if ((event.which && event.which == 13) || (event.keyCode && event.keyCode == 13)) { - from.selectedIndex = 0; - SelectBox.move(field_id + '_from', field_id + '_to'); - from.selectedIndex = 0; - return false; - } - var temp = from.selectedIndex; - SelectBox.filter(field_id + '_from', document.getElementById(field_id + '_input').value); - from.selectedIndex = temp; - return true; - }, - filter_key_down: function(event, field_id) { - var from = document.getElementById(field_id + '_from'); - // right arrow -- move across - if ((event.which && event.which == 39) || (event.keyCode && event.keyCode == 39)) { - var old_index = from.selectedIndex; - SelectBox.move(field_id + '_from', field_id + '_to'); - from.selectedIndex = (old_index == from.length) ? from.length - 1 : old_index; - return false; - } - // down arrow -- wrap around - if ((event.which && event.which == 40) || (event.keyCode && event.keyCode == 40)) { - from.selectedIndex = (from.length == from.selectedIndex + 1) ? 0 : from.selectedIndex + 1; - } - // up arrow -- wrap around - if ((event.which && event.which == 38) || (event.keyCode && event.keyCode == 38)) { - from.selectedIndex = (from.selectedIndex == 0) ? from.length - 1 : from.selectedIndex - 1; - } - return true; - } -} - -})(django.jQuery); diff --git a/django-os2webscanner/os2webscanner/static/css/webscanner.css b/django-os2webscanner/os2webscanner/static/css/webscanner.css index 1f8b0abd..d54cc3c5 100755 --- a/django-os2webscanner/os2webscanner/static/css/webscanner.css +++ b/django-os2webscanner/os2webscanner/static/css/webscanner.css @@ -223,12 +223,20 @@ max-width:20%; padding-bottom:0; margin-bottom:-1px; } +#selected_rules .remove-rule.disabled { + pointer-events: none; + cursor: default; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14.588' height='14.588'%3E%3Cpath fill='grey' d='M14.588 1.414L13.173 0l-5.88 5.879L1.414 0 0 1.414l5.879 5.879L0 13.173l1.414 1.415 5.879-5.88 5.88 5.88 1.415-1.415-5.88-5.88z'/%3E%3C/svg%3E"); +} #selected_rules > .selected_rule span:not([data-original-title=""]):hover, #selected_rules > .selected_rule span:not([data-original-title=""]):focus { /* don't give items with empty tooltips the hover style */ border-bottom:1px dotted #999; padding-bottom:0; margin-bottom:calc(.5em - 1px); } +#selected_rules > .selected_rule .disabled { + color: #aaa +} #selected_rules #rules_list { float:right; margin:0 1em 1em 0; @@ -379,3 +387,7 @@ padding:0; .selector-available h2, .selector-chosen h2 { font-size: inherit; } + +input.phantom { +display: none; +} diff --git a/django-os2webscanner/os2webscanner/static/js/ruleselector.js b/django-os2webscanner/os2webscanner/static/js/ruleselector.js index d087541f..fa36f646 100755 --- a/django-os2webscanner/os2webscanner/static/js/ruleselector.js +++ b/django-os2webscanner/os2webscanner/static/js/ruleselector.js @@ -47,20 +47,23 @@ recalcIframeHeight(); }); - // removing a rule from the list of selected rules - $("#selected_rules").on("click", ".remove-rule", function() { - var elm = $(this).closest("div"); // we want the actual parent div, not the a itself - var ruleId = elm.attr("data-rule-id"); - var ruleLi = $("#available_rules").find("li[data-rule-id=\"" + ruleId + "\"]"); - var ruleAnchor = ruleLi.find("a"); - ruleLi.removeAttr("data-disabled"); - ruleAnchor.tooltip(); // re-enable tooltip - $(this).closest("form").find("input[type=\"hidden\"][name=\"regex_rules\"][value=\"" + ruleId + "\"]").remove(); // remove the hidden input field corresponding to the rule we removed - elm.remove(); + if ( $("#edit-scanner-modal-title").length ){ + // removing a rule from the list of selected rules + $("#selected_rules").on("click", ".remove-rule", function() { + var elm = $(this).closest("div"); // we want the actual parent div, not the a itself + var ruleId = elm.attr("data-rule-id"); + var ruleLi = $("#available_rules").find("li[data-rule-id=\"" + ruleId + "\"]"); + var ruleAnchor = ruleLi.find("a"); + ruleLi.removeAttr("data-disabled"); + ruleAnchor.tooltip(); // re-enable tooltip - recalcIframeHeight(); - }); + $(this).closest("form").find("input[type=\"hidden\"][name=\"regex_rules\"][value=\"" + ruleId + "\"]").remove(); // remove the hidden input field corresponding to the rule we removed + elm.remove(); + + recalcIframeHeight(); + }); + } // // adding a system rule // $("#available_rules").on("click", "[data-systemrule-target]:not([data-disabled])", function() { @@ -120,17 +123,4 @@ $("#available_rules").css("max-height", maxHeight + "px"); }); - // function toggleCheckboxGroup(checkbox) { - // var state = checkbox.prop("checked"); - // var checkboxGroup = checkbox.parent(".checkbox-group"); - // var ruleLi = $("[data-systemrule-target=\"" + checkbox.attr("id").replace("id_", "") + "\"]"); - // if(state) { - // checkboxGroup.show(); - // ruleLi.attr("data-disabled", ""); - // } else { - // checkboxGroup.hide(); - // ruleLi.removeAttr("data-disabled"); - // } - // handleSubChoices(checkbox); - // } })(os2web, jQuery); diff --git a/django-os2webscanner/os2webscanner/templates/os2webscanner/domain_form.html b/django-os2webscanner/os2webscanner/templates/os2webscanner/domain_form.html index 6aa84991..0f21eda9 100644 --- a/django-os2webscanner/os2webscanner/templates/os2webscanner/domain_form.html +++ b/django-os2webscanner/os2webscanner/templates/os2webscanner/domain_form.html @@ -76,6 +76,23 @@
+ {% if form.alias %} +
+
+ +
+ + {% if form.alias.help_text %} +

+ {{ form.alias.help_text }} +

+ {% endif %} + {% if form.alias.errors %}{{ form.alias.errors }}{% endif %} +
+
+
+ {% endif %} + {% if form.organization %}
@@ -324,13 +341,13 @@

Indsæt følgende

-
+
{{valid_txt_0|escape}}
-
+
{{valid_txt_1|escape}}
-
+
{{valid_txt_2|escape}}
diff --git a/django-os2webscanner/os2webscanner/templates/os2webscanner/report.html b/django-os2webscanner/os2webscanner/templates/os2webscanner/report.html index 72fefd00..c41994fe 100644 --- a/django-os2webscanner/os2webscanner/templates/os2webscanner/report.html +++ b/django-os2webscanner/os2webscanner/templates/os2webscanner/report.html @@ -22,7 +22,11 @@

Domæner

{% if scan.domains.all and not scan.scanner.process_urls %} {% for domain in scan.domains.all %} - {{domain.url}}
+ {% if domain.filedomain.alias %} + {{domain.filedomain.alias}}: ({{domain.url}})
+ {% else %} + {{domain.url}}
+ {% endif %} {% endfor %} {% endif %} @@ -183,12 +187,15 @@

Resultater

- {% if "file:///" in match.url.url %} + {% if "file://" in match.url.url %} {{ match.url.url|slice:"7:" }} {% else %} {{ match.url.url }} {% endif %} + {% if "file://" in match.url.url %} + + {% endif %} {{ match.get_matched_rule_display }} @@ -257,6 +264,7 @@

Broken Links

{% for referrer in referrer_urls %} @@ -271,10 +279,23 @@

Broken Links

- @@ -524,26 +545,47 @@