Completed
Push — master ( ccac5d...08d670 )
by Andrew
01:22
created

Command.create_json_info()   A

Complexity

Conditions 2

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
1
import json
2
import os
3
import re
4
import struct
5
from time import strftime
6
7
from django.core.management.base import BaseCommand
8
9
from chat.py2_3 import get_unicode
10
from chat.settings import BASE_DIR, SMILEYS_ROOT
11
12
ext = {
13
	b'\x47\x49': 'gif',
14
	b'\xff\xd8': 'jpg',
15
	b'\x89\x50': 'png',
16
	b'\x42\x4d': 'bmp'
17
}
18
19
file_names_pattern = {
20
	"I" : "base",
21
	"II" : "girls",
22
	"III": "extra"
23
}
24
25
START_CHAR = 13313
26
27
smiley_pattern = re.compile(r'^:.*:$')
28
29
30
class Command(BaseCommand):
31
	requires_system_checks = False
32
	def __init__(self):
33
		super(Command, self).__init__()
34
	help = 'CFPack Stealer 1.01'
35
36
	def add_arguments(self, parser):
37
		parser.add_argument(
38
			'--source',
39
			dest='port',
40
			default= os.path.join(BASE_DIR, 'DefaultSmilies.cfpack'),
41
			type=str,
42
		)
43
44
	def extract_file(self):
45
		with open(self.pack_path, 'rb') as f:
46
			addition_info, cats = {}, []
47
			smileys = {}
48
			start_char  = START_CHAR
49
50
			if not os.path.exists(SMILEYS_ROOT):
51
				print("Created smileys dir" + SMILEYS_ROOT)
52
				os.mkdir(SMILEYS_ROOT)
53
			size = struct.unpack('<H', f.read(2))  # header size (useless)
54
			addition_info['width'], addition_info['height'], count = struct.unpack('<HHB', f.read(5))
55
			for c in range(count):
56
				size = ord(f.read(1)) * 2  # 2 bytes per utf8
57
				cats.append((f.read(size)).decode('utf-16le'))  # save category
58
				addition_info[cats[c]] = []
59
				tab_dir_path = os.sep.join((SMILEYS_ROOT, file_names_pattern[cats[c]]))
60
				if not os.path.exists(tab_dir_path):
61
					os.mkdir(tab_dir_path)
62
			addition_info['count'] = struct.unpack('<H', f.read(2))[0]  # amount of bytes in a single pack
63
			for item in range(addition_info['count']):
64
				f.seek(1, 1)  # skip header size
65
				cat_cur = ord(f.read(1))
66
				if cat_cur >= count:
67
					raise SyntaxError('File is not valid')
68
				size = ord(f.read(1)) * 2
69
				alias = (f.read(size)).decode('utf-16le')
70
				f.seek(1, 1)  # 0
71
				size = struct.unpack('<I', f.read(4))[0]
72
				data = f.read(size)
73
				file_ext = ext.get(data[:2], '')
74
				file_name = '{0:04x}.{1}'.format(item, file_ext)
75
				tab = file_names_pattern[cats[cat_cur]]
76
				gif_file_path = os.sep.join((SMILEYS_ROOT, tab, file_name))
77
				smileys.setdefault(tab, [])
78
				start_char += 1
79
				if not smiley_pattern.match(alias):
80
					alias = ":%s:" % alias
81
				smileys[tab].append({
82
					'code': get_unicode(start_char),
83
					'alt': alias,
84
					'src': file_name,
85
				})
86
				with open(gif_file_path, 'wb') as gif:
87
					gif.write(data)
88
		return smileys
89
90
	def create_json_info(self, info):
91
92
		info_file_name = os.sep.join((SMILEYS_ROOT, 'info.json'))
93
		with open(info_file_name, 'w') as f:
94
			f.write(json.dumps(info))
95
96
	def handle(self, *args, **options):
97
		self.pack_path = options['port']
98
		if not os.path.exists(self.pack_path):
99
			raise Exception("cfpack file <<%s>> doesn't exist" % self.pack_path)
100
		info = self.extract_file()
101
		self.create_json_info(info)
102
		print(strftime('[%H:%M:%S] Done.'))
103
104
105