Browse Source

flake8 code fixes, other than exceptions

Kevin Cummings 5 years ago
parent
commit
4acec09781
66 changed files with 1262 additions and 176 deletions
  1. 818 0
      coderedcms/Lib/tcl8.6/init.tcl
  2. BIN
      coderedcms/Scripts/_asyncio.pyd
  3. BIN
      coderedcms/Scripts/_bz2.pyd
  4. BIN
      coderedcms/Scripts/_ctypes.pyd
  5. BIN
      coderedcms/Scripts/_ctypes_test.pyd
  6. BIN
      coderedcms/Scripts/_decimal.pyd
  7. BIN
      coderedcms/Scripts/_distutils_findvs.pyd
  8. BIN
      coderedcms/Scripts/_elementtree.pyd
  9. BIN
      coderedcms/Scripts/_hashlib.pyd
  10. BIN
      coderedcms/Scripts/_lzma.pyd
  11. BIN
      coderedcms/Scripts/_msi.pyd
  12. BIN
      coderedcms/Scripts/_multiprocessing.pyd
  13. BIN
      coderedcms/Scripts/_overlapped.pyd
  14. BIN
      coderedcms/Scripts/_socket.pyd
  15. BIN
      coderedcms/Scripts/_sqlite3.pyd
  16. BIN
      coderedcms/Scripts/_ssl.pyd
  17. BIN
      coderedcms/Scripts/_testbuffer.pyd
  18. BIN
      coderedcms/Scripts/_testcapi.pyd
  19. BIN
      coderedcms/Scripts/_testconsole.pyd
  20. BIN
      coderedcms/Scripts/_testimportmultiple.pyd
  21. BIN
      coderedcms/Scripts/_testmultiphase.pyd
  22. BIN
      coderedcms/Scripts/_tkinter.pyd
  23. BIN
      coderedcms/Scripts/pyexpat.pyd
  24. BIN
      coderedcms/Scripts/python.exe
  25. BIN
      coderedcms/Scripts/python3.dll
  26. BIN
      coderedcms/Scripts/python36.dll
  27. BIN
      coderedcms/Scripts/pythonw.exe
  28. BIN
      coderedcms/Scripts/select.pyd
  29. BIN
      coderedcms/Scripts/sqlite3.dll
  30. BIN
      coderedcms/Scripts/tcl86t.dll
  31. BIN
      coderedcms/Scripts/tk86t.dll
  32. BIN
      coderedcms/Scripts/unicodedata.pyd
  33. BIN
      coderedcms/Scripts/vcruntime140.dll
  34. BIN
      coderedcms/Scripts/winsound.pyd
  35. 10 2
      coderedcms/api/mailchimp.py
  36. 13 4
      coderedcms/bin/coderedcms.py
  37. 51 16
      coderedcms/blocks/__init__.py
  38. 8 8
      coderedcms/blocks/base_blocks.py
  39. 1 0
      coderedcms/blocks/content_blocks.py
  40. 19 3
      coderedcms/blocks/html_blocks.py
  41. 3 2
      coderedcms/blocks/layout_blocks.py
  42. 7 1
      coderedcms/blocks/metadata_blocks.py
  43. 6 6
      coderedcms/blocks/stream_form_blocks.py
  44. 2 2
      coderedcms/blocks/tests/test_blocks.py
  45. 2 1
      coderedcms/fields.py
  46. 14 4
      coderedcms/forms.py
  47. 4 4
      coderedcms/models/__init__.py
  48. 15 12
      coderedcms/models/integration_models.py
  49. 119 55
      coderedcms/models/page_models.py
  50. 36 6
      coderedcms/models/snippet_models.py
  51. 10 6
      coderedcms/models/tests/test_page_models.py
  52. 45 8
      coderedcms/models/wagtailsettings_models.py
  53. 3 0
      coderedcms/pyvenv.cfg
  54. 7 3
      coderedcms/settings.py
  55. 21 3
      coderedcms/templatetags/coderedcms_tags.py
  56. 2 2
      coderedcms/tests/settings.py
  57. 7 2
      coderedcms/tests/testapp/models.py
  58. 0 1
      coderedcms/tests/urls.py
  59. 5 2
      coderedcms/urls.py
  60. 6 1
      coderedcms/utils.py
  61. 5 5
      coderedcms/views.py
  62. 4 5
      coderedcms/wagtail_flexible_forms/models.py
  63. 5 5
      coderedcms/wagtail_flexible_forms/wagtail_hooks.py
  64. 12 5
      coderedcms/wagtail_hooks.py
  65. 2 2
      docs/conf.py
  66. BIN
      flake8output.txt

+ 818 - 0
coderedcms/Lib/tcl8.6/init.tcl

