Copied to Clipboard
Project Avatar

Social Tech

A school project made to solve a real-world problem from one of participating company's. The best solution would then be …

View on GitHub

Social Tech

Social Tech is a school project made to solve a real-world problem from one of the participating companies. The best solution would then be used by the business.

We developed a WebApp for SMILE Business Solutions, the webapp was made to streamline their business and help improve the way they worked with their clients.

SMILE is a life coaching company that helps other SME Businesses and individuals improve their lives by identifying problems and setting goals to alleviate these issues. The coach would then meet on a regular basis to check up on the client and record the progress made towards their goals and offer advice and suggestions along the way.

Our WebApp got rid of their need for pen and paper and the issues of scheduling in-person meetings (which were oftern cancelled), as they could now do everything online in one place. The coach would be able to check on their progress and message the client.

We attempted to make a friendly themed site and decided going with a natured themed site

Project Overview

There are 3 main parts this project was split up into:

Database - PostgreSQL API - ExpressJS WebApp - Angular

I did the work on WebApp part while my other 2 team-mates worked on the database and API respectavly

The project is also Hosted on Heroku!
Check it out

User: smile@dev-api.ru
Password: password

Web Preview

Also made to work on mobile devices

Also created a fully functioning dashboard for administrators

Project Avatar

Hiragana Handwriting Classifier

None

View on GitHub

Hiragana Handwritting Recognition

Using p5.js and my own custom implementation of the knearest algorithm to guess what Hiragana letter you drew

Made just for fun and to help learn the alphabet

Project Avatar

Scripts

None

Pic to Asscii

Made my own simple implementation converting an image to asscii

Copy to Clipboard
"""
Pic to Asscii
Made my own simple implementation converting an image to asscii
"""
import sys, random, argparse 
import numpy as np 
import math 
  
from PIL import Image 
  
# gray scale level values from:  
# http://paulbourke.net/dataformats/asciiart/ 
  
# 70 levels of gray 
gscale1 = "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. "
  
# 10 levels of gray 
gscale2 = '@%#*+=-:. '
  
def getAverageL(image): 
  
    """ 
    Given PIL Image, return average value of grayscale value 
    """
    # get image as numpy array 
    im = np.array(image) 
  
    # get shape 
    w,h = im.shape 
  
    # get average 
    return np.average(im.reshape(w*h)) 
  
def covertImageToAscii(fileName, cols, scale, moreLevels): 
    """ 
    Given Image and dims (rows, cols) returns an m*n list of Images  
    """
    # declare globals 
    global gscale1, gscale2 
  
    # open image and convert to grayscale 
    image = Image.open(fileName).convert('L') 
  
    # store dimensions 
    W, H = image.size[0], image.size[1] 
    print("input image dims: %d x %d" % (W, H)) 
  
    # compute width of tile 
    w = W/cols 
  
    # compute tile height based on aspect ratio and scale 
    h = w/scale 
  
    # compute number of rows 
    rows = int(H/h) 
      
    print("cols: %d, rows: %d" % (cols, rows)) 
    print("tile dims: %d x %d" % (w, h)) 
  
    # check if image size is too small 
    if cols > W or rows > H: 
        print("Image too small for specified cols!") 
        exit(0) 
  
    # ascii image is a list of character strings 
    aimg = [] 
    # generate list of dimensions 
    for j in range(rows): 
        y1 = int(j*h) 
        y2 = int((j+1)*h) 
  
        # correct last tile 
        if j == rows-1: 
            y2 = H 
  
        # append an empty string 
        aimg.append("") 
  
        for i in range(cols): 
  
            # crop image to tile 
            x1 = int(i*w) 
            x2 = int((i+1)*w) 
  
            # correct last tile 
            if i == cols-1: 
                x2 = W 
  
            # crop image to extract tile 
            img = image.crop((x1, y1, x2, y2)) 
  
            # get average luminance 
            avg = int(getAverageL(img)) 
  
            # look up ascii char 
            if moreLevels: 
                gsval = gscale1[int((avg*69)/255)] 
            else: 
                gsval = gscale2[int((avg*9)/255)] 
  
            # append ascii char to string 
            aimg[j] += gsval 
      
    # return txt image 
    return aimg 
  
