Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Renamed all references of paid to free #379

Merged
merged 8 commits into from
Oct 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ run: build
run_windows: build
@cmd /c (IF NOT "$(shell ${DOCKER} ps -q -f name=resources-api)" == "" ${DOCKER_COMPOSE} down)
${DOCKER_COMPOSE} run -p 5000:5000 ${RESOURCES_CONTAINER} ${FLASK} run -h 0.0.0.0


.PHONY: bg
bg:
Expand Down
4 changes: 2 additions & 2 deletions app/api/routes/resource_creation.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@ def create_resources(json, db):
# Create each Resource in the database one by one
for resource in json:
langs, categ = get_attributes(resource)
paid_bool = ensure_bool(resource.get('paid'))
free_bool = ensure_bool(resource.get('free'))
new_resource = Resource(
name=resource.get('name'),
url=resource.get('url'),
category=categ,
languages=langs,
paid=paid_bool,
free=free_bool,
notes=resource.get('notes'))

try:
Expand Down
8 changes: 4 additions & 4 deletions app/api/routes/resource_modification.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,10 @@ def update_resource(id, json, db):
if json.get('url'):
resource.url = json.get('url')
index_object['url'] = json.get('url')
if 'paid' in json:
paid = ensure_bool(json.get('paid'))
resource.paid = paid
index_object['paid'] = paid
if 'free' in json:
free = ensure_bool(json.get('free'))
resource.free = free
index_object['free'] = free
if 'notes' in json:
resource.notes = json.get('notes')
index_object['notes'] = json.get('notes')
Expand Down
12 changes: 6 additions & 6 deletions app/api/routes/resource_retrieval.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def get_resources():
languages = request.args.getlist('languages')
category = request.args.get('category')
updated_after = request.args.get('updated_after')
paid = request.args.get('paid')
free = request.args.get('free')

q = Resource.query

Expand Down Expand Up @@ -81,13 +81,13 @@ def get_resources():
)
)

# Filter on paid
if isinstance(paid, str) and paid.lower() in ['true', 'false']:
paidAsBool = paid.lower() == 'true'
q = q.filter(Resource.paid == paidAsBool)
# Filter on free
if isinstance(free, str) and free.lower() in ['true', 'false']:
freeAsBool = free.lower() == 'true'
q = q.filter(Resource.free == freeAsBool)

