From dceba28d9fbe9c2f751e71b1093ac23c7ed958c5 Mon Sep 17 00:00:00 2001 From: j Date: Sat, 2 Nov 2013 17:24:11 +0100 Subject: [PATCH] django_lsd --- .gitignore | 4 ++ README | 30 +++++++++++++++ django_lsd/__init__.py | 0 django_lsd/models.py | 57 ++++++++++++++++++++++++++++ django_lsd/views.py | 86 ++++++++++++++++++++++++++++++++++++++++++ setup.py | 21 +++++++++++ 6 files changed, 198 insertions(+) create mode 100644 .gitignore create mode 100644 README create mode 100644 django_lsd/__init__.py create mode 100644 django_lsd/models.py create mode 100644 django_lsd/views.py create mode 100644 setup.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5f4e12a --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*.pyc +*.swp +MANIFEST +build diff --git a/README b/README new file mode 100644 index 0000000..3526b49 --- /dev/null +++ b/README @@ -0,0 +1,30 @@ +# django-lsd + integrate LSD into your django app + +# settings.py + +in settings set LSD_ITEM to your item model i.e.: + + LDS_ITEM="item.models.Item" + + and add "django_lsd" to INSTALLED_APPS + + +# add this to urls.py + +import ox.django.api.urls + +urlpatterns += patterns('', + (r'^api/?$', include(ox.django.api.urls)), +) + + +# custom models + +If you set a custom model via LSD_ITEMS, +the referenced model needs the following rows: + + sha1 = models.CharField(max_length=40, unique=True) + info_hash = models.CharField(max_length=40, unique=True, null=True) + data = ox.django.fields.DictField(default={}, editable=False) + diff --git a/django_lsd/__init__.py b/django_lsd/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/django_lsd/models.py b/django_lsd/models.py new file mode 100644 index 0000000..5c6dfc3 --- /dev/null +++ b/django_lsd/models.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# vi:si:et:sw=4:sts=4:ts=4 +from __future__ import division +import sys +import importlib + +from django.conf import settings +from django.db import models +from django.contrib.auth.models import User +from ox.django import fields + +def str_to_class(str): + if '.' in str: + module_name = '.'.join(str.split('.')[:-1]) + class_name = str.split('.')[-1] + m = importlib.import_module(module_name) + return getattr(m, class_name) + else: + return reduce(getattr, str.split("."), sys.modules[__name__]) + +class LSDItem(models.Model): + created = models.DateTimeField(auto_now_add=True) + modified = models.DateTimeField(auto_now=True) + accessed = models.DateTimeField(auto_now=True) + + sha1 = models.CharField(max_length=40, unique=True) + info_hash = models.CharField(max_length=40, unique=True, null=True) + + data = fields.DictField(default={}, editable=False) + +Item = str_to_class(getattr(settings, 'LSD_ITEM', 'LSDItem')) + +class Request(models.Model): + created = models.DateTimeField(auto_now_add=True) + modified = models.DateTimeField(auto_now=True) + + item = models.ForeignKey(Item, related_name='lsd_requests', db_index=True) + user = models.ForeignKey(User, related_name='lsd_requests', db_index=True) + + @classmethod + def get(cls, user): + return [f['sha1'] for f in Item.objects.filter( + lsd_files__in=File.objects.filter(user=user), + lsd_requests__in=cls.objects.exclude(user=user) + ).values('sha1')] + +class File(models.Model): + + item = models.ForeignKey(Item, related_name='lsd_files', db_index=True) + user = models.ForeignKey(User, related_name='lsd_files', db_index=True) + + @classmethod + def get(cls, user): + return [f['sha1'] for f in Item.objects.filter( + lsd_files__in=cls.objects.filter(user=user) + ).values('sha1')] + diff --git a/django_lsd/views.py b/django_lsd/views.py new file mode 100644 index 0000000..ae9508b --- /dev/null +++ b/django_lsd/views.py @@ -0,0 +1,86 @@ +# -*- coding: utf-8 -*- +# vi:si:et:sw=4:sts=4:ts=4 +from __future__ import division +import json + +from ox.django.decorators import login_required_json +from ox.django.shortcuts import render_to_json_response, json_response + +import models + +from ox.django.api import actions + +@login_required_json +def sync(request): + ''' + sync({}) -> {ids: [id]} + sync({add: [id], remove: [id]}) -> {update: [id]} + sync({update: [metadata]}) -> {} + ''' + response = json_response() + if 'data' in request.POST: + data = json.loads(request.POST['data']) + else: + data = {} + if not data: + response['data']['ids'] = models.File.get(request.user) + update = [] + if 'add' in data: + for sha1 in data['add']: + i, created = models.Item.objects.get_or_create(sha1=sha1) + if created: + update.append(sha1) + f, created = models.File.objects.get_or_create(item=i, user=request.user) + models.Request.objects.filter(user=request.user, item=i).delete() + if 'remove' in data: + models.File.objects.filter(item__sha1__in=data['remove'], user=request.user).delete() + if 'update' in data: + for f in data['update']: + i, created = models.Item.objects.get_or_create(sha1=f['sha1']) + i.info_hash = f['info_hash'] + for key in f.keys(): + if key not in ('sha1', 'info_hash'): + i.data[key] = f[key] + #i.update_external_data() + i.save() + response['data']['update'] = update + return render_to_json_response(response) +actions.register(sync) + +@login_required_json +def addRequests(request): + ''' + addRequests({ids: [id]}) -> {metadata: [metadata]} + ''' + response = json_response() + data = json.loads(request.POST['data']) + metadata = [] + for item in models.Item.objects.filter(sha1__in=data['ids']): + info_hash = item.info_hash + if info_hash and not request.user.lsd_files.filter(item=item).exists(): + r, created = models.Request.objects.get_or_create(user=request.user, item=item) + metadata.append({'sha1': item.sha1, 'info_hash': info_hash}) + response['data']['metadata'] = metadata + return render_to_json_response(response) +actions.register(addRequests) + +@login_required_json +def removeRequests(request): + ''' + removeRequests({ids: [id]}) -> {} + ''' + response = json_response() + data = json.loads(request.POST['data']) + models.Request.objects.filter(user=request.user, item__sha1__in=data['ids']).delete() + return render_to_json_response(response) +actions.register(removeRequests) + +@login_required_json +def getRequests(request): + ''' + getRequests({}) -> {ids: [id]} + ''' + response = json_response() + response['data']['ids'] = models.Request.get(request.user) + return render_to_json_response(response) +actions.register(getRequests) diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..bb9ffe0 --- /dev/null +++ b/setup.py @@ -0,0 +1,21 @@ +# setup.py +# -*- coding: UTF-8 -*- +# vi:si:et:sw=4:sts=4:ts=4 +from distutils.core import setup + +setup(name="django_lsd", + version="0.1", + packages=[ + 'django_lsd', + ], + install_requires=['ox'], + author="j", + author_email="j@mailb.org", + description=u"django_lsd integrates LSD into django", + classifiers = [ + 'Development Status :: 4 - Beta', + 'Operating System :: OS Independent', + 'Programming Language :: Python', + ], +) +