@@ -0,0 +1,818 @@
+# init.tcl --
+#
+# Default system startup file for Tcl-based applications.  Defines
+# "unknown" procedure and auto-load facilities.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 Scriptics Corporation.
+# Copyright (c) 2004 by Kevin B. Kenny.  All rights reserved.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+
+# This test intentionally written in pre-7.5 Tcl
+if {[info commands package] == ""} {
+    error "version mismatch: library\nscripts expect Tcl version 7.5b1 or later but the loaded version is\nonly [info patchlevel]"
+}
+package require -exact Tcl 8.6.6
+
+# Compute the auto path to use in this interpreter.
+# The values on the path come from several locations:
+#
+# The environment variable TCLLIBPATH
+#
+# tcl_library, which is the directory containing this init.tcl script.
+# [tclInit] (Tcl_Init()) searches around for the directory containing this
+# init.tcl and defines tcl_library to that location before sourcing it.
+#
+# The parent directory of tcl_library. Adding the parent
+# means that packages in peer directories will be found automatically.
+#
+# Also add the directory ../lib relative to the directory where the
+# executable is located.  This is meant to find binary packages for the
+# same architecture as the current executable.
+#
+# tcl_pkgPath, which is set by the platform-specific initialization routines
+#	On UNIX it is compiled in
+#       On Windows, it is not used
+
+if {![info exists auto_path]} {
+    if {[info exists env(TCLLIBPATH)]} {
+	set auto_path $env(TCLLIBPATH)
+    } else {
+	set auto_path ""
+    }
+}
+namespace eval tcl {
+    variable Dir
+    foreach Dir [list $::tcl_library [file dirname $::tcl_library]] {
+	if {$Dir ni $::auto_path} {
+	    lappend ::auto_path $Dir
+	}
+    }
+    set Dir [file join [file dirname [file dirname \
+	    [info nameofexecutable]]] lib]
+    if {$Dir ni $::auto_path} {
+	lappend ::auto_path $Dir
+    }
+    catch {
+	foreach Dir $::tcl_pkgPath {
+	    if {$Dir ni $::auto_path} {
+		lappend ::auto_path $Dir
+	    }
+	}
+    }
+
+    if {![interp issafe]} {
+        variable Path [encoding dirs]
+        set Dir [file join $::tcl_library encoding]
+        if {$Dir ni $Path} {
+	    lappend Path $Dir
+	    encoding dirs $Path
+        }
+    }
+
+    # TIP #255 min and max functions
+    namespace eval mathfunc {
+	proc min {args} {
+	    if {![llength $args]} {
+		return -code error \
+		    "too few arguments to math function \"min\""
+	    }
+	    set val Inf
+	    foreach arg $args {
+		# This will handle forcing the numeric value without
+		# ruining the internal type of a numeric object
+		if {[catch {expr {double($arg)}} err]} {
+		    return -code error $err
+		}
+		if {$arg < $val} {set val $arg}
+	    }
+	    return $val
+	}
+	proc max {args} {
+	    if {![llength $args]} {
+		return -code error \
+		    "too few arguments to math function \"max\""
+	    }
+	    set val -Inf
+	    foreach arg $args {
+		# This will handle forcing the numeric value without
+		# ruining the internal type of a numeric object
+		if {[catch {expr {double($arg)}} err]} {
+		    return -code error $err
+		}
+		if {$arg > $val} {set val $arg}
+	    }
+	    return $val
+	}
+	namespace export min max
+    }
+}
+
+# Windows specific end of initialization
+
+if {(![interp issafe]) && ($tcl_platform(platform) eq "windows")} {
+    namespace eval tcl {
+	proc EnvTraceProc {lo n1 n2 op} {
+	    global env
+	    set x $env($n2)
+	    set env($lo) $x
+	    set env([string toupper $lo]) $x
+	}
+	proc InitWinEnv {} {
+	    global env tcl_platform
+	    foreach p [array names env] {
+		set u [string toupper $p]
+		if {$u ne $p} {
+		    switch -- $u {
+			COMSPEC -
+			PATH {
+			    set temp $env($p)
+			    unset env($p)
+			    set env($u) $temp
+			    trace add variable env($p) write \
+				    [namespace code [list EnvTraceProc $p]]
+			    trace add variable env($u) write \
+				    [namespace code [list EnvTraceProc $p]]
+			}
+		    }
+		}
+	    }
+	    if {![info exists env(COMSPEC)]} {
+		set env(COMSPEC) cmd.exe
+	    }
+	}
+	InitWinEnv
+    }
+}
+
+# Setup the unknown package handler
+
+
+if {[interp issafe]} {
+    package unknown {::tcl::tm::UnknownHandler ::tclPkgUnknown}
+} else {
+    # Set up search for Tcl Modules (TIP #189).
+    # and setup platform specific unknown package handlers
+    if {$tcl_platform(os) eq "Darwin"
+	    && $tcl_platform(platform) eq "unix"} {
+	package unknown {::tcl::tm::UnknownHandler \
+		{::tcl::MacOSXPkgUnknown ::tclPkgUnknown}}
+    } else {
+	package unknown {::tcl::tm::UnknownHandler ::tclPkgUnknown}
+    }
+
+    # Set up the 'clock' ensemble
+
+    namespace eval ::tcl::clock [list variable TclLibDir $::tcl_library]
+
+    proc clock args {
+	namespace eval ::tcl::clock [list namespace ensemble create -command \
+		[uplevel 1 [list namespace origin [lindex [info level 0] 0]]] \
+		-subcommands {
+		    add clicks format microseconds milliseconds scan seconds
+		}]
+
+	# Auto-loading stubs for 'clock.tcl'
+
+	foreach cmd {add format scan} {
+	    proc ::tcl::clock::$cmd args {
+		variable TclLibDir
+		source -encoding utf-8 [file join $TclLibDir clock.tcl]
+		return [uplevel 1 [info level 0]]
+	    }
+	}
+
+	return [uplevel 1 [info level 0]]
+    }
+}
+
+# Conditionalize for presence of exec.
+
+if {[namespace which -command exec] eq ""} {
+
+    # Some machines do not have exec. Also, on all
+    # platforms, safe interpreters do not have exec.
+
+    set auto_noexec 1
+}
+
+# Define a log command (which can be overwitten to log errors
+# differently, specially when stderr is not available)
+
+if {[namespace which -command tclLog] eq ""} {
+    proc tclLog {string} {
+	catch {puts stderr $string}
+    }
+}
+
+# unknown --
+# This procedure is called when a Tcl command is invoked that doesn't
+# exist in the interpreter.  It takes the following steps to make the
+# command available:
+#
+#	1. See if the autoload facility can locate the command in a
+#	   Tcl script file.  If so, load it and execute it.
+#	2. If the command was invoked interactively at top-level:
+#	    (a) see if the command exists as an executable UNIX program.
+#		If so, "exec" the command.
+#	    (b) see if the command requests csh-like history substitution
+#		in one of the common forms !!, !<number>, or ^old^new.  If
+#		so, emulate csh's history substitution.
+#	    (c) see if the command is a unique abbreviation for another
+#		command.  If so, invoke the command.
+#
+# Arguments:
+# args -	A list whose elements are the words of the original
+#		command, including the command name.
+
+proc unknown args {
+    variable ::tcl::UnknownPending
+    global auto_noexec auto_noload env tcl_interactive errorInfo errorCode
+
+    if {[info exists errorInfo]} {
+	set savedErrorInfo $errorInfo
+    }
+    if {[info exists errorCode]} {
+	set savedErrorCode $errorCode
+    }
+
+    set name [lindex $args 0]
+    if {![info exists auto_noload]} {
+	#
+	# Make sure we're not trying to load the same proc twice.
+	#
+	if {[info exists UnknownPending($name)]} {
+	    return -code error "self-referential recursion\
+		    in \"unknown\" for command \"$name\""
+	}
+	set UnknownPending($name) pending
+	set ret [catch {
+		auto_load $name [uplevel 1 {::namespace current}]
+	} msg opts]
+	unset UnknownPending($name)
+	if {$ret != 0} {
+	    dict append opts -errorinfo "\n    (autoloading \"$name\")"
+	    return -options $opts $msg
+	}
+	if {![array size UnknownPending]} {
+	    unset UnknownPending
+	}
+	if {$msg} {
+	    if {[info exists savedErrorCode]} {
+		set ::errorCode $savedErrorCode
+	    } else {
+		unset -nocomplain ::errorCode
+	    }
+	    if {[info exists savedErrorInfo]} {
+		set errorInfo $savedErrorInfo
+	    } else {
+		unset -nocomplain errorInfo
+	    }
+	    set code [catch {uplevel 1 $args} msg opts]
+	    if {$code ==  1} {
+		#
+		# Compute stack trace contribution from the [uplevel].
+		# Note the dependence on how Tcl_AddErrorInfo, etc.
+		# construct the stack trace.
+		#
+		set errInfo [dict get $opts -errorinfo]
+		set errCode [dict get $opts -errorcode]
+		set cinfo $args
+		if {[string bytelength $cinfo] > 150} {
+		    set cinfo [string range $cinfo 0 150]
+		    while {[string bytelength $cinfo] > 150} {
+			set cinfo [string range $cinfo 0 end-1]
+		    }
+		    append cinfo ...
+		}
+		append cinfo "\"\n    (\"uplevel\" body line 1)"
+		append cinfo "\n    invoked from within"
+		append cinfo "\n\"uplevel 1 \$args\""
+		#
+		# Try each possible form of the stack trace
+		# and trim the extra contribution from the matching case
+		#
+		set expect "$msg\n    while executing\n\"$cinfo"
+		if {$errInfo eq $expect} {
+		    #
+		    # The stack has only the eval from the expanded command
+		    # Do not generate any stack trace here.
+		    #
+		    dict unset opts -errorinfo
+		    dict incr opts -level
+		    return -options $opts $msg
+		}
+		#
+		# Stack trace is nested, trim off just the contribution
+		# from the extra "eval" of $args due to the "catch" above.
+		#
+		set expect "\n    invoked from within\n\"$cinfo"
+		set exlen [string length $expect]
+		set eilen [string length $errInfo]
+		set i [expr {$eilen - $exlen - 1}]
+		set einfo [string range $errInfo 0 $i]
+		#
+		# For now verify that $errInfo consists of what we are about
+		# to return plus what we expected to trim off.
+		#
+		if {$errInfo ne "$einfo$expect"} {
+		    error "Tcl bug: unexpected stack trace in \"unknown\"" {} \
+			[list CORE UNKNOWN BADTRACE $einfo $expect $errInfo]
+		}
+		return -code error -errorcode $errCode \
+			-errorinfo $einfo $msg
+	    } else {
+		dict incr opts -level
+		return -options $opts $msg
+	    }
+	}
+    }
+
+    if {([info level] == 1) && ([info script] eq "")
+	    && [info exists tcl_interactive] && $tcl_interactive} {
+	if {![info exists auto_noexec]} {
+	    set new [auto_execok $name]
+	    if {$new ne ""} {
+		set redir ""
+		if {[namespace which -command console] eq ""} {
+		    set redir ">&@stdout <@stdin"
+		}
+		uplevel 1 [list ::catch \
+			[concat exec $redir $new [lrange $args 1 end]] \
+			::tcl::UnknownResult ::tcl::UnknownOptions]
+		dict incr ::tcl::UnknownOptions -level
+		return -options $::tcl::UnknownOptions $::tcl::UnknownResult
+	    }
+	}
+	if {$name eq "!!"} {
+	    set newcmd [history event]
+	} elseif {[regexp {^!(.+)$} $name -> event]} {
+	    set newcmd [history event $event]
+	} elseif {[regexp {^\^([^^]*)\^([^^]*)\^?$} $name -> old new]} {
+	    set newcmd [history event -1]
+	    catch {regsub -all -- $old $newcmd $new newcmd}
+	}
+	if {[info exists newcmd]} {
+	    tclLog $newcmd
+	    history change $newcmd 0
+	    uplevel 1 [list ::catch $newcmd \
+		    ::tcl::UnknownResult ::tcl::UnknownOptions]
+	    dict incr ::tcl::UnknownOptions -level
+	    return -options $::tcl::UnknownOptions $::tcl::UnknownResult
+	}
+
+	set ret [catch {set candidates [info commands $name*]} msg]
+	if {$name eq "::"} {
+	    set name ""
+	}
+	if {$ret != 0} {
+	    dict append opts -errorinfo \
+		    "\n    (expanding command prefix \"$name\" in unknown)"
+	    return -options $opts $msg
+	}
+	# Filter out bogus matches when $name contained
+	# a glob-special char [Bug 946952]
+	if {$name eq ""} {
+	    # Handle empty $name separately due to strangeness
+	    # in [string first] (See RFE 1243354)
+	    set cmds $candidates
+	} else {
+	    set cmds [list]
+	    foreach x $candidates {
+		if {[string first $name $x] == 0} {
+		    lappend cmds $x
+		}
+	    }
+	}
+	if {[llength $cmds] == 1} {
+	    uplevel 1 [list ::catch [lreplace $args 0 0 [lindex $cmds 0]] \
+		    ::tcl::UnknownResult ::tcl::UnknownOptions]
+	    dict incr ::tcl::UnknownOptions -level
+	    return -options $::tcl::UnknownOptions $::tcl::UnknownResult
+	}
+	if {[llength $cmds]} {
+	    return -code error "ambiguous command name \"$name\": [lsort $cmds]"
+	}
+    }
+    return -code error -errorcode [list TCL LOOKUP COMMAND $name] \
+	"invalid command name \"$name\""
+}
+
+# auto_load --
+# Checks a collection of library directories to see if a procedure
+# is defined in one of them.  If so, it sources the appropriate
+# library file to create the procedure.  Returns 1 if it successfully
+# loaded the procedure, 0 otherwise.
+#
+# Arguments:
+# cmd -			Name of the command to find and load.
+# namespace (optional)  The namespace where the command is being used - must be
+#                       a canonical namespace as returned [namespace current]
+#                       for instance. If not given, namespace current is used.
+
+proc auto_load {cmd {namespace {}}} {
+    global auto_index auto_path
+
+    if {$namespace eq ""} {
+	set namespace [uplevel 1 [list ::namespace current]]
+    }
+    set nameList [auto_qualify $cmd $namespace]
+    # workaround non canonical auto_index entries that might be around
+    # from older auto_mkindex versions
+    lappend nameList $cmd
+    foreach name $nameList {
+	if {[info exists auto_index($name)]} {
+	    namespace eval :: $auto_index($name)
+	    # There's a couple of ways to look for a command of a given
+	    # name.  One is to use
+	    #    info commands $name
+	    # Unfortunately, if the name has glob-magic chars in it like *
+	    # or [], it may not match.  For our purposes here, a better
+	    # route is to use
+	    #    namespace which -command $name
+	    if {[namespace which -command $name] ne ""} {
+		return 1
+	    }
+	}
+    }
+    if {![info exists auto_path]} {
+	return 0
+    }
+
+    if {![auto_load_index]} {
+	return 0
+    }
+    foreach name $nameList {
+	if {[info exists auto_index($name)]} {
+	    namespace eval :: $auto_index($name)
+	    if {[namespace which -command $name] ne ""} {
+		return 1
+	    }
+	}
+    }
+    return 0
+}
+
+# auto_load_index --
+# Loads the contents of tclIndex files on the auto_path directory
+# list.  This is usually invoked within auto_load to load the index
+# of available commands.  Returns 1 if the index is loaded, and 0 if
+# the index is already loaded and up to date.
+#
+# Arguments:
+# None.
+
+proc auto_load_index {} {
+    variable ::tcl::auto_oldpath
+    global auto_index auto_path
+
+    if {[info exists auto_oldpath] && ($auto_oldpath eq $auto_path)} {
+	return 0
+    }
+    set auto_oldpath $auto_path
+
+    # Check if we are a safe interpreter. In that case, we support only
+    # newer format tclIndex files.
+
+    set issafe [interp issafe]
+    for {set i [expr {[llength $auto_path] - 1}]} {$i >= 0} {incr i -1} {
+	set dir [lindex $auto_path $i]
+	set f ""
+	if {$issafe} {
+	    catch {source [file join $dir tclIndex]}
+	} elseif {[catch {set f [open [file join $dir tclIndex]]}]} {
+	    continue
+	} else {
+	    set error [catch {
+		set id [gets $f]
+		if {$id eq "# Tcl autoload index file, version 2.0"} {
+		    eval [read $f]
+		} elseif {$id eq "# Tcl autoload index file: each line identifies a Tcl"} {
+		    while {[gets $f line] >= 0} {
+			if {([string index $line 0] eq "#") \
+				|| ([llength $line] != 2)} {
+			    continue
+			}
+			set name [lindex $line 0]
+			set auto_index($name) \
+				"source [file join $dir [lindex $line 1]]"
+		    }
+		} else {
+		    error "[file join $dir tclIndex] isn't a proper Tcl index file"
+		}
+	    } msg opts]
+	    if {$f ne ""} {
+		close $f
+	    }
+	    if {$error} {
+		return -options $opts $msg
+	    }
+	}
+    }
+    return 1
+}
+
+# auto_qualify --
+#
+# Compute a fully qualified names list for use in the auto_index array.
+# For historical reasons, commands in the global namespace do not have leading
+# :: in the index key. The list has two elements when the command name is
+# relative (no leading ::) and the namespace is not the global one. Otherwise
+# only one name is returned (and searched in the auto_index).
+#
+# Arguments -
+# cmd		The command name. Can be any name accepted for command
+#               invocations (Like "foo::::bar").
+# namespace	The namespace where the command is being used - must be
+#               a canonical namespace as returned by [namespace current]
+#               for instance.
+
+proc auto_qualify {cmd namespace} {
+
+    # count separators and clean them up
+    # (making sure that foo:::::bar will be treated as foo::bar)
+    set n [regsub -all {::+} $cmd :: cmd]
+
+    # Ignore namespace if the name starts with ::
+    # Handle special case of only leading ::
+
+    # Before each return case we give an example of which category it is
+    # with the following form :
+    # (inputCmd, inputNameSpace) -> output
+
+    if {[string match ::* $cmd]} {
+	if {$n > 1} {
+	    # (::foo::bar , *) -> ::foo::bar
+	    return [list $cmd]
+	} else {
+	    # (::global , *) -> global
+	    return [list [string range $cmd 2 end]]
+	}
+    }
+
+    # Potentially returning 2 elements to try  :
+    # (if the current namespace is not the global one)
+
+    if {$n == 0} {
+	if {$namespace eq "::"} {
+	    # (nocolons , ::) -> nocolons
+	    return [list $cmd]
+	} else {
+	    # (nocolons , ::sub) -> ::sub::nocolons nocolons
+	    return [list ${namespace}::$cmd $cmd]
+	}
+    } elseif {$namespace eq "::"} {
+	#  (foo::bar , ::) -> ::foo::bar
+	return [list ::$cmd]
+    } else {
+	# (foo::bar , ::sub) -> ::sub::foo::bar ::foo::bar
+	return [list ${namespace}::$cmd ::$cmd]
+    }
+}
+
+# auto_import --
+#
+# Invoked during "namespace import" to make see if the imported commands
+# reside in an autoloaded library.  If so, the commands are loaded so
+# that they will be available for the import links.  If not, then this
+# procedure does nothing.
+#
+# Arguments -
+# pattern	The pattern of commands being imported (like "foo::*")
+#               a canonical namespace as returned by [namespace current]
+
+proc auto_import {pattern} {
+    global auto_index
+
+    # If no namespace is specified, this will be an error case
+
+    if {![string match *::* $pattern]} {
+	return
+    }
+
+    set ns [uplevel 1 [list ::namespace current]]
+    set patternList [auto_qualify $pattern $ns]
+
+    auto_load_index
+
+    foreach pattern $patternList {
+        foreach name [array names auto_index $pattern] {
+            if {([namespace which -command $name] eq "")
+		    && ([namespace qualifiers $pattern] eq [namespace qualifiers $name])} {
+                namespace eval :: $auto_index($name)
+            }
+        }
+    }
+}
+
+# auto_execok --
+#
+# Returns string that indicates name of program to execute if
+# name corresponds to a shell builtin or an executable in the
+# Windows search path, or "" otherwise.  Builds an associative
+# array auto_execs that caches information about previous checks,
+# for speed.
+#
+# Arguments:
+# name -			Name of a command.
+
+if {$tcl_platform(platform) eq "windows"} {
+# Windows version.
+#
+# Note that info executable doesn't work under Windows, so we have to
+# look for files with .exe, .com, or .bat extensions.  Also, the path
+# may be in the Path or PATH environment variables, and path
+# components are separated with semicolons, not colons as under Unix.
+#
+proc auto_execok name {
+    global auto_execs env tcl_platform
+
+    if {[info exists auto_execs($name)]} {
+	return $auto_execs($name)
+    }
+    set auto_execs($name) ""
+
+    set shellBuiltins [list cls copy date del dir echo erase md mkdir \
+	    mklink rd ren rename rmdir start time type ver vol]
+    if {[info exists env(PATHEXT)]} {
+	# Add an initial ; to have the {} extension check first.
+	set execExtensions [split ";$env(PATHEXT)" ";"]
+    } else {
+	set execExtensions [list {} .com .exe .bat .cmd]
+    }
+
+    if {[string tolower $name] in $shellBuiltins} {
+	# When this is command.com for some reason on Win2K, Tcl won't
+	# exec it unless the case is right, which this corrects.  COMSPEC
+	# may not point to a real file, so do the check.
+	set cmd $env(COMSPEC)
+	if {[file exists $cmd]} {
+	    set cmd [file attributes $cmd -shortname]
+	}
+	return [set auto_execs($name) [list $cmd /c $name]]
+    }
+
+    if {[llength [file split $name]] != 1} {
+	foreach ext $execExtensions {
+	    set file ${name}${ext}
+	    if {[file exists $file] && ![file isdirectory $file]} {
+		return [set auto_execs($name) [list $file]]
+	    }
+	}
+	return ""
+    }
+
+    set path "[file dirname [info nameof]];.;"
+    if {[info exists env(WINDIR)]} {
+	set windir $env(WINDIR)
+    }
+    if {[info exists windir]} {
+	if {$tcl_platform(os) eq "Windows NT"} {
+	    append path "$windir/system32;"
+	}
+	append path "$windir/system;$windir;"
+    }
+
+    foreach var {PATH Path path} {
+	if {[info exists env($var)]} {
+	    append path ";$env($var)"
+	}
+    }
+
+    foreach ext $execExtensions {
+	unset -nocomplain checked
+	foreach dir [split $path {;}] {
+	    # Skip already checked directories
+	    if {[info exists checked($dir)] || ($dir eq "")} {
+		continue
+	    }
+	    set checked($dir) {}
+	    set file [file join $dir ${name}${ext}]
+	    if {[file exists $file] && ![file isdirectory $file]} {
+		return [set auto_execs($name) [list $file]]
+	    }
+	}
+    }
+    return ""
+}
+
+} else {
+# Unix version.
+#
+proc auto_execok name {
+    global auto_execs env
+
+    if {[info exists auto_execs($name)]} {
+	return $auto_execs($name)
+    }
+    set auto_execs($name) ""
+    if {[llength [file split $name]] != 1} {
+	if {[file executable $name] && ![file isdirectory $name]} {
+	    set auto_execs($name) [list $name]
+	}
+	return $auto_execs($name)
+    }
+    foreach dir [split $env(PATH) :] {
+	if {$dir eq ""} {
+	    set dir .
+	}
+	set file [file join $dir $name]
+	if {[file executable $file] && ![file isdirectory $file]} {
+	    set auto_execs($name) [list $file]
+	    return $auto_execs($name)
+	}
+    }
+    return ""
+}
+
+}
+
+# ::tcl::CopyDirectory --
+#
+# This procedure is called by Tcl's core when attempts to call the
+# filesystem's copydirectory function fail.  The semantics of the call
+# are that 'dest' does not yet exist, i.e. dest should become the exact
+# image of src.  If dest does exist, we throw an error.
+#
+# Note that making changes to this procedure can change the results
+# of running Tcl's tests.
+#
+# Arguments:
+# action -              "renaming" or "copying"
+# src -			source directory
+# dest -		destination directory
+proc tcl::CopyDirectory {action src dest} {
+    set nsrc [file normalize $src]
+    set ndest [file normalize $dest]
+
+    if {$action eq "renaming"} {
+	# Can't rename volumes.  We could give a more precise
+	# error message here, but that would break the test suite.
+	if {$nsrc in [file volumes]} {
+	    return -code error "error $action \"$src\" to\
+	      \"$dest\": trying to rename a volume or move a directory\
+	      into itself"
+	}
+    }
+    if {[file exists $dest]} {
+	if {$nsrc eq $ndest} {
+	    return -code error "error $action \"$src\" to\
+	      \"$dest\": trying to rename a volume or move a directory\
+	      into itself"
+	}
+	if {$action eq "copying"} {
+	    # We used to throw an error here, but, looking more closely
+	    # at the core copy code in tclFCmd.c, if the destination
+	    # exists, then we should only call this function if -force
+	    # is true, which means we just want to over-write.  So,
+	    # the following code is now commented out.
+	    #
+	    # return -code error "error $action \"$src\" to\
+	    # \"$dest\": file already exists"
+	} else {
+	    # Depending on the platform, and on the current
+	    # working directory, the directories '.', '..'
+	    # can be returned in various combinations.  Anyway,
+	    # if any other file is returned, we must signal an error.
+	    set existing [glob -nocomplain -directory $dest * .*]
+	    lappend existing {*}[glob -nocomplain -directory $dest \
+		    -type hidden * .*]
+	    foreach s $existing {
+		if {[file tail $s] ni {. ..}} {
+		    return -code error "error $action \"$src\" to\
+		      \"$dest\": file already exists"
+		}
+	    }
+	}
+    } else {
+	if {[string first $nsrc $ndest] != -1} {
+	    set srclen [expr {[llength [file split $nsrc]] - 1}]
+	    set ndest [lindex [file split $ndest] $srclen]
+	    if {$ndest eq [file tail $nsrc]} {
+		return -code error "error $action \"$src\" to\
+		  \"$dest\": trying to rename a volume or move a directory\
+		  into itself"
+	    }
+	}
+	file mkdir $dest
+    }
+    # Have to be careful to capture both visible and hidden files.
+    # We will also be more generous to the file system and not
+    # assume the hidden and non-hidden lists are non-overlapping.
+    #
+    # On Unix 'hidden' files begin with '.'.  On other platforms
+    # or filesystems hidden files may have other interpretations.
+    set filelist [concat [glob -nocomplain -directory $src *] \
+      [glob -nocomplain -directory $src -types hidden *]]
+
+    foreach s [lsort -unique $filelist] {
+	if {[file tail $s] ni {. ..}} {
+	    file copy -force -- $s [file join $dest [file tail $s]]
+	}
+    }
+    return
+}

