Compare commits
No commits in common. "d1462470b17712ad2da1cbe075f1209e20980559" and "a228f94dd0d6daa10b5b31d1ff8cde443a254ceb" have entirely different histories.
d1462470b1
...
a228f94dd0
14
README.md
14
README.md
@ -2,21 +2,15 @@
|
|||||||
|
|
||||||
## What's up?
|
## What's up?
|
||||||
|
|
||||||
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').
|
Hey! This is a simple web-service called . 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
|
||||||
- 
|
- 
|
||||||
- 
|
- 
|
||||||
- `click` python library
|
- `click` library
|
||||||
|
|
||||||
## So, how do I use it?
|
## So, how do I use it?
|
||||||
|
|
||||||
I think the usage is too easy to explain it, but anyway here's [a video guide](https://yadi.sk/i/aiy78bDaoKqoJQ 'Watch!').
|
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!").
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<p align=center><i>© Masahiko AMANO a.k.a. H1K0, 2020-2021</i></p>
|
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 190 KiB After Width: | Height: | Size: 190 KiB |
7
css/bootstrap.min.css
vendored
7
css/bootstrap.min.css
vendored
File diff suppressed because one or more lines are too long
130
huffman.py
130
huffman.py
@ -2,8 +2,6 @@ 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):
|
||||||
@ -22,9 +20,7 @@ class Log:
|
|||||||
' | '
|
' | '
|
||||||
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):
|
||||||
@ -34,8 +30,7 @@ def huffman(data):
|
|||||||
units[c]+=1
|
units[c]+=1
|
||||||
else:
|
else:
|
||||||
units[c]=1
|
units[c]=1
|
||||||
codes = dict.fromkeys(units.keys(), '')
|
units,codes=sorted([([u],units[u]) for u in units],key=lambda u:u[1]),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:
|
||||||
@ -56,79 +51,78 @@ def huffman(data):
|
|||||||
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')
|
|
||||||
bits += code
|
|
||||||
else:
|
else:
|
||||||
bits += bin(int(table[i]))[2:].rjust(8, '0')
|
num=bin(int(table[i]))[2:]
|
||||||
continue
|
while len(num)>7:
|
||||||
return bits
|
byts.append(int('1'+num[:7],2))
|
||||||
|
num=num[7:]
|
||||||
|
byts.append(int(num,2))
|
||||||
|
byts.append(8-len(num))
|
||||||
|
return byts
|
||||||
|
|
||||||
|
|
||||||
def shichiro_decode(byts):
|
|
||||||
bits=''.join(byts)
|
def detbl(byts):
|
||||||
dec=[]
|
dec=[]
|
||||||
table={}
|
table={}
|
||||||
stack=''
|
stack=''
|
||||||
i=0
|
i=0
|
||||||
c = 0
|
while i<len(byts):
|
||||||
while i < len(bits) and len(bits) - i >= 8:
|
if byts[i][0]=='1':
|
||||||
if c % 2 == 0:
|
stack+=byts[i][1:]
|
||||||
dec.append(bits[i:i+8])
|
else:
|
||||||
i += 8
|
stack+=byts[i][int(byts[i+1],2):]
|
||||||
c += 1
|
dec.append(stack[:])
|
||||||
continue
|
stack=''
|
||||||
bitlen = int(bits[i:i+8], 2)
|
i+=1
|
||||||
i += 8
|
i+=1
|
||||||
dec.append(bits[i:i+bitlen])
|
|
||||||
i += bitlen
|
|
||||||
c += 1
|
|
||||||
for i in range(0,len(dec),2):
|
for i in range(0,len(dec),2):
|
||||||
table[dec[i+1]]=int(dec[i],2)
|
table[dec[i+1]]=int(dec[i],2)
|
||||||
return table
|
return table
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def compress_file(filename):
|
def compress_file(filename):
|
||||||
global log, output
|
|
||||||
log.log(f"Loading '{filename}'...")
|
log.log(f"Loading '{filename}'...")
|
||||||
with open(filename,'rb') as file: #get data
|
with open(filename,'rb') as file: #get data
|
||||||
data=list(map(int,file.read()))
|
data=list(map(int,file.read()))
|
||||||
log.log(f'Original size: {len(data)} bytes.')
|
log.log(f'Original size: {len(data)} bytes.')
|
||||||
log.log('Creating Huffman table...')
|
log.log('Creating Huffman table...')
|
||||||
hf=huffman(data)
|
hf=huffman(data)
|
||||||
table = shichiro_encode(hf)
|
table=tbl(hf)
|
||||||
log.log('Embedding Huffman table...')
|
log.log('Embedding Huffman table...')
|
||||||
tablen = bin(len(table))[2:] # embed the table
|
|
||||||
bits = ''
|
|
||||||
bitlen = bin(len(tablen))[2:]
|
|
||||||
while len(bitlen) > 7:
|
|
||||||
bits += '1' + bitlen[:7]
|
|
||||||
bitlen = bitlen[7:]
|
|
||||||
bits += bitlen.rjust(8, '0') + bin(len(bitlen))[2:].rjust(8, '0') + tablen + table
|
|
||||||
log.log(f'Huffman table size: {len(bits)} bits.')
|
|
||||||
log.log('Compressing...')
|
|
||||||
for i in range(len(data)): # encode to Haffman
|
|
||||||
bits += hf[data[i]]
|
|
||||||
out=[]
|
out=[]
|
||||||
for i in range(0, len(bits), 8):
|
ln=bin(len(table))[2:] #embed the table
|
||||||
out.append(int(bits[i:i+8].ljust(8, '0'), 2))
|
while len(ln)>7:
|
||||||
out.append(len(bits) % 8)
|
out.append(int('1'+ln[:7],2))
|
||||||
|
ln=ln[7:]
|
||||||
|
out+=[int(ln,2),8-len(ln)]+table
|
||||||
|
log.log(f'Huffman table size: {len(out)} bytes.')
|
||||||
|
log.log('Compressing...')
|
||||||
|
stack=''
|
||||||
|
for i in range(len(data)): #encode to Haffman
|
||||||
|
stack+=hf[data[i]]
|
||||||
|
while len(stack)>=8:
|
||||||
|
out.append(int(stack[:8],2))
|
||||||
|
stack=stack[8:]
|
||||||
|
out+=[int(stack.ljust(8,'0'),2),len(stack)]
|
||||||
log.log(f'Compressed size: {len(out)} bytes.')
|
log.log(f'Compressed size: {len(out)} bytes.')
|
||||||
log.log(f"Saving to '{filename}.hfm'...")
|
log.log(f"Saving to '{filename}.hfm'...")
|
||||||
with open(f'{filename}.hfm','wb') as file: #save Haffman code
|
with open(f'{filename}.hfm','wb') as file: #save Haffman code
|
||||||
file.write(bytes(out))
|
file.write(bytes(out))
|
||||||
log.log('SUCCESSFULLY COMPRESSED')
|
log.log('SUCCESSFULLY COMPRESSED')
|
||||||
output += f'"origSize":{len(data)},'
|
print(f'"origSize":{len(data)},')
|
||||||
output += f'"compSize":{len(out)},'
|
print(f'"compSize":{len(out)},')
|
||||||
|
|
||||||
|
|
||||||
def decompress_file(filename):
|
def decompress_file(filename):
|
||||||
global log, output
|
|
||||||
log.log(f"Loading '{filename}'...")
|
log.log(f"Loading '{filename}'...")
|
||||||
with open(filename,'rb') as file: #get data
|
with open(filename,'rb') as file: #get data
|
||||||
data=[bin(byte)[2:].rjust(8,'0')for byte in file.read()]
|
data=[bin(byte)[2:].rjust(8,'0')for byte in file.read()]
|
||||||
@ -136,21 +130,19 @@ def decompress_file(filename):
|
|||||||
data[-2]=data[-2][:int(data[-1],2)]
|
data[-2]=data[-2][:int(data[-1],2)]
|
||||||
del data[-1]
|
del data[-1]
|
||||||
log.log('Extracting Huffman table...')
|
log.log('Extracting Huffman table...')
|
||||||
bitlen = '' # extract the table
|
ln='' #extract the table
|
||||||
i=0
|
i=0
|
||||||
while 1:
|
while 1:
|
||||||
if data[i][0]=='1':
|
if data[i][0]=='1':
|
||||||
bitlen += data[i][1:]
|
ln+=data[i][1:]
|
||||||
else:
|
else:
|
||||||
bitlen += data[i][int(data[i + 1], 2):]
|
ln+=data[i][int(data[i+1],2):]
|
||||||
break
|
break
|
||||||
i+=1
|
i+=1
|
||||||
del data[:i+2]
|
del data[:i+2]
|
||||||
|
table=detbl(data[:int(ln,2)])
|
||||||
|
del data[:int(ln,2)]
|
||||||
data=''.join(data)
|
data=''.join(data)
|
||||||
bitlen = int(bitlen, 2)
|
|
||||||
tablen = int(data[:bitlen], 2)
|
|
||||||
table = shichiro_decode(data[bitlen:tablen+bitlen])
|
|
||||||
data = data[bitlen+tablen:]
|
|
||||||
stack=''
|
stack=''
|
||||||
out=[]
|
out=[]
|
||||||
log.log('Decompressing...')
|
log.log('Decompressing...')
|
||||||
@ -159,45 +151,39 @@ def decompress_file(filename):
|
|||||||
if stack in table:
|
if stack in table:
|
||||||
out.append(int(table[stack]))
|
out.append(int(table[stack]))
|
||||||
stack=''
|
stack=''
|
||||||
if filename[-4:] == '.hfm':
|
|
||||||
filename=filename[:-4]
|
filename=filename[:-4]
|
||||||
log.log(f"Saving to '{filename}'...")
|
log.log(f"Saving to '{filename}'...")
|
||||||
with open(f'{filename}','wb') as file: #save decoded data
|
with open(f'{filename}','wb') as file: #save decoded data
|
||||||
file.write(bytes(out))
|
file.write(bytes(out))
|
||||||
log.log(f'SUCCESSFULLY DECOMPRESSED')
|
log.log(f'SUCCESSFULLY DECOMPRESSED')
|
||||||
output += f'"compSize":{os},'
|
print(f'"compSize":{os},')
|
||||||
output += f'"origSize":{len(out)},'
|
print(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):
|
||||||
global log, output
|
log.log(f'hfm {"-c"*comp}{"-d"*(not comp)} {" ".join(files)}')
|
||||||
log.log(f'hfm {"-c" * comp}{"-d" * (not comp)} "' + "\" \"".join(files) + '"')
|
|
||||||
for file in files:
|
for file in files:
|
||||||
output += '{'
|
print('{')
|
||||||
stime=time()
|
stime=time()
|
||||||
if comp:
|
if comp:
|
||||||
try:
|
|
||||||
compress_file(path(file))
|
compress_file(path(file))
|
||||||
wtime=time()-stime
|
wtime=time()-stime
|
||||||
output += '"status":true,'
|
print('"status":true,')
|
||||||
output += f'"time":{round(wtime, 3)},'
|
print(f'"time":{round(wtime,3)},')
|
||||||
output += f'"dlink":"./files/{url(basename(file)) + ".hfm"}"'
|
print(f'"dlink":"./files/{basename(file)+".hfm"}"')
|
||||||
except Exception as e:
|
|
||||||
output += f'"status":false'
|
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
decompress_file(path(file))
|
decompress_file(path(file))
|
||||||
wtime=time()-stime
|
wtime=time()-stime
|
||||||
output += '"status":true,'
|
print('"status":true,')
|
||||||
output += f'"time":{round(wtime, 3)},'
|
print(f'"time":{round(wtime,3)},')
|
||||||
output += f'"dlink":"./files/{url(basename(file)[:-4])}"'
|
print(f'"dlink":"./files/{basename(file)[:-4]}"')
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
output += f'"status":false'
|
print(f'"status":false')
|
||||||
output += '}'
|
print('}')
|
||||||
print(output)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__=='__main__':
|
if __name__=='__main__':
|
||||||
|
|||||||
@ -1,17 +1,12 @@
|
|||||||
<?php
|
<?php
|
||||||
$mode=$_POST['mode'];
|
$mode=$_POST['mode'];
|
||||||
$file=$_FILES['file'];
|
$file=$_FILES['file'];
|
||||||
if (!is_dir('./files')) {
|
if (!is_dir(dirname(__file__).'/files')){
|
||||||
mkdir('./files');
|
mkdir(dirname(__file__).'/files');
|
||||||
}
|
}
|
||||||
if (!file_exists('./files/counter.txt')){
|
$path=dirname(__file__).'/files/'.basename($file['name']);
|
||||||
file_put_contents('./files/counter.txt', '0');
|
|
||||||
}
|
|
||||||
$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);
|
move_uploaded_file($file['tmp_name'],$path);
|
||||||
$result = json_decode((string)shell_exec(dirname(__file__)."/huffman.py -".($mode == 'compress' ? 'c' : 'd')." \"{$path}\""));
|
$result=json_decode((string)shell_exec('python '.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);
|
||||||
?>
|
?>
|
||||||
File diff suppressed because one or more lines are too long
25
index.html
25
index.html
@ -1,14 +1,13 @@
|
|||||||
<!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="./css/bootstrap.min.css" />
|
<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/style.css" />
|
<link rel="stylesheet" href="style.css">
|
||||||
<script src="./js/jquery-3.6.0.min.js"></script>
|
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
|
||||||
<script src="./js/console.image.min.js"></script>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
@ -27,20 +26,18 @@
|
|||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="custom-file">
|
<div class="custom-file">
|
||||||
<label class="custom-file-label" for="file">Choose file...</label>
|
<label class="custom-file-label" for="file">Choose file...</label>
|
||||||
<input id="file" type="file" class="custom-file-input" required />
|
<input id="file" type="file" class="custom-file-input" required>
|
||||||
<div class="invalid-feedback">Let's choose your file!</div>
|
<div class="invalid-feedback">Let's choose your file!</div>
|
||||||
<div class="valid-feedback">Ready to start!</div>
|
<div class="valid-feedback">Ready to start!</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<input id="submit" type="submit" class="btn btn-primary" value="HuffPress!" />
|
<input id="submit" type="submit" class="btn btn-primary" value="HuffPress!">
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</main>
|
</main>
|
||||||
<div class="wrap">
|
<div class="wrap">
|
||||||
<div class="process">
|
<div class="process"><img src="processing.gif" alt="Processing..."></div>
|
||||||
<img src="./images/processing.gif" alt="Processing..." />
|
|
||||||
</div>
|
|
||||||
<div class="complete">
|
<div class="complete">
|
||||||
<h3>Completed!</h3>
|
<h3>Completed!</h3>
|
||||||
<p class="status"></p>
|
<p class="status"></p>
|
||||||
@ -51,12 +48,12 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="error">
|
<div class="error">
|
||||||
<h3>Error!</h3>
|
<h3>Error!</h3>
|
||||||
<p class="status">Something went wrong!</p>
|
<p class="status">Unable to decompress this file!</p>
|
||||||
<div class="btncont">
|
<div class="btncont">
|
||||||
<button class="btn closebtn">Close</button>
|
<button class="btn closebtn">Close</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script src="./js/script.js"></script>
|
<script src="script.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
4
js/console.image.min.js
vendored
4
js/console.image.min.js
vendored
File diff suppressed because one or more lines are too long
2
js/jquery-3.6.0.min.js
vendored
2
js/jquery-3.6.0.min.js
vendored
File diff suppressed because one or more lines are too long
106
js/script.js
106
js/script.js
@ -1,106 +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).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: ${resp.origSize} B<br>Compressed size: ${resp.compSize} B<br>Time: ${resp.time} s`
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
$('.complete .status').html(
|
|
||||||
`Compressed size: ${resp.compSize} B<br>Original size: ${resp.origSize} B<br>Time: ${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);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
Before Width: | Height: | Size: 972 KiB After Width: | Height: | Size: 972 KiB |
76
script.js
Normal file
76
script.js
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
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: ${resp.origSize} B<br>Compressed size: ${resp.compSize} B<br>Time: ${resp.time} s`);
|
||||||
|
} else {
|
||||||
|
$('.complete .status').html(`Compressed size: ${resp.compSize} B<br>Original size: ${resp.origSize} B<br>Time: ${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');
|
||||||
|
});
|
||||||
@ -1,6 +1,5 @@
|
|||||||
@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,
|
html,body{
|
||||||
body {
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@ -16,7 +15,7 @@ body {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
background-image: url(../images/bg.webp);
|
background-image: url(bg.webp);
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
}
|
}
|
||||||
header{
|
header{
|
||||||
@ -38,10 +37,10 @@ main {
|
|||||||
display: none;
|
display: none;
|
||||||
margin-bottom: 2vw;
|
margin-bottom: 2vw;
|
||||||
background-color: #fff8;
|
background-color: #fff8;
|
||||||
box-shadow: 0 0 0.5vw black;
|
box-shadow: 0 0 .5vw black;
|
||||||
border-radius: 1.5vw;
|
border-radius: 1.5vw;
|
||||||
min-height: 9vw;
|
min-height: 9vw;
|
||||||
transition: 0.3s;
|
transition: .3s;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
main:hover{
|
main:hover{
|
||||||
@ -56,11 +55,11 @@ 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%, 0.6);
|
background-color: hsla(270,80%,80%,.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 0.5px white;
|
text-shadow: 2.5px 2px .5px white;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
form{
|
form{
|
||||||
@ -84,9 +83,7 @@ form {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
}
|
}
|
||||||
.process,
|
.process,.complete,.error{
|
||||||
.complete,
|
|
||||||
.error {
|
|
||||||
display: none;
|
display: none;
|
||||||
padding: 2vw 5vw;
|
padding: 2vw 5vw;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
@ -100,13 +97,13 @@ form {
|
|||||||
}
|
}
|
||||||
h3{
|
h3{
|
||||||
margin: 0;
|
margin: 0;
|
||||||
margin-top: 0.5vw;
|
margin-top: .5vw;
|
||||||
font-family: Secular One;
|
font-family: Secular One;
|
||||||
font-size: 3vw;
|
font-size: 3vw;
|
||||||
}
|
}
|
||||||
.status{
|
.status{
|
||||||
margin: 0;
|
margin: 0;
|
||||||
margin-top: 0.5vw;
|
margin-top: .5vw;
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
font-size: 1.5vw;
|
font-size: 1.5vw;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user