Completed
Push — master ( cd5ef7...1da252 )
by Andrew
35s
created

UploadedFile   A

Size/Duplication

Total Lines 16
Duplicated Lines 100 %

Importance

Changes 0
Metric Value
dl 16
loc 16
rs 10
c 0
b 0
f 0

1 Method

Rating   Name   Duplication   Size   Complexity  
A type_enum() 3 3 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
import datetime
2
import json
3
import time
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, URLField
10
11
from chat.log_filters import id_generator
12
from chat.settings import GENDERS, DEFAULT_PROFILE_ID, JS_CONSOLE_LOGS
13
14
15
def get_random_path(instance, filename):
16
	"""
17
	:param filename base string for generated name
18
	:return: a unique string filename
19
	"""
20
	return "{}_{}".format(id_generator(8), filename)
21
22
def myoverridenmeta(name, bases, adict):
23
	newClass = type(name, bases, adict)
24
	for field in newClass._meta.fields:
25
		if field.attname == 'password':
26
			field.blank = True
27
	return newClass
28
29
30
class User(AbstractBaseUser):
31
	def get_short_name(self):
32
		return self.username
33
34
	def get_full_name(self):
35
		return self.username
36
37
	@property
38
	def is_staff(self):
39
		# every registered user can edit database
40
		return self.pk == DEFAULT_PROFILE_ID
41
42
	def has_perm(self, perm, obj=None):
43
		return self.is_staff
44
45
	def has_perms(self, perm, obj=None):
46
		return True
47
48
	def has_module_perms(self, app_label):
49
		return self.is_staff
50
51
	USERNAME_FIELD = 'username'
52
	username = CharField(max_length=30, null=False, unique=True)
53
54
	# specifies auth, create email, etc methods
55
	objects = BaseUserManager()
56
57
	# ISO/IEC 5218 1 male, 2 - female
58
	sex = models.SmallIntegerField(null=False, default=0)
59
60
	@property
61
	def sex_str(self):
62
		return GENDERS[self.sex]
63
64
	@sex_str.setter
65
	def sex_str(self, sex):
66
		if sex == 'Male':
67
			self.sex = 1
68
		elif sex == 'Female':
69
			self.sex = 2
70
		else:
71
			self.sex = 0
72
73
	__metaclass__ = myoverridenmeta
74
75
76
class Subscription(models.Model):
77
	user = models.ForeignKey(User, null=False)
78
	inactive = BooleanField(default=False, null=False)
79
	registration_id = models.CharField(null=False, max_length=191, unique=True)
80
	created = models.DateTimeField(default=datetime.datetime.now)
81
	updated = models.DateTimeField(default=datetime.datetime.now)
82
	agent = models.CharField(max_length=64, null=True, blank=True)
83
	is_mobile = BooleanField(default=False, null=False, blank=True)
84
	ip = models.ForeignKey('IpAddress', null=True, blank=True)
85
86
	def __unicode__(self):
87
		return self.__str__()
88
89
	def __str__(self):
90
		return str(self.id)
91
92
93
class Verification(models.Model):
94
95
	class TypeChoices(Enum):
96
		register = 'r'
97
		password = 'p'
98
		email = 'e'
99
		confirm_email = 'c'
100
101
	# a - account activation, r - recover
102
	type = models.CharField(null=False, max_length=1)
103
	token = models.CharField(max_length=17, null=False, default=id_generator)
104
	user = models.ForeignKey(User, null=False)
105
	time = models.DateTimeField(default=datetime.datetime.now)
106
	verified = BooleanField(default=False)
107
	email = models.EmailField(null=True, unique=False, blank=True, max_length=190)
108
109
	def __unicode__(self):
110
		return self.__str__()
111
112
	def __str__(self):
113
		return str(self.id)
114
115
	@property
116
	def type_enum(self):
117
		return self.TypeChoices(self.type)
118
119
	@type_enum.setter
120
	def type_enum(self, p_type):
121
		"""
122
		:type p_type: Verification.TypeChoices
123
		"""
124
		self.type = p_type.value
125
126
127
class UserProfile(User):
128
	name = CharField(max_length=30, null=True, blank=True)