BIN
coderedcms/Scripts/_asyncio.pyd


BIN
coderedcms/Scripts/_bz2.pyd


BIN
coderedcms/Scripts/_ctypes.pyd


BIN
coderedcms/Scripts/_ctypes_test.pyd


BIN
coderedcms/Scripts/_decimal.pyd


BIN
coderedcms/Scripts/_distutils_findvs.pyd


BIN
coderedcms/Scripts/_elementtree.pyd


BIN
coderedcms/Scripts/_hashlib.pyd


BIN
coderedcms/Scripts/_lzma.pyd


BIN
coderedcms/Scripts/_msi.pyd


BIN
coderedcms/Scripts/_multiprocessing.pyd


BIN
coderedcms/Scripts/_overlapped.pyd


BIN
coderedcms/Scripts/_socket.pyd


BIN
coderedcms/Scripts/_sqlite3.pyd


BIN
coderedcms/Scripts/_ssl.pyd


BIN
coderedcms/Scripts/_testbuffer.pyd


BIN
coderedcms/Scripts/_testcapi.pyd


BIN
coderedcms/Scripts/_testconsole.pyd


BIN
coderedcms/Scripts/_testimportmultiple.pyd


BIN
coderedcms/Scripts/_testmultiphase.pyd


BIN
coderedcms/Scripts/_tkinter.pyd


BIN
coderedcms/Scripts/pyexpat.pyd


BIN
coderedcms/Scripts/python.exe


BIN
coderedcms/Scripts/python3.dll


BIN
coderedcms/Scripts/python36.dll


BIN
coderedcms/Scripts/pythonw.exe


BIN
coderedcms/Scripts/select.pyd


BIN
coderedcms/Scripts/sqlite3.dll


BIN
coderedcms/Scripts/tcl86t.dll


BIN
coderedcms/Scripts/tk86t.dll


BIN
coderedcms/Scripts/unicodedata.pyd


BIN
coderedcms/Scripts/vcruntime140.dll


BIN
coderedcms/Scripts/winsound.pyd


+ 10 - 2
coderedcms/api/mailchimp.py

@@ -3,6 +3,7 @@ from coderedcms.models.wagtailsettings_models import MailchimpApiSettings
 
 import requests
 
+
 class MailchimpApi:
     user_string = "Website"
     proto_base_url = "https://{0}.api.mailchimp.com/3.0/"
@@ -40,7 +41,11 @@ class MailchimpApi:
         return json_response
 
     def get_merge_fields_for_list(self, list_id):
-        endpoint = "lists/{0}/merge-fields?fields=merge_fields.tag,merge_fields.merge_id,merge_fields.name".format(list_id)
+        endpoint = '''
+        lists/{0}/merge-fields?fields=merge_fields.tag,
+        merge_fields.merge_id,
+        merge_fields.name
+        '''.format(list_id)
         json_response = self._get(endpoint)
         return json_response
 
@@ -50,7 +55,10 @@ class MailchimpApi:
         return json_response
 
     def get_interests_for_interest_category(self, list_id, interest_category_id):
-        endpoint = "lists/{0}/interest-categories/{1}/interests?fields=interests.id,interests.name".format(list_id, interest_category_id)
+        endpoint = '''
+        lists/{0}/interest-categories/{1}/interests?fields=interests.id,
+        interests.name
+        '''.format(list_id, interest_category_id)
         json_response = self._get(endpoint)
         return json_response
 

+ 13 - 4
coderedcms/bin/coderedcms.py

@@ -2,7 +2,6 @@
 import os
 import sys
 
-from django.core.management import ManagementUtility
 from django.core.management.templates import TemplateCommand
 from django.core.management.utils import get_random_secret_key
 
@@ -11,7 +10,11 @@ CURRENT_PYTHON = sys.version_info[:2]
 REQUIRED_PYTHON = (3, 4)
 
 if CURRENT_PYTHON < REQUIRED_PYTHON:
-    sys.stderr.write("This version of Wagtail requires Python {}.{} or above - you are running {}.{}\n".format(*(REQUIRED_PYTHON + CURRENT_PYTHON)))
+    sys.stderr.write(
+        '''
+        This version of Wagtail requires Python {}.{} or above - you are running {}.{}\n
+        '''.format(*(REQUIRED_PYTHON + CURRENT_PYTHON))
+    )
     sys.exit(1)
 
 
@@ -23,8 +26,14 @@ class CreateProject(TemplateCommand):
     missing_args_message = "You must provide a project name."
 
     def add_arguments(self, parser):
-        parser.add_argument('--sitename', help='Human readable name of your website or brand, e.g. "Mega Corp Inc."')
-        parser.add_argument('--domain', help='Domain that will be used for your website in production, e.g. "www.example.com"')
+        parser.add_argument(
+            '--sitename',
+            help='Human readable name of your website or brand, e.g. "Mega Corp Inc."'
+        )
+        parser.add_argument(
+            '--domain',
+            help='Domain that will be used for your website in production, e.g. "www.example.com"'
+        )
         super().add_arguments(parser)
 
     def handle(self, **options):

+ 51 - 16
coderedcms/blocks/__init__.py

