{"id":16320144,"url":"https://github.com/amirgon/snippetbin","last_synced_at":"2025-09-01T21:39:38.920Z","repository":{"id":41774763,"uuid":"201129034","full_name":"amirgon/snippetbin","owner":"amirgon","description":"A simple pastebin/gist like service (server side), with git as its backend","archived":false,"fork":false,"pushed_at":"2022-12-11T01:36:43.000Z","size":76,"stargazers_count":6,"open_issues_count":2,"forks_count":1,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-07-07T15:45:34.908Z","etag":null,"topics":["gist","git","pastebin","rest-api"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/amirgon.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-08-07T21:15:17.000Z","updated_at":"2024-07-07T15:45:34.909Z","dependencies_parsed_at":"2023-01-26T12:40:11.686Z","dependency_job_id":null,"html_url":"https://github.com/amirgon/snippetbin","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amirgon%2Fsnippetbin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amirgon%2Fsnippetbin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amirgon%2Fsnippetbin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amirgon%2Fsnippetbin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/amirgon","download_url":"https://codeload.github.com/amirgon/snippetbin/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":219865150,"owners_count":16555931,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["gist","git","pastebin","rest-api"],"created_at":"2024-10-10T22:43:09.695Z","updated_at":"2024-10-10T22:43:10.298Z","avatar_url":"https://github.com/amirgon.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# SnippetBin\n\n---\n\n# Rational\n\nA simple pastebin/gist-like service (server side).\nThe underlying database is git. \nSyncs automatically with GitHub or any other git server.\n\nIt allows\n- Creating new (unamed) files and saving them on the server\n- A file revision is immutable. Once written to the server it cannot be changed.\n- A file revision can have history. It is an edit of another revision.\n- Sharing the files by publishing a \"revision id\" that identifies that revision of that file\n- Editing an existing file revision according to its revision id (this will create a new file with the original text and original history)\n- Browsing the change history of a file, and branching it to a new file\n\n# Configuration and deployment\n\nTo deploy in a Docker container, first build the docker image:\n```\nsudo docker build -t snippetbin ./\n```\n\nThen run it with environemnt variables like this:\n\n```\nsudo docker run -d --restart unless-stopped --name snippetbin -p 443:443 \\\n        -v /var/snippetbin/data:/snippetbin_data \\\n        -e \"SNIPPETBIN_PORT=443\" \\\n        -e \"SNIPPETBIN_DEPLOY_KEY=$(cat /var/snippetbin/deploy_key)\" \\\n        -e \"SNIPPETBIN_REMOTE_REPO=my_snippetbin_data.git\" \\\n        -e \"SNIPPETBIN_DATA_DIR=/snippetbin_data\" \\\n        -e \"SNIPPETBIN_SSL_KEY=$(cat /var/snippetbin/ssl.key)\" \\\n        -e \"SNIPPETBIN_SSL_CERT=$(cat /var/snippetbin/ssl.cer)\" \\\n        snippetbin npm start\n```\n\nThis example would start SnippetBin in Docker and start HTTPS server on port 443, \nwith the specified GitHub deploy key (ssh) and certificates (ssl).  \nThe data directory would be mounted to `/var/snippetbin/data` on the host.  \nIt will look for the deploy_key and ssl keys under `/var/snippetbin/` on the host.  \nIt will use my_snippetbin_data.git repo on as backing database.\n\n# Demo\n\nhttps://snippet-bin.herokuapp.com\n\n# API\n\n## LOAD-FILE\n\nInput:\n - revision key\n\nOutput: \n - file text\n - revision history (list of revision keys)\n\n## SAVE-FILE\n\nInput:\n - file text\n - original revision key (optional)\n\nOutput:\n - new revision key\n\n# Client flows\n\n## New file\n\n- User provides new text, and asks to save the file\n- Client calls SAVE-FILE with user text.\n- Client publishes revision key in a URL\n- Client saves revision key. It will be used when the user edits the file\n\n## Edit existing file\n\n- User continues to edit an existing file, and asks to save the file. (or file automatially saved)\n- Client remembers the revision key for the file the user is editing\n- Client calls SAVE-FILE with user text and the revision key\n\n## Load file\n\n- User provides revision key (through URL, or by selecting it from revision history)\n- Client calls LOAD-FILE with the revision key\n- Client displays file text to the user, and allows editing it.\n- Client displays the user the revision history, in case the user wants to go back to historic revision of the file\n- Client saves revision key. It will be used when the user saves his edits of the file\n\n# Implementation\n\n- Underlying database is git.\n- Revision key is a commit hash\n- Revision history is the log of a given commit hash\n- Each commit will contain a singe file\n- When saving a file\n  - A new file without \"original revision key\" will be named by a unique ID and commited.\n  - An existing file with commit ID will be branched from the original revision ID.\n\n\nNOTE: each commit must have a parent, otherwise `git diff-tree` will not work correctly. So don't start with empty repo!\n\n## git commands for LOAD-FILE\n\nGet file text according to revision key. Revision key is actually the commit ID, and each commit has only one file\n\nInputs:\n- `revision_key`\n\nOutputs:\n- `file_text`\n- `revision_history`\n\n```bash\nfile_hash=$(git diff-tree --no-commit-id \"${revision_key}\" | cut -d ' ' -f 4)\nfile_text=$(git cat-file -p \"${file_hash}\")\nfile_name=$(git diff-tree --no-commit-id --name-only \"${revision_key}\")\nrevision_history=($(git rev-list \"${revision_key}\" -- \"${file_name}\"))\n```\n\n## git commands for SAVE-FILE\n\nInputs:\n- `file_text`\n- optional `original_revision_key`\n- `commit_msg` \n\nOutputs:\n- `revision_key`\n\n```bash\nif [ -z \"$original_revision_key\" ]\nthen\n    file_name=$(uuidgen)\n    git checkout master\nelse\n    file_name=$(git diff-tree --no-commit-id --name-only -r \"$original_revision_key\")\n    git checkout -B branch_$(uuidgen) \"$original_revision_key\"\nfi\necho \"$file_text\" \u003e \"$file_name\"\ngit add \"$file_name\"\ngit commit -am \"$commit_msg\"\nrevision_key=$(git rev-parse HEAD)\n```\n\n# TODO\n\n- Change SAVE-FILE implementation to use git plumbing commands\n- Prevent checking out, no need to update all files locally when only one is used simultaneously\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Famirgon%2Fsnippetbin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Famirgon%2Fsnippetbin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Famirgon%2Fsnippetbin/lists"}