base site for phantas.ma

This commit is contained in:
j 2023-03-02 15:59:40 +01:00
parent 1e082c6786
commit d27f4ac0c0
32 changed files with 50 additions and 710 deletions

View file

@ -5,6 +5,5 @@ python3 -m venv venv
./venv/bin/pip install -r requirements.txt
./manage.py migrate
./manage.py update_geoip
./manage.py load_titles
./mange.py runserver
```

View file

@ -1,7 +1,7 @@
from django.conf import settings
from django.core.mail import EmailMessage
from django.shortcuts import render
from app.video.utils import render_to_json_response
from ..utils import render_to_json_response
from . import forms
from . import models
@ -11,7 +11,7 @@ def index(request):
form = forms.ContactForm(request.POST)
if form.is_valid():
message = 'From: %s\n\n%s' % (form.cleaned_data['email'], form.cleaned_data['message'])
subject = 'njp.ma contact message'
subject = 'phantas.ma contact message'
from_ = settings.CONTACT_FROM_EMAIL
to = [settings.CONTACT_TO_EMAIL]
msg = EmailMessage(subject, message, from_, to, reply_to=[form.cleaned_data['email']])

View file

@ -39,7 +39,6 @@ INSTALLED_APPS = [
'app',
'app.user',
'app.video',
'app.text',
'app.contact',
@ -145,13 +144,11 @@ DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
GEOIP_PATH = BASE_DIR / 'geo'
DEFAULT_PANDORA_API = "https://archive.njp.ma/api/"
DEFAULT_PANDORA_API = "https://pad.ma/api/"
TIMELINE_QUERY = {'conditions': []}
URL_PREFIX = ''
CONTACT_TO_EMAIL = 'contact@njp.ma'
CONTACT_FROM_EMAIL = 'contact@njp.ma'
CONTACT_TO_EMAIL = 'contact@phantas.ma'
CONTACT_FROM_EMAIL = 'contact@phantas.ma'
try:
from .local_settings import *

View file

@ -1,15 +0,0 @@
{% extends "base.html" %}
{% block title %}About{% endblock title %}
{% block body_class%}body--about animated animated-text{% endblock %}
{% block main %}
<div class="about">
</div>
{% endblock %}
{% block end %}
<script>
var pandoraURL = "{{ pandora_url }}";
</script>
<script src="{% static 'js/api.js' %}"></script>
<script src="{% static 'js/about.js' %}"></script>
{% endblock %}

View file

@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<title>
{% block title %}
njp.ma
phantas.ma
{% endblock title %}
</title>
<link href="{% sass_src 'css/style.scss' %}" rel="stylesheet" type="text/css">
@ -15,14 +15,16 @@
<div class="topnav">
<a href="/" class="title font-family-wrong">
<div class="title-text text">
njp.ma
phantas.ma{{text.get_absolute_url}}
</div>
</a>
<div class="item-title"></div>
<nav>
{% comment %}
<a href="{% url 'films' %}" class="animated-title"><span class="text">videos 비디오</span></a>
<a href="{% url 'texts' %}" class="animated-title"><span class="text">cuts 장면들</span></a>
<a href="{% url 'about' %}" class="animated-title"><span class="text">about 소개</span></a>
{% endcomment %}
</nav>
</div>
<main>

View file

@ -1,4 +0,0 @@
{% extends "base.html" %}
{% block main %}
some overview page with stuff
{% endblock %}

View file

@ -1,7 +0,0 @@
{% extends "base.html" %}
{% block main %}
<h1>{{ edit.data.title }}</h1>
{% if edit.vimeo_id %}
<iframe src="https://player.vimeo.com/video/{{ edit.vimeo_id }}" width="640" height="564" frameborder="0" allow="autoplay; fullscreen" allowfullscreen></iframe>
{% endif %}
{% endblock %}

View file

@ -1,4 +0,0 @@
{% extends "base.html" %}
{% block main %}
some overview page with stuff
{% endblock %}

View file

@ -67,12 +67,12 @@
</style>
<title>njp.ma</title>
<title>phantas.ma</title>
</head>
<body>
<div id="box">
<div id="shadowBox">
<h1 class="rainbow rainbow_text_animated">njp.ma</h1>
<h1 class="rainbow rainbow_text_animated">phantas.ma</h1>
<h2></h2>
</div>
</div>
@ -81,7 +81,7 @@
document.location.href = '/'
path = document.location.pathname.slice(1)
if (path) {
document.querySelector('h1').innerHTML = 'njp.ma/' + path
document.querySelector('h1').innerHTML = 'phantas.ma/' + path
if (path == 'polis') {
setTimeout(() => {
document.querySelector('h2').innerHTML = 'Oct 30, 2021 Mar 6, 2022'

View file

@ -1,120 +0,0 @@
{% extends "base.html" %}
{% block head %}
<meta name="title" content="{{ film.data.title }}"/>
<meta name="description" content="{% for director in film.data.director %}{{ director|safe }}{% endfor %}"/>
<meta property="og:title" content="{{ film.data.title }} {{ film.data.tile.zh }}"/>
<meta property="og:type" content="movie"/>
<meta property="og:url" content="https://njp.ma{{ film.get_absolute_url }}"/>
<meta property="og:site_name" content="njp.ma"/>
<meta property="og:description" content="{% for director in film.data.director %}{{ director|safe }}{% endfor %}"/>
<meta property="twitter:card" content="summary_large_image"/>
<meta property="twitter:title" content="{{ film.data.title }} {{ film.data.tile.zh }}"/>
<meta property="twitter:description" content="{% for director in film.data.director %}{{ director|safe }}{% endfor %}"/>
{% endblock head %}
{% block body_class%}animated{% endblock %}
{% block main %}
{% comment %}
<style>
:root {
--bg-color-1: {{ film.color_1 }};
--bg-color-2: {{ film.color_2 }};
--bg-color-3: {{ film.color_2 }};
--bg-color-4: {{ film.color_4 }};
}
body {
background-attachment: fixed;
}
</style>
{% endcomment %}
<div class="film">
<div class="info">
<div class="info-meta">
<h1>
<span class="font-bold">{{ film.data.title | safe }}</span>
</h1>
{% if film.data.date %}
<div class="date">
{{ film.data.date | safe }}
</div>
{% endif %}
<div class="country">
{{ film.data.country|default:''|join:', ' }}
</div>
<div class="type">
{{ film.data.type|default:''|join:', ' }}
</div>
<div class="details">
{{ film.data.description|default:''|safe }}
</div>
<div class="featuring">
Featuring:
{{ film.data.featuring|default:''|join:', ' }}
</div>
</div>
<div class="video-block">
<img src="{{ stream_prefix }}/{{ film.data.items.0.id }}/timelineslitscan64pframe.jpg" class="video-fallback-block">
<video
id="timeline-video"
src="{{ stream_prefix }}/{{ film.data.items.0.id }}/timelineslitscan64p.mp4"
poster="{{ stream_prefix }}/{{ film.data.items.0.id }}/timelineslitscan64pframe.jpg"
controlsList="nodownload"
autoplay
loop
muted
playsinline>
</video>
</div>
<div class="items">
{% for item in film.data.items %}
<div class="item">
<a href="play/{{ item.id }}">
<figure>
<div class="overlay">
<img src="{% static 'svg/play.svg' %}">
</div>
<img src="{{ stream_prefix }}/{{ item.id }}/480p.jpg">
<figcaption>
{{ item.title | safe }}
{% if item.date %}({{item.date | safe }}){% endif %}
</figcaption>
</figure>
</a>
</div>
{% endfor %}
</div>
<div class="play">
<div class="film-play-pandora"><a href="{{ film.pandora_url }}" target="_blank">Open in Archive</a></div>
</div>
{% if film.related_texts.exists %}
<div class="texts">
<h2>Related Assemblies</h2>
{% for text in film.related_texts %}
<div class="text">
<a href="{{ text.get_absolute_url }}">
{{ text.title | safe }}<br>
</a>
</div>
{% endfor %}
</div>
{% endif %}
</div>
</div>
{% endblock %}
{% block end %}
<script>
var film = {{ film.json | safe }};
film.prefix = "{{ stream_prefix }}";
var pandoraURL = "{{ pandora_url }}";
</script>
{% comment %}
<script src="{% static 'js/film.js' %}"></script>
{% endcomment %}
{% endblock %}

View file

@ -1,13 +0,0 @@
{% extends "base.html" %}
{% block main %}
<div id="ascroll"></div>
{% endblock %}
{% block end %}
<script>
var config = {{ config | safe }};
var pandoraURL = "{{ pandora_url }}";
var streamPrefix = "{{ stream_prefix }}";
</script>
<script src="{% static 'js/api.js' %}"></script>
<script src="{% static 'js/play.js' %}"></script>
{% endblock %}

View file

@ -1,54 +0,0 @@
{% extends "base.html" %}
{% block body_class%}animated animated-text{% endblock %}
{% block main %}
<div class="films">
<div class="actions">
<strong>Filter:</strong>
<select id="filter-select">
<option value="" selected>All Types</option>
{% for type in types %}
<option value="{{ type.value }}">{{ type.title }}</option>
{% endfor %}
</select>
<strong>Sort:</strong>
<select id="sort-select">
<option value="title">Title</option>
<option value="year">Year</option>
<option value="duration">Duration</option>
</select>
</div>
<div id="films-list">
{% for film in films %}
<div class="film"
data-position="{{ film.position }}"
data-title="{{ film.data.title }}"
data-year="{{ film.data.year|default:"9999" }}"
data-duration="{{ film.duration_seconds }}"
data-type="{{ film.data.type|join:"," }}"
>
<a href="{{ film.get_absolute_url }}">
<figure>
<div>
{% for item in film.data.items %}
<img src="{{ stream_prefix }}/{{ item.id }}/480p.jpg">
{% endfor %}
</div>
<figcaption>
<img src="{{ stream_prefix }}/{{ film.data.items.0.id }}/timeline64p.jpg">
</figcaption>
<figcaption>
{{ film.data.title | safe }}
{% if film.data.date %}({{ film.data.date|safe}}){% endif %}
</figcaption>
</figure>
</a>
</div>
{% endfor %}
</div>
</div>
{% endblock %}
{% block end %}
<script src="{% static 'js/films.js' %}"></script>
{% endblock %}

View file

@ -1,17 +1,16 @@
{% extends "base.html" %}
{% block head %}
<meta name="title" content="njp.ma"/>
<meta name="description" content="This archive was initiated in the context of CAMP After Media Promises"/>
<meta property="og:title" content="njp.ma"/>
<meta name="title" content="phantas.ma"/>
<meta name="description" content="phantas.ma"/>
<meta property="og:title" content="phantas.ma"/>
<meta property="og:url" content="https://njp.ma"/>
<meta property="og:url" content="https://phantas.ma"/>
<meta property="og:type" content="website"/>
<meta property="og:title" content="njp.ma" />
<meta property="og:description" content="This archive was initiated in the context of CAMP After Media Promises"/>
<meta property="og:title" content="phantas.ma" />
<meta property="og:description" content="phantas.ma"/>
<meta property="twitter:card" content="summary_large_image"/>
<meta property="twitter:title" content="njp.ma" />
<meta property="twitter:description" content="This archive was initiated in the context of CAMP After Media Promises"/>
<meta property="twitter:title" content="phantas.ma" />
<meta property="twitter:description" content="phantas.ma"/>
{% endblock head %}
{% block body_class%}animated animated-text body--home{% endblock %}
{% block main %}
@ -33,11 +32,11 @@
{% endif %}
<div class="home">
<div class="box">
<h1 class="h1-en-home">njp.ma</h1>
<h1 class="h1-en-home">Phantas.ma</h1>
<div class="font-size-sm">
<div class="h3"><a href="{% url 'films'%}" class="font-bold">videos 비디오</a></div>
<div class="h3"><a href="{% url 'texts' %}" class="font-bold">cuts 장면들</a></div>
<div class="h3"><a href="{% url 'about' %}" class="font-bold">about 소개</a></div>
{% for text in texts %}
<div class="h3"><a href="{{ text.get_absolute_url }}" class="font-bold">{{ text.title }}</a></div>
{% endfor %}
</div>
</div>
</div>

View file

@ -4,15 +4,15 @@
<meta name="description" content="{{ text.byline|striptags }}"/>
<meta property="og:title" content="{{ text.title }}"/>
<meta property="og:type" content="movie"/>
<meta property="og:url" content="https://njp.ma{{ text.get_absolute_url }}"/>
<meta property="og:site_name" content="njp.ma"/>
<meta property="og:url" content="https://phantas.ma{{ text.get_absolute_url }}"/>
<meta property="og:site_name" content="phantas.ma"/>
<meta property="og:description" content="{{ text.byline|striptags }}"/>
<meta name="title" content="{{ text.title }}"/>
<meta name="description" content="{{ text.byline|striptags }}"/>
<meta property="og:site_name" content="njp.ma"/>
<meta property="og:site_name" content="phantas.ma"/>
<meta property="og:description" content="{% for director in text.data.director %}{{ director|safe }}{% endfor %}"/>
<meta property="twitter:card" content="summary_large_image"/>
@ -20,7 +20,7 @@
<meta property="twitter:description" content="{{ text.byline|striptags }}"/>
{% endblock head %}
{% block title %}{{ text.title }} - njp.ma{% endblock title %}
{% block title %}{{ text.title }} - phantas.ma{% endblock title %}
{% block main %}
<div id="ascroll"></div>
{% endblock %}

View file

@ -1,5 +0,0 @@
{% extends "base.html" %}
{% block title %}TV{% endblock%}
{% block main %}
here be TV stuff
{% endblock %}

View file

@ -41,7 +41,7 @@ class Text(models.Model):
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
language = models.CharField(choices=LANGUAGE_CHOICES, max_length=8, default='en')
slug = models.SlugField()
slug = models.CharField(max_length=1024)
public = models.BooleanField(default=False)
listed = models.BooleanField("List this item on overview page", default=True)
position = models.IntegerField(default=0)
@ -50,14 +50,14 @@ class Text(models.Model):
byline = models.TextField(default="", blank=True)
body = models.TextField(default="", blank=True)
data = models.JSONField(default=dict)
data = models.JSONField(default=dict, blank=True)
annotations = models.JSONField(default=dict, blank=True, editable=False)
def __str__(self):
return self.title
def get_absolute_url(self):
return '/' + settings.URL_PREFIX + 'cuts/' + self.slug
return '/' + self.slug
def get_annotations(self):
api = ox.api.signin(settings.DEFAULT_PANDORA_API)
@ -165,21 +165,11 @@ class Text(models.Model):
super().save(*args, **kwargs)
def json(self):
from ..video.models import Film
data = {}
data['title'] = self.title
data['byline'] = self.byline
data['body'] = self.body
data['language'] = self.language
item_id = self.data.get('related')
if not item_id:
item_id = self.data.get('item')
if item_id:
item = Film.objects.filter(pandora_url=item_id).first()
if item:
for key in ('title', 'title_zh', 'director'):
data['item_' + key] = item.data[key]
data['item_url'] = item.get_absolute_url()
if isinstance(self.annotations, list) and len(self.annotations) > 0:
data['annotations'] = self.annotations
data.update(self.data)

View file

@ -3,7 +3,6 @@ from django.shortcuts import render, redirect, get_object_or_404
from django.conf import settings
from . import models
from ..video.views import get_stream_prefix
def fallback(request, slug=''):
if not slug:
@ -13,26 +12,17 @@ def fallback(request, slug=''):
return render(request, 'fallback.html', context)
def index(request):
from ..video.models import Film
from ..text.models import Text
context = {}
context['films'] = Film.objects.filter(public=True).count()
context['texts'] = Text.objects.filter(public=True, listed=True).count()
context['stream_prefix'] = get_stream_prefix(request)
featured = Film.objects.filter(featured=True)
featured_count = featured.count()
if featured_count:
featured = featured[random.randint(0, featured_count - 1)]
try:
featured = featured.data['items'][0]['id']
except:
featured = None
context['featured'] = featured
context['texts'] = Text.objects.filter(public=True, listed=True).order_by('title')
return render(request, 'index.html', context)
def page(request, slug=''):
print('page!!', slug)
context = {}
if request.user.is_staff:
if slug == "":
return index(request)
elif request.user.is_staff:
page = models.Page.objects.filter(slug=slug).first()
else:
page = models.Page.objects.filter(slug=slug, public=True).first()
@ -40,7 +30,7 @@ def page(request, slug=''):
context['page'] = page
return render(request, 'page.html', context)
else:
return render(request, 'fallback.html', context)
return text(request, slug)
def about(request):
context = {}
@ -54,11 +44,11 @@ def texts(request):
return render(request, 'texts.html', context)
def text(request, slug):
print('find text', slug)
context = {}
if request.user.is_staff:
context['text'] = get_object_or_404(models.Text, slug=slug)
else:
context['text'] = get_object_or_404(models.Text, slug=slug, public=True)
context['stream_prefix'] = get_stream_prefix(request)
context['pandora_url'] = settings.DEFAULT_PANDORA_API.replace('/api/', '')
return render(request, 'text.html', context)

View file

@ -17,27 +17,13 @@ from django.contrib import admin
from django.urls import path
from django.conf import settings
from .video import views as video
from .text import views as text
from .contact.views import index as contact
urlpatterns = [
path('admin/', admin.site.urls),
#path('pandoraAPI/', video.pandoraAPI, name='pandoraAPI'),
path(settings.URL_PREFIX + 'videos/', video.films, name='films'),
path(settings.URL_PREFIX + 'video/<str:slug>/play/<str:id>', video.film_play, name='film_play'),
path(settings.URL_PREFIX + 'video/<str:slug>/', video.film, name='film'),
path(settings.URL_PREFIX + 'edits/', video.edits, name='edits'),
path(settings.URL_PREFIX + 'edit/<str:slug>/play/<str:lang>', video.edit_play, name='edit_play'),
path(settings.URL_PREFIX + 'edit/<str:slug>/', video.edit, name='edit'),
path(settings.URL_PREFIX + 'tv/', video.tv, name='tv'),
path(settings.URL_PREFIX + 'cuts/', text.texts, name='texts'),
path(settings.URL_PREFIX + 'cuts/<str:slug>', text.text, name='text'),
#path(settings.URL_PREFIX + 'index-alt/', text.index_alt, name='index_alt'),
path(settings.URL_PREFIX + 'about/', text.about, name='about'),
path(settings.URL_PREFIX + 'contact/', contact, name='contact'),
path(settings.URL_PREFIX + '<str:slug>/', text.page, name='page'),
path(settings.URL_PREFIX[:-1], text.index, name='index'),
path('', text.fallback, name='fallback'),
path('<str:slug>', text.fallback, name='fallback'),
path('about/', text.about, name='about'),
path('contact/', contact, name='contact'),
path('<str:slug>', text.page, name='page'),
path('', text.index, name='index'),
]

View file

View file

@ -1,27 +0,0 @@
import logging
import json
from django.contrib import admin
from django.db.models import JSONField
from . import models
from ..widgets import PrettyJSONWidget
logger = logging.getLogger(__name__)
@admin.decorators.register(models.Film)
class FilmAdmin(admin.ModelAdmin):
formfield_overrides = {
JSONField: {'widget': PrettyJSONWidget}
}
list_display = (
'__str__',
'position',
'slug',
'public',
)
list_editable = ['public', 'position']
list_filter = ['public', 'featured']
#@admin.decorators.register(models.Edit)
#class EditAdmin(admin.ModelAdmin):
# pass

View file

@ -1,6 +0,0 @@
from django.apps import AppConfig
class VideoConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'app.video'

View file

@ -1,80 +0,0 @@
from django.core.management.base import BaseCommand
from django.conf import settings
import ox
from ... import models
def escape(key):
return key.replace('%', '%25').replace('&', '%26').replace('_', '%09').replace(' ', '_').replace('<', '%0E').replace('>', '%0F')
def escape_slug(key):
key = ox.decode_html(key).replace('%', '').replace('&', '-').replace('_', '-').replace(' ', '-').replace('<', '').replace('>', '').lower()
key = key.replace("'", '').replace('"', '').strip()
return key
class Command(BaseCommand):
help = 'import titles from pan.do/ra'
def add_arguments(self, parser):
parser.add_argument("--api", dest="api", type=str, default=settings.DEFAULT_PANDORA_API),
parser.add_argument("--group", dest="group", type=str, default='Asian Art Biennial 2021'),
def handle(self, *args, **options):
api = ox.api.signin(options['api'])
keys = [
'id', 'title', 'director', 'summary', 'source', 'sourcedescription', 'date', 'location',
'country', 'type', 'year',
'duration', 'featuring', 'cinematographer',
'hue', 'saturation', 'lightness',
'folder', 'folderdescription', 'rightslevel'
]
query = {
'query': {
},
'keys': ['id'],
'sort': [{'key': 'duration', 'operator': '-'}],
'range': [0, 1000]
}
folders = {}
for item in api.find(**query)['data']['items']:
item = api.get(id=item['id'], keys=keys)['data']
if item['rightslevel'] > 0:
continue
if isinstance(item['folder'], list):
print(item['id'])
if item['folder'] not in folders:
description = item['folderdescription'] or item.get('summary', '')
folders[item['folder']] = {
'title': item['folder'],
'date': item.get('date', ''),
'year': item.get('year', ''),
'country': item.get('country', []),
'featuring': item.get('featuring', []),
'type': item['type'],
'description': description,
'url': api.url.replace('/api/', '/grid/folder==' + escape(ox.decode_html(item['folder']))),
'items': [],
}
del item['folderdescription']
if 'summary' in item and item['summary'] == folders[item['folder']]['description']:
item['summary'] = ''
folders[item['folder']]['items'].append(item)
slugs = []
for item in folders.values():
slug = escape_slug(item['title'].split(' / ')[0])
f, c = models.Film.objects.get_or_create(slug=slug)
f.pandora_url = item['url']
for key, value in item.items():
if key != 'url':
f.data[{
}.get(key, key)] = value
if c:
f.public = True
f.save()
slugs.append(slug)
models.Film.objects.exclude(slug__in=slugs).delete()

View file

@ -1,29 +0,0 @@
import os
import re
import ox
from django.core.management.base import BaseCommand
from django.conf import settings
class Command(BaseCommand):
"""
"""
help = 'update geoip database'
args = ''
def handle(self, **options):
force = False
path = settings.GEOIP_PATH / 'GeoLite2-City.mmdb'
index = ox.net.read_url('https://db-ip.com/db/download/ip-to-city-lite').decode()
match = re.compile('href=[\'"](http.*.mmdb.gz)').findall(index)
if match:
url = match[0]
print('download', url)
ox.net.save_url(url, "%s.gz" % path)
if os.path.exists(path):
os.unlink(path)
os.system('gunzip "%s.gz"' % path)
else:
print('failed to download GeoLite2-City.mmdb')

View file

@ -1,27 +0,0 @@
# Generated by Django 3.2.9 on 2021-11-12 09:35
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Film',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', models.DateTimeField(auto_now_add=True)),
('modified', models.DateTimeField(auto_now=True)),
('slug', models.SlugField()),
('public', models.BooleanField(default=False)),
('position', models.IntegerField(default=0)),
('pandora_url', models.CharField(max_length=1024)),
('data', models.JSONField(blank=True, default=dict)),
],
),
]

View file

@ -1,18 +0,0 @@
# Generated by Django 3.2.9 on 2021-11-22 12:48
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('video', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='film',
name='featured',
field=models.BooleanField(default=False),
),
]

View file

@ -1,83 +0,0 @@
import logging
import json
from django.conf import settings
from django.contrib.auth import get_user_model
from django.db import models
from django.db.models import Q
import ox
logger = logging.getLogger(__name__)
User = get_user_model()
class Film(models.Model):
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
slug = models.SlugField()
public = models.BooleanField(default=False)
featured = models.BooleanField(default=False)
position = models.IntegerField(default=0)
pandora_url = models.CharField(max_length=1024)
data = models.JSONField(default=dict, blank=True)
def __str__(self):
return self.data.get('title', self.slug)
def get_absolute_url(self):
return '/' + settings.URL_PREFIX + 'video/' + self.slug
def related_texts(self):
from ..text.models import Text
folder = self.data.get('title')
if folder:
return Text.objects.filter(Q(data__folder=folder) | Q(data__related=folder))
def duration_seconds(self):
duration = 0
for item in self.data.get('items', []):
duration += item['duration']
return duration
def duration(self):
return ox.format_duration(self.data['duration'] * 1000, verbosity=1, milliseconds=False)
def color_1(self):
hue = self.data['hue']
saturation = self.data['saturation'] * 100
saturation = 70
lightness = self.data['lightness'] * 100
return "hsl({}, {}%, {}%)".format(hue, saturation, lightness)
def color_2(self):
hue = self.data['hue']
saturation = self.data['saturation'] * 100
saturation = 70
lightness = self.data['lightness'] * 50
return "hsl({}, {}%, {}%)".format(hue, saturation, lightness)
def color_3(self):
hue = self.data['hue']
saturation = self.data['saturation'] * 100
saturation = 70
lightness = self.data['lightness'] * 110
return "hsl({}, {}%, {}%)".format(hue, saturation, lightness)
def color_4(self):
hue = self.data['hue']
saturation = self.data['saturation'] * 100
saturation = 70
lightness = self.data['lightness'] * 80
return "hsl({}, {}%, {}%)".format(hue, saturation, lightness)
def json(self):
data = {}
data['url'] = self.pandora_url
#data.update(self.data)
return json.dumps(data)

View file

@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.

View file

@ -1,128 +0,0 @@
import logging
import json
from collections import Counter
from django.shortcuts import render, redirect, get_object_or_404
from django.views.decorators.csrf import csrf_exempt
from django.conf import settings
from django.contrib.gis.geoip2 import GeoIP2, GeoIP2Exception
import ox.geo
from . import models
logger = logging.getLogger(__name__)
stream_prefix_cache = {}
def get_ip(request):
if 'HTTP_X_FORWARDED_FOR' in request.META:
ip = request.META['HTTP_X_FORWARDED_FOR'].split(',')[0]
else:
ip = request.META['REMOTE_ADDR']
if ip.startswith('::ffff:'):
ip = ip[len('::ffff:'):]
return ip
def get_stream_prefix(request):
#domain = settings.DEFAULT_PANDORA_API.split('/')[2]
domain = 'njp.ma'
prefix = "https://media.v1.%s" % domain
cdn = {
'Eastern Asia': "https://media.v2.%s" % domain,
'Southern Asia': "https://media.v2.%s" % domain,
'Asia': "https://media.v2.%s" % domain,
}
ip = get_ip(request)
if ip in stream_prefix_cache:
return stream_prefix_cache[ip]
try:
g = GeoIP2()
country = g.country(ip)
if country:
country = ox.get_country_name(country['country_code'])
info = ox.geo.get_country(country)
for key in ('name', 'region', 'continent'):
location = info.get(key)
#print(location)
if location in cdn:
stream_prefix_cache[ip] = cdn[location]
return cdn[location]
except:
logger.error('using default prefix, no geoip data found, run ./mange.py update_geoio', exc_info=True)
stream_prefix_cache[ip] = prefix
return prefix
stream_prefix_cache[ip] = prefix
return prefix
def films(request):
context = {}
context['films'] = models.Film.objects.filter(public=True).order_by('position', 'data__title')
types = []
for f in context['films']:
types += [t.capitalize() for t in f.data['type']]
types = Counter(types)
context['types'] = []
for t in sorted(types):
context['types'].append({
'title': '%s (%s)' % (t, types[t]), 'value': t
})
context['stream_prefix'] = get_stream_prefix(request)
context['settings'] = settings
return render(request, 'films.html', context)
def film(request, slug):
context = {}
context['film'] = get_object_or_404(models.Film, slug=slug)
context['settings'] = settings
context['stream_prefix'] = get_stream_prefix(request)
context['pandora_url'] = settings.DEFAULT_PANDORA_API.replace('/api/', '')
return render(request, 'film.html', context)
def film_play(request, slug, id):
context = {}
context['settings'] = settings
context['config'] = json.dumps({
'layer': 'transcripts',
'item': id
})
context['stream_prefix'] = get_stream_prefix(request)
context['pandora_url'] = settings.DEFAULT_PANDORA_API.replace('/api/', '')
return render(request, 'film_play.html', context)
def edits(request):
context = {}
context['edits'] = models.Edit.objects.filter(public=True).order_by('created')
return render(request, 'edits.html', context)
def edit(request, slug):
context = {}
context['edit'] = get_object_or_404(models.Edit, slug=slug)
context['settings'] = settings
return render(request, 'edit.html', context)
def edit_play(request, slug, lang):
context = {}
context['edit'] = get_object_or_404(models.Edit, slug=slug)
context['lang'] = lang
context['settings'] = settings
return render(request, 'edit_play.html', context)
def tv(request):
context = {}
context['settings'] = settings
return render(request, 'tv.html', context)
@csrf_exempt
def pandoraAPI(request):
import ox
from .utils import render_to_json_response
import json
data = json.loads(request.body.decode())
print('pandora request', data)
api = ox.api.signin('https://pad.ma/api/')
data = getattr(api, data['action'])(**data['data'])
print('response', data)
return render_to_json_response(data)

View file

@ -9,19 +9,19 @@ server {
root /var/www/html;
autoindex off;
}
rewrite ^/(.*) https://njp.ma/$1 permanent;
rewrite ^/(.*) https://phantas.ma/$1 permanent;
}
server {
server_tokens off;
server_name njp.ma;
server_name phantas.ma;
listen 443 ssl http2;
listen [::]:443 ssl http2;
ssl_trusted_certificate /etc/letsencrypt/live/njp.ma/chain.pem;
ssl_certificate /etc/letsencrypt/live/njp.ma/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/njp.ma/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/phantas.ma/chain.pem;
ssl_certificate /etc/letsencrypt/live/phantas.ma/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/phantas.ma/privkey.pem;
#include /etc/letsencrypt/nginx.conf;
location /favicon.ico {

View file

@ -1,14 +1,14 @@
[Unit]
Description=njpma
Description=phantasma
[Service]
Type=simple
Restart=always
User=pandora
Group=pandora
WorkingDirectory=/srv/njpma
WorkingDirectory=/srv/phantasma
ExecReload=/bin/kill -HUP $MAINPID
ExecStart=/srv/njpma/venv/bin/gunicorn app.wsgi:application --reuse-port -b [::]:8080
ExecStart=/srv/phantasma/venv/bin/gunicorn app.wsgi:application --reuse-port -b [::]:8085
[Install]
WantedBy=multi-user.target