@@ -5,18 +5,53 @@ single `blocks` module.
 """
 
 from django.utils.translation import ugettext_lazy as _
-from wagtail.core.blocks import CharBlock, StreamBlock, StructBlock
-
-from coderedcms.wagtail_flexible_forms.blocks import FormStepBlock, FormStepsBlock
-
-from .stream_form_blocks import * #noqa
-from .base_blocks import * #noqa
-from .html_blocks import * #noqa
-from .metadata_blocks import * #noqa
-from .content_blocks import * #noqa
-from .layout_blocks import * #noqa
 
+from wagtail.core import blocks
 
+from .stream_form_blocks import (
+    CoderedStreamFormCharFieldBlock,
+    CoderedStreamFormCheckboxesFieldBlock,
+    CoderedStreamFormCheckboxFieldBlock,
+    CoderedStreamFormDateFieldBlock,
+    CoderedStreamFormDateTimeFieldBlock,
+    CoderedStreamFormDropdownFieldBlock,
+    CoderedStreamFormFileFieldBlock,
+    CoderedStreamFormImageFieldBlock,
+    CoderedStreamFormNumberFieldBlock,
+    CoderedStreamFormRadioButtonsFieldBlock,
+    CoderedStreamFormStepBlock,
+    CoderedStreamFormTextFieldBlock,
+    CoderedStreamFormTimeFieldBlock
+)
+from .html_blocks import (
+    ButtonBlock,
+    EmbedGoogleMapBlock,
+    ImageBlock,
+    ImageLinkBlock,
+    DownloadBlock,
+    EmbedVideoBlock,
+    PageListBlock,
+    PagePreviewBlock,
+    QuoteBlock,
+    RichTextBlock,
+    TableBlock
+)
+from .content_blocks import (
+    CardBlock,
+    CarouselBlock,
+    ImageGalleryBlock,
+    ModalBlock,
+    NavDocumentLinkWithSubLinkBlock,
+    NavExternalLinkWithSubLinkBlock,
+    NavPageLinkWithSubLinkBlock,
+    PriceListBlock,
+    ReusableContentBlock
+)
+from .layout_blocks import (
+    CardGridBlock,
+    GridBlock,
+    HeroBlock
+)
 
 # Collections of blocks commonly used together.
 
@@ -59,14 +94,14 @@ LAYOUT_STREAMBLOCKS = [
     ('hero', HeroBlock([
         ('row', GridBlock(CONTENT_STREAMBLOCKS)),
         ('cardgrid', CardGridBlock([
-            ('card', CardBlock()),])
-        ),
-        ('html', blocks.RawHTMLBlock(icon='code', classname='monospace', label=_('HTML'))),])
-    ),
+            ('card', CardBlock()),
+        ])),
+        ('html', blocks.RawHTMLBlock(icon='code', classname='monospace', label=_('HTML'))),
+    ])),
     ('row', GridBlock(CONTENT_STREAMBLOCKS)),
     ('cardgrid', CardGridBlock([
-        ('card', CardBlock()),])
-    ),
+        ('card', CardBlock()),
+    ])),
     ('html', blocks.RawHTMLBlock(icon='code', classname='monospace', label=_('HTML'))),
 ]
 

+ 8 - 8
coderedcms/blocks/base_blocks.py

@@ -42,9 +42,9 @@ class ClassifierTermChooserBlock(blocks.FieldBlock):
     widget = forms.Select
 
     def __init__(self, required=False, label=None, help_text=None, *args, **kwargs):
-        self._required=required
-        self._help_text=help_text
-        self._label=label
+        self._required = required
+        self._help_text = help_text
+        self._label = label
         super().__init__(*args, **kwargs)
 
     @cached_property
@@ -86,9 +86,9 @@ class CollectionChooserBlock(blocks.FieldBlock):
     widget = forms.Select
 
     def __init__(self, required=False, label=None, help_text=None, *args, **kwargs):
-        self._required=required
-        self._help_text=help_text
-        self._label=label
+        self._required = required
+        self._help_text = help_text
+        self._label = label
         super().__init__(*args, **kwargs)
 
     @cached_property
@@ -227,7 +227,7 @@ class BaseBlock(blocks.StructBlock):
         """
         klassname = self.__class__.__name__.lower()
         choices = cr_settings['FRONTEND_TEMPLATES_BLOCKS'].get('*', ()) + \
-                  cr_settings['FRONTEND_TEMPLATES_BLOCKS'].get(klassname, ())
+            cr_settings['FRONTEND_TEMPLATES_BLOCKS'].get(klassname, ())
 
         if not local_blocks:
             local_blocks = ()
@@ -285,6 +285,7 @@ class LinkStructValue(blocks.StructValue):
         else:
             return ext
 
+
 class BaseLinkBlock(BaseBlock):
     """
     Common attributes for creating a link within the CMS.
@@ -307,4 +308,3 @@ class BaseLinkBlock(BaseBlock):
 
     class Meta:
         value_class = LinkStructValue
-

+ 1 - 0
coderedcms/blocks/content_blocks.py

@@ -265,6 +265,7 @@ class ContentWallBlock(BaseBlock):
         verbose_name=_('Show content walls on children pages?'),
         help_text=_('If this is checked, the content walls will be displayed on all children pages of this page.')
     )
+
     class Meta:
         icon = 'fa-stop'
         label = _('Content Wall')

+ 19 - 3
coderedcms/blocks/html_blocks.py

@@ -79,7 +79,12 @@ class EmbedGoogleMapBlock(BaseBlock):
         required=False,
         default=14,
         label=_('Map zoom level'),
-        help_text=_('Requires API key to use zoom. 1: World, 5: Landmass/continent, 10: City, 15: Streets, 20: Buildings')
+        help_text=_(
+            '''
+            Requires API key to use zoom. 1: World, 5: Landmass/continent,
+            10: City, 15: Streets, 20: Buildings
+            '''
+        )
     )
 
     class Meta:
@@ -199,7 +204,12 @@ class PageListBlock(BaseBlock):
     indexed_by = blocks.PageChooserBlock(
         required=True,
         label=_('Parent page'),
-        help_text=_('Show a preview of pages that are children of the selected page. Uses ordering specified in the page’s LAYOUT tab.'),
+        help_text=_(
+            '''
+            Show a preview of pages that are children of the selected page.
+            Uses ordering specified in the page’s LAYOUT tab.
+            '''
+        ),
     )
     classified_by = ClassifierTermChooserBlock(
         required=False,
@@ -235,7 +245,13 @@ class PageListBlock(BaseBlock):
                     pages = pages.filter(classifier_terms=value['classified_by'])
                 except:
                     # `pages` is not a queryset, or is not a queryset of CoderedPage.
-                    logger.warning("Tried to filter by ClassifierTerm in PageListBlock, but <%s.%s ('%s')>.get_index_children() did not return a queryset or is not a queryset of CoderedPage models.", indexer._meta.app_label, indexer.__class__.__name__, indexer.title)
+                    logger.warning(
+                        '''
+                        Tried to filter by ClassifierTerm in PageListBlock, but <%s.%s ('%s')>.get_index_children()
+                        did not return a queryset or is not a queryset of CoderedPage models.
+                        ''',
+                        indexer._meta.app_label, indexer.__class__.__name__, indexer.title
+                    )
         else:
             pages = indexer.get_children().live()
 

+ 3 - 2
coderedcms/blocks/layout_blocks.py

@@ -12,7 +12,7 @@ from coderedcms.settings import cr_settings
 from .base_blocks import BaseLayoutBlock, CoderedAdvColumnSettings
 
 
-### Level 1 layout blocks
+# Level 1 layout blocks
 
 
 class ColumnBlock(BaseLayoutBlock):
@@ -50,11 +50,12 @@ class GridBlock(BaseLayoutBlock):
 
     def __init__(self, local_blocks=None, **kwargs):
         super().__init__(
-            local_blocks = [
+            local_blocks=[
                 ('content', ColumnBlock(local_blocks))
             ]
         )
 
+
 class CardGridBlock(BaseLayoutBlock):
     """
     Renders a row of cards.

+ 7 - 1
coderedcms/blocks/metadata_blocks.py

@@ -23,6 +23,7 @@ class OpenHoursValue(blocks.StructValue):
         """
         return json.dumps(self['days'])
 
+
 class OpenHoursBlock(blocks.StructBlock):
     """
     Holds day and time combination for business open hours.
@@ -80,7 +81,12 @@ class StructuredDataActionBlock(blocks.StructBlock):
         required=False,
         verbose_name=_('Additional action markup'),
         classname='monospace',
-        help_text=_('Additional JSON-LD inserted into the Action dictionary. Must be properties of https://schema.org/Action.')
+        help_text=_(
+            '''
+            Additional JSON-LD inserted into the Action dictionary.
+            Must be properties of https://schema.org/Action.
+            '''
+        )
     )
 
     class Meta:

+ 6 - 6
coderedcms/blocks/stream_form_blocks.py

@@ -4,9 +4,9 @@ from wagtail.core import blocks
 from coderedcms.wagtail_flexible_forms import blocks as form_blocks
 from coderedcms.blocks.base_blocks import BaseBlock, CoderedAdvSettings
 from coderedcms.forms import (
-    CoderedDateField, CoderedDateInput, 
-    CoderedDateTimeField, CoderedDateTimeInput, 
-    CoderedTimeField, CoderedTimeInput, 
+    CoderedDateField, CoderedDateInput,
+    CoderedDateTimeField, CoderedDateTimeInput,
+    CoderedTimeField, CoderedTimeInput,
     SecureFileField
 )
 
@@ -29,7 +29,7 @@ class CoderedFormAdvSettings(CoderedAdvSettings):
 
 class FormBlockMixin(BaseBlock):
     class Meta:
-        abstract=True
+        abstract = True
 
     advsettings_class = CoderedFormAdvSettings
 