# main() function 
def main(): 
    # create parser 
    descStr = "This program converts an image into ASCII art."
    parser = argparse.ArgumentParser(description=descStr) 
    # add expected arguments 
    parser.add_argument('--file', dest='imgFile', required=True) 
    parser.add_argument('--scale', dest='scale', required=False) 
    parser.add_argument('--out', dest='outFile', required=False) 
    parser.add_argument('--cols', dest='cols', required=False) 
    parser.add_argument('--morelevels',dest='moreLevels',action='store_true') 
  
    # parse args 
    args = parser.parse_args() 
    
    imgFile = args.imgFile 
  
    # set output file 
    outFile = 'out.txt'
    if args.outFile: 
        outFile = args.outFile 
  
    # set scale default as 0.43 which suits 
    # a Courier font 
    scale = 0.43
    if args.scale: 
        scale = float(args.scale) 
  
    # set cols 
    cols = 80
    if args.cols: 
        cols = int(args.cols) 
  
    print('generating ASCII art...') 
    # convert image to ascii txt 
    aimg = covertImageToAscii(imgFile, cols, scale, args.moreLevels) 
  
    # open file 
    f = open(outFile, 'w') 
  
    # write to file 
    for row in aimg: 
        f.write(row + '\n') 
  
    # cleanup 
    f.close() 
    print("ASCII art written to %s" % outFile) 
  
# call main 
if __name__ == '__main__': 
    main()

Extract Text from Image

Simple script uses pytesseract to pull text from an image.

Copy to Clipboard
"""
Extract Text from Image
Simple script uses pytesseract to pull text from an image. 
"""
import pytesseract
from PIL import Image
import json

def pro(n):
    image = Image.open('1.png')
    return pytesseract.image_to_string(image)

t = []
for i in range(1, 13):
    print("Doing: ", i)
    t.append(pro(i))

open('out', 'w+').write(json.dumps(t))

Find Duplicate Images

Script to try find duplicate images regardless of file type. Converts them into their encoding hash to compare other images.

Copy to Clipboard
"""
Find Duplicate Images
Script to try find duplicate images regardless of file type.
Converts them into their encoding hash to compare other images. 
"""

from PIL import Image
import imagehash
import os
from pathlib import Path
from imagededup.methods import PHash

phasher = PHash()
# Generate hashes for all images in the folder
encodings = phasher.encode_images(image_dir='D:\My Drive\Shared\Whiteriver')

# Find duplicates
duplicates = phasher.find_duplicates(encoding_map=encodings, min_similarity_threshold=0.9)

# Print the results
for key, value in duplicates.items():
    if value:
        print(f"{key} is a duplicate of {value}")

# def find_duplicates(directory):
#     hashes = {}
#     for root, dirs, files in os.walk(directory):
#         for f in files:
#             filename = os.path.join(root, f)
#             if filename.endswith(('png', 'jpg', 'jpeg', 'gif', 'avif')):
#                 img = Image.open(filename)
#                 img_hash = imagehash.phash(img)  # pHash for similarity detection

#                 if img_hash in hashes:
#                     print(f"Duplicate found: {filename} and {hashes[img_hash]}")
#                 else:
#                     hashes[img_hash] = filename

# find_duplicates('D:\My Drive\Shared\Whiteriver')

Convert Images to the AVIF format

AVIF is a lot smaller as well as other benifits. Specifically this script was used on my Google Drive root folder finding all images and converting them to avif.

Copy to Clipboard
"""
Convert Images to the AVIF format
AVIF is a lot smaller as well as other benifits.
Specifically this script was used on my Google Drive root folder
finding all images and converting them to avif.
"""

