We are no longer offering accounts on this server. Consider https://gitlab.freedesktop.org/ as a place to host projects.

Commit d3e57c4d authored by mattl's avatar mattl

move experimental

parent 316f05de
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Libre.fm &mdash; discover new music</title>
<link rel="stylesheet" href="http://yui.yahooapis.com/2.7.0/build/reset-fonts-grids/reset-fonts-grids.css" type="text/css">
<link rel="stylesheet" href="http://yui.yahooapis.com/2.7.0/build/base/base.css" type="text/css">
<link rel="stylesheet" href="librefm.css" type="text/css">
</head>
<body>
<div id="doc2" class="yui-t7">
<div id="hd" role="navigation"><h1><a href="/">Header</a></h1>
<ul>
<li><a href="#">Code</a></li>
<li><a href="#">Blog</a></li>
<li><a href="#">Wiki</a></li>
<li><a href="#">List</a></li>
<li><a href="#">Bugs</a></li>
<li id="login"><a href="#">Log in</a></li>
</ul>
</div>
<div id="bd" role="main">
<div id="coolio">
<div class="yui-g" id="banner">
<img src="/i/topblock.png" alt="" />
</div>
<div class="yui-gc">
<div class="yui-u first" id="content">
<div style="padding: 10px;">
<h2>We're building a free network service that will let you share and discover new music.</h2>
<p>Libre.fm is a project to help you keep track of what music
you like and share that, with your friends, discover new music,
and meet new people who share your taste in music.</p>
<ul>
<li>Complete public source code licensed under the GNU AGPL!</li>
<li>You own your own data!</li>
<li>Use our service, or run your own!</li>
<li>Get started and hacking today!</li>
</ul>
<h2>We're still in the alpha stages of the project, but many users and developers are actively using Libre.fm to share their listening habits.</h2>
<ul>
<li><a href="http://turtle.libre.fm/">See what people are listening to</a></li>
<li><a href="https://savannah.nongnu.org/my/groups.php?words=libre.fm#searchgroup">Join the project at Savannah</a></li>
<li><a href="">Browse our source code</a> or <a href="https://savannah.nongnu.org/svn/?group=librefm">check out a copy for yourself</a></li>
<li><a href="http://ideas.libre.fm/">Add your ideas to our ideas wiki</a></li>
<li><a href="http://lists.autonomo.us/mailman/listinfo/libre-fm">Join our mailing list</a> or just <a href="http://lists.autonomo.us/pipermail/libre-fm/">browse the archives</a></li>
</ul>
</div></div>
<div class="yui-u" id="sidebar">
<div style="padding: 10px;">
<h3>Explore popular artists</h3>
<ul class="tagcloud">
<li class="tc t1"><a href="#">They Might Be Giants</a></li>
<li class="tc t3"><a href="#">John Lennon</a></li>
<li class="tc t1"><a href="#">Half Man Half Biscuit</a></li>
<li class="tc t3"><a href="#">Explosions in the sky</a></li>
<li class="tc t1"><a href="#">Belle and Sebastian</a></li>
<li class="tc t2"><a href="#">nine inch nails</a></li>
<li class="tc t5"><a href="#">Pulp</a></li>
<li class="tc t1"><a href="#">Radiohead</a></li>
<li class="tc t6"><a href="#">Tom Lehrer</a></li>
<li class="tc t2"><a href="#">The Beatles</a></li>
<li class="tc t3"><a href="#">Dead Kennedys</a></li>
<li class="tc t4"><a href="#">Bishop Allen</a></li>
<li class="tc t2"><a href="#">The Orb</a></li>
<li class="tc t3"><a href="#">gorillaz</a></li>
<li class="tc t4"><a href="#">Carbon Based Lifeforms</a></li>
<li class="tc t5"><a href="#">Laura Cantrell</a></li>
<li class="tc t6"><a href="#">Jem</a></li>
<li class="tc t1"><a href="#">Solar Fields</a></li>
<li class="tc t4"><a href="#">billy talent</a></li>
<li class="tc t3"><a href="#">Blur</a></li>
</ul>
</div></div>
</div></div>
<div class="yui-g" id="artists">
<strong><a href="/contact/">Talk to us</a></strong> if you're in a band, represent a
label or music service, we'd like to talk ideas and
possibilities. While our intention is eventually provide download
and streaming services for freely-licensed music, we are also
interested in linking all bands to respectable DRM-free music
services.
</div>
<div class="yui-g">
<div class="yui-u first" id="links">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sit amet metus. Nunc quam elit, posuere nec, auctor in, rhoncus quis, dui. Aliquam erat volutpat. Ut dignissim, massa sit amet dignissim cursus, quam lacus feugiat. </div>
<div class="yui-u" id="moarlinks">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sit amet metus. Nunc quam elit, posuere nec, auctor in, rhoncus quis, dui. Aliquam erat volutpat. Ut dignissim, massa sit amet dignissim cursus, quam lacus feugiat. </div>
</div>
</div>
<div id="ft" role="navigation">
<ul>
<li class="copy">&copy; 2009 Libre.fm Project</li>
<li><a href="/contributors/">Contributors</a></li>
<li><a href="/licensing/">Licensing information</a></li>
<li><a href="/developer/">Developers</a></li>
<li><a href="/api/">API</a></li>
<li><a href="/download/">Download</a></li>
</ul>
<p><img src="/i/cc-by-sa.png" alt="Attribution-ShareAlike 3.0" /></p>
</div>
</div>
</body>
</html>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="120"
height="42"
id="svg2759"
sodipodi:version="0.32"
inkscape:version="0.46"
version="1.0"
sodipodi:docname="by-sa.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<defs
id="defs2761">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 21 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="120 : 21 : 1"
inkscape:persp3d-origin="60 : 14 : 1"
id="perspective2560" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#8b8b8b"
borderopacity="1"
gridtolerance="10000"
guidetolerance="10"
objecttolerance="10"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="-21"
inkscape:cy="89.569904"
inkscape:document-units="px"
inkscape:current-layer="layer1"
width="120px"
height="42px"
inkscape:showpageshadow="false"
inkscape:window-width="1198"
inkscape:window-height="687"
inkscape:window-x="474"
inkscape:window-y="309"
showgrid="false" />
<metadata
id="metadata2764">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<g
id="g2585"
transform="matrix(1.1920966,0,0,1.1920966,-16.663843,3.1216691)"
style="opacity:0.3">
<g
id="g5908_2_"
transform="matrix(0.644019,0,0,0.6439464,-73.580401,50.851808)">
<path
id="path5906_2_"
cx="296.35416"
ry="22.939548"
cy="264.3577"
type="arc"
rx="22.939548"
d="M 187.20944,-55.6792 C 187.21502,-46.99896 180.18158,-39.95825 171.50134,-39.95212 C 162.82113,-39.94708 155.77929,-46.97998 155.77426,-55.66016 C 155.77426,-55.66687 155.77426,-55.67249 155.77426,-55.6792 C 155.76922,-64.36054 162.80209,-71.40125 171.48233,-71.40631 C 180.16367,-71.41193 187.20441,-64.37842 187.20944,-55.69824 C 187.20944,-55.69263 187.20944,-55.68591 187.20944,-55.6792 z"
style="fill:#ffffff" />
<g
id="g5706_2_"
transform="translate(-289.616,99.0653)">
<path
id="path5708_2_"
d="M 473.88455,-167.54724 C 477.36996,-164.06128 479.11294,-159.79333 479.11294,-154.74451 C 479.11294,-149.69513 477.40014,-145.47303 473.9746,-142.07715 C 470.33929,-138.50055 466.04281,-136.71283 461.08513,-136.71283 C 456.18736,-136.71283 451.96526,-138.48544 448.42003,-142.03238 C 444.87419,-145.57819 443.10158,-149.81537 443.10158,-154.74451 C 443.10158,-159.6731 444.87419,-163.94049 448.42003,-167.54724 C 451.87523,-171.03375 456.09728,-172.77618 461.08513,-172.77618 C 466.13342,-172.77618 470.39914,-171.03375 473.88455,-167.54724 z M 450.76657,-165.20239 C 447.81982,-162.22601 446.34701,-158.7395 446.34701,-154.74005 C 446.34701,-150.7417 447.80529,-147.28485 450.72125,-144.36938 C 453.63778,-141.45288 457.10974,-139.99462 461.1383,-139.99462 C 465.16683,-139.99462 468.66848,-141.46743 471.64486,-144.41363 C 474.47076,-147.14947 475.88427,-150.59069 475.88427,-154.74005 C 475.88427,-158.85809 474.44781,-162.35297 471.57659,-165.22479 C 468.70595,-168.09546 465.22671,-169.53131 461.1383,-169.53131 C 457.04993,-169.53131 453.59192,-168.08813 450.76657,-165.20239 z M 458.52106,-156.49927 C 458.07074,-157.4809 457.39673,-157.9715 456.49781,-157.9715 C 454.90867,-157.9715 454.11439,-156.90198 454.11439,-154.763 C 454.11439,-152.62341 454.90867,-151.55389 456.49781,-151.55389 C 457.54719,-151.55389 458.29676,-152.07519 458.74647,-153.11901 L 460.94923,-151.94598 C 459.8993,-150.0805 458.32417,-149.14697 456.22374,-149.14697 C 454.60384,-149.14697 453.30611,-149.64367 452.33168,-150.63653 C 451.35561,-151.62994 450.86894,-152.99926 450.86894,-154.7445 C 450.86894,-156.46008 451.37123,-157.82159 452.37642,-158.83013 C 453.38161,-159.83806 454.63347,-160.34264 456.13423,-160.34264 C 458.35435,-160.34264 459.94407,-159.46776 460.90504,-157.71978 L 458.52106,-156.49927 z M 468.8844,-156.49927 C 468.43353,-157.4809 467.77292,-157.9715 466.90201,-157.9715 C 465.28095,-157.9715 464.46988,-156.90198 464.46988,-154.763 C 464.46988,-152.62341 465.28095,-151.55389 466.90201,-151.55389 C 467.95304,-151.55389 468.68918,-152.07519 469.10925,-153.11901 L 471.36126,-151.94598 C 470.31301,-150.0805 468.74007,-149.14697 466.64358,-149.14697 C 465.02587,-149.14697 463.73095,-149.64367 462.75711,-150.63653 C 461.78494,-151.62994 461.29773,-152.99926 461.29773,-154.7445 C 461.29773,-156.46008 461.79221,-157.82159 462.78061,-158.83013 C 463.76843,-159.83806 465.02588,-160.34264 466.55408,-160.34264 C 468.77027,-160.34264 470.35776,-159.46776 471.3154,-157.71978 L 468.8844,-156.49927 z" />
</g>
</g>
<g
id="g6316_1_"
transform="matrix(0.6211082,0,0,0.6210382,211.10195,101.39304)">
<path
id="path6318_1_"
cx="475.97119"
ry="29.209877"
cy="252.08646"
type="arc"
rx="29.209877"
d="M -175.0083,-139.1153 C -175.00204,-129.7035 -182.62555,-122.06751 -192.03812,-122.06049 C -201.44913,-122.05341 -209.08512,-129.67774 -209.09293,-139.09028 C -209.09293,-139.09809 -209.09293,-139.10749 -209.09293,-139.1153 C -209.09919,-148.52784 -201.47413,-156.1623 -192.06311,-156.17011 C -182.65054,-156.17713 -175.01456,-148.55207 -175.0083,-139.14026 C -175.0083,-139.13092 -175.0083,-139.1239 -175.0083,-139.1153 z"
style="fill:#ffffff" />
<g
id="g6320_1_"
transform="translate(-23.9521,-89.7296)">
<path
id="path6322_1_"
d="M -168.2204,-68.05536 C -173.39234,-68.05536 -177.76892,-66.25067 -181.35175,-62.64203 C -185.02836,-58.90759 -186.86588,-54.48883 -186.86588,-49.38568 C -186.86588,-44.28253 -185.02836,-39.89416 -181.35175,-36.22308 C -177.67673,-32.55114 -173.29859,-30.71521 -168.2204,-30.71521 C -163.07974,-30.71521 -158.62503,-32.56677 -154.85312,-36.26996 C -151.30307,-39.78558 -149.52652,-44.15827 -149.52652,-49.38568 C -149.52652,-54.6123 -151.33432,-59.03265 -154.94843,-62.64203 C -158.5625,-66.25067 -162.98599,-68.05536 -168.2204,-68.05536 z M -168.17352,-64.69519 C -163.936,-64.69519 -160.33752,-63.20221 -157.37655,-60.21466 C -154.38748,-57.25836 -152.89214,-53.64899 -152.89214,-49.38568 C -152.89214,-45.09186 -154.35466,-41.52856 -157.28438,-38.69653 C -160.36876,-35.64727 -163.99849,-34.12304 -168.17351,-34.12304 C -172.34856,-34.12304 -175.94701,-35.63244 -178.96892,-38.64965 C -181.9908,-41.66918 -183.50176,-45.24657 -183.50176,-49.38567 C -183.50176,-53.52398 -181.97518,-57.13414 -178.92205,-60.21465 C -175.9939,-63.20221 -172.41107,-64.69519 -168.17352,-64.69519 z" />
<path
id="path6324_1_"
d="M -176.49548,-52.02087 C -175.75171,-56.71856 -172.44387,-59.22949 -168.30008,-59.22949 C -162.33911,-59.22949 -158.70783,-54.90448 -158.70783,-49.1372 C -158.70783,-43.50982 -162.57194,-39.13793 -168.39383,-39.13793 C -172.39856,-39.13793 -175.98297,-41.60277 -176.63611,-46.43877 L -171.93292,-46.43877 C -171.7923,-43.92778 -170.1626,-43.04418 -167.83447,-43.04418 C -165.1813,-43.04418 -163.4563,-45.50908 -163.4563,-49.27709 C -163.4563,-53.22942 -164.94693,-55.32244 -167.74228,-55.32244 C -169.79074,-55.32244 -171.55948,-54.57787 -171.93292,-52.02087 L -170.56418,-52.02789 L -174.26734,-48.32629 L -177.96894,-52.02789 L -176.49548,-52.02087 z" />
</g>
</g>
<g
transform="matrix(0.993781,0,0,0.993669,-176.73095,-74.419724)"
id="g313">
<circle
cx="242.56226"
cy="90.224609"
r="10.8064"
id="circle315"
sodipodi:cx="242.56226"
sodipodi:cy="90.224609"
sodipodi:rx="10.8064"
sodipodi:ry="10.8064"
style="fill:#ffffff" />
<g
id="g317">
<path
d="M 245.68994,87.09766 C 245.68994,86.68116 245.35205,86.34424 244.93603,86.34424 L 240.16357,86.34424 C 239.74755,86.34424 239.40966,86.68115 239.40966,87.09766 L 239.40966,91.87061 L 240.74071,91.87061 L 240.74071,97.52295 L 244.3579,97.52295 L 244.3579,91.87061 L 245.68993,91.87061 L 245.68993,87.09766 L 245.68994,87.09766 z"
id="path319" />
<circle
cx="242.5498"
cy="84.083008"
r="1.63232"
id="circle321"
sodipodi:cx="242.5498"
sodipodi:cy="84.083008"
sodipodi:rx="1.63232"
sodipodi:ry="1.63232" />
</g>
<path
clip-rule="evenodd"
d="M 242.53467,78.31836 C 239.30322,78.31836 236.56641,79.4458 234.32715,81.70215 C 232.0293,84.03516 230.88086,86.79736 230.88086,89.98633 C 230.88086,93.1753 232.0293,95.91846 234.32715,98.21338 C 236.625,100.50781 239.36133,101.65527 242.53467,101.65527 C 245.74756,101.65527 248.53272,100.49853 250.88819,98.18359 C 253.10889,95.98681 254.21827,93.2539 254.21827,89.98632 C 254.21827,86.71874 253.08936,83.95751 250.83057,81.70214 C 248.57178,79.4458 245.80615,78.31836 242.53467,78.31836 z M 242.56396,80.41797 C 245.2124,80.41797 247.46142,81.35156 249.31103,83.21875 C 251.18115,85.06592 252.11572,87.32227 252.11572,89.98633 C 252.11572,92.66992 251.20068,94.89746 249.36963,96.66699 C 247.4419,98.57275 245.17334,99.52539 242.56397,99.52539 C 239.9546,99.52539 237.70557,98.58252 235.81739,96.6958 C 233.92774,94.80957 232.98389,92.57324 232.98389,89.98633 C 232.98389,87.3999 233.93799,85.14404 235.84619,83.21875 C 237.67676,81.35156 239.9165,80.41797 242.56396,80.41797 z"
id="path323"
style="fill-rule:evenodd" />
</g>
</g>
</g>
</svg>
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
html{background-color: #ececec;}
#coolio {background-color: white; padding: 15px;}
#hd {background-color: #980101; margin-top: -9px;}
#bd{padding: 5px;}
#hd {margin-bottom: 8px; height: 70px; position: relative;}
#hd ul{ margin: 0; padding: 0; line-height: 70px; position: absolute; top: 0; right: 20px;}
#hd li a{ color: white; text-decoration: none; }
#login a{ color: yellow !important; }
#hd li{ display: inline; font-size: 21px; text-transform: lowercase; font-weight: bold; margin-right: 20px;}
#banner { height: 345px; position: relative;}
#banner img{ position: absolute; top: -12px; left: 0; }
#sidebar {background-color: #eee;}
#content { font-size: 140%; }
#artists{background-color: lightblue; margin: 15px 0 15px 0; padding: 5px;}
#links, #moarlinks, #ft{font-size: 85%;}
#ft{margin-top: 15px; height: 102px;position: relative;}
#ft p{ text-align: right;}
#ft li{ display: inline; margin-right: 0.5em; }
#ft li.copy { margin-right: 1em; }
#hd h1{ background: #980101 url(http://alpha.libre.fm/themes/librefm/images/header.png) no-repeat;
border: 0;
padding: 0;
}
#hd h1 a{
display: block;
text-decoration: none;
overflow: hidden;
border: 0;
margin: 0;
padding: 0;
padding-top: 70px;
height: 0px !important;
height /**/: 70px;
width: 418px;
cursor: pointer;
}
li{ line-height: 1.6em; }
.tagcloud { margin: 0; padding: 0; text-align: center; }
.tagcloud li{ display: inline; margin-right: 0.2em; line-height: 1.2em; }
.tagcloud .t1 { font-size: 200%; }
.tagcloud .t2 { font-size: 180%; }
.tagcloud .t3 { font-size: 160%; }
.tagcloud .t4 { font-size: 140%; }
.tagcloud .t5 { font-size: 120%; }
.tagcloud .t6 { font-size: 100%; }
a:hover { color: red !important; }
a:visited{ color: #07c;}
.highlight{ background-color: #ffb;}
\ No newline at end of file
* profiles (excluding recently gobbled tracks)
* registration/invitation
* include all information in libre.fm database schema in django.fm database schema
* allow libre.fm and django.fm to run from the same database
* now playing expiries
* client identification
# Libre.fm -- a free network service for sharing your music listening habits
#
# Copyright (C) 2009 Libre.fm Project
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import md5
from django.contrib import admin
from django.contrib.auth.models import get_hexdigest, User
from django.contrib.auth.admin import UserAdmin
from django.template.defaultfilters import slugify
from django.db import models
RATING_CHOICES = (
('L', 'Love'),
('B', 'Ban'),
('S', 'Skip')
)
SOURCE_CHOICES = (
('P', 'Chosen by the user'),
('R', 'Non-personalised broadcast'),
('E', 'Personalised recommendation except Last.fm'),
('L', 'Last.fm'),
('U', 'Unknown')
)
class GobblerUser(User):
def set_password(self, raw_password):
import random
algo = 'sha1'
salt = get_hexdigest(algo, str(random.random()), str(random.random()))[:5]
hsh = get_hexdigest(algo, salt, raw_password)
self.password = '%s$%s$%s' % (algo, salt, hsh)
pwd,created = Md5Password.objects.get_or_create(user=self)
pwd.password = md5.new(raw_password).hexdigest()
pwd.save()
def get_md5(self):
pwd = Md5Password.objects.get(user=self)
return pwd.password
class Meta:
proxy = True
admin.site.register(GobblerUser, UserAdmin)
class Artist(models.Model):
name = models.CharField(max_length=255, unique=True)
slug = models.SlugField(unique=True, editable=False)
def get_absolute_url(self):
return "/music/%s/" % (self.slug,)
def save(self, force_insert=False, force_update=False):
self.slug = slugify(self.name)
super(Artist, self).save(force_insert, force_update)
def __unicode__(self):
return self.name
class Album(models.Model):
name = models.CharField(max_length=256)
artist = models.ForeignKey(Artist)
slug = models.SlugField(editable=False)
def get_absolute_url(self):
return "%s%s/" % (self.artist.get_absolute_url(), self.slug)
def save(self, force_insert=False, force_update=False):
self.slug = slugify(self.name)
super(Album, self).save(force_insert, force_update)
def __unicode__(self):
return "%s by %s" % (self.name, self.artist)
class Meta:
unique_together = (('artist', 'name'), ('artist', 'slug'))
class Track(models.Model):
name = models.CharField(max_length=256)
track_number = models.PositiveSmallIntegerField(blank=True, null=True)
length = models.PositiveSmallIntegerField(null=True)
album = models.ForeignKey(Album, null=True)
mbid = models.CharField(max_length=256, blank=True)
slug = models.SlugField(editable=False)
def get_absolute_url(self):
return "%s%s/" % (self.album.get_absolute_url(), self.name)
def save(self, force_insert=False, force_update=False):
self.slug = slugify(self.name)
super(Track, self).save(force_insert, force_update)
def __unicode__(self):
return "%s - %s" % (self.album.artist, self.name)
class Meta:
unique_together = ('album', 'slug')
class Session(models.Model):
user = models.OneToOneField(GobblerUser, primary_key=True)
key = models.CharField(max_length=32)
class Md5Password(models.Model):
user = models.OneToOneField(GobblerUser, primary_key=True)
password = models.CharField(max_length=32)
class NowPlaying(models.Model):
user = models.OneToOneField(GobblerUser, primary_key=True)
track = models.ForeignKey(Track)
expires = models.DateTimeField(editable=False)
@property
def artist(self):
return self.track.album.artist
def save(self, force_insert=False, force_update=False):
if self.track.length is not None:
self.expires = datetime.now() + self.track.length
else:
self.expires = datetime.now() + 300
super(NowPlaying, self).save(force_insert, force_update)
def __unicode__(self):
return "%s is playing %s" % (self.user, self.track)
class Gobble(models.Model):
user = models.ForeignKey(GobblerUser)
track = models.ForeignKey(Track)
time = models.DateTimeField()
source = models.CharField(choices=SOURCE_CHOICES, max_length=1)
rating = models.CharField(choices=RATING_CHOICES, max_length=1,
blank=True)
@property
def artist(self):
return self.track.album.artist
def __unicode__(self):
return "%s at %s" % (self.user, self.time)
admin.site.register(Gobble)
# Libre.fm -- a free network service for sharing your music listening habits
#
# Copyright (C) 2009 Libre.fm Project
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from datetime import datetime
import md5
import random
from django.contrib.sites.models import Site
from django.http import HttpResponse
from gobbler.models import (Album, Artist, Gobble, GobblerUser, Md5Password,
NowPlaying, Session, Track)
from web.views import frontpage
def handshake_11(request):
g = request.GET
try:
client_id,client_version,user = g['c'], g['v'], g['u']
except KeyError:
return HttpResponse("FAILED The request was malformed\nINTERVAL 0\n")
challenge = md5.new(str(random.random())).hexdigest()
try:
guser = GobblerUser.objects.get(username=user)
except GobblerUser.DoesNotExist:
return HttpResponse("BADUSER\nINTERVAL 0\n")
session,created = Session.objects.get_or_create(user=guser)
session.key = challenge
session.save()
domain = Site.objects.get_current().domain
return HttpResponse("\n".join(["UPTODATE",
challenge,
"http://%s/protocol_1.1/" % (domain,),