@@ -84,7 +84,7 @@ class CoderedStreamFormDateFieldBlock(form_blocks.DateFieldBlock, FormBlockMixin
     class Meta:
         label = _("Date")
         icon = "fa-calendar"
-    
+
     field_class = CoderedDateField
     widget = CoderedDateInput
 
@@ -126,7 +126,7 @@ class CoderedStreamFormStepBlock(form_blocks.FormStepBlock):
 
     def __init__(self, local_blocks=None, **kwargs):
         super().__init__(
-            local_blocks = [
+            local_blocks=[
                 ('form_fields', blocks.StreamBlock(local_blocks))
             ]
         )

+ 2 - 2
coderedcms/blocks/tests/test_blocks.py

@@ -1,8 +1,9 @@
 from coderedcms.blocks import base_blocks
-from django.test import SimpleTestCase, TestCase
+from django.test import SimpleTestCase
 
 from wagtail.tests.utils import WagtailTestUtils
 
+
 class TestMultiSelectBlock(WagtailTestUtils, SimpleTestCase):
     def test_render_single_choice(self):
         block = base_blocks.MultiSelectBlock(choices=[('tea', 'Tea'), ('coffee', 'Coffee'), ('water', 'Water')])
@@ -16,4 +17,3 @@ class TestMultiSelectBlock(WagtailTestUtils, SimpleTestCase):
         self.assertInHTML('<option value="tea" selected>Tea</option>', html)
         self.assertInHTML('<option value="coffee" selected>Coffee</option>', html)
         self.assertTrue(html.count('selected'), 2)
-

+ 2 - 1
coderedcms/fields.py

@@ -2,7 +2,8 @@ from django.db import models
 
 from coderedcms.widgets import ColorPickerWidget
 
-class ColorField(models.CharField):    
+
+class ColorField(models.CharField):
     def __init__(self, *args, **kwargs):
         kwargs['max_length'] = 255
         super(ColorField, self).__init__(*args, **kwargs)

+ 14 - 4
coderedcms/forms.py

@@ -79,6 +79,7 @@ class SecureFileField(forms.FileField):
 class CoderedDateInput(forms.DateInput):
     template_name = 'coderedcms/formfields/date.html'
 
+
 class CoderedDateField(forms.DateField):
     widget = CoderedDateInput()
 
@@ -88,6 +89,7 @@ class CoderedDateField(forms.DateField):
 class CoderedDateTimeInput(forms.DateTimeInput):
     template_name = 'coderedcms/formfields/datetime.html'
 
+
 class CoderedDateTimeField(forms.DateTimeField):
     widget = CoderedDateTimeInput()
     input_formats = ['%Y-%m-%dT%H:%M', '%m/%d/%Y %I:%M %p', '%m/%d/%Y %I:%M%p', '%m/%d/%Y %H:%M']
@@ -98,6 +100,7 @@ class CoderedDateTimeField(forms.DateTimeField):
 class CoderedTimeInput(forms.TimeInput):
     template_name = 'coderedcms/formfields/time.html'
 
+
 class CoderedTimeField(forms.TimeField):
     widget = CoderedTimeInput()
     input_formats = ['%H:%M', '%I:%M %p', '%I:%M%p']
@@ -122,8 +125,6 @@ class CoderedFormBuilder(FormBuilder):
 
 
 class CoderedSubmissionsListView(WagtailSubmissionsListView):
-
-    
     def get_csv_response(self, context):
         filename = self.get_csv_filename()
         response = HttpResponse(content_type='text/csv; charset=utf-8')
@@ -161,11 +162,20 @@ class SearchForm(forms.Form):
         label=_('Page type'),
     )
 
+
 def get_page_model_choices():
     """
-    Returns a list of tuples of all creatable Codered pages in the format of ("Custom Codered Page", "CustomCoderedPage")
+    Returns a list of tuples of all creatable Codered pages
+    in the format of ("Custom Codered Page", "CustomCoderedPage")
     """
     from coderedcms.models import get_page_models
     return (
-        (page.__name__, re.sub(r'((?<=[a-z])[A-Z]|(?<!\A)[A-Z](?=[a-z]))', r' \1', page.__name__)) for page in get_page_models() if page.is_creatable
+        (
+            page.__name__,
+            re.sub(
+                r'((?<=[a-z])[A-Z]|(?<!\A)[A-Z](?=[a-z]))',
+                r' \1',
+                page.__name__
+            )
+        ) for page in get_page_models() if page.is_creatable
     )

+ 4 - 4
coderedcms/models/__init__.py

@@ -4,7 +4,7 @@ into files based on their purpose, but provide them all via
 a single `models` module.
 """
 
-from .integration_models import * #noqa
-from .page_models import * #noqa
-from .snippet_models import * #noqa
-from .wagtailsettings_models import * #noqa
+from .integration_models import *  # noqa
+from .page_models import *  # noqa
+from .snippet_models import *  # noqa
+from .wagtailsettings_models import *  # noqa

+ 15 - 12
coderedcms/models/integration_models.py

@@ -1,13 +1,11 @@
 from django.db import models
-from django.forms.widgets import Select, Input
+from django.forms.widgets import Input
 from django.template import Context, Template
 from django.template.loader import render_to_string
 from django.utils.translation import ugettext_lazy as _
 
 from wagtail.admin.edit_handlers import FieldPanel
 from wagtail.core import hooks
-from wagtail.core.models import Orderable, Page
-from modelcluster.fields import ParentalKey
 
 from coderedcms.api.mailchimp import MailchimpApi
 
@@ -34,15 +32,14 @@ class MailchimpSubscriberIntegrationWidget(Input):
     def render_js(self, name, list_library, json_value):
         ctx = {
             'widget_name': name,
-            'widget_js_name' : name.replace('-', '_'),
-            'list_library' : list_library,
+            'widget_js_name': name.replace('-', '_'),
+            'list_library': list_library,
             'stored_mailchimp_list': self.get_stored_mailchimp_list(json_value),
-            'stored_merge_fields' : self.get_stored_merge_fields(json_value),
+            'stored_merge_fields': self.get_stored_merge_fields(json_value),
         }
 
         return render_to_string(self.js_template_name, ctx)
 
-
     def get_json_value(self, value):
         if value:
             json_value = json.loads(value)
@@ -85,18 +82,24 @@ class MailchimpSubscriberIntegrationWidget(Input):
                     'merge_fields': {},
                     'interest_categories': {}
                 }
-                
+
                 list_library[l['id']]['merge_fields'] = mailchimp.get_merge_fields_for_list(l['id'])['merge_fields']
-                list_library[l['id']]['interest_categories'] = mailchimp.get_interest_categories_for_list(l['id'])['categories']
+                list_library[l['id']]['interest_categories'] = mailchimp.get_interest_categories_for_list(
+                    l['id']
+                )['categories']
 
                 for category in list_library[l['id']]['interest_categories']:
-                    category['interests'] = mailchimp.get_interests_for_interest_category(l['id'], category['id'])['interests']
+                    category['interests'] = mailchimp.get_interests_for_interest_category(
+                        l['id'],
+                        category['id']
+                    )['interests']
 
         return list_library
 
+
 class MailchimpSubscriberIntegration(models.Model):
     class Meta:
-        abstract=True
+        abstract = True
 
     subscriber_json_data = models.TextField(
         blank=True,
@@ -146,7 +149,6 @@ class MailchimpSubscriberIntegration(models.Model):
             ]
         })
 
-
         rendered_dictionary = Template(rendered_dictionary_template).render(Context(form_submission))
         return rendered_dictionary
 
@@ -154,6 +156,7 @@ class MailchimpSubscriberIntegration(models.Model):
         FieldPanel('subscriber_json_data', widget=MailchimpSubscriberIntegrationWidget)
     ]
 
+
 @hooks.register('form_page_submit')
 def run_mailchimp_subscriber_integrations(instance, **kwargs):
     if hasattr(instance, 'integration_panels'):

+ 119 - 55
coderedcms/models/page_models.py

@@ -48,7 +48,7 @@ from wagtail.core.utils import resolve_model_string
 from wagtail.contrib.forms.edit_handlers import FormSubmissionsPanel
 from wagtail.contrib.forms.forms import WagtailAdminFormPageForm
 from wagtail.images.edit_handlers import ImageChooserPanel
-from wagtail.contrib.forms.models import AbstractFormSubmission, FormSubmission
+from wagtail.contrib.forms.models import FormSubmission
 from wagtail.search import index
 from wagtailcache.cache import WagtailCacheMixin
 
@@ -59,14 +59,20 @@ from coderedcms.blocks import (
     STREAMFORM_BLOCKS,
     ContentWallBlock,
     OpenHoursBlock,
-    StructuredDataActionBlock,
-    CoderedStreamFormStepBlock)
+    StructuredDataActionBlock)
 from coderedcms.fields import ColorField
 from coderedcms.forms import CoderedFormBuilder, CoderedSubmissionsListView
 from coderedcms.models.snippet_models import ClassifierTerm
 from coderedcms.models.wagtailsettings_models import GeneralSettings, LayoutSettings, SeoSettings, GoogleApiSettings
 from coderedcms.wagtail_flexible_forms.blocks import FormFieldBlock, FormStepBlock
-from coderedcms.wagtail_flexible_forms.models import Step, Steps, StreamFormMixin, StreamFormJSONEncoder, SessionFormSubmission, SubmissionRevision
+from coderedcms.wagtail_flexible_forms.models import (
+    Step,
+    Steps,
+    StreamFormMixin,
+    StreamFormJSONEncoder,
+    SessionFormSubmission,
+    SubmissionRevision
+)
 from coderedcms.settings import cr_settings
 from coderedcms.widgets import ClassifierSelectWidget
 
@@ -76,6 +82,7 @@ logger = logging.getLogger('coderedcms')
 
 CODERED_PAGE_MODELS = []
 
+
 def get_page_models():
     return CODERED_PAGE_MODELS
 
@@ -100,11 +107,13 @@ class CoderedPageMeta(PageBase):
         if not cls._meta.abstract:
             CODERED_PAGE_MODELS.append(cls)
 
+
 class CoderedTag(TaggedItemBase):
     class Meta:
         verbose_name = _('CodeRed Tag')
     content_object = ParentalKey('coderedcms.CoderedPage', related_name='tagged_items')
 
+
 class CoderedPage(WagtailCacheMixin, Page, metaclass=CoderedPageMeta):
     """
     General use page with caching, templating, and SEO functionality.
@@ -124,7 +133,6 @@ class CoderedPage(WagtailCacheMixin, Page, metaclass=CoderedPageMeta):
     # ajax_template = ''
     # search_template = ''
 
-
     ###############
     # Content fields
     ###############
@@ -138,7 +146,6 @@ class CoderedPage(WagtailCacheMixin, Page, metaclass=CoderedPageMeta):
         verbose_name=_('Cover image'),
     )
 
-
     ###############
     # Index fields
     ###############
@@ -184,7 +191,6 @@ class CoderedPage(WagtailCacheMixin, Page, metaclass=CoderedPageMeta):
         help_text=_('Enable filtering child pages by these classifiers.'),
     )
 
-
     ###############
     # Layout fields
     ###############
@@ -196,7 +202,6 @@ class CoderedPage(WagtailCacheMixin, Page, metaclass=CoderedPageMeta):
         verbose_name=_('Template')
     )
 
-
     ###############
     # SEO fields
     ###############
@@ -208,7 +213,12 @@ class CoderedPage(WagtailCacheMixin, Page, metaclass=CoderedPageMeta):
         on_delete=models.SET_NULL,
         related_name='+',
         verbose_name=_('Open Graph preview image'),
-        help_text=_('The image shown when linking to this page on social media. If blank, defaults to article cover image, or logo in Settings > Layout > Logo')
+        help_text=_(
+            '''
+            The image shown when linking to this page on social media.
+            If blank, defaults to article cover image, or logo in Settings > Layout > Logo
+            '''
+        )
     )
     struct_org_type = models.CharField(
         default='',
@@ -241,7 +251,12 @@ class CoderedPage(WagtailCacheMixin, Page, metaclass=CoderedPageMeta):
         on_delete=models.SET_NULL,
         related_name='+',
         verbose_name=_('Photo of Organization'),
-        help_text=_('A photo of the facility. This photo will be cropped to 1:1, 4:3, and 16:9 aspect ratios automatically.')
+        help_text=_(
+            '''
+            A photo of the facility. This photo will be cropped to 1:1,
+            4:3, and 16:9 aspect ratios automatically.
+            '''
+        )
     )
     struct_org_phone = models.CharField(
         blank=True,
@@ -277,7 +292,12 @@ class CoderedPage(WagtailCacheMixin, Page, metaclass=CoderedPageMeta):
         blank=True,
         max_length=255,
         verbose_name=_('Country'),
-        help_text=_('For example, USA. Two-letter ISO 3166-1 alpha-2 country code is also acceptible https://en.wikipedia.org/wiki/ISO_3166-1')
+        help_text=_(
+            '''
+            For example, USA. Two-letter ISO 3166-1 alpha-2 country
+            code is also acceptible https://en.wikipedia.org/wiki/ISO_3166-1
+            '''
+        )
     )
     struct_org_geo_lat = models.DecimalField(
         blank=True,
@@ -310,10 +330,14 @@ class CoderedPage(WagtailCacheMixin, Page, metaclass=CoderedPageMeta):
     struct_org_extra_json = models.TextField(
         blank=True,
         verbose_name=_('Additional Organization markup'),
-        help_text=_('Additional JSON-LD inserted into the Organization dictionary. Must be properties of https://schema.org/Organization or the selected organization type.')
+        help_text=_(
+            '''
+            Additional JSON-LD inserted into the Organization dictionary.
+            Must be properties of https://schema.org/Organization or the selected organization type.
+            '''
+        )
     )
 
-
     ###############
     # Classify
     ###############
@@ -322,7 +346,12 @@ class CoderedPage(WagtailCacheMixin, Page, metaclass=CoderedPageMeta):
         'coderedcms.ClassifierTerm',
         blank=True,
         verbose_name=_('Classifiers'),
-        help_text=_('Categorize and group pages together with classifiers. Used to organize and filter pages across the site.'),
+        help_text=_(
+            '''
+            Categorize and group pages together with classifiers.
+            Used to organize and filter pages across the site.
+            '''
+        ),
     )
     tags = ClusterTaggableManager(
         through=CoderedTag,
@@ -331,7 +360,6 @@ class CoderedPage(WagtailCacheMixin, Page, metaclass=CoderedPageMeta):
         help_text=_('Used to organize pages across the site.'),
     )
 
-
     ###############
     # Settings
     ###############
@@ -344,7 +372,6 @@ class CoderedPage(WagtailCacheMixin, Page, metaclass=CoderedPageMeta):
         verbose_name=_('Content Walls')
     )
 
-
     ###############
     # Search
     ###############
@@ -370,7 +397,6 @@ class CoderedPage(WagtailCacheMixin, Page, metaclass=CoderedPageMeta):
         index.FilterField('classifier_terms'),
     ]
 
-
     ###############
     # Panels
     ###############
@@ -460,8 +486,7 @@ class CoderedPage(WagtailCacheMixin, Page, metaclass=CoderedPageMeta):
         super().__init__(*args, **kwargs)
         klassname = self.__class__.__name__.lower()
         template_choices = cr_settings['FRONTEND_TEMPLATES_PAGES'].get('*', ()) + \
-                           cr_settings['FRONTEND_TEMPLATES_PAGES'].get(klassname, ())
-
+            cr_settings['FRONTEND_TEMPLATES_PAGES'].get(klassname, ())
 
         self._meta.get_field('index_order_by').choices = self.index_order_by_choices
         self._meta.get_field('custom_template').choices = template_choices
@@ -469,14 +494,16 @@ class CoderedPage(WagtailCacheMixin, Page, metaclass=CoderedPageMeta):
             self.index_order_by = self.index_order_by_default
             self.index_show_subpages = self.index_show_subpages_default
 
-
     @classmethod
     def get_edit_handler(cls):
         """
         Override to "lazy load" the panels overriden by subclasses.
         """
         panels = [
-            ObjectList(cls.content_panels + cls.body_content_panels + cls.bottom_content_panels, heading=_('Content')),
+            ObjectList(
+                cls.content_panels + cls.body_content_panels + cls.bottom_content_panels,
+                heading=_('Content')
+            ),
             ObjectList(cls.classify_panels, heading=_('Classify')),
             ObjectList(cls.layout_panels, heading=_('Layout')),
             ObjectList(cls.promote_panels, heading=_('SEO'), classname="seo"),
@@ -484,7 +511,11 @@ class CoderedPage(WagtailCacheMixin, Page, metaclass=CoderedPageMeta):
         ]
 
         if cls.integration_panels:
-            panels.append(ObjectList(cls.integration_panels, heading='Integrations', classname='integrations'))
+            panels.append(ObjectList(
+                cls.integration_panels,
+                heading='Integrations',
+                classname='integrations'
+            ))
 
         return TabbedInterface(panels).bind_to_model(cls)
 
@@ -581,7 +612,15 @@ class CoderedPage(WagtailCacheMixin, Page, metaclass=CoderedPageMeta):
                             for term in selected_terms:
                                 all_children = all_children.filter(classifier_terms=term)
                         except:
-                            logger.warning("Tried to filter by ClassifierTerm, but <%s.%s ('%s')>.get_index_children() did not return a queryset or is not a queryset of CoderedPage models.", self._meta.app_label, self.__class__.__name__, self.title)
+                            logger.warning(
+                                '''
+                                Tried to filter by ClassifierTerm, but <%s.%s ('%s')>.get_index_children() did
+                                not return a queryset or is not a queryset of CoderedPage models.
+                                ''',
+                                self._meta.app_label,
+                                self.__class__.__name__,
+                                self.title
+                            )
             paginator = Paginator(all_children, self.index_num_per_page)
             pagenum = request.GET.get('p', 1)
             try:
