From 61e8af0116a421587f87a6edf922ee2cdd85d1e5 Mon Sep 17 00:00:00 2001 From: petercat12 Date: Wed, 26 Apr 2017 14:17:26 -0500 Subject: [PATCH 1/5] initi commit --- .gitignore | 1 + README.md | 42 ++++++- example18/example18/__init__.py | 0 example18/example18/settings.py | 112 ++++++++++++++++++ example18/example18/urls.py | 21 ++++ example18/example18/wsgi.py | 16 +++ example18/manage.py | 10 ++ example18/requirements.txt | 2 + example18/requirements/pypi_requirements.txt | 4 + example18/templates/admin/base.html | 92 ++++++++++++++ setup.py | 9 ++ version_viewer/__init__.py | 0 version_viewer/mixins.py | 6 + version_viewer/pip_viewer.py | 8 ++ version_viewer/templates/version_viewer.html | 56 +++++++++ version_viewer/templatetags/__init__.py | 0 .../templatetags/pip_version_viewer_tags.py | 19 +++ version_viewer/urls.py | 14 +++ version_viewer/views.py | 20 ++++ 19 files changed, 431 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 example18/example18/__init__.py create mode 100644 example18/example18/settings.py create mode 100644 example18/example18/urls.py create mode 100644 example18/example18/wsgi.py create mode 100755 example18/manage.py create mode 100644 example18/requirements.txt create mode 100644 example18/requirements/pypi_requirements.txt create mode 100644 example18/templates/admin/base.html create mode 100644 setup.py create mode 100644 version_viewer/__init__.py create mode 100644 version_viewer/mixins.py create mode 100644 version_viewer/pip_viewer.py create mode 100644 version_viewer/templates/version_viewer.html create mode 100644 version_viewer/templatetags/__init__.py create mode 100644 version_viewer/templatetags/pip_version_viewer_tags.py create mode 100644 version_viewer/urls.py create mode 100644 version_viewer/views.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0d20b64 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.pyc diff --git a/README.md b/README.md index 278ee81..32feece 100644 --- a/README.md +++ b/README.md @@ -1 +1,41 @@ -# Pip-Version-Viewer \ No newline at end of file +# Pip Package Version Viewer + +The pip package version viewer plugin allows a queryable endpoint to display a list of dicts representing all installed pip packages in the environment that django is running in. It also allows the insertion of a template tag to any template to display a link which calls up a pop up modal displaying all installed pip packages. You may also configure which users have access to the link and endpoint. + +--------------------------------------- +## Installation +--------------------------------------- + +Add the following to `INSTALLED_APPS` in `settings.py` + + INSTALLED_APPS = [ + 'version_viewer' + ] + +Add `version_viewer` include to `urls.py` + + urlpatterns = [ + ... + url(r'^version_viewer/', include('version_viewer.urls')), + ... + ] + +Choose the Accessor class that determins who can view/access the version_viewer template tag and route: + + # Version Viewer settings: + # default class only allows superusers access + ACCESSOR_CLASS_PATH = 'version_viewer.mxins.Accessor' + + +Override the `base.html` django Admin template (or the template of your choosing) by creating a `base.html` file inside a `templates/admin` directory in your project. + +Make sure you insert the necessary `src` and `link` blocks so that the popup modal works properly. + + + + + +Finally, load the template tags file and insert the template tag where ever you want the "Installed Versions" link to show up: + + {% load pip_version_viewer_tags %} + {% show_pip_package_versions %} diff --git a/example18/example18/__init__.py b/example18/example18/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/example18/example18/settings.py b/example18/example18/settings.py new file mode 100644 index 0000000..0bd7fed --- /dev/null +++ b/example18/example18/settings.py @@ -0,0 +1,112 @@ +""" +Django settings for example18 project. + +Generated by 'django-admin startproject' using Django 1.8.18. + +For more information on this file, see +https://docs.djangoproject.com/en/1.8/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/1.8/ref/settings/ +""" + +# Build paths inside the project like this: os.path.join(BASE_DIR, ...) +import os + +BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +PROJECT_DIR = os.path.join(BASE_DIR, "example") + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = '*2$rhmg25-#et_b5nt)_oq*u5ymb!xo0*2xl#5(-!h#)m@&bqq' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = [] + + +# Application definition + +INSTALLED_APPS = ( + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + + 'django_extensions', + 'version_viewer' +) + +MIDDLEWARE_CLASSES = ( + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', + 'django.middleware.security.SecurityMiddleware', +) + +ROOT_URLCONF = 'example18.urls' +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [os.path.join(BASE_DIR, 'templates'), ], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'example18.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/1.8/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.postgresql_psycopg2', + 'NAME': 'postgres', + 'USER': 'postgres', + 'PASSWORD': 'postgres', + 'HOST': 'localhost', + 'PORT': 5461 + } +} + + +# Internationalization +# https://docs.djangoproject.com/en/1.8/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'UTC' + +USE_I18N = True + +USE_L10N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/1.8/howto/static-files/ + +STATIC_URL = '/static/' + +PHYSICIAN_DETAIL_SERIALIZER_PATH = 'physicians.plugins.physicians_api.serializers.PhysicianBaseSerializer' +ACCESSOR_CLASS_PATH = 'version_viewer.mixins.Accessor' diff --git a/example18/example18/urls.py b/example18/example18/urls.py new file mode 100644 index 0000000..d933e77 --- /dev/null +++ b/example18/example18/urls.py @@ -0,0 +1,21 @@ +"""example18 URL Configuration + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/1.8/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') +Including another URLconf + 1. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) +""" +from django.conf.urls import include, url +from django.contrib import admin + +urlpatterns = [ + url(r'^admin/', include(admin.site.urls)), + url(r'^version_viewer/', include('version_viewer.urls')), +] diff --git a/example18/example18/wsgi.py b/example18/example18/wsgi.py new file mode 100644 index 0000000..e50407d --- /dev/null +++ b/example18/example18/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for example18 project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/1.8/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "example18.settings") + +application = get_wsgi_application() diff --git a/example18/manage.py b/example18/manage.py new file mode 100755 index 0000000..d1178cb --- /dev/null +++ b/example18/manage.py @@ -0,0 +1,10 @@ +#!/usr/bin/env python +import os +import sys + +if __name__ == "__main__": + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "example18.settings") + + from django.core.management import execute_from_command_line + + execute_from_command_line(sys.argv) diff --git a/example18/requirements.txt b/example18/requirements.txt new file mode 100644 index 0000000..3c05aa7 --- /dev/null +++ b/example18/requirements.txt @@ -0,0 +1,2 @@ +-r ./requirements/pypi_requirements.txt +-e .. # install with containing version_viewer version diff --git a/example18/requirements/pypi_requirements.txt b/example18/requirements/pypi_requirements.txt new file mode 100644 index 0000000..8ab26cc --- /dev/null +++ b/example18/requirements/pypi_requirements.txt @@ -0,0 +1,4 @@ +Django==1.8.18 +django-extensions==1.7.8 +psycopg2==2.7.1 +gunicorn==19.7.1 diff --git a/example18/templates/admin/base.html b/example18/templates/admin/base.html new file mode 100644 index 0000000..f60f3d5 --- /dev/null +++ b/example18/templates/admin/base.html @@ -0,0 +1,92 @@ +{% load i18n admin_static pip_version_viewer_tags %} +{% get_current_language as LANGUAGE_CODE %}{% get_current_language_bidi as LANGUAGE_BIDI %} + + +{% block title %}{% endblock %} + + +{% block extrastyle %}{% endblock %} + +{% if LANGUAGE_BIDI %}{% endif %} + + + + +{% block extrahead %}{% endblock %} +{% block blockbots %}{% endblock %} + +{% load i18n %} + + + + +
+ {% if not is_popup %} + + + + {% block breadcrumbs %} + + {% endblock %} + {% endif %} + + {% block messages %} + {% if messages %} + + {% endif %} + {% endblock messages %} + + +
+ {% block pretitle %}{% show_pip_package_versions %}{% endblock %} + {% block content_title %}{% if title %}

