1 # -*- coding: utf-8 -*-
3 from __future__ import division
5 from datetime import datetime
6 from django.db import models
7 from django.contrib.auth.models import get_hexdigest
8 from django.utils import html
10 from ais.common import Nmea, mmsi_to_strmmsi, nice_timedelta_str
12 from ais.jobrunner import make_unique_job_id
14 class UserMessageCategory(models.Model):
15 id = models.CharField(max_length=10, primary_key=True)
17 db_table = u'user_message_category'
19 class UserMessage(models.Model):
20 id = models.AutoField(primary_key=True)
21 user = models.ForeignKey('User')
22 category = models.ForeignKey(UserMessageCategory, db_column='user_message_category_id')
23 txt = models.TextField()
25 db_table = u'user_message'
27 class User(models.Model):
28 id = models.AutoField(primary_key=True)
29 login = models.CharField(max_length=16, unique=True)
30 password_hash = models.CharField(max_length=75)
31 name = models.CharField(max_length=50)
32 email = models.EmailField()
33 father = models.ForeignKey('User')
34 creation_datetime = models.DateTimeField(auto_now_add=True)
35 phone = models.CharField(max_length=20, blank=True)
36 access_datetime = models.DateTimeField(blank=True, null=True)
37 flag_allowhidden = models.BooleanField(default=False)
42 def __unicode__(self):
45 def set_password(self, raw_password):
48 salt = get_hexdigest(algo, str(random.random()), str(random.random()))[:5]
49 hsh = get_hexdigest(algo, salt, raw_password)
50 self.password_hash = '%s$%s$%s' % (algo, salt, hsh)
51 self.info('Password changed') # FIXME
53 def check_password(self, raw_password):
54 password_hash = self.password_hash
57 algo, salt, hsh = password_hash.split('$')
58 return hsh == get_hexdigest(algo, salt, raw_password)
61 def update_access_datetime(self):
62 self.access_datetime = datetime.utcnow()
65 def get_and_delete_messages(self):
68 def is_admin_by(self, user_id):
69 if self.id == user_id:
71 if self.father_id is None:
73 return self.father.is_admin_by(user_id)
75 def get_messages(self):
76 messages = UserMessage.objects.filter(user__id = self.id)
78 [ {'category': message.category, \
80 for message in messages \
85 def info(self, message):
86 UserMessage(user_id = self.id, category_id=u'info', txt=html.escape(message)).save()
88 def error(self, message):
89 UserMessage(user_id = self.id, category_id=u'error', txt=html.escape(message)).save()
91 def check_sandbox_access(self, source_user=None):
94 FleetUser.objects.get(fleet = SANDBOX_FLEET, user = self)
95 except FleetUser.DoesNotExist:
98 fu.fleet_id = SANDBOX_FLEET
101 source_user.info("%s was granted access to 'sandbox' fleet" % self.login)
103 def fleets_count(self):
104 return FleetUser.objects.filter(user=self.id).count()
107 class Vessel(models.Model):
108 mmsi = models.IntegerField(primary_key=True)
109 name = models.CharField(max_length=20)
110 imo = models.IntegerField()
111 callsign = models.CharField(max_length=7)
112 type = models.IntegerField(default=0)
113 destination = models.CharField(max_length=20, blank=True, null=True)
114 updated = models.DateTimeField()
115 source = models.CharField(max_length=8)
116 dim_bow = models.IntegerField(default=0)
117 dim_stern = models.IntegerField(default=0)
118 dim_port = models.IntegerField(default=0)
119 dim_starboard = models.IntegerField(default=0)
120 eta = models.CharField(max_length=8, default='00002460') # format MMDDhhmm
123 def __unicode__(self):
124 return unicode(self.mmsi) # FIXME
125 def get_last_nmea(self):
126 strmmsi = mmsi_to_strmmsi(self.mmsi)
127 return Nmea.new_from_lastinfo(strmmsi)
130 class Fleet(models.Model):
131 id = models.AutoField(primary_key=True)
132 name = models.CharField(max_length=50)
133 vessel = models.ManyToManyField(Vessel, through='FleetVessel')
134 description = models.TextField()
137 def __unicode__(self):
139 def vessel_count(self):
140 return FleetVessel.objects.filter(fleet=self.id).count()
141 def user_count(self):
142 return FleetUser.objects.filter(fleet=self.id).count()
144 if os.path.exists('/var/lib/ais/cron/fleets/%s.cron' % self.name):
149 class FleetUser(models.Model):
150 id = models.AutoField(primary_key=True)
151 fleet = models.ForeignKey(Fleet) #, db_column='fleet_id', to_field='id')
152 user = models.ForeignKey(User)
154 db_table = u'fleet_user'
156 class FleetVessel(models.Model):
157 id = models.AutoField(primary_key=True)
158 fleet = models.ForeignKey(Fleet, db_column='fleet_id', to_field='id')
159 vessel = models.ForeignKey(Vessel, db_column='mmsi', to_field='mmsi')
161 db_table = u'fleet_vessel'
163 ## manual input source
164 #class MiSource(models.Model):
165 # id = models.IntegerField(primary_key=True)
166 # userid = models.IntegerField()
167 # name = models.TextField(unique=True)
169 # db_table = u'mi_source'
171 ## manual input vessel
172 #class MiVessel(models.Model):
173 # mmsi_txt = models.TextField(primary_key=True) # This field type is a guess.
175 # db_table = u'mi_vessel'
179 #class Ppuser(models.Model):
180 # usr = models.TextField(primary_key=True) # This field type is a guess.
181 # lat = models.FloatField()
182 # lon = models.FloatField()
184 # db_table = u'ppuser'
186 #class Plane(models.Model):
187 # flight = models.CharField(max_length=8)
188 # reg = models.CharField(max_length=8)
189 # ads = models.CharField(max_length=8)
190 # type = models.CharField(max_length=4)
191 # usr = models.TextField() # This field type is a guess.
192 # updated = models.DateTimeField()
194 # db_table = u'plane'
198 class News(models.Model):
199 id = models.AutoField(primary_key=True)
200 created = models.DateTimeField()
201 updated = models.DateTimeField()
202 title = models.TextField()
203 txt = models.TextField()
208 class Job(models.Model):
209 id = models.CharField(primary_key=True, max_length=8, default=make_unique_job_id)
210 user = models.ForeignKey(User)
211 queue_time = models.DateTimeField() #auto_now_add=True) is buggy, not GMT
212 start_time = models.DateTimeField(blank=True, null=True)
213 finish_time = models.DateTimeField(blank=True, null=True)
214 command = models.TextField()
215 friendly_filename = models.CharField(max_length=255)
216 pid = models.IntegerField(blank=True, null=True)
217 result = models.IntegerField(blank=True, null=True)
218 archive_time = models.DateTimeField(blank=True, null=True)
219 notify = models.CharField(max_length=1, blank=True, null=True)
221 def queue_rank(self):
222 return Job.objects.filter(queue_time__lt=self.queue_time).filter(start_time__isnull=True).count() + 1
226 return Job.objects.filter(start_time__isnull=True).count()
228 def process_time(self):
229 dt = self.finish_time - self.start_time
230 return nice_timedelta_str(dt)
232 def running_time(self):
233 dt = datetime.utcnow() - self.start_time
234 return nice_timedelta_str(dt)
238 return proc.Stat(self.pid)
242 def get_sucess_size(self):
243 extension = os.path.splitext(self.friendly_filename)[-1]
244 filename = '/var/lib/ais/jobs/%s%s' % (self.id, extension)
245 return os.path.getsize(filename)
247 def get_log_size(self):
248 filename = '/var/lib/ais/jobs/%s.log' % self.id
250 return os.path.getsize(filename)
258 ordering = ('queue_time',)