IEEE.org     |     IEEE Xplore Digital Library     |     IEEE Standards     |     IEEE Spectrum     |     More Sites

Verified Commit 01c3ef6d authored by Emi Simpson's avatar Emi Simpson
Browse files

[new arch] Sprinkle in a healthy helping of comments to long expressions

parent a379d6d2
Pipeline #897 passed with stage
in 54 seconds
......@@ -74,24 +74,31 @@ def add_source(req: Request, pid: UncheckedPID, user: UserID) -> Outcomes | Quer
Use with :meth:`auth_action()`
"""
try:
# Check for the arguments in the form
source_type = req.form['source_type'].strip()
source_url = req.form['source_url'].strip()
# Error if zero-length
if len(source_url) == 0:
return (outcome.Error(
ProjectField(pid, ProjectFieldKind.AddSource),
"Make sure you include a URL for your data source"),)
else:
try:
# Identify which processor corresponds to this type of source
source_processor = SOURCE_PROCESSORS[source_type]
except KeyError:
# And throw a fit if this source doesn't exist
return (outcome.Error(
ProjectField(pid, ProjectFieldKind.AddSource),
"Invalid source type specified"),)
except KeyError:
# If the form didn't have all the necessary arguments, be sad about it
return (outcome.Error(
ProjectField(pid, ProjectFieldKind.AddSource),
"Missing parameter, make sure both 'type' and 'url' are specified"),)
# Validate that the source is shaped right
source = source_processor(-1, Project(pid), source_type, source_url, False)
validation_error = source.validate_source()
if validation_error is not None:
......@@ -100,23 +107,31 @@ def add_source(req: Request, pid: UncheckedPID, user: UserID) -> Outcomes | Quer
validation_error
),)
# Then actually start building the query
return queries.BoundQuery(
validate_and_fetch_pid(pid, user),
lambda project: queries.MappedQuery(
validate_and_fetch_pid(pid, user), # first we check that the user has permissions
lambda project: queries.MappedQuery( # if so...
# add a source to the project
queries.AddSourceToProject(project.project_id, source_type, source_url),
lambda source_id: \
# then rebuild the projects.json file
[outcome.RebuildProjectsJson()
# and submit a new job for scanning this specific source
,outcome.SubmitCoordinatorJob(
[compute_alphaid(pid), f's-{source_id}'],
f'Scan {source.display_name()} {source.get_simplified_form()}',
20,
_fold_sources(source.expand_source()))]
_fold_sources(source.expand_source()))] # (plus all its variants)
if project.draft_owner is None else
[],
# if there was a problem adding the source, turn it into an error
lambda e: ({
# this shouldn't be possible, because we validated that the project
# existed in the last step
queries.AddSourceError.NonexistantProject: outcome.Error(
ProjectField(pid, ProjectFieldKind.Generic),
"[INTERNAL ERROR] This project does not exist"),
# the data source has already been added
queries.AddSourceError.SourceAlreadyPresent: outcome.Error(
ProjectField(pid, ProjectFieldKind.AddSource),
"This data source has already been added to this project"),
......@@ -129,22 +144,30 @@ def add_owner(req: Request, pid: UncheckedPID, user: UserID) -> Outcomes | Query
Takes the form field `new_owner`
Use with :meth:`auth_action()`
"""
# if the new owner isn't specified
if 'new_owner' not in req.form or req.form['new_owner'] is None or len(req.form['new_owner']) == 0:
# pout if so
return (outcome.Error(
ProjectField(pid, ProjectFieldKind.AddOwner),
"Please specify an owner to add"),)
# start building the query
return queries.BoundQuery(
validate_pid(pid, user),
validate_pid(pid, user), # first validate that the user owns this project
lambda project_id: queries.MappedQuery(
# then add the new owner
queries.AddOwnerByUsername(req.form['new_owner'], project_id),
lambda _: tuple(),
lambda error: ({
lambda _: tuple(), # nothing needs to happen if we succeed
lambda error: ({ # if we fail, pick decipher the error by picking 1
# This shouldn't be possible, since we validated the project already
queries.AddOwnerError.NonexistantProject: outcome.Error(
ProjectField(project_id, ProjectFieldKind.AddOwner),
"[INTERNAL ERROR] This project does not exist"),
# The user tried to add an owner who already owned the project
queries.AddOwnerError.DuplicateOwner: outcome.Error(
ProjectField(project_id, ProjectFieldKind.AddOwner),
"This user is already an owner of this project"),
# The username the user entered does not exist
queries.AddOwnerError.UsernameDNE: outcome.Error(
ProjectField(project_id, ProjectFieldKind.AddOwner),
"This user does not exist or hasn't logged in yet"),
......@@ -159,13 +182,17 @@ def edit_properties(req: Request, pid: UncheckedPID, user: UserID) -> Outcomes |
Use with :meth:`auth_action()`
"""
try:
# pull out the required fields
name = req.form['name'].strip()
desc = req.form['desc'].strip()
slug = req.form['slug'].strip()
except KeyError:
# and error if any aren't provided
return (outcome.Error(
GenericAlert(),
'Editing properties requires that the "name", "desc", and "slug" arguments are set'),)
# Create an error for each field that's empty, but don't return them yet
missing_fields: Collection[Outcome] = [
outcome.Error(ProjectField(pid, field), msg)
for (field, value, msg)
......@@ -174,26 +201,42 @@ def edit_properties(req: Request, pid: UncheckedPID, user: UserID) -> Outcomes |
(ProjectFieldKind.Description, desc, "Tell us a little bit about your project"),
(ProjectFieldKind.Slug, slug, "Pick a short and sweet name to use in URLs"),)
if len(value) == 0 ]
return queries.BoundQuery(
validate_and_fetch_pid(pid, user),
validate_and_fetch_pid(pid, user), # Check that the user owns the project
lambda project_info: queries.BoundQuery(
# if so...
queries.MappedQuery(
# Update the project's properties with the new values
queries.UpdateProjectProperties(
project_info.project_id,
*[f if len(f) > 0 else None for f in (slug, name, desc)]),
# If that succeeds, check whether or not the project was a draft that is
# now finalized
lambda is_final: is_final and project_info.draft_owner is not None,
# If there was an error, decode it
lambda error: {
# We already checked that the project exists, so this just means no
# change happened. We can report the errors for missing fields and
# nothing else
queries.UpdateProjectError.NonexistantProjectOrNoChange: missing_fields,
# If the slug entered was already taken, let the user know, along with
# any fields they left empty
queries.UpdateProjectError.DuplicateSlug: [outcome.Error(
ProjectField(pid, ProjectFieldKind.Slug),
"It looks like this URL is already taken!"
)] + missing_fields,
}[error]),
lambda needs_rescan:
# If updating the project properties succeeded, do one of two things:
# If the project was a draft that was just finalized, we need to scan it
queries.MappedQuery(
# So get a list of the project's sources
queries.GetSources(project_info.project_id),
lambda sources: (
# rebuild the projects.json
outcome.RebuildProjectsJson(),
# and then request that all those sources be rebuilt
outcome.SubmitCoordinatorJob(
[f's-{source.origin_id:x}' for source in sources] + \
[compute_alphaid(project_info.project_id)],
......@@ -203,8 +246,10 @@ def edit_properties(req: Request, pid: UncheckedPID, user: UserID) -> Outcomes |
e_source
for source in sources
for e_source in source.expand_source()]))),
lambda noreturn: noreturn)
lambda noreturn: noreturn) # impossible
if needs_rescan else
# If the project wasn't just finalized, we don't need to do anything but
# report the missing fields
queries.Noop(missing_fields)))
def remove_owner(req: Request, pid: UncheckedPID, user: UserID) -> Outcomes | Query[Outcomes, Outcomes]:
......@@ -215,16 +260,22 @@ def remove_owner(req: Request, pid: UncheckedPID, user: UserID) -> Outcomes | Qu
Use with :meth:`auth_action()`
"""
try:
# Try to sus out the user's ID from the form
owner = UserID(parse_alphaid(req.form['user']))
except KeyError:
# The form doesn't even have the key
return (outcome.Error(GenericAlert(), "Please include the 'user' field"),)
except MalformedId as e:
# The form had a user listed, but their ID was malformed
return (outcome.Error(GenericAlert(), str(e)),)
return queries.BoundQuery(validate_pid(pid, user),
# If the ID was retrieved successfully, start describing the query
return queries.BoundQuery(validate_pid(pid, user), # check the user owns this project
lambda pid: queries.MappedQuery(
# if so, remove the attached owner
queries.RemoveOwner(pid, owner),
lambda _: tuple(),
lambda _: tuple(), # if it succeeded, nothing else needs to happen
lambda _: (outcome.Error(
# otherwise, this indicates that the mentioned account isn't an owner
ProjectField(pid, ProjectFieldKind.Generic),
"That user is not an owner of this project"),)))
......@@ -234,10 +285,11 @@ def delete_project(_: Request, pid: UncheckedPID, user: UserID) -> Outcomes | Qu
Use with :meth:`auth_action()`
"""
return queries.BoundQuery(validate_pid(pid, user),
return queries.BoundQuery(validate_pid(pid, user), # validate ownership
lambda pid: queries.MappedQuery(
queries.DeleteProject(pid),
lambda _: tuple(),
queries.DeleteProject(pid), # try to delete the project
lambda _: tuple(), # success - nothing needs to change
# error - should be impossible due to the above validation
lambda _: (outcome.Error(ProjectField(pid, ProjectFieldKind.Generic),
"[INTERNAL ERROR] This project does not exist"),)))
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment