Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
H
hypha
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
ots
hypha
Commits
a0881832
Commit
a0881832
authored
6 years ago
by
Todd Dembrey
Browse files
Options
Downloads
Patches
Plain Diff
Refactor the comparison to pull the code into a seperate file
parent
f5f69863
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
opentech/apply/funds/differ.py
+69
-0
69 additions, 0 deletions
opentech/apply/funds/differ.py
opentech/apply/funds/views.py
+5
-58
5 additions, 58 deletions
opentech/apply/funds/views.py
with
74 additions
and
58 deletions
opentech/apply/funds/differ.py
0 → 100644
+
69
−
0
View file @
a0881832
from
difflib
import
SequenceMatcher
import
bleach
from
django.utils.html
import
format_html
from
django.utils.text
import
mark_safe
def
wrap_with_span
(
text
,
class_name
):
return
format_html
(
'
<span class=
"
{}
"
>{}</span>
'
,
class_name
,
mark_safe
(
text
))
def
wrap_deleted
(
text
):
return
wrap_with_span
(
text
,
'
deleted
'
)
def
wrap_added
(
text
):
return
wrap_with_span
(
text
,
'
added
'
)
def
compare
(
answer_a
,
answer_b
,
should_bleach
=
True
):
if
not
answer_a
and
not
answer_b
:
# This catches the case where both results are None and we cant compare
return
answer_b
if
isinstance
(
answer_a
,
dict
)
or
isinstance
(
answer_b
,
dict
):
# TODO: handle file dictionaries
return
answer_b
if
should_bleach
:
answer_a
=
bleach
.
clean
(
answer_a
)
answer_b
=
bleach
.
clean
(
answer_b
)
diff
=
SequenceMatcher
(
None
,
answer_a
,
answer_b
)
output
=
[]
added
=
[]
deleted
=
[]
for
opcode
,
a0
,
a1
,
b0
,
b1
in
diff
.
get_opcodes
():
if
opcode
==
'
equal
'
:
if
a1
-
a0
>
2
or
not
(
added
or
deleted
):
# if there is more than 2 chars the same commit the added and removed text
if
added
:
output
.
append
(
wrap_added
(
''
.
join
(
added
)))
added
=
[]
if
deleted
:
output
.
append
(
wrap_deleted
(
''
.
join
(
deleted
)))
deleted
=
[]
output
.
append
(
diff
.
a
[
a0
:
a1
])
else
:
# ignore the small gap pretend it has been both added and removed
added
.
append
(
diff
.
a
[
a0
:
a1
])
deleted
.
append
(
diff
.
a
[
a0
:
a1
])
elif
opcode
==
'
insert
'
:
added
.
append
(
diff
.
b
[
b0
:
b1
])
elif
opcode
==
'
delete
'
:
deleted
.
append
(
diff
.
a
[
a0
:
a1
])
elif
opcode
==
'
replace
'
:
deleted
.
append
(
diff
.
a
[
a0
:
a1
])
added
.
append
(
diff
.
b
[
b0
:
b1
])
# Handle text not added to the output already
if
added
==
deleted
:
output
.
append
(
added
)
else
:
if
added
:
output
.
append
(
wrap_deleted
(
''
.
join
(
deleted
)))
if
deleted
:
output
.
append
(
wrap_added
(
''
.
join
(
added
)))
return
mark_safe
(
''
.
join
(
output
))
This diff is collapsed.
Click to expand it.
opentech/apply/funds/views.py
+
5
−
58
View file @
a0881832
from
difflib
import
SequenceMatcher
from
django.contrib.auth.decorators
import
login_required
from
django.contrib.auth.decorators
import
login_required
from
django.core.exceptions
import
PermissionDenied
from
django.core.exceptions
import
PermissionDenied
from
django.http
import
HttpResponseRedirect
from
django.http
import
HttpResponseRedirect
...
@@ -28,6 +26,7 @@ from opentech.apply.utils.views import DelegateableView, ViewDispatcher
...
@@ -28,6 +26,7 @@ from opentech.apply.utils.views import DelegateableView, ViewDispatcher
from
opentech.apply.users.models
import
User
from
opentech.apply.users.models
import
User
from
.blocks
import
MustIncludeFieldBlock
from
.blocks
import
MustIncludeFieldBlock
from
.differ
import
compare
from
.forms
import
ProgressSubmissionForm
,
UpdateReviewersForm
,
UpdateSubmissionLeadForm
from
.forms
import
ProgressSubmissionForm
,
UpdateReviewersForm
,
UpdateSubmissionLeadForm
from
.models
import
ApplicationSubmission
,
ApplicationRevision
from
.models
import
ApplicationSubmission
,
ApplicationRevision
from
.tables
import
AdminSubmissionsTable
,
SubmissionFilter
,
SubmissionFilterAndSearch
from
.tables
import
AdminSubmissionsTable
,
SubmissionFilter
,
SubmissionFilterAndSearch
...
@@ -266,65 +265,13 @@ class RevisionListView(ListView):
...
@@ -266,65 +265,13 @@ class RevisionListView(ListView):
class
RevisionCompareView
(
TemplateView
):
class
RevisionCompareView
(
TemplateView
):
template_name
=
'
funds/revisions_compare.html
'
template_name
=
'
funds/revisions_compare.html
'
def
wrap
(
self
,
class_name
,
text
):
def
compare_revisions
(
self
,
from_data
,
to_data
):
return
format_html
(
'
<span class=
"
{}
"
>{}</span>
'
,
class_name
,
mark_safe
(
text
))
def
deleted
(
self
,
text
):
return
self
.
wrap
(
'
deleted
'
,
text
)
def
added
(
self
,
text
):
return
self
.
wrap
(
'
added
'
,
text
)
def
compare_answer
(
self
,
answer_a
,
answer_b
):
if
not
answer_a
and
not
answer_b
:
# This catches the case where both results are None and we cant compare
return
answer_b
if
isinstance
(
answer_a
,
dict
)
or
isinstance
(
answer_b
,
dict
):
# TODO: handle file dictionaries
return
answer_b
diff
=
SequenceMatcher
(
None
,
answer_a
,
answer_b
)
output
=
[]
added
=
''
deleted
=
''
for
opcode
,
a0
,
a1
,
b0
,
b1
in
diff
.
get_opcodes
():
if
opcode
==
'
equal
'
:
if
a1
-
a0
>
2
or
not
(
added
or
deleted
):
if
added
:
output
.
append
(
self
.
added
(
added
))
added
=
''
if
deleted
:
output
.
append
(
self
.
deleted
(
deleted
))
deleted
=
''
output
.
append
(
diff
.
a
[
a0
:
a1
])
else
:
added
+=
diff
.
a
[
a0
:
a1
]
deleted
+=
diff
.
a
[
a0
:
a1
]
elif
opcode
==
'
insert
'
:
added
+=
diff
.
b
[
b0
:
b1
]
elif
opcode
==
'
delete
'
:
deleted
+=
diff
.
a
[
a0
:
a1
]
elif
opcode
==
'
replace
'
:
deleted
+=
diff
.
a
[
a0
:
a1
]
added
+=
diff
.
b
[
b0
:
b1
]
if
added
==
deleted
:
output
.
append
(
added
)
else
:
if
added
:
output
.
append
(
self
.
deleted
(
deleted
))
if
deleted
:
output
.
append
(
self
.
added
(
added
))
return
mark_safe
(
''
.
join
(
output
))
def
compare
(
self
,
from_data
,
to_data
):
diffed_form_data
=
{
diffed_form_data
=
{
field
:
self
.
compare
_answer
(
from_data
.
form_data
.
get
(
field
),
to_data
.
form_data
[
field
])
field
:
compare
(
from_data
.
form_data
.
get
(
field
),
to_data
.
form_data
[
field
])
for
field
in
to_data
.
form_data
for
field
in
to_data
.
form_data
}
}
diffed_answers
=
[
diffed_answers
=
[
self
.
compare
_answer
(
*
fields
)
compare
(
*
fields
,
should_bleach
=
False
)
for
fields
in
zip
(
from_data
.
fields
,
to_data
.
fields
)
for
fields
in
zip
(
from_data
.
fields
,
to_data
.
fields
)
]
]
to_data
.
form_data
=
diffed_form_data
to_data
.
form_data
=
diffed_form_data
...
@@ -334,7 +281,7 @@ class RevisionCompareView(TemplateView):
...
@@ -334,7 +281,7 @@ class RevisionCompareView(TemplateView):
def
get_context_data
(
self
,
**
kwargs
):
def
get_context_data
(
self
,
**
kwargs
):
from_revision
=
ApplicationSubmission
.
objects
.
get
(
id
=
self
.
kwargs
[
'
from
'
])
from_revision
=
ApplicationSubmission
.
objects
.
get
(
id
=
self
.
kwargs
[
'
from
'
])
to_revision
=
ApplicationSubmission
.
objects
.
get
(
id
=
self
.
kwargs
[
'
to
'
])
to_revision
=
ApplicationSubmission
.
objects
.
get
(
id
=
self
.
kwargs
[
'
to
'
])
diff
=
self
.
compare
(
from_revision
,
to_revision
)
diff
=
self
.
compare
_revisions
(
from_revision
,
to_revision
)
return
super
().
get_context_data
(
return
super
().
get_context_data
(
submission
=
ApplicationSubmission
.
objects
.
get
(
id
=
self
.
kwargs
[
'
submission_pk
'
]),
submission
=
ApplicationSubmission
.
objects
.
get
(
id
=
self
.
kwargs
[
'
submission_pk
'
]),
diff
=
diff
,
diff
=
diff
,
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment