Compare commits

..

10 Commits

Author SHA1 Message Date
Masahiko AMANO
d1462470b1 Some funny little change
:)
2022-02-09 19:12:17 +03:00
Masahiko AMANO
afa417d251 A little optimization for table encoding 2021-12-14 13:13:26 +03:00
Masahiko AMANO
52c6c95050 Update README.md 2021-12-11 00:30:00 +03:00
Masahiko AMANO
309521897b Rearranged files
So, now it all works standalone without any dependencies on external resources.
2021-12-11 00:29:21 +03:00
Masahiko AMANO
f63cb6cb59 Minor fixes 2021-12-10 00:45:29 +03:00
Masahiko AMANO
0ed8d1482b Some minor changes 2021-12-09 16:16:33 +03:00
Masahiko AMANO
06e53e7972 Change table encoding to SHICHIRO 2021-12-09 16:15:47 +03:00
Masahiko AMANO
01ff16fddd Update README.md 2021-12-08 16:01:31 +03:00
Masahiko AMANO
fef8f4ec00 Just fixed it all
Back to this project after over a half-year
2021-12-08 15:58:48 +03:00
31d5b1c0f2 Rearranged files and beautified code 2021-05-03 00:45:54 +03:00
14 changed files with 404 additions and 329 deletions

View File

@ -2,15 +2,21 @@
## What's up? ## What's up?
Hey! This is a simple web-service called ![HuffPress](https://img.shields.io/badge/Huff-Press-orange.svg). What it does? Well, actually it *huffpresses* files... I mean, compresses files using the [Huffman compression](https://en.wikipedia.org/wiki/Huffman_coding "Read about it on Wikipedia"). Hey! This is a simple web-service called __HuffPress__. What it does? Well, actually it _huffpresses_ files... I mean, compresses files using the [Huffman compression](https://en.wikipedia.org/wiki/Huffman_coding 'Read about it on Wikipedia').
Also it uses a bit modified [SHICHIRO coding](https://github.com/H1K0/SHICHIRO 'View on GitHub') for compressing and embedding Huffman table.
## What do I need? ## What do I need?
- Any web browser - Any web browser
- ![PHP 7+](https://img.shields.io/badge/PHP-7+-blueviolet.svg) - ![PHP 7+](https://img.shields.io/badge/PHP-7+-blueviolet.svg)
- ![Python 3+](https://img.shields.io/badge/Python-3+-blue.svg) - ![Python 3.7+](https://img.shields.io/badge/Python-3+-blue.svg)
- `click` library - `click` python library
## So, how do I use it? ## So, how do I use it?
I think it's too easy to explain the usage of this service, but anyway here's [a video guide](https://yadi.sk/i/aiy78bDaoKqoJQ "Watch!"). I think the usage is too easy to explain it, but anyway here's [a video guide](https://yadi.sk/i/aiy78bDaoKqoJQ 'Watch!').
---
<p align=center><i>&copy; Masahiko AMANO a.k.a. H1K0, 2020-2021</i></p>

7
css/bootstrap.min.css vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -1,11 +1,12 @@
@import url('https://fonts.googleapis.com/css2?family=Epilogue&family=Secular+One&display=swap'); @import url('https://fonts.googleapis.com/css2?family=Epilogue&family=Secular+One&display=swap');
html,body{ html,
body {
width: 100%; width: 100%;
min-height: 100vh; min-height: 100vh;
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
body{ body {
position: absolute; position: absolute;
left: 0; left: 0;
right: 0; right: 0;
@ -15,16 +16,16 @@ body{
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
background-image: url(bg.webp); background-image: url(../images/bg.webp);
background-size: cover; background-size: cover;
} }
header{ header {
margin: 0; margin: 0;
margin-top: 2vw; margin-top: 2vw;
padding: 0; padding: 0;
text-align: center; text-align: center;
} }
h1{ h1 {
margin: 0; margin: 0;
padding: 0; padding: 0;
color: white; color: white;
@ -33,21 +34,21 @@ h1{
text-shadow: 0 0 1vw black; text-shadow: 0 0 1vw black;
cursor: default; cursor: default;
} }
main{ main {
display: none; display: none;
margin-bottom: 2vw; margin-bottom: 2vw;
background-color: #fff8; background-color: #fff8;
box-shadow: 0 0 .5vw black; box-shadow: 0 0 0.5vw black;
border-radius: 1.5vw; border-radius: 1.5vw;
min-height: 9vw; min-height: 9vw;
transition: .3s; transition: 0.3s;
overflow: hidden; overflow: hidden;
} }
main:hover{ main:hover {
background-color: #fff; background-color: #fff;
box-shadow: 0 0 1vw black; box-shadow: 0 0 1vw black;
} }
h2{ h2 {
margin: 0; margin: 0;
padding: 0 2vw; padding: 0 2vw;
height: 9vw; height: 9vw;
@ -55,14 +56,14 @@ h2{
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
background-color: hsla(270,80%,80%,.6); background-color: hsla(270, 80%, 80%, 0.6);
border-bottom: 0; border-bottom: 0;
font-family: Secular One; font-family: Secular One;
font-size: 3vw; font-size: 3vw;
text-shadow: 2.5px 2px .5px white; text-shadow: 2.5px 2px 0.5px white;
cursor: pointer; cursor: pointer;
} }
form{ form {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
@ -71,7 +72,7 @@ form{
padding: 2vw 2vw; padding: 2vw 2vw;
box-sizing: border-box; box-sizing: border-box;
} }
.wrap{ .wrap {
display: none; display: none;
position: absolute; position: absolute;
left: 0; left: 0;
@ -83,7 +84,9 @@ form{
align-items: center; align-items: center;
z-index: 10; z-index: 10;
} }
.process,.complete,.error{ .process,
.complete,
.error {
display: none; display: none;
padding: 2vw 5vw; padding: 2vw 5vw;
background-color: white; background-color: white;
@ -92,28 +95,28 @@ form{
font-size: 5vw; font-size: 5vw;
cursor: default; cursor: default;
} }
.process img{ .process img {
width: 15vw; width: 15vw;
} }
h3{ h3 {
margin: 0; margin: 0;
margin-top: .5vw; margin-top: 0.5vw;
font-family: Secular One; font-family: Secular One;
font-size: 3vw; font-size: 3vw;
} }
.status{ .status {
margin: 0; margin: 0;
margin-top: .5vw; margin-top: 0.5vw;
font-family: monospace; font-family: monospace;
font-size: 1.5vw; font-size: 1.5vw;
} }
.btncont{ .btncont {
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
.btncont *{ .btncont * {
font-size: 2vw; font-size: 2vw;
} }
#dlink{ #dlink {
margin-right: 1vw; margin-right: 1vw;
} }

View File

@ -1,190 +1,204 @@
from os.path import dirname,basename,join,abspath as path from os.path import dirname, basename, join, abspath as path
from time import time from time import time
from datetime import datetime as dt from datetime import datetime as dt
import click import click
from urllib.parse import quote as url
class Log: class Log:
def __init__(self,path,name): def __init__(self, path, name):
self.path=path self.path = path
self.name=name self.name = name
def log(self,msg,name=None): def log(self, msg, name=None):
if name is None: if name is None:
name=self.name name = self.name
now=dt.today() now = dt.today()
with open(self.path,'a',encoding='utf-8') as file: with open(self.path, 'a', encoding='utf-8') as file:
file.write(f'{now.year}-{str(now.month).rjust(2,"0")}-{str(now.day).rjust(2,"0")} ' file.write(f'{now.year}-{str(now.month).rjust(2, "0")}-{str(now.day).rjust(2, "0")} '
f'{str(now.hour).rjust(2,"0")}:{str(now.minute).rjust(2,"0")}:{str(now.second).rjust(2,"0")},{str(now.microsecond)[:3]}' f'{str(now.hour).rjust(2, "0")}:{str(now.minute).rjust(2, "0")}:{str(now.second).rjust(2, "0")},{str(now.microsecond)[:3]}'
' | ' ' | '
f'{name}' f'{name}'
' | ' ' | '
f'{msg}\n') f'{msg}\n')
log=Log(join(dirname(__file__),'hfm.log'),'hfm-py')
log = Log(join(dirname(__file__), 'hfm.log'), 'hfm-py')
output = ''
def huffman(data): def huffman(data):
units={} #getting element-wise info units = {} # getting element-wise info
for c in data: for c in data:
if c in units: if c in units:
units[c]+=1 units[c] += 1
else: else:
units[c]=1 units[c] = 1
units,codes=sorted([([u],units[u]) for u in units],key=lambda u:u[1]),dict.fromkeys(units.keys(),'') codes = dict.fromkeys(units.keys(), '')
units = sorted([([u], units[u]) for u in units], key=lambda u: u[1])
while units: #creating Haffman table while units: # creating Haffman table
if len(units)>2: if len(units) > 2:
b=int(units[0][1]+units[1][1]>units[1][1]+units[2][1]) b = int(units[0][1] + units[1][1] > units[1][1] + units[2][1])
else: else:
b=0 b = 0
for c in units[b][0]: for c in units[b][0]:
codes[c]='0'+codes[c] codes[c] = '0' + codes[c]
for c in units[1+b][0]: for c in units[1 + b][0]:
codes[c]='1'+codes[c] codes[c] = '1' + codes[c]
units[2*b]=units[b][0]+units[1+b][0],units[b][1]+units[1+b][1] units[2 * b] = units[b][0] + units[1 + b][0], units[b][1] + units[1 + b][1]
if len(units)>2: if len(units) > 2:
del units[1] del units[1]
units.sort(key=lambda u:u[1]) units.sort(key=lambda u: u[1])
else: else:
del units del units
break break
return codes return codes
def shichiro_encode(table):
def tbl(table): table = ';'.join([f'{k};{table[k]}' for k in table]).split(';')
table=';'.join([f'{k};{table[k]}' for k in table]).split(';') bits = ''
byts=[] for i in range(len(table)):
for i in range(len(table)): if i % 2:
if i%2: code = table[i]
num=table[i] bits += bin(len(code))[2:].rjust(8,'0')
else: bits += code
num=bin(int(table[i]))[2:] else:
while len(num)>7: bits += bin(int(table[i]))[2:].rjust(8, '0')
byts.append(int('1'+num[:7],2)) continue
num=num[7:] return bits
byts.append(int(num,2))
byts.append(8-len(num))
return byts
def shichiro_decode(byts):
def detbl(byts): bits=''.join(byts)
dec=[] dec = []
table={} table = {}
stack='' stack = ''
i=0 i = 0
while i<len(byts): c = 0
if byts[i][0]=='1': while i < len(bits) and len(bits) - i >= 8:
stack+=byts[i][1:] if c % 2 == 0:
else: dec.append(bits[i:i+8])
stack+=byts[i][int(byts[i+1],2):] i += 8
dec.append(stack[:]) c += 1
stack='' continue
i+=1 bitlen = int(bits[i:i+8], 2)
i+=1 i += 8
for i in range(0,len(dec),2): dec.append(bits[i:i+bitlen])
table[dec[i+1]]=int(dec[i],2) i += bitlen
return table c += 1
for i in range(0, len(dec), 2):
table[dec[i + 1]] = int(dec[i], 2)
return table
def compress_file(filename): def compress_file(filename):
log.log(f"Loading '{filename}'...") global log, output
with open(filename,'rb') as file: #get data log.log(f"Loading '{filename}'...")
data=list(map(int,file.read())) with open(filename, 'rb') as file: # get data
log.log(f'Original size: {len(data)} bytes.') data = list(map(int, file.read()))
log.log('Creating Huffman table...') log.log(f'Original size: {len(data)} bytes.')
hf=huffman(data) log.log('Creating Huffman table...')
table=tbl(hf) hf = huffman(data)
log.log('Embedding Huffman table...') table = shichiro_encode(hf)
out=[] log.log('Embedding Huffman table...')
ln=bin(len(table))[2:] #embed the table tablen = bin(len(table))[2:] # embed the table
while len(ln)>7: bits = ''
out.append(int('1'+ln[:7],2)) bitlen = bin(len(tablen))[2:]
ln=ln[7:] while len(bitlen) > 7:
out+=[int(ln,2),8-len(ln)]+table bits += '1' + bitlen[:7]
log.log(f'Huffman table size: {len(out)} bytes.') bitlen = bitlen[7:]
log.log('Compressing...') bits += bitlen.rjust(8, '0') + bin(len(bitlen))[2:].rjust(8, '0') + tablen + table
stack='' log.log(f'Huffman table size: {len(bits)} bits.')
for i in range(len(data)): #encode to Haffman log.log('Compressing...')
stack+=hf[data[i]] for i in range(len(data)): # encode to Haffman
while len(stack)>=8: bits += hf[data[i]]
out.append(int(stack[:8],2)) out = []
stack=stack[8:] for i in range(0, len(bits), 8):
out+=[int(stack.ljust(8,'0'),2),len(stack)] out.append(int(bits[i:i+8].ljust(8, '0'), 2))
log.log(f'Compressed size: {len(out)} bytes.') out.append(len(bits) % 8)
log.log(f"Saving to '{filename}.hfm'...") log.log(f'Compressed size: {len(out)} bytes.')
with open(f'{filename}.hfm','wb') as file: #save Haffman code log.log(f"Saving to '{filename}.hfm'...")
file.write(bytes(out)) with open(f'{filename}.hfm', 'wb') as file: # save Haffman code
log.log('SUCCESSFULLY COMPRESSED') file.write(bytes(out))
print(f'"origSize":{len(data)},') log.log('SUCCESSFULLY COMPRESSED')
print(f'"compSize":{len(out)},') output += f'"origSize":{len(data)},'
output += f'"compSize":{len(out)},'
def decompress_file(filename): def decompress_file(filename):
log.log(f"Loading '{filename}'...") global log, output
with open(filename,'rb') as file: #get data log.log(f"Loading '{filename}'...")
data=[bin(byte)[2:].rjust(8,'0')for byte in file.read()] with open(filename, 'rb') as file: # get data
os=len(data) data = [bin(byte)[2:].rjust(8, '0') for byte in file.read()]
data[-2]=data[-2][:int(data[-1],2)] os = len(data)
del data[-1] data[-2] = data[-2][:int(data[-1], 2)]
log.log('Extracting Huffman table...') del data[-1]
ln='' #extract the table log.log('Extracting Huffman table...')
i=0 bitlen = '' # extract the table
while 1: i = 0
if data[i][0]=='1': while 1:
ln+=data[i][1:] if data[i][0] == '1':
else: bitlen += data[i][1:]
ln+=data[i][int(data[i+1],2):] else:
break bitlen += data[i][int(data[i + 1], 2):]
i+=1 break
del data[:i+2] i += 1
table=detbl(data[:int(ln,2)]) del data[:i + 2]
del data[:int(ln,2)] data = ''.join(data)
data=''.join(data) bitlen = int(bitlen, 2)
stack='' tablen = int(data[:bitlen], 2)
out=[] table = shichiro_decode(data[bitlen:tablen+bitlen])
log.log('Decompressing...') data = data[bitlen+tablen:]
for c in data: #decode Haffman stack = ''
stack+=c out = []
if stack in table: log.log('Decompressing...')
out.append(int(table[stack])) for c in data: # decode Haffman
stack='' stack += c
filename=filename[:-4] if stack in table:
log.log(f"Saving to '{filename}'...") out.append(int(table[stack]))
with open(f'{filename}','wb') as file: #save decoded data stack = ''
file.write(bytes(out)) if filename[-4:] == '.hfm':
log.log(f'SUCCESSFULLY DECOMPRESSED') filename = filename[:-4]
print(f'"compSize":{os},') log.log(f"Saving to '{filename}'...")
print(f'"origSize":{len(out)},') with open(f'{filename}', 'wb') as file: # save decoded data
file.write(bytes(out))
log.log(f'SUCCESSFULLY DECOMPRESSED')
output += f'"compSize":{os},'
output += f'"origSize":{len(out)},'
@click.command(options_metavar='[-c / -d]') @click.command(options_metavar='[-c / -d]')
@click.argument('files',nargs=-1,metavar='<file [file [...]]>') @click.argument('files', nargs=-1, metavar='<file [file [...]]>')
@click.option('-c/-d','comp',default=True,help='Compress/decompress mode selectors.') @click.option('-c/-d', 'comp', default=True, help='Compress/decompress mode selectors.')
def CLI(files,comp): def CLI(files, comp):
log.log(f'hfm {"-c"*comp}{"-d"*(not comp)} {" ".join(files)}') global log, output
for file in files: log.log(f'hfm {"-c" * comp}{"-d" * (not comp)} "' + "\" \"".join(files) + '"')
print('{') for file in files:
stime=time() output += '{'
if comp: stime = time()
compress_file(path(file)) if comp:
wtime=time()-stime try:
print('"status":true,') compress_file(path(file))
print(f'"time":{round(wtime,3)},') wtime = time() - stime
print(f'"dlink":"./files/{basename(file)+".hfm"}"') output += '"status":true,'
else: output += f'"time":{round(wtime, 3)},'
try: output += f'"dlink":"./files/{url(basename(file)) + ".hfm"}"'
decompress_file(path(file)) except Exception as e:
wtime=time()-stime output += f'"status":false'
print('"status":true,') else:
print(f'"time":{round(wtime,3)},') try:
print(f'"dlink":"./files/{basename(file)[:-4]}"') decompress_file(path(file))
except Exception as e: wtime = time() - stime
print(f'"status":false') output += '"status":true,'
print('}') output += f'"time":{round(wtime, 3)},'
output += f'"dlink":"./files/{url(basename(file)[:-4])}"'
except Exception as e:
output += f'"status":false'
output += '}'
print(output)
if __name__=='__main__': if __name__ == '__main__':
CLI() CLI()

View File

@ -1,12 +1,17 @@
<?php <?php
$mode=$_POST['mode']; $mode = $_POST['mode'];
$file=$_FILES['file']; $file = $_FILES['file'];
if (!is_dir(dirname(__file__).'/files')){ if (!is_dir('./files')) {
mkdir(dirname(__file__).'/files'); mkdir('./files');
} }
$path=dirname(__file__).'/files/'.basename($file['name']); if (!file_exists('./files/counter.txt')){
move_uploaded_file($file['tmp_name'],$path); file_put_contents('./files/counter.txt', '0');
$result=json_decode((string)shell_exec('python '.dirname(__file__).'/huffman.py -'.($mode=='compress'?'c':'d').' "'.$path.'"')); }
$id = (int)file_get_contents('./files/counter.txt');
file_put_contents('./files/counter.txt', (string)($id+1));
$path = "./files/{$id}__".basename($file['name']);
move_uploaded_file($file['tmp_name'], $path);
$result = json_decode((string)shell_exec(dirname(__file__)."/huffman.py -".($mode == 'compress' ? 'c' : 'd')." \"{$path}\""));
header('Content-Type: application/json'); header('Content-Type: application/json');
echo json_encode($result); echo json_encode($result);
?> ?>

1
images/angry_huffman Normal file

File diff suppressed because one or more lines are too long

View File

Before

Width:  |  Height:  |  Size: 190 KiB

After

Width:  |  Height:  |  Size: 190 KiB

View File

Before

Width:  |  Height:  |  Size: 972 KiB

After

Width:  |  Height:  |  Size: 972 KiB

View File

@ -1,59 +1,62 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>HuffPress</title> <title>HuffPress</title>
<link rel="shortcut icon" href="favicon.ico"> <link rel="shortcut icon" href="./favicon.ico" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"> <link rel="stylesheet" href="./css/bootstrap.min.css" />
<link rel="stylesheet" href="style.css"> <link rel="stylesheet" href="./css/style.css" />
<script src="http://code.jquery.com/jquery-latest.min.js"></script> <script src="./js/jquery-3.6.0.min.js"></script>
</head> <script src="./js/console.image.min.js"></script>
<body> </head>
<header> <body>
<h1>HuffPress</h1> <header>
</header> <h1>HuffPress</h1>
<main> </header>
<h2>Compress your files with the Huffman compression!</h2> <main>
<form id="form" class="was-validated" method="post" enctype="multipart/form-data"> <h2>Compress your files with the Huffman compression!</h2>
<div class="form-group"> <form id="form" class="was-validated" method="post" enctype="multipart/form-data">
<label for="mode">Select mode</label> <div class="form-group">
<select id="mode" class="form-control" id="mode"> <label for="mode">Select mode</label>
<option value="compress">Compress</option> <select id="mode" class="form-control" id="mode">
<option value="decompress">Decompress</option> <option value="compress">Compress</option>
</select> <option value="decompress">Decompress</option>
</select>
</div>
<div class="form-group">
<div class="custom-file">
<label class="custom-file-label" for="file">Choose file...</label>
<input id="file" type="file" class="custom-file-input" required />
<div class="invalid-feedback">Let's choose your file!</div>
<div class="valid-feedback">Ready to start!</div>
</div>
</div>
<div class="form-group">
<input id="submit" type="submit" class="btn btn-primary" value="HuffPress!" />
</div>
</form>
</main>
<div class="wrap">
<div class="process">
<img src="./images/processing.gif" alt="Processing..." />
</div> </div>
<div class="form-group"> <div class="complete">
<div class="custom-file"> <h3>Completed!</h3>
<label class="custom-file-label" for="file">Choose file...</label> <p class="status"></p>
<input id="file" type="file" class="custom-file-input" required> <div class="btncont">
<div class="invalid-feedback">Let's choose your file!</div> <a id="dlink" class="btn btn-primary" href="" download>Download</a>
<div class="valid-feedback">Ready to start!</div> <button class="btn closebtn">Close</button>
</div> </div>
</div> </div>
<div class="form-group"> <div class="error">
<input id="submit" type="submit" class="btn btn-primary" value="HuffPress!"> <h3>Error!</h3>
</div> <p class="status">Something went wrong!</p>
</form> <div class="btncont">
</main> <button class="btn closebtn">Close</button>
<div class="wrap"> </div>
<div class="process"><img src="processing.gif" alt="Processing..."></div>
<div class="complete">
<h3>Completed!</h3>
<p class="status"></p>
<div class="btncont">
<a id="dlink" class="btn btn-primary" href="" download>Download</a>
<button class="btn closebtn">Close</button>
</div> </div>
</div> </div>
<div class="error"> <script src="./js/script.js"></script>
<h3>Error!</h3> </body>
<p class="status">Unable to decompress this file!</p>
<div class="btncont">
<button class="btn closebtn">Close</button>
</div>
</div>
</div>
<script src="script.js"></script>
</body>
</html> </html>

4
js/console.image.min.js vendored Normal file

File diff suppressed because one or more lines are too long

2
js/jquery-3.6.0.min.js vendored Normal file

File diff suppressed because one or more lines are too long

106
js/script.js Normal file
View File

@ -0,0 +1,106 @@
function winsize() {
if (
(!toggled && $(window).width() / $(window).height() > 90/31) ||
(toggled && $(window).width() / ($(window).height()-219) > 18/7)
) {
$('body').css('justify-content', 'flex-start');
} else {
$('body').css('justify-content', 'center');
}
};
$(window).on('load', function () {
setTimeout(() => {
$('main').slideDown(500);
}, 100);
winsize();
});
$(window).on('resize', function () {
winsize();
});
var toggled = false;
$('h2').click(function () {
var time = 300;
if (toggled) {
$('form').slideUp(time);
$('main').css('min-height', '9vw');
setTimeout(() => {
$('h2').css('border-bottom', '0');
}, time);
toggled = false;
winsize();
} else {
$('main').css('min-height', 'calc(9vw + 260px)');
$('form').slideDown(time);
$('form').css('display', 'flex');
$('h2').css('border-bottom', '1px solid black');
toggled = true;
setTimeout(() => {
winsize();
}, time);
};
});
$('form').on('submit', function submit(e) {
e.preventDefault();
$('.wrap').css('display', 'flex');
$('.process').css('display', 'block');
var form = new FormData();
form.append('mode', $('#mode').val());
$.each($('#file')[0].files, function (i, file) {
form.append('file', file);
});
$.ajax({
url: 'huffpress.php',
type: 'POST',
processData: false,
contentType: false,
dataType: 'json',
data: form,
success: function (resp) {
if (resp === null) {
$('.process').css('display', 'none');
$('.error').css('display', 'block');
} else if (resp.status) {
$('.process').css('display', 'none');
$('.complete').css('display', 'block');
if ($('#mode').val() == 'compress') {
$('.complete .status').html(
`Original size:&nbsp;&nbsp;&nbsp;${resp.origSize} B<br>Compressed size: ${resp.compSize} B<br>Time:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;${resp.time} s`
);
} else {
$('.complete .status').html(
`Compressed size: ${resp.compSize} B<br>Original size:&nbsp;&nbsp;&nbsp;${resp.origSize} B<br>Time:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;${resp.time} s`
);
}
$('#dlink').attr('href', resp.dlink);
} else {
$('.process').css('display', 'none');
$('.error').css('display', 'block');
};
},
});
});
$('.closebtn').click(function () {
$('.wrap').css('display', 'none');
$('.process').css('display', 'none');
$('.error').css('display', 'none');
$('.complete').css('display', 'none');
});
$(window).on('load', function() {
let msg = 'И что это мы тут забыли?\nА ну кыш отседова!\nНашлись тут кулхацкеры понимаешь!';
let style = [
'padding: 1rem;',
'font-family: monospace;',
'font-size: 18pt;',
].join('');
console.log('%c%s', style, msg);
$.ajax({
url: './images/angry_huffman',
success: function(data) {
console.image(data);
},
});
});

View File

@ -1,76 +0,0 @@
function winsize(){
if (!toggled && $(window).width()/$(window).height()>(90/31) ||
toggled && $(window).width()/($(window).height()-219)>(18/7)){
$('body').css('justify-content','flex-start');
} else {
$('body').css('justify-content','center');
}
};
window.onload=function(){
setTimeout(()=>{$('main').slideDown(500)},100);
winsize();
};
$(window).on('resize',function(){
winsize();
});
var toggled=false;
$('h2').click(function(){
var time=300;
if (toggled) {
$('form').slideUp(time);
$('main').css('min-height','9vw');
setTimeout(()=>{$('h2').css('border-bottom','0')},time);
toggled=false;
winsize();
} else {
$('main').css('min-height','calc(9vw + 260px)');
$('form').slideDown(time);
$('form').css('display','flex');
$('h2').css('border-bottom','1px solid black');
toggled=true;
setTimeout(()=>{winsize()},time);
}
});
$('form').on('submit',function submit(e){
e.preventDefault();
$('.wrap').css('display','flex');
$('.process').css('display','block');
var form=new FormData();
form.append('mode',$('#mode').val());
$.each($('#file')[0].files, function(i, file) {
form.append('file', file);
});
$.ajax({
url: 'huffpress.php',
type: 'POST',
processData: false,
contentType: false,
dataType: 'json',
data: form,
success: function(resp){
console.log(resp);
if (resp.status){
$('.process').css('display','none');
$('.complete').css('display','block');
if ($('#mode').val()=='compress'){
$('.complete .status').html(`Original size:&nbsp;&nbsp;&nbsp;${resp.origSize} B<br>Compressed size: ${resp.compSize} B<br>Time:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;${resp.time} s`);
} else {
$('.complete .status').html(`Compressed size: ${resp.compSize} B<br>Original size:&nbsp;&nbsp;&nbsp;${resp.origSize} B<br>Time:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;${resp.time} s`);
}
$('#dlink').attr('href',resp.dlink);
} else {
$('.process').css('display','none');
$('.error').css('display','block');
}
}
});
});
$('.closebtn').click(function(){
$('.wrap').css('display','none');
$('.process').css('display','none');
$('.error').css('display','none');
$('.complete').css('display','none');
});