import requests
from pathlib import Path
import os
import concurrent.futures
from tqdm import tqdm  # Install with: pip install tqdm
from threading import Lock
import shutil
from time import sleep
import json
import psutil

api_url = 'http://localhost:8080/api'
input_dir = 'D:\My Drive\Shared'
output_dir = Path('C:\Processed')
image_extensions = [
    ".jpeg", ".jpg", ".png", ".gif", ".bmp", ".tiff", ".tif",
    ".webp", ".heif", ".heic", ".ico", ".svg",
    ".cr2", ".cr3", ".nef", ".arw", ".raf", ".orf", ".rw2", ".dng"
]
lock = Lock()


def convert(filepath):
    suf = Path(filepath).suffix.lower()
    if suf in image_extensions:
        try:
            output_name = str(filepath).split(suf)[0] + '.avif'

            with open(filepath, 'rb') as f:
                r = requests.post(api_url, data={'quality': 80}, files={'file': f})
            if r.status_code == requests.codes.ok and r.headers.get('Content-Type') == 'image/avif':
                with open(output_name, 'wb') as f:
                    f.write(r.content)
                
                full_output_dir = output_dir / '/'.join(filepath.parts[1:-1])
                full_output_dir.mkdir(parents=True, exist_ok=True)
                shutil.move(filepath, full_output_dir)
            else:
                print('Error with:', filepath)
        except Exception as e:
            print(f'Error {e} with:', filepath)


def list_files_and_folders(directory):
    # Collect all file and folder paths
    items = []
    for root, dirs, files in os.walk(directory):
        items.extend([Path(os.path.join(root, f)) for f in files])

    total_items = len(items)
    if total_items == 0:
        print("No files or folders found.")
        return

    # Use tqdm to display a progress bar
    with tqdm(total=total_items, desc="Processing", unit="item") as pbar:
        with concurrent.futures.ThreadPoolExecutor() as executor:
            futures = [executor.submit(convert, item) for item in items]

            # Update the progress bar as each task completes
            for future in concurrent.futures.as_completed(futures):
                with lock:
                    pbar.update(1)  # Increment the progress bar by 1

list_files_and_folders(input_dir)

I have my own web server and like to run a few projects.

  • Home

    Home Page of my server and domain. 🌐 I'm always updating this page since I use it to test out whatever new thing I'm working on.

  • Planka

    Self-hosted Planka, an alternative to Trello / Jira. πŸ—‚οΈ I use it to plan my side projects, create cards, and keep track of progress.

  • Jellyfin

    Self-hosted Jellyfin, an alternative to Plex. 🎢 Makes it easy to access my music from any device.

  • VS Code Web

    Self-hosted VS Code Editor πŸ’» Runs on my server so I can code and manage it from anywhere, on any device.

  • Excalidraw

    Self-hosted Excalidraw ✏️ A draw.io alternative, great for sketching out project ideas and designs.

  • TOTP Authenticator

    Side project πŸ” I built my own 2FA Authenticator after losing my phone and getting locked out of everything. This way I add my own security and access it from the web instead of being tied to a device.

  • Peer-to-Peer File Transfer

    Side project πŸ“€ Transfers files directly between devices without storing them on the server.

  • Paste Room

    Side project πŸ“ A simple way to share text between devices (like my PC and laptop). Create a 'room' by changing the URL, and it becomes your unique space for shared text.

  • Media Gallery

    I wanted an easy way to show off pictures without filling up my phone storage. πŸ“Έ This site displays media from any folder I choose, and I can share it with anyone via ngrok.

  • Suika Game Clone

    I made a Suika Game clone in Godot πŸ‰ β€” simple but fun!

  • EagleCraft

    Minecraft in your browser! ⛏️ I used to run a dedicated server, but if it’s offline you can always connect to another public server.