Skip to content

Implement article model #30

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

Closed
wants to merge 16 commits into from
Closed
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
8 changes: 8 additions & 0 deletions .storybook/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module.exports = {
stories: ['../src/**/*.stories.js'],
addons: [
'@storybook/preset-create-react-app',
'@storybook/addon-actions',
'@storybook/addon-links',
],
};
2 changes: 2 additions & 0 deletions api/backend/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@
from ..backend.home.routes import home_bp
from ..backend.meta.routes import meta_bp
from ..backend.users.routes import user_bp
from ..backend.articles.routes import articles_bp

app.register_blueprint(authentication_bp)
app.register_blueprint(home_bp)
app.register_blueprint(meta_bp)
app.register_blueprint(user_bp)
app.register_blueprint(articles_bp)
53 changes: 53 additions & 0 deletions api/backend/articles/decorators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
from ..articles.schemas import article_form_schema
from functools import wraps
from flask import request
from ..models import Article


# Decorator to check if the article exists
def article_exists(f):
@wraps(f)
def wrap(*args, **kwargs):
article = Article.query.get(kwargs["article_id"])

if article:
return f(*args, **kwargs)
else:
return {
"message": "Article does not exist"
}, 404

return wrap


# Decorator to check if a article form data is valid
def valid_article_form(f):
@wraps(f)
def wrap(*args, **kwargs):
form_data = request.get_json()
errors = article_form_schema.validate(form_data)

# If form data is not validated by the article_form_schema, then return a 500 error
# else create the article and add it to the database
if errors:
return {
"message": "Missing or sending incorrect data to create a article. Double check the JSON data that it has everything needed to create a classroom."
}, 422
else:
return f(*args, **kwargs)

return wrap


# Decorator to check if the Article table has articles before printing upto 15 articles
def article_table_empty(f):
@wraps(f)
def wrap(*args, **kwargs):
if Article.query.first():
return f(*args, **kwargs)
else:
return {
"message": "No articles present"
}, 404

return wrap
67 changes: 67 additions & 0 deletions api/backend/articles/routes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
from .. import api, db
from ..articles.decorators import article_exists, valid_article_form, article_table_empty
from ..articles.utils import create_article, update_article
from ..articles.schemas import article_schema, articles_schema
from flask import Blueprint, request
from flask_restful import Resource
from ..models import Article

# Blueprint for articles
articles_bp = Blueprint("articles", __name__)


# Class to handle information regarding the Article model
class Articles(Resource):

# Function to create an article
@valid_article_form
def post(self):
form_data = request.get_json()
article = create_article(form_data)

db.session.add(article)
db.session.commit()

return {"message": "Successfully created Article"}, 201

# Function to display all the articles up to a limit of 15
@article_table_empty
def get(self):
article = Article.query.limit(15)
return articles_schema.dump(article, default=str)


class ArticleCRUD(Resource):

# Function to edit an article
@valid_article_form
@article_exists
def put(self, article_id):
article = Article.query.get(article_id)
form_data = request.get_json()
update_article(article, form_data)

db.session.commit()

return {"message": "Article successfully updated"}, 200

# Function to delete an article
@article_exists
def delete(self, article_id):
article = Article.query.get(article_id)

db.session.delete(article)
db.session.commit()

return {"message": "Article successfully deleted"}, 200

# Function to display an article
@article_exists
def get(self, article_id):
article = Article.query.get(article_id)

return article_schema.dump(article)

# Creates the routes for the classes
api.add_resource(Articles, "/api/articles")
api.add_resource(ArticleCRUD, "/api/articles/<int:article_id>")
26 changes: 26 additions & 0 deletions api/backend/articles/schemas.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from marshmallow import Schema, fields
import toastedmarshmallow

# This schema is used to display article data
class ArticleFormSchema(Schema):
title = fields.Str(required=True)
cover_image = fields.Str(required=False)
content = fields.Str(required=False)


# This schema is used to display article data
class ArticleSchema(Schema):
id = fields.Int(required=True)

class Meta:
# Fields to show when sending data
fields = ("id",)
ordered = True


article_form_schema = ArticleFormSchema()
article_schema = ArticleSchema()
articles_schema = ArticleSchema(many=True)
article_form_schema.jit = toastedmarshmallow.Jit
article_schema.jit = toastedmarshmallow.Jit
articles_schema.jit = toastedmarshmallow.Jit
20 changes: 20 additions & 0 deletions api/backend/articles/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from ..models import Article