129
	surname = CharField(max_length=30, null=True, blank=True)
130
	# tho email max length is 254 characted mysql supports unique keys only 767 bytes long (utf8 4 bytes = 767/4 = 191)
131
	email = models.EmailField(null=True, unique=True, blank=True, max_length=190)
132
	city = CharField(max_length=50, null=True, blank=True)
133
134
	birthday = DateField(null=True, blank=True)
135
	contacts = CharField(max_length=100, null=True, blank=True)
136
	# fileField + <img instead of ImageField (removes preview link)
137
	photo = FileField(upload_to=get_random_path, null=True, blank=True)
138
	suggestions = BooleanField(null=False, default=True)
139
	embedded_youtube = BooleanField(null=False, default=True)
140
	highlight_code = BooleanField(null=False, default=False)
141
	logs = BooleanField(null=False, default=JS_CONSOLE_LOGS)
142
	theme = CharField(max_length=16, null=False, default='color-reg')
143
	online_change_sound = BooleanField(null=False, default=True)
144
	incoming_file_call_sound = BooleanField(null=False, default=True)
145
	message_sound = BooleanField(null=False, default=True)
146
147
	email_verification = models.ForeignKey(Verification, null=True, blank=True)
148
149
	def save(self, *args, **kwargs):
150
		"""
151
		http://stackoverflow.com/questions/15422606/django-model-email-field-unique-if-not-null-blank
152
		"""
153
		if self.email is not None:
154
			self.email.lower().strip()  # Hopefully reduces junk to ""
155
			if self.email == "":
156
				self.email = None
157
		super(UserProfile, self).save(*args, **kwargs)
158
159
160
class Room(models.Model):
161
	name = CharField(max_length=16, null=True, blank=True)
162
	users = models.ManyToManyField(User, related_name='rooms', through='RoomUsers')
163
	disabled = BooleanField(default=False, null=False)
164
165
	@property
166
	def is_private(self):
167
		return self.name is None
168
169
	def __unicode__(self):
170
		return self.__str__()
171
172
	def __str__(self):
173
		return "{}/{}".format(self.id, self.name)
174
175
176
def get_milliseconds(dt=None):
177
	if dt is None:
178
		return int(time.time()*1000)
179
	if dt.time.timestamp:
180
		return int(dt.time.timestamp()*1000)
181
	else:
182
		return mktime(dt.time.timetuple()) * 1000 + int(dt.time.microsecond / 1000)
183
184
185
class MessageHistory(models.Model):
186
	time = models.BigIntegerField(default=get_milliseconds)
187
	message = models.ForeignKey('Message', null=False)
188
	content = models.TextField(null=True, blank=True)
189
	giphy = URLField(null=True, blank=True)
190
191
192
class Message(models.Model):
193
	"""
194
	Contains all public messages
195
	"""
196
	sender = models.ForeignKey(User, related_name='sender')
197
	room = models.ForeignKey(Room, null=True)
198
	# DateField.auto_now
199
	time = models.BigIntegerField(default=get_milliseconds)
200
	content = models.TextField(null=True, blank=True)
201
	# if symbol = null - no images refers this row
202
	# symbol is the same as "select max(symbol) from images where message_id = message.id
203
	# we store symbol in this table in case if user edits message
204
	# - images that refers same message always have unique symbols
205
	symbol = models.CharField(null=True, max_length=1, blank=True)
206
	deleted = BooleanField(default=False)
207
	giphy = URLField(null=True, blank=True)
208
	edited_times = models.IntegerField(default=0, null=False)
209
210
	def __unicode__(self):
211
		return self.__str__()
212
213
	def __str__(self):
214
215
		if self.content is None:
216
			v = ''
217
		elif len(self.content) > 50:
218
			v = self.content[:50]
219
		else:
220
			v = self.content
221
		v = json.dumps(v)
222
		return "{}/{}".format(self.id, v)
223
224
225 View Code Duplication
class UploadedFile(models.Model):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
226
	class UploadedFileChoices(Enum):
227
		video = 'v'
228
		image = 'i'