@@ -594,9 +633,6 @@ class CoderedPage(WagtailCacheMixin, Page, metaclass=CoderedPageMeta):
         context['content_walls'] = self.get_content_walls(check_child_setting=False)
         return context
 
-
-
-
 ###############################################################################
 # Abstract pages providing pre-built common website functionality, suitable for subclassing.
 # These are abstract so subclasses can override fields if desired.
@@ -841,7 +877,7 @@ class CoderedEventPage(CoderedWebPage, BaseEvent):
             for occurrence in self.occurrences.all():
                 aoc += [instance for instance in occurrence.all_occurrences()]
             if len(aoc) > 0:
-                return aoc[-1] # last one in the list
+                return aoc[-1]  # last one in the list
 
         except AttributeError:
             # Triggers when a preview is initiated on an EventPage because it uses a FakeQuerySet object.
@@ -862,8 +898,11 @@ class CoderedEventPage(CoderedWebPage, BaseEvent):
         }
 
         if 'limit' in kwargs:
-            if kwargs['limit'] != None:
-                # Limit the number of event instances that will be generated per occurrence rule to 10, if not otherwise specified.
+            if kwargs['limit'] is not None:
+                '''
+                Limit the number of event instances that will be
+                generated per occurrence rule to 10, if not otherwise specified.
+                '''
                 occurrence_kwargs['limit'] = kwargs.get('limit', 10)
 
         # For each occurrence rule in all of the occurrence rules for this event.
@@ -916,6 +955,7 @@ class CoderedEventPage(CoderedWebPage, BaseEvent):
             events.append(self.convert_to_ical_format(occurrence=occurrence))
         return events
 
+
 class DefaultCalendarViewChoices():
     MONTH = 'month'
     AGENDA_WEEK = 'agendaWeek'
@@ -930,6 +970,7 @@ class DefaultCalendarViewChoices():
         (LIST_MONTH, _('Calendar List View')),
     )
 
+
 class CoderedEventIndexPage(CoderedWebPage):
     """
     Shows a list of event sub-pages.
@@ -984,7 +1025,7 @@ class CoderedEventIndexPage(CoderedWebPage):
                 event_data = {
                     'title': event.title,
                     'start': occurrence[0].strftime('%Y-%m-%dT%H:%M:%S'),
-                    'end' : occurrence[1].strftime('%Y-%m-%dT%H:%M:%S') if occurrence[1] else "",
+                    'end': occurrence[1].strftime('%Y-%m-%dT%H:%M:%S') if occurrence[1] else "",
                     'description': "",
                 }
                 if event.url:
@@ -1002,25 +1043,33 @@ class CoderedEventOccurrence(Orderable, BaseOccurrence):
 
 
 class CoderedFormMixin(models.Model):
-
     class Meta:
-        abstract=True
+        abstract = True
 
     submissions_list_view_class = CoderedSubmissionsListView
     encoder = DjangoJSONEncoder
 
-    ### Custom codered fields
+    # Custom codered fields
     to_address = models.CharField(
         max_length=255,
         blank=True,
         verbose_name=_('Email form submissions to'),
-        help_text=_('Optional - email form submissions to this address. Separate multiple addresses by comma.')
+        help_text=_(
+            '''
+            Optional - email form submissions to this address. Separate multiple addresses by comma.
+            '''
+        )
     )
     reply_address = models.CharField(
         max_length=255,
         blank=True,
         verbose_name=_('Reply-to address'),
-        help_text=_('Optional - to reply to the submitter, specify the email field here. For example, if a form field above is labeled "Your Email", enter: {{ your_email }}')
+        help_text=_(
+            '''
+            Optional - to reply to the submitter, specify the email field here.
+            For example, if a form field above is labeled "Your Email", enter: {{ your_email }}'
+            '''
+        )
     )
     subject = models.CharField(
         max_length=255,
@@ -1091,7 +1140,6 @@ class CoderedFormMixin(models.Model):
         help_text=_('Date and time when the FORM will no longer be available on the page.'),
     )
 
-
     body_content_panels = [
         MultiFieldPanel(
             [
@@ -1131,7 +1179,6 @@ class CoderedFormMixin(models.Model):
         )
     ]
 
-
     @property
     def form_live(self):
         """
@@ -1327,6 +1374,7 @@ class CoderedFormMixin(models.Model):
         view = self.submissions_list_view_class.as_view()
         return view(request, form_page=self, *args, **kwargs)
 
+
 class CoderedFormPage(CoderedFormMixin, CoderedWebPage):
     """
     This is basically a clone of wagtail.contrib.forms.models.AbstractForm
@@ -1435,6 +1483,7 @@ class CoderedFormPage(CoderedFormMixin, CoderedWebPage):
         )
         return response
 
+
 class CoderedSubmissionRevision(SubmissionRevision, models.Model):
     pass
 
@@ -1476,11 +1525,9 @@ class CoderedSessionFormSubmission(SessionFormSubmission):
     def render_link(self, value):
         return "{0}{1}".format(cr_settings['PROTECTED_MEDIA_URL'], value)
 
-
     def render_image(self, value):
         return "{0}{1}".format(cr_settings['PROTECTED_MEDIA_URL'], value)
 
-
     def render_file(self, value):
         return "{0}{1}".format(cr_settings['PROTECTED_MEDIA_URL'], value)
 
@@ -1492,8 +1539,7 @@ def create_submission_changed_revision(sender, **kwargs):
     submission = kwargs['instance']
     created = kwargs['created']
     CoderedSubmissionRevision.create_from_submission(
-        submission, (CoderedSubmissionRevision.CREATED if created
-                     else CoderedSubmissionRevision.CHANGED))
+        submission, (CoderedSubmissionRevision.CREATED if created else CoderedSubmissionRevision.CHANGED))
 
 
 @receiver(post_delete)
@@ -1502,7 +1548,7 @@ def create_submission_deleted_revision(sender, **kwargs):
         return
     submission = kwargs['instance']
     CoderedSubmissionRevision.create_from_submission(submission,
-                                              SubmissionRevision.DELETED)
+                                                     SubmissionRevision.DELETED)
 
 
 class CoderedStep(Step):
@@ -1537,7 +1583,7 @@ class CoderedSteps(Steps):
 
 class CoderedStreamFormMixin(StreamFormMixin):
     class Meta:
-        abstract=True
+        abstract = True
 
     def get_steps(self, request=None):
         if not hasattr(self, 'steps'):
@@ -1591,9 +1637,9 @@ class CoderedStreamFormPage(CoderedStreamFormMixin, CoderedFormMixin, CoderedWeb
     body_content_panels = [
         StreamFieldPanel('form_fields')
     ] + \
-    CoderedFormMixin.body_content_panels + [
-        InlinePanel('confirmation_emails', label=_('Confirmation Emails'))
-    ]
+        CoderedFormMixin.body_content_panels + [
+            InlinePanel('confirmation_emails', label=_('Confirmation Emails'))
+        ]
 
     def serve(self, request, *args, **kwargs):
         context = self.get_context(request)
@@ -1619,6 +1665,7 @@ class CoderedStreamFormPage(CoderedStreamFormMixin, CoderedFormMixin, CoderedWeb
                 base_url=cr_settings['PROTECTED_MEDIA_URL']
             )
 
+
 class CoderedLocationPage(CoderedWebPage):
     """
     Location, suitable for store locations or help centers.
