set Note.name to filename by default
[oweals/karmaworld.git] / karmaworld / apps / notes / models.py
1 #!/usr/bin/env python
2 # -*- coding:utf8 -*-
3 # Copyright (C) 2012  FinalsClub Foundation
4
5 """
6     Models for the notes django app.
7     Contains only the minimum for handling files and their representation
8 """
9 import datetime
10
11 from django.conf import settings
12 from django.core.files.storage import FileSystemStorage
13 from django.db import models
14 from django.template import defaultfilters
15 from taggit.managers import TaggableManager
16 from oauth2client.client import Credentials
17
18 from karmaworld.apps.courses.models import Course
19
20 try:
21     from secrets.drive import GOOGLE_USER
22 except:
23     GOOGLE_USER = u'admin@karmanotes.org'
24
25 fs = FileSystemStorage(location=settings.MEDIA_ROOT)
26
27 class Note(models.Model):
28     """ A django model representing an uploaded file and associated metadata.
29     """
30     UNKNOWN_FILE = '???'
31     FILE_TYPE_CHOICES = (
32         ('doc', 'MS Word compatible file (.doc, .docx, .rtf, .odf)'),
33         ('img', 'Scan or picture of notes'),
34         ('pdf', 'PDF file'),
35         (UNKNOWN_FILE, 'Unknown file'),
36     )
37
38     course          = models.ForeignKey(Course)
39     # Tagging system
40     tags            = TaggableManager(blank=True)
41
42     name            = models.CharField(max_length=255, blank=True, null=True)
43     slug            = models.SlugField(max_length=255, null=True)
44     year            = models.IntegerField(blank=True, null=True, 
45                         default=datetime.datetime.utcnow().year)
46     desc            = models.TextField(max_length=511, blank=True, null=True)
47     uploaded_at     = models.DateTimeField(null=True, default=datetime.datetime.utcnow)
48
49     file_type       = models.CharField(max_length=15,
50                             choices=FILE_TYPE_CHOICES,
51                             default=UNKNOWN_FILE,
52                             blank=True, null=True)
53
54     # Upload files to MEDIA_ROOT/notes/YEAR/MONTH/DAY, 2012/10/30/filename
55     note_file       = models.FileField(
56                             storage=fs,
57                             upload_to="notes/%Y/%m/%j/",
58                             blank=True, null=True)
59
60     ## post gdrive conversion data
61     embed_url       = models.URLField(max_length=1024, blank=True, null=True)
62     download_url    = models.URLField(max_length=1024, blank=True, null=True)
63     # for word processor documents
64     html            = models.TextField(blank=True, null=True)
65     text            = models.TextField(blank=True, null=True)
66
67
68     class Meta:
69         """ Sort files by most recent first """
70         ordering = ['-uploaded_at']
71
72
73     def __unicode__(self):
74         return u"{0}: {1} -- {2}".format(self.file_type, self.name, self.uploaded_at)
75
76     def save(self, *args, **kwargs):
77         """ override built-in save to ensure contextual self.name """
78         # TODO: If self.name isn't set, generate one based on uploaded_name
79         # if we fail to set the Note.name earlier than this, use the saved filename
80
81         if not self.slug and self.name:
82             # only generate a slug if the name has been set, and slug hasn't
83             self.slug = defaultfilters.slugify(self.name)
84
85         # Check if Note.uploaded_at is after Course.updated_at
86         if self.uploaded_at and self.uploaded_at > self.course.updated_at:
87             self.course.updated_at = self.uploaded_at
88             # if it is, update Course.updated_at
89             self.course.save()
90
91         super(Note, self).save(*args, **kwargs)
92
93     def get_absolute_url(self):
94         """ Resolve note url, use 'note' route and slug if slug
95             otherwise use note.id
96         """
97         if self.slug is not None:
98             # return a url ending in slug
99             return u"/{0}/{1}/{2}".format(self.course.school.slug, self.course.slug, self.slug)
100         else:
101             # return a url ending in id
102             return u"/{0}/{1}/{2}".format(self.course.school.slug, self.course.slug, self.id)
103
104
105 class DriveAuth(models.Model):
106     """ stored google drive authentication and refresh token
107         used for interacting with google drive """
108
109     email = models.EmailField(default=GOOGLE_USER)
110     credentials = models.TextField() # JSON of Oauth2Credential object
111     stored_at = models.DateTimeField(auto_now=True)
112
113
114     @staticmethod
115     def get(email=GOOGLE_USER):
116         """ Staticmethod for getting the singleton DriveAuth object """
117         # FIXME: this is untested
118         return DriveAuth.objects.filter(email=email).reverse()[0]
119
120
121     def store(self, creds):
122         """ Transform an existing credentials object to a db serialized """
123         self.email = creds.id_token['email']
124         self.credentials = creds.to_json()
125         self.save()
126
127
128     def transform_to_cred(self):
129         """ take stored credentials and produce a Credentials object """
130         return Credentials.new_from_json(self.credentials)
131
132
133     def __unicode__(self):
134         return u'Gdrive auth for %s created/updated at %s' % \
135                     (self.email, self.stored_at)