Skip to content

Latest commit

 

History

History
383 lines (285 loc) · 9.94 KB

README.md

File metadata and controls

383 lines (285 loc) · 9.94 KB

Media Storage Server

A simple media storage server for storing images and videos of various formats.

Table of Contents

Introduction

This project provides a basic template for building a Go media storage server. It includes CRUD functionality for both folders and images. The images are stored within a folder which creates a more structured storage system. URLs are generated for use in displaying the media stored. The /images endpoints can be used to store both image and video media.

Version 1.0.2

All endpoints will be preceded by the version. Excluding the /uploads endpoint which will remain constant throughout the versions.

Acceptable version endpoints are...

  • /v1/

Features

  • Image & video storage.
  • Folders for sorting images.
  • Metadata storage in a database.
  • Generate a URL to display the media stored.
  • Generate reports and have them sent to your email.
  • Cache for quick media and folder retrieval.
  • Duplicate images are stored only once on the disk.
  • Supported media formats: [JPEG, PNG, WEBP, BMP, TIFF, ICO, MP4]

Getting Started

Follow these steps to get the project up and running on your local machine.

Prerequisites

  • Go (1.16 or higher)
  • PostgreSQL database
  • Git (optional)

Installation

  1. Clone the repository (if you haven't already):
    git clone https://github.com/Azpect3120/MediaStorageServer.git
  1. Set up your PostgreSQL database and configure the connection details in the .env file:
  # This URL can be found in the dashboard of most PSQL hosts,
  # or it can be constructed using the required pieces
  db_url=your-connection-url-here

  # For more information visit this link:
  # https://www.hostinger.com/tutorials/how-to-use-free-google-smtp-server
  smtp_email=your-email-here
  smtp_password=your-email-app-password-here
  1. Install dependencies:
  go mod tidy
  1. Define port (optional):

The port can be changed from the default (:3000) to whatever port you would like, this can be done by updating your environment.

  export MSS_PORT="<port>"

NOTE: Updating the .env file will also update the port.

    MSS_PORT="<port>"
  1. Build and run the server:
  go build -o ./bin/server cmd/mediaStorageServer/main.go
  ./bin/server

Your media storage server should now be running on http://localhost:3000.

The server's port can be changed in the cmd/mediaStorageServer/main.go file:

  err := server.Run("NEW PORT HERE")

Database

Once the server is up and running you will need to connect to a PostgreSQL database. If you would like the code to work out of the box, you may copy the database schema provided below.

  CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

  CREATE TABLE IF NOT EXISTS folders (
      id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
      name VARCHAR(32) UNIQUE,
      createdAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP
  );

  CREATE TABLE IF NOT EXISTS images (
      id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
      folderId UUID REFERENCES folders(id) ON DELETE CASCADE,
      name TEXT,
      size BIGINT,
      type TEXT,
      uploadedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP
  );

Usage

Creating Folders

To create a folder to begin storing images, send a POST request to the /folders endpoint.

NOTE: The name provided must be unique. Response will return an error if the name is invalid.

  {
    "name": "folder-name-here"
  }

Ex. Response

  {
    "folder": {
      "ID": "generated-id-here",
      "Name": "folder-name-here",
      "CreatedAt": "timestamp"
    },
    "status": 201
  }

Getting Folders

Folder meta data and images can be viewed by sending a GET request to the /folders/<folder_id> endpoint.

NOTE: If a folder is not found, a PSQL error will be returned with a 400 error code.

  GET http://localhost:3000/<version>/folders/<folder_id>

Ex. Response

  {
    "folder": {
      "ID": "generated-id-here",
      "Name": "folder-name-here",
      "CreatedAt": "timestamp"
    },
    "count": 1,
    "images": [
      {
        "ID": "image-id",
        "FolderId": "generated-id-here",
        "Name": "image-name.jpg",
        "Size": 940184,
        "Format": "image/jpeg",
        "UploadedAt": "timestamp",
        "Path": "uploads/generated-id-here/image-id.jpg"
      }
    ],
    "status": 200
  }

Editing Folders

Folder name can be updated by sending a PUT request to the /folders/<folder_id> endpoint.

NOTE: Folder names must be valid, if a name is provided that is not valid, it will be cleaned as best as possible. If it cannot be cleaned then an error will be thrown.

  {
    "name": "newFolderName"
  }

Ex. Response

  {
    "folder": {
      "ID": "folderIDHere",
      "Name": "newFoldername",
      "CreatedAt": "timestamp"
    },
    "status": 200
  }

Deleting Folders

A folder can be deleted by sending a DELETE request to the /folders/<folder_id> endpoint. Nothing is returned from this request unless an error is encountered.

NOTE: Images will be deleted when its parent folder is deleted.

  DELETE http://localhost:3000/<version>/folders/<folder_id>

Uploading Media

Images can be uploaded through forms on a web application. Each "flavor" or framework will do it slightly differently the only information that must remain constant is that the image must be uploaded from a form with the name media_upload. Send a POST request to the /images/<folder_id> endpoint with the form data. The endpoint response will be stored in the data variables in the following examples.

HTML Example

    <input type="file" id="fileInput" />
    <button onclick="uploadFile()"> Upload </button>

    <script>
      function uploadFile() {
        const fileInput = document.getElementById("fileInput");
        const file = fileInput.files[0];

        const formData = new FormData();
        formData.append("media_upload", file);

        fetch("http://localhost:3000/<version>/images/<folder_id>", {
            method: "POST",
            body: formData,
        })
        .then(res => res.json())
        .then(data => console.log(data));
      }
    </script>

React Example

  import React, { useState } from "react";

  function FileUploadComponent () {
    const [file, setFile] = useState(null);

    const handleFileChange = (event) => {
      setFile(event.target.files[0]);
    };
    
    uploadFile = () => {
      if (!file) {
        console.error("No file selected.");
        return;
      }

      const formData = new FormData();
      formData.append("media_upload", file);

      fetch("http://localhost:3000/<version>/images/<folder_id>", {
          method: "POST",
          body: formData,
      })
      .then(res => res.json())
      .then(data => console.log(data));
  };

    return (
      <>
        <input type="file" onChange={handleFileChange} />
        <button onClick={uploadFile}> Upload </button>
      </>
    )
  }

  export default FileUploadComponent;

Ex. Response

  {
    "image": {
      "ID": "image-id",
      "FolderId": "generated-id-here",
      "Name": "image-name.jpg",
      "Size": 940184,
      "Format": "image/jpeg",
      "UploadedAt": "timestamp",
      "Path": "uploads/generated-id-here/image-id.jpg"
    }
  }

Getting Media

An images metadata can be viewed by sending a GET request to the /images/<image_id> endpoint. The path property that is returned can be used to display the image.

  GET http://localhost:3000/<version>/images/<image_id>

Ex. Response

{
  "image": {
    "ID": "image-id",
    "FolderId": "generated-id-here",
    "Name": "image-name.jpg",
    "Size": 940184,
    "Format": "image/jpeg",
    "UploadedAt": "timestamp",
    "Path": "uploads/generated-id-here/image-id.jpg"
  },
  "status": 200
}

Displaying Media

In web applications, the images can be displayed using their path, which can be found in the image metadata. Simply use the path as the src attribute in any web application.

  <img src="http://localhost:3000/uploads/<folder_id>/<image_id>" alt="Media Storage Image">

Deleting Media

An image can be deleted by sending a DELETE request to the /images/<image_id> endpoint. Nothing is returned from this request unless an error is encountered.

  DELETE http://localhost:3000/<version>/images/<image_id>

Generating Reports

A folder report can be generated and sent to your email by sending a GET request to the /reports/:id/:email endpoint.

  GET http://localhost:3000/<version>/reports/<folder_id>/<your_email>

Contributing

Contributions are welcome! If you'd like to contribute to this project, please follow these steps:

  1. Fork the project.
  2. Create a new branch for your feature or bug fix.
  3. Make your changes.
  4. Test your changes thoroughly.
  5. Create a pull request.

License

The project is licensed under username the MIT License