@@ -1729,20 +1776,24 @@ class CoderedLocationPage(CoderedWebPage):
     def to_geojson(self):
         return {
             "type": "Feature",
-            "geometry":{
+            "geometry": {
                 "type": "Point",
                 "coordinates": [self.longitude, self.latitude]
             },
-            "properties":{
+            "properties": {
                 "list_description": self.render_list_description,
                 "pin_description": self.render_pin_description
             }
         }
 
     def save(self, *args, **kwargs):
-        if self.auto_update_latlng and GoogleApiSettings.for_site(Site.objects.get(is_default_site=True)).google_maps_api_key:
+        if self.auto_update_latlng and GoogleApiSettings.for_site(
+            Site.objects.get(is_default_site=True)
+        ).google_maps_api_key:
             try:
-                g = geocoder.google(self.address, key=GoogleApiSettings.for_site(Site.objects.get(is_default_site=True)).google_maps_api_key)
+                g = geocoder.google(self.address, key=GoogleApiSettings.for_site(
+                    Site.objects.get(is_default_site=True)
+                ).google_maps_api_key)
                 self.latitude = g.latlng[0]
                 self.longitude = g.latlng[1]
             except TypeError:
@@ -1751,10 +1802,11 @@ class CoderedLocationPage(CoderedWebPage):
 
         return super(CoderedLocationPage, self).save(*args, **kwargs)
 
-
     def get_context(self, request, *args, **kwargs):
         context = super().get_context(request)
-        context['google_api_key'] = GoogleApiSettings.for_site(Site.objects.get(is_default_site=True)).google_maps_api_key
+        context['google_api_key'] = GoogleApiSettings.for_site(
+            Site.objects.get(is_default_site=True)
+        ).google_maps_api_key
         return context
 
 
@@ -1788,7 +1840,12 @@ class CoderedLocationIndexPage(CoderedWebPage):
             MaxValueValidator(20),
             MinValueValidator(1),
         ],
-        help_text=_('Requires API key to use zoom. 1: World, 5: Landmass/continent, 10: City, 15: Streets, 20: Buildings')
+        help_text=_(
+            '''
+            Requires API key to use zoom. 1: World, 5: Landmass/continent,
+            10: City, 15: Streets, 20: Buildings
+            '''
+        )
     )
 
     layout_panels = CoderedWebPage.layout_panels + [
@@ -1820,7 +1877,12 @@ class CoderedLocationIndexPage(CoderedWebPage):
             southwest = [float(x) for x in southwest.split(',')]
             northeast = [float(x) for x in northeast.split(',')]
 
-            qs = qs.filter(latitude__gte=southwest[0], latitude__lte=northeast[0], longitude__gte=southwest[1], longitude__lte=northeast[1])
+            qs = qs.filter(
+                latitude__gte=southwest[0],
+                latitude__lte=northeast[0],
+                longitude__gte=southwest[1],
+                longitude__lte=northeast[1]
+            )
 
         return {
             "type": "FeatureCollection",
@@ -1841,5 +1903,7 @@ class CoderedLocationIndexPage(CoderedWebPage):
 
     def get_context(self, request, *args, **kwargs):
         context = super().get_context(request)
-        context['google_api_key'] = GoogleApiSettings.for_site(Site.objects.get(is_default_site=True)).google_maps_api_key
+        context['google_api_key'] = GoogleApiSettings.for_site(
+            Site.objects.get(is_default_site=True)
+        ).google_maps_api_key
         return context

+ 36 - 6
coderedcms/models/snippet_models.py

@@ -38,7 +38,11 @@ class Carousel(ClusterableModel):
     show_controls = models.BooleanField(
         default=True,
         verbose_name=_('Show controls'),
-        help_text=_('Shows arrows on the left and right of the carousel to advance next or previous slides.'),
+        help_text=_(
+            '''
+            Shows arrows on the left and right of the carousel to advance next or previous slides.
+            '''
+        ),
     )
     show_indicators = models.BooleanField(
         default=True,
@@ -297,6 +301,7 @@ class Footer(models.Model):
     def __str__(self):
         return self.name
 
+
 @register_snippet
 class ReusableContent(models.Model):
     """
@@ -375,11 +380,36 @@ class CoderedEmail(ClusterableModel):
         abstract = True
         verbose_name = _('CodeRed Email')
 
-    to_address = models.CharField(max_length=255, blank=True, verbose_name=_('To Addresses'), help_text=_('Separate multiple email addresses with commas.'))
-    from_address = models.CharField(max_length=255, blank=True, verbose_name=_('From Address'), help_text=_('For example: "sender@example.com" or "Sender Name <sender@example.com>" (without quotes).'))
-    reply_address = models.CharField(max_length=255, blank=True, verbose_name=_('Reply-To Address'), help_text=_('Separate multiple email addresses with commas.'))
-    cc_address = models.CharField(max_length=255, blank=True, verbose_name=_('CC'), help_text=_('Separate multiple email addresses with commas.'))
-    bcc_address = models.CharField(max_length=255, blank=True, verbose_name=_('BCC'), help_text=_('Separate multiple email addresses with commas.'))
+    to_address = models.CharField(
+        max_length=255,
+        blank=True,
+        verbose_name=_('To Addresses'),
+        help_text=_('Separate multiple email addresses with commas.')
+    )
+    from_address = models.CharField(
+        max_length=255,
+        blank=True,
+        verbose_name=_('From Address'),
+        help_text=_('For example: "sender@example.com" or "Sender Name <sender@example.com>" (without quotes).')
+    )
+    reply_address = models.CharField(
+        max_length=255,
+        blank=True,
+        verbose_name=_('Reply-To Address'),
+        help_text=_('Separate multiple email addresses with commas.')
+    )
+    cc_address = models.CharField(
+        max_length=255,
+        blank=True,
+        verbose_name=_('CC'),
+        help_text=_('Separate multiple email addresses with commas.')
+    )
+    bcc_address = models.CharField(
+        max_length=255,
+        blank=True,
+        verbose_name=_('BCC'),
+        help_text=_('Separate multiple email addresses with commas.')
+    )
     subject = models.CharField(max_length=255, blank=True, verbose_name=_('Subject'))
     body = models.TextField(blank=True, verbose_name=_('Body'))
 

+ 10 - 6
coderedcms/models/tests/test_page_models.py

@@ -28,12 +28,13 @@ from coderedcms.tests.testapp.models import (
     WebPage
 )
 
+
 class BasicPageTestCase():
     """
     This is a testing mixin used to run common tests for basic versions of page types.
     """
     class Meta:
-        abstract=True
+        abstract = True
 
     def setUp(self):
         self.request_factory = RequestFactory()
@@ -54,12 +55,13 @@ class BasicPageTestCase():
         response = self.basic_page.serve(request)
         self.assertEqual(response.status_code, 200)
 
+
 class AbstractPageTestCase():
     """
     This is a testing mixin used to run common tests for abstract page types.
     """
     class Meta:
-        abstract=True
+        abstract = True
 
     def test_not_available(self):
         """
@@ -74,7 +76,7 @@ class ConcretePageTestCase():
     This is a testing mixin used to run common tests for concrete page types.
     """
     class Meta:
-        abstract=True
+        abstract = True
 
     def test_is_available(self):
         """
@@ -86,11 +88,12 @@ class ConcretePageTestCase():
 
 class ConcreteBasicPageTestCase(ConcretePageTestCase, BasicPageTestCase):
     class Meta:
-        abstract=True
+        abstract = True
+
 
 class ConcreteFormPageTestCase(ConcreteBasicPageTestCase):
     class Meta:
-        abstract=True
+        abstract = True
 
     def test_post(self):
         """
@@ -103,6 +106,7 @@ class ConcreteFormPageTestCase(ConcreteBasicPageTestCase):
         response = self.basic_page.serve(request)
         self.assertEqual(response.status_code, 200)
 
+
 class CoderedArticleIndexPageTestCase(AbstractPageTestCase, WagtailPageTests):
     model = CoderedArticleIndexPage
 
@@ -180,4 +184,4 @@ class LocationPageTestCase(ConcreteBasicPageTestCase, WagtailPageTests):
 
 
 class StreamFormPageTestCase(ConcreteFormPageTestCase, WagtailPageTests):
-    model = StreamFormPage
+    model = StreamFormPage

+ 45 - 8
coderedcms/models/wagtailsettings_models.py

@@ -223,7 +223,12 @@ class AnalyticsSettings(BaseSetting):
     ga_track_button_clicks = models.BooleanField(
         default=False,
         verbose_name=_('Track button clicks'),
-        help_text=_('Track all button clicks using Google Analytics event tracking. Event tracking details can be specified in each button’s advanced settings options.'),
+        help_text=_(
+            '''
+            Track all button clicks using Google Analytics event tracking.
+            Event tracking details can be specified in each button’s advanced settings options.
+            '''
+        ),
     )
 
     panels = [
@@ -248,7 +253,11 @@ class ADASettings(BaseSetting):
     skip_navigation = models.BooleanField(
         default=False,
         verbose_name=_('Show skip navigation link'),
-        help_text=_('Shows a "Skip Navigation" link above the navbar that takes you directly to the main content.'),
+        help_text=_(
+            '''
+            Shows a "Skip Navigation" link above the navbar that takes you directly to the main content.
+            '''
+        ),
     )
 
     panels = [
@@ -273,7 +282,12 @@ class GeneralSettings(BaseSetting):
         blank=True,
         max_length=255,
         verbose_name=_('From email address'),
-        help_text=_('The default email address this site appears to send from. For example: "sender@example.com" or "Sender Name <sender@example.com>" (without quotes)'),
+        help_text=_(
+            '''
+            The default email address this site appears to send from.
+            For example: "sender@example.com" or "Sender Name <sender@example.com>" (without quotes)
+            '''
+        ),
     )
     search_num_results = models.PositiveIntegerField(
         default=10,
@@ -311,22 +325,41 @@ class SeoSettings(BaseSetting):
     og_meta = models.BooleanField(
         default=True,
         verbose_name=_('Use OpenGraph Markup'),
-        help_text=_('Show an optimized preview when linking to this site on Facebook, Linkedin, Twitter, and others. See http://ogp.me/.'),
+        help_text=_(
+            '''
+            Show an optimized preview when linking to this site on
+            Facebook, Linkedin, Twitter, and others. See http://ogp.me/.
+            '''
+        ),
     )
     twitter_meta = models.BooleanField(
         default=True,
         verbose_name=_('Use Twitter Markup'),
-        help_text=_('Shows content as a "card" when linking to this site on Twitter. See https://developer.twitter.com/en/docs/tweets/optimize-with-cards/overview/abouts-cards.'),
+        help_text=_(
+            '''
+            Shows content as a "card" when linking to this site on Twitter.
+            See https://developer.twitter.com/en/docs/tweets/optimize-with-cards/overview/abouts-cards.
+            '''
+        ),
     )
     struct_meta = models.BooleanField(
         default=True,
         verbose_name=_('Use Structured Data'),
-        help_text=_('Optimizes information about your organization for search engines. See https://schema.org/.'),
+        help_text=_(
+            '''
+            Optimizes information about your organization for search engines. See https://schema.org/.
+            '''
+        ),
     )
     amp_pages = models.BooleanField(
         default=True,
         verbose_name=_('Use AMP Pages'),
-        help_text=_('Generates an alternate AMP version of Article pages that are preferred by search engines. See https://www.ampproject.org/'),
+        help_text=_(
+            '''
+            Generates an alternate AMP version of Article pages that are preferred by search engines.
+            See https://www.ampproject.org/
+            '''
+        ),
     )
 
     panels = [
@@ -336,7 +369,11 @@ class SeoSettings(BaseSetting):
                 FieldPanel('twitter_meta'),
                 FieldPanel('struct_meta'),
                 FieldPanel('amp_pages'),
-                HelpPanel(content=_('If these settings are enabled, the corresponding values in each page’s SEO tab are used.')),
+                HelpPanel(content=_(
+                    '''
+                    If these settings are enabled, the corresponding values in each page’s SEO tab are used.
+                    '''
+                )),
             ],
             heading=_('Search Engine Optimization')
         )

+ 3 - 0
coderedcms/pyvenv.cfg

@@ -0,0 +1,3 @@
+home = C:\Users\KevinCummings\AppData\Local\Programs\Python\Python36
+include-system-site-packages = false
+version = 3.6.5

+ 7 - 3
coderedcms/settings.py

@@ -3,7 +3,9 @@ from django.conf import settings
 from django.utils.lru_cache import lru_cache
 
 
-PROJECT_DIR = settings.PROJECT_DIR if getattr(settings, 'PROJECT_DIR') else os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+PROJECT_DIR = settings.PROJECT_DIR if getattr(settings, 'PROJECT_DIR') else os.path.dirname(
+    os.path.dirname(os.path.abspath(__file__))
+)
 BASE_DIR = settings.BASE_DIR if getattr(settings, 'BASE_DIR') else os.path.dirname(PROJECT_DIR)
 
 DEFAULTS = {
@@ -95,7 +97,8 @@ DEFAULTS = {
         ('navbar-expand-xl', 'xl - Show on extra large screens (desktop, wide monitor)'),
     ),
 
-    'FRONTEND_THEME_HELP': 'Change the color palette of your site with a Bootstrap theme. Powered by Bootswatch https://bootswatch.com/.',
+    'FRONTEND_THEME_HELP': '''Change the color palette of your site with a Bootstrap theme.
+                              Powered by Bootswatch https://bootswatch.com/.''',
     'FRONTEND_THEME_DEFAULT': '',
     'FRONTEND_THEME_CHOICES': (
         ('', 'Default - Classic Bootstrap'),
@@ -140,7 +143,8 @@ DEFAULTS = {
             ('coderedcms/blocks/pagelist_block.html', 'General, simple list'),
             ('coderedcms/blocks/pagelist_list_group.html', 'General, list group navigation panel'),
             ('coderedcms/blocks/pagelist_article_media.html', 'Article, media format'),
-            ('coderedcms/blocks/pagelist_article_card_group.html', 'Article, card group - attached cards of equal size'),
+            ('coderedcms/blocks/pagelist_article_card_group.html',
+                'Article, card group - attached cards of equal size'),
             ('coderedcms/blocks/pagelist_article_card_deck.html', 'Article, card deck - separate cards of equal size'),
             ('coderedcms/blocks/pagelist_article_card_columns.html', 'Article, card masonry - fluid brick pattern'),
         ),

+ 21 - 3
coderedcms/templatetags/coderedcms_tags.py

@@ -1,13 +1,11 @@
 import string
 import random
-from html import unescape
 
 
 from datetime import datetime
 from django import template
 from django.conf import settings
 from django.forms import ClearableFileInput
-from django.utils import timezone
 from django.utils.html import mark_safe
 from wagtail.core.models import Collection
 from wagtail.core.rich_text import RichText
@@ -22,6 +20,7 @@ from coderedcms.settings import cr_settings, get_bootstrap_setting
 
 register = template.Library()
 
+
 @register.filter
 def get_embed_video_provider(url):
     if 'youtu.be' in url or 'youtube.com' in url:
@@ -30,6 +29,7 @@ def get_embed_video_provider(url):
         return 'vimeo'
     return ''
 
+
 @register.filter
 def get_embed_video_code(url):
     if get_embed_video_provider(url) == 'youtube':
@@ -40,31 +40,37 @@ def get_embed_video_code(url):
         return v.split('?', 1)[0]
     return ''
 
+
 @register.filter
 def is_advanced_setting(obj):
     return CoderedAdvSettings in (obj.__class__,) + obj.__class__.__bases__
 
+
 @register.filter
 def is_file_form(form):
     return any([isinstance(field.field.widget, ClearableFileInput) for field in form])
 
+
 @register.simple_tag
 def coderedcms_version():
     return __version__
 
+
 @register.simple_tag
 def generate_random_id():
     return ''.join(random.choice(string.ascii_letters + string.digits) for n in range(20))
 
+
 @register.simple_tag
 def is_menu_item_dropdown(value):
     return \
         len(value.get('sub_links', [])) > 0 or \
         (
-            value.get('show_child_links', False) and \
+            value.get('show_child_links', False) and
             len(value.get('page', []).get_children().live()) > 0
         )
 
+
 @register.simple_tag(takes_context=True)
 def is_active_page(context, curr_page, other_page):
     if hasattr(curr_page, 'get_url') and hasattr(other_page, 'get_url'):
@@ -73,29 +79,35 @@ def is_active_page(context, curr_page, other_page):
         return curr_url == other_url
     return False
 
+
 @register.simple_tag
 def get_pictures(collection_id):
     collection = Collection.objects.get(id=collection_id)
     return Image.objects.filter(collection=collection)
 
+
 @register.simple_tag
 def get_navbars():
     return Navbar.objects.all()
 
+
 @register.simple_tag
 def get_footers():
     return Footer.objects.all()
 
+
 @register.simple_tag
 def get_searchform(request=None):
     if request:
         return SearchForm(request.GET)
     return SearchForm()
 
+
 @register.simple_tag
 def get_pageform(page, request):
     return page.get_form(page=page, user=request.user)
 
+
 @register.simple_tag
 def process_form_cell(request, cell):
     if isinstance(cell, str) and cell.startswith(cr_settings['PROTECTED_MEDIA_URL']):
@@ -104,18 +116,22 @@ def process_form_cell(request, cell):
         return mark_safe("<a href='{0}'>{1}</a>".format(cell, cell))
     return cell
 
+
 @register.filter
 def codered_settings(value):
     return cr_settings.get(value, None)
 
+
 @register.filter
 def bootstrap_settings(value):
     return get_bootstrap_setting(value)
 
+
 @register.filter
 def django_settings(value):
     return getattr(settings, value)
 
+
 @register.simple_tag
 def query_update(querydict, key=None, value=None):
     """
@@ -132,6 +148,7 @@ def query_update(querydict, key=None, value=None):
                 pass
     return get
 
+
 @register.filter
 def structured_data_datetime(dt):
     """
@@ -141,6 +158,7 @@ def structured_data_datetime(dt):
         return datetime.strftime(dt, "%Y-%m-%dT%H:%M")
     return datetime.strftime(dt, "%Y-%m-%d")
 
+
 @register.filter
 def richtext_amp(value):
 

+ 2 - 2
coderedcms/tests/settings.py

@@ -78,7 +78,7 @@ MIDDLEWARE = [
     'django.middleware.security.SecurityMiddleware',
 
     # Error reporting. Uncomment this to recieve emails when a 404 is triggered.
-    #'django.middleware.common.BrokenLinkEmailsMiddleware',
+    # 'django.middleware.common.BrokenLinkEmailsMiddleware',
 
     # CMS functionality
     'wagtail.core.middleware.SiteMiddleware',
@@ -205,4 +205,4 @@ EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
 
 WAGTAIL_CACHE = False
 
-SECRET_KEY = 'not needed'
+SECRET_KEY = 'not needed'

+ 7 - 2
coderedcms/tests/testapp/models.py

@@ -21,7 +21,7 @@ class ArticlePage(CoderedArticlePage):
     """
     class Meta:
         verbose_name = 'Article'
-        ordering = ['-first_published_at',]
+        ordering = ['-first_published_at', ]
 
     # Only allow this page to be created beneath an ArticleIndexPage.
     parent_page_types = ['testapp.ArticleIndexPage']
@@ -67,6 +67,7 @@ class FormPageField(CoderedFormField):
 
     page = ParentalKey('FormPage', related_name='form_fields')
 
+
 class FormConfirmEmail(CoderedEmail):
     """
     Sends a confirmation email after submitting a FormPage.
@@ -84,6 +85,7 @@ class WebPage(CoderedWebPage):
 
     template = 'coderedcms/pages/web_page.html'
 
+
 class EventPage(CoderedEventPage):
     class Meta:
         verbose_name = 'Event Page'
@@ -112,6 +114,7 @@ class EventIndexPage(CoderedEventIndexPage):
 class EventOccurrence(CoderedEventOccurrence):
     event = ParentalKey(EventPage, related_name='occurrences')
 
+
 class LocationPage(CoderedLocationPage):
     """
     A page that holds a location.  This could be a store, a restaurant, etc.
@@ -141,11 +144,13 @@ class LocationIndexPage(CoderedLocationIndexPage):
 
     template = 'coderedcms/pages/location_index_page.html'
 
+
 class StreamFormPage(CoderedStreamFormPage):
     class Meta:
         verbose_name = 'Stream Form'
 
     template = 'coderedcms/pages/stream_form_page.html'
 
+
 class StreamFormConfirmEmail(CoderedEmail):
-    page = ParentalKey('StreamFormPage', related_name='confirmation_emails')
+    page = ParentalKey('StreamFormPage', related_name='confirmation_emails')

+ 0 - 1
coderedcms/tests/urls.py

@@ -1,4 +1,3 @@
-from django.conf import settings
 from django.urls import include, path, re_path
 from django.contrib import admin
 from wagtail.documents import urls as wagtaildocs_urls

+ 5 - 2
coderedcms/urls.py

@@ -18,7 +18,11 @@ urlpatterns = [
     # CodeRed custom URLs
     re_path(r'^sitemap\.xml$', cache_page(sitemap), name='codered_sitemap'),
     re_path(r'^robots\.txt$', cache_page(robots), name='codered_robots'),
-    re_path(r'^{0}(?P<path>.*)$'.format(cr_settings['PROTECTED_MEDIA_URL'].lstrip('/')), serve_protected_file, name="serve_protected_file"),
+    re_path(r'^{0}(?P<path>.*)$'.format(
+        cr_settings['PROTECTED_MEDIA_URL'].lstrip('/')),
+        serve_protected_file,
+        name="serve_protected_file"
+    ),
 
     # Event/Calendar URLs
     path('ical/generate/single/', event_generate_single_ical_for_event, name='event_generate_single_ical'),
@@ -28,5 +32,4 @@ urlpatterns = [
 
     # Wagtail
     re_path(r'', include(wagtailcore_urls)),
-
 ]

+ 6 - 1
coderedcms/utils.py

@@ -5,11 +5,13 @@ from django.utils.html import mark_safe
 
 from coderedcms.settings import cr_settings
 
+
 def get_protected_media_link(request, path, render_link=False):
     if render_link:
         return mark_safe("<a href='{0}{1}'>{0}{1}</a>".format(request.build_absolute_uri('/')[:-1], path))
     return "{0}{1}".format(request.build_absolute_uri('/')[:-1], path)
 
+
 def uri_validator(possible_uri):
     validate = URLValidator()
     try:
@@ -18,6 +20,7 @@ def uri_validator(possible_uri):
     except ValidationError:
         return False
 
+
 def attempt_protected_media_value_conversion(request, value):
     try:
         if value.startswith(cr_settings['PROTECTED_MEDIA_URL']):
@@ -28,6 +31,7 @@ def attempt_protected_media_value_conversion(request, value):
 
     return value
 
+
 def fix_ical_datetime_format(dt_str):
     """
     ICAL generation gives timezones in the format of 2018-06-30T14:00:00-04:00.
@@ -39,6 +43,7 @@ def fix_ical_datetime_format(dt_str):
         return dt_str
     return dt_str
 
+
 def convert_to_amp(value):
     """
     Function that converts non-amp compliant html to valid amp html.
@@ -46,7 +51,7 @@ def convert_to_amp(value):
     """
     soup = BeautifulSoup(value)
 
-    #Replace img tags with amp-img
+    # Replace img tags with amp-img
     try:
         img_tags = soup.find('img')
         img_tags.name = 'amp-img'

+ 5 - 5
coderedcms/views.py

@@ -13,7 +13,6 @@ from django.utils.translation import ungettext, ugettext_lazy as _
 from icalendar import Calendar
 
 from wagtail.admin import messages
-from wagtail.core.models import Page
 from wagtail.search.backends import db, get_search_backend
 from wagtail.search.models import Query
 
@@ -24,8 +23,6 @@ from coderedcms.importexport import convert_csv_to_json, import_pages, ImportPag
 from coderedcms.settings import cr_settings
 
 
-
-
 def search(request):
     """
     Searches pages across the entire site.
@@ -159,7 +156,7 @@ def event_generate_recurring_ical_for_event(request):
             try:
                 event = event_page_model.objects.get(pk=event_pk)
                 break
-            except event_page_modal.DoesNotExist:
+            except event_page_model.DoesNotExist:
                 pass
         ical = Calendar()
         for e in event.create_recurring_ical():
@@ -215,7 +212,10 @@ def import_pages_from_csv_file(request):
     if request.method == 'POST':
         form = ImportPagesFromCSVFileForm(request.POST, request.FILES)
         if form.is_valid():
-            import_data = convert_csv_to_json(form.cleaned_data['file'].read().decode('utf-8').splitlines(), form.cleaned_data['page_type'])
+            import_data = convert_csv_to_json(
+                form.cleaned_data['file'].read().decode('utf-8').splitlines(),
+                form.cleaned_data['page_type']
+            )
             parent_page = form.cleaned_data['parent_page']
             try:
                 page_count = import_pages(import_data, parent_page)

+ 4 - 5
coderedcms/wagtail_flexible_forms/models.py

@@ -12,7 +12,6 @@ from django.conf import settings
 from django.contrib import messages
 from django.contrib.contenttypes.fields import GenericForeignKey
 from django.contrib.contenttypes.models import ContentType
-from django.contrib.humanize.templatetags.humanize import naturaltime
 from django.core.files.storage import default_storage
 from django.core.serializers.json import DjangoJSONEncoder
 from django.db.models import (
@@ -20,7 +19,7 @@ from django.db.models import (
     QuerySet,
 )
 from django.db.models.fields.files import FieldFile
-from django.db.models.signals import post_delete, post_save
+from django.db.models.signals import post_delete
 from django.dispatch import receiver
 from django.forms import Form, ImageField, FileField, URLField, EmailField
 from django.http import HttpResponseRedirect
@@ -295,7 +294,7 @@ class SessionFormSubmission(AbstractFormSubmission):
         verbose_name_plural = _('form submissions')
         unique_together = (('page', 'session_key'),
                            ('page', 'user'))
-        abstract=True
+        abstract = True
 
     @property
     def is_complete(self):
@@ -535,7 +534,7 @@ class SubmissionRevision(Model):
 
     class Meta:
         ordering = ('-created_at',)
-        abstract=True
+        abstract = True
 
     @staticmethod
     def get_filters_for(submission):
@@ -838,4 +837,4 @@ class AbstractStreamForm(StreamFormMixin, AbstractForm):
 
 class AbstractEmailStreamForm(StreamFormMixin, AbstractEmailForm):
     class Meta:
-        abstract = True
+        abstract = True

+ 5 - 5
coderedcms/wagtail_flexible_forms/wagtail_hooks.py

@@ -7,7 +7,7 @@ from django.utils.translation import ugettext_lazy as _
 from wagtail.contrib.modeladmin.helpers import (
     PermissionHelper, PagePermissionHelper, PageAdminURLHelper, AdminURLHelper,
     ButtonHelper)
-from wagtail.contrib.modeladmin.options import ModelAdmin, modeladmin_register
+from wagtail.contrib.modeladmin.options import ModelAdmin
 from wagtail.contrib.modeladmin.views import IndexView, InstanceSpecificView
 from wagtail.admin import messages
 from wagtail.core import hooks
@@ -168,7 +168,7 @@ class SubmissionButtonHelper(ButtonHelper):
                                       classnames_exclude=classnames_exclude)
 
     def approve_button(self, pk, classnames_add=None,
-                        classnames_exclude=None):
+                       classnames_exclude=None):
         if classnames_add is None:
             classnames_add = []
         if 'button-secondary' in classnames_add:
@@ -288,11 +288,11 @@ class SubmissionAdmin(ModelAdmin):
         form_page = self.get_form_page(request)
         if form_page is None:
             return self.list_display
-        l = []
+        fields = []
         for name, label in form_page.get_data_fields():
-            l.append(name)
+            fields.append(name)
             self.add_data_bridge(name, label)
-        return l
+        return fields
 
     def set_status_view(self, request, instance_pk):
         kwargs = {'model_admin': self, 'instance_pk': instance_pk}

+ 12 - 5
coderedcms/wagtail_hooks.py

@@ -6,15 +6,13 @@ from django.http.response import HttpResponse
 from django.urls import reverse
 from django.utils.html import format_html, mark_safe
 from django.utils.translation import ugettext_lazy as _
-from wagtail.contrib.forms.models import AbstractForm
-from wagtail.contrib.modeladmin.options import modeladmin_register
 from wagtail.core import hooks
 from wagtail.core.models import UserPagePermissionsProxy, get_page_models
 from wagtailcache.cache import clear_cache
 
-from coderedcms import utils
 from coderedcms.wagtail_flexible_forms.wagtail_hooks import FormAdmin, SubmissionAdmin
 
+
 @hooks.register('insert_global_admin_css')
 def global_admin_css():
     return format_html('<link rel="stylesheet" type="text/css" href="{}">', static('coderedcms/css/codered-admin.css'))
@@ -58,6 +56,7 @@ def codered_forms(user, editable_forms):
 
     return editable_forms
 
+
 @hooks.register('before_serve_document')
 def serve_document_directly(document, request):
     """
@@ -94,10 +93,18 @@ class CoderedFormAdmin(FormAdmin):
         actions = []
         if issubclass(type(obj.specific), CoderedFormPage):
             actions.append(
-                '<a href="{0}">{1}</a>'.format(reverse('wagtailforms:list_submissions', args=(obj.pk,)), _('See all Submissions'))
+                '<a href="{0}">{1}</a>'.format(reverse(
+                    'wagtailforms:list_submissions',
+                    args=(obj.pk,)),
+                    _('See all Submissions')
+                )
             )
             actions.append(
-                '<a href="{0}">{1}</a>'.format(reverse('wagtailadmin_pages:edit', args=(obj.pk,)), _('Edit this form page'))
+                '<a href="{0}">{1}</a>'.format(reverse(
+                    'wagtailadmin_pages:edit',
+                    args=(obj.pk,)),
+                    _('Edit this form page')
+                )
             )
         elif issubclass(type(obj.specific), CoderedStreamFormPage):
             actions.append(self.unprocessed_submissions_link(obj))

+ 2 - 2
docs/conf.py

@@ -118,7 +118,7 @@ html_static_path = ['_static']
 # default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
 # 'searchbox.html']``.
 #
-html_sidebars = { '**': ['searchbox.html', 'globaltoc.html', 'relations.html', 'versions.html'] }
+html_sidebars = {'**': ['searchbox.html', 'globaltoc.html', 'relations.html', 'versions.html']}
 
 html_context = {
     'css_files': ['_static/docs.css'],
@@ -199,4 +199,4 @@ epub_title = project
 # epub_uid = ''
 
 # A list of files that should not be packed into the epub file.
-epub_exclude_files = ['search.html']
+epub_exclude_files = ['search.html']

BIN
flake8output.txt