Completed
Push — master ( 6ca66a...a573ac )
by Andrew
01:29
created

get_milliseconds()   A

Complexity

Conditions 3

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 3
dl 0
loc 7
rs 9.4285
1
import datetime
2
import time
3
import uuid
4
from enum import Enum
5
from time import mktime
6
7
from django.contrib.auth.models import BaseUserManager, AbstractBaseUser
8
from django.db import models
9
from django.db.models import CharField, DateField, FileField, BooleanField
10
11
from chat.log_filters import id_generator
12
from chat.settings import GENDERS, DEFAULT_PROFILE_ID
13
14
15
class User(AbstractBaseUser):
16
	def get_short_name(self):
17
		return self.username
18
19
	def get_full_name(self):
20
		return self.username
21
22
	@property
23
	def is_staff(self):
24
		# every registered user can edit database
25
		return self.pk == DEFAULT_PROFILE_ID
26
27
	def has_perm(self, perm, obj=None):
28
		return self.is_staff
29
30
	def has_perms(self, perm, obj=None):
31
		return True
32
33
	def has_module_perms(self, app_label):
34
		return self.is_staff
35
36
	USERNAME_FIELD = 'username'
37
	username = CharField(max_length=30, null=False, unique=True)
38
39
	# specifies auth, create email, etc methods
40
	objects = BaseUserManager()
41
42
	# ISO/IEC 5218 1 male, 2 - female
43
	sex = models.SmallIntegerField(null=False)
44
45
	@property
46
	def sex_str(self):
47
		return GENDERS[self.sex]
48
49
	@sex_str.setter
50
	def sex_str(self, sex):
51
		if sex == 'Male':
52
			self.sex = 1
53
		elif sex == 'Female':
54
			self.sex = 2
55
		else:
56
			self.sex = 0
57
58
59
60
class Verification(models.Model):
61
62
	class TypeChoices(Enum):
63
		register = 'r'
64
		password = 'p'
65
66
	# a - account activation, r - recover
67
	type = models.CharField(null=False, max_length=1)
68
	token = models.CharField(max_length=17, null=False, default=id_generator)
69
	user = models.ForeignKey(User, null=False)
70
	time = models.DateTimeField(default=datetime.datetime.now)
71
	verified = BooleanField(default=False)
72
73
	@property
74
	def type_enum(self):
75
		return self.TypeChoices(self.type)
76
77
	@type_enum.setter
78
	def type_enum(self, p_type):
79
		"""
80
		:type p_type: Verification.TypeChoices
81
		"""
82
		self.type = p_type.value
83
84
85
class UserProfile(User):
86
87
	def get_file_path(self, filename):
88
		"""
89
		:param filename base string for generated name
90
		:return: a unique string filename
91
		"""
92
		ext = filename.split('.')[-1]
93
		return "%s.%s" % (uuid.uuid4(), ext)
94
95
	name = CharField(max_length=30, null=True)
96
97
	surname = CharField(max_length=30, null=True)
98
	email = models.EmailField(null=True, unique=True, blank=True)
99
	city = CharField(max_length=50, null=True)
100
101
	birthday = DateField(null=True)
102
	contacts = CharField(max_length=100, null=True)
103
	# fileField + <img instead of ImageField (removes preview link)
104
	photo = FileField(upload_to=get_file_path, null=True)
105
	# TODO, save theme in profile? theme_name = CharField(max_length=16, null=True)
106
107
	email_verification = models.ForeignKey(Verification, null=True)
108
109
	def save(self, *args, **kwargs):
110
		"""
111
		http://stackoverflow.com/questions/15422606/django-model-email-field-unique-if-not-null-blank
112
		"""
113
		if self.email is not None:
114
			self.email.lower().strip()  # Hopefully reduces junk to ""
115
			if self.email == "":
116
				self.email = None
117
		super(UserProfile, self).save(*args, **kwargs)
118
119
120
class Room(models.Model):
121
	name = CharField(max_length=30, null=True, unique=True)
122
	users = models.ManyToManyField(User, related_name='rooms')
123
	is_private = BooleanField(default=True)
124
125
126
def get_milliseconds(dt=None):
127
	if dt is None:
128
		return int(time.time()*1000)
129
	if dt.time.timestamp:
130
		return int(dt.time.timestamp()*1000)
131
	else:
132
		return mktime(dt.time.timetuple()) * 1000 + int(dt.time.microsecond / 1000)
133
134
135
class Message(models.Model):
136
	"""
137
	Contains all public messages
138
	"""
139
	sender = models.ForeignKey(User, related_name='sender')
140
	room = models.ForeignKey(Room, null=True)
141
	# DateField.auto_now
142
	time = models.BigIntegerField(default=get_milliseconds)
143
	content = models.TextField()
144
	is_raw = models.BooleanField(default=True, null=False)
145
	receiver = models.ForeignKey(User, null=True, related_name='receiver')
146
147
148
class Issue(models.Model):
149
	content = models.TextField(null=False)  # unique = true, but mysql doesnt allow unique fields for unspecified size
150
151
	def __str__(self):
152
		return self.content
153
154
155
class IssueDetails(models.Model):
156
	sender = models.ForeignKey(User, null=True, blank=True)
157
	email = models.EmailField(null=True, blank=True)
158
	browser = models.CharField(null=False, max_length=32)
159
	time = models.DateField(default=datetime.datetime.now, blank=True)
160
	issue = models.ForeignKey(Issue, related_name='issue')
161
	log = models.TextField(null=True)
162
163
	class Meta:  # pylint: disable=C1001
164
		db_table = ''.join((User._meta.app_label, '_issue_detail'))
165
166
167
class IpAddress(models.Model):
168
	ip = models.CharField(null=False, max_length=32, unique=True)
169
	isp = models.CharField(null=True, max_length=32)
170
	country_code = models.CharField(null=True, max_length=16)
171
	country = models.CharField(null=True, max_length=32)
172
	region = models.CharField(null=True, max_length=32)
173
	city = models.CharField(null=True, max_length=32)
174
175
	def __str__(self):
176
		return self.ip
177
178
	class Meta:  # pylint: disable=C1001
179
		db_table = ''.join((User._meta.app_label, '_ip_address'))
180
181
182
class UserJoinedInfo(models.Model):
183
	ip = models.ForeignKey(IpAddress, null=True)
184
	user = models.ForeignKey(User, null=True)
185
	time = models.DateField(default=datetime.datetime.now)
186
187
	class Meta:  # pylint: disable=C1001
188
		db_table = ''.join((User._meta.app_label, '_user_joined_info'))
189
		unique_together = ("user", "ip")
190