# Order by "getting started" category
if not languages and not category and paid is None:
if not languages and not category and free is None:
show_first = Category.query.filter(Category.name == "Getting Started").first()
clause = (
f" CASE resource.category_id"
Expand Down
16 changes: 8 additions & 8 deletions app/api/routes/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,19 @@ def search_results():
page_size = request.args.get('page_size', Config.RESOURCE_PAGINATOR.per_page, int)

# Fetch the filter params from the url, if they were provided.
paid = request.args.get('paid')
free = request.args.get('free')
category = request.args.get('category')
languages = request.args.getlist('languages')
filters = []

# Filter on paid
if paid:
paid = paid.lower()
# Filter on free
if free:
free = free.lower()
# algolia filters boolean attributes with either 0 or 1
if paid == 'true':
filters.append('paid=1')
elif paid == 'false':
filters.append('paid=0')
if free == 'true':
filters.append('free=1')
elif free == 'false':
filters.append('free=0')

# Filter on category
if category:
Expand Down
4 changes: 2 additions & 2 deletions app/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ def create_resource(resource, db): # pragma: no cover
url=resource['url'],
category=resource['category'],
languages=resource['languages'],
paid=resource.get('paid'),
free=resource.get('free'),
notes=resource.get('notes', ''),
upvotes=resource.get('upvotes', 0),
downvotes=resource.get('downvotes', 0),
Expand All @@ -126,7 +126,7 @@ def update_resource(resource, existing_resource): # pragma: no cover
existing_resource.name = resource['name']
existing_resource.url = resource['url']
existing_resource.category = resource['category']
existing_resource.paid = resource.get('paid')
existing_resource.free = resource.get('free')
existing_resource.notes = resource.get('notes', '')
existing_resource.languages = resource['languages']

Expand Down
6 changes: 3 additions & 3 deletions app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class Resource(TimestampMixin, db.Model):
nullable=False)
category = db.relationship('Category')
languages = db.relationship('Language', secondary=language_identifier)
paid = db.Column(db.Boolean, nullable=False, default=False)
free = db.Column(db.Boolean, nullable=False, default=True)
notes = db.Column(db.String)
upvotes = db.Column(db.INTEGER, default=0)
downvotes = db.Column(db.INTEGER, default=0)
Expand All @@ -54,7 +54,7 @@ def serialize(self):
'url': self.url,
'category': self.category.name,
'languages': self.serialize_languages,
'paid': self.paid,
'free': self.free,
'notes': self.notes,
'upvotes': self.upvotes,
'downvotes': self.downvotes,
Expand Down Expand Up @@ -84,7 +84,7 @@ def __eq__(self, other):
for attribute in [
"name",
"url",
"paid",
"free",
"notes",
"category",
"languages",
Expand Down
46 changes: 23 additions & 23 deletions app/static/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,9 @@ paths:
type: string
required: true
- in: query
name: paid
name: free
required: false
description: Whether the resource is paid or not. To search for *free* resources, make a `GET` request to `/search?paid=false`.
description: Whether the resource is free or not. To search for *free* resources, make a `GET` request to `/search?free=true`.
schema:
type: boolean
- in: query
Expand Down Expand Up @@ -152,7 +152,7 @@ paths:
last_updated: '2019-05-25 18:52:15'
name: 'C Tutorial'
notes: 'Learn C with our popular C tutorial, which will take you from the very basics of C all the way through sophisticated topics like binary trees and data structures.'
paid: false
free: true
times_clicked: 0
upvotes: 0
url: 'https://www.cprogramming.com/tutorial/c-tutorial.html'
Expand Down Expand Up @@ -394,7 +394,7 @@ paths:
last_updated: '2019-06-15 17:55:32'
name: 'Free Tech Books'
notes: 'Focuses on general computer science concepts rather than a specific language'
paid: false
free: true
times_clicked: 0
upvotes: 0
url: 'http://www.freetechbooks.com/'
Expand Down Expand Up @@ -443,7 +443,7 @@ paths:
last_updated: '2019-07-22 16:05:53'
name: 'Updated Book Title'
notes: null
paid: false
free: true
times_clicked: 3
upvotes: 1
url: 'http://www.test.com'
Expand Down Expand Up @@ -506,7 +506,7 @@ paths:
last_updated: '2019-07-26 13:47:52'
name: 'Thinking Forth'
notes: null
paid: false
free: true
times_clicked: 2
upvotes: 0
url: 'http://thinking-forth.sourceforge.net/'
Expand Down Expand Up @@ -550,7 +550,7 @@ paths:
last_updated: '2020-03-12 23:17:52'
name: 'Teach Your Kids to Code'
notes: null
paid: true
free: false
times_clicked: 0
upvotes: 1
url: 'http://teachyourkidstocode.com/'
Expand Down Expand Up @@ -594,7 +594,7 @@ paths:
last_updated: '2020-03-12 23:17:52'
name: 'Teach Your Kids to Code'
notes: null
paid: true
free: false
times_clicked: 0
upvotes: 0
url: 'http://teachyourkidstocode.com/'
Expand All @@ -611,9 +611,9 @@ paths:
- List Resources
parameters:
- in: query
name: paid
name: free
required: false
description: Whether the resource is paid or not. To search for *free* resources, make a `GET` request to `/resources?paid=false`.
description: Whether the resource is free or not. To search for *free* resources, make a `GET` request to `/resources?free=true`.
schema:
type: boolean
- in: query
Expand Down Expand Up @@ -654,7 +654,7 @@ paths:
last_updated: '2019-07-22 17:39:50'
name: 'Some, but not ALL of the knowledge'
notes: null
paid: false
free: true
times_clicked: 3
upvotes: 1
url: 'http://www.test.com'
Expand Down Expand Up @@ -685,7 +685,7 @@ paths:

post:
summary: Create Resources
description: Creates new learning resources. The structure of the request is a list of resource objects. The required properties for each new resource are `category`, `name`, `paid`, and `url`.
description: Creates new learning resources. The structure of the request is a list of resource objects. The required properties for each new resource are `category`, `name`, `free`, and `url`.
tags:
- Create Resources
requestBody:
Expand All @@ -696,7 +696,7 @@ paths:
example:
- category: 'Tutorial'
name: 'CSS Tutorial'
paid: false
free: true
url: 'https://www.w3schools.com/css/'
required: true
responses:
Expand All @@ -718,7 +718,7 @@ paths:
last_updated: '2019-07-22 16:05:53'
name: 'CSS Tutorial'
notes: null
paid: false
free: true
times_clicked: 3
upvotes: 1
url: 'https://www.w3schools.com/css/'
Expand All @@ -744,11 +744,11 @@ paths:
- url
resource: 'https://resources.operationcode.org/api/v1/2137'
missing-params:
message: 'The following params were missing: name, category, paid.'
message: 'The following params were missing: name, category, free.'
params:
- name
- category
- paid
- free
status: 'Unprocessable Entity'
status_code: 422
security:
Expand Down Expand Up @@ -984,7 +984,7 @@ components:
CreateResourcesRequest:
allOf:
- $ref: '#/components/schemas/ResourcesRequest'
# - required: [category, name, paid, url]
# - required: [category, name, free, url]

ResourcesRequest:
type: array
Expand All @@ -1005,9 +1005,9 @@ components:
notes:
type: string
description: Resource notes
paid:
free:
type: boolean
description: True or false for whether resource is paid
description: True or false for whether resource is free
url:
type: string
description: Resource url
Expand All @@ -1028,9 +1028,9 @@ components:
notes:
type: string
description: Resource notes
paid:
free:
type: boolean
description: True or false for whether resource is paid
description: True or false for whether resource is free
url:
type: string
description: Resource url
Expand Down Expand Up @@ -1066,9 +1066,9 @@ components:
notes:
type: string
description: Resource notes
paid:
free:
type: boolean
description: True or false for whether resource is paid
description: True or false for whether resource is free
upvotes:
type: integer
description: Positive ratings
Expand Down
2 changes: 1 addition & 1 deletion app/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def format_resource_search(hit):
'url': hit['url'],
'category': hit['category'],
'languages': hit['languages'],
'paid': hit['paid'],
'free': hit['free'],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh snap, I forgot, this change is going to require us to do something about Algolia... I wonder if re-indexing will be enough? Anyway, nothing for you to do here, just wanted to make a note for myself that once we merge this and deploy we'll have to fix that

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I totally called it, seeing this in production

[2020-10-21 15:34:32,534] ERROR in app: Exception on /api/v1/search/ [GET]
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 2447, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1952, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1821, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1950, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1936, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "./app/api/routes/search.py", line 14, in search
    return search_results()
  File "./app/api/routes/search.py", line 72, in search_results
    results = [utils.format_resource_search(result) for result in search_result['hits']]
  File "./app/api/routes/search.py", line 72, in <listcomp>
    results = [utils.format_resource_search(result) for result in search_result['hits']]
  File "./app/utils.py", line 70, in format_resource_search
    'free': hit['free'],
KeyError: 'free'

I'm not sure exactly what to do to fix it... I assume reindex everything in algolia, but I'm not sure which commands to run to get there

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure as well about this as I have no experience in it but I think this could be the solution/related? https://www.algolia.com/doc/api-reference/api-methods/move-index/?language=python

'notes': hit['notes'],
'upvotes': hit['upvotes'],
'downvotes': hit['downvotes'],
Expand Down
29 changes: 29 additions & 0 deletions migrations/versions/fc34137ad3ba_.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"""Rename paid column to free

Revision ID: fc34137ad3ba
Revises: 205742d3b3f5
Create Date: 2020-09-30 22:35:20.007768

"""
from alembic import op
import sqlalchemy as sa
import sqlalchemy_utils


# revision identifiers, used by Alembic.
revision = 'fc34137ad3ba'
down_revision = '205742d3b3f5'
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column('resource', 'paid', new_column_name='free', existing_type=sa.Boolean, nullable=False)
aaron-junot marked this conversation as resolved.
Show resolved Hide resolved
# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column('resource', 'free', new_column_name='paid', existing_type=sa.Boolean, nullable=True)
# ### end Alembic commands ###
Loading