Archived
Django 1.7 and cleanups
This commit is contained in:
1 parent
dcae0e9048
commit
a46d07843e
30 files changed
+386
-415
No files matched your search
+3
-2
@@ -1,6 +1,7 @@
|
||||
*.pyc
|
||||
*.swp
|
||||
*.swo
|
||||
settings.py
|
||||
oliver_screen.sqlite3
|
||||
db.sqlite3
|
||||
local_settings.py
|
||||
venv
|
||||
.idea
|
||||
@@ -1,31 +1,16 @@
|
||||
Requirements
|
||||
============
|
||||
* Django
|
||||
* sudo apt-get install python-django
|
||||
* mod\_wsgi
|
||||
* sudo apt-get install libapache2-mod-wsgi
|
||||
* sudo a2enmod wsgi # enable it in apache.
|
||||
* pylast
|
||||
* svn checkout http://pylast.googlecode.com/svn/trunk/ pylast-read-only
|
||||
* cd pylast-read-only
|
||||
* sudo python setup.py install
|
||||
# Install
|
||||
apt install python-virtualenv
|
||||
virtualenv venv
|
||||
. venv/bin/activate
|
||||
pip install -r requirements.txt
|
||||
python manage.py migrate
|
||||
python manage.py runserver
|
||||
|
||||
You will also need a LastFM account and a API account (http://www.last.fm/api/account).
|
||||
* You will also need a LastFM account and a API account from http://www.last.fm/api/account
|
||||
* Create a local_settings.py and set your own LASTFM\_APIKEY and LASTFM\_API\_SECRET
|
||||
|
||||
Install with Apache
|
||||
===================
|
||||
* Get the code
|
||||
* $ git clone git://github.com/nikolaik/oliver\_screen.git
|
||||
* Make available static files under oliver\_screen/oliver\_screen/static by symlinking or setup a <Directory> and Alias in your Apache config.
|
||||
* Then setup a WSGIScriptAlias in your apache config pointing to the full path of django.wsgi.
|
||||
* sudo /etc/init.d/apache restart # load new Apache configuration settings
|
||||
* Copy settings-sample.py to settings.py and edit to suit your needs.
|
||||
* Set MEDIA\_URL to the URL where static files are served.
|
||||
* Set LASTFM\_APIKEY and LASTFM\_API\_SECRET
|
||||
* Create the database.
|
||||
* $ python manage.py syncdb (creating an admin user)
|
||||
* Make sure the files have correct permission (readable by www-data).
|
||||
* If you created a sqlite database, make sure the file is writeable by www-data.
|
||||
* Goto /admin and login with the admin user, then add a LastFMUser and make it active.
|
||||
* Setup your music player (f.ex Spotify) to scrobble to that account Last.fm account.
|
||||
# Usage
|
||||
* Create an admin user: python manage.py createsuperuser
|
||||
* Goto /admin, login, then add a LastFMUser and make it active.
|
||||
* Setup your music player (f.ex Spotify) to scrobble to that LastFM account.
|
||||
* Goto / and you should be set :=)
|
||||
@@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env python
|
||||
import os
|
||||
import sys
|
||||
|
||||
if __name__ == "__main__":
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "oliversite.settings")
|
||||
|
||||
from django.core.management import execute_from_command_line
|
||||
|
||||
execute_from_command_line(sys.argv)
|
||||
@@ -0,0 +1,14 @@
|
||||
from django.contrib import admin
|
||||
|
||||
from oliver_screen.models import LastFMUser, YouTubeVideo
|
||||
|
||||
|
||||
class LastFMAdmin(admin.ModelAdmin):
|
||||
pass
|
||||
|
||||
|
||||
class VideoAdmin(admin.ModelAdmin):
|
||||
pass
|
||||
|
||||
admin.site.register(LastFMUser, LastFMAdmin)
|
||||
admin.site.register(YouTubeVideo, VideoAdmin)
|
||||
@@ -1,15 +0,0 @@
|
||||
import os
|
||||
import sys
|
||||
from os.path import dirname, join
|
||||
|
||||
def map_path(target_name=''):
|
||||
'''Enables path names to be decided at runtime.'''
|
||||
return join(dirname(__file__), target_name).replace('\\', '/')
|
||||
|
||||
os.environ['DJANGO_SETTINGS_MODULE'] = 'oliver_screen.settings'
|
||||
|
||||
path = map_path("..")
|
||||
if path not in sys.path:
|
||||
sys.path.append(path)
|
||||
import django.core.handlers.wsgi
|
||||
application = django.core.handlers.wsgi.WSGIHandler()
|
||||
@@ -1,3 +0,0 @@
|
||||
from django.db import models
|
||||
|
||||
# Create your models here.
|
||||
@@ -1,23 +0,0 @@
|
||||
"""
|
||||
This file demonstrates two different styles of tests (one doctest and one
|
||||
unittest). These will both pass when you run "manage.py test".
|
||||
|
||||
Replace these with more appropriate tests for your application.
|
||||
"""
|
||||
|
||||
from django.test import TestCase
|
||||
|
||||
class SimpleTest(TestCase):
|
||||
def test_basic_addition(self):
|
||||
"""
|
||||
Tests that 1 + 1 always equals 2.
|
||||
"""
|
||||
self.failUnlessEqual(1 + 1, 2)
|
||||
|
||||
__test__ = {"doctest": """
|
||||
Another way to test that 1 + 1 is equal to 2.
|
||||
|
||||
>>> 1 + 1 == 2
|
||||
True
|
||||
"""}
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
from django.conf.urls.defaults import *
|
||||
urlpatterns = patterns('oliver_screen.main.views',
|
||||
(r'^$', 'index'),
|
||||
)
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
from django.http import HttpResponse
|
||||
from django.shortcuts import render_to_response, get_object_or_404
|
||||
from django.template import RequestContext
|
||||
|
||||
# My views
|
||||
def index(request):
|
||||
return render_to_response('public/index.html', context_instance=RequestContext(request))
|
||||
@@ -1,11 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
from django.core.management import execute_manager
|
||||
try:
|
||||
import settings # Assumed to be in the same directory.
|
||||
except ImportError:
|
||||
import sys
|
||||
sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
execute_manager(settings)
|
||||
@@ -0,0 +1,51 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='CurrentTrack',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('title', models.CharField(max_length=200)),
|
||||
('artist', models.CharField(max_length=200)),
|
||||
('image', models.CharField(max_length=200)),
|
||||
('retries', models.IntegerField()),
|
||||
],
|
||||
options={
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='LastFMUser',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('name', models.CharField(max_length=200)),
|
||||
('active', models.BooleanField(default=True)),
|
||||
],
|
||||
options={
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='YouTubeVideo',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('title', models.CharField(max_length=200)),
|
||||
('artist', models.CharField(max_length=200)),
|
||||
('video_id', models.CharField(max_length=200)),
|
||||
('start', models.IntegerField()),
|
||||
('active', models.BooleanField(default=True)),
|
||||
],
|
||||
options={
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
]
|
||||
File renamed without changes.
@@ -1,5 +1,6 @@
|
||||
from django.db import models
|
||||
|
||||
|
||||
class CurrentTrack(models.Model):
|
||||
title = models.CharField(max_length=200)
|
||||
artist = models.CharField(max_length=200)
|
||||
@@ -9,24 +10,25 @@ class CurrentTrack(models.Model):
|
||||
def __unicode__(self):
|
||||
return self.title + " - " + self.artist
|
||||
|
||||
|
||||
class LastFMUser(models.Model):
|
||||
name = models.CharField(max_length=200)
|
||||
active = models.BooleanField()
|
||||
active = models.BooleanField(default=True)
|
||||
|
||||
def __unicode__(self):
|
||||
if self.active:
|
||||
return self.name + ": active"
|
||||
return self.name + ": NOT active"
|
||||
|
||||
|
||||
class YouTubeVideo(models.Model):
|
||||
title = models.CharField(max_length=200)
|
||||
artist = models.CharField(max_length=200)
|
||||
videoId = models.CharField(max_length=200)
|
||||
video_id = models.CharField(max_length=200) # FIXME: Update template
|
||||
start = models.IntegerField()
|
||||
active = models.BooleanField()
|
||||
active = models.BooleanField(default=True)
|
||||
|
||||
def __unicode__(self):
|
||||
if self.active:
|
||||
return self.artist + " - " + self.title + ": active"
|
||||
return self.artist +" - " + self.title + " : NOT active"
|
||||
|
||||
return self.artist + " - " + self.title + " : NOT active"
|
||||
@@ -1,3 +0,0 @@
|
||||
Django==1.3.7
|
||||
pylast==0.5.11
|
||||
|
||||
@@ -1,107 +0,0 @@
|
||||
# Django settings for oliver_screen project.
|
||||
|
||||
from os.path import dirname, join
|
||||
|
||||
def map_path(target_name):
|
||||
'''Enables path names to be decided at runtime.'''
|
||||
return join(dirname(__file__), target_name).replace('\\', '/')
|
||||
|
||||
DEBUG = True
|
||||
TEMPLATE_DEBUG = DEBUG
|
||||
|
||||
ADMINS = (
|
||||
# ('EDB', 'nikolai@studentersamfundet.no'),
|
||||
)
|
||||
|
||||
MANAGERS = ADMINS
|
||||
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
|
||||
'NAME': map_path('oliver_screen.sqlite3'), # Or path to database file if using sqlite3.
|
||||
'USER': '', # Not used with sqlite3.
|
||||
'PASSWORD': '', # Not used with sqlite3.
|
||||
'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
|
||||
'PORT': '', # Set to empty string for default. Not used with sqlite3.
|
||||
}
|
||||
}
|
||||
|
||||
# Local time zone for this installation. Choices can be found here:
|
||||
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
|
||||
# although not all choices may be available on all operating systems.
|
||||
# On Unix systems, a value of None will cause Django to use the same
|
||||
# timezone as the operating system.
|
||||
# If running in a Windows environment this must be set to the same as your
|
||||
# system time zone.
|
||||
TIME_ZONE = 'Europe/Oslo'
|
||||
|
||||
# Language code for this installation. All choices can be found here:
|
||||
# http://www.i18nguy.com/unicode/language-identifiers.html
|
||||
LANGUAGE_CODE = 'en-us'
|
||||
|
||||
SITE_ID = 1
|
||||
|
||||
# If you set this to False, Django will make some optimizations so as not
|
||||
# to load the internationalization machinery.
|
||||
USE_I18N = True
|
||||
|
||||
# If you set this to False, Django will not format dates, numbers and
|
||||
# calendars according to the current locale
|
||||
USE_L10N = True
|
||||
|
||||
# Absolute path to the directory that holds media.
|
||||
# Example: "/home/media/media.lawrence.com/"
|
||||
MEDIA_ROOT = ''
|
||||
|
||||
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
|
||||
# trailing slash if there is a path component (optional in other cases).
|
||||
# Examples: "http://media.lawrence.com", "http://example.com/media/"
|
||||
MEDIA_URL = '/static/'
|
||||
|
||||
# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
|
||||
# trailing slash.
|
||||
# Examples: "http://foo.com/media/", "/media/".
|
||||
ADMIN_MEDIA_PREFIX = '/media/'
|
||||
|
||||
# Make this unique, and don't share it with anybody.
|
||||
SECRET_KEY = 'secretkey'
|
||||
|
||||
# List of callables that know how to import templates from various sources.
|
||||
TEMPLATE_LOADERS = (
|
||||
'django.template.loaders.filesystem.Loader',
|
||||
'django.template.loaders.app_directories.Loader',
|
||||
# 'django.template.loaders.eggs.Loader',
|
||||
)
|
||||
|
||||
MIDDLEWARE_CLASSES = (
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
)
|
||||
|
||||
ROOT_URLCONF = 'oliver_screen.urls'
|
||||
|
||||
TEMPLATE_DIRS = (
|
||||
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
|
||||
# Always use forward slashes, even on Windows.
|
||||
# Don't forget to use absolute paths, not relative paths.
|
||||
map_path('templates')
|
||||
)
|
||||
|
||||
INSTALLED_APPS = (
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.sites',
|
||||
'django.contrib.messages',
|
||||
# Uncomment the next line to enable the admin:
|
||||
'django.contrib.admin',
|
||||
# Uncomment the next line to enable admin documentation:
|
||||
# 'django.contrib.admindocs',
|
||||
'oliver_screen.tracks',
|
||||
'oliver_screen.main',
|
||||
)
|
||||
LASTFM_API_KEY = ''
|
||||
LASTFM_API_SECRET = ''
|
||||
@@ -1,27 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
||||
{% load staticfiles %}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Current track</title>
|
||||
<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}screen.css" />
|
||||
<script type="text/javascript" src="{{ MEDIA_URL }}jquery-1.6.1.min.js"></script>
|
||||
<script type="text/javascript" src="{{ MEDIA_URL }}jquery.timers-1.2.js"></script>
|
||||
<script type="text/javascript" src="{{ MEDIA_URL }}falling-pieces.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="{% static 'screen.css' %}" />
|
||||
<script type="text/javascript" src="{% static 'jquery-1.6.1.min.js' %}"></script>
|
||||
<script type="text/javascript" src="{% static 'jquery.timers-1.2.js' %}"></script>
|
||||
<script type="text/javascript" src="{% static 'falling-pieces.js' %}"></script>
|
||||
<script type="text/javascript">
|
||||
/* Update track and now playing */
|
||||
var get_last_track = function() {
|
||||
$( '#last_track' ).load(
|
||||
'{% url tracks.views.get_last_track %}');
|
||||
$( '#last_track' ).load('{% url 'last-track' %}');
|
||||
};
|
||||
var get_now_playing = function() {
|
||||
$( '#now_playing' ).load(
|
||||
'{% url tracks.views.get_now_playing %}', function() {
|
||||
if( is_tetris_song() ) {
|
||||
play_tetris();
|
||||
} else {
|
||||
dont_play_tetris();
|
||||
}
|
||||
});
|
||||
$( '#now_playing' ).load('{% url 'now-playing' %}', function() {
|
||||
if( is_tetris_song() ) {
|
||||
play_tetris();
|
||||
} else {
|
||||
dont_play_tetris();
|
||||
}
|
||||
});
|
||||
};
|
||||
/* Initial update */
|
||||
$( document ).ready( get_last_track );
|
||||
@@ -31,15 +29,17 @@
|
||||
$( document ).everyTime('10s', "now_playing", get_now_playing );
|
||||
|
||||
/* Ajax spinner */
|
||||
$( document ).ajaxStart( function() {
|
||||
$( '#spinner' ).show();
|
||||
}).ajaxStop( function() {
|
||||
$( document )
|
||||
.ajaxStart(function() {
|
||||
$( '#spinner' ).show();
|
||||
})
|
||||
.ajaxStop( function() {
|
||||
$( '#spinner' ).hide();
|
||||
});
|
||||
});
|
||||
|
||||
/* Loads the YouTube IFrame Player API code asynchronously. */
|
||||
var tag = document.createElement('script');
|
||||
tag.src = "http://www.youtube.com/player_api";
|
||||
tag.src = "https://www.youtube.com/player_api";
|
||||
var firstScriptTag = document.getElementsByTagName('script')[0];
|
||||
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="spinner"><img src="{{ MEDIA_URL }}spinner.gif"/></div>
|
||||
<div id="spinner"><img src="{% static 'spinner.gif' %}"/></div>
|
||||
<div id="container">
|
||||
<div id="content">
|
||||
<div id="player"></div>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
{% load staticfiles %}
|
||||
{% if now_playing %}
|
||||
{% if now_playing.video %}
|
||||
<script type="text/javascript">
|
||||
@@ -27,11 +28,11 @@
|
||||
<img src="{{ now_playing.image}}" class="now_playing" /><br />
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<img src="{{ MEDIA_URL}}spectrum-analyzer.gif" /> {{ now_playing.artist}} - {{ now_playing.title }} ♪♫<br />
|
||||
<img src="{% static 'spectrum-analyzer.gif' %}" /> {{ now_playing.artist}} - {{ now_playing.title }} ♪♫<br />
|
||||
{% else %}
|
||||
<script type="text/javascript">
|
||||
$("#player").delay(1000).hide();
|
||||
</script>
|
||||
<img src="{{ MEDIA_URL}}no_music_makes_me_sick_by_sakgaa.jpg" /><br />
|
||||
<img src="{% static 'no_music_makes_me_sick_by_sakgaa.jpg' %}" /><br />
|
||||
:[
|
||||
{% endif %}
|
||||
@@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
@@ -1,15 +0,0 @@
|
||||
from oliver_screen.tracks.models import LastFMUser, YouTubeVideo
|
||||
from django.contrib import admin
|
||||
|
||||
class LastFMAdmin(admin.ModelAdmin):
|
||||
fieldsets = [
|
||||
(None, {'fields': ['name','active']})
|
||||
]
|
||||
|
||||
class VideoAdmin(admin.ModelAdmin):
|
||||
fieldsets = [
|
||||
(None, {'fields': ['artist', 'title', 'videoId', 'start', 'active']})
|
||||
]
|
||||
|
||||
admin.site.register(LastFMUser, LastFMAdmin)
|
||||
admin.site.register(YouTubeVideo, VideoAdmin)
|
||||
@@ -1,23 +0,0 @@
|
||||
"""
|
||||
This file demonstrates two different styles of tests (one doctest and one
|
||||
unittest). These will both pass when you run "manage.py test".
|
||||
|
||||
Replace these with more appropriate tests for your application.
|
||||
"""
|
||||
|
||||
from django.test import TestCase
|
||||
|
||||
class SimpleTest(TestCase):
|
||||
def test_basic_addition(self):
|
||||
"""
|
||||
Tests that 1 + 1 always equals 2.
|
||||
"""
|
||||
self.failUnlessEqual(1 + 1, 2)
|
||||
|
||||
__test__ = {"doctest": """
|
||||
Another way to test that 1 + 1 is equal to 2.
|
||||
|
||||
>>> 1 + 1 == 2
|
||||
True
|
||||
"""}
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
from django.conf.urls.defaults import *
|
||||
urlpatterns = patterns('oliver_screen.tracks.views',
|
||||
(r'^last/$', 'get_last_track'),
|
||||
(r'^now_playing/$', 'get_now_playing'),
|
||||
)
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
from django.http import HttpResponse
|
||||
from django.shortcuts import render_to_response, get_object_or_404
|
||||
from django.template import RequestContext
|
||||
|
||||
from oliver_screen.tracks.models import LastFMUser, YouTubeVideo, CurrentTrack
|
||||
|
||||
import pylast
|
||||
from datetime import datetime
|
||||
from oliver_screen import settings
|
||||
|
||||
network = pylast.LastFMNetwork(api_key = settings.LASTFM_API_KEY, api_secret = settings.LASTFM_API_SECRET)
|
||||
|
||||
def get_lastfmuser():
|
||||
lastfmusers = LastFMUser.objects.filter(active=True)
|
||||
if len(lastfmusers) != 1:
|
||||
# default
|
||||
return network.get_user('kakdns')
|
||||
|
||||
return network.get_user(lastfmusers[0].name)
|
||||
|
||||
def get_youtubevideo(artist, title):
|
||||
videos = YouTubeVideo.objects.filter(artist=artist, title=title)
|
||||
if len(videos) != 1:
|
||||
# should only be one
|
||||
return ""
|
||||
return videos[0]
|
||||
|
||||
|
||||
|
||||
# My views
|
||||
def get_last_track(request):
|
||||
user = get_lastfmuser()
|
||||
playedtracks = user.get_recent_tracks(limit=2)
|
||||
playback_date = datetime.strptime(playedtracks[0].playback_date, "%d %b %Y, %H:%M")
|
||||
played = {'artist': playedtracks[0].track.get_artist().get_name(),
|
||||
'title': playedtracks[0].track.get_title(),
|
||||
'playback_date': playback_date,
|
||||
# provide utcnow since lastfm servers are UTC
|
||||
'utcnow': datetime.utcnow()
|
||||
}
|
||||
return render_to_response("public/tracks.html", {'played':played});
|
||||
|
||||
def get_now_playing(request):
|
||||
user = get_lastfmuser()
|
||||
track = user.get_now_playing()
|
||||
now_playing = []
|
||||
if not track is None:
|
||||
artist = track.get_artist()
|
||||
video = get_youtubevideo(artist.get_name(), track.get_title())
|
||||
image = artist.get_cover_image(size=4)
|
||||
|
||||
if "The Shins" in artist.get_name():
|
||||
image = 'http://nikolark.at.neuf.no/the_shins.jpg'
|
||||
|
||||
now_playing = {
|
||||
'artist': artist.get_name(),
|
||||
'title': track.get_title(),
|
||||
'image': image,
|
||||
'video': video
|
||||
}
|
||||
cache_current(now_playing)
|
||||
else:
|
||||
# No response from LastFM db?
|
||||
now_playing = get_current_from_cache()
|
||||
|
||||
return render_to_response("public/now_playing.html", {'now_playing':now_playing}, context_instance=RequestContext(request));
|
||||
|
||||
def cache_current(now_playing):
|
||||
# Fetch the one CurrentTrack entry in the db and update it with the current track.
|
||||
current = []
|
||||
try:
|
||||
current = CurrentTrack.objects.get(pk=1)
|
||||
except:
|
||||
#update
|
||||
current = CurrentTrack(artist="", title="", image="", retries=0)
|
||||
current.artist = now_playing['artist']
|
||||
current.title = now_playing['title']
|
||||
current.image = now_playing['image']
|
||||
current.retries = 0
|
||||
current.save()
|
||||
|
||||
def get_current_from_cache():
|
||||
current = []
|
||||
try:
|
||||
current = CurrentTrack.objects.get(pk=1)
|
||||
except:
|
||||
current = CurrentTrack(artist="", title="", image="", retries=0)
|
||||
current.save()
|
||||
|
||||
now_playing = {}
|
||||
|
||||
# try 3 times before clearing the cache
|
||||
if current.artist != "" and current.retries < 3:
|
||||
now_playing = {
|
||||
'artist': current.artist,
|
||||
'title': current.title,
|
||||
'image': current.image
|
||||
}
|
||||
|
||||
current.retries = current.retries + 1
|
||||
current.save()
|
||||
else:
|
||||
current.artist = ""
|
||||
current.title = ""
|
||||
current.image = ""
|
||||
current.save()
|
||||
|
||||
return now_playing
|
||||
|
||||
# Mock views
|
||||
def dummy_get_last_track(request):
|
||||
played = {'artist': 'The Album Leaf', 'title': 'Another Day (Revised)'}
|
||||
|
||||
return render_to_response("public/tracks.html", {'played':played});
|
||||
|
||||
def dummy_now_playing(request):
|
||||
now_playing = { 'artist':'The Album Leaf', 'title': 'Over The Pond', 'image': 'http://userserve-ak.last.fm/serve/_/2857325/The+Album+Leaf+1155442304.jpg'}
|
||||
|
||||
return render_to_response("public/now_playing.html", {'now_playing':now_playing});
|
||||
+6
-18
@@ -1,19 +1,7 @@
|
||||
from django.conf.urls.defaults import *
|
||||
from django.conf.urls import patterns, url
|
||||
|
||||
# Uncomment the next two lines to enable the admin:
|
||||
from django.contrib import admin
|
||||
admin.autodiscover()
|
||||
from os.path import dirname, join
|
||||
|
||||
def map_path(target_name):
|
||||
'''Enables path names to be decided at runtime.'''
|
||||
return join(dirname(__file__), target_name).replace('\\', '/')
|
||||
|
||||
urlpatterns = patterns('',
|
||||
# static file serving for development (http://docs.djangoproject.com/en/dev/howto/static-files/)
|
||||
(r'^static/(?P<path>.*)$', 'django.views.static.serve',
|
||||
{'document_root': map_path('static')}),
|
||||
(r'^admin/', include(admin.site.urls)),
|
||||
(r'^tracks/', include('oliver_screen.tracks.urls')),
|
||||
(r'^$', include('oliver_screen.main.urls')),
|
||||
)
|
||||
urlpatterns = patterns(
|
||||
'oliver_screen.views',
|
||||
url(r'^last/$', 'get_last_track', name='last-track'),
|
||||
url(r'^now_playing/$', 'get_now_playing', name='now-playing'),
|
||||
)
|
||||
@@ -0,0 +1,66 @@
|
||||
import pylast
|
||||
from django.conf import settings
|
||||
|
||||
from oliver_screen.models import CurrentTrack, LastFMUser, YouTubeVideo
|
||||
|
||||
|
||||
def get_lastfmuser():
|
||||
network = pylast.LastFMNetwork(api_key=settings.LASTFM_API_KEY, api_secret=settings.LASTFM_API_SECRET)
|
||||
lastfmusers = LastFMUser.objects.filter(active=True)
|
||||
if len(lastfmusers) != 1:
|
||||
# default
|
||||
return network.get_user(settings.LASTFM_DEFAULT_USERNAME)
|
||||
|
||||
return network.get_user(lastfmusers[0].name)
|
||||
|
||||
|
||||
def get_youtubevideo(artist, title):
|
||||
videos = YouTubeVideo.objects.filter(artist=artist, title=title)
|
||||
if len(videos) != 1:
|
||||
# should only be one
|
||||
return ""
|
||||
|
||||
return videos[0]
|
||||
|
||||
|
||||
def cache_current(now_playing):
|
||||
# Fetch the one CurrentTrack entry in the db and update it with the current track.
|
||||
try:
|
||||
current = CurrentTrack.objects.get(pk=1)
|
||||
except:
|
||||
# update
|
||||
current = CurrentTrack(artist="", title="", image="", retries=0)
|
||||
|
||||
current.artist = now_playing['artist']
|
||||
current.title = now_playing['title']
|
||||
current.image = now_playing['image']
|
||||
current.retries = 0
|
||||
current.save()
|
||||
|
||||
|
||||
def get_current_from_cache():
|
||||
try:
|
||||
current = CurrentTrack.objects.get(pk=1)
|
||||
except:
|
||||
current = CurrentTrack(artist="", title="", image="", retries=0)
|
||||
current.save()
|
||||
|
||||
now_playing = {}
|
||||
|
||||
# try 3 times before clearing the cache
|
||||
if current.artist != "" and current.retries < 3:
|
||||
now_playing = {
|
||||
'artist': current.artist,
|
||||
'title': current.title,
|
||||
'image': current.image
|
||||
}
|
||||
|
||||
current.retries += 1
|
||||
current.save()
|
||||
else:
|
||||
current.artist = ""
|
||||
current.title = ""
|
||||
current.image = ""
|
||||
current.save()
|
||||
|
||||
return now_playing
|
||||
@@ -0,0 +1,63 @@
|
||||
from datetime import datetime
|
||||
from django.shortcuts import render
|
||||
|
||||
from oliver_screen import utils
|
||||
|
||||
|
||||
def index(request):
|
||||
return render(request, 'public/index.html')
|
||||
|
||||
|
||||
def get_last_track(request):
|
||||
user = utils.get_lastfmuser()
|
||||
playedtracks = user.get_recent_tracks(limit=2)
|
||||
playback_date = datetime.strptime(playedtracks[0].playback_date, "%d %b %Y, %H:%M")
|
||||
played = {
|
||||
'artist': playedtracks[0].track.get_artist().get_name(),
|
||||
'title': playedtracks[0].track.get_title(),
|
||||
'playback_date': playback_date,
|
||||
'utcnow': datetime.utcnow() # provide utcnow since lastfm servers are UTC
|
||||
}
|
||||
return render(request, "public/tracks.html", {'played': played})
|
||||
|
||||
|
||||
def get_now_playing(request):
|
||||
user = utils.get_lastfmuser()
|
||||
track = user.get_now_playing()
|
||||
if track is not None:
|
||||
artist = track.get_artist()
|
||||
video = utils.get_youtubevideo(artist.get_name(), track.get_title())
|
||||
image = artist.get_cover_image(size=4)
|
||||
|
||||
if "The Shins" in artist.get_name():
|
||||
image = 'http://nikolark.at.neuf.no/the_shins.jpg'
|
||||
|
||||
now_playing = {
|
||||
'artist': artist.get_name(),
|
||||
'title': track.get_title(),
|
||||
'image': image,
|
||||
'video': video
|
||||
}
|
||||
utils.cache_current(now_playing)
|
||||
else:
|
||||
# No response from LastFM db?
|
||||
now_playing = utils.get_current_from_cache()
|
||||
|
||||
return render(request, "public/now_playing.html", {'now_playing': now_playing})
|
||||
|
||||
|
||||
# Mock views
|
||||
def dummy_get_last_track(request):
|
||||
played = {'artist': 'The Album Leaf', 'title': 'Another Day (Revised)'}
|
||||
|
||||
return render(request, "public/tracks.html", {'played': played})
|
||||
|
||||
|
||||
def dummy_now_playing(request):
|
||||
now_playing = {
|
||||
'artist': 'The Album Leaf',
|
||||
'title': 'Over The Pond',
|
||||
'image': 'http://userserve-ak.last.fm/serve/_/2857325/The+Album+Leaf+1155442304.jpg'
|
||||
}
|
||||
|
||||
return render(request, "public/now_playing.html", {'now_playing': now_playing})
|
||||
File renamed without changes.
@@ -0,0 +1,98 @@
|
||||
"""
|
||||
Django settings for oliversite project.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/1.7/topics/settings/
|
||||
|
||||
For the full list of settings and their values, see
|
||||
https://docs.djangoproject.com/en/1.7/ref/settings/
|
||||
"""
|
||||
|
||||
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
||||
import os
|
||||
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
|
||||
|
||||
|
||||
# Quick-start development settings - unsuitable for production
|
||||
# See https://docs.djangoproject.com/en/1.7/howto/deployment/checklist/
|
||||
|
||||
# SECURITY WARNING: keep the secret key used in production secret!
|
||||
SECRET_KEY = '#r65fsg)wsk&cs8m^i)@##7-wg=#z=*b_)a82#5z#4%&!j_9=6'
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = True
|
||||
|
||||
TEMPLATE_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',
|
||||
)
|
||||
|
||||
INSTALLED_APPS += (
|
||||
'oliver_screen',
|
||||
)
|
||||
|
||||
MIDDLEWARE_CLASSES = (
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||
)
|
||||
|
||||
ROOT_URLCONF = 'oliversite.urls'
|
||||
|
||||
WSGI_APPLICATION = 'oliversite.wsgi.application'
|
||||
|
||||
|
||||
# Database
|
||||
# https://docs.djangoproject.com/en/1.7/ref/settings/#databases
|
||||
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3',
|
||||
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
|
||||
}
|
||||
}
|
||||
|
||||
# Internationalization
|
||||
# https://docs.djangoproject.com/en/1.7/topics/i18n/
|
||||
|
||||
LANGUAGE_CODE = 'en-us'
|
||||
|
||||
TIME_ZONE = 'Europe/Oslo'
|
||||
|
||||
USE_I18N = True
|
||||
|
||||
USE_L10N = True
|
||||
|
||||
USE_TZ = True
|
||||
|
||||
|
||||
# Static files (CSS, JavaScript, Images)
|
||||
# https://docs.djangoproject.com/en/1.7/howto/static-files/
|
||||
|
||||
STATIC_URL = '/static/'
|
||||
|
||||
LASTFM_DEFAULT_USERNAME = 'kakdns'
|
||||
# Get these from http://www.last.fm/api/account
|
||||
LASTFM_API_KEY = ''
|
||||
LASTFM_API_SECRET = ''
|
||||
|
||||
# Local settings
|
||||
try:
|
||||
from local_settings import *
|
||||
except ImportError:
|
||||
pass
|
||||
@@ -0,0 +1,9 @@
|
||||
from django.conf.urls import patterns, include, url
|
||||
from django.contrib import admin
|
||||
|
||||
urlpatterns = patterns(
|
||||
'',
|
||||
url(r'^$', 'oliver_screen.views.index', name='index'),
|
||||
url(r'', include('oliver_screen.urls')),
|
||||
url(r'^admin/', include(admin.site.urls)),
|
||||
)
|
||||
@@ -0,0 +1,14 @@
|
||||
"""
|
||||
WSGI config for oliversite 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.7/howto/deployment/wsgi/
|
||||
"""
|
||||
|
||||
import os
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "oliversite.settings")
|
||||
|
||||
from django.core.wsgi import get_wsgi_application
|
||||
application = get_wsgi_application()
|
||||
@@ -0,0 +1,3 @@
|
||||
Django==1.7.4
|
||||
pylast==1.1.0
|
||||
|
||||
Reference in new issue
Block a user