{{ title }}

{% endif %}{% endblock %} + {% block content %} + {% block object-tools %}{% endblock %} + {{ content }} + {% endblock %} + {% block sidebar %}{% endblock %} +
+
+ + + {% block footer %}{% endblock %} +
+ + + + diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..eda0fcc --- /dev/null +++ b/setup.py @@ -0,0 +1,9 @@ +from setuptools import setup + +setup( + name='version_viewer', + version='0.0.1a1', + packages=['version_viewer'], + install_requires=( + ), +) diff --git a/version_viewer/__init__.py b/version_viewer/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/version_viewer/mixins.py b/version_viewer/mixins.py new file mode 100644 index 0000000..e65d6c5 --- /dev/null +++ b/version_viewer/mixins.py @@ -0,0 +1,6 @@ + + +class Accessor(object): + + def allow_access(self, request): + return request.user.is_superuser diff --git a/version_viewer/pip_viewer.py b/version_viewer/pip_viewer.py new file mode 100644 index 0000000..f217da3 --- /dev/null +++ b/version_viewer/pip_viewer.py @@ -0,0 +1,8 @@ +import pip +from operator import itemgetter + + +def list_package_versions(): + installed_packages = pip.get_installed_distributions() + results = [{"package_name": i.key, "package_version": i.version} for i in installed_packages] + return sorted(results, key=itemgetter('package_name')) diff --git a/version_viewer/templates/version_viewer.html b/version_viewer/templates/version_viewer.html new file mode 100644 index 0000000..127852a --- /dev/null +++ b/version_viewer/templates/version_viewer.html @@ -0,0 +1,56 @@ +{% block content %} +
+ {% if allow %} + Installed Versions + {% endif %} +
+ + + + +{% endblock %} + + +{% block javascript %} + +{% endblock %} diff --git a/version_viewer/templatetags/__init__.py b/version_viewer/templatetags/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/version_viewer/templatetags/pip_version_viewer_tags.py b/version_viewer/templatetags/pip_version_viewer_tags.py new file mode 100644 index 0000000..e6cdb1f --- /dev/null +++ b/version_viewer/templatetags/pip_version_viewer_tags.py @@ -0,0 +1,19 @@ +from pydoc import locate + +from django.conf import settings +from django import template +# from version_viewer.mixins import Accessor +# here pull in class location for Accessor.. + + +register = template.Library() +accessor_class = locate(settings.ACCESSOR_CLASS_PATH) +accessor = accessor_class() + + +@register.inclusion_tag('version_viewer.html', takes_context=True) +def show_pip_package_versions(context): + if accessor.allow_access(request=context['request']): + return {'allow': True} + else: + return {'allow': False} diff --git a/version_viewer/urls.py b/version_viewer/urls.py new file mode 100644 index 0000000..85ba88b --- /dev/null +++ b/version_viewer/urls.py @@ -0,0 +1,14 @@ +try: + # django 1.6+ + from django.conf.urls import url +except ImportError: + # django <1.6 + from django.conf.urls.defaults import url + +from . import views + +urlpatterns = [ + url(r'^$', views.PipPackageViewer.as_view(), name='version_viewer'), + # url(r'^$', views.pip_package_viewer, + # None, name='pip_package_viewer'), +] diff --git a/version_viewer/views.py b/version_viewer/views.py new file mode 100644 index 0000000..6ed1ca4 --- /dev/null +++ b/version_viewer/views.py @@ -0,0 +1,20 @@ +from pydoc import locate + +from django.http import HttpResponse +from django.conf import settings +from django.core.exceptions import PermissionDenied +from pip_viewer import list_package_versions +from django.views.generic import View +import json + +accessor_class = locate(settings.ACCESSOR_CLASS_PATH) +accessor = accessor_class() + + +class PipPackageViewer(View): + + def get(self, request, *args, **kwargs): + if not accessor.allow_access(request): + raise PermissionDenied + packages = list_package_versions() + return HttpResponse(json.dumps(packages), status=200, content_type="application/json") From 4d7b7f5623f45e455b9d14d0e19b1cd63870a68c Mon Sep 17 00:00:00 2001 From: petercat12 Date: Wed, 26 Apr 2017 14:25:22 -0500 Subject: [PATCH 2/5] change name to django_version_viewer --- README.md | 12 ++++++------ django_version_viewer.egg-info/PKG-INFO | 10 ++++++++++ django_version_viewer.egg-info/SOURCES.txt | 9 +++++++++ django_version_viewer.egg-info/dependency_links.txt | 1 + django_version_viewer.egg-info/top_level.txt | 1 + .../__init__.py | 0 {version_viewer => django_version_viewer}/mixins.py | 0 .../pip_viewer.py | 0 .../templates/version_viewer.html | 8 ++++---- .../templatetags/__init__.py | 0 .../templatetags/pip_version_viewer_tags.py | 2 -- {version_viewer => django_version_viewer}/urls.py | 4 +--- {version_viewer => django_version_viewer}/views.py | 2 +- example18/example18/settings.py | 6 ++++-- example18/example18/urls.py | 2 +- setup.py | 4 ++-- 16 files changed, 40 insertions(+), 21 deletions(-) create mode 100644 django_version_viewer.egg-info/PKG-INFO create mode 100644 django_version_viewer.egg-info/SOURCES.txt create mode 100644 django_version_viewer.egg-info/dependency_links.txt create mode 100644 django_version_viewer.egg-info/top_level.txt rename {version_viewer => django_version_viewer}/__init__.py (100%) rename {version_viewer => django_version_viewer}/mixins.py (100%) rename {version_viewer => django_version_viewer}/pip_viewer.py (100%) rename {version_viewer => django_version_viewer}/templates/version_viewer.html (82%) rename {version_viewer => django_version_viewer}/templatetags/__init__.py (100%) rename {version_viewer => django_version_viewer}/templatetags/pip_version_viewer_tags.py (83%) rename {version_viewer => django_version_viewer}/urls.py (53%) rename {version_viewer => django_version_viewer}/views.py (94%) diff --git a/README.md b/README.md index 32feece..83fd618 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Pip Package Version Viewer +# Django Version Viewer The pip package version viewer plugin allows a queryable endpoint to display a list of dicts representing all installed pip packages in the environment that django is running in. It also allows the insertion of a template tag to any template to display a link which calls up a pop up modal displaying all installed pip packages. You may also configure which users have access to the link and endpoint. @@ -9,22 +9,22 @@ The pip package version viewer plugin allows a queryable endpoint to display a l Add the following to `INSTALLED_APPS` in `settings.py` INSTALLED_APPS = [ - 'version_viewer' + 'django_version_viewer' ] -Add `version_viewer` include to `urls.py` +Add `django_version_viewer` include to `urls.py` urlpatterns = [ ... - url(r'^version_viewer/', include('version_viewer.urls')), + url(r'^django_version_viewer/', include('django_version_viewer.urls')), ... ] Choose the Accessor class that determins who can view/access the version_viewer template tag and route: - # Version Viewer settings: + # Django Version Viewer settings: # default class only allows superusers access - ACCESSOR_CLASS_PATH = 'version_viewer.mxins.Accessor' + ACCESSOR_CLASS_PATH = 'django_version_viewer.mxins.Accessor' Override the `base.html` django Admin template (or the template of your choosing) by creating a `base.html` file inside a `templates/admin` directory in your project. diff --git a/django_version_viewer.egg-info/PKG-INFO b/django_version_viewer.egg-info/PKG-INFO new file mode 100644 index 0000000..fc950dc --- /dev/null +++ b/django_version_viewer.egg-info/PKG-INFO @@ -0,0 +1,10 @@ +Metadata-Version: 1.0 +Name: django-version-viewer +Version: 0.0.1a1 +Summary: UNKNOWN +Home-page: UNKNOWN +Author: UNKNOWN +Author-email: UNKNOWN +License: UNKNOWN +Description: UNKNOWN +Platform: UNKNOWN diff --git a/django_version_viewer.egg-info/SOURCES.txt b/django_version_viewer.egg-info/SOURCES.txt new file mode 100644 index 0000000..259c07f --- /dev/null +++ b/django_version_viewer.egg-info/SOURCES.txt @@ -0,0 +1,9 @@ +django_version_viewer/__init__.py +django_version_viewer/mixins.py +django_version_viewer/pip_viewer.py +django_version_viewer/urls.py +django_version_viewer/views.py +django_version_viewer.egg-info/PKG-INFO +django_version_viewer.egg-info/SOURCES.txt +django_version_viewer.egg-info/dependency_links.txt +django_version_viewer.egg-info/top_level.txt \ No newline at end of file diff --git a/django_version_viewer.egg-info/dependency_links.txt b/django_version_viewer.egg-info/dependency_links.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/django_version_viewer.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/django_version_viewer.egg-info/top_level.txt b/django_version_viewer.egg-info/top_level.txt new file mode 100644 index 0000000..88ad37d --- /dev/null +++ b/django_version_viewer.egg-info/top_level.txt @@ -0,0 +1 @@ +django_version_viewer diff --git a/version_viewer/__init__.py b/django_version_viewer/__init__.py similarity index 100% rename from version_viewer/__init__.py rename to django_version_viewer/__init__.py diff --git a/version_viewer/mixins.py b/django_version_viewer/mixins.py similarity index 100% rename from version_viewer/mixins.py rename to django_version_viewer/mixins.py diff --git a/version_viewer/pip_viewer.py b/django_version_viewer/pip_viewer.py similarity index 100% rename from version_viewer/pip_viewer.py rename to django_version_viewer/pip_viewer.py diff --git a/version_viewer/templates/version_viewer.html b/django_version_viewer/templates/version_viewer.html similarity index 82% rename from version_viewer/templates/version_viewer.html rename to django_version_viewer/templates/version_viewer.html index 127852a..8c66b1b 100644 --- a/version_viewer/templates/version_viewer.html +++ b/django_version_viewer/templates/version_viewer.html @@ -1,13 +1,13 @@ {% block content %}
{% if allow %} - Installed Versions + Installed Versions {% endif %}
-