Skip to content

Commit

Permalink
minify and organize
Browse files Browse the repository at this point in the history
  • Loading branch information
DenysPacheco committed Jan 26, 2022
1 parent f857b53 commit 35d3758
Show file tree
Hide file tree
Showing 17 changed files with 193 additions and 222 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.vscode
.pytest_cache
test.py
__pycache__
16 changes: 11 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
# Css Hashfy Converter
# Css Hashfy Minify Converter

This is a python script to hashfy css classes.
It was inspired on Google's approach to minimize classes names to faster load web pages.

## What it does

- [x] Make a hash out of css and id classes
- [x] Make a random hash each run
- [x] Minify your css
- [x] Auto apply for all the html files
- [x] Create `-hashed` file with the output
- [x] Auto change the css file to `-hashed` in the html link tag
- [x] Multiple files on multiple folders
- [x] Auto change the css file names to `-hashed` in the html link tag
- [x] Multiple files on multiple folders (top-down)

## Usage

Expand All @@ -19,10 +21,14 @@ It will search all files with the extensions marked on the configuration file.

It will give the output with `foo-hashed.html` and `foo-hashed.css`.


### Configure

Change in the [configuration file](/config.json) the directories to be ignored, hash length and overwrite files.

## To Change?
**Mind that: if `overwrite` is `false` the hash will not be equal to the old files, therefore not in sync.**

## What to come

- [ ] Separation of classes and ids in prefix
- [ ] Obfuscate everything?
- [ ] How about js too?
8 changes: 5 additions & 3 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,17 @@
"filesIgnore": [
"-hashed"
],
"dirsIgnore":[
"dirsIgnore": [
".",
"packages",
"src",
"dist"
],
"extCopy": "-hashed",
"patternCSS": "[\\.\\#]-?[_a-zA-Z]+[_a-zA-Z0-9-]*\\s*\\{",
"patternCSS": "[\\.\\#]-?([_a-zA-Z]+[_a-zA-Z0-9-]*)\\s*\\{",
"patternHTML": "class[\t]*=[\t]*\"[^\"]+",
"hashLength": 6,
"overwriteFiles": false
"overwriteFiles": false,
"minimize": true,
"output": true
}
144 changes: 17 additions & 127 deletions convert.py
Original file line number Diff line number Diff line change
@@ -1,145 +1,35 @@
import os
import json
import re
from os import listdir
from os.path import isfile, join
from functions import *

config, _PATH = loadconfig()

def read(file):
with open(file, 'r') as f:
lines = f.readlines()
f.close()
return lines


def write(root, new_name, lines):
with open(os.path.join(root, new_name), 'w') as exf:
exf.writelines(lines)
exf.close()


def getVars(file, config):
# Get the extension and use as a flag e.g.: HTML, CSS...
pattern_file = file.split('.')[1].upper()

lines = read(file)

# Use the right regex to find the classes on the file
substring = re.findall(config['pattern' + pattern_file], str(lines))

name, ext = file.split('.')
new_name = name + config['extCopy'] + '.' + ext

return new_name, substring
search_files = lookfiles()


def main():
# Load config.json
with open("config.json") as json_data_file:
config = json.load(json_data_file)
_PATH = os.getcwd() + '/'

search_files = []
# Look for files
for root, subdirectories, files in os.walk(_PATH):
# Comprehension to break outter loop
if any([dirsIgnore for dirsIgnore in config['dirsIgnore'] if dirsIgnore in root]):
continue
search_files = lookfiles()

# And all its files
for index, file in enumerate(files):
for filesSearch in config['filesSearch']:
for filesIgnore in config['filesIgnore']:
if(filesSearch in file and filesIgnore not in file):
search_files.append((root, file))
if(config['output']):

#print(f'files: {search_files}\n')
#print(f'files: {search_files}\n')

print('CSS Hashfy found files:', end='\n\n')
for root, file in search_files:
print(os.path.join(root, file))
print()
print('CSS Hashfy found files:', end='\n\n')
for root, file in search_files:
print(os.path.join(root, file))
print()

print('Starting hashing...', end='\n\n')
print('Starting hashing...', end='\n\n')

# Initializing alg vars
count = 0
classes_dict = {}

# Get all the files with the '.css' extension
css_files = [(root, file)
for root, file in search_files if file.endswith('.css')]

# Copy the files of the search
for root, file in css_files:
lines = read(os.path.join(root, file))

new_name, substring = getVars(os.path.join(root, file), config)