229
	symbol = models.CharField(null=False, max_length=1)
230
	file = FileField(upload_to=get_random_path, null=True)
231
	user = models.ForeignKey(User, null=False)
232
	type = models.CharField(null=False, max_length=1)
233
234
	@property
235
	def type_enum(self):
236
		return UploadedFileChoices(self.type)
237
238
	@type_enum.setter
239
	def type_enum(self, p_type):
240
		self.type = p_type.value
241
242
243 View Code Duplication
class Image(models.Model):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
244
245
	class MediaTypeChoices(Enum):
246
		video = 'v'
247
		image = 'i'
248
249
	# character in Message.content that will be replaced with this image
250
	symbol = models.CharField(null=False, max_length=1)
251
	message = models.ForeignKey(Message, related_name='message', null=False)
252
	img = FileField(upload_to=get_random_path, null=True)
253
	type = models.CharField(null=False, max_length=1, default=MediaTypeChoices.image.value)
254
255
	@property
256
	def type_enum(self):
257
		return MediaTypeChoices(self.type)
258
259
	@type_enum.setter
260
	def type_enum(self, p_type):
261
		self.type = p_type.value
262
263
	class Meta:
264
		unique_together = ('symbol', 'message')
265
266
267
class RoomUsers(models.Model):
268
	room = models.ForeignKey(Room, null=False)
269
	user = models.ForeignKey(User, null=False)
270
	last_read_message = models.ForeignKey(Message, null=True)
271
	volume = models.IntegerField(default=2, null=False)
272
	notifications = BooleanField(null=False, default=True)
273
274
	class Meta:  # pylint: disable=C1001
275
		unique_together = ("user", "room")
276
		db_table = ''.join((User._meta.app_label, '_room_users'))
277
278
279
class SubscriptionMessages(models.Model):
280
	message = models.ForeignKey(Message, null=False)
281
	subscription = models.ForeignKey(Subscription, null=False)
282
	received = BooleanField(null=False, default=False)
283
284
	class Meta:  # pylint: disable=C1001
285
		unique_together = ("message", "subscription")
286
		db_table = ''.join((User._meta.app_label, '_subscription_message'))
287
288
289
class Issue(models.Model):
290
	content = models.TextField(null=False)  # unique = true, but mysql doesnt allow unique fields for unspecified size
291
292
	def __str__(self):
293
		return self.content
294
295
296
class IssueDetails(models.Model):
297
	sender = models.ForeignKey(User, null=False)
298
	browser = models.CharField(null=False, max_length=32, blank=True)
299
	time = models.DateField(default=datetime.datetime.now, blank=True)
300
	issue = models.ForeignKey(Issue, related_name='issue')
301
	log = models.TextField(null=True, blank=True)
302
303
	class Meta:  # pylint: disable=C1001
304
		db_table = ''.join((User._meta.app_label, '_issue_detail'))
305
306
307
class IpAddress(models.Model):
308
	ip = models.CharField(null=False, max_length=32, unique=True)
309
	isp = models.CharField(null=True, max_length=32, blank=True)
310
	country_code = models.CharField(null=True, max_length=16, blank=True)
311
	country = models.CharField(null=True, max_length=32, blank=True)
312
	region = models.CharField(null=True, max_length=32, blank=True)
313
	city = models.CharField(null=True, max_length=32, blank=True)
314
315
	def __str__(self):
316
		return self.ip
317
318
	@property
319
	def info(self):
320
		if self.country is not None:
321
			return "{} {} ({})".format(self.country, self.city, self.isp)
322
		else:
323
			return ""
324
325
326
	class Meta:  # pylint: disable=C1001
327
		db_table = ''.join((User._meta.app_label, '_ip_address'))
328
329
330
class UserJoinedInfo(models.Model):
331
	ip = models.ForeignKey(IpAddress, null=True)
332
	user = models.ForeignKey(User, null=True)
333
	time = models.DateField(default=datetime.datetime.now)
334
335
	class Meta:  # pylint: disable=C1001
336
		db_table = ''.join((User._meta.app_label, '_user_joined_info'))
337
		unique_together = ("user", "ip")
338