1
0
Fork 0
This commit is contained in:
Ava Gaiety Wroten 2019-12-24 13:48:22 -06:00
parent a03953a0ab
commit 84a1e7d972
71 changed files with 22530 additions and 0 deletions

View file

1
python-api/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/__pycache__

View file

@ -0,0 +1,112 @@
# The default ``config.py``
# flake8: noqa
def set_prefs(prefs):
"""This function is called before opening the project"""
# Specify which files and folders to ignore in the project.
# Changes to ignored resources are not added to the history and
# VCSs. Also they are not returned in `Project.get_files()`.
# Note that ``?`` and ``*`` match all characters but slashes.
# '*.pyc': matches 'test.pyc' and 'pkg/test.pyc'
# 'mod*.pyc': matches 'test/mod1.pyc' but not 'mod/1.pyc'
# '.svn': matches 'pkg/.svn' and all of its children
# 'build/*.o': matches 'build/lib.o' but not 'build/sub/lib.o'
# 'build//*.o': matches 'build/lib.o' and 'build/sub/lib.o'
prefs['ignored_resources'] = ['*.pyc', '*~', '.ropeproject',
'.hg', '.svn', '_svn', '.git', '.tox']
# Specifies which files should be considered python files. It is
# useful when you have scripts inside your project. Only files
# ending with ``.py`` are considered to be python files by
# default.
#prefs['python_files'] = ['*.py']
# Custom source folders: By default rope searches the project
# for finding source folders (folders that should be searched
# for finding modules). You can add paths to that list. Note
# that rope guesses project source folders correctly most of the
# time; use this if you have any problems.
# The folders should be relative to project root and use '/' for
# separating folders regardless of the platform rope is running on.
# 'src/my_source_folder' for instance.
#prefs.add('source_folders', 'src')
# You can extend python path for looking up modules
#prefs.add('python_path', '~/python/')
# Should rope save object information or not.
prefs['save_objectdb'] = True
prefs['compress_objectdb'] = False
# If `True`, rope analyzes each module when it is being saved.
prefs['automatic_soa'] = True
# The depth of calls to follow in static object analysis
prefs['soa_followed_calls'] = 0
# If `False` when running modules or unit tests "dynamic object
# analysis" is turned off. This makes them much faster.
prefs['perform_doa'] = True
# Rope can check the validity of its object DB when running.
prefs['validate_objectdb'] = True
# How many undos to hold?
prefs['max_history_items'] = 32
# Shows whether to save history across sessions.
prefs['save_history'] = True
prefs['compress_history'] = False
# Set the number spaces used for indenting. According to
# :PEP:`8`, it is best to use 4 spaces. Since most of rope's
# unit-tests use 4 spaces it is more reliable, too.
prefs['indent_size'] = 4
# Builtin and c-extension modules that are allowed to be imported
# and inspected by rope.
prefs['extension_modules'] = []
# Add all standard c-extensions to extension_modules list.
prefs['import_dynload_stdmods'] = True
# If `True` modules with syntax errors are considered to be empty.
# The default value is `False`; When `False` syntax errors raise
# `rope.base.exceptions.ModuleSyntaxError` exception.
prefs['ignore_syntax_errors'] = False
# If `True`, rope ignores unresolvable imports. Otherwise, they
# appear in the importing namespace.
prefs['ignore_bad_imports'] = False
# If `True`, rope will insert new module imports as
# `from <package> import <module>` by default.
prefs['prefer_module_from_imports'] = False
# If `True`, rope will transform a comma list of imports into
# multiple separate import statements when organizing
# imports.
prefs['split_imports'] = False
# If `True`, rope will remove all top-level import statements and
# reinsert them at the top of the module when making changes.
prefs['pull_imports_to_top'] = True
# If `True`, rope will sort imports alphabetically by module name instead of
# alphabetically by import statement, with from imports after normal
# imports.
prefs['sort_imports_alphabetically'] = False
# Location of implementation of rope.base.oi.type_hinting.interfaces.ITypeHintingFactory
# In general case, you don't have to change this value, unless you're an rope expert.
# Change this value to inject you own implementations of interfaces
# listed in module rope.base.oi.type_hinting.providers.interfaces
# For example, you can add you own providers for Django Models, or disable the search
# type-hinting in a class hierarchy, etc.
prefs['type_hinting_factory'] = 'rope.base.oi.type_hinting.factory.default_type_hinting_factory'
def project_opened(project):
"""This function is called after opening the project"""
# Do whatever you like here!

Binary file not shown.

Binary file not shown.

Binary file not shown.

13
python-api/README.md Normal file
View file

@ -0,0 +1,13 @@
# Python Backend for Sortable Recipes (EmberConf 2020)
## Getting Started
```bash
pip3 install requests gunicorn pycnic
gunicorn api:app
```
### Available Endpoints:
`http://localhost:8000/meals/random`
`http://localhost:8000/meal/{meal_id}`

Binary file not shown.

Binary file not shown.

71
python-api/api.py Normal file
View file

@ -0,0 +1,71 @@
from pycnic.core import WSGI, Handler
from key_replacer import KeyReplacer
import requests
import json
class Base(Handler):
hostname = "https://www.themealdb.com/api/json/v1/1/"
def __init__(self):
self.replacable_keys = KeyReplacer(
[
["idMeal", "id"],
["strMeal", "name"],
["strCategory", "category"],
["strArea", "area"],
["strInstructions", "instructions"],
["strDrinkAlternate", "alternate_drink"],
["strMealThumb", "thumbnail_url"],
["strTags", "tags"],
["strYoutube", "youtube_url"],
["strSource", "source_url"],
["dateModified", "date_modified"],
])
def cleanup(self, meal):
self.replacable_keys.do_replace(meal)
self.cleanup_ingredients(meal)
def cleanup_ingredients(self, meal):
potential_length = 20
true_length = 0
# Cleanup Empty Values
for i in reversed(range(potential_length)):
x = str(i + 1)
if (meal["strIngredient" + x] == ''):
true_length = i
del meal["strIngredient" + x]
del meal["strMeasure" + x]
# Convert Ingredients/Measures to Array of Objects
meal["ingredients"] = [0]*true_length
for i in range(0, true_length):
x = str(i + 1)
meal["ingredients"][i] = {
"name": meal["strIngredient" + x],
"measure": meal["strMeasure" + x],
}
del meal["strIngredient" + x]
del meal["strMeasure" + x]
class Details(Base):
def get(self, meal_id = ''):
response = json.loads(requests.get(self.hostname + "lookup.php?i=" + meal_id).text)
for meal in response["meals"]:
self.cleanup(meal)
return json.dumps(response)
class Random(Base):
def get(self):
response = json.loads(requests.get(self.hostname + "random.php").text)
for meal in response["meals"]:
self.cleanup(meal)
return json.dumps(response)
class app(WSGI):
routes = [
("/meals/random", Random()),
("/meal/([\w]+)", Details())
]

22318
python-api/get-pip.py Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,15 @@
class KeyReplacer():
def __init__(self, replacements = []):
self.replacements = self._build_replacements(replacements)
def _build_replacements(self, replacements):
return list(map(lambda r: { "old": r[0], "new": r[1] }, replacements))
def _rename(self, obj, old_key, new_key):
obj[new_key] = obj[old_key]
del obj[old_key]
def do_replace(self, obj):
for replacement in self.replacements:
self._rename(obj, replacement["old"], replacement["new"])