Skip to content
This repository was archived by the owner on Oct 27, 2022. It is now read-only.

Commit 4cc6b33

Browse files
committed
Merge branch 'develop'
2 parents 43ffecd + 84dd344 commit 4cc6b33

19 files changed

+844
-2
lines changed

.gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ coverage.xml
5252
# Django stuff:
5353
*.log
5454
local_settings.py
55+
pep8.txt
5556

5657
# Flask stuff:
5758
instance/
@@ -87,3 +88,7 @@ ENV/
8788

8889
# Rope project settings
8990
.ropeproject
91+
92+
# PyDev
93+
.project
94+
.pydevproject

.travis.yml

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
language: python
2+
python:
3+
- "2.7"
4+
- "3.4"
5+
- "3.5"
6+
env:
7+
- DJANGO=1.9
8+
- DJANGO=1.10
9+
install:
10+
- pip install -q Django==$DJANGO --use-mirrors
11+
- pip install -q -e . --use-mirrors
12+
script:
13+
- python setup.py test

MANIFEST.in

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
include LICENSE
2+
include README.rst
3+
recursive-include docs *

README.md

-2
This file was deleted.

README.rst

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
===================
2+
django-discord-bind
3+
===================
4+
5+
This is a simple Django app that allows users to bind their Discord accounts
6+
to their Django accounts and join a partner Discord server using the OAuth2
7+
functionality of the Discord API.
8+
9+
Quick start
10+
-----------
11+
12+
1. Add "discord_bind" to your INSTALLED_APPS setting like this::
13+
14+
INSTALLED_APPS = [
15+
...
16+
'discord_bind',
17+
]
18+
19+
2. Include the polls URLconf in your project urls.py like this::
20+
21+
url(r'^discord/', include('discord_bind.urls')),
22+
23+
3. Run `python manage.py migrate` to create the discord_bind models.
24+
25+
4. Start the development server and visit http://127.0.0.1:8000/admin/
26+
to add a Discord invite code (you'll need the Admin app enabled).
27+
28+
5. Visit https://discordapp.com/developers/applications/me to create
29+
an application. Add http://127.0.0.1:8000/discord/cb as a redirect URI.
30+
31+
6. Add the Client ID and Secret values to the project settings.py file::
32+
33+
DISCORD_CLIENT_ID = 212763200357720576
34+
DISCORD_CLIENT_SECRET = MfpBbcX2Ga3boNhoQoBTdHNUS2B1xX8f
35+
36+
5. Visit http://127.0.0.1:8000/discord/ to bind your Discord account and
37+
auto-accept the invite code.

discord_bind/__init__.py

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
"""
2+
3+
The MIT License (MIT)
4+
5+
Copyright (c) 2016, Mark Rogaski
6+
7+
Permission is hereby granted, free of charge, to any person obtaining a copy
8+
of this software and associated documentation files (the "Software"), to deal
9+
in the Software without restriction, including without limitation the rights
10+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
copies of the Software, and to permit persons to whom the Software is
12+
furnished to do so, subject to the following conditions:
13+
14+
The above copyright notice and this permission notice shall be included in all
15+
copies or substantial portions of the Software.
16+
17+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23+
SOFTWARE.
24+
25+
"""
26+
default_app_config = 'discord_bind.apps.DiscordBindConfig'

discord_bind/admin.py

+107
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
"""
2+
3+
The MIT License (MIT)
4+
5+
Copyright (c) 2016, Mark Rogaski
6+
7+
Permission is hereby granted, free of charge, to any person obtaining a copy
8+
of this software and associated documentation files (the "Software"), to deal
9+
in the Software without restriction, including without limitation the rights
10+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
copies of the Software, and to permit persons to whom the Software is
12+
furnished to do so, subject to the following conditions:
13+
14+
The above copyright notice and this permission notice shall be included in all
15+
copies or substantial portions of the Software.
16+
17+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23+
SOFTWARE.
24+
25+
"""
26+
import requests
27+
28+
from django.contrib import admin
29+
from .models import DiscordUser, DiscordInvite
30+
31+
from discord_bind.app_settings import BASE_URI
32+
33+
@admin.register(DiscordUser)
34+
class DiscordUserAdmin(admin.ModelAdmin):
35+
list_display = ('user',
36+
'uid',
37+
'username',
38+
'discriminator',
39+
'email')
40+
list_display_links = ('uid',)
41+
fieldsets = (
42+
(None, {
43+
'fields': ('user',),
44+
}),
45+
('Discord Account', {
46+
'fields': ('uid', ('username', 'discriminator'), 'email', 'avatar'),
47+
}),
48+
('OAuth2', {
49+
'classes': ('collapse',),
50+
'fields': ('access_token', 'refresh_token', 'scope', 'expiry'),
51+
}),
52+
)
53+
readonly_fields = ('user',
54+
'uid',
55+
'access_token',
56+
'refresh_token',
57+
'scope',
58+
'expiry')
59+
search_fields = ['user__username',
60+
'user__email',
61+
'username',
62+
'discriminator',
63+
'uid',
64+
'email']
65+
66+
@admin.register(DiscordInvite)
67+
class DiscordInviteAdmin(admin.ModelAdmin):
68+
list_display = ('code',
69+
'active',
70+
'description',
71+
'guild_name',
72+
'channel_name',
73+
'channel_type')
74+
list_display_links = ('code',)
75+
fieldsets = (
76+
(None, {
77+
'fields': (('code', 'active'), 'description', 'groups'),
78+
}),
79+
('Discord Guild', {
80+
'fields': ('guild_name', 'guild_id', 'guild_icon'),
81+
}),
82+
('Discord Channel', {
83+
'fields': ('channel_name', 'channel_id', 'channel_type'),
84+
}),
85+
)
86+
readonly_fields = ('guild_name',
87+
'guild_id',
88+
'guild_icon',
89+
'channel_name',
90+
'channel_id',
91+
'channel_type')
92+
filter_horizontal = ('groups',)
93+
actions = ['update_context']
94+
95+
def update_context(self, request, queryset):
96+
""" Pull invite details from Discord """
97+
update = 0
98+
delete = 0
99+
invites = queryset.all()
100+
for invite in invites:
101+
if invite.update_context():
102+
update += 1
103+
else:
104+
invite.delete()
105+
delete += 1
106+
self.message_user(request, '%d updated, %d deleted' % (update, delete))
107+
update_context.short_description = 'Update invite context'

discord_bind/app_settings.py

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
"""
2+
3+
The MIT License (MIT)
4+
5+
Copyright (c) 2016, Mark Rogaski
6+
7+
Permission is hereby granted, free of charge, to any person obtaining a copy
8+
of this software and associated documentation files (the "Software"), to deal
9+
in the Software without restriction, including without limitation the rights
10+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
copies of the Software, and to permit persons to whom the Software is
12+
furnished to do so, subject to the following conditions:
13+
14+
The above copyright notice and this permission notice shall be included in all
15+
copies or substantial portions of the Software.
16+
17+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23+
SOFTWARE.
24+
25+
"""
26+
from __future__ import unicode_literals
27+
28+
from django.conf import settings
29+
30+
31+
# API service endpoints
32+
BASE_URI = getattr(settings, 'DISCORD_BASE_URI',
33+
'https://discordapp.com/api')
34+
AUTHZ_URI = getattr(settings, 'DISCORD_AUTHZ_URI',
35+
BASE_URI + '/oauth2/authorize')
36+
TOKEN_URI = getattr(settings, 'DISCORD_TOKEN_URI',
37+
BASE_URI + '/oauth2/token')
38+
39+
# OAuth2 application credentials
40+
CLIENT_ID = getattr(settings, 'DISCORD_CLIENT_ID', '')
41+
CLIENT_SECRET = getattr(settings, 'DISCORD_CLIENT_SECRET', '')
42+
43+
# OAuth2 scope
44+
AUTHZ_SCOPE = (
45+
['email', 'guilds.join'] if getattr(settings, 'DISCORD_EMAIL_SCOPE', True)
46+
else ['identity', 'guilds.join'])
47+
48+
# Return URI
49+
INVITE_URI = getattr(settings, 'DISCORD_INVITE_URI',
50+
'https://discordapp.com/channels/@me')
51+
RETURN_URI = getattr(settings, 'DISCORD_RETURN_URI', '/')

discord_bind/apps.py

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
"""
2+
3+
The MIT License (MIT)
4+
5+
Copyright (c) 2016, Mark Rogaski
6+
7+
Permission is hereby granted, free of charge, to any person obtaining a copy
8+
of this software and associated documentation files (the "Software"), to deal
9+
in the Software without restriction, including without limitation the rights
10+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
copies of the Software, and to permit persons to whom the Software is
12+
furnished to do so, subject to the following conditions:
13+
14+
The above copyright notice and this permission notice shall be included in all
15+
copies or substantial portions of the Software.
16+
17+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23+
SOFTWARE.
24+
25+
"""
26+
from django.apps import AppConfig
27+
28+
29+
class DiscordBindConfig(AppConfig):
30+
name = 'discord_bind'
+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# -*- coding: utf-8 -*-
2+
# Generated by Django 1.10 on 2016-08-12 04:43
3+
from __future__ import unicode_literals
4+
5+
from django.conf import settings
6+
from django.db import migrations, models
7+
import django.db.models.deletion
8+
9+
10+
class Migration(migrations.Migration):
11+
12+
initial = True
13+
14+
dependencies = [
15+
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
16+
('auth', '0008_alter_user_username_max_length'),
17+
]
18+
19+
operations = [
20+
migrations.CreateModel(
21+
name='DiscordInvite',
22+
fields=[
23+
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
24+
('code', models.CharField(max_length=32, unique=True)),
25+
('active', models.BooleanField(default=False)),
26+
('description', models.CharField(blank=True, max_length=256)),
27+
('guild_name', models.CharField(blank=True, max_length=64)),
28+
('guild_id', models.CharField(blank=True, max_length=20)),
29+
('guild_icon', models.CharField(blank=True, max_length=32)),
30+
('channel_name', models.CharField(blank=True, max_length=64)),
31+
('channel_id', models.CharField(blank=True, max_length=20)),
32+
('channel_type', models.CharField(blank=True, choices=[('text', 'text'), ('voice', 'voice')], max_length=5)),
33+
('groups', models.ManyToManyField(blank=True, related_name='discord_invites', to='auth.Group')),
34+
],
35+
),
36+
migrations.CreateModel(
37+
name='DiscordUser',
38+
fields=[
39+
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
40+
('uid', models.CharField(max_length=20, unique=True)),
41+
('username', models.CharField(max_length=254)),
42+
('discriminator', models.CharField(max_length=4)),
43+
('avatar', models.CharField(blank=True, max_length=32)),
44+
('email', models.EmailField(blank=True, max_length=254)),
45+
('access_token', models.CharField(blank=True, max_length=32)),
46+
('refresh_token', models.CharField(blank=True, max_length=32)),
47+
('scope', models.CharField(blank=True, max_length=256)),
48+
('expiry', models.DateTimeField(null=True)),
49+
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
50+
],
51+
),
52+
]

discord_bind/migrations/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)