# If the file doesn't exist, create a new one
if(config['overwriteFiles'] or not isfile(join(root, new_name))):
substring = [s.translate({ord('.'): None, ord(
'{'): None, ord('#'): None}).strip() for s in substring]

# Create the dictionary with the classe's hashes of the CSS
classes_dict.update(
{s: str(abs(hash(s)) % (10 ** config['hashLength'])) for s in substring})

# CSS WRITE

# Copy the hashes to the copied lines of the file
for index, l in enumerate(lines):
for k, v in classes_dict.items():
if k in l:
l = l.replace(k, 'c'+v)
lines[index] = l

write(root, new_name, lines)
count += 1
print(f"{10*'*'} \t {new_name.split('/')[-1]} \t {10*'*'}")

# If it exists, pass
else:
print(f'!! file already existed: {new_name}')

# Overwrite HTML classes
html_files = [(root, file)
for root, file in search_files if file.endswith('.html')]

# Copy the files of the search
for root, file in html_files:
lines = read(os.path.join(root, file))

new_name, substring = getVars(os.path.join(root, file), config)

# HTML WRITE

# HTML overwrite link tags
if(config['overwriteFiles'] or not isfile(join(root, new_name))):
for index, l in enumerate(lines):
for root, file in css_files:
if file in l and 'link' in l:
l = l.replace(
file, f"{file.split('.')[0]}{config['extCopy']}.css")
lines[index] = l

# Overwrite html lines with the hashed css classes
for index, l in enumerate(lines):
for k, v in classes_dict.items():
if k in l:
l = l.replace(k, 'c'+v)
lines[index] = l
classes_dict, css_files, css_count = csshash(search_files)

write(root, new_name, lines)
count += 1
print(f"{10*'*'} \t {new_name.split('/')[-1]} \t {10*'*'}")
html_count = htmlhash(search_files, classes_dict, css_files)

# If it exists, pass
else:
print(f'!! file already existed: {new_name}')
if(config['output']):

print()
print(f'finished! {str(int(count/len(search_files))*100)}% done.')
print()
print(
f'finished! {str(int((html_count + css_count)/len(search_files))*100)}% done.')


main()
4 changes: 0 additions & 4 deletions css/newstyle-hashed.css

This file was deleted.

1 change: 1 addition & 0 deletions examples/css/newstyle-hashed.css
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.c472338{color:black;background-color:aqua;}
File renamed without changes.
1 change: 1 addition & 0 deletions examples/htmls/another-hashed.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metahttp-equiv="X-UA-Compatible"content="IE=edge"><metaname="viewport"content="width=device-width,initial-scale=1.0"><linkhref="/style-hashed.css"rel="stylesheet"><linkhref="/css/newstyle-hashed.css"rel="stylesheet"><linkrel="stylesheet"href="https://use.fontawesome.com/releases/v5.13.0/css/all.css"integrity="sha384-Bfad6CLCknfcloXFOyFnlgtENryhrpZCe29RTifKEixXQZ38WheV+i/6YWSzkz3V"crossorigin="anonymous"/><title>Document</title></head><body><divclass="c472338c892938c472338"><p>AnotherTestofhtml</p></div></body></html>
File renamed without changes.
1 change: 1 addition & 0 deletions examples/index-hashed.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metahttp-equiv="X-UA-Compatible"content="IE=edge"><metaname="viewport"content="width=device-width,initial-scale=1.0"><linkhref="/style-hashed.css"rel="stylesheet"><linkrel="stylesheet"href="https://use.fontawesome.com/releases/v5.13.0/css/all.css"integrity="sha384-Bfad6CLCknfcloXFOyFnlgtENryhrpZCe29RTifKEixXQZ38WheV+i/6YWSzkz3V"crossorigin="anonymous"/><title>Document</title></head><body><divclass="c892938c328534"><pclass="c65182">Thisisatextofahtml</p></div><divclass="c892938"><divclass="c65182"><spanclass="c209394">testofanotherkind</span></div></div><divid="c627821"><!--Itdoesn'tchangethecndfiles--><ulclass="fa-ul"><li><iclass="fa-lifafa-check-square"></i>Listicons</li><li><iclass="fa-lifafa-check-square"></i>canbeused</li><li><iclass="fa-lifafa-spinnerfa-spin"></i>asbullets</li><li><iclass="fa-lifafa-square"></i>inlists</li></ul></div></body></html>
File renamed without changes.
1 change: 1 addition & 0 deletions examples/style-hashed.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

File renamed without changes.

0 comments on commit 35d3758

Please sign in to comment.