├── .gitignore
├── .idea
├── $CACHE_FILE$
├── .gitignore
├── dataSources.xml
├── dictionaries
│ └── mkennedy.xml
├── inspectionProfiles
│ └── profiles_settings.xml
├── misc.xml
├── modules.xml
├── ten-tips-python-web-devs.iml
├── vagrant.xml
└── vcs.xml
├── LICENSE
├── README.md
├── code
├── data
│ └── pypi-top-100
│ │ ├── amqp.json
│ │ ├── appdirs.json
│ │ ├── argparse.json
│ │ ├── asn1crypto.json
│ │ ├── awscli-cwlogs.json
│ │ ├── awscli.json
│ │ ├── babel.json
│ │ ├── beautifulsoup4.json
│ │ ├── boto.json
│ │ ├── boto3.json
│ │ ├── botocore.json
│ │ ├── certifi.json
│ │ ├── cffi.json
│ │ ├── chardet.json
│ │ ├── click.json
│ │ ├── colorama.json
│ │ ├── coverage.json
│ │ ├── cryptography.json
│ │ ├── cython.json
│ │ ├── decorator.json
│ │ ├── django.json
│ │ ├── docopt.json
│ │ ├── docutils.json
│ │ ├── elasticsearch.json
│ │ ├── enum34.json
│ │ ├── flake8.json
│ │ ├── flask.json
│ │ ├── funcsigs.json
│ │ ├── functools32.json
│ │ ├── future.json
│ │ ├── futures.json
│ │ ├── gevent.json
│ │ ├── greenlet.json
│ │ ├── gunicorn.json
│ │ ├── httplib2.json
│ │ ├── idna.json
│ │ ├── ipaddress.json
│ │ ├── ipython.json
│ │ ├── itsdangerous.json
│ │ ├── jinja2.json
│ │ ├── jmespath.json
│ │ ├── jsonschema.json
│ │ ├── kombu.json
│ │ ├── lxml.json
│ │ ├── markupsafe.json
│ │ ├── mccabe.json
│ │ ├── mock.json
│ │ ├── nose.json
│ │ ├── numpy.json
│ │ ├── oauth2client.json
│ │ ├── packaging.json
│ │ ├── pandas.json
│ │ ├── paramiko.json
│ │ ├── pbr.json
│ │ ├── pep8.json
│ │ ├── pexpect.json
│ │ ├── pillow.json
│ │ ├── pip.json
│ │ ├── protobuf.json
│ │ ├── psutil.json
│ │ ├── psycopg2.json
│ │ ├── ptyprocess.json
│ │ ├── py.json
│ │ ├── pyasn1-modules.json
│ │ ├── pyasn1.json
│ │ ├── pycodestyle.json
│ │ ├── pycparser.json
│ │ ├── pycrypto.json
│ │ ├── pyflakes.json
│ │ ├── pygments.json
│ │ ├── pyopenssl.json
│ │ ├── pyparsing.json
│ │ ├── pytest-runner.json
│ │ ├── pytest.json
│ │ ├── python-dateutil.json
│ │ ├── pytz.json
│ │ ├── pyyaml.json
│ │ ├── redis.json
│ │ ├── requests.json
│ │ ├── rsa.json
│ │ ├── s3transfer.json
│ │ ├── scipy.json
│ │ ├── selenium.json
│ │ ├── setuptools.json
│ │ ├── simplejson.json
│ │ ├── singledispatch.json
│ │ ├── six.json
│ │ ├── sqlalchemy.json
│ │ ├── tornado.json
│ │ ├── urllib3.json
│ │ ├── vcversioner.json
│ │ ├── virtualenv.json
│ │ ├── websocket-client.json
│ │ ├── werkzeug.json
│ │ ├── wheel.json
│ │ └── wrapt.json
├── ex01_html_forms
│ ├── extras
│ │ ├── form.css
│ │ ├── form_hook.js
│ │ └── site.css
│ └── index.html
├── ex02_ngrok
│ └── pypi_org
│ │ ├── app.py
│ │ ├── data
│ │ ├── __all_models.py
│ │ ├── __init__.py
│ │ ├── auditing.py
│ │ ├── db_session.py
│ │ ├── downloads.py
│ │ ├── languages.py
│ │ ├── licenses.py
│ │ ├── maintainers.py
│ │ ├── modelbase.py
│ │ ├── package.py
│ │ ├── packages.py
│ │ ├── releases.py
│ │ └── users.py
│ │ ├── db
│ │ ├── placeholder.txt
│ │ └── pypi.sqlite
│ │ ├── infrastructure
│ │ └── view_modifiers.py
│ │ ├── services
│ │ ├── cms_service.py
│ │ └── package_service.py
│ │ ├── static
│ │ ├── css
│ │ │ ├── nav.css
│ │ │ └── site.css
│ │ └── img
│ │ │ ├── blue-cube.svg
│ │ │ ├── favicon.png
│ │ │ ├── pypi-logo.svg
│ │ │ └── white-cube.svg
│ │ ├── templates
│ │ ├── cms
│ │ │ └── page.html
│ │ ├── home
│ │ │ ├── about.html
│ │ │ └── index.html
│ │ ├── packages
│ │ │ └── details.html
│ │ └── shared
│ │ │ └── _layout.html
│ │ └── views
│ │ ├── account_views.py
│ │ ├── cms_views.py
│ │ ├── home_views.py
│ │ └── package_views.py
├── ex03_async_core
│ └── program.py
├── ex04_async_web
│ ├── app.py
│ ├── config
│ │ ├── dev.json
│ │ ├── prod.json
│ │ └── settings.py
│ ├── services
│ │ ├── event_service.py
│ │ ├── location_service.py
│ │ ├── sun_service.py
│ │ └── weather_service.py
│ └── views
│ │ ├── city_api.py
│ │ └── home.py
├── ex05_migrations
│ ├── alembic.ini
│ ├── alembic
│ │ ├── README
│ │ ├── env.py
│ │ └── script.py.mako
│ ├── pypi_org
│ │ ├── __init__.py
│ │ ├── app.py
│ │ ├── data
│ │ │ ├── __all_models.py
│ │ │ ├── __init__.py
│ │ │ ├── db_session.py
│ │ │ ├── downloads.py
│ │ │ ├── languages.py
│ │ │ ├── licenses.py
│ │ │ ├── maintainers.py
│ │ │ ├── modelbase.py
│ │ │ ├── package.py
│ │ │ ├── releases.py
│ │ │ └── users.py
│ │ ├── db
│ │ │ ├── __init__.py
│ │ │ ├── placeholder.txt
│ │ │ └── pypi.sqlite
│ │ ├── infrastructure
│ │ │ ├── __init__.py
│ │ │ └── view_modifiers.py
│ │ ├── services
│ │ │ ├── __init__.py
│ │ │ ├── cms_service.py
│ │ │ ├── package_service.py
│ │ │ └── user_service.py
│ │ ├── static
│ │ │ ├── css
│ │ │ │ ├── nav.css
│ │ │ │ └── site.css
│ │ │ └── img
│ │ │ │ ├── blue-cube.svg
│ │ │ │ ├── favicon.png
│ │ │ │ ├── pypi-logo.svg
│ │ │ │ └── white-cube.svg
│ │ ├── templates
│ │ │ ├── cms
│ │ │ │ └── page.html
│ │ │ ├── home
│ │ │ │ ├── about.html
│ │ │ │ └── index.html
│ │ │ ├── packages
│ │ │ │ └── details.html
│ │ │ └── shared
│ │ │ │ └── _layout.html
│ │ └── views
│ │ │ ├── __init__.py
│ │ │ ├── account_views.py
│ │ │ ├── cms_views.py
│ │ │ ├── home_views.py
│ │ │ └── package_views.py
│ └── setup.py
├── ex06_vue
│ └── movie_exploder
│ │ ├── css
│ │ ├── bootstrap
│ │ │ ├── css
│ │ │ │ ├── bootstrap-grid.css
│ │ │ │ ├── bootstrap-grid.min.css
│ │ │ │ ├── bootstrap-reboot.css
│ │ │ │ ├── bootstrap-reboot.min.css
│ │ │ │ ├── bootstrap.css
│ │ │ │ └── bootstrap.min.css
│ │ │ └── js
│ │ │ │ ├── bootstrap.bundle.js
│ │ │ │ ├── bootstrap.bundle.min.js
│ │ │ │ ├── bootstrap.js
│ │ │ │ └── bootstrap.min.js
│ │ ├── dropdown.css
│ │ └── site.css
│ │ ├── js
│ │ ├── dropdown.js
│ │ ├── fake_data.js
│ │ ├── site.js
│ │ └── vue
│ │ │ ├── README.md
│ │ │ ├── vue.common.dev.js
│ │ │ ├── vue.common.js
│ │ │ ├── vue.common.prod.js
│ │ │ ├── vue.esm.browser.js
│ │ │ ├── vue.esm.browser.min.js
│ │ │ ├── vue.esm.js
│ │ │ ├── vue.js
│ │ │ ├── vue.min.js
│ │ │ ├── vue.runtime.common.dev.js
│ │ │ ├── vue.runtime.common.js
│ │ │ ├── vue.runtime.common.prod.js
│ │ │ ├── vue.runtime.esm.js
│ │ │ ├── vue.runtime.js
│ │ │ └── vue.runtime.min.js
│ │ ├── node_modules
│ │ └── vue
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── package.json
│ │ │ ├── src
│ │ │ ├── compiler
│ │ │ │ ├── codeframe.js
│ │ │ │ ├── codegen
│ │ │ │ │ ├── events.js
│ │ │ │ │ └── index.js
│ │ │ │ ├── create-compiler.js
│ │ │ │ ├── directives
│ │ │ │ │ ├── bind.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── model.js
│ │ │ │ │ └── on.js
│ │ │ │ ├── error-detector.js
│ │ │ │ ├── helpers.js
│ │ │ │ ├── index.js
│ │ │ │ ├── optimizer.js
│ │ │ │ ├── parser
│ │ │ │ │ ├── entity-decoder.js
│ │ │ │ │ ├── filter-parser.js
│ │ │ │ │ ├── html-parser.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── text-parser.js
│ │ │ │ └── to-function.js
│ │ │ ├── core
│ │ │ │ ├── components
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── keep-alive.js
│ │ │ │ ├── config.js
│ │ │ │ ├── global-api
│ │ │ │ │ ├── assets.js
│ │ │ │ │ ├── extend.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── mixin.js
│ │ │ │ │ └── use.js
│ │ │ │ ├── index.js
│ │ │ │ ├── observer
│ │ │ │ │ ├── array.js
│ │ │ │ │ ├── dep.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── scheduler.js
│ │ │ │ │ ├── traverse.js
│ │ │ │ │ └── watcher.js
│ │ │ │ ├── util
│ │ │ │ │ ├── debug.js
│ │ │ │ │ ├── env.js
│ │ │ │ │ ├── error.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── lang.js
│ │ │ │ │ ├── next-tick.js
│ │ │ │ │ ├── options.js
│ │ │ │ │ ├── perf.js
│ │ │ │ │ └── props.js
│ │ │ │ └── vdom
│ │ │ │ │ ├── create-component.js
│ │ │ │ │ ├── create-element.js
│ │ │ │ │ ├── create-functional-component.js
│ │ │ │ │ ├── helpers
│ │ │ │ │ ├── extract-props.js
│ │ │ │ │ ├── get-first-component-child.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── is-async-placeholder.js
│ │ │ │ │ ├── merge-hook.js
│ │ │ │ │ ├── normalize-children.js
│ │ │ │ │ ├── normalize-scoped-slots.js
│ │ │ │ │ ├── resolve-async-component.js
│ │ │ │ │ └── update-listeners.js
│ │ │ │ │ ├── modules
│ │ │ │ │ ├── directives.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── ref.js
│ │ │ │ │ ├── patch.js
│ │ │ │ │ └── vnode.js
│ │ │ ├── platforms
│ │ │ │ ├── web
│ │ │ │ │ ├── compiler
│ │ │ │ │ │ ├── directives
│ │ │ │ │ │ │ ├── html.js
│ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ ├── model.js
│ │ │ │ │ │ │ └── text.js
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── modules
│ │ │ │ │ │ │ ├── class.js
│ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ ├── model.js
│ │ │ │ │ │ │ └── style.js
│ │ │ │ │ │ ├── options.js
│ │ │ │ │ │ └── util.js
│ │ │ │ │ ├── entry-compiler.js
│ │ │ │ │ ├── entry-runtime-with-compiler.js
│ │ │ │ │ ├── entry-runtime.js
│ │ │ │ │ ├── entry-server-basic-renderer.js
│ │ │ │ │ ├── entry-server-renderer.js
│ │ │ │ │ ├── runtime
│ │ │ │ │ │ ├── class-util.js
│ │ │ │ │ │ ├── components
│ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ ├── transition-group.js
│ │ │ │ │ │ │ └── transition.js
│ │ │ │ │ │ ├── directives
│ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ ├── model.js
│ │ │ │ │ │ │ └── show.js
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── modules
│ │ │ │ │ │ │ ├── attrs.js
│ │ │ │ │ │ │ ├── class.js
│ │ │ │ │ │ │ ├── dom-props.js
│ │ │ │ │ │ │ ├── events.js
│ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ ├── style.js
│ │ │ │ │ │ │ └── transition.js
│ │ │ │ │ │ ├── node-ops.js
│ │ │ │ │ │ ├── patch.js
│ │ │ │ │ │ └── transition-util.js
│ │ │ │ │ ├── server
│ │ │ │ │ │ ├── compiler.js
│ │ │ │ │ │ ├── directives
│ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ ├── model.js
│ │ │ │ │ │ │ └── show.js
│ │ │ │ │ │ ├── modules
│ │ │ │ │ │ │ ├── attrs.js
│ │ │ │ │ │ │ ├── class.js
│ │ │ │ │ │ │ ├── dom-props.js
│ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ └── style.js
│ │ │ │ │ │ └── util.js
│ │ │ │ │ └── util
│ │ │ │ │ │ ├── attrs.js
│ │ │ │ │ │ ├── class.js
│ │ │ │ │ │ ├── compat.js
│ │ │ │ │ │ ├── element.js
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ └── style.js
│ │ │ │ └── weex
│ │ │ │ │ ├── compiler
│ │ │ │ │ ├── directives
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ └── model.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── modules
│ │ │ │ │ │ ├── append.js
│ │ │ │ │ │ ├── class.js
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── props.js
│ │ │ │ │ │ ├── recycle-list
│ │ │ │ │ │ ├── component-root.js
│ │ │ │ │ │ ├── component.js
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── recycle-list.js
│ │ │ │ │ │ ├── text.js
│ │ │ │ │ │ ├── v-bind.js
│ │ │ │ │ │ ├── v-for.js
│ │ │ │ │ │ ├── v-if.js
│ │ │ │ │ │ ├── v-on.js
│ │ │ │ │ │ └── v-once.js
│ │ │ │ │ │ └── style.js
│ │ │ │ │ ├── entry-compiler.js
│ │ │ │ │ ├── entry-framework.js
│ │ │ │ │ ├── entry-runtime-factory.js
│ │ │ │ │ ├── runtime
│ │ │ │ │ ├── components
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── richtext.js
│ │ │ │ │ │ ├── transition-group.js
│ │ │ │ │ │ └── transition.js
│ │ │ │ │ ├── directives
│ │ │ │ │ │ └── index.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── modules
│ │ │ │ │ │ ├── attrs.js
│ │ │ │ │ │ ├── class.js
│ │ │ │ │ │ ├── events.js
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── style.js
│ │ │ │ │ │ └── transition.js
│ │ │ │ │ ├── node-ops.js
│ │ │ │ │ ├── patch.js
│ │ │ │ │ ├── recycle-list
│ │ │ │ │ │ ├── render-component-template.js
│ │ │ │ │ │ └── virtual-component.js
│ │ │ │ │ └── text-node.js
│ │ │ │ │ └── util
│ │ │ │ │ ├── element.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── parser.js
│ │ │ ├── server
│ │ │ │ ├── bundle-renderer
│ │ │ │ │ ├── create-bundle-renderer.js
│ │ │ │ │ ├── create-bundle-runner.js
│ │ │ │ │ └── source-map-support.js
│ │ │ │ ├── create-basic-renderer.js
│ │ │ │ ├── create-renderer.js
│ │ │ │ ├── optimizing-compiler
│ │ │ │ │ ├── codegen.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── modules.js
│ │ │ │ │ ├── optimizer.js
│ │ │ │ │ └── runtime-helpers.js
│ │ │ │ ├── render-context.js
│ │ │ │ ├── render-stream.js
│ │ │ │ ├── render.js
│ │ │ │ ├── template-renderer
│ │ │ │ │ ├── create-async-file-mapper.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── parse-template.js
│ │ │ │ │ └── template-stream.js
│ │ │ │ ├── util.js
│ │ │ │ ├── webpack-plugin
│ │ │ │ │ ├── client.js
│ │ │ │ │ ├── server.js
│ │ │ │ │ └── util.js
│ │ │ │ └── write.js
│ │ │ ├── sfc
│ │ │ │ └── parser.js
│ │ │ └── shared
│ │ │ │ ├── constants.js
│ │ │ │ └── util.js
│ │ │ └── types
│ │ │ ├── index.d.ts
│ │ │ ├── options.d.ts
│ │ │ ├── plugin.d.ts
│ │ │ ├── vnode.d.ts
│ │ │ └── vue.d.ts
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ └── views
│ │ └── index.html
├── ex07_viewmodels
│ ├── alembic.ini
│ ├── pypi_vm
│ │ ├── __init__.py
│ │ ├── app.py
│ │ ├── config.py
│ │ ├── data
│ │ │ ├── __all_models.py
│ │ │ ├── __init__.py
│ │ │ ├── auditing.py
│ │ │ ├── db_session.py
│ │ │ ├── downloads.py
│ │ │ ├── languages.py
│ │ │ ├── maintainers.py
│ │ │ ├── modelbase.py
│ │ │ ├── packages.py
│ │ │ ├── releases.py
│ │ │ └── users.py
│ │ ├── db
│ │ │ └── pypi.sqlite
│ │ ├── infrastructure
│ │ │ ├── __init__.py
│ │ │ ├── cookie_auth.py
│ │ │ ├── number_utils.py
│ │ │ ├── request_dict.py
│ │ │ └── view_modifiers.py
│ │ ├── services
│ │ │ ├── __init__.py
│ │ │ ├── package_service.py
│ │ │ └── user_service.py
│ │ ├── static
│ │ │ ├── css
│ │ │ │ ├── account.css
│ │ │ │ ├── home.css
│ │ │ │ ├── site.css
│ │ │ │ ├── theme-overrides.css
│ │ │ │ └── theme.css
│ │ │ └── img
│ │ │ │ ├── blue-cube.svg
│ │ │ │ ├── favicon.png
│ │ │ │ ├── pypi-logo.svg
│ │ │ │ └── white-cube.svg
│ │ ├── templates
│ │ │ ├── account
│ │ │ │ ├── index.html
│ │ │ │ ├── login.html
│ │ │ │ └── register.html
│ │ │ ├── cms
│ │ │ │ └── page.html
│ │ │ ├── home
│ │ │ │ └── index.html
│ │ │ ├── packages
│ │ │ │ ├── details.html
│ │ │ │ └── popular.html
│ │ │ ├── seo
│ │ │ │ ├── robots.txt
│ │ │ │ └── sitemap.html
│ │ │ └── shared
│ │ │ │ └── _layout.html
│ │ ├── viewmodels
│ │ │ ├── __init__.py
│ │ │ ├── account
│ │ │ │ ├── account_home_viewmodel.py
│ │ │ │ ├── login_viewmodel.py
│ │ │ │ └── register_viewmodel.py
│ │ │ ├── cms
│ │ │ │ └── page_viewmodel.py
│ │ │ ├── home
│ │ │ │ └── home_index_viewmodel.py
│ │ │ ├── packages
│ │ │ │ ├── package_details_viewmodel.py
│ │ │ │ └── popular_viewmodel.py
│ │ │ ├── shared
│ │ │ │ └── viewmodel_base.py
│ │ │ └── utils
│ │ │ │ └── sitemap_viewmodel.py
│ │ └── views
│ │ │ ├── __init__.py
│ │ │ ├── account_view.py
│ │ │ ├── cms_view.py
│ │ │ ├── home_view.py
│ │ │ ├── packages_view.py
│ │ │ └── seo_view.py
│ ├── server
│ │ ├── pypi.nginx
│ │ ├── pypi.service
│ │ └── server_setup.sh
│ ├── setup.py
│ └── tests
│ │ ├── _all_tests.py
│ │ ├── account_tests.py
│ │ ├── commands.txt
│ │ ├── home_tests.py
│ │ ├── package_tests.py
│ │ ├── sitemap_tests.py
│ │ └── test_client.py
├── ex08_docker
│ ├── base_server
│ │ └── dockerfile
│ ├── docker-compose.yml
│ ├── frontend
│ │ ├── dockerfile
│ │ ├── movie_exploder
│ │ │ ├── css
│ │ │ │ ├── bootstrap
│ │ │ │ │ ├── css
│ │ │ │ │ │ ├── bootstrap-grid.css
│ │ │ │ │ │ ├── bootstrap-grid.min.css
│ │ │ │ │ │ ├── bootstrap-reboot.css
│ │ │ │ │ │ ├── bootstrap-reboot.min.css
│ │ │ │ │ │ ├── bootstrap.css
│ │ │ │ │ │ └── bootstrap.min.css
│ │ │ │ │ └── js
│ │ │ │ │ │ ├── bootstrap.bundle.js
│ │ │ │ │ │ ├── bootstrap.bundle.min.js
│ │ │ │ │ │ ├── bootstrap.js
│ │ │ │ │ │ └── bootstrap.min.js
│ │ │ │ ├── dropdown.css
│ │ │ │ └── site.css
│ │ │ ├── js
│ │ │ │ ├── dropdown.js
│ │ │ │ ├── fake_data.js
│ │ │ │ ├── site.js
│ │ │ │ └── vue
│ │ │ │ │ ├── README.md
│ │ │ │ │ ├── vue.common.dev.js
│ │ │ │ │ ├── vue.common.js
│ │ │ │ │ ├── vue.common.prod.js
│ │ │ │ │ ├── vue.esm.browser.js
│ │ │ │ │ ├── vue.esm.browser.min.js
│ │ │ │ │ ├── vue.esm.js
│ │ │ │ │ ├── vue.js
│ │ │ │ │ ├── vue.min.js
│ │ │ │ │ ├── vue.runtime.common.dev.js
│ │ │ │ │ ├── vue.runtime.common.js
│ │ │ │ │ ├── vue.runtime.common.prod.js
│ │ │ │ │ ├── vue.runtime.esm.js
│ │ │ │ │ ├── vue.runtime.js
│ │ │ │ │ └── vue.runtime.min.js
│ │ │ ├── node_modules
│ │ │ │ └── vue
│ │ │ │ │ ├── LICENSE
│ │ │ │ │ ├── README.md
│ │ │ │ │ ├── package.json
│ │ │ │ │ ├── src
│ │ │ │ │ ├── compiler
│ │ │ │ │ │ ├── codeframe.js
│ │ │ │ │ │ ├── codegen
│ │ │ │ │ │ │ ├── events.js
│ │ │ │ │ │ │ └── index.js
│ │ │ │ │ │ ├── create-compiler.js
│ │ │ │ │ │ ├── directives
│ │ │ │ │ │ │ ├── bind.js
│ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ ├── model.js
│ │ │ │ │ │ │ └── on.js
│ │ │ │ │ │ ├── error-detector.js
│ │ │ │ │ │ ├── helpers.js
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── optimizer.js
│ │ │ │ │ │ ├── parser
│ │ │ │ │ │ │ ├── entity-decoder.js
│ │ │ │ │ │ │ ├── filter-parser.js
│ │ │ │ │ │ │ ├── html-parser.js
│ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ └── text-parser.js
│ │ │ │ │ │ └── to-function.js
│ │ │ │ │ ├── core
│ │ │ │ │ │ ├── components
│ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ └── keep-alive.js
│ │ │ │ │ │ ├── config.js
│ │ │ │ │ │ ├── global-api
│ │ │ │ │ │ │ ├── assets.js
│ │ │ │ │ │ │ ├── extend.js
│ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ ├── mixin.js
│ │ │ │ │ │ │ └── use.js
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── observer
│ │ │ │ │ │ │ ├── array.js
│ │ │ │ │ │ │ ├── dep.js
│ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ ├── scheduler.js
│ │ │ │ │ │ │ ├── traverse.js
│ │ │ │ │ │ │ └── watcher.js
│ │ │ │ │ │ ├── util
│ │ │ │ │ │ │ ├── debug.js
│ │ │ │ │ │ │ ├── env.js
│ │ │ │ │ │ │ ├── error.js
│ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ ├── lang.js
│ │ │ │ │ │ │ ├── next-tick.js
│ │ │ │ │ │ │ ├── options.js
│ │ │ │ │ │ │ ├── perf.js
│ │ │ │ │ │ │ └── props.js
│ │ │ │ │ │ └── vdom
│ │ │ │ │ │ │ ├── create-component.js
│ │ │ │ │ │ │ ├── create-element.js
│ │ │ │ │ │ │ ├── create-functional-component.js
│ │ │ │ │ │ │ ├── helpers
│ │ │ │ │ │ │ ├── extract-props.js
│ │ │ │ │ │ │ ├── get-first-component-child.js
│ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ ├── is-async-placeholder.js
│ │ │ │ │ │ │ ├── merge-hook.js
│ │ │ │ │ │ │ ├── normalize-children.js
│ │ │ │ │ │ │ ├── normalize-scoped-slots.js
│ │ │ │ │ │ │ ├── resolve-async-component.js
│ │ │ │ │ │ │ └── update-listeners.js
│ │ │ │ │ │ │ ├── modules
│ │ │ │ │ │ │ ├── directives.js
│ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ └── ref.js
│ │ │ │ │ │ │ ├── patch.js
│ │ │ │ │ │ │ └── vnode.js
│ │ │ │ │ ├── platforms
│ │ │ │ │ │ ├── web
│ │ │ │ │ │ │ ├── compiler
│ │ │ │ │ │ │ │ ├── directives
│ │ │ │ │ │ │ │ │ ├── html.js
│ │ │ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ │ │ ├── model.js
│ │ │ │ │ │ │ │ │ └── text.js
│ │ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ │ ├── modules
│ │ │ │ │ │ │ │ │ ├── class.js
│ │ │ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ │ │ ├── model.js
│ │ │ │ │ │ │ │ │ └── style.js
│ │ │ │ │ │ │ │ ├── options.js
│ │ │ │ │ │ │ │ └── util.js
│ │ │ │ │ │ │ ├── entry-compiler.js
│ │ │ │ │ │ │ ├── entry-runtime-with-compiler.js
│ │ │ │ │ │ │ ├── entry-runtime.js
│ │ │ │ │ │ │ ├── entry-server-basic-renderer.js
│ │ │ │ │ │ │ ├── entry-server-renderer.js
│ │ │ │ │ │ │ ├── runtime
│ │ │ │ │ │ │ │ ├── class-util.js
│ │ │ │ │ │ │ │ ├── components
│ │ │ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ │ │ ├── transition-group.js
│ │ │ │ │ │ │ │ │ └── transition.js
│ │ │ │ │ │ │ │ ├── directives
│ │ │ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ │ │ ├── model.js
│ │ │ │ │ │ │ │ │ └── show.js
│ │ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ │ ├── modules
│ │ │ │ │ │ │ │ │ ├── attrs.js
│ │ │ │ │ │ │ │ │ ├── class.js
│ │ │ │ │ │ │ │ │ ├── dom-props.js
│ │ │ │ │ │ │ │ │ ├── events.js
│ │ │ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ │ │ ├── style.js
│ │ │ │ │ │ │ │ │ └── transition.js
│ │ │ │ │ │ │ │ ├── node-ops.js
│ │ │ │ │ │ │ │ ├── patch.js
│ │ │ │ │ │ │ │ └── transition-util.js
│ │ │ │ │ │ │ ├── server
│ │ │ │ │ │ │ │ ├── compiler.js
│ │ │ │ │ │ │ │ ├── directives
│ │ │ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ │ │ ├── model.js
│ │ │ │ │ │ │ │ │ └── show.js
│ │ │ │ │ │ │ │ ├── modules
│ │ │ │ │ │ │ │ │ ├── attrs.js
│ │ │ │ │ │ │ │ │ ├── class.js
│ │ │ │ │ │ │ │ │ ├── dom-props.js
│ │ │ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ │ │ └── style.js
│ │ │ │ │ │ │ │ └── util.js
│ │ │ │ │ │ │ └── util
│ │ │ │ │ │ │ │ ├── attrs.js
│ │ │ │ │ │ │ │ ├── class.js
│ │ │ │ │ │ │ │ ├── compat.js
│ │ │ │ │ │ │ │ ├── element.js
│ │ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ │ └── style.js
│ │ │ │ │ │ └── weex
│ │ │ │ │ │ │ ├── compiler
│ │ │ │ │ │ │ ├── directives
│ │ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ │ └── model.js
│ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ └── modules
│ │ │ │ │ │ │ │ ├── append.js
│ │ │ │ │ │ │ │ ├── class.js
│ │ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ │ ├── props.js
│ │ │ │ │ │ │ │ ├── recycle-list
│ │ │ │ │ │ │ │ ├── component-root.js
│ │ │ │ │ │ │ │ ├── component.js
│ │ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ │ ├── recycle-list.js
│ │ │ │ │ │ │ │ ├── text.js
│ │ │ │ │ │ │ │ ├── v-bind.js
│ │ │ │ │ │ │ │ ├── v-for.js
│ │ │ │ │ │ │ │ ├── v-if.js
│ │ │ │ │ │ │ │ ├── v-on.js
│ │ │ │ │ │ │ │ └── v-once.js
│ │ │ │ │ │ │ │ └── style.js
│ │ │ │ │ │ │ ├── entry-compiler.js
│ │ │ │ │ │ │ ├── entry-framework.js
│ │ │ │ │ │ │ ├── entry-runtime-factory.js
│ │ │ │ │ │ │ ├── runtime
│ │ │ │ │ │ │ ├── components
│ │ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ │ ├── richtext.js
│ │ │ │ │ │ │ │ ├── transition-group.js
│ │ │ │ │ │ │ │ └── transition.js
│ │ │ │ │ │ │ ├── directives
│ │ │ │ │ │ │ │ └── index.js
│ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ ├── modules
│ │ │ │ │ │ │ │ ├── attrs.js
│ │ │ │ │ │ │ │ ├── class.js
│ │ │ │ │ │ │ │ ├── events.js
│ │ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ │ ├── style.js
│ │ │ │ │ │ │ │ └── transition.js
│ │ │ │ │ │ │ ├── node-ops.js
│ │ │ │ │ │ │ ├── patch.js
│ │ │ │ │ │ │ ├── recycle-list
│ │ │ │ │ │ │ │ ├── render-component-template.js
│ │ │ │ │ │ │ │ └── virtual-component.js
│ │ │ │ │ │ │ └── text-node.js
│ │ │ │ │ │ │ └── util
│ │ │ │ │ │ │ ├── element.js
│ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ └── parser.js
│ │ │ │ │ ├── server
│ │ │ │ │ │ ├── bundle-renderer
│ │ │ │ │ │ │ ├── create-bundle-renderer.js
│ │ │ │ │ │ │ ├── create-bundle-runner.js
│ │ │ │ │ │ │ └── source-map-support.js
│ │ │ │ │ │ ├── create-basic-renderer.js
│ │ │ │ │ │ ├── create-renderer.js
│ │ │ │ │ │ ├── optimizing-compiler
│ │ │ │ │ │ │ ├── codegen.js
│ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ ├── modules.js
│ │ │ │ │ │ │ ├── optimizer.js
│ │ │ │ │ │ │ └── runtime-helpers.js
│ │ │ │ │ │ ├── render-context.js
│ │ │ │ │ │ ├── render-stream.js
│ │ │ │ │ │ ├── render.js
│ │ │ │ │ │ ├── template-renderer
│ │ │ │ │ │ │ ├── create-async-file-mapper.js
│ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ ├── parse-template.js
│ │ │ │ │ │ │ └── template-stream.js
│ │ │ │ │ │ ├── util.js
│ │ │ │ │ │ ├── webpack-plugin
│ │ │ │ │ │ │ ├── client.js
│ │ │ │ │ │ │ ├── server.js
│ │ │ │ │ │ │ └── util.js
│ │ │ │ │ │ └── write.js
│ │ │ │ │ ├── sfc
│ │ │ │ │ │ └── parser.js
│ │ │ │ │ └── shared
│ │ │ │ │ │ ├── constants.js
│ │ │ │ │ │ └── util.js
│ │ │ │ │ └── types
│ │ │ │ │ ├── index.d.ts
│ │ │ │ │ ├── options.d.ts
│ │ │ │ │ ├── plugin.d.ts
│ │ │ │ │ ├── vnode.d.ts
│ │ │ │ │ └── vue.d.ts
│ │ │ ├── package-lock.json
│ │ │ ├── package.json
│ │ │ └── views
│ │ │ │ └── index.html
│ │ └── site.nginx
│ └── services
│ │ ├── dockerfile
│ │ └── movie_svc
│ │ ├── app.py
│ │ ├── app_instance.py
│ │ ├── data
│ │ ├── db.py
│ │ └── movies.csv
│ │ ├── requirements.txt
│ │ ├── routes.py
│ │ ├── static
│ │ └── css
│ │ │ ├── docs.css
│ │ │ └── theme.css
│ │ ├── templates
│ │ ├── home
│ │ │ └── index.html
│ │ └── shared
│ │ │ └── _layout.html
│ │ └── views
│ │ ├── api_views.py
│ │ └── home.py
├── ex09_lets_encrypt
│ ├── make_secure.sh
│ └── server_setup.sh
├── ex10_securepy
│ ├── pypi_secure
│ │ ├── __init__.py
│ │ ├── app.py
│ │ ├── data
│ │ │ ├── __all_models.py
│ │ │ ├── __init__.py
│ │ │ ├── db_session.py
│ │ │ ├── downloads.py
│ │ │ ├── languages.py
│ │ │ ├── licenses.py
│ │ │ ├── maintainers.py
│ │ │ ├── modelbase.py
│ │ │ ├── package.py
│ │ │ ├── releases.py
│ │ │ └── users.py
│ │ ├── db
│ │ │ ├── __init__.py
│ │ │ ├── placeholder.txt
│ │ │ └── pypi.sqlite
│ │ ├── infrastructure
│ │ │ ├── __init__.py
│ │ │ └── view_modifiers.py
│ │ ├── services
│ │ │ ├── __init__.py
│ │ │ ├── cms_service.py
│ │ │ ├── package_service.py
│ │ │ └── user_service.py
│ │ ├── static
│ │ │ ├── css
│ │ │ │ ├── nav.css
│ │ │ │ └── site.css
│ │ │ └── img
│ │ │ │ ├── blue-cube.svg
│ │ │ │ ├── favicon.png
│ │ │ │ ├── pypi-logo.svg
│ │ │ │ └── white-cube.svg
│ │ ├── templates
│ │ │ ├── cms
│ │ │ │ └── page.html
│ │ │ ├── home
│ │ │ │ ├── about.html
│ │ │ │ └── index.html
│ │ │ ├── packages
│ │ │ │ └── details.html
│ │ │ └── shared
│ │ │ │ └── _layout.html
│ │ └── views
│ │ │ ├── __init__.py
│ │ │ ├── account_views.py
│ │ │ ├── cms_views.py
│ │ │ ├── home_views.py
│ │ │ └── package_views.py
│ └── setup.py
├── node_modules
│ └── vue
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src
│ │ ├── compiler
│ │ │ ├── codeframe.js
│ │ │ ├── codegen
│ │ │ │ ├── events.js
│ │ │ │ └── index.js
│ │ │ ├── create-compiler.js
│ │ │ ├── directives
│ │ │ │ ├── bind.js
│ │ │ │ ├── index.js
│ │ │ │ ├── model.js
│ │ │ │ └── on.js
│ │ │ ├── error-detector.js
│ │ │ ├── helpers.js
│ │ │ ├── index.js
│ │ │ ├── optimizer.js
│ │ │ ├── parser
│ │ │ │ ├── entity-decoder.js
│ │ │ │ ├── filter-parser.js
│ │ │ │ ├── html-parser.js
│ │ │ │ ├── index.js
│ │ │ │ └── text-parser.js
│ │ │ └── to-function.js
│ │ ├── core
│ │ │ ├── components
│ │ │ │ ├── index.js
│ │ │ │ └── keep-alive.js
│ │ │ ├── config.js
│ │ │ ├── global-api
│ │ │ │ ├── assets.js
│ │ │ │ ├── extend.js
│ │ │ │ ├── index.js
│ │ │ │ ├── mixin.js
│ │ │ │ └── use.js
│ │ │ ├── index.js
│ │ │ ├── observer
│ │ │ │ ├── array.js
│ │ │ │ ├── dep.js
│ │ │ │ ├── index.js
│ │ │ │ ├── scheduler.js
│ │ │ │ ├── traverse.js
│ │ │ │ └── watcher.js
│ │ │ ├── util
│ │ │ │ ├── debug.js
│ │ │ │ ├── env.js
│ │ │ │ ├── error.js
│ │ │ │ ├── index.js
│ │ │ │ ├── lang.js
│ │ │ │ ├── next-tick.js
│ │ │ │ ├── options.js
│ │ │ │ ├── perf.js
│ │ │ │ └── props.js
│ │ │ └── vdom
│ │ │ │ ├── create-component.js
│ │ │ │ ├── create-element.js
│ │ │ │ ├── create-functional-component.js
│ │ │ │ ├── helpers
│ │ │ │ ├── extract-props.js
│ │ │ │ ├── get-first-component-child.js
│ │ │ │ ├── index.js
│ │ │ │ ├── is-async-placeholder.js
│ │ │ │ ├── merge-hook.js
│ │ │ │ ├── normalize-children.js
│ │ │ │ ├── normalize-scoped-slots.js
│ │ │ │ ├── resolve-async-component.js
│ │ │ │ └── update-listeners.js
│ │ │ │ ├── modules
│ │ │ │ ├── directives.js
│ │ │ │ ├── index.js
│ │ │ │ └── ref.js
│ │ │ │ ├── patch.js
│ │ │ │ └── vnode.js
│ │ ├── platforms
│ │ │ ├── web
│ │ │ │ ├── compiler
│ │ │ │ │ ├── directives
│ │ │ │ │ │ ├── html.js
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── model.js
│ │ │ │ │ │ └── text.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── modules
│ │ │ │ │ │ ├── class.js
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── model.js
│ │ │ │ │ │ └── style.js
│ │ │ │ │ ├── options.js
│ │ │ │ │ └── util.js
│ │ │ │ ├── entry-compiler.js
│ │ │ │ ├── entry-runtime-with-compiler.js
│ │ │ │ ├── entry-runtime.js
│ │ │ │ ├── entry-server-basic-renderer.js
│ │ │ │ ├── entry-server-renderer.js
│ │ │ │ ├── runtime
│ │ │ │ │ ├── class-util.js
│ │ │ │ │ ├── components
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── transition-group.js
│ │ │ │ │ │ └── transition.js
│ │ │ │ │ ├── directives
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── model.js
│ │ │ │ │ │ └── show.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── modules
│ │ │ │ │ │ ├── attrs.js
│ │ │ │ │ │ ├── class.js
│ │ │ │ │ │ ├── dom-props.js
│ │ │ │ │ │ ├── events.js
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── style.js
│ │ │ │ │ │ └── transition.js
│ │ │ │ │ ├── node-ops.js
│ │ │ │ │ ├── patch.js
│ │ │ │ │ └── transition-util.js
│ │ │ │ ├── server
│ │ │ │ │ ├── compiler.js
│ │ │ │ │ ├── directives
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── model.js
│ │ │ │ │ │ └── show.js
│ │ │ │ │ ├── modules
│ │ │ │ │ │ ├── attrs.js
│ │ │ │ │ │ ├── class.js
│ │ │ │ │ │ ├── dom-props.js
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ └── style.js
│ │ │ │ │ └── util.js
│ │ │ │ └── util
│ │ │ │ │ ├── attrs.js
│ │ │ │ │ ├── class.js
│ │ │ │ │ ├── compat.js
│ │ │ │ │ ├── element.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── style.js
│ │ │ └── weex
│ │ │ │ ├── compiler
│ │ │ │ ├── directives
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── model.js
│ │ │ │ ├── index.js
│ │ │ │ └── modules
│ │ │ │ │ ├── append.js
│ │ │ │ │ ├── class.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── props.js
│ │ │ │ │ ├── recycle-list
│ │ │ │ │ ├── component-root.js
│ │ │ │ │ ├── component.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── recycle-list.js
│ │ │ │ │ ├── text.js
│ │ │ │ │ ├── v-bind.js
│ │ │ │ │ ├── v-for.js
│ │ │ │ │ ├── v-if.js
│ │ │ │ │ ├── v-on.js
│ │ │ │ │ └── v-once.js
│ │ │ │ │ └── style.js
│ │ │ │ ├── entry-compiler.js
│ │ │ │ ├── entry-framework.js
│ │ │ │ ├── entry-runtime-factory.js
│ │ │ │ ├── runtime
│ │ │ │ ├── components
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── richtext.js
│ │ │ │ │ ├── transition-group.js
│ │ │ │ │ └── transition.js
│ │ │ │ ├── directives
│ │ │ │ │ └── index.js
│ │ │ │ ├── index.js
│ │ │ │ ├── modules
│ │ │ │ │ ├── attrs.js
│ │ │ │ │ ├── class.js
│ │ │ │ │ ├── events.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── style.js
│ │ │ │ │ └── transition.js
│ │ │ │ ├── node-ops.js
│ │ │ │ ├── patch.js
│ │ │ │ ├── recycle-list
│ │ │ │ │ ├── render-component-template.js
│ │ │ │ │ └── virtual-component.js
│ │ │ │ └── text-node.js
│ │ │ │ └── util
│ │ │ │ ├── element.js
│ │ │ │ ├── index.js
│ │ │ │ └── parser.js
│ │ ├── server
│ │ │ ├── bundle-renderer
│ │ │ │ ├── create-bundle-renderer.js
│ │ │ │ ├── create-bundle-runner.js
│ │ │ │ └── source-map-support.js
│ │ │ ├── create-basic-renderer.js
│ │ │ ├── create-renderer.js
│ │ │ ├── optimizing-compiler
│ │ │ │ ├── codegen.js
│ │ │ │ ├── index.js
│ │ │ │ ├── modules.js
│ │ │ │ ├── optimizer.js
│ │ │ │ └── runtime-helpers.js
│ │ │ ├── render-context.js
│ │ │ ├── render-stream.js
│ │ │ ├── render.js
│ │ │ ├── template-renderer
│ │ │ │ ├── create-async-file-mapper.js
│ │ │ │ ├── index.js
│ │ │ │ ├── parse-template.js
│ │ │ │ └── template-stream.js
│ │ │ ├── util.js
│ │ │ ├── webpack-plugin
│ │ │ │ ├── client.js
│ │ │ │ ├── server.js
│ │ │ │ └── util.js
│ │ │ └── write.js
│ │ ├── sfc
│ │ │ └── parser.js
│ │ └── shared
│ │ │ ├── constants.js
│ │ │ └── util.js
│ │ └── types
│ │ ├── index.d.ts
│ │ ├── options.d.ts
│ │ ├── plugin.d.ts
│ │ ├── vnode.d.ts
│ │ └── vue.d.ts
├── package-lock.json
├── package.json
└── requirements.txt
├── node_modules
└── vue
│ ├── LICENSE
│ ├── README.md
│ ├── package.json
│ ├── src
│ ├── compiler
│ │ ├── codeframe.js
│ │ ├── codegen
│ │ │ ├── events.js
│ │ │ └── index.js
│ │ ├── create-compiler.js
│ │ ├── directives
│ │ │ ├── bind.js
│ │ │ ├── index.js
│ │ │ ├── model.js
│ │ │ └── on.js
│ │ ├── error-detector.js
│ │ ├── helpers.js
│ │ ├── index.js
│ │ ├── optimizer.js
│ │ ├── parser
│ │ │ ├── entity-decoder.js
│ │ │ ├── filter-parser.js
│ │ │ ├── html-parser.js
│ │ │ ├── index.js
│ │ │ └── text-parser.js
│ │ └── to-function.js
│ ├── core
│ │ ├── components
│ │ │ ├── index.js
│ │ │ └── keep-alive.js
│ │ ├── config.js
│ │ ├── global-api
│ │ │ ├── assets.js
│ │ │ ├── extend.js
│ │ │ ├── index.js
│ │ │ ├── mixin.js
│ │ │ └── use.js
│ │ ├── index.js
│ │ ├── observer
│ │ │ ├── array.js
│ │ │ ├── dep.js
│ │ │ ├── index.js
│ │ │ ├── scheduler.js
│ │ │ ├── traverse.js
│ │ │ └── watcher.js
│ │ ├── util
│ │ │ ├── debug.js
│ │ │ ├── env.js
│ │ │ ├── error.js
│ │ │ ├── index.js
│ │ │ ├── lang.js
│ │ │ ├── next-tick.js
│ │ │ ├── options.js
│ │ │ ├── perf.js
│ │ │ └── props.js
│ │ └── vdom
│ │ │ ├── create-component.js
│ │ │ ├── create-element.js
│ │ │ ├── create-functional-component.js
│ │ │ ├── helpers
│ │ │ ├── extract-props.js
│ │ │ ├── get-first-component-child.js
│ │ │ ├── index.js
│ │ │ ├── is-async-placeholder.js
│ │ │ ├── merge-hook.js
│ │ │ ├── normalize-children.js
│ │ │ ├── normalize-scoped-slots.js
│ │ │ ├── resolve-async-component.js
│ │ │ └── update-listeners.js
│ │ │ ├── modules
│ │ │ ├── directives.js
│ │ │ ├── index.js
│ │ │ └── ref.js
│ │ │ ├── patch.js
│ │ │ └── vnode.js
│ ├── platforms
│ │ ├── web
│ │ │ ├── compiler
│ │ │ │ ├── directives
│ │ │ │ │ ├── html.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── model.js
│ │ │ │ │ └── text.js
│ │ │ │ ├── index.js
│ │ │ │ ├── modules
│ │ │ │ │ ├── class.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── model.js
│ │ │ │ │ └── style.js
│ │ │ │ ├── options.js
│ │ │ │ └── util.js
│ │ │ ├── entry-compiler.js
│ │ │ ├── entry-runtime-with-compiler.js
│ │ │ ├── entry-runtime.js
│ │ │ ├── entry-server-basic-renderer.js
│ │ │ ├── entry-server-renderer.js
│ │ │ ├── runtime
│ │ │ │ ├── class-util.js
│ │ │ │ ├── components
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── transition-group.js
│ │ │ │ │ └── transition.js
│ │ │ │ ├── directives
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── model.js
│ │ │ │ │ └── show.js
│ │ │ │ ├── index.js
│ │ │ │ ├── modules
│ │ │ │ │ ├── attrs.js
│ │ │ │ │ ├── class.js
│ │ │ │ │ ├── dom-props.js
│ │ │ │ │ ├── events.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── style.js
│ │ │ │ │ └── transition.js
│ │ │ │ ├── node-ops.js
│ │ │ │ ├── patch.js
│ │ │ │ └── transition-util.js
│ │ │ ├── server
│ │ │ │ ├── compiler.js
│ │ │ │ ├── directives
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── model.js
│ │ │ │ │ └── show.js
│ │ │ │ ├── modules
│ │ │ │ │ ├── attrs.js
│ │ │ │ │ ├── class.js
│ │ │ │ │ ├── dom-props.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── style.js
│ │ │ │ └── util.js
│ │ │ └── util
│ │ │ │ ├── attrs.js
│ │ │ │ ├── class.js
│ │ │ │ ├── compat.js
│ │ │ │ ├── element.js
│ │ │ │ ├── index.js
│ │ │ │ └── style.js
│ │ └── weex
│ │ │ ├── compiler
│ │ │ ├── directives
│ │ │ │ ├── index.js
│ │ │ │ └── model.js
│ │ │ ├── index.js
│ │ │ └── modules
│ │ │ │ ├── append.js
│ │ │ │ ├── class.js
│ │ │ │ ├── index.js
│ │ │ │ ├── props.js
│ │ │ │ ├── recycle-list
│ │ │ │ ├── component-root.js
│ │ │ │ ├── component.js
│ │ │ │ ├── index.js
│ │ │ │ ├── recycle-list.js
│ │ │ │ ├── text.js
│ │ │ │ ├── v-bind.js
│ │ │ │ ├── v-for.js
│ │ │ │ ├── v-if.js
│ │ │ │ ├── v-on.js
│ │ │ │ └── v-once.js
│ │ │ │ └── style.js
│ │ │ ├── entry-compiler.js
│ │ │ ├── entry-framework.js
│ │ │ ├── entry-runtime-factory.js
│ │ │ ├── runtime
│ │ │ ├── components
│ │ │ │ ├── index.js
│ │ │ │ ├── richtext.js
│ │ │ │ ├── transition-group.js
│ │ │ │ └── transition.js
│ │ │ ├── directives
│ │ │ │ └── index.js
│ │ │ ├── index.js
│ │ │ ├── modules
│ │ │ │ ├── attrs.js
│ │ │ │ ├── class.js
│ │ │ │ ├── events.js
│ │ │ │ ├── index.js
│ │ │ │ ├── style.js
│ │ │ │ └── transition.js
│ │ │ ├── node-ops.js
│ │ │ ├── patch.js
│ │ │ ├── recycle-list
│ │ │ │ ├── render-component-template.js
│ │ │ │ └── virtual-component.js
│ │ │ └── text-node.js
│ │ │ └── util
│ │ │ ├── element.js
│ │ │ ├── index.js
│ │ │ └── parser.js
│ ├── server
│ │ ├── bundle-renderer
│ │ │ ├── create-bundle-renderer.js
│ │ │ ├── create-bundle-runner.js
│ │ │ └── source-map-support.js
│ │ ├── create-basic-renderer.js
│ │ ├── create-renderer.js
│ │ ├── optimizing-compiler
│ │ │ ├── codegen.js
│ │ │ ├── index.js
│ │ │ ├── modules.js
│ │ │ ├── optimizer.js
│ │ │ └── runtime-helpers.js
│ │ ├── render-context.js
│ │ ├── render-stream.js
│ │ ├── render.js
│ │ ├── template-renderer
│ │ │ ├── create-async-file-mapper.js
│ │ │ ├── index.js
│ │ │ ├── parse-template.js
│ │ │ └── template-stream.js
│ │ ├── util.js
│ │ ├── webpack-plugin
│ │ │ ├── client.js
│ │ │ ├── server.js
│ │ │ └── util.js
│ │ └── write.js
│ ├── sfc
│ │ └── parser.js
│ └── shared
│ │ ├── constants.js
│ │ └── util.js
│ └── types
│ ├── index.d.ts
│ ├── options.d.ts
│ ├── plugin.d.ts
│ ├── vnode.d.ts
│ └── vue.d.ts
├── package-lock.json
├── package.json
└── tools-and-techniques-web.pdf
/.idea/$CACHE_FILE$:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | DeprecationUnit files (systemd)
13 |
14 |
15 | General
16 |
17 |
18 | Python
19 |
20 |
21 | Unit files (systemd)
22 |
23 |
24 |
25 |
26 | Angular
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /workspace.xml
3 | # Datasource local storage ignored files
4 | /dataSources/
5 | /dataSources.local.xml
--------------------------------------------------------------------------------
/.idea/dictionaries/mkennedy.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | aiodns
5 | aiohttp
6 | asyncio
7 | billtrackerprodemo
8 | cchardet
9 | colorama
10 | httpx
11 | nginx
12 | ngrok
13 | passlib
14 | podcast
15 | pytest
16 | sqlalchemy
17 | subcontrols
18 | tablename
19 | uwsgi
20 |
21 |
22 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/vagrant.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ten-tips-python-web-devs
--------------------------------------------------------------------------------
/code/ex01_html_forms/extras/form_hook.js:
--------------------------------------------------------------------------------
1 | $(document).ready(function () {
2 |
3 | $("form").submit(function (e) {
4 | e.preventDefault()
5 |
6 | const $inputs = $('form :input');
7 |
8 | let values = {}
9 | $inputs.each(function () {
10 | if (this.name) {
11 | values[this.name] = $(this).val();
12 | }
13 | })
14 |
15 | alert(JSON.stringify(values, null, 2))
16 |
17 | return false
18 | })
19 | })
20 |
--------------------------------------------------------------------------------
/code/ex01_html_forms/extras/site.css:
--------------------------------------------------------------------------------
1 |
2 | form {
3 | margin-left: auto;
4 | margin-right: auto;
5 | max-width: 350px;
6 | background-color: white;
7 | padding: 20px;
8 | padding-right: 30px;
9 | border-radius: 10px;
10 | }
11 |
12 | form > * {
13 | margin: 10px;
14 | }
15 |
16 | form > div {
17 | text-align: right;
18 | margin-right: -10px;
19 | }
20 |
21 | body {
22 | background-color: #84cbff;
23 | }
24 |
25 | h1 {
26 | color: white;
27 | text-align: center;
28 | margin-top: 50px;
29 | margin-bottom: 50px;
30 | font-size: 64px;
31 | font-weight: lighter;
32 | }
--------------------------------------------------------------------------------
/code/ex02_ngrok/pypi_org/app.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | import flask
4 | import pypi_org.data.db_session as db_session
5 |
6 | app = flask.Flask(__name__)
7 |
8 |
9 | def main():
10 | register_blueprints()
11 | setup_db()
12 | app.run(debug=True)
13 |
14 |
15 | def setup_db():
16 | db_file = os.path.join(
17 | os.path.dirname(__file__),
18 | 'db',
19 | 'pypi.sqlite')
20 |
21 | db_session.global_init(db_file)
22 |
23 |
24 | def register_blueprints():
25 | from pypi_org.views import home_views
26 | from pypi_org.views import package_views
27 | from pypi_org.views import cms_views
28 |
29 | app.register_blueprint(package_views.blueprint)
30 | app.register_blueprint(home_views.blueprint)
31 | app.register_blueprint(cms_views.blueprint)
32 |
33 |
34 | if __name__ == '__main__':
35 | main()
36 |
--------------------------------------------------------------------------------
/code/ex02_ngrok/pypi_org/data/__all_models.py:
--------------------------------------------------------------------------------
1 | # Add all your SQLAlchemy models here.
2 | # This allows us to import just this file when
3 | # we need to preload the models and ensure they
4 | # are all loaded.
5 |
6 | # noinspection PyUnresolvedReferences
7 | import pypi_vm.data.auditing
8 | # noinspection PyUnresolvedReferences
9 | import pypi_vm.data.downloads
10 | # noinspection PyUnresolvedReferences
11 | import pypi_vm.data.languages
12 | # noinspection PyUnresolvedReferences
13 | import pypi_vm.data.maintainers
14 | # noinspection PyUnresolvedReferences
15 | import pypi_vm.data.packages
16 | # noinspection PyUnresolvedReferences
17 | import pypi_vm.data.releases
18 | # noinspection PyUnresolvedReferences
19 | import pypi_vm.data.users
20 |
--------------------------------------------------------------------------------
/code/ex02_ngrok/pypi_org/data/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeckennedy/ten-tips-python-web-devs/e2406853a3d2e1d02ca5b00f68ae510993d4ad19/code/ex02_ngrok/pypi_org/data/__init__.py
--------------------------------------------------------------------------------
/code/ex02_ngrok/pypi_org/data/auditing.py:
--------------------------------------------------------------------------------
1 | import datetime
2 | import sqlalchemy
3 | from pypi_vm.data.modelbase import SqlAlchemyBase
4 |
5 |
6 | class Auditing(SqlAlchemyBase):
7 | __tablename__ = 'auditing'
8 |
9 | id = sqlalchemy.Column(sqlalchemy.String, primary_key=True)
10 | created_date = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True)
11 | description = sqlalchemy.Column(sqlalchemy.String)
12 |
--------------------------------------------------------------------------------
/code/ex02_ngrok/pypi_org/data/db_session.py:
--------------------------------------------------------------------------------
1 | import sqlalchemy
2 | import sqlalchemy.orm
3 | from pypi_vm.data.modelbase import SqlAlchemyBase
4 | # noinspection PyUnresolvedReferences
5 | import pypi_vm.data.__all_models
6 |
7 |
8 | class DbSession:
9 | factory = None
10 | engine = None
11 |
12 | @staticmethod
13 | def global_init(db_file: str):
14 | if DbSession.factory:
15 | return
16 |
17 | if not db_file or not db_file.strip():
18 | raise Exception("You must specify a data file.")
19 |
20 | conn_str = 'sqlite:///' + db_file
21 | print("Connecting to DB at: {}".format(conn_str))
22 |
23 | engine = sqlalchemy.create_engine(conn_str, echo=False, connect_args={'check_same_thread': False})
24 | DbSession.engine = engine
25 | DbSession.factory = sqlalchemy.orm.sessionmaker(bind=engine)
26 |
27 | SqlAlchemyBase.metadata.create_all(engine)
28 |
29 |
--------------------------------------------------------------------------------
/code/ex02_ngrok/pypi_org/data/downloads.py:
--------------------------------------------------------------------------------
1 | import datetime
2 | import sqlalchemy
3 | from pypi_vm.data.modelbase import SqlAlchemyBase
4 |
5 |
6 | class Download(SqlAlchemyBase):
7 | __tablename__ = 'downloads'
8 |
9 | id = sqlalchemy.Column(sqlalchemy.BigInteger, primary_key=True, autoincrement=True)
10 | created_date = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True)
11 |
12 | package_id = sqlalchemy.Column(sqlalchemy.String, index=True)
13 | release_id = sqlalchemy.Column(sqlalchemy.BigInteger, index=True)
14 |
15 | ip_address = sqlalchemy.Column(sqlalchemy.String)
16 | user_agent = sqlalchemy.Column(sqlalchemy.String)
17 |
--------------------------------------------------------------------------------
/code/ex02_ngrok/pypi_org/data/languages.py:
--------------------------------------------------------------------------------
1 | import datetime
2 | import sqlalchemy
3 | from pypi_vm.data.modelbase import SqlAlchemyBase
4 |
5 |
6 | class ProgrammingLanguage(SqlAlchemyBase):
7 | __tablename__ = 'languages'
8 |
9 | id = sqlalchemy.Column(sqlalchemy.String, primary_key=True)
10 | created_date = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True)
11 | description = sqlalchemy.Column(sqlalchemy.String)
12 |
--------------------------------------------------------------------------------
/code/ex02_ngrok/pypi_org/data/licenses.py:
--------------------------------------------------------------------------------
1 | import datetime
2 | import sqlalchemy
3 | from pypi_org.data.modelbase import SqlAlchemyBase
4 |
5 |
6 | class License(SqlAlchemyBase):
7 | __tablename__ = 'licenses'
8 |
9 | id = sqlalchemy.Column(sqlalchemy.String, primary_key=True)
10 | created_date = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True)
11 | description = sqlalchemy.Column(sqlalchemy.String)
12 |
--------------------------------------------------------------------------------
/code/ex02_ngrok/pypi_org/data/maintainers.py:
--------------------------------------------------------------------------------
1 | import datetime
2 |
3 | import sqlalchemy
4 | from pypi_vm.data.modelbase import SqlAlchemyBase
5 |
6 |
7 | class Maintainer(SqlAlchemyBase):
8 | __tablename__ = 'maintainers'
9 |
10 | user_id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True)
11 | package_id = sqlalchemy.Column(sqlalchemy.String, primary_key=True)
12 | # date_added = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now)
13 |
--------------------------------------------------------------------------------
/code/ex02_ngrok/pypi_org/data/modelbase.py:
--------------------------------------------------------------------------------
1 | import sqlalchemy.ext.declarative as dec
2 |
3 | SqlAlchemyBase = dec.declarative_base()
4 |
--------------------------------------------------------------------------------
/code/ex02_ngrok/pypi_org/data/users.py:
--------------------------------------------------------------------------------
1 | import datetime
2 | import sqlalchemy
3 | from pypi_vm.data.modelbase import SqlAlchemyBase
4 |
5 |
6 | class User(SqlAlchemyBase):
7 | __tablename__ = 'users'
8 |
9 | id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True, autoincrement=True)
10 | name = sqlalchemy.Column(sqlalchemy.String, nullable=True)
11 | email = sqlalchemy.Column(sqlalchemy.String, index=True, nullable=True)
12 | hashed_password = sqlalchemy.Column(sqlalchemy.String, nullable=True, index=True)
13 | created_date = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True)
14 | profile_image_url = sqlalchemy.Column(sqlalchemy.String)
15 | last_login = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True)
16 |
--------------------------------------------------------------------------------
/code/ex02_ngrok/pypi_org/db/placeholder.txt:
--------------------------------------------------------------------------------
1 | Just here so git will create this folder.
--------------------------------------------------------------------------------
/code/ex02_ngrok/pypi_org/db/pypi.sqlite:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeckennedy/ten-tips-python-web-devs/e2406853a3d2e1d02ca5b00f68ae510993d4ad19/code/ex02_ngrok/pypi_org/db/pypi.sqlite
--------------------------------------------------------------------------------
/code/ex02_ngrok/pypi_org/services/cms_service.py:
--------------------------------------------------------------------------------
1 | fake_db = {
2 | '/company/history': {
3 | 'page_title': 'Company history',
4 | 'page_details': 'Details about company history...',
5 | },
6 | '/company/employees': {
7 | 'page_title': 'Our team',
8 | 'page_details': 'Details about company employees ...',
9 | },
10 | }
11 |
12 |
13 | def get_page(url: str) -> dict:
14 | if not url:
15 | return {}
16 |
17 | url = url.strip().lower()
18 | url = '/' + url.lstrip('/')
19 |
20 | page = fake_db.get(url, {})
21 | return page
22 |
--------------------------------------------------------------------------------
/code/ex02_ngrok/pypi_org/services/package_service.py:
--------------------------------------------------------------------------------
1 | def get_latest_packages():
2 | return [
3 | {'name': 'flask', 'version': '1.2.3'},
4 | {'name': 'sqlalchemy', 'version': '2.2.0'},
5 | {'name': 'passlib', 'version': '3.0.0'},
6 | ]
7 |
--------------------------------------------------------------------------------
/code/ex02_ngrok/pypi_org/static/img/blue-cube.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/code/ex02_ngrok/pypi_org/static/img/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeckennedy/ten-tips-python-web-devs/e2406853a3d2e1d02ca5b00f68ae510993d4ad19/code/ex02_ngrok/pypi_org/static/img/favicon.png
--------------------------------------------------------------------------------
/code/ex02_ngrok/pypi_org/static/img/white-cube.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/code/ex02_ngrok/pypi_org/templates/cms/page.html:
--------------------------------------------------------------------------------
1 | {% extends "shared/_layout.html" %}
2 | {% block title %}About PyPI Demo{% endblock %}
3 |
4 | {% block main_content %}
5 |
{{ page_title }}
6 |
7 |
8 | {{ page_details }}
9 |
10 | {% endblock %}
11 |
--------------------------------------------------------------------------------
/code/ex02_ngrok/pypi_org/templates/home/about.html:
--------------------------------------------------------------------------------
1 | {% extends "shared/_layout.html" %}
2 | {% block title %}About PyPI Demo{% endblock %}
3 |
4 | {% block main_content %}
5 | About Python Package Index
6 |
7 |
8 | This is our demo app for our Flask course.
9 |
10 | {% endblock %}
11 |
12 | {% block additional_css %}
13 |
14 | {% endblock %}
--------------------------------------------------------------------------------
/code/ex02_ngrok/pypi_org/templates/packages/details.html:
--------------------------------------------------------------------------------
1 | {% extends "shared/_layout.html" %}
2 | {% block main_content %}
3 |
4 | Python Package Index
5 |
6 | Packages
7 |
8 | {% for p in packages %}
9 |
10 |
11 |
12 | {{ p.name.upper() }}
13 |
14 |
15 | {{ p.version }}
16 |
17 |
18 |
19 | {% endfor %}
20 | {% endblock %}
--------------------------------------------------------------------------------
/code/ex02_ngrok/pypi_org/views/cms_views.py:
--------------------------------------------------------------------------------
1 | import flask
2 |
3 | from pypi_org.infrastructure.view_modifiers import response
4 | import pypi_org.services.cms_service as cms_service
5 |
6 | blueprint = flask.Blueprint('cms', __name__, template_folder='templates')
7 |
8 |
9 | @blueprint.route('/')
10 | @response(template_file='cms/page.html')
11 | def cms_page(full_url: str):
12 | print("Getting CMS page for {}".format(full_url))
13 |
14 | page = cms_service.get_page(full_url)
15 | if not page:
16 | return flask.abort(404)
17 |
18 | return page
19 |
--------------------------------------------------------------------------------
/code/ex02_ngrok/pypi_org/views/home_views.py:
--------------------------------------------------------------------------------
1 | import flask
2 |
3 | from pypi_org.infrastructure.view_modifiers import response
4 | import pypi_org.services.package_service as package_service
5 |
6 | blueprint = flask.Blueprint('home', __name__, template_folder='templates')
7 |
8 |
9 | @blueprint.route('/')
10 | @response(template_file='home/index.html')
11 | def index():
12 | test_packages = package_service.get_latest_packages()
13 | return {'packages': test_packages}
14 | # return flask.render_template('home/index.html', packages=test_packages)
15 |
16 |
17 | @blueprint.route('/about')
18 | @response(template_file='home/about.html')
19 | def about():
20 | return {}
21 |
--------------------------------------------------------------------------------
/code/ex02_ngrok/pypi_org/views/package_views.py:
--------------------------------------------------------------------------------
1 | import flask
2 |
3 | from pypi_org.infrastructure.view_modifiers import response
4 | import pypi_org.services.package_service as package_service
5 |
6 | blueprint = flask.Blueprint('packages', __name__, template_folder='templates')
7 |
8 |
9 | @blueprint.route('/project/')
10 | # @response(template_file='packages/details.html')
11 | def package_details(package_name: str):
12 | return "Package details for {}".format(package_name)
13 |
14 |
15 | @blueprint.route('/')
16 | def popular(rank: int):
17 | print(type(rank), rank)
18 | return "The details for the {}th most popular package".format(rank)
19 |
--------------------------------------------------------------------------------
/code/ex04_async_web/config/dev.json:
--------------------------------------------------------------------------------
1 | {
2 | "dev": true,
3 | "use_cached_data": false,
4 | "weather_key": "684e93644281bf1398569ccf91aca62d"
5 | }
--------------------------------------------------------------------------------
/code/ex04_async_web/config/prod.json:
--------------------------------------------------------------------------------
1 | {
2 | "dev": false,
3 | "use_cached_data": false,
4 | "weather_key": "684e93644281bf1398569ccf91aca62d"
5 | }
--------------------------------------------------------------------------------
/code/ex04_async_web/config/settings.py:
--------------------------------------------------------------------------------
1 | import os
2 | import json
3 |
4 |
5 | def load(mode='dev') -> dict:
6 | file = os.path.join(os.path.dirname(__file__), f"{mode}.json")
7 | if not os.path.exists(file):
8 | raise Exception(f"Config not found for {mode}.")
9 |
10 | with open(file, 'r', encoding='utf-8') as fin:
11 | return json.load(fin)
12 |
--------------------------------------------------------------------------------
/code/ex04_async_web/services/event_service.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeckennedy/ten-tips-python-web-devs/e2406853a3d2e1d02ca5b00f68ae510993d4ad19/code/ex04_async_web/services/event_service.py
--------------------------------------------------------------------------------
/code/ex04_async_web/services/weather_service.py:
--------------------------------------------------------------------------------
1 | import aiohttp
2 |
3 | __api_key = ''
4 |
5 |
6 | def global_init(api_key: str):
7 | global __api_key
8 | __api_key = api_key
9 |
10 |
11 | async def get_current(zip_code: str, country_code: str) -> dict:
12 | url = f'https://api.openweathermap.org/data/2.5/weather?zip={zip_code},{country_code}&appid={__api_key}'
13 | async with aiohttp.ClientSession() as session:
14 | async with session.get(url) as resp:
15 | resp.raise_for_status()
16 |
17 | return await resp.json()
18 |
--------------------------------------------------------------------------------
/code/ex04_async_web/views/city_api.py:
--------------------------------------------------------------------------------
1 | import quart
2 | from services import weather_service, sun_service, location_service
3 |
4 | blueprint = quart.blueprints.Blueprint(__name__, __name__)
5 |
6 |
7 | @blueprint.route('/api/weather//', methods=['GET'])
8 | async def weather(zip_code: str, country: str):
9 | weather_data = await weather_service.get_current(zip_code, country)
10 | if not weather_data:
11 | quart.abort(404)
12 | return quart.jsonify(weather_data)
13 |
14 |
15 | @blueprint.route('/api/sun//', methods=['GET'])
16 | async def sun(zip_code: str, country: str):
17 | lat, long = await location_service.get_lat_long(zip_code, country)
18 | sun_data = await sun_service.for_today(lat, long)
19 | if not sun_data:
20 | quart.abort(404)
21 | return quart.jsonify(sun_data)
22 |
--------------------------------------------------------------------------------
/code/ex04_async_web/views/home.py:
--------------------------------------------------------------------------------
1 | import quart
2 |
3 | blueprint = quart.blueprints.Blueprint(__name__, __name__)
4 |
5 |
6 | @blueprint.route('/')
7 | def index():
8 | return "Welcome to the city_scape API. " \
9 | "Use /api/sun/[zipcode]/[country code (e.g. us)] and" \
10 | "/api/weather/[zipcode]/[country code (e.g. us)] for API calls."
11 |
12 |
13 | @blueprint.errorhandler(404)
14 | def not_found(_):
15 | return quart.Response("The page was not found.", status=404)
16 |
--------------------------------------------------------------------------------
/code/ex05_migrations/alembic/README:
--------------------------------------------------------------------------------
1 | Generic single-database configuration.
--------------------------------------------------------------------------------
/code/ex05_migrations/alembic/script.py.mako:
--------------------------------------------------------------------------------
1 | """${message}
2 |
3 | Revision ID: ${up_revision}
4 | Revises: ${down_revision | comma,n}
5 | Create Date: ${create_date}
6 |
7 | """
8 | from alembic import op
9 | import sqlalchemy as sa
10 | ${imports if imports else ""}
11 |
12 | # revision identifiers, used by Alembic.
13 | revision = ${repr(up_revision)}
14 | down_revision = ${repr(down_revision)}
15 | branch_labels = ${repr(branch_labels)}
16 | depends_on = ${repr(depends_on)}
17 |
18 |
19 | def upgrade():
20 | ${upgrades if upgrades else "pass"}
21 |
22 |
23 | def downgrade():
24 | ${downgrades if downgrades else "pass"}
25 |
--------------------------------------------------------------------------------
/code/ex05_migrations/pypi_org/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeckennedy/ten-tips-python-web-devs/e2406853a3d2e1d02ca5b00f68ae510993d4ad19/code/ex05_migrations/pypi_org/__init__.py
--------------------------------------------------------------------------------
/code/ex05_migrations/pypi_org/app.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | import flask
4 | import pypi_org.data.db_session as db_session
5 |
6 | app = flask.Flask(__name__)
7 |
8 |
9 | def main():
10 | register_blueprints()
11 | setup_db()
12 | app.run(debug=True)
13 |
14 |
15 | def setup_db():
16 | db_file = os.path.join(
17 | os.path.dirname(__file__),
18 | 'db',
19 | 'pypi.sqlite')
20 |
21 | db_session.global_init(db_file)
22 |
23 |
24 | def register_blueprints():
25 | from pypi_org.views import home_views
26 | from pypi_org.views import package_views
27 | from pypi_org.views import cms_views
28 |
29 | app.register_blueprint(package_views.blueprint)
30 | app.register_blueprint(home_views.blueprint)
31 | app.register_blueprint(cms_views.blueprint)
32 |
33 |
34 | if __name__ == '__main__':
35 | main()
36 |
--------------------------------------------------------------------------------
/code/ex05_migrations/pypi_org/data/__all_models.py:
--------------------------------------------------------------------------------
1 | # Add all your SQLAlchemy models here.
2 | # This allows us to import just this file when
3 | # we need to preload the models and ensure they
4 | # are all loaded.
5 |
6 | # noinspection PyUnresolvedReferences
7 | import pypi_org.data.downloads
8 | # noinspection PyUnresolvedReferences
9 | import pypi_org.data.languages
10 | # noinspection PyUnresolvedReferences
11 | import pypi_org.data.licenses
12 | # noinspection PyUnresolvedReferences
13 | import pypi_org.data.maintainers
14 | # noinspection PyUnresolvedReferences
15 | import pypi_org.data.package
16 | # noinspection PyUnresolvedReferences
17 | import pypi_org.data.releases
18 | # noinspection PyUnresolvedReferences
19 | import pypi_org.data.users
20 |
--------------------------------------------------------------------------------
/code/ex05_migrations/pypi_org/data/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeckennedy/ten-tips-python-web-devs/e2406853a3d2e1d02ca5b00f68ae510993d4ad19/code/ex05_migrations/pypi_org/data/__init__.py
--------------------------------------------------------------------------------
/code/ex05_migrations/pypi_org/data/db_session.py:
--------------------------------------------------------------------------------
1 | import sqlalchemy as sa
2 | import sqlalchemy.orm as orm
3 | from sqlalchemy.orm import Session
4 |
5 | from pypi_org.data.modelbase import SqlAlchemyBase
6 |
7 | __factory = None
8 |
9 |
10 | def global_init(db_file: str):
11 | global __factory
12 |
13 | if __factory:
14 | return
15 |
16 | if not db_file or not db_file.strip():
17 | raise Exception("You must specify a db file.")
18 |
19 | conn_str = 'sqlite:///' + db_file.strip()
20 | print("Connecting to DB with {}".format(conn_str))
21 |
22 | engine = sa.create_engine(conn_str, echo=False)
23 | __factory = orm.sessionmaker(bind=engine)
24 |
25 | # noinspection PyUnresolvedReferences
26 | import pypi_org.data.__all_models
27 |
28 | SqlAlchemyBase.metadata.create_all(engine)
29 |
30 |
31 | def create_session() -> Session:
32 | global __factory
33 | return __factory()
34 |
--------------------------------------------------------------------------------
/code/ex05_migrations/pypi_org/data/downloads.py:
--------------------------------------------------------------------------------
1 | import datetime
2 | import sqlalchemy
3 | from pypi_org.data.modelbase import SqlAlchemyBase
4 |
5 |
6 | class Download(SqlAlchemyBase):
7 | __tablename__ = 'downloads'
8 |
9 | id: int = sqlalchemy.Column(sqlalchemy.BigInteger, primary_key=True, autoincrement=True)
10 | created_date: datetime.datetime = sqlalchemy.Column(
11 | sqlalchemy.DateTime, default=datetime.datetime.now, index=True)
12 |
13 | package_id: str = sqlalchemy.Column(sqlalchemy.String, index=True)
14 | release_id: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True)
15 |
16 | ip_address: str = sqlalchemy.Column(sqlalchemy.String)
17 | user_agent: str = sqlalchemy.Column(sqlalchemy.String)
18 |
--------------------------------------------------------------------------------
/code/ex05_migrations/pypi_org/data/languages.py:
--------------------------------------------------------------------------------
1 | import datetime
2 | import sqlalchemy
3 | from pypi_org.data.modelbase import SqlAlchemyBase
4 |
5 |
6 | class ProgrammingLanguage(SqlAlchemyBase):
7 | __tablename__ = 'languages'
8 |
9 | id: str = sqlalchemy.Column(sqlalchemy.String, primary_key=True)
10 | created_date: datetime.datetime = sqlalchemy.Column(
11 | sqlalchemy.DateTime, default=datetime.datetime.now, index=True)
12 | description: str = sqlalchemy.Column(sqlalchemy.String)
13 |
--------------------------------------------------------------------------------
/code/ex05_migrations/pypi_org/data/licenses.py:
--------------------------------------------------------------------------------
1 | import datetime
2 | import sqlalchemy
3 | from pypi_org.data.modelbase import SqlAlchemyBase
4 |
5 |
6 | class License(SqlAlchemyBase):
7 | __tablename__ = 'licenses'
8 |
9 | id: str = sqlalchemy.Column(sqlalchemy.String, primary_key=True)
10 | created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True)
11 | description: str = sqlalchemy.Column(sqlalchemy.String)
12 |
--------------------------------------------------------------------------------
/code/ex05_migrations/pypi_org/data/maintainers.py:
--------------------------------------------------------------------------------
1 | import sqlalchemy
2 | from pypi_org.data.modelbase import SqlAlchemyBase
3 |
4 |
5 | class Maintainer(SqlAlchemyBase):
6 | __tablename__ = 'maintainers'
7 |
8 | user_id: int = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True)
9 | package_id: str = sqlalchemy.Column(sqlalchemy.String, primary_key=True)
10 |
--------------------------------------------------------------------------------
/code/ex05_migrations/pypi_org/data/modelbase.py:
--------------------------------------------------------------------------------
1 | import sqlalchemy.ext.declarative as dec
2 |
3 | SqlAlchemyBase = dec.declarative_base()
4 |
--------------------------------------------------------------------------------
/code/ex05_migrations/pypi_org/data/users.py:
--------------------------------------------------------------------------------
1 | import datetime
2 | import sqlalchemy
3 | from pypi_org.data.modelbase import SqlAlchemyBase
4 |
5 |
6 | class User(SqlAlchemyBase):
7 | __tablename__ = 'users'
8 |
9 | id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True, autoincrement=True)
10 | name = sqlalchemy.Column(sqlalchemy.String, nullable=True)
11 | email = sqlalchemy.Column(sqlalchemy.String, index=True, unique=True, nullable=True)
12 | hashed_password = sqlalchemy.Column(sqlalchemy.String, nullable=True, index=True)
13 | created_date = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True)
14 | profile_image_url = sqlalchemy.Column(sqlalchemy.String)
15 | last_login = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True)
16 |
--------------------------------------------------------------------------------
/code/ex05_migrations/pypi_org/db/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeckennedy/ten-tips-python-web-devs/e2406853a3d2e1d02ca5b00f68ae510993d4ad19/code/ex05_migrations/pypi_org/db/__init__.py
--------------------------------------------------------------------------------
/code/ex05_migrations/pypi_org/db/placeholder.txt:
--------------------------------------------------------------------------------
1 | Just here so git will create this folder.
--------------------------------------------------------------------------------
/code/ex05_migrations/pypi_org/db/pypi.sqlite:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeckennedy/ten-tips-python-web-devs/e2406853a3d2e1d02ca5b00f68ae510993d4ad19/code/ex05_migrations/pypi_org/db/pypi.sqlite
--------------------------------------------------------------------------------
/code/ex05_migrations/pypi_org/infrastructure/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeckennedy/ten-tips-python-web-devs/e2406853a3d2e1d02ca5b00f68ae510993d4ad19/code/ex05_migrations/pypi_org/infrastructure/__init__.py
--------------------------------------------------------------------------------
/code/ex05_migrations/pypi_org/services/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeckennedy/ten-tips-python-web-devs/e2406853a3d2e1d02ca5b00f68ae510993d4ad19/code/ex05_migrations/pypi_org/services/__init__.py
--------------------------------------------------------------------------------
/code/ex05_migrations/pypi_org/services/cms_service.py:
--------------------------------------------------------------------------------
1 | fake_db = {
2 | '/company/history': {
3 | 'page_title': 'Company history',
4 | 'page_details': 'Details about company history...',
5 | },
6 | '/company/employees': {
7 | 'page_title': 'Our team',
8 | 'page_details': 'Details about company employees ...',
9 | },
10 | }
11 |
12 |
13 | def get_page(url: str) -> dict:
14 | if not url:
15 | return {}
16 |
17 | url = url.strip().lower()
18 | url = '/' + url.lstrip('/')
19 |
20 | page = fake_db.get(url, {})
21 | return page
22 |
--------------------------------------------------------------------------------
/code/ex05_migrations/pypi_org/services/user_service.py:
--------------------------------------------------------------------------------
1 | import pypi_org.data.db_session as db_session
2 | from pypi_org.data.users import User
3 |
4 |
5 | def get_user_count() -> int:
6 | session = db_session.create_session()
7 | return session.query(User).count()
8 |
--------------------------------------------------------------------------------
/code/ex05_migrations/pypi_org/static/img/blue-cube.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/code/ex05_migrations/pypi_org/static/img/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeckennedy/ten-tips-python-web-devs/e2406853a3d2e1d02ca5b00f68ae510993d4ad19/code/ex05_migrations/pypi_org/static/img/favicon.png
--------------------------------------------------------------------------------
/code/ex05_migrations/pypi_org/static/img/white-cube.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/code/ex05_migrations/pypi_org/templates/cms/page.html:
--------------------------------------------------------------------------------
1 | {% extends "shared/_layout.html" %}
2 | {% block title %}About PyPI Demo{% endblock %}
3 |
4 | {% block main_content %}
5 | {{ page_title }}
6 |
7 |
8 | {{ page_details }}
9 |
10 | {% endblock %}
11 |
--------------------------------------------------------------------------------
/code/ex05_migrations/pypi_org/templates/home/about.html:
--------------------------------------------------------------------------------
1 | {% extends "shared/_layout.html" %}
2 | {% block title %}About PyPI Demo{% endblock %}
3 |
4 | {% block main_content %}
5 | About Python Package Index
6 |
7 |
8 | This is our demo app for our Flask course.
9 |
10 | {% endblock %}
11 |
12 | {% block additional_css %}
13 |
14 | {% endblock %}
--------------------------------------------------------------------------------
/code/ex05_migrations/pypi_org/views/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeckennedy/ten-tips-python-web-devs/e2406853a3d2e1d02ca5b00f68ae510993d4ad19/code/ex05_migrations/pypi_org/views/__init__.py
--------------------------------------------------------------------------------
/code/ex05_migrations/pypi_org/views/cms_views.py:
--------------------------------------------------------------------------------
1 | import flask
2 |
3 | from pypi_org.infrastructure.view_modifiers import response
4 | import pypi_org.services.cms_service as cms_service
5 |
6 | blueprint = flask.Blueprint('cms', __name__, template_folder='templates')
7 |
8 |
9 | @blueprint.route('/')
10 | @response(template_file='cms/page.html')
11 | def cms_page(full_url: str):
12 | print("Getting CMS page for {}".format(full_url))
13 |
14 | page = cms_service.get_page(full_url)
15 | if not page:
16 | return flask.abort(404)
17 |
18 | return page
19 |
--------------------------------------------------------------------------------
/code/ex05_migrations/pypi_org/views/home_views.py:
--------------------------------------------------------------------------------
1 | import flask
2 |
3 | from pypi_org.infrastructure.view_modifiers import response
4 | import pypi_org.services.package_service as package_service
5 | import pypi_org.services.user_service as user_service
6 |
7 | blueprint = flask.Blueprint('home', __name__, template_folder='templates')
8 |
9 |
10 | @blueprint.route('/')
11 | @response(template_file='home/index.html')
12 | def index():
13 | return {
14 | 'releases': package_service.get_latest_releases(),
15 | 'package_count': package_service.get_package_count(),
16 | 'release_count': package_service.get_release_count(),
17 | 'user_count': user_service.get_user_count(),
18 | }
19 |
20 |
21 | @blueprint.route('/about')
22 | @response(template_file='home/about.html')
23 | def about():
24 | return {}
25 |
--------------------------------------------------------------------------------
/code/ex05_migrations/setup.py:
--------------------------------------------------------------------------------
1 | from setuptools import setup
2 |
3 | setup(
4 | name='pypi_org',
5 | version='',
6 | packages=['pypi_org', 'pypi_org.db', 'pypi_org.data', 'pypi_org.views', 'pypi_org.services',
7 | 'pypi_org.infrastructure'],
8 | package_dir={'': '.'},
9 | url='',
10 | license='',
11 | author='Michael Kennedy',
12 | author_email='',
13 | description=''
14 | )
15 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/js/dropdown.js:
--------------------------------------------------------------------------------
1 | /* https://freefrontend.com/css-select-boxes/ */
2 |
3 | let el = {};
4 |
5 | $('.placeholder').on('click', function (ev) {
6 | $('.placeholder').css('opacity', '0');
7 | $('.list__ul').toggle();
8 | });
9 |
10 | $('.list__ul a').on('click', function (ev) {
11 | ev.preventDefault();
12 | var index = $(this).parent().index();
13 |
14 | $('.placeholder').text($(this).text()).css('opacity', '1');
15 |
16 | console.log($('.list__ul').find('li').eq(index).html());
17 |
18 | $('.list__ul').find('li').eq(index).prependTo('.list__ul');
19 | $('.list__ul').toggle();
20 |
21 | });
22 |
23 |
24 | $('select').on('change', function (e) {
25 |
26 | // Set text on placeholder hidden element
27 | $('.placeholder').text(this.value);
28 |
29 | // Animate select width as placeholder
30 | $(this).animate({width: $('.placeholder').width() + 'px'});
31 |
32 | });
33 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/js/vue/vue.common.js:
--------------------------------------------------------------------------------
1 | if (process.env.NODE_ENV === 'production') {
2 | module.exports = require('./vue.common.prod.js')
3 | } else {
4 | module.exports = require('./vue.common.dev.js')
5 | }
6 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/js/vue/vue.runtime.common.js:
--------------------------------------------------------------------------------
1 | if (process.env.NODE_ENV === 'production') {
2 | module.exports = require('./vue.runtime.common.prod.js')
3 | } else {
4 | module.exports = require('./vue.runtime.common.dev.js')
5 | }
6 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/compiler/directives/bind.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | export default function bind (el: ASTElement, dir: ASTDirective) {
4 | el.wrapData = (code: string) => {
5 | return `_b(${code},'${el.tag}',${dir.value},${
6 | dir.modifiers && dir.modifiers.prop ? 'true' : 'false'
7 | }${
8 | dir.modifiers && dir.modifiers.sync ? ',true' : ''
9 | })`
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/compiler/directives/index.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import on from './on'
4 | import bind from './bind'
5 | import { noop } from 'shared/util'
6 |
7 | export default {
8 | on,
9 | bind,
10 | cloak: noop
11 | }
12 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/compiler/directives/on.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { warn } from 'core/util/index'
4 |
5 | export default function on (el: ASTElement, dir: ASTDirective) {
6 | if (process.env.NODE_ENV !== 'production' && dir.modifiers) {
7 | warn(`v-on without argument does not support modifiers.`)
8 | }
9 | el.wrapListeners = (code: string) => `_g(${code},${dir.value})`
10 | }
11 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/compiler/index.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { parse } from './parser/index'
4 | import { optimize } from './optimizer'
5 | import { generate } from './codegen/index'
6 | import { createCompilerCreator } from './create-compiler'
7 |
8 | // `createCompilerCreator` allows creating compilers that use alternative
9 | // parser/optimizer/codegen, e.g the SSR optimizing compiler.
10 | // Here we just export a default compiler using the default parts.
11 | export const createCompiler = createCompilerCreator(function baseCompile (
12 | template: string,
13 | options: CompilerOptions
14 | ): CompiledResult {
15 | const ast = parse(template.trim(), options)
16 | if (options.optimize !== false) {
17 | optimize(ast, options)
18 | }
19 | const code = generate(ast, options)
20 | return {
21 | ast,
22 | render: code.render,
23 | staticRenderFns: code.staticRenderFns
24 | }
25 | })
26 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/compiler/parser/entity-decoder.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | let decoder
4 |
5 | export default {
6 | decode (html: string): string {
7 | decoder = decoder || document.createElement('div')
8 | decoder.innerHTML = html
9 | return decoder.textContent
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/core/components/index.js:
--------------------------------------------------------------------------------
1 | import KeepAlive from './keep-alive'
2 |
3 | export default {
4 | KeepAlive
5 | }
6 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/core/global-api/mixin.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { mergeOptions } from '../util/index'
4 |
5 | export function initMixin (Vue: GlobalAPI) {
6 | Vue.mixin = function (mixin: Object) {
7 | this.options = mergeOptions(this.options, mixin)
8 | return this
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/core/global-api/use.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { toArray } from '../util/index'
4 |
5 | export function initUse (Vue: GlobalAPI) {
6 | Vue.use = function (plugin: Function | Object) {
7 | const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
8 | if (installedPlugins.indexOf(plugin) > -1) {
9 | return this
10 | }
11 |
12 | // additional parameters
13 | const args = toArray(arguments, 1)
14 | args.unshift(this)
15 | if (typeof plugin.install === 'function') {
16 | plugin.install.apply(plugin, args)
17 | } else if (typeof plugin === 'function') {
18 | plugin.apply(null, args)
19 | }
20 | installedPlugins.push(plugin)
21 | return this
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/core/index.js:
--------------------------------------------------------------------------------
1 | import Vue from './instance/index'
2 | import { initGlobalAPI } from './global-api/index'
3 | import { isServerRendering } from 'core/util/env'
4 | import { FunctionalRenderContext } from 'core/vdom/create-functional-component'
5 |
6 | initGlobalAPI(Vue)
7 |
8 | Object.defineProperty(Vue.prototype, '$isServer', {
9 | get: isServerRendering
10 | })
11 |
12 | Object.defineProperty(Vue.prototype, '$ssrContext', {
13 | get () {
14 | /* istanbul ignore next */
15 | return this.$vnode && this.$vnode.ssrContext
16 | }
17 | })
18 |
19 | // expose FunctionalRenderContext for ssr runtime helper installation
20 | Object.defineProperty(Vue, 'FunctionalRenderContext', {
21 | value: FunctionalRenderContext
22 | })
23 |
24 | Vue.version = '__VERSION__'
25 |
26 | export default Vue
27 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/core/util/index.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | export * from 'shared/util'
4 | export * from './lang'
5 | export * from './env'
6 | export * from './options'
7 | export * from './debug'
8 | export * from './props'
9 | export * from './error'
10 | export * from './next-tick'
11 | export { defineReactive } from '../observer/index'
12 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/core/util/perf.js:
--------------------------------------------------------------------------------
1 | import { inBrowser } from './env'
2 |
3 | export let mark
4 | export let measure
5 |
6 | if (process.env.NODE_ENV !== 'production') {
7 | const perf = inBrowser && window.performance
8 | /* istanbul ignore if */
9 | if (
10 | perf &&
11 | perf.mark &&
12 | perf.measure &&
13 | perf.clearMarks &&
14 | perf.clearMeasures
15 | ) {
16 | mark = tag => perf.mark(tag)
17 | measure = (name, startTag, endTag) => {
18 | perf.measure(name, startTag, endTag)
19 | perf.clearMarks(startTag)
20 | perf.clearMarks(endTag)
21 | // perf.clearMeasures(name)
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/core/vdom/helpers/get-first-component-child.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { isDef } from 'shared/util'
4 | import { isAsyncPlaceholder } from './is-async-placeholder'
5 |
6 | export function getFirstComponentChild (children: ?Array): ?VNode {
7 | if (Array.isArray(children)) {
8 | for (let i = 0; i < children.length; i++) {
9 | const c = children[i]
10 | if (isDef(c) && (isDef(c.componentOptions) || isAsyncPlaceholder(c))) {
11 | return c
12 | }
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/core/vdom/helpers/index.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | export * from './merge-hook'
4 | export * from './extract-props'
5 | export * from './update-listeners'
6 | export * from './normalize-children'
7 | export * from './resolve-async-component'
8 | export * from './get-first-component-child'
9 | export * from './is-async-placeholder'
10 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/core/vdom/helpers/is-async-placeholder.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | export function isAsyncPlaceholder (node: VNode): boolean {
4 | return node.isComment && node.asyncFactory
5 | }
6 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/core/vdom/modules/index.js:
--------------------------------------------------------------------------------
1 | import directives from './directives'
2 | import ref from './ref'
3 |
4 | export default [
5 | ref,
6 | directives
7 | ]
8 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/platforms/web/compiler/directives/html.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { addProp } from 'compiler/helpers'
4 |
5 | export default function html (el: ASTElement, dir: ASTDirective) {
6 | if (dir.value) {
7 | addProp(el, 'innerHTML', `_s(${dir.value})`, dir)
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/platforms/web/compiler/directives/index.js:
--------------------------------------------------------------------------------
1 | import model from './model'
2 | import text from './text'
3 | import html from './html'
4 |
5 | export default {
6 | model,
7 | text,
8 | html
9 | }
10 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/platforms/web/compiler/directives/text.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { addProp } from 'compiler/helpers'
4 |
5 | export default function text (el: ASTElement, dir: ASTDirective) {
6 | if (dir.value) {
7 | addProp(el, 'textContent', `_s(${dir.value})`, dir)
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/platforms/web/compiler/index.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { baseOptions } from './options'
4 | import { createCompiler } from 'compiler/index'
5 |
6 | const { compile, compileToFunctions } = createCompiler(baseOptions)
7 |
8 | export { compile, compileToFunctions }
9 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/platforms/web/compiler/modules/index.js:
--------------------------------------------------------------------------------
1 | import klass from './class'
2 | import style from './style'
3 | import model from './model'
4 |
5 | export default [
6 | klass,
7 | style,
8 | model
9 | ]
10 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/platforms/web/compiler/options.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import {
4 | isPreTag,
5 | mustUseProp,
6 | isReservedTag,
7 | getTagNamespace
8 | } from '../util/index'
9 |
10 | import modules from './modules/index'
11 | import directives from './directives/index'
12 | import { genStaticKeys } from 'shared/util'
13 | import { isUnaryTag, canBeLeftOpenTag } from './util'
14 |
15 | export const baseOptions: CompilerOptions = {
16 | expectHTML: true,
17 | modules,
18 | directives,
19 | isPreTag,
20 | isUnaryTag,
21 | mustUseProp,
22 | canBeLeftOpenTag,
23 | isReservedTag,
24 | getTagNamespace,
25 | staticKeys: genStaticKeys(modules)
26 | }
27 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/platforms/web/entry-compiler.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | export { parseComponent } from 'sfc/parser'
4 | export { compile, compileToFunctions } from './compiler/index'
5 | export { ssrCompile, ssrCompileToFunctions } from './server/compiler'
6 | export { generateCodeFrame } from 'compiler/codeframe'
7 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/platforms/web/entry-runtime.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import Vue from './runtime/index'
4 |
5 | export default Vue
6 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/platforms/web/entry-server-basic-renderer.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import modules from './server/modules/index'
4 | import directives from './server/directives/index'
5 | import { isUnaryTag, canBeLeftOpenTag } from './compiler/util'
6 | import { createBasicRenderer } from 'server/create-basic-renderer'
7 |
8 | export default createBasicRenderer({
9 | modules,
10 | directives,
11 | isUnaryTag,
12 | canBeLeftOpenTag
13 | })
14 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/platforms/web/runtime/components/index.js:
--------------------------------------------------------------------------------
1 | import Transition from './transition'
2 | import TransitionGroup from './transition-group'
3 |
4 | export default {
5 | Transition,
6 | TransitionGroup
7 | }
8 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/platforms/web/runtime/directives/index.js:
--------------------------------------------------------------------------------
1 | import model from './model'
2 | import show from './show'
3 |
4 | export default {
5 | model,
6 | show
7 | }
8 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/platforms/web/runtime/modules/index.js:
--------------------------------------------------------------------------------
1 | import attrs from './attrs'
2 | import klass from './class'
3 | import events from './events'
4 | import domProps from './dom-props'
5 | import style from './style'
6 | import transition from './transition'
7 |
8 | export default [
9 | attrs,
10 | klass,
11 | events,
12 | domProps,
13 | style,
14 | transition
15 | ]
16 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/platforms/web/runtime/patch.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import * as nodeOps from 'web/runtime/node-ops'
4 | import { createPatchFunction } from 'core/vdom/patch'
5 | import baseModules from 'core/vdom/modules/index'
6 | import platformModules from 'web/runtime/modules/index'
7 |
8 | // the directive module should be applied last, after all
9 | // built-in modules have been applied.
10 | const modules = platformModules.concat(baseModules)
11 |
12 | export const patch: Function = createPatchFunction({ nodeOps, modules })
13 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/platforms/web/server/compiler.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { baseOptions } from '../compiler/options'
4 | import { createCompiler } from 'server/optimizing-compiler/index'
5 |
6 | const { compile, compileToFunctions } = createCompiler(baseOptions)
7 |
8 | export {
9 | compile as ssrCompile,
10 | compileToFunctions as ssrCompileToFunctions
11 | }
12 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/platforms/web/server/directives/index.js:
--------------------------------------------------------------------------------
1 | import show from './show'
2 | import model from './model'
3 |
4 | export default {
5 | show,
6 | model
7 | }
8 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/platforms/web/server/directives/show.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | export default function show (node: VNodeWithData, dir: VNodeDirective) {
4 | if (!dir.value) {
5 | const style: any = node.data.style || (node.data.style = {})
6 | if (Array.isArray(style)) {
7 | style.push({ display: 'none' })
8 | } else {
9 | style.display = 'none'
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/platforms/web/server/modules/class.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { escape } from '../util'
4 | import { genClassForVnode } from 'web/util/index'
5 |
6 | export default function renderClass (node: VNodeWithData): ?string {
7 | const classList = genClassForVnode(node)
8 | if (classList !== '') {
9 | return ` class="${escape(classList)}"`
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/platforms/web/server/modules/index.js:
--------------------------------------------------------------------------------
1 | import attrs from './attrs'
2 | import domProps from './dom-props'
3 | import klass from './class'
4 | import style from './style'
5 |
6 | export default [
7 | attrs,
8 | domProps,
9 | klass,
10 | style
11 | ]
12 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/platforms/web/util/compat.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { inBrowser } from 'core/util/index'
4 |
5 | // check whether current browser encodes a char inside attribute values
6 | let div
7 | function getShouldDecode (href: boolean): boolean {
8 | div = div || document.createElement('div')
9 | div.innerHTML = href ? `` : ``
10 | return div.innerHTML.indexOf('
') > 0
11 | }
12 |
13 | // #3663: IE encodes newlines inside attribute values while other browsers don't
14 | export const shouldDecodeNewlines = inBrowser ? getShouldDecode(false) : false
15 | // #6828: chrome encodes content in a[href]
16 | export const shouldDecodeNewlinesForHref = inBrowser ? getShouldDecode(true) : false
17 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/platforms/web/util/index.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { warn } from 'core/util/index'
4 |
5 | export * from './attrs'
6 | export * from './class'
7 | export * from './element'
8 |
9 | /**
10 | * Query an element selector if it's not an element already.
11 | */
12 | export function query (el: string | Element): Element {
13 | if (typeof el === 'string') {
14 | const selected = document.querySelector(el)
15 | if (!selected) {
16 | process.env.NODE_ENV !== 'production' && warn(
17 | 'Cannot find element: ' + el
18 | )
19 | return document.createElement('div')
20 | }
21 | return selected
22 | } else {
23 | return el
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/platforms/weex/compiler/directives/index.js:
--------------------------------------------------------------------------------
1 | import model from './model'
2 |
3 | export default {
4 | model
5 | }
6 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/platforms/weex/compiler/modules/append.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { makeMap } from 'shared/util'
4 |
5 | // The "unitary tag" means that the tag node and its children
6 | // must be sent to the native together.
7 | const isUnitaryTag = makeMap('cell,header,cell-slot,recycle-list', true)
8 |
9 | function preTransformNode (el: ASTElement) {
10 | if (isUnitaryTag(el.tag) && !el.attrsList.some(item => item.name === 'append')) {
11 | el.attrsMap.append = 'tree'
12 | el.attrsList.push({ name: 'append', value: 'tree' })
13 | }
14 | if (el.attrsMap.append === 'tree') {
15 | el.appendAsTree = true
16 | }
17 | }
18 |
19 | function genData (el: ASTElement): string {
20 | return el.appendAsTree ? `appendAsTree:true,` : ''
21 | }
22 |
23 | export default {
24 | staticKeys: ['appendAsTree'],
25 | preTransformNode,
26 | genData
27 | }
28 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/platforms/weex/compiler/modules/index.js:
--------------------------------------------------------------------------------
1 | import klass from './class'
2 | import style from './style'
3 | import props from './props'
4 | import append from './append'
5 | import recycleList from './recycle-list/index'
6 |
7 | export default [
8 | recycleList,
9 | klass,
10 | style,
11 | props,
12 | append
13 | ]
14 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/component-root.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { addAttr } from 'compiler/helpers'
4 |
5 | // mark component root nodes as
6 | export function postTransformComponentRoot (el: ASTElement) {
7 | if (!el.parent) {
8 | // component root
9 | addAttr(el, '@isComponentRoot', 'true')
10 | addAttr(el, '@templateId', '_uid')
11 | addAttr(el, '@componentProps', '$props || {}')
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/component.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { addAttr } from 'compiler/helpers'
4 | import { RECYCLE_LIST_MARKER } from 'weex/util/index'
5 |
6 | // mark components as inside recycle-list so that we know we need to invoke
7 | // their special @render function instead of render in create-component.js
8 | export function postTransformComponent (
9 | el: ASTElement,
10 | options: WeexCompilerOptions
11 | ) {
12 | // $flow-disable-line (we know isReservedTag is there)
13 | if (!options.isReservedTag(el.tag) && el.tag !== 'cell-slot') {
14 | addAttr(el, RECYCLE_LIST_MARKER, 'true')
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/text.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { addAttr } from 'compiler/helpers'
4 |
5 | function genText (node: ASTNode) {
6 | const value = node.type === 3
7 | ? node.text
8 | : node.type === 2
9 | ? node.tokens.length === 1
10 | ? node.tokens[0]
11 | : node.tokens
12 | : ''
13 | return JSON.stringify(value)
14 | }
15 |
16 | export function postTransformText (el: ASTElement) {
17 | // weex can only contain text, so the parser
18 | // always generates a single child.
19 | if (el.children.length) {
20 | addAttr(el, 'value', genText(el.children[0]))
21 | el.children = []
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/v-bind.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { camelize } from 'shared/util'
4 | import { generateBinding } from 'weex/util/parser'
5 | import { bindRE } from 'compiler/parser/index'
6 | import { getAndRemoveAttr, addRawAttr } from 'compiler/helpers'
7 |
8 | function parseAttrName (name: string): string {
9 | return camelize(name.replace(bindRE, ''))
10 | }
11 |
12 | export function preTransformVBind (el: ASTElement) {
13 | for (const attr in el.attrsMap) {
14 | if (bindRE.test(attr)) {
15 | const name: string = parseAttrName(attr)
16 | const value = generateBinding(getAndRemoveAttr(el, attr))
17 | delete el.attrsMap[attr]
18 | addRawAttr(el, name, value)
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/v-on.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | const inlineStatementRE = /^\s*([A-Za-z_$0-9\['\."\]]+)*\s*\(\s*(([A-Za-z_$0-9\['\."\]]+)?(\s*,\s*([A-Za-z_$0-9\['\."\]]+))*)\s*\)$/
4 |
5 | function parseHandlerParams (handler: ASTElementHandler) {
6 | const res = inlineStatementRE.exec(handler.value)
7 | if (res && res[2]) {
8 | handler.params = res[2].split(/\s*,\s*/)
9 | }
10 | }
11 |
12 | export function postTransformVOn (el: ASTElement) {
13 | const events: ASTElementHandlers | void = el.events
14 | if (!events) {
15 | return
16 | }
17 | for (const name in events) {
18 | const handler: ASTElementHandler | Array = events[name]
19 | if (Array.isArray(handler)) {
20 | handler.map(fn => parseHandlerParams(fn))
21 | } else {
22 | parseHandlerParams(handler)
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/v-once.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { getAndRemoveAttr, addRawAttr } from 'compiler/helpers'
4 |
5 | function containVOnce (el: ASTElement): boolean {
6 | for (const attr in el.attrsMap) {
7 | if (/^v\-once$/i.test(attr)) {
8 | return true
9 | }
10 | }
11 | return false
12 | }
13 |
14 | export function preTransformVOnce (el: ASTElement) {
15 | if (containVOnce(el)) {
16 | getAndRemoveAttr(el, 'v-once', true)
17 | addRawAttr(el, '[[once]]', true)
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/platforms/weex/entry-compiler.js:
--------------------------------------------------------------------------------
1 | export { compile } from 'weex/compiler/index'
2 | export { generateCodeFrame } from 'compiler/codeframe'
3 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/platforms/weex/entry-runtime-factory.js:
--------------------------------------------------------------------------------
1 | // this entry is built and wrapped with a factory function
2 | // used to generate a fresh copy of Vue for every Weex instance.
3 |
4 | import Vue from './runtime/index'
5 |
6 | exports.Vue = Vue
7 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/platforms/weex/runtime/components/index.js:
--------------------------------------------------------------------------------
1 | import Richtext from './richtext'
2 | import Transition from './transition'
3 | import TransitionGroup from './transition-group'
4 |
5 | export default {
6 | Richtext,
7 | Transition,
8 | TransitionGroup
9 | }
10 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/platforms/weex/runtime/components/transition.js:
--------------------------------------------------------------------------------
1 | // reuse same transition component logic from web
2 | export {
3 | transitionProps,
4 | extractTransitionData
5 | } from 'web/runtime/components/transition'
6 |
7 | import Transition from 'web/runtime/components/transition'
8 |
9 | export default Transition
10 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/platforms/weex/runtime/directives/index.js:
--------------------------------------------------------------------------------
1 | export default {
2 | }
3 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/platforms/weex/runtime/modules/index.js:
--------------------------------------------------------------------------------
1 | import attrs from './attrs'
2 | import klass from './class'
3 | import events from './events'
4 | import style from './style'
5 | import transition from './transition'
6 |
7 | export default [
8 | attrs,
9 | klass,
10 | events,
11 | style,
12 | transition
13 | ]
14 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/platforms/weex/runtime/patch.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import * as nodeOps from 'weex/runtime/node-ops'
4 | import { createPatchFunction } from 'core/vdom/patch'
5 | import baseModules from 'core/vdom/modules/index'
6 | import platformModules from 'weex/runtime/modules/index'
7 |
8 | // the directive module should be applied last, after all
9 | // built-in modules have been applied.
10 | const modules = platformModules.concat(baseModules)
11 |
12 | export const patch: Function = createPatchFunction({
13 | nodeOps,
14 | modules,
15 | LONG_LIST_THRESHOLD: 10
16 | })
17 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/platforms/weex/runtime/text-node.js:
--------------------------------------------------------------------------------
1 | let latestNodeId = 1
2 |
3 | export default function TextNode (text) {
4 | this.instanceId = ''
5 | this.nodeId = latestNodeId++
6 | this.parentNode = null
7 | this.nodeType = 3
8 | this.text = text
9 | }
10 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/server/optimizing-compiler/index.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { parse } from 'compiler/parser/index'
4 | import { generate } from './codegen'
5 | import { optimize } from './optimizer'
6 | import { createCompilerCreator } from 'compiler/create-compiler'
7 |
8 | export const createCompiler = createCompilerCreator(function baseCompile (
9 | template: string,
10 | options: CompilerOptions
11 | ): CompiledResult {
12 | const ast = parse(template.trim(), options)
13 | optimize(ast, options)
14 | const code = generate(ast, options)
15 | return {
16 | ast,
17 | render: code.render,
18 | staticRenderFns: code.staticRenderFns
19 | }
20 | })
21 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/server/util.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | export const isJS = (file: string): boolean => /\.js(\?[^.]+)?$/.test(file)
4 |
5 | export const isCSS = (file: string): boolean => /\.css(\?[^.]+)?$/.test(file)
6 |
7 | export function createPromiseCallback () {
8 | let resolve, reject
9 | const promise: Promise = new Promise((_resolve, _reject) => {
10 | resolve = _resolve
11 | reject = _reject
12 | })
13 | const cb = (err: Error, res?: string) => {
14 | if (err) return reject(err)
15 | resolve(res || '')
16 | }
17 | return { promise, cb }
18 | }
19 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/src/shared/constants.js:
--------------------------------------------------------------------------------
1 | export const SSR_ATTR = 'data-server-rendered'
2 |
3 | export const ASSET_TYPES = [
4 | 'component',
5 | 'directive',
6 | 'filter'
7 | ]
8 |
9 | export const LIFECYCLE_HOOKS = [
10 | 'beforeCreate',
11 | 'created',
12 | 'beforeMount',
13 | 'mounted',
14 | 'beforeUpdate',
15 | 'updated',
16 | 'beforeDestroy',
17 | 'destroyed',
18 | 'activated',
19 | 'deactivated',
20 | 'errorCaptured',
21 | 'serverPrefetch'
22 | ]
23 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/types/index.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from "./vue";
2 |
3 | export default Vue;
4 |
5 | export as namespace Vue;
6 |
7 | export {
8 | CreateElement,
9 | VueConstructor
10 | } from "./vue";
11 |
12 | export {
13 | Component,
14 | AsyncComponent,
15 | ComponentOptions,
16 | FunctionalComponentOptions,
17 | RenderContext,
18 | PropType,
19 | PropOptions,
20 | ComputedOptions,
21 | WatchHandler,
22 | WatchOptions,
23 | WatchOptionsWithHandler,
24 | DirectiveFunction,
25 | DirectiveOptions
26 | } from "./options";
27 |
28 | export {
29 | PluginFunction,
30 | PluginObject
31 | } from "./plugin";
32 |
33 | export {
34 | VNodeChildren,
35 | VNodeChildrenArrayContents,
36 | VNode,
37 | VNodeComponentOptions,
38 | VNodeData,
39 | VNodeDirective
40 | } from "./vnode";
41 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/node_modules/vue/types/plugin.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue as _Vue } from "./vue";
2 |
3 | export type PluginFunction = (Vue: typeof _Vue, options?: T) => void;
4 |
5 | export interface PluginObject {
6 | install: PluginFunction;
7 | [key: string]: any;
8 | }
9 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "movie_exploder",
3 | "version": "1.0.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "vue": {
8 | "version": "2.6.3",
9 | "resolved": "https://registry.npmjs.org/vue/-/vue-2.6.3.tgz",
10 | "integrity": "sha512-yftjtahz4UTAtOlXXuw7UaYD86fWrMDAAzqTdqJJx2FIBqcPmBN6kPBHiBJFGaQELVblb5ijbFMXsx0i0F7q3g=="
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/code/ex06_vue/movie_exploder/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "movie_exploder",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "dependencies": {
12 | "vue": "^2.6.3"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/code/ex07_viewmodels/pypi_vm/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeckennedy/ten-tips-python-web-devs/e2406853a3d2e1d02ca5b00f68ae510993d4ad19/code/ex07_viewmodels/pypi_vm/__init__.py
--------------------------------------------------------------------------------
/code/ex07_viewmodels/pypi_vm/config.py:
--------------------------------------------------------------------------------
1 | class Config:
2 | DEBUG = False
3 | TESTING = False
4 | DATABASE_URI = 'sqlite://:memory:'
5 | ENV = 'development'
6 |
7 |
8 | class ProductionConfig(Config):
9 | DATABASE_URI = 'mysql://user@localhost/foo'
10 | ENV = 'production'
11 |
12 |
13 | class DevelopmentConfig(Config):
14 | DEBUG = True
15 |
16 |
17 | class TestingConfig(Config):
18 | TESTING = True
19 |
--------------------------------------------------------------------------------
/code/ex07_viewmodels/pypi_vm/data/__all_models.py:
--------------------------------------------------------------------------------
1 | # Add all your SQLAlchemy models here.
2 | # This allows us to import just this file when
3 | # we need to preload the models and ensure they
4 | # are all loaded.
5 |
6 | # noinspection PyUnresolvedReferences
7 | import pypi_vm.data.auditing
8 | # noinspection PyUnresolvedReferences
9 | import pypi_vm.data.downloads
10 | # noinspection PyUnresolvedReferences
11 | import pypi_vm.data.languages
12 | # noinspection PyUnresolvedReferences
13 | import pypi_vm.data.maintainers
14 | # noinspection PyUnresolvedReferences
15 | import pypi_vm.data.packages
16 | # noinspection PyUnresolvedReferences
17 | import pypi_vm.data.releases
18 | # noinspection PyUnresolvedReferences
19 | import pypi_vm.data.users
20 |
--------------------------------------------------------------------------------
/code/ex07_viewmodels/pypi_vm/data/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeckennedy/ten-tips-python-web-devs/e2406853a3d2e1d02ca5b00f68ae510993d4ad19/code/ex07_viewmodels/pypi_vm/data/__init__.py
--------------------------------------------------------------------------------
/code/ex07_viewmodels/pypi_vm/data/auditing.py:
--------------------------------------------------------------------------------
1 | import datetime
2 | import sqlalchemy
3 | from pypi_vm.data.modelbase import SqlAlchemyBase
4 |
5 |
6 | class Auditing(SqlAlchemyBase):
7 | __tablename__ = 'auditing'
8 |
9 | id = sqlalchemy.Column(sqlalchemy.String, primary_key=True)
10 | created_date = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True)
11 | description = sqlalchemy.Column(sqlalchemy.String)
12 |
--------------------------------------------------------------------------------
/code/ex07_viewmodels/pypi_vm/data/db_session.py:
--------------------------------------------------------------------------------
1 | import sqlalchemy
2 | import sqlalchemy.orm
3 | from pypi_vm.data.modelbase import SqlAlchemyBase
4 | # noinspection PyUnresolvedReferences
5 | import pypi_vm.data.__all_models
6 |
7 |
8 | class DbSession:
9 | factory = None
10 | engine = None
11 |
12 | @staticmethod
13 | def global_init(db_file: str):
14 | if DbSession.factory:
15 | return
16 |
17 | if not db_file or not db_file.strip():
18 | raise Exception("You must specify a data file.")
19 |
20 | conn_str = 'sqlite:///' + db_file
21 | print("Connecting to DB at: {}".format(conn_str))
22 |
23 | engine = sqlalchemy.create_engine(conn_str, echo=False, connect_args={'check_same_thread': False})
24 | DbSession.engine = engine
25 | DbSession.factory = sqlalchemy.orm.sessionmaker(bind=engine)
26 |
27 | SqlAlchemyBase.metadata.create_all(engine)
28 |
29 |
--------------------------------------------------------------------------------
/code/ex07_viewmodels/pypi_vm/data/downloads.py:
--------------------------------------------------------------------------------
1 | import datetime
2 | import sqlalchemy
3 | from pypi_vm.data.modelbase import SqlAlchemyBase
4 |
5 |
6 | class Download(SqlAlchemyBase):
7 | __tablename__ = 'downloads'
8 |
9 | id = sqlalchemy.Column(sqlalchemy.BigInteger, primary_key=True, autoincrement=True)
10 | created_date = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True)
11 |
12 | package_id = sqlalchemy.Column(sqlalchemy.String, index=True)
13 | release_id = sqlalchemy.Column(sqlalchemy.BigInteger, index=True)
14 |
15 | ip_address = sqlalchemy.Column(sqlalchemy.String)
16 | user_agent = sqlalchemy.Column(sqlalchemy.String)
17 |
--------------------------------------------------------------------------------
/code/ex07_viewmodels/pypi_vm/data/languages.py:
--------------------------------------------------------------------------------
1 | import datetime
2 | import sqlalchemy
3 | from pypi_vm.data.modelbase import SqlAlchemyBase
4 |
5 |
6 | class ProgrammingLanguage(SqlAlchemyBase):
7 | __tablename__ = 'languages'
8 |
9 | id = sqlalchemy.Column(sqlalchemy.String, primary_key=True)
10 | created_date = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True)
11 | description = sqlalchemy.Column(sqlalchemy.String)
12 |
--------------------------------------------------------------------------------
/code/ex07_viewmodels/pypi_vm/data/maintainers.py:
--------------------------------------------------------------------------------
1 | import datetime
2 |
3 | import sqlalchemy
4 | from pypi_vm.data.modelbase import SqlAlchemyBase
5 |
6 |
7 | class Maintainer(SqlAlchemyBase):
8 | __tablename__ = 'maintainers'
9 |
10 | user_id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True)
11 | package_id = sqlalchemy.Column(sqlalchemy.String, primary_key=True)
12 | # date_added = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now)
13 |
--------------------------------------------------------------------------------
/code/ex07_viewmodels/pypi_vm/data/modelbase.py:
--------------------------------------------------------------------------------
1 | import sqlalchemy.ext.declarative as dec
2 |
3 | SqlAlchemyBase = dec.declarative_base()
4 |
--------------------------------------------------------------------------------
/code/ex07_viewmodels/pypi_vm/data/users.py:
--------------------------------------------------------------------------------
1 | import datetime
2 | import sqlalchemy
3 | from pypi_vm.data.modelbase import SqlAlchemyBase
4 |
5 |
6 | class User(SqlAlchemyBase):
7 | __tablename__ = 'users'
8 |
9 | id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True, autoincrement=True)
10 | name = sqlalchemy.Column(sqlalchemy.String, nullable=True)
11 | email = sqlalchemy.Column(sqlalchemy.String, index=True, nullable=True)
12 | hashed_password = sqlalchemy.Column(sqlalchemy.String, nullable=True, index=True)
13 | created_date = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True)
14 | profile_image_url = sqlalchemy.Column(sqlalchemy.String)
15 | last_login = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True)
16 |
--------------------------------------------------------------------------------
/code/ex07_viewmodels/pypi_vm/db/pypi.sqlite:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeckennedy/ten-tips-python-web-devs/e2406853a3d2e1d02ca5b00f68ae510993d4ad19/code/ex07_viewmodels/pypi_vm/db/pypi.sqlite
--------------------------------------------------------------------------------
/code/ex07_viewmodels/pypi_vm/infrastructure/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeckennedy/ten-tips-python-web-devs/e2406853a3d2e1d02ca5b00f68ae510993d4ad19/code/ex07_viewmodels/pypi_vm/infrastructure/__init__.py
--------------------------------------------------------------------------------
/code/ex07_viewmodels/pypi_vm/infrastructure/number_utils.py:
--------------------------------------------------------------------------------
1 | from typing import Optional
2 |
3 |
4 | def try_int(text: str) -> Optional[int]:
5 | try:
6 | return int(text)
7 | except:
8 | return None
9 |
--------------------------------------------------------------------------------
/code/ex07_viewmodels/pypi_vm/infrastructure/request_dict.py:
--------------------------------------------------------------------------------
1 | from flask import Request
2 |
3 |
4 | class RequestDictionary(dict):
5 | def __getattr__(self, key):
6 | return self.get(key)
7 |
8 |
9 | def create(request: Request, **route_args) -> RequestDictionary:
10 | data = {
11 | **request.args, # The key/value pairs in the URL query string
12 | **request.headers, # Header values
13 | **request.form, # The key/value pairs in the body, from a HTML post form
14 | **route_args # And additional arguments the method access, if they want them merged.
15 | }
16 |
17 | return RequestDictionary(data)
18 |
--------------------------------------------------------------------------------
/code/ex07_viewmodels/pypi_vm/services/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeckennedy/ten-tips-python-web-devs/e2406853a3d2e1d02ca5b00f68ae510993d4ad19/code/ex07_viewmodels/pypi_vm/services/__init__.py
--------------------------------------------------------------------------------
/code/ex07_viewmodels/pypi_vm/static/css/account.css:
--------------------------------------------------------------------------------
1 |
2 | form.account-form {
3 | margin-top: 50px;
4 | margin-left: auto;
5 | margin-right: auto;
6 | width: 500px;
7 | background-color: #ddd;
8 | color: #222;
9 | border: 1px solid gray;
10 | border-radius: 5px;
11 | text-align: center;
12 | }
13 |
14 | form.account-form h1 {
15 | text-align: center;
16 | }
17 |
18 | form.account-form > * {
19 | margin-top: 5px;
20 | margin-bottom: 5px;
21 | }
22 |
23 | form.account-form input.form-control {
24 | max-width: 95%;
25 | display: inline-block;
26 | }
27 |
28 | form.account-form button {
29 | margin-left: 350px;
30 |
31 | }
32 |
33 | .starter-template .content.account-home {
34 | margin-left: auto;
35 | margin-right: auto;
36 | max-width: 80%;
37 | }
38 |
39 |
--------------------------------------------------------------------------------
/code/ex07_viewmodels/pypi_vm/static/css/home.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeckennedy/ten-tips-python-web-devs/e2406853a3d2e1d02ca5b00f68ae510993d4ad19/code/ex07_viewmodels/pypi_vm/static/css/home.css
--------------------------------------------------------------------------------
/code/ex07_viewmodels/pypi_vm/static/img/blue-cube.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/code/ex07_viewmodels/pypi_vm/static/img/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeckennedy/ten-tips-python-web-devs/e2406853a3d2e1d02ca5b00f68ae510993d4ad19/code/ex07_viewmodels/pypi_vm/static/img/favicon.png
--------------------------------------------------------------------------------
/code/ex07_viewmodels/pypi_vm/static/img/white-cube.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/code/ex07_viewmodels/pypi_vm/templates/account/index.html:
--------------------------------------------------------------------------------
1 | {% extends "shared/_layout.html" %}
2 | {% block content %}
3 |
4 |
5 |
Account
6 |
7 | Welcome to your account {{ user.name }}!
8 |
9 |
10 |
11 | {% endblock %}
12 |
13 |
14 | {% block additional_css %}
15 |
16 | {% endblock %}
--------------------------------------------------------------------------------
/code/ex07_viewmodels/pypi_vm/templates/cms/page.html:
--------------------------------------------------------------------------------
1 | {% extends "shared/_layout.html" %}
2 | {% block content %}
3 |
4 |
{{ page.page_title }}
5 |
6 | {{ page.page_details }}
7 |
8 |
9 |
10 | {% endblock %}
--------------------------------------------------------------------------------
/code/ex07_viewmodels/pypi_vm/templates/packages/popular.html:
--------------------------------------------------------------------------------
1 | {% extends "shared/_layout.html" %}
2 | {% block content %}
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | {{ package_name }}
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | {% endblock %}
23 |
--------------------------------------------------------------------------------
/code/ex07_viewmodels/pypi_vm/templates/seo/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow:
3 |
--------------------------------------------------------------------------------
/code/ex07_viewmodels/pypi_vm/viewmodels/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeckennedy/ten-tips-python-web-devs/e2406853a3d2e1d02ca5b00f68ae510993d4ad19/code/ex07_viewmodels/pypi_vm/viewmodels/__init__.py
--------------------------------------------------------------------------------
/code/ex07_viewmodels/pypi_vm/viewmodels/account/account_home_viewmodel.py:
--------------------------------------------------------------------------------
1 | from pypi_vm.services import user_service
2 | from pypi_vm.viewmodels.shared.viewmodel_base import ViewModelBase
3 |
4 |
5 | class AccountHomeViewModel(ViewModelBase):
6 | def __init__(self):
7 | super().__init__()
8 |
9 | self.user = user_service.find_user_by_id(self.user_id)
10 |
--------------------------------------------------------------------------------
/code/ex07_viewmodels/pypi_vm/viewmodels/cms/page_viewmodel.py:
--------------------------------------------------------------------------------
1 | from pypi_vm.viewmodels.shared.viewmodel_base import ViewModelBase
2 |
3 | fake_db = {
4 | '/company/history': {
5 | 'page_title': 'Company history',
6 | 'page_details': 'Details about company history...',
7 | },
8 | '/company/employees': {
9 | 'page_title': 'Our team',
10 | 'page_details': 'Details about company employees ...',
11 | },
12 | }
13 |
14 |
15 | class PageViewModel(ViewModelBase):
16 | def __init__(self, sub_path: str):
17 | super().__init__()
18 |
19 | self.sub_path = sub_path
20 | self.sub_url = None
21 | if self.sub_path:
22 | self.sub_url = '/' + self.sub_path.lstrip('/')
23 |
24 | self.page = fake_db.get(self.sub_url)
25 |
--------------------------------------------------------------------------------
/code/ex07_viewmodels/pypi_vm/viewmodels/home/home_index_viewmodel.py:
--------------------------------------------------------------------------------
1 | from pypi_vm.services import user_service, package_service
2 | from pypi_vm.viewmodels.shared.viewmodel_base import ViewModelBase
3 |
4 |
5 | class HomeIndexViewModel(ViewModelBase):
6 | def __init__(self):
7 | super().__init__()
8 |
9 | self.packages = package_service.latest_releases()
10 | self.package_count = package_service.package_count()
11 | self.release_count = package_service.release_count()
12 | self.user_count = user_service.user_count()
13 |
--------------------------------------------------------------------------------
/code/ex07_viewmodels/pypi_vm/viewmodels/packages/popular_viewmodel.py:
--------------------------------------------------------------------------------
1 | from pypi_vm.viewmodels.shared.viewmodel_base import ViewModelBase
2 |
3 |
4 | class PopularPackageViewModel(ViewModelBase):
5 | def __init__(self, num: int):
6 | super().__init__()
7 | self.num = num
8 | self.package_name = "The {}th most popular package".format(self.num)
9 |
--------------------------------------------------------------------------------
/code/ex07_viewmodels/pypi_vm/viewmodels/shared/viewmodel_base.py:
--------------------------------------------------------------------------------
1 | from typing import Optional, Any
2 |
3 | import flask
4 | from flask import Request
5 |
6 | from pypi_vm.infrastructure import request_dict, cookie_auth
7 |
8 |
9 | class ViewModelBase:
10 | def __init__(self):
11 | self.request: Request = flask.request
12 | self.request_dict = request_dict.create(self.request)
13 | self.error: Optional[str] = None
14 | self.user_id: int = cookie_auth.get_user_id_via_auth_cookie(self.request)
15 | self.name = "VM Name"
16 | self.stringify = self.stringify_func
17 |
18 | def to_dict(self):
19 | return self.__dict__
20 |
21 | @staticmethod
22 | def stringify_func(item: Optional[Any]) -> str:
23 | if not item:
24 | return ''
25 |
26 | return str(item)
27 |
--------------------------------------------------------------------------------
/code/ex07_viewmodels/pypi_vm/viewmodels/utils/sitemap_viewmodel.py:
--------------------------------------------------------------------------------
1 | import flask
2 |
3 | from pypi_vm.services import package_service
4 | from pypi_vm.viewmodels.shared.viewmodel_base import ViewModelBase
5 |
6 |
7 | class SiteMapViewModel(ViewModelBase):
8 | def __init__(self, limit: int):
9 | super().__init__()
10 | self.packages = package_service.all_packages(limit)
11 | self.last_updated_text = "2018-07-15"
12 | self.site = "{}://{}".format(flask.request.scheme, flask.request.host)
13 |
--------------------------------------------------------------------------------
/code/ex07_viewmodels/pypi_vm/views/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeckennedy/ten-tips-python-web-devs/e2406853a3d2e1d02ca5b00f68ae510993d4ad19/code/ex07_viewmodels/pypi_vm/views/__init__.py
--------------------------------------------------------------------------------
/code/ex07_viewmodels/pypi_vm/views/cms_view.py:
--------------------------------------------------------------------------------
1 | import flask
2 |
3 | from pypi_vm.infrastructure.view_modifiers import response
4 | from pypi_vm.viewmodels.cms.page_viewmodel import PageViewModel
5 |
6 | blueprint = flask.Blueprint('cms', __name__, template_folder='templates')
7 |
8 |
9 | @blueprint.route('/')
10 | @response(template_file='cms/page.html')
11 | def cms_page(full_url: str):
12 | vm = PageViewModel(full_url)
13 | if not vm.page:
14 | flask.abort(status=404)
15 |
16 | return vm.to_dict()
17 |
--------------------------------------------------------------------------------
/code/ex07_viewmodels/pypi_vm/views/home_view.py:
--------------------------------------------------------------------------------
1 | import flask
2 |
3 | from pypi_vm.infrastructure.view_modifiers import response
4 | from pypi_vm.viewmodels.home.home_index_viewmodel import HomeIndexViewModel
5 |
6 | blueprint = flask.Blueprint('home', __name__, template_folder='templates')
7 |
8 |
9 | @blueprint.route('/')
10 | @response(template_file='home/index.html')
11 | def index():
12 | vm = HomeIndexViewModel()
13 | return vm.to_dict()
14 |
--------------------------------------------------------------------------------
/code/ex07_viewmodels/pypi_vm/views/seo_view.py:
--------------------------------------------------------------------------------
1 | import flask
2 |
3 | from pypi_vm.infrastructure.view_modifiers import response
4 | from pypi_vm.viewmodels.utils.sitemap_viewmodel import SiteMapViewModel
5 |
6 | blueprint = flask.Blueprint('seo', __name__, template_folder='templates')
7 |
8 |
9 | # ################### Sitemap #################################
10 |
11 |
12 | @blueprint.route('/sitemap.xml')
13 | @response(mimetype='application/xml', template_file='seo/sitemap.html')
14 | def sitemap():
15 | vm = SiteMapViewModel(1000)
16 | return vm.to_dict()
17 |
18 |
19 | # ################### Robots #################################
20 |
21 | @blueprint.route('/robots.txt')
22 | @response(mimetype='text/plain', template_file='seo/robots.txt')
23 | def robots():
24 | return {}
25 |
--------------------------------------------------------------------------------
/code/ex07_viewmodels/server/pypi.nginx:
--------------------------------------------------------------------------------
1 | server {
2 | listen 80;
3 | server_name fake_pypi.com
4 | server_tokens off;
5 | charset utf-8;
6 | client_max_body_size 150M;
7 |
8 | location /static {
9 | gzip on;
10 | gzip_buffers 8 256k;
11 | uwsgi_buffers 8 256k;
12 |
13 | alias /apps/appcode/demo_apps/pypi/pypi_org/static;
14 | expires 365d;
15 | }
16 | location / {
17 | try_files $uri @yourapplication;
18 | }
19 | location @yourapplication {
20 | include uwsgi_params;
21 |
22 | gzip on;
23 | gzip_buffers 8 256k;
24 | uwsgi_buffers 8 256k;
25 | uwsgi_read_timeout 300;
26 |
27 | proxy_pass http://127.0.0.1:5000;
28 | proxy_set_header Host $host;
29 | proxy_set_header X-Real-IP $remote_addr;
30 | proxy_set_header X-Forwarded-Protocol $scheme;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/code/ex07_viewmodels/server/pypi.service:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=uWSGI PyPI server instance
3 | After=syslog.target
4 |
5 | [Service]
6 | ExecStart=/apps/venv/bin/uwsgi -H /apps/venv --master --processes 4 --threads 2 --http :5000 --manage-script-name --mount /pypi_org=pypi_org.app:app
7 | RuntimeDirectory=/apps/appcode/demo_apps/pypi/pypi_org/
8 | Restart=always
9 | KillSignal=SIGQUIT
10 | Type=notify
11 | StandardError=syslog
12 | NotifyAccess=all
13 |
14 | [Install]
15 | WantedBy=multi-user.target
--------------------------------------------------------------------------------
/code/ex07_viewmodels/setup.py:
--------------------------------------------------------------------------------
1 | from setuptools import setup
2 |
3 | setup(
4 | name='pypi_vm',
5 | version='1.0.0.0',
6 | package_dir={'pypi_vm': 'pypi_vm'},
7 | url='',
8 | license='',
9 | author='Michael Kennedy',
10 | author_email='',
11 | description=''
12 | )
13 |
--------------------------------------------------------------------------------
/code/ex07_viewmodels/tests/_all_tests.py:
--------------------------------------------------------------------------------
1 | # noinspection PyUnresolvedReferences
2 | from account_tests import *
3 | # noinspection PyUnresolvedReferences
4 | from package_tests import *
5 | # noinspection PyUnresolvedReferences
6 | from sitemap_tests import *
7 | # noinspection PyUnresolvedReferences
8 | from home_tests import *
9 |
--------------------------------------------------------------------------------
/code/ex07_viewmodels/tests/commands.txt:
--------------------------------------------------------------------------------
1 | Run without warnings:
2 |
3 | -p no:warnings
4 |
5 |
6 |
7 | pytest /Users/mkennedy/github/talk-python/courses/data-driven-web/flask-materials/demo_apps/pypi/tests/_all_tests.py -p no:warnings
8 | pytest tests/_all_tests.py -p no:warnings
--------------------------------------------------------------------------------
/code/ex07_viewmodels/tests/home_tests.py:
--------------------------------------------------------------------------------
1 | from flask import Response
2 |
3 | from test_client import client, flask_app
4 | from views import home_view
5 |
6 |
7 | def test_homepage(client):
8 | r: Response = client.get('/')
9 | assert r.status_code == 200
10 | assert b'Find, install and publish Python packages' in r.data
11 |
12 |
13 | def test_homepage_directly():
14 | with flask_app.app.test_request_context(path='/'):
15 | r: Response = home_view.index()
16 |
17 | assert r.status_code == 200
18 | # noinspection PyUnresolvedReferences
19 | assert len(r.model.get('packages')) > 0
20 |
--------------------------------------------------------------------------------
/code/ex07_viewmodels/tests/test_client.py:
--------------------------------------------------------------------------------
1 | # noinspection PyPackageRequirements
2 | import pytest
3 |
4 | import sys
5 | import os
6 |
7 | container_folder = os.path.abspath(os.path.join(
8 | os.path.dirname(__file__), '..'
9 | ))
10 | sys.path.append(container_folder)
11 |
12 | from pypi_vm import app as flask_app
13 |
14 |
15 | @pytest.fixture
16 | def client():
17 | flask_app.app.config['TESTING'] = True
18 | client = flask_app.app.test_client()
19 |
20 | flask_app.register_blueprints()
21 | flask_app.init_db()
22 | client.post()
23 |
24 | yield client
25 |
--------------------------------------------------------------------------------
/code/ex08_docker/base_server/dockerfile:
--------------------------------------------------------------------------------
1 | FROM ubuntu:latest
2 |
3 | RUN apt-get update && apt-get upgrade -y
4 | ENV TZ=America/Los_Angeles
5 | RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
6 | RUN apt-get install -y -q sudo
7 | RUN apt-get install -y -q fail2ban
8 | RUN apt-get install -y -q httpie
9 | RUN apt-get install -y -q glances
10 |
--------------------------------------------------------------------------------
/code/ex08_docker/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3"
2 | services:
3 | base_server:
4 | build: ./base_server/
5 | image: base_server:latest
6 | frontend:
7 | build: ./frontend/
8 | command: nginx -g "daemon off;"
9 | depends_on:
10 | - services
11 | - base_server
12 | ports:
13 | - "80:80"
14 | services:
15 | build: ./services/
16 | command: /venv/bin/python /app/app.py
17 | depends_on:
18 | - base_server
19 | ports:
20 | - "7007:7007"
21 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/dockerfile:
--------------------------------------------------------------------------------
1 | FROM base_server:latest
2 |
3 | RUN apt-get install -y -q nginx
4 | RUN rm /etc/nginx/sites-enabled/default
5 | COPY site.nginx /etc/nginx/sites-enabled/site.nginx
6 | COPY movie_exploder /app
7 |
8 | ENTRYPOINT nginx -g "daemon off;"
9 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/js/dropdown.js:
--------------------------------------------------------------------------------
1 | /* https://freefrontend.com/css-select-boxes/ */
2 |
3 | let el = {};
4 |
5 | $('.placeholder').on('click', function (ev) {
6 | $('.placeholder').css('opacity', '0');
7 | $('.list__ul').toggle();
8 | });
9 |
10 | $('.list__ul a').on('click', function (ev) {
11 | ev.preventDefault();
12 | var index = $(this).parent().index();
13 |
14 | $('.placeholder').text($(this).text()).css('opacity', '1');
15 |
16 | console.log($('.list__ul').find('li').eq(index).html());
17 |
18 | $('.list__ul').find('li').eq(index).prependTo('.list__ul');
19 | $('.list__ul').toggle();
20 |
21 | });
22 |
23 |
24 | $('select').on('change', function (e) {
25 |
26 | // Set text on placeholder hidden element
27 | $('.placeholder').text(this.value);
28 |
29 | // Animate select width as placeholder
30 | $(this).animate({width: $('.placeholder').width() + 'px'});
31 |
32 | });
33 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/js/vue/vue.common.js:
--------------------------------------------------------------------------------
1 | if (process.env.NODE_ENV === 'production') {
2 | module.exports = require('./vue.common.prod.js')
3 | } else {
4 | module.exports = require('./vue.common.dev.js')
5 | }
6 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/js/vue/vue.runtime.common.js:
--------------------------------------------------------------------------------
1 | if (process.env.NODE_ENV === 'production') {
2 | module.exports = require('./vue.runtime.common.prod.js')
3 | } else {
4 | module.exports = require('./vue.runtime.common.dev.js')
5 | }
6 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/compiler/directives/bind.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | export default function bind (el: ASTElement, dir: ASTDirective) {
4 | el.wrapData = (code: string) => {
5 | return `_b(${code},'${el.tag}',${dir.value},${
6 | dir.modifiers && dir.modifiers.prop ? 'true' : 'false'
7 | }${
8 | dir.modifiers && dir.modifiers.sync ? ',true' : ''
9 | })`
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/compiler/directives/index.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import on from './on'
4 | import bind from './bind'
5 | import { noop } from 'shared/util'
6 |
7 | export default {
8 | on,
9 | bind,
10 | cloak: noop
11 | }
12 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/compiler/directives/on.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { warn } from 'core/util/index'
4 |
5 | export default function on (el: ASTElement, dir: ASTDirective) {
6 | if (process.env.NODE_ENV !== 'production' && dir.modifiers) {
7 | warn(`v-on without argument does not support modifiers.`)
8 | }
9 | el.wrapListeners = (code: string) => `_g(${code},${dir.value})`
10 | }
11 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/compiler/index.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { parse } from './parser/index'
4 | import { optimize } from './optimizer'
5 | import { generate } from './codegen/index'
6 | import { createCompilerCreator } from './create-compiler'
7 |
8 | // `createCompilerCreator` allows creating compilers that use alternative
9 | // parser/optimizer/codegen, e.g the SSR optimizing compiler.
10 | // Here we just export a default compiler using the default parts.
11 | export const createCompiler = createCompilerCreator(function baseCompile (
12 | template: string,
13 | options: CompilerOptions
14 | ): CompiledResult {
15 | const ast = parse(template.trim(), options)
16 | if (options.optimize !== false) {
17 | optimize(ast, options)
18 | }
19 | const code = generate(ast, options)
20 | return {
21 | ast,
22 | render: code.render,
23 | staticRenderFns: code.staticRenderFns
24 | }
25 | })
26 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/compiler/parser/entity-decoder.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | let decoder
4 |
5 | export default {
6 | decode (html: string): string {
7 | decoder = decoder || document.createElement('div')
8 | decoder.innerHTML = html
9 | return decoder.textContent
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/core/components/index.js:
--------------------------------------------------------------------------------
1 | import KeepAlive from './keep-alive'
2 |
3 | export default {
4 | KeepAlive
5 | }
6 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/core/global-api/mixin.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { mergeOptions } from '../util/index'
4 |
5 | export function initMixin (Vue: GlobalAPI) {
6 | Vue.mixin = function (mixin: Object) {
7 | this.options = mergeOptions(this.options, mixin)
8 | return this
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/core/global-api/use.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { toArray } from '../util/index'
4 |
5 | export function initUse (Vue: GlobalAPI) {
6 | Vue.use = function (plugin: Function | Object) {
7 | const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
8 | if (installedPlugins.indexOf(plugin) > -1) {
9 | return this
10 | }
11 |
12 | // additional parameters
13 | const args = toArray(arguments, 1)
14 | args.unshift(this)
15 | if (typeof plugin.install === 'function') {
16 | plugin.install.apply(plugin, args)
17 | } else if (typeof plugin === 'function') {
18 | plugin.apply(null, args)
19 | }
20 | installedPlugins.push(plugin)
21 | return this
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/core/index.js:
--------------------------------------------------------------------------------
1 | import Vue from './instance/index'
2 | import { initGlobalAPI } from './global-api/index'
3 | import { isServerRendering } from 'core/util/env'
4 | import { FunctionalRenderContext } from 'core/vdom/create-functional-component'
5 |
6 | initGlobalAPI(Vue)
7 |
8 | Object.defineProperty(Vue.prototype, '$isServer', {
9 | get: isServerRendering
10 | })
11 |
12 | Object.defineProperty(Vue.prototype, '$ssrContext', {
13 | get () {
14 | /* istanbul ignore next */
15 | return this.$vnode && this.$vnode.ssrContext
16 | }
17 | })
18 |
19 | // expose FunctionalRenderContext for ssr runtime helper installation
20 | Object.defineProperty(Vue, 'FunctionalRenderContext', {
21 | value: FunctionalRenderContext
22 | })
23 |
24 | Vue.version = '__VERSION__'
25 |
26 | export default Vue
27 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/core/util/index.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | export * from 'shared/util'
4 | export * from './lang'
5 | export * from './env'
6 | export * from './options'
7 | export * from './debug'
8 | export * from './props'
9 | export * from './error'
10 | export * from './next-tick'
11 | export { defineReactive } from '../observer/index'
12 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/core/util/perf.js:
--------------------------------------------------------------------------------
1 | import { inBrowser } from './env'
2 |
3 | export let mark
4 | export let measure
5 |
6 | if (process.env.NODE_ENV !== 'production') {
7 | const perf = inBrowser && window.performance
8 | /* istanbul ignore if */
9 | if (
10 | perf &&
11 | perf.mark &&
12 | perf.measure &&
13 | perf.clearMarks &&
14 | perf.clearMeasures
15 | ) {
16 | mark = tag => perf.mark(tag)
17 | measure = (name, startTag, endTag) => {
18 | perf.measure(name, startTag, endTag)
19 | perf.clearMarks(startTag)
20 | perf.clearMarks(endTag)
21 | // perf.clearMeasures(name)
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/core/vdom/helpers/get-first-component-child.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { isDef } from 'shared/util'
4 | import { isAsyncPlaceholder } from './is-async-placeholder'
5 |
6 | export function getFirstComponentChild (children: ?Array): ?VNode {
7 | if (Array.isArray(children)) {
8 | for (let i = 0; i < children.length; i++) {
9 | const c = children[i]
10 | if (isDef(c) && (isDef(c.componentOptions) || isAsyncPlaceholder(c))) {
11 | return c
12 | }
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/core/vdom/helpers/index.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | export * from './merge-hook'
4 | export * from './extract-props'
5 | export * from './update-listeners'
6 | export * from './normalize-children'
7 | export * from './resolve-async-component'
8 | export * from './get-first-component-child'
9 | export * from './is-async-placeholder'
10 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/core/vdom/helpers/is-async-placeholder.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | export function isAsyncPlaceholder (node: VNode): boolean {
4 | return node.isComment && node.asyncFactory
5 | }
6 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/core/vdom/modules/index.js:
--------------------------------------------------------------------------------
1 | import directives from './directives'
2 | import ref from './ref'
3 |
4 | export default [
5 | ref,
6 | directives
7 | ]
8 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/platforms/web/compiler/directives/html.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { addProp } from 'compiler/helpers'
4 |
5 | export default function html (el: ASTElement, dir: ASTDirective) {
6 | if (dir.value) {
7 | addProp(el, 'innerHTML', `_s(${dir.value})`, dir)
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/platforms/web/compiler/directives/index.js:
--------------------------------------------------------------------------------
1 | import model from './model'
2 | import text from './text'
3 | import html from './html'
4 |
5 | export default {
6 | model,
7 | text,
8 | html
9 | }
10 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/platforms/web/compiler/directives/text.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { addProp } from 'compiler/helpers'
4 |
5 | export default function text (el: ASTElement, dir: ASTDirective) {
6 | if (dir.value) {
7 | addProp(el, 'textContent', `_s(${dir.value})`, dir)
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/platforms/web/compiler/index.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { baseOptions } from './options'
4 | import { createCompiler } from 'compiler/index'
5 |
6 | const { compile, compileToFunctions } = createCompiler(baseOptions)
7 |
8 | export { compile, compileToFunctions }
9 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/platforms/web/compiler/modules/index.js:
--------------------------------------------------------------------------------
1 | import klass from './class'
2 | import style from './style'
3 | import model from './model'
4 |
5 | export default [
6 | klass,
7 | style,
8 | model
9 | ]
10 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/platforms/web/compiler/options.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import {
4 | isPreTag,
5 | mustUseProp,
6 | isReservedTag,
7 | getTagNamespace
8 | } from '../util/index'
9 |
10 | import modules from './modules/index'
11 | import directives from './directives/index'
12 | import { genStaticKeys } from 'shared/util'
13 | import { isUnaryTag, canBeLeftOpenTag } from './util'
14 |
15 | export const baseOptions: CompilerOptions = {
16 | expectHTML: true,
17 | modules,
18 | directives,
19 | isPreTag,
20 | isUnaryTag,
21 | mustUseProp,
22 | canBeLeftOpenTag,
23 | isReservedTag,
24 | getTagNamespace,
25 | staticKeys: genStaticKeys(modules)
26 | }
27 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/platforms/web/entry-compiler.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | export { parseComponent } from 'sfc/parser'
4 | export { compile, compileToFunctions } from './compiler/index'
5 | export { ssrCompile, ssrCompileToFunctions } from './server/compiler'
6 | export { generateCodeFrame } from 'compiler/codeframe'
7 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/platforms/web/entry-runtime.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import Vue from './runtime/index'
4 |
5 | export default Vue
6 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/platforms/web/entry-server-basic-renderer.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import modules from './server/modules/index'
4 | import directives from './server/directives/index'
5 | import { isUnaryTag, canBeLeftOpenTag } from './compiler/util'
6 | import { createBasicRenderer } from 'server/create-basic-renderer'
7 |
8 | export default createBasicRenderer({
9 | modules,
10 | directives,
11 | isUnaryTag,
12 | canBeLeftOpenTag
13 | })
14 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/platforms/web/runtime/components/index.js:
--------------------------------------------------------------------------------
1 | import Transition from './transition'
2 | import TransitionGroup from './transition-group'
3 |
4 | export default {
5 | Transition,
6 | TransitionGroup
7 | }
8 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/platforms/web/runtime/directives/index.js:
--------------------------------------------------------------------------------
1 | import model from './model'
2 | import show from './show'
3 |
4 | export default {
5 | model,
6 | show
7 | }
8 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/platforms/web/runtime/modules/index.js:
--------------------------------------------------------------------------------
1 | import attrs from './attrs'
2 | import klass from './class'
3 | import events from './events'
4 | import domProps from './dom-props'
5 | import style from './style'
6 | import transition from './transition'
7 |
8 | export default [
9 | attrs,
10 | klass,
11 | events,
12 | domProps,
13 | style,
14 | transition
15 | ]
16 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/platforms/web/runtime/patch.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import * as nodeOps from 'web/runtime/node-ops'
4 | import { createPatchFunction } from 'core/vdom/patch'
5 | import baseModules from 'core/vdom/modules/index'
6 | import platformModules from 'web/runtime/modules/index'
7 |
8 | // the directive module should be applied last, after all
9 | // built-in modules have been applied.
10 | const modules = platformModules.concat(baseModules)
11 |
12 | export const patch: Function = createPatchFunction({ nodeOps, modules })
13 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/platforms/web/server/compiler.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { baseOptions } from '../compiler/options'
4 | import { createCompiler } from 'server/optimizing-compiler/index'
5 |
6 | const { compile, compileToFunctions } = createCompiler(baseOptions)
7 |
8 | export {
9 | compile as ssrCompile,
10 | compileToFunctions as ssrCompileToFunctions
11 | }
12 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/platforms/web/server/directives/index.js:
--------------------------------------------------------------------------------
1 | import show from './show'
2 | import model from './model'
3 |
4 | export default {
5 | show,
6 | model
7 | }
8 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/platforms/web/server/directives/show.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | export default function show (node: VNodeWithData, dir: VNodeDirective) {
4 | if (!dir.value) {
5 | const style: any = node.data.style || (node.data.style = {})
6 | if (Array.isArray(style)) {
7 | style.push({ display: 'none' })
8 | } else {
9 | style.display = 'none'
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/platforms/web/server/modules/class.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { escape } from '../util'
4 | import { genClassForVnode } from 'web/util/index'
5 |
6 | export default function renderClass (node: VNodeWithData): ?string {
7 | const classList = genClassForVnode(node)
8 | if (classList !== '') {
9 | return ` class="${escape(classList)}"`
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/platforms/web/server/modules/index.js:
--------------------------------------------------------------------------------
1 | import attrs from './attrs'
2 | import domProps from './dom-props'
3 | import klass from './class'
4 | import style from './style'
5 |
6 | export default [
7 | attrs,
8 | domProps,
9 | klass,
10 | style
11 | ]
12 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/platforms/web/util/compat.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { inBrowser } from 'core/util/index'
4 |
5 | // check whether current browser encodes a char inside attribute values
6 | let div
7 | function getShouldDecode (href: boolean): boolean {
8 | div = div || document.createElement('div')
9 | div.innerHTML = href ? `` : ``
10 | return div.innerHTML.indexOf('
') > 0
11 | }
12 |
13 | // #3663: IE encodes newlines inside attribute values while other browsers don't
14 | export const shouldDecodeNewlines = inBrowser ? getShouldDecode(false) : false
15 | // #6828: chrome encodes content in a[href]
16 | export const shouldDecodeNewlinesForHref = inBrowser ? getShouldDecode(true) : false
17 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/platforms/web/util/index.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { warn } from 'core/util/index'
4 |
5 | export * from './attrs'
6 | export * from './class'
7 | export * from './element'
8 |
9 | /**
10 | * Query an element selector if it's not an element already.
11 | */
12 | export function query (el: string | Element): Element {
13 | if (typeof el === 'string') {
14 | const selected = document.querySelector(el)
15 | if (!selected) {
16 | process.env.NODE_ENV !== 'production' && warn(
17 | 'Cannot find element: ' + el
18 | )
19 | return document.createElement('div')
20 | }
21 | return selected
22 | } else {
23 | return el
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/platforms/weex/compiler/directives/index.js:
--------------------------------------------------------------------------------
1 | import model from './model'
2 |
3 | export default {
4 | model
5 | }
6 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/platforms/weex/compiler/modules/append.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { makeMap } from 'shared/util'
4 |
5 | // The "unitary tag" means that the tag node and its children
6 | // must be sent to the native together.
7 | const isUnitaryTag = makeMap('cell,header,cell-slot,recycle-list', true)
8 |
9 | function preTransformNode (el: ASTElement) {
10 | if (isUnitaryTag(el.tag) && !el.attrsList.some(item => item.name === 'append')) {
11 | el.attrsMap.append = 'tree'
12 | el.attrsList.push({ name: 'append', value: 'tree' })
13 | }
14 | if (el.attrsMap.append === 'tree') {
15 | el.appendAsTree = true
16 | }
17 | }
18 |
19 | function genData (el: ASTElement): string {
20 | return el.appendAsTree ? `appendAsTree:true,` : ''
21 | }
22 |
23 | export default {
24 | staticKeys: ['appendAsTree'],
25 | preTransformNode,
26 | genData
27 | }
28 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/platforms/weex/compiler/modules/index.js:
--------------------------------------------------------------------------------
1 | import klass from './class'
2 | import style from './style'
3 | import props from './props'
4 | import append from './append'
5 | import recycleList from './recycle-list/index'
6 |
7 | export default [
8 | recycleList,
9 | klass,
10 | style,
11 | props,
12 | append
13 | ]
14 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/component-root.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { addAttr } from 'compiler/helpers'
4 |
5 | // mark component root nodes as
6 | export function postTransformComponentRoot (el: ASTElement) {
7 | if (!el.parent) {
8 | // component root
9 | addAttr(el, '@isComponentRoot', 'true')
10 | addAttr(el, '@templateId', '_uid')
11 | addAttr(el, '@componentProps', '$props || {}')
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/component.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { addAttr } from 'compiler/helpers'
4 | import { RECYCLE_LIST_MARKER } from 'weex/util/index'
5 |
6 | // mark components as inside recycle-list so that we know we need to invoke
7 | // their special @render function instead of render in create-component.js
8 | export function postTransformComponent (
9 | el: ASTElement,
10 | options: WeexCompilerOptions
11 | ) {
12 | // $flow-disable-line (we know isReservedTag is there)
13 | if (!options.isReservedTag(el.tag) && el.tag !== 'cell-slot') {
14 | addAttr(el, RECYCLE_LIST_MARKER, 'true')
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/text.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { addAttr } from 'compiler/helpers'
4 |
5 | function genText (node: ASTNode) {
6 | const value = node.type === 3
7 | ? node.text
8 | : node.type === 2
9 | ? node.tokens.length === 1
10 | ? node.tokens[0]
11 | : node.tokens
12 | : ''
13 | return JSON.stringify(value)
14 | }
15 |
16 | export function postTransformText (el: ASTElement) {
17 | // weex can only contain text, so the parser
18 | // always generates a single child.
19 | if (el.children.length) {
20 | addAttr(el, 'value', genText(el.children[0]))
21 | el.children = []
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/v-bind.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { camelize } from 'shared/util'
4 | import { generateBinding } from 'weex/util/parser'
5 | import { bindRE } from 'compiler/parser/index'
6 | import { getAndRemoveAttr, addRawAttr } from 'compiler/helpers'
7 |
8 | function parseAttrName (name: string): string {
9 | return camelize(name.replace(bindRE, ''))
10 | }
11 |
12 | export function preTransformVBind (el: ASTElement) {
13 | for (const attr in el.attrsMap) {
14 | if (bindRE.test(attr)) {
15 | const name: string = parseAttrName(attr)
16 | const value = generateBinding(getAndRemoveAttr(el, attr))
17 | delete el.attrsMap[attr]
18 | addRawAttr(el, name, value)
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/v-on.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | const inlineStatementRE = /^\s*([A-Za-z_$0-9\['\."\]]+)*\s*\(\s*(([A-Za-z_$0-9\['\."\]]+)?(\s*,\s*([A-Za-z_$0-9\['\."\]]+))*)\s*\)$/
4 |
5 | function parseHandlerParams (handler: ASTElementHandler) {
6 | const res = inlineStatementRE.exec(handler.value)
7 | if (res && res[2]) {
8 | handler.params = res[2].split(/\s*,\s*/)
9 | }
10 | }
11 |
12 | export function postTransformVOn (el: ASTElement) {
13 | const events: ASTElementHandlers | void = el.events
14 | if (!events) {
15 | return
16 | }
17 | for (const name in events) {
18 | const handler: ASTElementHandler | Array = events[name]
19 | if (Array.isArray(handler)) {
20 | handler.map(fn => parseHandlerParams(fn))
21 | } else {
22 | parseHandlerParams(handler)
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/v-once.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { getAndRemoveAttr, addRawAttr } from 'compiler/helpers'
4 |
5 | function containVOnce (el: ASTElement): boolean {
6 | for (const attr in el.attrsMap) {
7 | if (/^v\-once$/i.test(attr)) {
8 | return true
9 | }
10 | }
11 | return false
12 | }
13 |
14 | export function preTransformVOnce (el: ASTElement) {
15 | if (containVOnce(el)) {
16 | getAndRemoveAttr(el, 'v-once', true)
17 | addRawAttr(el, '[[once]]', true)
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/platforms/weex/entry-compiler.js:
--------------------------------------------------------------------------------
1 | export { compile } from 'weex/compiler/index'
2 | export { generateCodeFrame } from 'compiler/codeframe'
3 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/platforms/weex/entry-runtime-factory.js:
--------------------------------------------------------------------------------
1 | // this entry is built and wrapped with a factory function
2 | // used to generate a fresh copy of Vue for every Weex instance.
3 |
4 | import Vue from './runtime/index'
5 |
6 | exports.Vue = Vue
7 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/platforms/weex/runtime/components/index.js:
--------------------------------------------------------------------------------
1 | import Richtext from './richtext'
2 | import Transition from './transition'
3 | import TransitionGroup from './transition-group'
4 |
5 | export default {
6 | Richtext,
7 | Transition,
8 | TransitionGroup
9 | }
10 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/platforms/weex/runtime/components/transition.js:
--------------------------------------------------------------------------------
1 | // reuse same transition component logic from web
2 | export {
3 | transitionProps,
4 | extractTransitionData
5 | } from 'web/runtime/components/transition'
6 |
7 | import Transition from 'web/runtime/components/transition'
8 |
9 | export default Transition
10 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/platforms/weex/runtime/directives/index.js:
--------------------------------------------------------------------------------
1 | export default {
2 | }
3 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/platforms/weex/runtime/modules/index.js:
--------------------------------------------------------------------------------
1 | import attrs from './attrs'
2 | import klass from './class'
3 | import events from './events'
4 | import style from './style'
5 | import transition from './transition'
6 |
7 | export default [
8 | attrs,
9 | klass,
10 | events,
11 | style,
12 | transition
13 | ]
14 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/platforms/weex/runtime/patch.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import * as nodeOps from 'weex/runtime/node-ops'
4 | import { createPatchFunction } from 'core/vdom/patch'
5 | import baseModules from 'core/vdom/modules/index'
6 | import platformModules from 'weex/runtime/modules/index'
7 |
8 | // the directive module should be applied last, after all
9 | // built-in modules have been applied.
10 | const modules = platformModules.concat(baseModules)
11 |
12 | export const patch: Function = createPatchFunction({
13 | nodeOps,
14 | modules,
15 | LONG_LIST_THRESHOLD: 10
16 | })
17 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/platforms/weex/runtime/text-node.js:
--------------------------------------------------------------------------------
1 | let latestNodeId = 1
2 |
3 | export default function TextNode (text) {
4 | this.instanceId = ''
5 | this.nodeId = latestNodeId++
6 | this.parentNode = null
7 | this.nodeType = 3
8 | this.text = text
9 | }
10 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/server/optimizing-compiler/index.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { parse } from 'compiler/parser/index'
4 | import { generate } from './codegen'
5 | import { optimize } from './optimizer'
6 | import { createCompilerCreator } from 'compiler/create-compiler'
7 |
8 | export const createCompiler = createCompilerCreator(function baseCompile (
9 | template: string,
10 | options: CompilerOptions
11 | ): CompiledResult {
12 | const ast = parse(template.trim(), options)
13 | optimize(ast, options)
14 | const code = generate(ast, options)
15 | return {
16 | ast,
17 | render: code.render,
18 | staticRenderFns: code.staticRenderFns
19 | }
20 | })
21 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/server/util.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | export const isJS = (file: string): boolean => /\.js(\?[^.]+)?$/.test(file)
4 |
5 | export const isCSS = (file: string): boolean => /\.css(\?[^.]+)?$/.test(file)
6 |
7 | export function createPromiseCallback () {
8 | let resolve, reject
9 | const promise: Promise = new Promise((_resolve, _reject) => {
10 | resolve = _resolve
11 | reject = _reject
12 | })
13 | const cb = (err: Error, res?: string) => {
14 | if (err) return reject(err)
15 | resolve(res || '')
16 | }
17 | return { promise, cb }
18 | }
19 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/src/shared/constants.js:
--------------------------------------------------------------------------------
1 | export const SSR_ATTR = 'data-server-rendered'
2 |
3 | export const ASSET_TYPES = [
4 | 'component',
5 | 'directive',
6 | 'filter'
7 | ]
8 |
9 | export const LIFECYCLE_HOOKS = [
10 | 'beforeCreate',
11 | 'created',
12 | 'beforeMount',
13 | 'mounted',
14 | 'beforeUpdate',
15 | 'updated',
16 | 'beforeDestroy',
17 | 'destroyed',
18 | 'activated',
19 | 'deactivated',
20 | 'errorCaptured',
21 | 'serverPrefetch'
22 | ]
23 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/types/index.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from "./vue";
2 |
3 | export default Vue;
4 |
5 | export as namespace Vue;
6 |
7 | export {
8 | CreateElement,
9 | VueConstructor
10 | } from "./vue";
11 |
12 | export {
13 | Component,
14 | AsyncComponent,
15 | ComponentOptions,
16 | FunctionalComponentOptions,
17 | RenderContext,
18 | PropType,
19 | PropOptions,
20 | ComputedOptions,
21 | WatchHandler,
22 | WatchOptions,
23 | WatchOptionsWithHandler,
24 | DirectiveFunction,
25 | DirectiveOptions
26 | } from "./options";
27 |
28 | export {
29 | PluginFunction,
30 | PluginObject
31 | } from "./plugin";
32 |
33 | export {
34 | VNodeChildren,
35 | VNodeChildrenArrayContents,
36 | VNode,
37 | VNodeComponentOptions,
38 | VNodeData,
39 | VNodeDirective
40 | } from "./vnode";
41 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/node_modules/vue/types/plugin.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue as _Vue } from "./vue";
2 |
3 | export type PluginFunction = (Vue: typeof _Vue, options?: T) => void;
4 |
5 | export interface PluginObject {
6 | install: PluginFunction;
7 | [key: string]: any;
8 | }
9 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "movie_exploder",
3 | "version": "1.0.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "vue": {
8 | "version": "2.6.3",
9 | "resolved": "https://registry.npmjs.org/vue/-/vue-2.6.3.tgz",
10 | "integrity": "sha512-yftjtahz4UTAtOlXXuw7UaYD86fWrMDAAzqTdqJJx2FIBqcPmBN6kPBHiBJFGaQELVblb5ijbFMXsx0i0F7q3g=="
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/movie_exploder/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "movie_exploder",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "dependencies": {
12 | "vue": "^2.6.3"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/code/ex08_docker/frontend/site.nginx:
--------------------------------------------------------------------------------
1 | server {
2 | listen 80;
3 | server_name movieexploder.com;
4 | server_tokens off;
5 | charset utf-8;
6 | client_max_body_size 150M;
7 |
8 | root /app;
9 |
10 | location /css {
11 | alias /app/css;
12 | # autoindex on;
13 | expires 365d;
14 | }
15 |
16 | location / {
17 | index /views/index.html;
18 | }
19 |
20 | location /js {
21 | alias /app/js;
22 | # autoindex on;
23 | expires 365d;
24 | }
25 | location /node_modules {
26 | alias /app/node_modules;
27 | # autoindex on;
28 | expires 365d;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/code/ex08_docker/services/dockerfile:
--------------------------------------------------------------------------------
1 | FROM base_server:latest
2 |
3 | RUN apt-get install -y -q build-essential git python3-pip python3-dev python3-venv
4 | RUN python3 -m venv /venv
5 | RUN /venv/bin/pip install -U pip setuptools
6 | RUN /venv/bin/pip install responder
7 |
8 | COPY movie_svc /app
9 | WORKDIR /app
10 | RUN /venv/bin/pip install -r /app/requirements.txt
11 |
12 | ENTRYPOINT /venv/bin/python /app/app.py
13 |
--------------------------------------------------------------------------------
/code/ex08_docker/services/movie_svc/app.py:
--------------------------------------------------------------------------------
1 | # noinspection PyUnresolvedReferences
2 | from app_instance import api
3 | from routes import *
4 | from data import db
5 |
6 | db.global_init()
7 |
8 |
9 | api.run(port=7007, address="0.0.0.0")
10 |
--------------------------------------------------------------------------------
/code/ex08_docker/services/movie_svc/app_instance.py:
--------------------------------------------------------------------------------
1 | import responder
2 |
3 | cors_params = {
4 | 'allow_origins': '*',
5 | 'allow_methods': '*',
6 | }
7 |
8 | api = responder.API(cors=True, cors_params=cors_params)
9 |
--------------------------------------------------------------------------------
/code/ex08_docker/services/movie_svc/requirements.txt:
--------------------------------------------------------------------------------
1 | responder
2 |
--------------------------------------------------------------------------------
/code/ex08_docker/services/movie_svc/routes.py:
--------------------------------------------------------------------------------
1 | # noinspection PyUnresolvedReferences
2 | from app_instance import api
3 | # noinspection PyUnresolvedReferences
4 | from views.api_views import *
5 | # noinspection PyUnresolvedReferences
6 | from views.home import *
7 |
8 | api.add_route("/static", static=True)
9 |
--------------------------------------------------------------------------------
/code/ex08_docker/services/movie_svc/static/css/docs.css:
--------------------------------------------------------------------------------
1 | .request {
2 | font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
3 | font-weight: bold;
4 | border: 1px solid gray;
5 | border-radius: 5px;
6 | padding: 10px;
7 | font-size: 24px;
8 | }
9 |
10 | .get {
11 | color: #2b542c;
12 | background-color: #beffbd;
13 | }
14 |
15 | .post {
16 | color: #ae5900;
17 | background-color: #ffc79d;
18 | }
19 |
20 | .response_formats span {
21 | font-weight: bold;
22 | color: darkred;
23 | font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
24 | }
25 |
26 | pre {
27 | font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
28 | }
29 |
30 | ul li {
31 | font-size: 18px;
32 | margin-bottom: 10px;
33 | }
--------------------------------------------------------------------------------
/code/ex08_docker/services/movie_svc/views/home.py:
--------------------------------------------------------------------------------
1 | from app_instance import api
2 |
3 |
4 | @api.route("/")
5 | def index(req, resp):
6 | resp.content = api.template('home/index.html')
7 |
--------------------------------------------------------------------------------
/code/ex09_lets_encrypt/make_secure.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # Steps:
4 | # https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-18-04
5 |
6 | add-apt-repository ppa:certbot/certbot -y
7 | apt update
8 | apt install python-certbot-nginx -y
9 |
10 | certbot --nginx -d billssltest.talkpython.com
11 |
12 | service nginx restart
--------------------------------------------------------------------------------
/code/ex10_securepy/pypi_secure/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeckennedy/ten-tips-python-web-devs/e2406853a3d2e1d02ca5b00f68ae510993d4ad19/code/ex10_securepy/pypi_secure/__init__.py
--------------------------------------------------------------------------------
/code/ex10_securepy/pypi_secure/data/__all_models.py:
--------------------------------------------------------------------------------
1 | # Add all your SQLAlchemy models here.
2 | # This allows us to import just this file when
3 | # we need to preload the models and ensure they
4 | # are all loaded.
5 |
6 | # noinspection PyUnresolvedReferences
7 | import pypi_secure.data.downloads
8 | # noinspection PyUnresolvedReferences
9 | import pypi_secure.data.languages
10 | # noinspection PyUnresolvedReferences
11 | import pypi_secure.data.licenses
12 | # noinspection PyUnresolvedReferences
13 | import pypi_secure.data.maintainers
14 | # noinspection PyUnresolvedReferences
15 | import pypi_secure.data.package
16 | # noinspection PyUnresolvedReferences
17 | import pypi_secure.data.releases
18 | # noinspection PyUnresolvedReferences
19 | import pypi_secure.data.users
20 |
--------------------------------------------------------------------------------
/code/ex10_securepy/pypi_secure/data/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeckennedy/ten-tips-python-web-devs/e2406853a3d2e1d02ca5b00f68ae510993d4ad19/code/ex10_securepy/pypi_secure/data/__init__.py
--------------------------------------------------------------------------------
/code/ex10_securepy/pypi_secure/data/db_session.py:
--------------------------------------------------------------------------------
1 | import sqlalchemy as sa
2 | import sqlalchemy.orm as orm
3 | from sqlalchemy.orm import Session
4 |
5 | from pypi_secure.data.modelbase import SqlAlchemyBase
6 |
7 | __factory = None
8 |
9 |
10 | def global_init(db_file: str):
11 | global __factory
12 |
13 | if __factory:
14 | return
15 |
16 | if not db_file or not db_file.strip():
17 | raise Exception("You must specify a db file.")
18 |
19 | conn_str = 'sqlite:///' + db_file.strip()
20 | print("Connecting to DB with {}".format(conn_str))
21 |
22 | engine = sa.create_engine(conn_str, echo=False)
23 | __factory = orm.sessionmaker(bind=engine)
24 |
25 | # noinspection PyUnresolvedReferences
26 | import pypi_secure.data.__all_models
27 |
28 | SqlAlchemyBase.metadata.create_all(engine)
29 |
30 |
31 | def create_session() -> Session:
32 | global __factory
33 | return __factory()
34 |
--------------------------------------------------------------------------------
/code/ex10_securepy/pypi_secure/data/downloads.py:
--------------------------------------------------------------------------------
1 | import datetime
2 | import sqlalchemy
3 | from pypi_secure.data.modelbase import SqlAlchemyBase
4 |
5 |
6 | class Download(SqlAlchemyBase):
7 | __tablename__ = 'downloads'
8 |
9 | id: int = sqlalchemy.Column(sqlalchemy.BigInteger, primary_key=True, autoincrement=True)
10 | created_date: datetime.datetime = sqlalchemy.Column(
11 | sqlalchemy.DateTime, default=datetime.datetime.now, index=True)
12 |
13 | package_id: str = sqlalchemy.Column(sqlalchemy.String, index=True)
14 | release_id: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True)
15 |
16 | ip_address: str = sqlalchemy.Column(sqlalchemy.String)
17 | user_agent: str = sqlalchemy.Column(sqlalchemy.String)
18 |
--------------------------------------------------------------------------------
/code/ex10_securepy/pypi_secure/data/languages.py:
--------------------------------------------------------------------------------
1 | import datetime
2 | import sqlalchemy
3 | from pypi_secure.data.modelbase import SqlAlchemyBase
4 |
5 |
6 | class ProgrammingLanguage(SqlAlchemyBase):
7 | __tablename__ = 'languages'
8 |
9 | id: str = sqlalchemy.Column(sqlalchemy.String, primary_key=True)
10 | created_date: datetime.datetime = sqlalchemy.Column(
11 | sqlalchemy.DateTime, default=datetime.datetime.now, index=True)
12 | description: str = sqlalchemy.Column(sqlalchemy.String)
13 |
--------------------------------------------------------------------------------
/code/ex10_securepy/pypi_secure/data/licenses.py:
--------------------------------------------------------------------------------
1 | import datetime
2 | import sqlalchemy
3 | from pypi_secure.data.modelbase import SqlAlchemyBase
4 |
5 |
6 | class License(SqlAlchemyBase):
7 | __tablename__ = 'licenses'
8 |
9 | id: str = sqlalchemy.Column(sqlalchemy.String, primary_key=True)
10 | created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True)
11 | description: str = sqlalchemy.Column(sqlalchemy.String)
12 |
--------------------------------------------------------------------------------
/code/ex10_securepy/pypi_secure/data/maintainers.py:
--------------------------------------------------------------------------------
1 | import sqlalchemy
2 | from pypi_secure.data.modelbase import SqlAlchemyBase
3 |
4 |
5 | class Maintainer(SqlAlchemyBase):
6 | __tablename__ = 'maintainers'
7 |
8 | user_id: int = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True)
9 | package_id: str = sqlalchemy.Column(sqlalchemy.String, primary_key=True)
10 |
--------------------------------------------------------------------------------
/code/ex10_securepy/pypi_secure/data/modelbase.py:
--------------------------------------------------------------------------------
1 | import sqlalchemy.ext.declarative as dec
2 |
3 | SqlAlchemyBase = dec.declarative_base()
4 |
--------------------------------------------------------------------------------
/code/ex10_securepy/pypi_secure/data/users.py:
--------------------------------------------------------------------------------
1 | import datetime
2 | import sqlalchemy
3 | from pypi_secure.data.modelbase import SqlAlchemyBase
4 |
5 |
6 | class User(SqlAlchemyBase):
7 | __tablename__ = 'users'
8 |
9 | id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True, autoincrement=True)
10 | name = sqlalchemy.Column(sqlalchemy.String, nullable=True)
11 | email = sqlalchemy.Column(sqlalchemy.String, index=True, unique=True, nullable=True)
12 | hashed_password = sqlalchemy.Column(sqlalchemy.String, nullable=True, index=True)
13 | created_date = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True)
14 | profile_image_url = sqlalchemy.Column(sqlalchemy.String)
15 | last_login = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True)
16 |
--------------------------------------------------------------------------------
/code/ex10_securepy/pypi_secure/db/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeckennedy/ten-tips-python-web-devs/e2406853a3d2e1d02ca5b00f68ae510993d4ad19/code/ex10_securepy/pypi_secure/db/__init__.py
--------------------------------------------------------------------------------
/code/ex10_securepy/pypi_secure/db/placeholder.txt:
--------------------------------------------------------------------------------
1 | Just here so git will create this folder.
--------------------------------------------------------------------------------
/code/ex10_securepy/pypi_secure/db/pypi.sqlite:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeckennedy/ten-tips-python-web-devs/e2406853a3d2e1d02ca5b00f68ae510993d4ad19/code/ex10_securepy/pypi_secure/db/pypi.sqlite
--------------------------------------------------------------------------------
/code/ex10_securepy/pypi_secure/infrastructure/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeckennedy/ten-tips-python-web-devs/e2406853a3d2e1d02ca5b00f68ae510993d4ad19/code/ex10_securepy/pypi_secure/infrastructure/__init__.py
--------------------------------------------------------------------------------
/code/ex10_securepy/pypi_secure/services/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeckennedy/ten-tips-python-web-devs/e2406853a3d2e1d02ca5b00f68ae510993d4ad19/code/ex10_securepy/pypi_secure/services/__init__.py
--------------------------------------------------------------------------------
/code/ex10_securepy/pypi_secure/services/cms_service.py:
--------------------------------------------------------------------------------
1 | fake_db = {
2 | '/company/history': {
3 | 'page_title': 'Company history',
4 | 'page_details': 'Details about company history...',
5 | },
6 | '/company/employees': {
7 | 'page_title': 'Our team',
8 | 'page_details': 'Details about company employees ...',
9 | },
10 | }
11 |
12 |
13 | def get_page(url: str) -> dict:
14 | if not url:
15 | return {}
16 |
17 | url = url.strip().lower()
18 | url = '/' + url.lstrip('/')
19 |
20 | page = fake_db.get(url, {})
21 | return page
22 |
--------------------------------------------------------------------------------
/code/ex10_securepy/pypi_secure/services/user_service.py:
--------------------------------------------------------------------------------
1 | import pypi_secure.data.db_session as db_session
2 | from pypi_secure.data.users import User
3 |
4 |
5 | def get_user_count() -> int:
6 | session = db_session.create_session()
7 | return session.query(User).count()
8 |
--------------------------------------------------------------------------------
/code/ex10_securepy/pypi_secure/static/img/blue-cube.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/code/ex10_securepy/pypi_secure/static/img/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeckennedy/ten-tips-python-web-devs/e2406853a3d2e1d02ca5b00f68ae510993d4ad19/code/ex10_securepy/pypi_secure/static/img/favicon.png
--------------------------------------------------------------------------------
/code/ex10_securepy/pypi_secure/static/img/white-cube.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/code/ex10_securepy/pypi_secure/templates/cms/page.html:
--------------------------------------------------------------------------------
1 | {% extends "shared/_layout.html" %}
2 | {% block title %}About PyPI Demo{% endblock %}
3 |
4 | {% block main_content %}
5 | {{ page_title }}
6 |
7 |
8 | {{ page_details }}
9 |
10 | {% endblock %}
11 |
--------------------------------------------------------------------------------
/code/ex10_securepy/pypi_secure/templates/home/about.html:
--------------------------------------------------------------------------------
1 | {% extends "shared/_layout.html" %}
2 | {% block title %}About PyPI Demo{% endblock %}
3 |
4 | {% block main_content %}
5 | About Python Package Index
6 |
7 |
8 | This is our demo app for our Flask course.
9 |
10 | {% endblock %}
11 |
12 | {% block additional_css %}
13 |
14 | {% endblock %}
--------------------------------------------------------------------------------
/code/ex10_securepy/pypi_secure/views/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeckennedy/ten-tips-python-web-devs/e2406853a3d2e1d02ca5b00f68ae510993d4ad19/code/ex10_securepy/pypi_secure/views/__init__.py
--------------------------------------------------------------------------------
/code/ex10_securepy/pypi_secure/views/cms_views.py:
--------------------------------------------------------------------------------
1 | import flask
2 |
3 | from pypi_secure.infrastructure.view_modifiers import response
4 | import pypi_secure.services.cms_service as cms_service
5 |
6 | blueprint = flask.Blueprint('cms', __name__, template_folder='templates')
7 |
8 |
9 | @blueprint.route('/')
10 | @response(template_file='cms/page.html')
11 | def cms_page(full_url: str):
12 | print("Getting CMS page for {}".format(full_url))
13 |
14 | page = cms_service.get_page(full_url)
15 | if not page:
16 | return flask.abort(404)
17 |
18 | return page
19 |
--------------------------------------------------------------------------------
/code/ex10_securepy/pypi_secure/views/home_views.py:
--------------------------------------------------------------------------------
1 | import flask
2 |
3 | from pypi_secure.infrastructure.view_modifiers import response
4 | import pypi_secure.services.package_service as package_service
5 | import pypi_secure.services.user_service as user_service
6 |
7 | blueprint = flask.Blueprint('home', __name__, template_folder='templates')
8 |
9 |
10 | @blueprint.route('/')
11 | @response(template_file='home/index.html')
12 | def index():
13 | return {
14 | 'releases': package_service.get_latest_releases(),
15 | 'package_count': package_service.get_package_count(),
16 | 'release_count': package_service.get_release_count(),
17 | 'user_count': user_service.get_user_count(),
18 | }
19 |
20 |
21 | @blueprint.route('/about')
22 | @response(template_file='home/about.html')
23 | def about():
24 | return {}
25 |
--------------------------------------------------------------------------------
/code/ex10_securepy/setup.py:
--------------------------------------------------------------------------------
1 | from setuptools import setup
2 |
3 | setup(
4 | name='pypi_secure',
5 | version='',
6 | packages=['pypi_secure', 'pypi_secure.db', 'pypi_secure.data', 'pypi_secure.views', 'pypi_secure.services',
7 | 'pypi_secure.infrastructure'],
8 | package_dir={'': '.'},
9 | url='',
10 | license='',
11 | author='Michael Kennedy',
12 | author_email='',
13 | description=''
14 | )
15 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/compiler/directives/bind.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | export default function bind (el: ASTElement, dir: ASTDirective) {
4 | el.wrapData = (code: string) => {
5 | return `_b(${code},'${el.tag}',${dir.value},${
6 | dir.modifiers && dir.modifiers.prop ? 'true' : 'false'
7 | }${
8 | dir.modifiers && dir.modifiers.sync ? ',true' : ''
9 | })`
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/compiler/directives/index.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import on from './on'
4 | import bind from './bind'
5 | import { noop } from 'shared/util'
6 |
7 | export default {
8 | on,
9 | bind,
10 | cloak: noop
11 | }
12 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/compiler/directives/on.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { warn } from 'core/util/index'
4 |
5 | export default function on (el: ASTElement, dir: ASTDirective) {
6 | if (process.env.NODE_ENV !== 'production' && dir.modifiers) {
7 | warn(`v-on without argument does not support modifiers.`)
8 | }
9 | el.wrapListeners = (code: string) => `_g(${code},${dir.value})`
10 | }
11 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/compiler/index.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { parse } from './parser/index'
4 | import { optimize } from './optimizer'
5 | import { generate } from './codegen/index'
6 | import { createCompilerCreator } from './create-compiler'
7 |
8 | // `createCompilerCreator` allows creating compilers that use alternative
9 | // parser/optimizer/codegen, e.g the SSR optimizing compiler.
10 | // Here we just export a default compiler using the default parts.
11 | export const createCompiler = createCompilerCreator(function baseCompile (
12 | template: string,
13 | options: CompilerOptions
14 | ): CompiledResult {
15 | const ast = parse(template.trim(), options)
16 | if (options.optimize !== false) {
17 | optimize(ast, options)
18 | }
19 | const code = generate(ast, options)
20 | return {
21 | ast,
22 | render: code.render,
23 | staticRenderFns: code.staticRenderFns
24 | }
25 | })
26 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/compiler/parser/entity-decoder.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | let decoder
4 |
5 | export default {
6 | decode (html: string): string {
7 | decoder = decoder || document.createElement('div')
8 | decoder.innerHTML = html
9 | return decoder.textContent
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/core/components/index.js:
--------------------------------------------------------------------------------
1 | import KeepAlive from './keep-alive'
2 |
3 | export default {
4 | KeepAlive
5 | }
6 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/core/global-api/mixin.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { mergeOptions } from '../util/index'
4 |
5 | export function initMixin (Vue: GlobalAPI) {
6 | Vue.mixin = function (mixin: Object) {
7 | this.options = mergeOptions(this.options, mixin)
8 | return this
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/core/global-api/use.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { toArray } from '../util/index'
4 |
5 | export function initUse (Vue: GlobalAPI) {
6 | Vue.use = function (plugin: Function | Object) {
7 | const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
8 | if (installedPlugins.indexOf(plugin) > -1) {
9 | return this
10 | }
11 |
12 | // additional parameters
13 | const args = toArray(arguments, 1)
14 | args.unshift(this)
15 | if (typeof plugin.install === 'function') {
16 | plugin.install.apply(plugin, args)
17 | } else if (typeof plugin === 'function') {
18 | plugin.apply(null, args)
19 | }
20 | installedPlugins.push(plugin)
21 | return this
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/core/index.js:
--------------------------------------------------------------------------------
1 | import Vue from './instance/index'
2 | import { initGlobalAPI } from './global-api/index'
3 | import { isServerRendering } from 'core/util/env'
4 | import { FunctionalRenderContext } from 'core/vdom/create-functional-component'
5 |
6 | initGlobalAPI(Vue)
7 |
8 | Object.defineProperty(Vue.prototype, '$isServer', {
9 | get: isServerRendering
10 | })
11 |
12 | Object.defineProperty(Vue.prototype, '$ssrContext', {
13 | get () {
14 | /* istanbul ignore next */
15 | return this.$vnode && this.$vnode.ssrContext
16 | }
17 | })
18 |
19 | // expose FunctionalRenderContext for ssr runtime helper installation
20 | Object.defineProperty(Vue, 'FunctionalRenderContext', {
21 | value: FunctionalRenderContext
22 | })
23 |
24 | Vue.version = '__VERSION__'
25 |
26 | export default Vue
27 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/core/util/index.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | export * from 'shared/util'
4 | export * from './lang'
5 | export * from './env'
6 | export * from './options'
7 | export * from './debug'
8 | export * from './props'
9 | export * from './error'
10 | export * from './next-tick'
11 | export { defineReactive } from '../observer/index'
12 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/core/util/perf.js:
--------------------------------------------------------------------------------
1 | import { inBrowser } from './env'
2 |
3 | export let mark
4 | export let measure
5 |
6 | if (process.env.NODE_ENV !== 'production') {
7 | const perf = inBrowser && window.performance
8 | /* istanbul ignore if */
9 | if (
10 | perf &&
11 | perf.mark &&
12 | perf.measure &&
13 | perf.clearMarks &&
14 | perf.clearMeasures
15 | ) {
16 | mark = tag => perf.mark(tag)
17 | measure = (name, startTag, endTag) => {
18 | perf.measure(name, startTag, endTag)
19 | perf.clearMarks(startTag)
20 | perf.clearMarks(endTag)
21 | // perf.clearMeasures(name)
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/core/vdom/helpers/get-first-component-child.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { isDef } from 'shared/util'
4 | import { isAsyncPlaceholder } from './is-async-placeholder'
5 |
6 | export function getFirstComponentChild (children: ?Array): ?VNode {
7 | if (Array.isArray(children)) {
8 | for (let i = 0; i < children.length; i++) {
9 | const c = children[i]
10 | if (isDef(c) && (isDef(c.componentOptions) || isAsyncPlaceholder(c))) {
11 | return c
12 | }
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/core/vdom/helpers/index.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | export * from './merge-hook'
4 | export * from './extract-props'
5 | export * from './update-listeners'
6 | export * from './normalize-children'
7 | export * from './resolve-async-component'
8 | export * from './get-first-component-child'
9 | export * from './is-async-placeholder'
10 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/core/vdom/helpers/is-async-placeholder.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | export function isAsyncPlaceholder (node: VNode): boolean {
4 | return node.isComment && node.asyncFactory
5 | }
6 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/core/vdom/modules/index.js:
--------------------------------------------------------------------------------
1 | import directives from './directives'
2 | import ref from './ref'
3 |
4 | export default [
5 | ref,
6 | directives
7 | ]
8 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/platforms/web/compiler/directives/html.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { addProp } from 'compiler/helpers'
4 |
5 | export default function html (el: ASTElement, dir: ASTDirective) {
6 | if (dir.value) {
7 | addProp(el, 'innerHTML', `_s(${dir.value})`, dir)
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/platforms/web/compiler/directives/index.js:
--------------------------------------------------------------------------------
1 | import model from './model'
2 | import text from './text'
3 | import html from './html'
4 |
5 | export default {
6 | model,
7 | text,
8 | html
9 | }
10 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/platforms/web/compiler/directives/text.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { addProp } from 'compiler/helpers'
4 |
5 | export default function text (el: ASTElement, dir: ASTDirective) {
6 | if (dir.value) {
7 | addProp(el, 'textContent', `_s(${dir.value})`, dir)
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/platforms/web/compiler/index.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { baseOptions } from './options'
4 | import { createCompiler } from 'compiler/index'
5 |
6 | const { compile, compileToFunctions } = createCompiler(baseOptions)
7 |
8 | export { compile, compileToFunctions }
9 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/platforms/web/compiler/modules/index.js:
--------------------------------------------------------------------------------
1 | import klass from './class'
2 | import style from './style'
3 | import model from './model'
4 |
5 | export default [
6 | klass,
7 | style,
8 | model
9 | ]
10 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/platforms/web/compiler/options.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import {
4 | isPreTag,
5 | mustUseProp,
6 | isReservedTag,
7 | getTagNamespace
8 | } from '../util/index'
9 |
10 | import modules from './modules/index'
11 | import directives from './directives/index'
12 | import { genStaticKeys } from 'shared/util'
13 | import { isUnaryTag, canBeLeftOpenTag } from './util'
14 |
15 | export const baseOptions: CompilerOptions = {
16 | expectHTML: true,
17 | modules,
18 | directives,
19 | isPreTag,
20 | isUnaryTag,
21 | mustUseProp,
22 | canBeLeftOpenTag,
23 | isReservedTag,
24 | getTagNamespace,
25 | staticKeys: genStaticKeys(modules)
26 | }
27 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/platforms/web/entry-compiler.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | export { parseComponent } from 'sfc/parser'
4 | export { compile, compileToFunctions } from './compiler/index'
5 | export { ssrCompile, ssrCompileToFunctions } from './server/compiler'
6 | export { generateCodeFrame } from 'compiler/codeframe'
7 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/platforms/web/entry-runtime.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import Vue from './runtime/index'
4 |
5 | export default Vue
6 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/platforms/web/entry-server-basic-renderer.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import modules from './server/modules/index'
4 | import directives from './server/directives/index'
5 | import { isUnaryTag, canBeLeftOpenTag } from './compiler/util'
6 | import { createBasicRenderer } from 'server/create-basic-renderer'
7 |
8 | export default createBasicRenderer({
9 | modules,
10 | directives,
11 | isUnaryTag,
12 | canBeLeftOpenTag
13 | })
14 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/platforms/web/runtime/components/index.js:
--------------------------------------------------------------------------------
1 | import Transition from './transition'
2 | import TransitionGroup from './transition-group'
3 |
4 | export default {
5 | Transition,
6 | TransitionGroup
7 | }
8 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/platforms/web/runtime/directives/index.js:
--------------------------------------------------------------------------------
1 | import model from './model'
2 | import show from './show'
3 |
4 | export default {
5 | model,
6 | show
7 | }
8 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/platforms/web/runtime/modules/index.js:
--------------------------------------------------------------------------------
1 | import attrs from './attrs'
2 | import klass from './class'
3 | import events from './events'
4 | import domProps from './dom-props'
5 | import style from './style'
6 | import transition from './transition'
7 |
8 | export default [
9 | attrs,
10 | klass,
11 | events,
12 | domProps,
13 | style,
14 | transition
15 | ]
16 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/platforms/web/runtime/patch.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import * as nodeOps from 'web/runtime/node-ops'
4 | import { createPatchFunction } from 'core/vdom/patch'
5 | import baseModules from 'core/vdom/modules/index'
6 | import platformModules from 'web/runtime/modules/index'
7 |
8 | // the directive module should be applied last, after all
9 | // built-in modules have been applied.
10 | const modules = platformModules.concat(baseModules)
11 |
12 | export const patch: Function = createPatchFunction({ nodeOps, modules })
13 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/platforms/web/server/compiler.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { baseOptions } from '../compiler/options'
4 | import { createCompiler } from 'server/optimizing-compiler/index'
5 |
6 | const { compile, compileToFunctions } = createCompiler(baseOptions)
7 |
8 | export {
9 | compile as ssrCompile,
10 | compileToFunctions as ssrCompileToFunctions
11 | }
12 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/platforms/web/server/directives/index.js:
--------------------------------------------------------------------------------
1 | import show from './show'
2 | import model from './model'
3 |
4 | export default {
5 | show,
6 | model
7 | }
8 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/platforms/web/server/directives/show.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | export default function show (node: VNodeWithData, dir: VNodeDirective) {
4 | if (!dir.value) {
5 | const style: any = node.data.style || (node.data.style = {})
6 | if (Array.isArray(style)) {
7 | style.push({ display: 'none' })
8 | } else {
9 | style.display = 'none'
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/platforms/web/server/modules/class.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { escape } from '../util'
4 | import { genClassForVnode } from 'web/util/index'
5 |
6 | export default function renderClass (node: VNodeWithData): ?string {
7 | const classList = genClassForVnode(node)
8 | if (classList !== '') {
9 | return ` class="${escape(classList)}"`
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/platforms/web/server/modules/index.js:
--------------------------------------------------------------------------------
1 | import attrs from './attrs'
2 | import domProps from './dom-props'
3 | import klass from './class'
4 | import style from './style'
5 |
6 | export default [
7 | attrs,
8 | domProps,
9 | klass,
10 | style
11 | ]
12 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/platforms/web/util/compat.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { inBrowser } from 'core/util/index'
4 |
5 | // check whether current browser encodes a char inside attribute values
6 | let div
7 | function getShouldDecode (href: boolean): boolean {
8 | div = div || document.createElement('div')
9 | div.innerHTML = href ? `` : ``
10 | return div.innerHTML.indexOf('
') > 0
11 | }
12 |
13 | // #3663: IE encodes newlines inside attribute values while other browsers don't
14 | export const shouldDecodeNewlines = inBrowser ? getShouldDecode(false) : false
15 | // #6828: chrome encodes content in a[href]
16 | export const shouldDecodeNewlinesForHref = inBrowser ? getShouldDecode(true) : false
17 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/platforms/web/util/index.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { warn } from 'core/util/index'
4 |
5 | export * from './attrs'
6 | export * from './class'
7 | export * from './element'
8 |
9 | /**
10 | * Query an element selector if it's not an element already.
11 | */
12 | export function query (el: string | Element): Element {
13 | if (typeof el === 'string') {
14 | const selected = document.querySelector(el)
15 | if (!selected) {
16 | process.env.NODE_ENV !== 'production' && warn(
17 | 'Cannot find element: ' + el
18 | )
19 | return document.createElement('div')
20 | }
21 | return selected
22 | } else {
23 | return el
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/platforms/weex/compiler/directives/index.js:
--------------------------------------------------------------------------------
1 | import model from './model'
2 |
3 | export default {
4 | model
5 | }
6 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/platforms/weex/compiler/modules/append.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { makeMap } from 'shared/util'
4 |
5 | // The "unitary tag" means that the tag node and its children
6 | // must be sent to the native together.
7 | const isUnitaryTag = makeMap('cell,header,cell-slot,recycle-list', true)
8 |
9 | function preTransformNode (el: ASTElement) {
10 | if (isUnitaryTag(el.tag) && !el.attrsList.some(item => item.name === 'append')) {
11 | el.attrsMap.append = 'tree'
12 | el.attrsList.push({ name: 'append', value: 'tree' })
13 | }
14 | if (el.attrsMap.append === 'tree') {
15 | el.appendAsTree = true
16 | }
17 | }
18 |
19 | function genData (el: ASTElement): string {
20 | return el.appendAsTree ? `appendAsTree:true,` : ''
21 | }
22 |
23 | export default {
24 | staticKeys: ['appendAsTree'],
25 | preTransformNode,
26 | genData
27 | }
28 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/platforms/weex/compiler/modules/index.js:
--------------------------------------------------------------------------------
1 | import klass from './class'
2 | import style from './style'
3 | import props from './props'
4 | import append from './append'
5 | import recycleList from './recycle-list/index'
6 |
7 | export default [
8 | recycleList,
9 | klass,
10 | style,
11 | props,
12 | append
13 | ]
14 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/component-root.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { addAttr } from 'compiler/helpers'
4 |
5 | // mark component root nodes as
6 | export function postTransformComponentRoot (el: ASTElement) {
7 | if (!el.parent) {
8 | // component root
9 | addAttr(el, '@isComponentRoot', 'true')
10 | addAttr(el, '@templateId', '_uid')
11 | addAttr(el, '@componentProps', '$props || {}')
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/component.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { addAttr } from 'compiler/helpers'
4 | import { RECYCLE_LIST_MARKER } from 'weex/util/index'
5 |
6 | // mark components as inside recycle-list so that we know we need to invoke
7 | // their special @render function instead of render in create-component.js
8 | export function postTransformComponent (
9 | el: ASTElement,
10 | options: WeexCompilerOptions
11 | ) {
12 | // $flow-disable-line (we know isReservedTag is there)
13 | if (!options.isReservedTag(el.tag) && el.tag !== 'cell-slot') {
14 | addAttr(el, RECYCLE_LIST_MARKER, 'true')
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/text.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { addAttr } from 'compiler/helpers'
4 |
5 | function genText (node: ASTNode) {
6 | const value = node.type === 3
7 | ? node.text
8 | : node.type === 2
9 | ? node.tokens.length === 1
10 | ? node.tokens[0]
11 | : node.tokens
12 | : ''
13 | return JSON.stringify(value)
14 | }
15 |
16 | export function postTransformText (el: ASTElement) {
17 | // weex can only contain text, so the parser
18 | // always generates a single child.
19 | if (el.children.length) {
20 | addAttr(el, 'value', genText(el.children[0]))
21 | el.children = []
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/v-bind.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { camelize } from 'shared/util'
4 | import { generateBinding } from 'weex/util/parser'
5 | import { bindRE } from 'compiler/parser/index'
6 | import { getAndRemoveAttr, addRawAttr } from 'compiler/helpers'
7 |
8 | function parseAttrName (name: string): string {
9 | return camelize(name.replace(bindRE, ''))
10 | }
11 |
12 | export function preTransformVBind (el: ASTElement) {
13 | for (const attr in el.attrsMap) {
14 | if (bindRE.test(attr)) {
15 | const name: string = parseAttrName(attr)
16 | const value = generateBinding(getAndRemoveAttr(el, attr))
17 | delete el.attrsMap[attr]
18 | addRawAttr(el, name, value)
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/v-on.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | const inlineStatementRE = /^\s*([A-Za-z_$0-9\['\."\]]+)*\s*\(\s*(([A-Za-z_$0-9\['\."\]]+)?(\s*,\s*([A-Za-z_$0-9\['\."\]]+))*)\s*\)$/
4 |
5 | function parseHandlerParams (handler: ASTElementHandler) {
6 | const res = inlineStatementRE.exec(handler.value)
7 | if (res && res[2]) {
8 | handler.params = res[2].split(/\s*,\s*/)
9 | }
10 | }
11 |
12 | export function postTransformVOn (el: ASTElement) {
13 | const events: ASTElementHandlers | void = el.events
14 | if (!events) {
15 | return
16 | }
17 | for (const name in events) {
18 | const handler: ASTElementHandler | Array = events[name]
19 | if (Array.isArray(handler)) {
20 | handler.map(fn => parseHandlerParams(fn))
21 | } else {
22 | parseHandlerParams(handler)
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/v-once.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { getAndRemoveAttr, addRawAttr } from 'compiler/helpers'
4 |
5 | function containVOnce (el: ASTElement): boolean {
6 | for (const attr in el.attrsMap) {
7 | if (/^v\-once$/i.test(attr)) {
8 | return true
9 | }
10 | }
11 | return false
12 | }
13 |
14 | export function preTransformVOnce (el: ASTElement) {
15 | if (containVOnce(el)) {
16 | getAndRemoveAttr(el, 'v-once', true)
17 | addRawAttr(el, '[[once]]', true)
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/platforms/weex/entry-compiler.js:
--------------------------------------------------------------------------------
1 | export { compile } from 'weex/compiler/index'
2 | export { generateCodeFrame } from 'compiler/codeframe'
3 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/platforms/weex/entry-runtime-factory.js:
--------------------------------------------------------------------------------
1 | // this entry is built and wrapped with a factory function
2 | // used to generate a fresh copy of Vue for every Weex instance.
3 |
4 | import Vue from './runtime/index'
5 |
6 | exports.Vue = Vue
7 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/platforms/weex/runtime/components/index.js:
--------------------------------------------------------------------------------
1 | import Richtext from './richtext'
2 | import Transition from './transition'
3 | import TransitionGroup from './transition-group'
4 |
5 | export default {
6 | Richtext,
7 | Transition,
8 | TransitionGroup
9 | }
10 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/platforms/weex/runtime/components/transition.js:
--------------------------------------------------------------------------------
1 | // reuse same transition component logic from web
2 | export {
3 | transitionProps,
4 | extractTransitionData
5 | } from 'web/runtime/components/transition'
6 |
7 | import Transition from 'web/runtime/components/transition'
8 |
9 | export default Transition
10 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/platforms/weex/runtime/directives/index.js:
--------------------------------------------------------------------------------
1 | export default {
2 | }
3 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/platforms/weex/runtime/modules/index.js:
--------------------------------------------------------------------------------
1 | import attrs from './attrs'
2 | import klass from './class'
3 | import events from './events'
4 | import style from './style'
5 | import transition from './transition'
6 |
7 | export default [
8 | attrs,
9 | klass,
10 | events,
11 | style,
12 | transition
13 | ]
14 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/platforms/weex/runtime/patch.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import * as nodeOps from 'weex/runtime/node-ops'
4 | import { createPatchFunction } from 'core/vdom/patch'
5 | import baseModules from 'core/vdom/modules/index'
6 | import platformModules from 'weex/runtime/modules/index'
7 |
8 | // the directive module should be applied last, after all
9 | // built-in modules have been applied.
10 | const modules = platformModules.concat(baseModules)
11 |
12 | export const patch: Function = createPatchFunction({
13 | nodeOps,
14 | modules,
15 | LONG_LIST_THRESHOLD: 10
16 | })
17 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/platforms/weex/runtime/text-node.js:
--------------------------------------------------------------------------------
1 | let latestNodeId = 1
2 |
3 | export default function TextNode (text) {
4 | this.instanceId = ''
5 | this.nodeId = latestNodeId++
6 | this.parentNode = null
7 | this.nodeType = 3
8 | this.text = text
9 | }
10 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/server/optimizing-compiler/index.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { parse } from 'compiler/parser/index'
4 | import { generate } from './codegen'
5 | import { optimize } from './optimizer'
6 | import { createCompilerCreator } from 'compiler/create-compiler'
7 |
8 | export const createCompiler = createCompilerCreator(function baseCompile (
9 | template: string,
10 | options: CompilerOptions
11 | ): CompiledResult {
12 | const ast = parse(template.trim(), options)
13 | optimize(ast, options)
14 | const code = generate(ast, options)
15 | return {
16 | ast,
17 | render: code.render,
18 | staticRenderFns: code.staticRenderFns
19 | }
20 | })
21 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/server/util.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | export const isJS = (file: string): boolean => /\.js(\?[^.]+)?$/.test(file)
4 |
5 | export const isCSS = (file: string): boolean => /\.css(\?[^.]+)?$/.test(file)
6 |
7 | export function createPromiseCallback () {
8 | let resolve, reject
9 | const promise: Promise = new Promise((_resolve, _reject) => {
10 | resolve = _resolve
11 | reject = _reject
12 | })
13 | const cb = (err: Error, res?: string) => {
14 | if (err) return reject(err)
15 | resolve(res || '')
16 | }
17 | return { promise, cb }
18 | }
19 |
--------------------------------------------------------------------------------
/code/node_modules/vue/src/shared/constants.js:
--------------------------------------------------------------------------------
1 | export const SSR_ATTR = 'data-server-rendered'
2 |
3 | export const ASSET_TYPES = [
4 | 'component',
5 | 'directive',
6 | 'filter'
7 | ]
8 |
9 | export const LIFECYCLE_HOOKS = [
10 | 'beforeCreate',
11 | 'created',
12 | 'beforeMount',
13 | 'mounted',
14 | 'beforeUpdate',
15 | 'updated',
16 | 'beforeDestroy',
17 | 'destroyed',
18 | 'activated',
19 | 'deactivated',
20 | 'errorCaptured',
21 | 'serverPrefetch'
22 | ]
23 |
--------------------------------------------------------------------------------
/code/node_modules/vue/types/index.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from "./vue";
2 |
3 | export default Vue;
4 |
5 | export as namespace Vue;
6 |
7 | export {
8 | CreateElement,
9 | VueConstructor
10 | } from "./vue";
11 |
12 | export {
13 | Component,
14 | AsyncComponent,
15 | ComponentOptions,
16 | FunctionalComponentOptions,
17 | RenderContext,
18 | PropType,
19 | PropOptions,
20 | ComputedOptions,
21 | WatchHandler,
22 | WatchOptions,
23 | WatchOptionsWithHandler,
24 | DirectiveFunction,
25 | DirectiveOptions
26 | } from "./options";
27 |
28 | export {
29 | PluginFunction,
30 | PluginObject
31 | } from "./plugin";
32 |
33 | export {
34 | VNodeChildren,
35 | VNodeChildrenArrayContents,
36 | VNode,
37 | VNodeComponentOptions,
38 | VNodeData,
39 | VNodeDirective
40 | } from "./vnode";
41 |
--------------------------------------------------------------------------------
/code/node_modules/vue/types/plugin.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue as _Vue } from "./vue";
2 |
3 | export type PluginFunction = (Vue: typeof _Vue, options?: T) => void;
4 |
5 | export interface PluginObject {
6 | install: PluginFunction;
7 | [key: string]: any;
8 | }
9 |
--------------------------------------------------------------------------------
/code/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "top_10_web_explore",
3 | "version": "1.0.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "vue": {
8 | "version": "2.6.10",
9 | "resolved": "https://registry.npmjs.org/vue/-/vue-2.6.10.tgz",
10 | "integrity": "sha512-ImThpeNU9HbdZL3utgMCq0oiMzAkt1mcgy3/E6zWC/G6AaQoeuFdsl9nDhTDU3X1R6FK7nsIUuRACVcjI+A2GQ=="
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/code/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "top_10_web_explore",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "dependencies": {
12 | "vue": "^2.6.10"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/node_modules/vue/src/compiler/directives/bind.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | export default function bind (el: ASTElement, dir: ASTDirective) {
4 | el.wrapData = (code: string) => {
5 | return `_b(${code},'${el.tag}',${dir.value},${
6 | dir.modifiers && dir.modifiers.prop ? 'true' : 'false'
7 | }${
8 | dir.modifiers && dir.modifiers.sync ? ',true' : ''
9 | })`
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/node_modules/vue/src/compiler/directives/index.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import on from './on'
4 | import bind from './bind'
5 | import { noop } from 'shared/util'
6 |
7 | export default {
8 | on,
9 | bind,
10 | cloak: noop
11 | }
12 |
--------------------------------------------------------------------------------
/node_modules/vue/src/compiler/directives/on.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { warn } from 'core/util/index'
4 |
5 | export default function on (el: ASTElement, dir: ASTDirective) {
6 | if (process.env.NODE_ENV !== 'production' && dir.modifiers) {
7 | warn(`v-on without argument does not support modifiers.`)
8 | }
9 | el.wrapListeners = (code: string) => `_g(${code},${dir.value})`
10 | }
11 |
--------------------------------------------------------------------------------
/node_modules/vue/src/compiler/index.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { parse } from './parser/index'
4 | import { optimize } from './optimizer'
5 | import { generate } from './codegen/index'
6 | import { createCompilerCreator } from './create-compiler'
7 |
8 | // `createCompilerCreator` allows creating compilers that use alternative
9 | // parser/optimizer/codegen, e.g the SSR optimizing compiler.
10 | // Here we just export a default compiler using the default parts.
11 | export const createCompiler = createCompilerCreator(function baseCompile (
12 | template: string,
13 | options: CompilerOptions
14 | ): CompiledResult {
15 | const ast = parse(template.trim(), options)
16 | if (options.optimize !== false) {
17 | optimize(ast, options)
18 | }
19 | const code = generate(ast, options)
20 | return {
21 | ast,
22 | render: code.render,
23 | staticRenderFns: code.staticRenderFns
24 | }
25 | })
26 |
--------------------------------------------------------------------------------
/node_modules/vue/src/compiler/parser/entity-decoder.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | let decoder
4 |
5 | export default {
6 | decode (html: string): string {
7 | decoder = decoder || document.createElement('div')
8 | decoder.innerHTML = html
9 | return decoder.textContent
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/node_modules/vue/src/core/components/index.js:
--------------------------------------------------------------------------------
1 | import KeepAlive from './keep-alive'
2 |
3 | export default {
4 | KeepAlive
5 | }
6 |
--------------------------------------------------------------------------------
/node_modules/vue/src/core/global-api/mixin.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { mergeOptions } from '../util/index'
4 |
5 | export function initMixin (Vue: GlobalAPI) {
6 | Vue.mixin = function (mixin: Object) {
7 | this.options = mergeOptions(this.options, mixin)
8 | return this
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/node_modules/vue/src/core/global-api/use.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { toArray } from '../util/index'
4 |
5 | export function initUse (Vue: GlobalAPI) {
6 | Vue.use = function (plugin: Function | Object) {
7 | const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
8 | if (installedPlugins.indexOf(plugin) > -1) {
9 | return this
10 | }
11 |
12 | // additional parameters
13 | const args = toArray(arguments, 1)
14 | args.unshift(this)
15 | if (typeof plugin.install === 'function') {
16 | plugin.install.apply(plugin, args)
17 | } else if (typeof plugin === 'function') {
18 | plugin.apply(null, args)
19 | }
20 | installedPlugins.push(plugin)
21 | return this
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/node_modules/vue/src/core/index.js:
--------------------------------------------------------------------------------
1 | import Vue from './instance/index'
2 | import { initGlobalAPI } from './global-api/index'
3 | import { isServerRendering } from 'core/util/env'
4 | import { FunctionalRenderContext } from 'core/vdom/create-functional-component'
5 |
6 | initGlobalAPI(Vue)
7 |
8 | Object.defineProperty(Vue.prototype, '$isServer', {
9 | get: isServerRendering
10 | })
11 |
12 | Object.defineProperty(Vue.prototype, '$ssrContext', {
13 | get () {
14 | /* istanbul ignore next */
15 | return this.$vnode && this.$vnode.ssrContext
16 | }
17 | })
18 |
19 | // expose FunctionalRenderContext for ssr runtime helper installation
20 | Object.defineProperty(Vue, 'FunctionalRenderContext', {
21 | value: FunctionalRenderContext
22 | })
23 |
24 | Vue.version = '__VERSION__'
25 |
26 | export default Vue
27 |
--------------------------------------------------------------------------------
/node_modules/vue/src/core/util/index.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | export * from 'shared/util'
4 | export * from './lang'
5 | export * from './env'
6 | export * from './options'
7 | export * from './debug'
8 | export * from './props'
9 | export * from './error'
10 | export * from './next-tick'
11 | export { defineReactive } from '../observer/index'
12 |
--------------------------------------------------------------------------------
/node_modules/vue/src/core/util/perf.js:
--------------------------------------------------------------------------------
1 | import { inBrowser } from './env'
2 |
3 | export let mark
4 | export let measure
5 |
6 | if (process.env.NODE_ENV !== 'production') {
7 | const perf = inBrowser && window.performance
8 | /* istanbul ignore if */
9 | if (
10 | perf &&
11 | perf.mark &&
12 | perf.measure &&
13 | perf.clearMarks &&
14 | perf.clearMeasures
15 | ) {
16 | mark = tag => perf.mark(tag)
17 | measure = (name, startTag, endTag) => {
18 | perf.measure(name, startTag, endTag)
19 | perf.clearMarks(startTag)
20 | perf.clearMarks(endTag)
21 | // perf.clearMeasures(name)
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/node_modules/vue/src/core/vdom/helpers/get-first-component-child.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { isDef } from 'shared/util'
4 | import { isAsyncPlaceholder } from './is-async-placeholder'
5 |
6 | export function getFirstComponentChild (children: ?Array): ?VNode {
7 | if (Array.isArray(children)) {
8 | for (let i = 0; i < children.length; i++) {
9 | const c = children[i]
10 | if (isDef(c) && (isDef(c.componentOptions) || isAsyncPlaceholder(c))) {
11 | return c
12 | }
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/node_modules/vue/src/core/vdom/helpers/index.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | export * from './merge-hook'
4 | export * from './extract-props'
5 | export * from './update-listeners'
6 | export * from './normalize-children'
7 | export * from './resolve-async-component'
8 | export * from './get-first-component-child'
9 | export * from './is-async-placeholder'
10 |
--------------------------------------------------------------------------------
/node_modules/vue/src/core/vdom/helpers/is-async-placeholder.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | export function isAsyncPlaceholder (node: VNode): boolean {
4 | return node.isComment && node.asyncFactory
5 | }
6 |
--------------------------------------------------------------------------------
/node_modules/vue/src/core/vdom/modules/index.js:
--------------------------------------------------------------------------------
1 | import directives from './directives'
2 | import ref from './ref'
3 |
4 | export default [
5 | ref,
6 | directives
7 | ]
8 |
--------------------------------------------------------------------------------
/node_modules/vue/src/platforms/web/compiler/directives/html.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { addProp } from 'compiler/helpers'
4 |
5 | export default function html (el: ASTElement, dir: ASTDirective) {
6 | if (dir.value) {
7 | addProp(el, 'innerHTML', `_s(${dir.value})`, dir)
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/node_modules/vue/src/platforms/web/compiler/directives/index.js:
--------------------------------------------------------------------------------
1 | import model from './model'
2 | import text from './text'
3 | import html from './html'
4 |
5 | export default {
6 | model,
7 | text,
8 | html
9 | }
10 |
--------------------------------------------------------------------------------
/node_modules/vue/src/platforms/web/compiler/directives/text.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { addProp } from 'compiler/helpers'
4 |
5 | export default function text (el: ASTElement, dir: ASTDirective) {
6 | if (dir.value) {
7 | addProp(el, 'textContent', `_s(${dir.value})`, dir)
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/node_modules/vue/src/platforms/web/compiler/index.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { baseOptions } from './options'
4 | import { createCompiler } from 'compiler/index'
5 |
6 | const { compile, compileToFunctions } = createCompiler(baseOptions)
7 |
8 | export { compile, compileToFunctions }
9 |
--------------------------------------------------------------------------------
/node_modules/vue/src/platforms/web/compiler/modules/index.js:
--------------------------------------------------------------------------------
1 | import klass from './class'
2 | import style from './style'
3 | import model from './model'
4 |
5 | export default [
6 | klass,
7 | style,
8 | model
9 | ]
10 |
--------------------------------------------------------------------------------
/node_modules/vue/src/platforms/web/compiler/options.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import {
4 | isPreTag,
5 | mustUseProp,
6 | isReservedTag,
7 | getTagNamespace
8 | } from '../util/index'
9 |
10 | import modules from './modules/index'
11 | import directives from './directives/index'
12 | import { genStaticKeys } from 'shared/util'
13 | import { isUnaryTag, canBeLeftOpenTag } from './util'
14 |
15 | export const baseOptions: CompilerOptions = {
16 | expectHTML: true,
17 | modules,
18 | directives,
19 | isPreTag,
20 | isUnaryTag,
21 | mustUseProp,
22 | canBeLeftOpenTag,
23 | isReservedTag,
24 | getTagNamespace,
25 | staticKeys: genStaticKeys(modules)
26 | }
27 |
--------------------------------------------------------------------------------
/node_modules/vue/src/platforms/web/entry-compiler.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | export { parseComponent } from 'sfc/parser'
4 | export { compile, compileToFunctions } from './compiler/index'
5 | export { ssrCompile, ssrCompileToFunctions } from './server/compiler'
6 | export { generateCodeFrame } from 'compiler/codeframe'
7 |
--------------------------------------------------------------------------------
/node_modules/vue/src/platforms/web/entry-runtime.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import Vue from './runtime/index'
4 |
5 | export default Vue
6 |
--------------------------------------------------------------------------------
/node_modules/vue/src/platforms/web/entry-server-basic-renderer.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import modules from './server/modules/index'
4 | import directives from './server/directives/index'
5 | import { isUnaryTag, canBeLeftOpenTag } from './compiler/util'
6 | import { createBasicRenderer } from 'server/create-basic-renderer'
7 |
8 | export default createBasicRenderer({
9 | modules,
10 | directives,
11 | isUnaryTag,
12 | canBeLeftOpenTag
13 | })
14 |
--------------------------------------------------------------------------------
/node_modules/vue/src/platforms/web/runtime/components/index.js:
--------------------------------------------------------------------------------
1 | import Transition from './transition'
2 | import TransitionGroup from './transition-group'
3 |
4 | export default {
5 | Transition,
6 | TransitionGroup
7 | }
8 |
--------------------------------------------------------------------------------
/node_modules/vue/src/platforms/web/runtime/directives/index.js:
--------------------------------------------------------------------------------
1 | import model from './model'
2 | import show from './show'
3 |
4 | export default {
5 | model,
6 | show
7 | }
8 |
--------------------------------------------------------------------------------
/node_modules/vue/src/platforms/web/runtime/modules/index.js:
--------------------------------------------------------------------------------
1 | import attrs from './attrs'
2 | import klass from './class'
3 | import events from './events'
4 | import domProps from './dom-props'
5 | import style from './style'
6 | import transition from './transition'
7 |
8 | export default [
9 | attrs,
10 | klass,
11 | events,
12 | domProps,
13 | style,
14 | transition
15 | ]
16 |
--------------------------------------------------------------------------------
/node_modules/vue/src/platforms/web/runtime/patch.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import * as nodeOps from 'web/runtime/node-ops'
4 | import { createPatchFunction } from 'core/vdom/patch'
5 | import baseModules from 'core/vdom/modules/index'
6 | import platformModules from 'web/runtime/modules/index'
7 |
8 | // the directive module should be applied last, after all
9 | // built-in modules have been applied.
10 | const modules = platformModules.concat(baseModules)
11 |
12 | export const patch: Function = createPatchFunction({ nodeOps, modules })
13 |
--------------------------------------------------------------------------------
/node_modules/vue/src/platforms/web/server/compiler.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { baseOptions } from '../compiler/options'
4 | import { createCompiler } from 'server/optimizing-compiler/index'
5 |
6 | const { compile, compileToFunctions } = createCompiler(baseOptions)
7 |
8 | export {
9 | compile as ssrCompile,
10 | compileToFunctions as ssrCompileToFunctions
11 | }
12 |
--------------------------------------------------------------------------------
/node_modules/vue/src/platforms/web/server/directives/index.js:
--------------------------------------------------------------------------------
1 | import show from './show'
2 | import model from './model'
3 |
4 | export default {
5 | show,
6 | model
7 | }
8 |
--------------------------------------------------------------------------------
/node_modules/vue/src/platforms/web/server/directives/show.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | export default function show (node: VNodeWithData, dir: VNodeDirective) {
4 | if (!dir.value) {
5 | const style: any = node.data.style || (node.data.style = {})
6 | if (Array.isArray(style)) {
7 | style.push({ display: 'none' })
8 | } else {
9 | style.display = 'none'
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/node_modules/vue/src/platforms/web/server/modules/class.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { escape } from '../util'
4 | import { genClassForVnode } from 'web/util/index'
5 |
6 | export default function renderClass (node: VNodeWithData): ?string {
7 | const classList = genClassForVnode(node)
8 | if (classList !== '') {
9 | return ` class="${escape(classList)}"`
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/node_modules/vue/src/platforms/web/server/modules/index.js:
--------------------------------------------------------------------------------
1 | import attrs from './attrs'
2 | import domProps from './dom-props'
3 | import klass from './class'
4 | import style from './style'
5 |
6 | export default [
7 | attrs,
8 | domProps,
9 | klass,
10 | style
11 | ]
12 |
--------------------------------------------------------------------------------
/node_modules/vue/src/platforms/web/util/compat.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { inBrowser } from 'core/util/index'
4 |
5 | // check whether current browser encodes a char inside attribute values
6 | let div
7 | function getShouldDecode (href: boolean): boolean {
8 | div = div || document.createElement('div')
9 | div.innerHTML = href ? `` : ``
10 | return div.innerHTML.indexOf('
') > 0
11 | }
12 |
13 | // #3663: IE encodes newlines inside attribute values while other browsers don't
14 | export const shouldDecodeNewlines = inBrowser ? getShouldDecode(false) : false
15 | // #6828: chrome encodes content in a[href]
16 | export const shouldDecodeNewlinesForHref = inBrowser ? getShouldDecode(true) : false
17 |
--------------------------------------------------------------------------------
/node_modules/vue/src/platforms/web/util/index.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { warn } from 'core/util/index'
4 |
5 | export * from './attrs'
6 | export * from './class'
7 | export * from './element'
8 |
9 | /**
10 | * Query an element selector if it's not an element already.
11 | */
12 | export function query (el: string | Element): Element {
13 | if (typeof el === 'string') {
14 | const selected = document.querySelector(el)
15 | if (!selected) {
16 | process.env.NODE_ENV !== 'production' && warn(
17 | 'Cannot find element: ' + el
18 | )
19 | return document.createElement('div')
20 | }
21 | return selected
22 | } else {
23 | return el
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/node_modules/vue/src/platforms/weex/compiler/directives/index.js:
--------------------------------------------------------------------------------
1 | import model from './model'
2 |
3 | export default {
4 | model
5 | }
6 |
--------------------------------------------------------------------------------
/node_modules/vue/src/platforms/weex/compiler/modules/append.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { makeMap } from 'shared/util'
4 |
5 | // The "unitary tag" means that the tag node and its children
6 | // must be sent to the native together.
7 | const isUnitaryTag = makeMap('cell,header,cell-slot,recycle-list', true)
8 |
9 | function preTransformNode (el: ASTElement) {
10 | if (isUnitaryTag(el.tag) && !el.attrsList.some(item => item.name === 'append')) {
11 | el.attrsMap.append = 'tree'
12 | el.attrsList.push({ name: 'append', value: 'tree' })
13 | }
14 | if (el.attrsMap.append === 'tree') {
15 | el.appendAsTree = true
16 | }
17 | }
18 |
19 | function genData (el: ASTElement): string {
20 | return el.appendAsTree ? `appendAsTree:true,` : ''
21 | }
22 |
23 | export default {
24 | staticKeys: ['appendAsTree'],
25 | preTransformNode,
26 | genData
27 | }
28 |
--------------------------------------------------------------------------------
/node_modules/vue/src/platforms/weex/compiler/modules/index.js:
--------------------------------------------------------------------------------
1 | import klass from './class'
2 | import style from './style'
3 | import props from './props'
4 | import append from './append'
5 | import recycleList from './recycle-list/index'
6 |
7 | export default [
8 | recycleList,
9 | klass,
10 | style,
11 | props,
12 | append
13 | ]
14 |
--------------------------------------------------------------------------------
/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/component-root.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { addAttr } from 'compiler/helpers'
4 |
5 | // mark component root nodes as
6 | export function postTransformComponentRoot (el: ASTElement) {
7 | if (!el.parent) {
8 | // component root
9 | addAttr(el, '@isComponentRoot', 'true')
10 | addAttr(el, '@templateId', '_uid')
11 | addAttr(el, '@componentProps', '$props || {}')
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/component.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { addAttr } from 'compiler/helpers'
4 | import { RECYCLE_LIST_MARKER } from 'weex/util/index'
5 |
6 | // mark components as inside recycle-list so that we know we need to invoke
7 | // their special @render function instead of render in create-component.js
8 | export function postTransformComponent (
9 | el: ASTElement,
10 | options: WeexCompilerOptions
11 | ) {
12 | // $flow-disable-line (we know isReservedTag is there)
13 | if (!options.isReservedTag(el.tag) && el.tag !== 'cell-slot') {
14 | addAttr(el, RECYCLE_LIST_MARKER, 'true')
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/text.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { addAttr } from 'compiler/helpers'
4 |
5 | function genText (node: ASTNode) {
6 | const value = node.type === 3
7 | ? node.text
8 | : node.type === 2
9 | ? node.tokens.length === 1
10 | ? node.tokens[0]
11 | : node.tokens
12 | : ''
13 | return JSON.stringify(value)
14 | }
15 |
16 | export function postTransformText (el: ASTElement) {
17 | // weex can only contain text, so the parser
18 | // always generates a single child.
19 | if (el.children.length) {
20 | addAttr(el, 'value', genText(el.children[0]))
21 | el.children = []
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/v-bind.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { camelize } from 'shared/util'
4 | import { generateBinding } from 'weex/util/parser'
5 | import { bindRE } from 'compiler/parser/index'
6 | import { getAndRemoveAttr, addRawAttr } from 'compiler/helpers'
7 |
8 | function parseAttrName (name: string): string {
9 | return camelize(name.replace(bindRE, ''))
10 | }
11 |
12 | export function preTransformVBind (el: ASTElement) {
13 | for (const attr in el.attrsMap) {
14 | if (bindRE.test(attr)) {
15 | const name: string = parseAttrName(attr)
16 | const value = generateBinding(getAndRemoveAttr(el, attr))
17 | delete el.attrsMap[attr]
18 | addRawAttr(el, name, value)
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/v-on.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | const inlineStatementRE = /^\s*([A-Za-z_$0-9\['\."\]]+)*\s*\(\s*(([A-Za-z_$0-9\['\."\]]+)?(\s*,\s*([A-Za-z_$0-9\['\."\]]+))*)\s*\)$/
4 |
5 | function parseHandlerParams (handler: ASTElementHandler) {
6 | const res = inlineStatementRE.exec(handler.value)
7 | if (res && res[2]) {
8 | handler.params = res[2].split(/\s*,\s*/)
9 | }
10 | }
11 |
12 | export function postTransformVOn (el: ASTElement) {
13 | const events: ASTElementHandlers | void = el.events
14 | if (!events) {
15 | return
16 | }
17 | for (const name in events) {
18 | const handler: ASTElementHandler | Array = events[name]
19 | if (Array.isArray(handler)) {
20 | handler.map(fn => parseHandlerParams(fn))
21 | } else {
22 | parseHandlerParams(handler)
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/v-once.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { getAndRemoveAttr, addRawAttr } from 'compiler/helpers'
4 |
5 | function containVOnce (el: ASTElement): boolean {
6 | for (const attr in el.attrsMap) {
7 | if (/^v\-once$/i.test(attr)) {
8 | return true
9 | }
10 | }
11 | return false
12 | }
13 |
14 | export function preTransformVOnce (el: ASTElement) {
15 | if (containVOnce(el)) {
16 | getAndRemoveAttr(el, 'v-once', true)
17 | addRawAttr(el, '[[once]]', true)
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/node_modules/vue/src/platforms/weex/entry-compiler.js:
--------------------------------------------------------------------------------
1 | export { compile } from 'weex/compiler/index'
2 | export { generateCodeFrame } from 'compiler/codeframe'
3 |
--------------------------------------------------------------------------------
/node_modules/vue/src/platforms/weex/entry-runtime-factory.js:
--------------------------------------------------------------------------------
1 | // this entry is built and wrapped with a factory function
2 | // used to generate a fresh copy of Vue for every Weex instance.
3 |
4 | import Vue from './runtime/index'
5 |
6 | exports.Vue = Vue
7 |
--------------------------------------------------------------------------------
/node_modules/vue/src/platforms/weex/runtime/components/index.js:
--------------------------------------------------------------------------------
1 | import Richtext from './richtext'
2 | import Transition from './transition'
3 | import TransitionGroup from './transition-group'
4 |
5 | export default {
6 | Richtext,
7 | Transition,
8 | TransitionGroup
9 | }
10 |
--------------------------------------------------------------------------------
/node_modules/vue/src/platforms/weex/runtime/components/transition.js:
--------------------------------------------------------------------------------
1 | // reuse same transition component logic from web
2 | export {
3 | transitionProps,
4 | extractTransitionData
5 | } from 'web/runtime/components/transition'
6 |
7 | import Transition from 'web/runtime/components/transition'
8 |
9 | export default Transition
10 |
--------------------------------------------------------------------------------
/node_modules/vue/src/platforms/weex/runtime/directives/index.js:
--------------------------------------------------------------------------------
1 | export default {
2 | }
3 |
--------------------------------------------------------------------------------
/node_modules/vue/src/platforms/weex/runtime/modules/index.js:
--------------------------------------------------------------------------------
1 | import attrs from './attrs'
2 | import klass from './class'
3 | import events from './events'
4 | import style from './style'
5 | import transition from './transition'
6 |
7 | export default [
8 | attrs,
9 | klass,
10 | events,
11 | style,
12 | transition
13 | ]
14 |
--------------------------------------------------------------------------------
/node_modules/vue/src/platforms/weex/runtime/patch.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import * as nodeOps from 'weex/runtime/node-ops'
4 | import { createPatchFunction } from 'core/vdom/patch'
5 | import baseModules from 'core/vdom/modules/index'
6 | import platformModules from 'weex/runtime/modules/index'
7 |
8 | // the directive module should be applied last, after all
9 | // built-in modules have been applied.
10 | const modules = platformModules.concat(baseModules)
11 |
12 | export const patch: Function = createPatchFunction({
13 | nodeOps,
14 | modules,
15 | LONG_LIST_THRESHOLD: 10
16 | })
17 |
--------------------------------------------------------------------------------
/node_modules/vue/src/platforms/weex/runtime/text-node.js:
--------------------------------------------------------------------------------
1 | let latestNodeId = 1
2 |
3 | export default function TextNode (text) {
4 | this.instanceId = ''
5 | this.nodeId = latestNodeId++
6 | this.parentNode = null
7 | this.nodeType = 3
8 | this.text = text
9 | }
10 |
--------------------------------------------------------------------------------
/node_modules/vue/src/server/optimizing-compiler/index.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { parse } from 'compiler/parser/index'
4 | import { generate } from './codegen'
5 | import { optimize } from './optimizer'
6 | import { createCompilerCreator } from 'compiler/create-compiler'
7 |
8 | export const createCompiler = createCompilerCreator(function baseCompile (
9 | template: string,
10 | options: CompilerOptions
11 | ): CompiledResult {
12 | const ast = parse(template.trim(), options)
13 | optimize(ast, options)
14 | const code = generate(ast, options)
15 | return {
16 | ast,
17 | render: code.render,
18 | staticRenderFns: code.staticRenderFns
19 | }
20 | })
21 |
--------------------------------------------------------------------------------
/node_modules/vue/src/server/util.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | export const isJS = (file: string): boolean => /\.js(\?[^.]+)?$/.test(file)
4 |
5 | export const isCSS = (file: string): boolean => /\.css(\?[^.]+)?$/.test(file)
6 |
7 | export function createPromiseCallback () {
8 | let resolve, reject
9 | const promise: Promise = new Promise((_resolve, _reject) => {
10 | resolve = _resolve
11 | reject = _reject
12 | })
13 | const cb = (err: Error, res?: string) => {
14 | if (err) return reject(err)
15 | resolve(res || '')
16 | }
17 | return { promise, cb }
18 | }
19 |
--------------------------------------------------------------------------------
/node_modules/vue/src/shared/constants.js:
--------------------------------------------------------------------------------
1 | export const SSR_ATTR = 'data-server-rendered'
2 |
3 | export const ASSET_TYPES = [
4 | 'component',
5 | 'directive',
6 | 'filter'
7 | ]
8 |
9 | export const LIFECYCLE_HOOKS = [
10 | 'beforeCreate',
11 | 'created',
12 | 'beforeMount',
13 | 'mounted',
14 | 'beforeUpdate',
15 | 'updated',
16 | 'beforeDestroy',
17 | 'destroyed',
18 | 'activated',
19 | 'deactivated',
20 | 'errorCaptured',
21 | 'serverPrefetch'
22 | ]
23 |
--------------------------------------------------------------------------------
/node_modules/vue/types/index.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from "./vue";
2 |
3 | export default Vue;
4 |
5 | export as namespace Vue;
6 |
7 | export {
8 | CreateElement,
9 | VueConstructor
10 | } from "./vue";
11 |
12 | export {
13 | Component,
14 | AsyncComponent,
15 | ComponentOptions,
16 | FunctionalComponentOptions,
17 | RenderContext,
18 | PropType,
19 | PropOptions,
20 | ComputedOptions,
21 | WatchHandler,
22 | WatchOptions,
23 | WatchOptionsWithHandler,
24 | DirectiveFunction,
25 | DirectiveOptions
26 | } from "./options";
27 |
28 | export {
29 | PluginFunction,
30 | PluginObject
31 | } from "./plugin";
32 |
33 | export {
34 | VNodeChildren,
35 | VNodeChildrenArrayContents,
36 | VNode,
37 | VNodeComponentOptions,
38 | VNodeData,
39 | VNodeDirective
40 | } from "./vnode";
41 |
--------------------------------------------------------------------------------
/node_modules/vue/types/plugin.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue as _Vue } from "./vue";
2 |
3 | export type PluginFunction = (Vue: typeof _Vue, options?: T) => void;
4 |
5 | export interface PluginObject {
6 | install: PluginFunction;
7 | [key: string]: any;
8 | }
9 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ten-tips-python-web-devs",
3 | "version": "1.0.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "vue": {
8 | "version": "2.6.10",
9 | "resolved": "https://registry.npmjs.org/vue/-/vue-2.6.10.tgz",
10 | "integrity": "sha512-ImThpeNU9HbdZL3utgMCq0oiMzAkt1mcgy3/E6zWC/G6AaQoeuFdsl9nDhTDU3X1R6FK7nsIUuRACVcjI+A2GQ=="
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ten-tips-python-web-devs",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "git+https://github.com/mikeckennedy/ten-tips-python-web-devs.git"
12 | },
13 | "author": "",
14 | "license": "ISC",
15 | "bugs": {
16 | "url": "https://github.com/mikeckennedy/ten-tips-python-web-devs/issues"
17 | },
18 | "homepage": "https://github.com/mikeckennedy/ten-tips-python-web-devs#readme",
19 | "dependencies": {
20 | "vue": "^2.6.10"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/tools-and-techniques-web.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeckennedy/ten-tips-python-web-devs/e2406853a3d2e1d02ca5b00f68ae510993d4ad19/tools-and-techniques-web.pdf
--------------------------------------------------------------------------------