# Function to create an article
def create_article(form_data):
article = Article(title=form_data["title"],
cover_image=form_data["cover_image"],
content=form_data["content"]
)

return article


# Function to update an article
def update_article(article, form_data):
article.title = form_data["title"]
article.cover_image = form_data["cover_image"]
article.content = form_data["content"]

return
14 changes: 14 additions & 0 deletions api/backend/models.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from api.backend import db
import datetime


class Meta(db.Model):
Expand Down Expand Up @@ -54,3 +55,16 @@ class Teacher(db.Model):

def __repr__(self):
return f"Teacher('{self.id}')"


class Article(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.Text, nullable=False)
cover_image = db.Column(db.Text, nullable=True)
content = db.Column(db.Text, nullable=False)
date_published = db.Column(db.DateTime, nullable=False, default=datetime.date.today)
likes = db.Column(db.Integer, nullable=False, default=0)
is_published = db.Column(db.Boolean, nullable=False, default=True)

def __repr__(self):
return f"Article('{self.id}')"
36 changes: 36 additions & 0 deletions meetings/one-on-ones/5-12-20-Anurag-onboarding.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Meeting Purpose
Weekly meeting

**Lead**
Bryan

**Attendees**
* Anurag

## Updates:
*What has been completed and can be checked off*

*

## Discussion Points:
*Ideas, feedback, concerns, plans*
* Understand the overview of the onboarding procedure
* Breakdown of tasks and expectations for the first week
* Understand what Engineering team does
Practice taking notes on Github during the 1:1
* Please give your overview feedback and express what position you are within the Engineering team!
* Give onboarding feedback
*

## Action Plan:
*Where to go next, dependencies, all deadlines*
*Bryan will talk to the People team to improve the onboarding process and have them delve more into what BitProject actually represents as an organization.
*Watch the remaining webinars and close this issue.

## Deliverables:
*Within the next (timeframe)*
*Anurag will watch the webinars by Thursday and finish the onboarding checklist.

Name | Assigned To | Deadline | Notes
------|-------------|----------|------
Name | @ | May 20th | Explanation
34 changes: 34 additions & 0 deletions meetings/one-on-ones/5-13-20-Jason-onboarding.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Meeting Purpose

**Lead**
Bryan Wong

**Attendees**
* Zexing(Jason) Fang

## Updates:
*What has been completed and can be checked off*

* Jason is almost done with onboarding checklist

## Discussion Points:
*Ideas, feedback, concerns, plans*
* Understand the overview of the onboarding procedure
* Breakdown of tasks and expectations for the first week
* Understand what Engineering team does
* Practice taking notes on Github during the 1:1
* Please give your overview feedback and express what position you are interested within the Engineering team!
* Give onboarding feedback
* Clear up the onboarding issue


## Action Plan:
*Where to go next, dependencies, all deadlines*
* None. Jason finished his onboarding checklist!

## Deliverables:
*Within the next (timeframe)*

Name | Assigned To | Deadline | Notes
------|-------------|----------|------
Example 1 | @studentusername2 | Feb 30th | Explanation
13 changes: 11 additions & 2 deletions meetings/weekly/frontend/5-11-20.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ Bryan
* Alex
* Tom

**Video Link**
https://ucdavis.zoom.us/rec/share/5uBtLOnM93JLe8_J4Wfaeb4zO9jYeaa80HQcrPEPmB1VRx1WiBf18WdHLAjTfhvv

## Updates:
*What has been completed and can be checked off*

Expand All @@ -30,11 +33,17 @@ Bryan

## Action Plan:
*Where to go next, dependencies, all deadlines*
* Plan1
* Mark will work on the Explore page
* Jason will work on User Dashboard
* Yuan will work on the Home page

## Deliverables:
*Within the next (timeframe)*

Name | Assigned To | Deadline | Notes
------|-------------|----------|------
Example 1 | @studentusername2 | Feb 30th | Explanation
Mark | @mzp0625 | May 20th | Integrate the explore page
Jason | @JersinFong | May 20th | Integrate the User Dashboard page
Yuan | @VelForce | May 20th | Integrate the Home page
Ayush | @ayushbha | May 20th | Integrate the Markdown Editor
Aishwarya | @aishwarya-mustoori | May 20th | Integrate Article viewer page
Loading