diff --git a/.gitignore b/.gitignore index 3a412d80..26ae9a31 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,15 @@ docs/doctrees/* .project .pydevproject .directory + +# ignore demo attachments that user might have added +demo/demodesk/media/helpdesk/attachments/* +!demo/demodesk/media/helpdesk/attachments/DH-3 +demo/demodesk/media/helpdesk/attachments/DH-3/* +!demo/demodesk/media/helpdesk/attachments/DH-3/3 +!demo/demodesk/media/helpdesk/attachments/DH-3/4 +demo/demodesk/media/helpdesk/attachments/DH-3/3/* +demo/demodesk/media/helpdesk/attachments/DH-3/4/* +!demo/demodesk/media/helpdesk/attachments/DH-3/3/someinfo.txt +!demo/demodesk/media/helpdesk/attachments/DH-3/4/helpdesk.png + diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..601799cf --- /dev/null +++ b/Makefile @@ -0,0 +1,125 @@ +# Shortcuts for django-helpdesk testing and development using make +# +# For standard installation of django-helpdesk as a library, +# see INSTALL and the documentation in docs/. +# +# For details about how to develop django-helpdesk, +# see CONTRIBUTING.rst. +PIP = pip3 +TOX = tox + + +#: help - Display callable targets. +.PHONY: help +help: + @echo "django-helpdesk make shortcuts" + @echo "Here are available targets:" + @egrep -o "^#: (.+)" [Mm]akefile | sed 's/#: /* /' + + +#: develop - Install minimal development utilities for Python3 +.PHONY: develop +develop: + $(PIP) install -e . + +#: develop - Install minimal development utilities for Python2 +.PHONY: develop2 +develop2: + pip2 install -e . + + +#: clean - Basic cleanup, mostly temporary files. +.PHONY: clean +clean: + find . -name "*.pyc" -delete + find . -name '*.pyo' -delete + find . -name "__pycache__" -delete + + +#: distclean - Remove local builds, such as *.egg-info. +.PHONY: distclean +distclean: clean + rm -rf *.egg + rm -rf *.egg-info + rm -rf demo/*.egg-info + # remove the django-created database + rm -f demo/demodesk/*.sqlite3 + + +#: maintainer-clean - Remove almost everything that can be re-generated. +.PHONY: maintainer-clean +maintainer-clean: distclean + rm -rf build/ + rm -rf dist/ + rm -rf .tox/ + + +#: test - Run test suites. +.PHONY: test +test: + mkdir -p var + $(PIP) install -e .[test] + $(TOX) + + +#: documentation - Build documentation (Sphinx, README, ...) +.PHONY: documentation +documentation: sphinx readme + + +#: sphinx - Build Sphinx documentation (docs). +.PHONY: sphinx +sphinx: + $(TOX) -e sphinx + + +#: readme - Build standalone documentation files (README, CONTRIBUTING...). +.PHONY: readme +readme: + $(TOX) -e readme + + +#: demo - Setup demo project using Python3. +.PHONY: demo +demo: + $(PIP) install -e . + $(PIP) install -e demo + demodesk migrate --noinput + # Create superuser; user will be prompted to manually set a password + # When you get a prompt, enter a password of your choosing. + # We suggest a default of 'Test1234' for the demo project. + demodesk createsuperuser --username admin --email helpdesk@example.com + # Install fixtures + demodesk loaddata emailtemplate.json + demodesk loaddata demo.json + +#: demo - Setup demo project using Python2. +.PHONY: demo2 +demo2: + pip2 install -e . + pip2 install -e demo + demodesk migrate --noinput + # Create superuser; user will be prompted to manually set a password. + # When you get a prompt, enter a password of your choosing. + # We suggest a default of 'Test1234' for the demo project. + demodesk createsuperuser --username admin --email helpdesk@example.com + # Install fixtures (helpdesk templates as well as demo ticket data) + demodesk loaddata emailtemplate.json + demodesk loaddata demo.json + + +#: runserver - Run demo server using Python3 +.PHONY: rundemo +rundemo: demo + demodesk runserver 8080 + +#: runserver - Run demo server using Python2 +.PHONY: rundemo2 +rundemo2: demo2 + demodesk runserver 8080 + + +#: release - Tag and push to PyPI. +.PHONY: release +release: + $(TOX) -e release diff --git a/demo/README.rst b/demo/README.rst new file mode 100644 index 00000000..548bb850 --- /dev/null +++ b/demo/README.rst @@ -0,0 +1,110 @@ +django-helpdesk Demo Project +============================ + +This folder contains a demo Django project that +illustrates a simple django-helpdesk installation +with common settings. + +This project is *NOT* production ready, but can be +used as a template to get started. + +In particular, this should be useful for testing +purposes and for those that want to contribute +to development of django-helpdesk. For more information +on contributing, see the CONTRIBUTING.rst file +in the top level of the django-helpdesk directory. + +Running the demo +---------------- + +By default, the demo is configured for Python 3. + +While not recommended, the simplest way to get +started is to simply install django-helpdesk +to your system python package directory. +Ideally, you'd use a virtualenv instead +(see below for details). + +To use your system directory, from the top-level +django-helpdesk directory, simply run: + + sudo make rundemo + +Once the console gives a prompt that the HTTP +server is listening, open your web browser +and navigate to: + + localhost:8080 + +You should see the django-helpdesk public web portal! + +If you shut down the server, you can't immediately +re-run the demo because the make commands would +encounter problems trying to re-write the database. +Instead, before running the demo, you will need +to first clean the demo: + + sudo make distclean + +You may need to use sudo with other make targets too. + +*NOTE ON USING VIRTUALENV* + +Rather than using the system python, you probably +want to use a virtualenv. + +If so, you might change the pip in the makefile +to point to your virtualenv's pip instead +before running: + + make rundemo + +*NOTE ON USING PYTHON 2* + +By default, the demo uses Python 3, as Python 3 +will be the recommended version of python for +django-helpdesk and even Django itself in the near future. +However, if you wish to use Python 2, you can +instead run the following: + + sudo make rundemo2 + +Then navigate to the site in a browser as above. + +*NOTE ON DJANGO VERISON* + +The demo project was also created with Django 1.10 +in mind. If you are using a different version of Django, +slight tweaks might be necessary to make the demo work. + +*NOTE ON ATTACHMENTS* + +The folder: + + demo/demodesk/media/helpdesk/attachments + +comes pre-populated with a couple of attachments, +to demo how django-helpdesk deals with attachments. +You can look in this folder to see the raw data. +You can also create a different folder for this +and update settings.py, but note that this will +break the demo as some attachments may not be available +unless you migrate the existing data to the +new location. + +The demodesk project +-------------------- + +"demodesk" is the name of our demo Django project. + +You probably will want to look at demo/demodesk/config/settings.py +and read the comments, which walk you through a basic +installation with common configuration options. + +The top-level Makefile also gives a list of commands so you +can see how to get the project running. Of course, +when you plan to deploy this project, it is recommended +to use a "real" HTTP server like apache or nginx, +and so further configuration will be necessary. + +More information can be found in the top-level docs/ folder. diff --git a/demo/demodesk/config/__init__.py b/demo/demodesk/config/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/demo/demodesk/config/settings.py b/demo/demodesk/config/settings.py new file mode 100644 index 00000000..dde89105 --- /dev/null +++ b/demo/demodesk/config/settings.py @@ -0,0 +1,208 @@ +""" +Django settings for django-helpdesk demodesk project. + +Generated by 'django-admin startproject' using Django 1.10.2. + +For more information on this file, see +https://docs.djangoproject.com/en/1.10/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/1.10/ref/settings/ +""" + +import os + +# Build paths inside the project like this: os.path.join(BASE_DIR, ...) +BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = '_crkn1+fnzu5$vns_-d+^ayiq%z4k*s!!ag0!mfy36(y!vrazd' + +# 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.contrib.sites', + 'django.contrib.humanize', + 'bootstrapform', + 'helpdesk' +] + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'demodesk.config.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + '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 = 'demodesk.config.wsgi.application' + + +# django-helpdesk configuration settings +# You can override django-helpdesk's defaults by redefining them here. +# To see what settings are available, see the docs/configuration.rst +# file for more information. +# Some common settings are below. + +HELPDESK_DEFAULT_SETTINGS = { + 'use_email_as_submitter': True, + 'email_on_ticket_assign': True, + 'email_on_ticket_change': True, + 'login_view_ticketlist': True, + 'email_on_ticket_apichange': True, + 'preset_replies': True, + 'tickets_per_page': 25 +} + +# Should the public web portal be enabled? +HELPDESK_PUBLIC_ENABLED = True +HELPDESK_VIEW_A_TICKET_PUBLIC = True +HELPDESK_SUBMIT_A_TICKET_PUBLIC = True + +# Should the Knowledgebase be enabled? +HELPDESK_KB_ENABLED = True + +# Instead of showing the public web portal first, +# we can instead redirect users straight to the login page. +HELPDESK_REDIRECT_TO_LOGIN_BY_DEFAULT = False +LOGIN_URL = '/login/' +LOGIN_REDIRECT_URL = '/login/' + + +# Database +# - by default, we use SQLite3 for the demo, but you can also +# configure MySQL or PostgreSQL, see the docs for more: +# https://docs.djangoproject.com/en/1.10/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + } +} + + +# Sites +# - this allows hosting of more than one site from a single server, +# in practice you can probably just leave this default if you only +# host a single site, but read more in the docs: +# https://docs.djangoproject.com/en/1.10/ref/contrib/sites/ + +SITE_ID = 1 + + +# Sessions +# https://docs.djangoproject.com/en/1.10/topics/http/sessions + +SESSION_COOKIE_AGE = 86400 # = 1 day + +# For better default security, set these cookie flags, but +# these are likely to cause problems when testing locally +#CSRF_COOKIE_SECURE = True +#SESSION_COOKIE_SECURE = True +#CSRF_COOKIE_HTTPONLY = True +#SESSION_COOKIE_HTTPONLY = True + + +# Password validation +# https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + +# Email +# https://docs.djangoproject.com/en/1.10/topics/email/ + +# This demo uses the console backend, which simply prints emails to the console +# rather than actually sending them out. +DEFAULT_FROM_EMAIL = 'helpdesk@example.com' +SERVER_EMAIL = 'helpdesk@example.com' +EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' + +# If you want to test sending real emails, uncomment and modify the following: +#EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' +#EMAIL_HOST = 'smtp.example.com' +#EMAIL_PORT = '25' + +# Internationalization +# https://docs.djangoproject.com/en/1.10/topics/i18n/ + +# By default, django-helpdesk uses en, but other languages are also available. +# The most complete translations are: es-MX, ru +# Contribute to our translations via Transifex if you can! +# See CONTRIBUTING.rst for more info. +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.10/howto/static-files/ + +STATIC_URL = '/static/' + +# MEDIA_ROOT is where media uploads are stored. +# We set this to a directory to host file attachments created +# with tickets. +MEDIA_URL = '/media/' +MEDIA_ROOT = os.path.join(BASE_DIR, 'media') + +# Fixtures +# https://docs.djangoproject.com/en/1.10/ref/settings/#std:setting-FIXTURE_DIRS +# - This is only necessary to make the demo project work, not needed for +# your own projects unless you make your own fixtures +FIXTURE_DIRS = [os.path.join(BASE_DIR, 'fixtures')] diff --git a/demo/demodesk/config/urls.py b/demo/demodesk/config/urls.py new file mode 100644 index 00000000..0c37aac6 --- /dev/null +++ b/demo/demodesk/config/urls.py @@ -0,0 +1,31 @@ +"""django-helpdesk demodesk URL Configuration + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/1.10/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. Import the include() function: from django.conf.urls import url, include + 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) +""" +from django.conf.urls import url, include +from django.contrib import admin +from django.conf import settings +from django.conf.urls.static import static + + +# The following uses the static() helper function, +# which only works when in development mode (using DEBUG). +# For a real deployment, you'd have to properly configure a media server. +# For more information, see: +# https://docs.djangoproject.com/en/1.10/howto/static-files/ + +urlpatterns = [ + url(r'^admin/', admin.site.urls), + url(r'^', include('helpdesk.urls', namespace='helpdesk')), +] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/demo/demodesk/config/wsgi.py b/demo/demodesk/config/wsgi.py new file mode 100644 index 00000000..f8e39f59 --- /dev/null +++ b/demo/demodesk/config/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for django-helpdesk demodesk 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.10/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "demodesk.config.settings") + +application = get_wsgi_application() diff --git a/demo/demodesk/fixtures/demo.json b/demo/demodesk/fixtures/demo.json new file mode 100644 index 00000000..b921f295 --- /dev/null +++ b/demo/demodesk/fixtures/demo.json @@ -0,0 +1,13 @@ +[ + {"model": "helpdesk.queue", "pk": 1, "fields": {"title": "Django Helpdesk", "slug": "DH", "email_address": "django-helpdesk@example.com", "locale": "en-US", "allow_public_submission": true, "allow_email_submission": true, "escalate_days": 5, "new_ticket_cc": "", "updated_ticket_cc": "", "email_box_type": null, "email_box_host": "", "email_box_port": null, "email_box_ssl": false, "email_box_user": "", "email_box_pass": "", "email_box_imap_folder": "", "email_box_local_dir": "", "permission_name": "helpdesk.queue_access_DH", "email_box_interval": 5, "email_box_last_check": null, "socks_proxy_type": null, "socks_proxy_host": null, "socks_proxy_port": null, "logging_type": null, "logging_dir": "", "default_owner": null}}, + {"model": "helpdesk.queue", "pk": 2, "fields": {"title": "Some Product", "slug": "SP", "email_address": "sp-help@example.com", "locale": "en-US", "allow_public_submission": true, "allow_email_submission": true, "escalate_days": null, "new_ticket_cc": "", "updated_ticket_cc": "", "email_box_type": null, "email_box_host": "", "email_box_port": null, "email_box_ssl": false, "email_box_user": "", "email_box_pass": "", "email_box_imap_folder": "", "email_box_local_dir": "", "permission_name": "helpdesk.queue_access_SP", "email_box_interval": 5, "email_box_last_check": null, "socks_proxy_type": null, "socks_proxy_host": null, "socks_proxy_port": null, "logging_type": null, "logging_dir": "", "default_owner": null}}, + {"model": "helpdesk.ticket", "pk": 1, "fields": {"title": "Some django-helpdesk Problem", "queue": 1, "created": "2017-03-20T04:52:18.321Z", "modified": "2017-03-20T04:52:18.561Z", "submitter_email": "helpdesk@example.com", "assigned_to": null, "status": 1, "on_hold": false, "description": "I'm having some problem with django-helpdesk that I need help with.", "resolution": null, "priority": 3, "due_date": "2017-03-04T00:00:00Z", "last_escalation": null}}, + {"model": "helpdesk.followup", "pk": 1, "fields": {"ticket": 1, "date": "2017-03-20T04:52:18.561Z", "title": "Ticket Opened", "comment": "I'm having some problem with django-helpdesk that I need help with.", "public": true, "user": 1, "new_status": null}}, + {"model": "helpdesk.ticket", "pk": 2, "fields": {"title": "Something else", "queue": 2, "created": "2017-03-20T04:54:53.001Z", "modified": "2017-03-20T04:54:53.031Z", "submitter_email": "helpdesk@example.com", "assigned_to": null, "status": 1, "on_hold": false, "description": "Something else with some other product. Not a big deal.", "resolution": null, "priority": 4, "due_date": "2017-03-01T00:00:00Z", "last_escalation": null}}, + {"model": "helpdesk.followup", "pk": 2, "fields": {"ticket": 2, "date": "2017-03-20T04:54:53.031Z", "title": "Ticket Opened", "comment": "Something else with some other product. Not a big deal.", "public": true, "user": 1, "new_status": null}}, + {"model": "helpdesk.ticket", "pk": 3, "fields": {"title": "Something with an attachment", "queue": 1, "created": "2017-03-20T05:14:36.320Z", "modified": "2017-03-20T05:28:28.695Z", "submitter_email": "helpdesk@example.com", "assigned_to": null, "status": 1, "on_hold": false, "description": "WHOA!", "resolution": null, "priority": 1, "due_date": null, "last_escalation": null}}, + {"model": "helpdesk.followup", "pk": 3, "fields": {"ticket": 3, "date": "2017-03-20T05:14:36.345Z", "title": "Ticket Opened", "comment": "WHOA!", "public": true, "user": 1, "new_status": null}}, + {"model": "helpdesk.attachment", "pk": 1, "fields": {"followup": 3, "file": "helpdesk/attachments/DH-3/3/someinfo.txt", "filename": "someinfo.txt", "mime_type": "text/plain", "size": 56}}, + {"model": "helpdesk.followup", "pk": 4, "fields": {"ticket": 3, "date": "2017-03-20T05:28:28.458Z", "title": "Comment", "comment": "An image attachment goes here!", "public": true, "user": 1, "new_status": null}}, + {"model": "helpdesk.attachment", "pk": 2, "fields": {"followup": 4, "file": "helpdesk/attachments/DH-3/4/helpdesk.png", "filename": "helpdesk.png", "mime_type": "image/png", "size": 30229}} +] diff --git a/demo/demodesk/manage.py b/demo/demodesk/manage.py new file mode 100755 index 00000000..3427b7bc --- /dev/null +++ b/demo/demodesk/manage.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python +import os +import sys + +def main(): + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "demodesk.config.settings") + try: + from django.core.management import execute_from_command_line + except ImportError: + # The above import may fail for some other reason. Ensure that the + # issue is really that Django is missing to avoid masking other + # exceptions on Python 2. + try: + import django + except ImportError: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) + raise + execute_from_command_line(sys.argv) + +if __name__ == "__main__": + main() diff --git a/demo/demodesk/media/helpdesk/attachments/DH-3/3/someinfo.txt b/demo/demodesk/media/helpdesk/attachments/DH-3/3/someinfo.txt new file mode 100644 index 00000000..5259f04e --- /dev/null +++ b/demo/demodesk/media/helpdesk/attachments/DH-3/3/someinfo.txt @@ -0,0 +1,3 @@ +Here's a report about a bug. + +Some stuff would go here. diff --git a/demo/demodesk/media/helpdesk/attachments/DH-3/4/helpdesk.png b/demo/demodesk/media/helpdesk/attachments/DH-3/4/helpdesk.png new file mode 100644 index 00000000..584db614 Binary files /dev/null and b/demo/demodesk/media/helpdesk/attachments/DH-3/4/helpdesk.png differ diff --git a/demo/setup.py b/demo/setup.py new file mode 100644 index 00000000..02a18ebb --- /dev/null +++ b/demo/setup.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +"""Python packaging.""" + +from __future__ import unicode_literals + +from setuptools import setup +import os + +here = os.path.abspath(os.path.dirname(__file__)) +project_root = os.path.dirname(here) + + +NAME = 'django-helpdesk-demodesk' +DESCRIPTION = 'A demo Django project using django-helpdesk' +README = open(os.path.join(here, 'README.rst')).read() +VERSION = '0.2.0' +#VERSION = open(os.path.join(project_root, 'VERSION')).read().strip() +AUTHOR = 'django-helpdesk team' +URL = 'https://github.com/django-helpdesk/django-helpdesk' +CLASSIFIERS = ['Development Status :: 4 - Beta', + 'License :: OSI Approved :: BSD License', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'Framework :: Django'] +KEYWORDS = [] +PACKAGES = ['demodesk'] +REQUIREMENTS = [ + 'django-helpdesk' + ] +ENTRY_POINTS = { + 'console_scripts': ['demodesk = demodesk.manage:main'] +} + + +if __name__ == '__main__': # Don't run setup() when we import this module. + setup(name=NAME, + version=VERSION, + description=DESCRIPTION, + long_description=README, + classifiers=CLASSIFIERS, + keywords=' '.join(KEYWORDS), + author=AUTHOR, + url=URL, + license='BSD', + packages=PACKAGES, + include_package_data=True, + zip_safe=False, + install_requires=REQUIREMENTS, + entry_points=ENTRY_POINTS)