├── .bumpversion.cfg ├── .gitignore ├── .travis.yml ├── AUTHORS.rst ├── CONTRIBUTING.md ├── LICENSE.rst ├── README.md ├── dev-requirements.txt ├── requirements.txt ├── robot_rest ├── __init__.py ├── requirements.txt ├── robot_rest.py ├── settings │ ├── __init__.tpl │ ├── defaults.tpl │ ├── dev.tpl │ ├── production.tpl │ └── tests.tpl ├── tests │ ├── __init__.tpl │ ├── settingstest.tpl │ └── test_rest_api.tpl └── urls.tpl ├── setup.cfg ├── setup.py ├── tests ├── __init__.py ├── settings.py └── test_robot.py └── tox.ini /.bumpversion.cfg: -------------------------------------------------------------------------------- 1 | [bumpversion] 2 | current_version = 0.5.4 3 | commit = True 4 | tag = True 5 | 6 | [bumpversion:file:robot_rest/__init__.py] -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.gitignore.io/api/python,pycharm 2 | 3 | ### Python ### 4 | # Byte-compiled / optimized / DLL files 5 | __pycache__/ 6 | *.py[cod] 7 | *$py.class 8 | 9 | # C extensions 10 | *.so 11 | 12 | # Distribution / packaging 13 | .Python 14 | env/ 15 | build/ 16 | develop-eggs/ 17 | dist/ 18 | downloads/ 19 | eggs/ 20 | .eggs/ 21 | lib/ 22 | lib64/ 23 | parts/ 24 | sdist/ 25 | var/ 26 | *.egg-info/ 27 | .installed.cfg 28 | *.egg 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *,cover 49 | 50 | # Translations 51 | *.mo 52 | *.pot 53 | 54 | # Django stuff: 55 | *.log 56 | 57 | # Sphinx documentation 58 | docs/build/ 59 | 60 | # PyBuilder 61 | target/ 62 | 63 | 64 | ### PyCharm ### 65 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio 66 | 67 | *.iml 68 | 69 | ## Directory-based project format: 70 | .idea/ 71 | .DS* 72 | # if you remove the above rule, at least ignore the following: 73 | 74 | # User-specific stuff: 75 | # .idea/workspace.xml 76 | # .idea/tasks.xml 77 | # .idea/dictionaries 78 | 79 | # Sensitive or high-churn files: 80 | # .idea/dataSources.ids 81 | # .idea/dataSources.xml 82 | # .idea/sqlDataSources.xml 83 | # .idea/dynamic.xml 84 | # .idea/uiDesigner.xml 85 | 86 | # Gradle: 87 | # .idea/gradle.xml 88 | # .idea/libraries 89 | 90 | # Mongo Explorer plugin: 91 | # .idea/mongoSettings.xml 92 | 93 | ## File-based project format: 94 | *.ipr 95 | *.iws 96 | 97 | ## Plugin-specific files: 98 | 99 | # IntelliJ 100 | /out/ 101 | 102 | # mpeltonen/sbt-idea plugin 103 | .idea_modules/ 104 | 105 | # JIRA plugin 106 | atlassian-ide-plugin.xml 107 | 108 | # Crashlytics plugin (for Android Studio and IntelliJ) 109 | com_crashlytics_export_strings.xml 110 | crashlytics.properties 111 | crashlytics-build.properties 112 | 113 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | 3 | python: 4 | - '3.4' 5 | - '2.7' 6 | - pypy 7 | 8 | env: 9 | - $DJANGO='django<1.9' 10 | 11 | sudo: false 12 | 13 | install: 14 | - pip install $DJANGO 15 | - pip install -r requirements.txt 16 | - pip install coveralls 17 | - pip freeze 18 | 19 | script: python setup.py test 20 | 21 | after_success: coveralls 22 | 23 | deploy: 24 | provider: pypi 25 | user: alexandreproenca 26 | password: 27 | secure: AMjbHI8OQJ5yPrQk/Z+lzO+eNiCXro8EDv73FgoJ8HpxXn3jSJp6RqhTNZpgmOig7zR+41lRX5ol/awxHL6pMMhrQRXVKBbAgC0V9B5iwVigsjTjQRyozuL2SzQDPYHsYMkT4s9qdRAMhqNp4wSRqw73cjlvZjCSxhTQ/tvNAuqde0RPWDN+oX6BcwpOAF4IjD4jujUMceBtDzlrREY8Tnpwf379uhM552RGxbdkyR8v9Ca2EF2HqOrRzZhlB9j59bOviV6rCozWzd+SlwjJhJhaVrkwSu8tLt67Zq8+M2pCYb6pEuIxqWTJjwtD7c8UWhMJ+Q/h+i+qNmzZ2DT6QwyLYilmtr7dVmXOUKBhiK87uXWwH43YUA7pahFwscfVLL5pxeIvPChI1eVaHBhmbasLuE2GYeqduf0S2HXDjJ79dO0CfDCCqa/n02cItNpHTRZXjQLrCr8lzfcUBXsYNNkxKN2ziwkbTNJuSR3C0F0/guDYTTMHBiy4IYu7prC4gbiO763kn4z6kYq6JZVgTEMYoJVg64X2rpVjqzYhB6i7lgtUmQAFTZJix1A6xjEJzFIc/Mo5AA8hJnVokiXch266ssP7UBFAc15BfYeXNo0KpNaE3YxxcNj+cI4VnziaS1RXCRKCOLQ7jg6xgHOpX4L1jxX5CkfMpMHo69GVuFs= 28 | on: 29 | tags: true 30 | -------------------------------------------------------------------------------- /AUTHORS.rst: -------------------------------------------------------------------------------- 1 | Credits 2 | ------- 3 | 4 | Development Lead 5 | ---------------- 6 | 7 | * Alexandre Proença - https://github.com/AlexandreProenca 8 | 9 | Contributors 10 | ------------ 11 | 12 | None yet. Why not be the first? feel free to fork the project and submit pull requests. 13 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /LICENSE.rst: -------------------------------------------------------------------------------- 1 | License 2 | ------- 3 | 4 | :: 5 | 6 | The MIT License (MIT) 7 | 8 | Copyright (c) 2015, Alexandre Proença 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in 18 | all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ###Django Auto REST Project 2 | 3 | [![Badge](https://travis-ci.org/AlexandreProenca/django-auto-rest-project.svg?branch=master)](https://travis-ci.org/AlexandreProenca/django-auto-rest-project "Travis CI") 4 | [![Badge](https://img.shields.io/pypi/v/django-auto-rest-project.svg)](https://pypi.python.org/pypi/django-auto-rest-project "Pypi") 5 | [![Badge](https://img.shields.io/pypi/dd/django-auto-rest-project.svg)](https://pypi.python.org/pypi/django-auto-rest-project "Pypi") 6 | [![Badge](https://img.shields.io/pypi/pyversions/django-auto-rest-project.svg)](https://pypi.python.org/pypi/django-auto-rest-project "Pypi") 7 | [![Badge](https://img.shields.io/pypi/l/django-auto-rest-project.svg)](https://pypi.python.org/pypi/django-auto-rest-project "Pypi") 8 | [![Badge](https://img.shields.io/pypi/wheel/django-auto-rest-project.svg)](https://pypi.python.org/pypi/django-auto-rest-project "Pypi") 9 | [![Badge](https://img.shields.io/pypi/format/django-auto-rest-project.svg)](https://pypi.python.org/pypi/django-auto-rest-project "Pypi") 10 | [![Badge](https://img.shields.io/pypi/implementation/django-auto-rest-project.svg)](https://pypi.python.org/pypi/django-auto-rest-project "Pypi") 11 | [![Badge](https://img.shields.io/pypi/status/django-auto-rest-project.svg)](https://pypi.python.org/pypi/django-auto-rest-project "Pypi") 12 | [![Badge](https://api.codacy.com/project/badge/50515222d332430aba11bcbe76706f14)](https://www.codacy.com/app/linuxloco/django-auto-rest-project "Codacy") 13 | [![Badge](https://readthedocs.org/projects/django-auto-rest-project/badge/?version=latest)](http://django-auto-rest-project.readthedocs.org/en/latest/ "ReadDocs") 14 | [![Badge](http://img.shields.io/badge/tech-stack-0690fa.svg?style=flat)](http://stackshare.io/AlexandreProenca/django-auto-rest-project "StackShare") 15 | [![Badge](https://img.shields.io/badge/GITTER-join%20chat-green.svg)](https://gitter.im/AlexandreProenca/devfriends?utm_source=share-link&utm_medium=link&utm_campaign=share-link "Livechat") 16 | 17 | ----------- 18 | 19 | [![Badge](https://img.shields.io/badge/english-ok-blue.svg)](https://img.shields.io/badge/english-ok-green.svg" Livechat") 20 | 21 | This package aims to facilitate the creation of Django projects with Django Rest Framework, just type database connetions informations and the robot will gives you a Django RESTful project based on your mysql database. 22 | Ridiculously simple and fast to use, just install the package and type the command like the exemple below. 23 | 24 | [![Badge](https://img.shields.io/badge/portugues--brasil-ok-green.svg)](https://img.shields.io/badge/portugues--brasil-ok-green.svg" Livechat") 25 | 26 | Este pacote tem o objectivo de facilitar a criação de projetos Django + Django Rest Framework, basta apenas digitar os dados de conexão com seu banco de dados e o robo vai criar um projeto Django RESTful baseado no seu banco de dados mysql. 27 | Ridiculamente fácil de usar, basta instalar o pacote e digitar o comando, como no exemplo abaixo: 28 | 29 | `$pip install django-auto-rest-project` 30 | 31 | `$robot_rest -ip 227.33.126.233 -user punkhard -database banddb -project alsage -password jhhf4` 32 | 33 | Some packages included 34 | 35 | Modern template for Django admin interface with improved functionality 36 | 37 | [![Badge](https://raw.githubusercontent.com/geex-arts/jet/static/screen1.png)](http://readdocs.com" Jet Admin") 38 | 39 | Swagger the best way to document your API 40 | 41 | [![Badge](http://artsy.github.io/images/2013-06-21-adding-api-documentation-with-grape-swagger/swagger-ui.png)](http://readdocs.com" Swagger") 42 | 43 | 44 | ###Safe Installation 45 | 46 | Easiest and safe way to install this library is by using pip and virtualenv: 47 | 48 | $ virtualenv myenv 49 | $ cd myenv 50 | $ source bin/activate 51 | $ mkdir myproject 52 | $ cd myproject 53 | $ pip install django-auto-rest-project 54 | 55 | Usage 56 | ----- 57 | usage: robot_rest [-h] [-vv VERBOSE] -ip DATABASE_HOST -user DATABASE_USER -database DATABASE_NAME -password DATABASE_PASSWORD -project PROJECT_NAME 58 | 59 | optional arguments: 60 | -h, --help Show this help message and exit 61 | 62 | -vv VERBOSE, --verbose VERBOSE Increase verbosity. 63 | 64 | -ip DATABASE_HOST Host address of the database 65 | 66 | -user DATABASE_USER Username that have access database 67 | 68 | -database DATABASE_NAME The name of the database 69 | 70 | -password DATABASE_PASSWORD Password to access the database 71 | 72 | -project PROJECT_NAME The name of the project. 73 | 74 | 75 | Exemples: 76 | 77 | robot_rest -ip 187.45.196.236 -user nwpartner3 -database partnerdb -project webscrapy -password sdf435*7 78 | 79 | ###Project's Scheme 80 | 81 | |project_name 82 | ├── core 83 | │   ├── admin.py 84 | │   ├── __init__.py 85 | │   ├── migrations 86 | │   │   └── __init__.py 87 | │   ├── models.py 88 | │   ├── serializers.py 89 | │   ├── tests.py 90 | │   ├── urls.py 91 | │   └── views.py 92 | ├── manage.py 93 | └── project_name 94 | ├── __init__.py 95 | ├── settings.py 96 | ├── urls.py 97 | └── wsgi.py 98 | 99 | 100 | ###Packages that will be installed 101 | 102 | cached-property (1.2.0) 103 | Django (1.8.4) 104 | django-admin-bootstrapped (2.5.5) 105 | django-auto-rest-project (0.1.1) 106 | django-braces (1.8.1) 107 | django-cors-headers (1.1.0) 108 | django-drf-file-generator (0.1.0) 109 | django-filter (0.11.0) 110 | django-jet (0.0.9) 111 | django-oauth-toolkit (0.9.0) 112 | django-rest-auth (0.5.0) 113 | django-rest-swagger (0.3.4) 114 | django-url-filter (0.2.0) 115 | djangorestframework (3.2.3) 116 | enum34 (1.0.4) 117 | funcsigs (0.4) 118 | Markdown (2.6.2) 119 | mock (1.3.0) 120 | MySQL-python (1.2.5) 121 | oauthlib (1.0.1) 122 | pbr (1.7.0) 123 | python-memcached (1.57) 124 | PyYAML (3.11) 125 | setuptools (3.6) 126 | simplejson (3.8.0) 127 | six (1.9.0) 128 | wsgiref (0.1.2) 129 | yet-another-django-profiler (1.0.0) 130 | 131 | ###Urls that will be created 132 | url(r'^admin/', include(admin.site.urls)), 133 | url(r'^docs/', include('rest_framework_swagger.urls')), 134 | url(r'^o/', include('oauth2_provider.urls', namespace='oauth2_provider')), 135 | url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')), 136 | url(r'^', include('core.urls')), 137 | 138 | ###Requirements 139 | Python 2.7, 3.x, pypy or pypy3 140 | Django 1.8+ (there are plans to support older Django versions) 141 | Django REST Framework 2 or 3 142 | 143 | ##Authors 144 | `django-auto-rest-project` was written by `Alexandre Proença `_. 145 | -------------------------------------------------------------------------------- /dev-requirements.txt: -------------------------------------------------------------------------------- 1 | Babel==2.0 2 | Jinja2==2.11.3 3 | MarkupSafe==0.23 4 | Pygments==2.7.4 5 | Sphinx==1.3.1 6 | alabaster==0.7.6 7 | bumpversion==0.5.3 8 | docutils==0.12 9 | pluggy==0.3.0 10 | py==1.4.30 11 | pytz==2015.4 12 | six==1.9.0 13 | snowballstemmer==1.2.0 14 | sphinx-rtd-theme==0.1.8 15 | tox==2.1.1 16 | virtualenv==13.1.2 17 | wsgiref==0.1.2 18 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Django 2 | pytest==2.7.2 3 | djangorestframework 4 | django-drf-file-generator -------------------------------------------------------------------------------- /robot_rest/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | 4 | /[-])// ___ 5 | __ --\ `_/~--| / \ 6 | /_-/~~--~~ /~~~\\_\ /\ 7 | | |___|===|_-- | \ \ \ 8 | _/~~~~~~~~|~~\, ---|---\___/----| \/\-\ 9 | ~\________|__/ / // \__ | || / | | | | 10 | ,~-|~~~~~\--, | \|--|/~||| | | | 11 | [3-|____---~~ _--'==;/ _, | |_| 12 | / /\__|_/ \ \__/--/ 13 | /---/_\ -___/ | /,--| 14 | / /\/~--| | | \/// 15 | / / |-__ \ |/ 16 | |--/ / |-- | \ 17 | \^~~\\/\ \ \/- _ 18 | \ | \ |~~\~~| \ 19 | \ \ \ \ \ | \ 20 | \ \ | \ \ \ 21 | |~~|\/\| \ \ | 22 | | |/ \_--_- |\ 23 | | / / |/\/ 24 | ~~ / / 25 | |__/ 26 | 27 | 28 | """ 29 | 30 | __title__ = 'Djanago Auto REST Project' 31 | __version__ = '0.5.4' 32 | __author__ = 'Alexandre Proença' 33 | __license__ = 'MIT' 34 | __copyright__ = 'Copyright 2015 Alexandre Proença' 35 | 36 | # Version synonym 37 | VERSION = __version__ 38 | 39 | # Header encoding (see RFC5987) 40 | HTTP_HEADER_ENCODING = 'iso-8859-1' 41 | 42 | # Default datetime input and output formats 43 | ISO_8601 = 'iso-8601' 44 | -------------------------------------------------------------------------------- /robot_rest/requirements.txt: -------------------------------------------------------------------------------- 1 | Django 2 | django-auto-rest-project 3 | django-braces 4 | django-cors-headers 5 | django-drf-file-generator 6 | django-filter 7 | django-jet 8 | django-oauth-toolkit 9 | django-rest-auth 10 | django-rest-swagger 11 | django-social-auth 12 | django-url-filter 13 | djangorestframework 14 | django-rest-framework-social-oauth2 15 | feedparser 16 | google-api-python-client 17 | Markdown 18 | MySQL-python 19 | oauth2client 20 | oauthlib 21 | openapi-codec 22 | pyasn1 23 | pyasn1-modules 24 | requests 25 | rsa 26 | simplejson 27 | django-allauth 28 | -------------------------------------------------------------------------------- /robot_rest/robot_rest.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | # Esse programa tem o objetvo de facilitar a criação de projetos Django + Djangorestframework 3 | # Autor: Alexandre Proença - linuxloco@gmail.com - alexandre.proenca@hotmail.com.br 4 | # Floripa Dom 00:52 13/09/2015 5 | # !/usr/bin/python 6 | from argparse import ArgumentParser 7 | import pkg_resources 8 | import string 9 | from random import choice 10 | import os 11 | import shutil 12 | import subprocess 13 | import sys 14 | 15 | 16 | def main(): 17 | """ 18 | Metodo principal que vai receber os valores passados por linha de comando e manipular a criação de um projeto 19 | Django 1.8 + Djangorestframework 3.2, instala uma lista de pacotes predefinidos 20 | O metodo vai conectar em uma base de dados e fazer o mapeamento das entidades, transformando-as em objetos do tipo 21 | django.db.models, após este mapeamento configura o arquivo settings.py e gera mais quatro arquivos, 22 | dentro do app core, admin.py, urls.py, views.py, serializers.py, arquivos ja no padrao para ser usado com 23 | djangorestframework. 24 | """ 25 | ap = ArgumentParser() 26 | ap.add_argument('-vv', '--verbose', 27 | default=False, 28 | help='Increase verbosity.') 29 | 30 | ap.add_argument('-ip', 31 | required=True, 32 | action='store', 33 | dest='database_host', 34 | help='Host address of the database') 35 | 36 | ap.add_argument('-user', 37 | action='store', 38 | required=True, 39 | dest='database_user', 40 | help='Username that have access database') 41 | 42 | ap.add_argument('-database', 43 | action='store', 44 | required=True, 45 | dest='database_name', 46 | help='The name of the database') 47 | 48 | ap.add_argument('-password', 49 | action='store', 50 | required=True, 51 | dest='database_password', 52 | help='Password to access the database') 53 | 54 | ap.add_argument('-project', 55 | action='store', 56 | required=True, 57 | dest='project_name', 58 | help='The name of the project.') 59 | 60 | args = ap.parse_args() 61 | 62 | if args.database_host: 63 | 64 | def sed(paths): 65 | for path in paths: 66 | with open(args.project_name + r'/' + path+'.py', 'wt') as fout: 67 | with open(pkg_resources.resource_filename('robot_rest', path+'.tpl'), 'rt') as fin: 68 | for line in fin: 69 | if '@projeto@' in line: 70 | fout.write(line.replace('@projeto@', args.project_name)) 71 | elif '@HOST@' in line: 72 | fout.write(line.replace('@HOST@', args.database_host)) 73 | elif '@USER@' in line: 74 | fout.write(line.replace('@USER@', args.database_user)) 75 | elif '@PASSWORD@' in line: 76 | fout.write(line.replace('@PASSWORD@', args.database_password)) 77 | elif '@NAME@' in line: 78 | fout.write(line.replace('@NAME@', args.database_name)) 79 | elif '@SECRET@' in line: 80 | fout.write(line.replace('@SECRET@', ''.join([choice(string.letters + string.digits) for _ in range(50)]))) 81 | else: 82 | fout.write(line) 83 | os.remove(args.project_name + r'/'+path+'.tpl') 84 | 85 | with open(pkg_resources.resource_filename('robot_rest', 'requirements.txt'), 'rt') as requirements: 86 | for line in requirements: 87 | subprocess.call(["pip", "install", line]) 88 | 89 | subprocess.call(["django-admin", "startproject", args.project_name]) 90 | os.chdir(args.project_name) 91 | subprocess.call(["django-admin", "startapp", "core"]) 92 | 93 | subprocess.call(['cp', pkg_resources.resource_filename('robot_rest', 'urls.tpl'), args.project_name + r'/urls.py']) 94 | subprocess.call(['cp', '-r', pkg_resources.resource_filename('robot_rest', 'settings'), args.project_name + r'/']) 95 | subprocess.call(['cp', '-r', pkg_resources.resource_filename('robot_rest', 'tests'), args.project_name + r'/']) 96 | 97 | sed(['settings/defaults', 98 | '/settings/dev', 99 | '/settings/production', 100 | '/settings/tests', 101 | '/settings/__init__', 102 | 'tests/__init__', 103 | 'tests/settingstest', 104 | 'tests/test_rest_api' 105 | ]) 106 | 107 | os.remove(args.project_name + r'/settings.py') 108 | subprocess.call(['cp', args.project_name +'/settings/defaults.py', args.project_name + r'/settings.py']) 109 | 110 | models = subprocess.check_output(['python', 'manage.py', 'inspectdb']) 111 | 112 | with open("core/models.py", "w") as f: 113 | [f.write(l) for l in models] 114 | 115 | subprocess.call(["drf_gen", "-m", "core/models.py", "-A"]) 116 | subprocess.call(["mv", "drf_gen_build/admin.py", "core"]) 117 | subprocess.call(["mv", "drf_gen_build/urls.py", "core"]) 118 | subprocess.call(["mv", "drf_gen_build/views.py", "core"]) 119 | subprocess.call(["mv", "drf_gen_build/serializers.py", "core"]) 120 | shutil.rmtree('drf_gen_build') 121 | 122 | with open('requirements.txt', 'w') as f: 123 | requirements = subprocess.check_output(['pip', 'freeze']) 124 | [f.write(l) for l in requirements] 125 | 126 | subprocess.call(['python', 'manage.py', 'makemigrations']) 127 | subprocess.call(['python', 'manage.py', 'migrate']) 128 | subprocess.call(['python', 'manage.py', 'createsuperuser']) 129 | subprocess.call(['python', 'manage.py', 'collectstatic']) 130 | os.remove(args.project_name + r'/settings.py') 131 | sys.exit(0) 132 | 133 | 134 | if __name__ == "__main__": 135 | main() 136 | -------------------------------------------------------------------------------- /robot_rest/settings/__init__.tpl: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | from dev import * 3 | #from production import * -------------------------------------------------------------------------------- /robot_rest/settings/defaults.tpl: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | """ 3 | Django settings for project. 4 | 5 | Generated by 'django-admin startproject' using Django 1.10.2. 6 | 7 | For more information on this file, see 8 | https://docs.djangoproject.com/en/1.10/topics/settings/ 9 | 10 | For the full list of settings and their values, see 11 | https://docs.djangoproject.com/en/1.10/ref/settings/ 12 | """ 13 | 14 | import os 15 | 16 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 17 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 18 | 19 | 20 | # Quick-start development settings - unsuitable for production 21 | # See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/ 22 | 23 | # SECURITY WARNING: keep the secret key used in production secret! 24 | SECRET_KEY = '@SECRET@' 25 | 26 | # SECURITY WARNING: don't run with debug turned on in production! 27 | DEBUG = True 28 | 29 | ALLOWED_HOSTS = ['*'] 30 | 31 | 32 | # Application definition 33 | 34 | INSTALLED_APPS = [ 35 | 'jet.dashboard', 36 | 'jet', 37 | 'django.contrib.admin', 38 | 'django.contrib.auth', 39 | 'django.contrib.contenttypes', 40 | 'django.contrib.sessions', 41 | 'django.contrib.messages', 42 | 'django.contrib.staticfiles', 43 | 'core', 44 | 'rest_framework', 45 | 'corsheaders', 46 | 'rest_framework.authtoken', 47 | 'rest_auth', 48 | 'rest_framework_swagger', 49 | 50 | ] 51 | 52 | MIDDLEWARE = [ 53 | 'django.middleware.security.SecurityMiddleware', 54 | 'django.contrib.sessions.middleware.SessionMiddleware', 55 | 'django.middleware.common.CommonMiddleware', 56 | 'django.middleware.csrf.CsrfViewMiddleware', 57 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 58 | 'django.contrib.messages.middleware.MessageMiddleware', 59 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 60 | ] 61 | 62 | 63 | 64 | TEMPLATES = [ 65 | { 66 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 67 | 'DIRS': [], 68 | 'APP_DIRS': True, 69 | 'OPTIONS': { 70 | 'context_processors': [ 71 | 'django.template.context_processors.debug', 72 | 'django.template.context_processors.request', 73 | 'django.contrib.auth.context_processors.auth', 74 | 'django.contrib.messages.context_processors.messages', 75 | 'social.apps.django_app.context_processors.backends', 76 | 'social.apps.django_app.context_processors.login_redirect', 77 | ], 78 | }, 79 | }, 80 | ] 81 | 82 | 83 | # Database 84 | # https://docs.djangoproject.com/en/1.10/ref/settings/#databases 85 | 86 | #TODO substituir como o nome do projeto 87 | ROOT_URLCONF = '@projeto@.urls' 88 | 89 | 90 | #TODO subtituir com o nome do projeto 91 | WSGI_APPLICATION = '@projeto@.wsgi.application' 92 | 93 | 94 | # Database 95 | # https://docs.djangoproject.com/en/1.8/ref/settings/#databases 96 | 97 | 98 | DATABASES = { 99 | 'default': { 100 | 'ENGINE': 'django.db.backends.mysql', 101 | 'NAME': '@NAME@', 102 | 'USER': '@USER@', 103 | 'PASSWORD': '@PASSWORD@', 104 | 'HOST': '@HOST@', 105 | 'PORT': '3306', 106 | } 107 | } 108 | 109 | AUTHENTICATION_BACKENDS = ( 110 | 111 | # Facebook OAuth2 112 | 'social.backends.facebook.FacebookAppOAuth2', 113 | 'social.backends.facebook.FacebookOAuth2', 114 | 115 | # django-rest-framework-social-oauth2 116 | 'rest_framework_social_oauth2.backends.DjangoOAuth2', 117 | 118 | # Django 119 | 'django.contrib.auth.backends.ModelBackend', 120 | ) 121 | 122 | 123 | #Django Restframework configuration 124 | REST_FRAMEWORK = { 125 | 126 | 'DEFAULT_AUTHENTICATION_CLASSES': ( 127 | 'oauth2_provider.ext.rest_framework.OAuth2Authentication', 128 | 'rest_framework_social_oauth2.authentication.SocialAuthentication', 129 | 'rest_framework.authentication.BasicAuthentication', 130 | 'rest_framework.authentication.SessionAuthentication', 131 | 'rest_framework.authentication.TokenAuthentication', 132 | ), 133 | 134 | 'DEFAULT_PERMISSION_CLASSES':( 135 | #'rest_framework.permissions.IsAuthenticated', 136 | 'rest_framework.permissions.AllowAny', 137 | ), 138 | 139 | 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', 140 | 'PAGE_SIZE': 10 141 | } 142 | 143 | OAUTH2_PROVIDER = { 144 | # this is the list of available scopes 145 | 'SCOPES': {'read': 'Read scope', 'write': 'Write scope', 'groups': 'Access to your groups'} 146 | } 147 | 148 | EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' 149 | # EMAIL_BACKEND = 'django_smtp_ssl.SSLEmailBackend:wq' 150 | 151 | 152 | if DEBUG: 153 | EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' 154 | 155 | # To test emails send by Google 156 | EMAIL_USE_TLS = True 157 | EMAIL_HOST = 'smtp.gmail.com' 158 | EMAIL_PORT = 587 159 | EMAIL_HOST_USER = 'linuxloco@gmail.com' 160 | EMAIL_HOST_PASSWORD = '' 161 | SERVER_EMAIL = 'linuxloco@gmail.com' 162 | DEFAULT_FROM_EMAIL = 'linuxloco@gmail.com' 163 | 164 | 165 | # To use with http://swagger.io/ 166 | SWAGGER_SETTINGS = { 167 | 'exclude_namespaces': [], 168 | 'api_version': '', 169 | 'api_path': '/', 170 | 'enabled_methods': [ 171 | 'get', 172 | 'post', 173 | 'put', 174 | 'patch', 175 | 'delete' 176 | ], 177 | 'api_key': '', 178 | 'is_authenticated': False, 179 | 'is_superuser': False, 180 | 'permission_denied_handler': None, 181 | 'info': { 182 | 'contact': '', 183 | 'description': '', 184 | 'title': '@projeto@', 185 | }, 186 | 'doc_expansion': 'none', 187 | } 188 | 189 | 190 | # Internationalization 191 | # https://docs.djangoproject.com/en/1.8/topics/i18n/ 192 | 193 | LANGUAGE_CODE = 'pt-BR' 194 | 195 | TIME_ZONE = 'America/Sao_Paulo' 196 | 197 | USE_I18N = True 198 | 199 | USE_L10N = True 200 | 201 | USE_TZ = True 202 | 203 | CORS_ORIGIN_ALLOW_ALL = True 204 | 205 | # Password validation 206 | # https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators 207 | 208 | AUTH_PASSWORD_VALIDATORS = [ 209 | { 210 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 211 | }, 212 | { 213 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 214 | }, 215 | { 216 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 217 | }, 218 | { 219 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 220 | }, 221 | ] 222 | 223 | # Static files (CSS, JavaScript, Images) 224 | # https://docs.djangoproject.com/en/1.10/howto/static-files/ 225 | 226 | STATIC_URL = '/static/' 227 | STATIC_ROOT = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'static') 228 | 229 | -------------------------------------------------------------------------------- /robot_rest/settings/dev.tpl: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | from defaults import * 3 | 4 | # SECURITY WARNING: don't run with debug turned on in production! 5 | DEBUG = True 6 | 7 | ALLOWED_HOSTS = ['*'] 8 | 9 | # DATABASES = { 10 | # 'default': { 11 | # 'ENGINE': 'django.db.backends.sqlite3', 12 | # 'NAME': 'dev_db', 13 | # } 14 | # } 15 | 16 | DATABASES = { 17 | 'default': { 18 | 'ENGINE': 'django.db.backends.mysql', 19 | 'NAME': '@NAME@', 20 | 'USER': '@USER@', 21 | 'PASSWORD': '@PASSWORD@', 22 | 'HOST': '@HOST@', 23 | 'PORT': '3306', 24 | } 25 | } 26 | 27 | 28 | # Django Restframework configuration 29 | REST_FRAMEWORK = { 30 | 31 | 'DEFAULT_AUTHENTICATION_CLASSES': ( 32 | 'oauth2_provider.ext.rest_framework.OAuth2Authentication', 33 | 'rest_framework_social_oauth2.authentication.SocialAuthentication', 34 | 'rest_framework.authentication.BasicAuthentication', 35 | 'rest_framework.authentication.SessionAuthentication', 36 | 'rest_framework.authentication.TokenAuthentication', 37 | ), 38 | 39 | 'DEFAULT_PERMISSION_CLASSES':( 40 | #'rest_framework.permissions.IsAuthenticated', 41 | 'rest_framework.permissions.AllowAny', 42 | ), 43 | 44 | 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', 45 | 'PAGE_SIZE': 10 46 | } 47 | 48 | 49 | -------------------------------------------------------------------------------- /robot_rest/settings/production.tpl: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | from defaults import * 3 | import os 4 | 5 | # SECURITY WARNING: don't run with debug turned on in production! 6 | DEBUG = False 7 | 8 | ALLOWED_HOSTS = [] 9 | 10 | DATABASES = { 11 | 'default': { 12 | 'ENGINE': 'django.db.backends.mysql', 13 | 'NAME': os.environ.get("MYAPP_DB_USER", ''), 14 | 'USER': os.environ.get("MYAPP_DB_USER", ''), 15 | 'PASSWORD': os.environ.get("MYAPP_DB_PASSWORD", ''), 16 | 'HOST': os.environ.get("HOST_DB_MF", ''), 17 | 'PORT': '3306', 18 | } 19 | } 20 | 21 | EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' 22 | 23 | # To test emails send by Google 24 | EMAIL_USE_TLS = True 25 | EMAIL_HOST = 'smtp.gmail.com' 26 | EMAIL_PORT = 587 27 | EMAIL_HOST_USER = os.environ.get("EMAIL_HOST_USER", '') 28 | EMAIL_HOST_PASSWORD = os.environ.get("EMAIL_HOST_PASSWORD", '') 29 | SERVER_EMAIL = os.environ.get("SERVER_EMAIL", '') 30 | DEFAULT_FROM_EMAIL = os.environ.get("DEFAULT_FROM_EMAIL", '') 31 | 32 | 33 | # Django Restframework configuration 34 | REST_FRAMEWORK = { 35 | 36 | 'DEFAULT_AUTHENTICATION_CLASSES': ( 37 | 'oauth2_provider.ext.rest_framework.OAuth2Authentication', 38 | 'rest_framework_social_oauth2.authentication.SocialAuthentication', 39 | 'rest_framework.authentication.BasicAuthentication', 40 | 'rest_framework.authentication.SessionAuthentication', 41 | 'rest_framework.authentication.TokenAuthentication', 42 | ), 43 | 44 | 'DEFAULT_PERMISSION_CLASSES':( 45 | 'rest_framework.permissions.IsAuthenticated', 46 | ), 47 | 48 | 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', 49 | 'PAGE_SIZE': 10 50 | } 51 | 52 | 53 | CORS_ORIGIN_ALLOW_ALL = True 54 | 55 | 56 | -------------------------------------------------------------------------------- /robot_rest/settings/tests.tpl: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | from defaults import * 3 | 4 | DEBUG = True 5 | 6 | DATABASES = { 7 | 'default': { 8 | 'ENGINE': 'django.db.backends.sqlite3', 9 | 'NAME': 'test_db', 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /robot_rest/tests/__init__.tpl: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | __author__ = 'Alexandre Proença' 3 | -------------------------------------------------------------------------------- /robot_rest/tests/settingstest.tpl: -------------------------------------------------------------------------------- 1 | from @projeto@.settings.tests import * 2 | -------------------------------------------------------------------------------- /robot_rest/tests/test_rest_api.tpl: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | from django.test import TestCase 3 | from django.contrib.auth.models import User 4 | from rest_framework.authtoken.models import Token 5 | from rest_framework.test import APIClient 6 | 7 | 8 | class TestAPIViews(TestCase): 9 | 10 | def setUp(self): 11 | """ 12 | Objetos necessarios para os testes 13 | :return: 14 | """ 15 | self.client = APIClient() 16 | self.user = User.objects.create_user('testuser@test.com', password='testing') 17 | self.user.save() 18 | self.token = Token.objects.get(user=self.user) 19 | 20 | def _require_login(self): 21 | """ 22 | Token do usuario de teste 23 | :return: APIClient().credentials() 24 | """ 25 | self.client.credentials(HTTP_AUTHORIZATION='Token ' + str(self.token)) 26 | 27 | def test_login_account(self): 28 | """ 29 | Login 30 | :return: 200 31 | """ 32 | response = self.client.post(path='/v1/rest-auth/login/', 33 | data={"username": 'testuser@test.com', "password": 'testing'}, format='json') 34 | self.assertEqual(response.status_code, 200, 35 | 'Expected Response Code 200, received {0} instead.'.format(response.status_code)) 36 | 37 | def test_login_account_fail(self): 38 | """ 39 | Falha no login (credenciais erradas). 40 | :return: 400 41 | """ 42 | response = self.client.post('/v1/rest-auth/login/', 43 | {"username": 'testuser@test.com', "password": 'testings'}, 44 | format='json') 45 | 46 | self.assertEqual(response.status_code, 400, 47 | 'Expected Response Code 400, received {0} instead.'.format(response.status_code)) 48 | 49 | def test_create_account_user(self): 50 | """ 51 | Criação de conta de usuario. 52 | :return: 201 53 | """ 54 | 55 | response = self.client.post('/v1/users/', 56 | {"username": 'toni@maluco', "password": 'cidade'}, 57 | format='json') 58 | 59 | self.assertEqual(response.status_code, 201, 60 | 'Expected Response Code 201, received {0} instead.'.format(response.status_code)) 61 | 62 | def test_update_account_user(self): 63 | """ 64 | Update de usuario e senha. 65 | :return: 200 66 | """ 67 | self._require_login() 68 | 69 | response = self.client.put('/v1/users/' +str(self.user.id)+'/', 70 | {"username": 'toni@malucao', "password": 'cidadeeee'}, 71 | format='json') 72 | 73 | self.assertEqual(response.status_code, 200, 74 | 'Expected Response Code 200, received {0} instead.'.format(response.status_code)) 75 | 76 | def test_update_account_user_fail(self): 77 | """ 78 | Update de usuario e senha não autorizados. 79 | :return: 401 80 | """ 81 | response = self.client.put('/v1/users/' +str(self.user.id)+'/', 82 | {"username": 'toni@malucao', "password": 'cidadeeee'}, 83 | format='json') 84 | 85 | self.assertEqual(response.status_code, 401, 86 | 'Expected Response Code 401, received {0} instead.'.format(response.status_code)) 87 | 88 | def test_delete_account_user(self): 89 | """ 90 | Deleção da conta. 91 | :return: 204 92 | """ 93 | self._require_login() 94 | response = self.client.delete('/v1/users/' +str(self.user.id)+'/', format='json') 95 | self.assertEqual(response.status_code, 204, 96 | 'Expected Response Code 204, received {0} instead.'.format(response.status_code)) 97 | 98 | def test_delete_account_user_fail(self): 99 | """ 100 | Deleção da conta não autorizado. 101 | :return: 401 102 | """ 103 | response = self.client.delete('/v1/users/' +str(self.user.id)+'/', format='json') 104 | self.assertEqual(response.status_code, 401, 105 | 'Expected Response Code 401, received {0} instead.'.format(response.status_code)) 106 | 107 | def test_list_users(self): 108 | """ 109 | Listagem dos usuários. 110 | :return: 200 111 | """ 112 | self._require_login() 113 | response = self.client.get('/v1/users/', format='json') 114 | self.assertEqual(response.status_code, 200, 115 | 'Expected Response Code 200, received {0} instead.'.format(response.status_code)) 116 | 117 | def test_list_users_fail(self): 118 | """ 119 | Listagem dos usuários não autorizado. 120 | :return: 401 121 | """ 122 | response = self.client.get('/v1/users/', format='json') 123 | self.assertEqual(response.status_code, 401, 124 | 'Expected Response Code 401, received {0} instead.'.format(response.status_code)) -------------------------------------------------------------------------------- /robot_rest/urls.tpl: -------------------------------------------------------------------------------- 1 | """liberdade URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/1.8/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Add an import: from blog import urls as blog_urls 14 | 2. Add a URL to urlpatterns: url(r'^blog/', include(blog_urls)) 15 | """ 16 | from django.conf.urls import include, url 17 | from django.contrib import admin 18 | from rest_framework_swagger.views import get_swagger_view 19 | from core.views import obtain_auth_token, password_reset 20 | from django.contrib.auth.views import password_reset as pass_reset_django 21 | from django.contrib.auth.views import password_reset_done as reset_done 22 | from django.contrib.auth.views import password_reset_confirm as reset_confirm 23 | from django.contrib.auth.views import password_reset_complete as reset_complete 24 | 25 | 26 | urlpatterns = [ 27 | url(r'^jet/', include('jet.urls', 'jet')), # Django JET URLS 28 | url(r'^jet/dashboard/', include('jet.dashboard.urls', 'jet-dashboard')), # Django JET dashboard URLS 29 | url(r'^admin/', include(admin.site.urls)), 30 | url(r'^o/', include('oauth2_provider.urls', namespace='oauth2_provider')), 31 | url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')), 32 | url(r'^v1/', include('core.urls')), 33 | url(r'^v1/docs/', get_swagger_view(title='REST Project')), 34 | url(r'^v1/auth/', include('rest_framework_social_oauth2.urls')), # Social Login 35 | 36 | url(r'^v1/token-auth/', obtain_auth_token), 37 | 38 | url(r'^v1/password-reset/$', password_reset, {'post_reset_redirect' : '/accounts/password_reset/mailed/'}, name='password-reset'), 39 | 40 | # To use management credentials in web page and reset password 41 | url(r'^v1/accounts/password_reset/$', pass_reset_django, {'post_reset_redirect': '/accounts/password_reset/mailed/'}, name="password_reset"), 42 | url(r'^v1/accounts/password_reset/mailed/$', reset_done, name="password_reset_confirm"), 43 | url(r'^v1/accounts/password_reset/(?P[0-9A-Za-z]{1,13})-(?P[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$', reset_confirm, {'post_reset_redirect' : '/accounts/password_reset/complete/'}, name="password_reset_confirm"), 44 | url(r'^v1/accounts/password_reset/complete/$', reset_complete), 45 | url(r'^v1/rest-auth/', include('rest_auth.urls')), #default autentication 46 | 47 | ] 48 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [wheel] 2 | universal = 1 -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | import os 4 | import re 5 | import shutil 6 | import sys 7 | 8 | from setuptools import setup 9 | 10 | 11 | def get_version(package): 12 | """ 13 | Return package version as listed in `__version__` in `init.py`. 14 | """ 15 | init_py = open(os.path.join(package, '__init__.py')).read() 16 | return re.search("__version__ = ['\"]([^'\"]+)['\"]", init_py).group(1) 17 | 18 | 19 | def get_packages(package): 20 | """ 21 | Return root package and all sub-packages. 22 | """ 23 | return [dirpath 24 | for dirpath, dirnames, filenames in os.walk(package) 25 | if os.path.exists(os.path.join(dirpath, '__init__.py'))] 26 | 27 | 28 | def get_package_data(package): 29 | """ 30 | Return all files under the root package, that are not in a 31 | package themselves. 32 | """ 33 | walk = [(dirpath.replace(package + os.sep, '', 1), filenames) 34 | for dirpath, dirnames, filenames in os.walk(package) 35 | if not os.path.exists(os.path.join(dirpath, '__init__.py'))] 36 | 37 | filepaths = [] 38 | for base, filenames in walk: 39 | filepaths.extend([os.path.join(base, filename) 40 | for filename in filenames]) 41 | return {package: filepaths} 42 | 43 | version = get_version('robot_rest') 44 | 45 | if sys.argv[-1] == 'publish': 46 | # if os.system("pip freeze | grep wheel"): 47 | # print("wheel not installed.\nUse `pip install wheel`.\nExiting.") 48 | # sys.exit() 49 | # if os.system("pip freeze | grep twine"): 50 | # print("twine not installed.\nUse `pip install twine`.\nExiting.") 51 | # sys.exit() 52 | os.system("python setup.py sdist bdist_wheel") 53 | # os.system("twine upload dist/*") 54 | # print("You probably want to also tag the version now:") 55 | # print(" git tag -a %s -m 'version %s'" % (version, version)) 56 | # print(" git push --tags") 57 | # shutil.rmtree('dist') 58 | # shutil.rmtree('build') 59 | # shutil.rmtree('django_auto_rest_project.egg-info') 60 | sys.exit() 61 | 62 | 63 | setup( 64 | name='django-auto-rest-project', 65 | version=version, 66 | url="https://github.com/AlexandreProenca/django-auto-rest-project", 67 | license='MIT', 68 | description='This tool provide a way to build Django RESTful projects based your database', 69 | author='Alexandre Proença', 70 | author_email='alexandre.proenca@hotmail.com.br', # SEE NOTE BELOW (*) 71 | packages=get_packages('robot_rest'), 72 | install_requires=[], 73 | entry_points={ 74 | 'console_scripts': [ 75 | 'robot_rest=robot_rest.robot_rest:main', 76 | ], 77 | }, 78 | zip_safe=False, 79 | keywords='django', 80 | 81 | 82 | package_data={ 83 | 'robot_rest': ['*.tpl', 84 | '*.txt', 85 | 'settings/__init__.tpl', 86 | 'settings/defaults.tpl', 87 | 'settings/dev.tpl', 88 | 'settings/production.tpl', 89 | 'settings/tests.tpl', 90 | 'tests/__init__.tpl', 91 | 'tests/settingstest.tpl', 92 | 'tests/test_rest_api.tpl' 93 | ], 94 | }, 95 | classifiers=[ 96 | 'Development Status :: 2 - Pre-Alpha', 97 | 'Environment :: Web Environment', 98 | 'Framework :: Django', 99 | 'Intended Audience :: Developers', 100 | 'License :: OSI Approved :: MIT License', 101 | 'Operating System :: OS Independent', 102 | 'Programming Language :: Python', 103 | 'Programming Language :: Python :: 3', 104 | 'Topic :: Internet :: WWW/HTTP', 105 | ] 106 | ) 107 | 108 | # (*) Please direct queries to the discussion group, rather than to me directly 109 | # Doing so helps ensure your question is helpful to other users. 110 | # Queries directly to my email are likely to receive a canned response. 111 | # 112 | # Many thanks for your understanding. 113 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'Alexandre Proença' 3 | -------------------------------------------------------------------------------- /tests/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for money project. 3 | 4 | Generated by 'django-admin startproject' using Django 1.10.2. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.10/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/1.10/ref/settings/ 11 | """ 12 | 13 | import os 14 | 15 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 16 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 17 | 18 | 19 | # Quick-start development settings - unsuitable for production 20 | # See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/ 21 | 22 | # SECURITY WARNING: keep the secret key used in production secret! 23 | SECRET_KEY = '@SECRET@' 24 | 25 | # SECURITY WARNING: don't run with debug turned on in production! 26 | DEBUG = True 27 | 28 | ALLOWED_HOSTS = ['*'] 29 | 30 | 31 | # Application definition 32 | 33 | INSTALLED_APPS = [ 34 | 'django.contrib.admin', 35 | 'django.contrib.auth', 36 | 'django.contrib.contenttypes', 37 | 'django.contrib.sessions', 38 | 'django.contrib.messages', 39 | 'django.contrib.staticfiles', 40 | 'core', 41 | 'rest_framework', 42 | 'corsheaders', 43 | 'rest_framework.authtoken', 44 | 'rest_auth', 45 | 'oauth2_provider', 46 | 'rest_framework_swagger', 47 | ] 48 | 49 | MIDDLEWARE = [ 50 | 'django.middleware.security.SecurityMiddleware', 51 | 'django.contrib.sessions.middleware.SessionMiddleware', 52 | 'django.middleware.common.CommonMiddleware', 53 | 'django.middleware.csrf.CsrfViewMiddleware', 54 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 55 | 'django.contrib.messages.middleware.MessageMiddleware', 56 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 57 | ] 58 | 59 | 60 | TEMPLATES = [ 61 | { 62 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 63 | 'DIRS': [], 64 | 'APP_DIRS': True, 65 | 'OPTIONS': { 66 | 'context_processors': [ 67 | 'django.template.context_processors.debug', 68 | 'django.template.context_processors.request', 69 | 'django.contrib.auth.context_processors.auth', 70 | 'django.contrib.messages.context_processors.messages', 71 | ], 72 | }, 73 | }, 74 | ] 75 | 76 | 77 | # Database 78 | # https://docs.djangoproject.com/en/1.10/ref/settings/#databases 79 | 80 | #TODO substituir como o nome do projeto 81 | ROOT_URLCONF = '@projeto@.urls' 82 | 83 | 84 | #TODO subtituir com o nome do projeto 85 | WSGI_APPLICATION = '@projeto@.wsgi.application' 86 | 87 | 88 | # Database 89 | # https://docs.djangoproject.com/en/1.8/ref/settings/#databases 90 | 91 | 92 | DATABASES = { 93 | 'default': { 94 | 'ENGINE': 'django.db.backends.mysql', 95 | 'NAME': '@NAME@', 96 | 'USER': '@USER@', 97 | 'PASSWORD': '@PASSWORD@', 98 | 'HOST': '@HOST@', 99 | 'PORT': '3306', 100 | } 101 | } 102 | 103 | #Django Restframework configuration 104 | REST_FRAMEWORK = { 105 | 106 | 'DEFAULT_AUTHENTICATION_CLASSES': ( 107 | #'oauth2_provider.ext.rest_framework.OAuth2Authentication', 108 | #'rest_framework.authentication.BasicAuthentication', 109 | #'rest_framework.authentication.SessionAuthentication', 110 | 'rest_framework.authentication.TokenAuthentication', 111 | ), 112 | 113 | 'DEFAULT_PERMISSION_CLASSES':( 114 | 'rest_framework.permissions.IsAuthenticated', 115 | ), 116 | 117 | 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', 118 | 'PAGE_SIZE': 10 119 | } 120 | 121 | OAUTH2_PROVIDER = { 122 | # this is the list of available scopes 123 | 'SCOPES': {'read': 'Read scope', 'write': 'Write scope', 'groups': 'Access to your groups'} 124 | } 125 | 126 | EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' 127 | # EMAIL_BACKEND = 'django_smtp_ssl.SSLEmailBackend:wq' 128 | 129 | 130 | if DEBUG: 131 | EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' 132 | 133 | # To test emails send by Google 134 | EMAIL_USE_TLS = True 135 | EMAIL_HOST = 'smtp.gmail.com' 136 | EMAIL_PORT = 587 137 | EMAIL_HOST_USER = 'linuxloco@gmail.com' 138 | EMAIL_HOST_PASSWORD = '' 139 | SERVER_EMAIL = 'linuxloco@gmail.com' 140 | DEFAULT_FROM_EMAIL = 'linuxloco@gmail.com' 141 | 142 | 143 | # To use with http://swagger.io/ 144 | SWAGGER_SETTINGS = { 145 | 'exclude_namespaces': [], 146 | 'api_version': '', 147 | 'api_path': '/', 148 | 'enabled_methods': [ 149 | 'get', 150 | 'post', 151 | 'put', 152 | 'patch', 153 | 'delete' 154 | ], 155 | 'api_key': '', 156 | 'is_authenticated': False, 157 | 'is_superuser': False, 158 | 'permission_denied_handler': None, 159 | 'info': { 160 | 'contact': '', 161 | 'description': '', 162 | 'title': '@projeto@', 163 | }, 164 | 'doc_expansion': 'none', 165 | } 166 | 167 | 168 | # Internationalization 169 | # https://docs.djangoproject.com/en/1.8/topics/i18n/ 170 | 171 | LANGUAGE_CODE = 'pt-BR' 172 | 173 | TIME_ZONE = 'America/Sao_Paulo' 174 | 175 | USE_I18N = True 176 | 177 | USE_L10N = True 178 | 179 | USE_TZ = True 180 | 181 | CORS_ORIGIN_ALLOW_ALL = True 182 | 183 | # Password validation 184 | # https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators 185 | 186 | AUTH_PASSWORD_VALIDATORS = [ 187 | { 188 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 189 | }, 190 | { 191 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 192 | }, 193 | { 194 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 195 | }, 196 | { 197 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 198 | }, 199 | ] 200 | 201 | # Static files (CSS, JavaScript, Images) 202 | # https://docs.djangoproject.com/en/1.10/howto/static-files/ 203 | 204 | STATIC_URL = '/static/' 205 | 206 | 207 | -------------------------------------------------------------------------------- /tests/test_robot.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import unittest 5 | 6 | 7 | class TestDrfGen(unittest.TestCase): 8 | ''' 9 | Test basic of main methods 10 | ''' 11 | def test_create_serializers(self): 12 | pass 13 | #self.assertEqual(make_serializers(outdir), True) 14 | 15 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | envlist = 3 | {py27,py34,pypy,pypy3}-django{18} 4 | 5 | [testenv] 6 | basepython = 7 | py27: python2.7 8 | py34: python3.4 9 | pypy: pypy 10 | pypy3: pypy3 11 | setenv = 12 | PYTHONPATH = {toxinidir} 13 | commands = 14 | make install-quite 15 | pip freeze 16 | make check 17 | deps = 18 | django16: django<1.7 19 | django17: django<1.8 20 | django18: django<1.9 21 | whitelist_externals = 22 | make 23 | 24 | [flake8] 25 | ignore = E501s --------------------------------------------------------------------------------