├── intercom ├── templatetags │ ├── __init__.py │ └── intercom_tags.py ├── __init__.py └── templates │ └── intercom │ └── _intercom_js.html ├── MANIFEST.in ├── README.rst ├── .travis.yml ├── docs ├── installation.rst ├── changelog.rst ├── index.rst ├── conf.py ├── usage.rst └── Makefile ├── LICENSE └── setup.py /intercom/templatetags/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /intercom/__init__.py: -------------------------------------------------------------------------------- 1 | __version__ = "1.0.0" 2 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include README.rst 2 | recursive-include intercom/templates *.html 3 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | ================== 2 | django-intercom-io 3 | ================== 4 | 5 | A pluggable app for adding `intercom.io `_ to your Django site. 6 | 7 | Documentation can be found at http://django-intercom-io.rtfd.org. 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | 3 | python: 4 | - 2.7 5 | 6 | install: 7 | - pip install flake8 8 | - pip install -e . 9 | 10 | script: 11 | - flake8 --max-line-length=100 --max-complexity=10 --statistics --benchmark intercom 12 | -------------------------------------------------------------------------------- /docs/installation.rst: -------------------------------------------------------------------------------- 1 | .. _installation: 2 | 3 | Installation 4 | ============ 5 | 6 | * To install :: 7 | 8 | pip install django-intercom-io 9 | 10 | * Add ``"intercom"`` to your ``INSTALLED_APPS`` setting:: 11 | 12 | INSTALLED_APPS = [ 13 | # other apps 14 | "intercom", 15 | ] 16 | -------------------------------------------------------------------------------- /docs/changelog.rst: -------------------------------------------------------------------------------- 1 | .. _changelog: 2 | 3 | ChangeLog 4 | ========= 5 | 6 | 0.4 7 | --- 8 | 9 | - change has function to use user.pk instead of email address 10 | 11 | 0.3 12 | --- 13 | 14 | - add user id 15 | 16 | 17 | 0.2 18 | --- 19 | 20 | - pass user to context for rendering template 21 | 22 | 0.1 23 | --- 24 | 25 | - initial release 26 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | django-intercom-io 2 | ================== 3 | 4 | **django-intercom-io** makes it easy for you to add support for **intercom.io** to your Django website. 5 | 6 | 7 | Development 8 | ----------- 9 | 10 | The source repository can be found at https://github.com/eldarion/django-intercom-io 11 | 12 | 13 | Contents 14 | ======== 15 | 16 | .. toctree:: 17 | :maxdepth: 1 18 | 19 | changelog 20 | installation 21 | usage 22 | -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- 1 | import sys, os 2 | 3 | extensions = [] 4 | templates_path = [] 5 | source_suffix = '.rst' 6 | master_doc = 'index' 7 | project = u'django-intercom-io' 8 | copyright_holder = '' 9 | copyright = u'2013, %s' % copyright_holder 10 | exclude_patterns = ['_build'] 11 | pygments_style = 'sphinx' 12 | html_theme = 'default' 13 | htmlhelp_basename = '%sdoc' % project 14 | latex_documents = [ 15 | ('index', '%s.tex' % project, u'%s Documentation' % project, 16 | copyright_holder, 'manual'), 17 | ] 18 | man_pages = [ 19 | ('index', project, u'%s Documentation' % project, 20 | [copyright_holder], 1) 21 | ] 22 | 23 | sys.path.insert(0, os.pardir) 24 | m = __import__("intercom") 25 | 26 | version = m.__version__ 27 | release = version 28 | -------------------------------------------------------------------------------- /intercom/templates/intercom/_intercom_js.html: -------------------------------------------------------------------------------- 1 | {% if email %}{% endif %} 13 | -------------------------------------------------------------------------------- /intercom/templatetags/intercom_tags.py: -------------------------------------------------------------------------------- 1 | import json 2 | import hashlib 3 | import hmac 4 | import time 5 | 6 | from django import template 7 | from django.conf import settings 8 | 9 | 10 | register = template.Library() 11 | 12 | 13 | @register.inclusion_tag("intercom/_intercom_js.html") 14 | def intercom_js(user): 15 | if hasattr(settings, "INTERCOM_APP_ID") and user.is_authenticated(): 16 | if hasattr(settings, "INTERCOM_USER_HASH_KEY"): 17 | user_hash = hmac.new(settings.INTERCOM_USER_HASH_KEY, str(user.pk), hashlib.sha256).hexdigest() 18 | else: 19 | user_hash = None 20 | 21 | custom_data = {} 22 | for app in getattr(settings, "INTERCOM_APPS", []): 23 | m = __import__(app + ".intercom", globals(), locals(), ["intercom"]) 24 | custom_data.update(m.custom_data(user)) 25 | 26 | return { 27 | "app_id": settings.INTERCOM_APP_ID, 28 | "email": user.email, 29 | "user_hash": user_hash, 30 | "user": user, 31 | "created_at": int(time.mktime(user.date_joined.timetuple())), 32 | "custom_data": json.dumps(custom_data, ensure_ascii=False) 33 | } 34 | else: 35 | return {} 36 | -------------------------------------------------------------------------------- /docs/usage.rst: -------------------------------------------------------------------------------- 1 | .. _usage: 2 | 3 | Usage 4 | ===== 5 | 6 | At the top of your base template add:: 7 | 8 | {% load intercom_tags %} 9 | 10 | 11 | And just before the ```` tag add:: 12 | 13 | {% intercom_js user %} 14 | 15 | 16 | And if you want a feedback/support link, put:: 17 | 18 | Support 19 | 20 | somewhere (e.g. in your nav bar) as explained by the **intercom.io** documentation. 21 | 22 | In your settings file set ``INTERCOM_APP_ID`` and optionally (if you use a user hash for security) ``INTERCOM_USER_HASH_KEY`` with the values 23 | provided by **intercom.io**. 24 | 25 | 26 | Custom Data 27 | ----------- 28 | 29 | **intercom.io** lets you send custom, per-user data to its site. **django-intercom** lets individual apps contribute what custom data they want to provide. 30 | 31 | If you have an ``INTERCOM_APPS`` setting, it should be a list of apps that have an ``intercom`` module in them containing a ``custom_data`` function. This function should take a ``user`` and return a dictionary to be sent to **intercom.io** as custom data. 32 | 33 | For example, if you have an app called ``foo`` with a ``Foo`` model, you might add:: 34 | 35 | INTERCOM_APPS = [ 36 | "foo", 37 | ] 38 | 39 | to your settings and then in ``foo/intercom.py`` have:: 40 | 41 | from foo.models import Foo 42 | 43 | def custom_data(user): 44 | return { 45 | "foo_count" : Foo.objects.filter(user=user).count(), 46 | } 47 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012-2014, Eldarion, Inc. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of Eldarion, Inc. nor the names of its contributors may 15 | be used to endorse or promote products derived from this software without 16 | specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | PAPER = 8 | BUILDDIR = _build 9 | 10 | # Internal variables. 11 | PAPEROPT_a4 = -D latex_paper_size=a4 12 | PAPEROPT_letter = -D latex_paper_size=letter 13 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 14 | PROJECT = django-intercom-io 15 | 16 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest 17 | 18 | help: 19 | @echo "Please use \`make ' where is one of" 20 | @echo " html to make standalone HTML files" 21 | @echo " dirhtml to make HTML files named index.html in directories" 22 | @echo " singlehtml to make a single large HTML file" 23 | @echo " pickle to make pickle files" 24 | @echo " json to make JSON files" 25 | @echo " htmlhelp to make HTML files and a HTML help project" 26 | @echo " qthelp to make HTML files and a qthelp project" 27 | @echo " devhelp to make HTML files and a Devhelp project" 28 | @echo " epub to make an epub" 29 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" 30 | @echo " latexpdf to make LaTeX files and run them through pdflatex" 31 | @echo " text to make text files" 32 | @echo " man to make manual pages" 33 | @echo " changes to make an overview of all changed/added/deprecated items" 34 | @echo " linkcheck to check all external links for integrity" 35 | @echo " doctest to run all doctests embedded in the documentation (if enabled)" 36 | 37 | clean: 38 | -rm -rf $(BUILDDIR)/* 39 | 40 | html: 41 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 42 | @echo 43 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." 44 | 45 | dirhtml: 46 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml 47 | @echo 48 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." 49 | 50 | singlehtml: 51 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml 52 | @echo 53 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." 54 | 55 | pickle: 56 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle 57 | @echo 58 | @echo "Build finished; now you can process the pickle files." 59 | 60 | json: 61 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json 62 | @echo 63 | @echo "Build finished; now you can process the JSON files." 64 | 65 | htmlhelp: 66 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp 67 | @echo 68 | @echo "Build finished; now you can run HTML Help Workshop with the" \ 69 | ".hhp project file in $(BUILDDIR)/htmlhelp." 70 | 71 | qthelp: 72 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp 73 | @echo 74 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ 75 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:" 76 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/$(PROJECT).qhcp" 77 | @echo "To view the help file:" 78 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/$(PROJECT).qhc" 79 | 80 | devhelp: 81 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp 82 | @echo 83 | @echo "Build finished." 84 | @echo "To view the help file:" 85 | @echo "# mkdir -p $$HOME/.local/share/devhelp/$(PROJECT)" 86 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/$(PROJECT)" 87 | @echo "# devhelp" 88 | 89 | epub: 90 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub 91 | @echo 92 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub." 93 | 94 | latex: 95 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 96 | @echo 97 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." 98 | @echo "Run \`make' in that directory to run these through (pdf)latex" \ 99 | "(use \`make latexpdf' here to do that automatically)." 100 | 101 | latexpdf: 102 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 103 | @echo "Running LaTeX files through pdflatex..." 104 | make -C $(BUILDDIR)/latex all-pdf 105 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 106 | 107 | text: 108 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text 109 | @echo 110 | @echo "Build finished. The text files are in $(BUILDDIR)/text." 111 | 112 | man: 113 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man 114 | @echo 115 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man." 116 | 117 | changes: 118 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes 119 | @echo 120 | @echo "The overview file is in $(BUILDDIR)/changes." 121 | 122 | linkcheck: 123 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck 124 | @echo 125 | @echo "Link check complete; look for any errors in the above output " \ 126 | "or in $(BUILDDIR)/linkcheck/output.txt." 127 | 128 | doctest: 129 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest 130 | @echo "Testing of doctests in the sources finished, look at the " \ 131 | "results in $(BUILDDIR)/doctest/output.txt." 132 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import codecs 2 | import os 3 | import sys 4 | 5 | from distutils.util import convert_path 6 | from fnmatch import fnmatchcase 7 | from setuptools import setup, find_packages 8 | 9 | 10 | def read(fname): 11 | return codecs.open(os.path.join(os.path.dirname(__file__), fname)).read() 12 | 13 | 14 | # Provided as an attribute, so you can append to these instead 15 | # of replicating them: 16 | standard_exclude = ["*.py", "*.pyc", "*$py.class", "*~", ".*", "*.bak"] 17 | standard_exclude_directories = [ 18 | ".*", "CVS", "_darcs", "./build", "./dist", "EGG-INFO", "*.egg-info" 19 | ] 20 | 21 | 22 | # (c) 2005 Ian Bicking and contributors; written for Paste (http://pythonpaste.org) 23 | # Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php 24 | # Note: you may want to copy this into your setup.py file verbatim, as 25 | # you can't import this from another package, when you don't know if 26 | # that package is installed yet. 27 | def find_package_data( 28 | where=".", 29 | package="", 30 | exclude=standard_exclude, 31 | exclude_directories=standard_exclude_directories, 32 | only_in_packages=True, 33 | show_ignored=False): 34 | """ 35 | Return a dictionary suitable for use in ``package_data`` 36 | in a distutils ``setup.py`` file. 37 | 38 | The dictionary looks like:: 39 | 40 | {"package": [files]} 41 | 42 | Where ``files`` is a list of all the files in that package that 43 | don"t match anything in ``exclude``. 44 | 45 | If ``only_in_packages`` is true, then top-level directories that 46 | are not packages won"t be included (but directories under packages 47 | will). 48 | 49 | Directories matching any pattern in ``exclude_directories`` will 50 | be ignored; by default directories with leading ``.``, ``CVS``, 51 | and ``_darcs`` will be ignored. 52 | 53 | If ``show_ignored`` is true, then all the files that aren"t 54 | included in package data are shown on stderr (for debugging 55 | purposes). 56 | 57 | Note patterns use wildcards, or can be exact paths (including 58 | leading ``./``), and all searching is case-insensitive. 59 | """ 60 | out = {} 61 | stack = [(convert_path(where), "", package, only_in_packages)] 62 | while stack: 63 | where, prefix, package, only_in_packages = stack.pop(0) 64 | for name in os.listdir(where): 65 | fn = os.path.join(where, name) 66 | if os.path.isdir(fn): 67 | bad_name = False 68 | for pattern in exclude_directories: 69 | if (fnmatchcase(name, pattern) 70 | or fn.lower() == pattern.lower()): 71 | bad_name = True 72 | if show_ignored: 73 | print >> sys.stderr, ( 74 | "Directory %s ignored by pattern %s" 75 | % (fn, pattern)) 76 | break 77 | if bad_name: 78 | continue 79 | if (os.path.isfile(os.path.join(fn, "__init__.py")) 80 | and not prefix): 81 | if not package: 82 | new_package = name 83 | else: 84 | new_package = package + "." + name 85 | stack.append((fn, "", new_package, False)) 86 | else: 87 | stack.append((fn, prefix + name + "/", package, only_in_packages)) 88 | elif package or not only_in_packages: 89 | # is a file 90 | bad_name = False 91 | for pattern in exclude: 92 | if (fnmatchcase(name, pattern) 93 | or fn.lower() == pattern.lower()): 94 | bad_name = True 95 | if show_ignored: 96 | print >> sys.stderr, ( 97 | "File %s ignored by pattern %s" 98 | % (fn, pattern)) 99 | break 100 | if bad_name: 101 | continue 102 | out.setdefault(package, []).append(prefix+name) 103 | return out 104 | 105 | 106 | PACKAGE = "intercom" 107 | NAME = "django-intercom-io" 108 | DESCRIPTION = "a pluggable app for adding intercom.io to your website" 109 | AUTHOR = "James Tauber" 110 | AUTHOR_EMAIL = "developer@eldarion.com" 111 | URL = "https://github.com/eldarion/django-intercom-io" 112 | VERSION = __import__(PACKAGE).__version__ 113 | 114 | 115 | setup( 116 | name=NAME, 117 | version=VERSION, 118 | description=DESCRIPTION, 119 | long_description=read("README.rst"), 120 | author=AUTHOR, 121 | author_email=AUTHOR_EMAIL, 122 | license="BSD", 123 | url=URL, 124 | packages=find_packages(exclude=["tests.*", "tests"]), 125 | package_data=find_package_data(PACKAGE, only_in_packages=False), 126 | classifiers=[ 127 | "Development Status :: 3 - Alpha", 128 | "Environment :: Web Environment", 129 | "Intended Audience :: Developers", 130 | "License :: OSI Approved :: BSD License", 131 | "Operating System :: OS Independent", 132 | "Programming Language :: Python", 133 | "Framework :: Django", 134 | ], 135 | zip_safe=False, 136 | ) 137 | 138 | --------------------------------------------------------------------------------