diff --git a/env.example b/env.example index 3b703bebba92d99e88b0ba05a04d7903be5c1037..6c528c0e1f97c09b04947d1426c1f383d49206f2 100644 --- a/env.example +++ b/env.example @@ -5,5 +5,8 @@ SECRET_KEY="%@=^sip3=tqn6d_-xvvidc1@-t0t3&*kab@vr4c4" CHOBOTNICE_API_URL="https://chobotnice.pirati.cz/graphql/" CHOBOTNICE_RV_GID="R3JvdXBUeXBlOjYyNQ==" +INSTAGRAM_CLIENT_ID=3828083077418467 +INSTAGRAM_CLIENT_SECRET=da7ea1af344e60ccd2bfcfa0f296b808 + # Production settings ALLOWED_HOSTS="tools.pirati.cz" diff --git a/instagram_token/__init__.py b/instagram_token/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/instagram_token/admin.py b/instagram_token/admin.py new file mode 100644 index 0000000000000000000000000000000000000000..8c38f3f3dad51e4585f3984282c2a4bec5349c1e --- /dev/null +++ b/instagram_token/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/instagram_token/apps.py b/instagram_token/apps.py new file mode 100644 index 0000000000000000000000000000000000000000..135a246c66478b2cdb299307c8b08b1c71354cc1 --- /dev/null +++ b/instagram_token/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class InstagramTokenConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'instagram_token' diff --git a/instagram_token/migrations/__init__.py b/instagram_token/migrations/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/instagram_token/models.py b/instagram_token/models.py new file mode 100644 index 0000000000000000000000000000000000000000..71a836239075aa6e6e4ecb700e9c42c95c022d91 --- /dev/null +++ b/instagram_token/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/instagram_token/templates/instagram_token/exchange.html b/instagram_token/templates/instagram_token/exchange.html new file mode 100644 index 0000000000000000000000000000000000000000..d13b75dd2aff48b2ff0e96c5f5dd29a062059b3b --- /dev/null +++ b/instagram_token/templates/instagram_token/exchange.html @@ -0,0 +1,39 @@ +{% extends "shared/base.html" %} + +{% load render_bundle from webpack_loader %} + +{% block title %}Kalkulačka přístupových tokenů do Instagramu{% endblock %} +{% block header_name %}Instagram{% endblock %} +{% block description %}Přihlášením svým účtem získáš přístupové údaje, které můžeš využít pro synchronizaci obsahu na domovské stránce pirati.cz.{% endblock %} + +{% block head %} + <link + rel="stylesheet" + href="https://styleguide.pirati.cz/2.11.x/css/styles.css" + > +{% endblock %} + +{% block content %} + <main> + <h1 class="text-6xl font-bebas mb-5">Kalkulačka přístupových tokenů do Instagramu</h1> + + <div class="prose max-w-none mb-5"> + <p> + Přihlášením svým účtem získáš přístupové údaje, které můžeš využít pro + <a href="https://majak.pirati.cz/admin" target="_blank">synchronizaci obsahu</a> + na domovské stránce pirati.cz. + </p> + </div> + + <div class="prose max-w-none"> + <p> + <strong>Uživatelské ID:</strong> <i>{{ user_id }}</i> + </p> + + <p> + <strong>Přístupový token:</strong> + <pre>{{ access_token }}</pre> + </p> + </div> + </main> +{% endblock %} diff --git a/instagram_token/templates/instagram_token/index.html b/instagram_token/templates/instagram_token/index.html new file mode 100644 index 0000000000000000000000000000000000000000..99261ed39f70f3e38ec5c96a8c427247edd92381 --- /dev/null +++ b/instagram_token/templates/instagram_token/index.html @@ -0,0 +1,35 @@ +{% extends "shared/base.html" %} + +{% load render_bundle from webpack_loader %} + +{% block title %}Kalkulačka přístupových tokenů do Instagramu{% endblock %} +{% block header_name %}Instagram{% endblock %} +{% block description %}Přihlášením svým účtem získáš přístupové údaje, které můžeš využít pro synchronizaci obsahu na domovské stránce pirati.cz.{% endblock %} + +{% block head %} + <link + rel="stylesheet" + href="https://styleguide.pirati.cz/2.11.x/css/styles.css" + > +{% endblock %} + +{% block content %} + <main> + <h1 class="text-6xl font-bebas mb-5">Kalkulačka přístupových tokenů do Instagramu</h1> + + <div class="prose max-w-none mb-5"> + <p> + Výsledky níže můžeš zkopírovat do Majáku. + </p> + </div> + + <a class="btn btn--icon" href="{{ authorization_url }}"> + <div class="btn__body-wrap"> + <div class="btn__body">Přihlásit se</div> + <div class="btn__icon"> + <i class="ico--chevron-right"></i> + </div> + </div> + </a> + </main> +{% endblock %} diff --git a/instagram_token/tests.py b/instagram_token/tests.py new file mode 100644 index 0000000000000000000000000000000000000000..7ce503c2dd97ba78597f6ff6e4393132753573f6 --- /dev/null +++ b/instagram_token/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/instagram_token/urls.py b/instagram_token/urls.py new file mode 100644 index 0000000000000000000000000000000000000000..85837f074a97cba8b2b5209e6cdfa0ee4d923596 --- /dev/null +++ b/instagram_token/urls.py @@ -0,0 +1,9 @@ +from django.urls import path + +from . import views + +app_name = "instagram_token" +urlpatterns = [ + path("", views.index, name="index"), + path("exchange", views.exchange, name="exchange"), +] diff --git a/instagram_token/views.py b/instagram_token/views.py new file mode 100644 index 0000000000000000000000000000000000000000..8cb892bc83d9739c95aae8e9432bd933848a929c --- /dev/null +++ b/instagram_token/views.py @@ -0,0 +1,58 @@ +import requests + +from django.conf import settings +from django.shortcuts import render +from django.urls import reverse +from django_http_exceptions import HTTPExceptions + +# Create your views here. + + +def index(request): + redirect_uri = request.build_absolute_uri(reverse("instagram_token:exchange")) + + authorization_url = ( + "https://api.instagram.com/oauth/authorize" + f"?client_id={settings.INSTAGRAM_CLIENT_ID}" + f"&redirect_uri={redirect_uri}" + "&scope=user_profile,user_media" + "&response_type=code" + ) + + return render( + request, + "instagram_token/index.html", + { + "authorization_url": authorization_url + } + ) + + +def exchange(request): + code = request.GET.get("code") + + if code is None: + return reverse("instagram_token:index") + + exchange_request = requests.post( + "https://api.instagram.com/oauth/access_token", + data={ + "client_id": settings.INSTAGRAM_CLIENT_ID, + "client_secret": settings.INSTAGRAM_CLIENT_SECRET, + "code": code, + "grant_type": "authorization_code", + "redirect_uri": request.build_absolute_uri(reverse("instagram_token:exchange")), + } + ) + + exchange_request.raise_for_status() + exchange_request = exchange_request.json() + + return render( + request, + "instagram_token/exchange.html", + { + "access_token": exchange_request["access_token"], + "user_id": exchange_request["user_id"], + } + ) diff --git a/rybicka/settings/base.py b/rybicka/settings/base.py index 882e6cdb172c968dc011c88623654de11d64bb94..83b43c6c1924e23fc8d7345945cba980f1c3f23a 100644 --- a/rybicka/settings/base.py +++ b/rybicka/settings/base.py @@ -49,6 +49,7 @@ INSTALLED_APPS = [ "member_group_size_calc", "rv_voting_calc", "mail_signature", + "instagram_token", ] MIDDLEWARE = [ @@ -125,3 +126,8 @@ CHOBOTNICE_API_URL=env.str( "https://chobotnice.pirati.cz/graphql/" ) CHOBOTNICE_RV_GID=env.str("CHOBOTNICE_RV_GID") + +# Instagram + +INSTAGRAM_CLIENT_ID = env.str("INSTAGRAM_CLIENT_ID") +INSTAGRAM_CLIENT_SECRET = env.str("INSTAGRAM_CLIENT_SECRET") diff --git a/rybicka/urls.py b/rybicka/urls.py index 4ebfaabffa1eedac7536f972d8a4317aa939411f..85428a70c90d275a61058f23eac19606a2525777 100644 --- a/rybicka/urls.py +++ b/rybicka/urls.py @@ -19,5 +19,6 @@ urlpatterns = [ path("vypocet-skupiny-clenu/", include("member_group_size_calc.urls")), path("hlasovani-rv/", include("rv_voting_calc.urls")), path("emailove-podpisy/", include("mail_signature.urls")), + path("instagram/", include("instagram_token.urls")), path("", include("shared.urls")), ] diff --git a/shared/static/shared/instagram.webp b/shared/static/shared/instagram.webp new file mode 100644 index 0000000000000000000000000000000000000000..014dc7e491ad8fc32c381fc2d5d907d15d52f1a3 Binary files /dev/null and b/shared/static/shared/instagram.webp differ diff --git a/shared/templates/shared/index.html b/shared/templates/shared/index.html index a42a2850239e307d86cddbda031c3c7b4435065e..2a62c24876693fd2db0d8c154b841766a984acb9 100644 --- a/shared/templates/shared/index.html +++ b/shared/templates/shared/index.html @@ -15,7 +15,7 @@ <main class="flex flex-col gap-8"> <section> <h2 class="head-alt-md mb-5">Zabudované nástroje</h2> - + <ul class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8"> <li class="card"> <a href="{% url "member_group_size_calc:index" %}"> @@ -36,7 +36,7 @@ </div> </div> </li> - + <li class="card"> <a href="{% url "rv_voting_calc:index" %}"> <img @@ -56,7 +56,7 @@ </div> </div> </li> - + <li class="card"> <a href="{% url "mail_signature:index" %}" target="_blank"> <img @@ -76,12 +76,33 @@ </div> </div> </li> + + <li class="card"> + <a href="{% url "instagram_token:index" %}" target="_blank"> + <img + src="{% static "shared/instagram.webp" %}" + alt="Kalkulačka přístupových tokenů do Instagramu" + class="w-full h-48 object-cover" + > + </a> + <div class="p-4"> + <h2 class="mb-2 text-xl font-bold"> + <a href="{% url "instagram_token:index" %}" target="_blank"> + Kalkulačka přístupových tokenů do Instagramu + </a> + </h2> + <div class="font-light text-sm break-words"> + Přihlášením svým účtem získáš přístupové údaje, které můžeš využít pro + synchronizaci obsahu na domovské stránce pirati.cz. + </div> + </div> + </li> </ul> </section> - + <section> <h2 class="head-alt-md mb-5">Externí nástroje</h2> - + <ul class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8"> <li class="card"> <a href="https://z.pirati.cz" target="_blank"> @@ -102,7 +123,7 @@ </div> </div> </li> - + <li class="card"> <a href="https://generator.pirati.cz" target="_blank"> <img