{"id":14955444,"url":"https://github.com/lykos/cube_trainer","last_synced_at":"2025-09-30T13:30:55.331Z","repository":{"id":37271099,"uuid":"56964310","full_name":"Lykos/cube_trainer","owner":"Lykos","description":"Website with tools to support Rubik's Cube training with a focus on blindfolded solving.","archived":false,"fork":false,"pushed_at":"2025-01-16T22:03:47.000Z","size":10837,"stargazers_count":11,"open_issues_count":74,"forks_count":4,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-01-20T04:52:02.009Z","etag":null,"topics":["rails","rails-api","rails6","rubiks-cube","rubiks-cube-timer","ruby","typescript"],"latest_commit_sha":null,"homepage":"https://www.cubetrainer.org","language":"Ruby","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/Lykos.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-04-24T09:41:22.000Z","updated_at":"2025-01-11T08:28:52.000Z","dependencies_parsed_at":"2023-02-18T13:01:15.708Z","dependency_job_id":"b0738c3e-4f87-4cfd-8f39-b772e26e8ecb","html_url":"https://github.com/Lykos/cube_trainer","commit_stats":{"total_commits":2781,"total_committers":7,"mean_commits":397.2857142857143,"dds":"0.26896799712333697","last_synced_commit":"f62177e2f2883ae2b67e4dea0014e7a9b404c002"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Lykos%2Fcube_trainer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Lykos%2Fcube_trainer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Lykos%2Fcube_trainer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Lykos%2Fcube_trainer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Lykos","download_url":"https://codeload.github.com/Lykos/cube_trainer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":234737856,"owners_count":18879180,"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":["rails","rails-api","rails6","rubiks-cube","rubiks-cube-timer","ruby","typescript"],"created_at":"2024-09-24T13:11:10.009Z","updated_at":"2025-09-30T13:30:49.598Z","avatar_url":"https://github.com/Lykos.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![CodeQL](https://github.com/Lykos/cube_trainer/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/Lykos/cube_trainer/actions/workflows/codeql-analysis.yml)\n[![Rubocop](https://github.com/Lykos/cube_trainer/actions/workflows/rubocop.yml/badge.svg)](https://github.com/Lykos/cube_trainer/actions/workflows/rubocop.yml)\n[![Ruby](https://github.com/Lykos/cube_trainer/actions/workflows/ruby.yml/badge.svg)](https://github.com/Lykos/cube_trainer/actions/workflows/ruby.yml)\n[![Typescript](https://github.com/Lykos/cube_trainer/actions/workflows/typescript.yml/badge.svg)](https://github.com/Lykos/cube_trainer/actions/workflows/typescript.yml)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\n# CubeTrainer\n\nThis is the repository for https://www.cubetrainer.org, which is a small website that contains some tools to support Rubik's Cube training with a focus on blindfolded solving.\n\n## Install\n\n### Clone the repository\n\n```shell\ngit clone git@github.com:Lykos/cube_trainer.git\ncd cube_trainer\n```\n\n### Install OS dependencies\n\n### Postgresql\n\nThis example is what I did on Ubuntu, but I'm sure you can figure out how to install\nPostgreSQL on your OS, too.\n\n```shell\nsudo apt install postgresql libpq-dev\n```\n\n### Ruby\n\nRuby is the programming language that is used for the CubeTrainer backend. If you only want to run the frontend, this dependency might not be necessary, but note that the frontend alone cannot do a lot, so this is only useful if you want to contribute something where the backend really isn't relevant.\n\nYou can install Ruby via any means you prefer. We recommend installing Ruby via [rbenv](https://github.com/rbenv/rbenv). This is a tool that lets you manage different Ruby versions. Check the first few lines in the [Gemfile](Gemfile) for the Ruby version that should be used for CubeTrainer. Other versions might work as well, but there is no guarantee.\n\nYou can try to use the Ruby installation that comes via your OS package manager, too, but there is a good chance that this will be an older Ruby version that won't work.\n\n### Node.js and NPM\n\nNPM is the package manager and toolchain we use for the CubeTrainer frontend and Node.js is the JavaScript runtime that NPM uses. If you only want to run the backend, this dependency might not be necessary, but note that the backend alone cannot do a lot, so this is only useful if you want to contribute something where the frontend really isn't relevant.\n\nYou can install Node.js and NPM via any means you prefer. We recommend installing it via [nvm](https://github.com/nvm-sh/nvm). This is a tool that lets you manage different Node.js and NPM versions. Check the first few line of the [package.json](package.json) (look for the string \"engines\") for the Node.js and NPM versions that should be used for CubeTrainer. Other versions might work as well, but there is no guarantee.\n\nYou can try to use the Node.js and NPM installation that comes via your OS package manager, too, but there is a good chance that this will be older versions that won't work.\n\n### Filemagic\n\nAt the moment, cube trainer depends on the `ruby-filemagic` Gem that depends on the C magic library. We are trying to get rid of this, but while it is still active, you need to install it. This is what I did on Ubuntu:\n\n```\nsudo apt install libmagic-dev\n```\n\n### Mailcatcher (optional)\n\nOptionally, you can install mailcatcher. This is a useful tool to debug emails that the website sends. Note that the documentation of mailcatcher recommends to set it up separately as a global gem and to not make it a gem dependency.\n\n```shell\ngem install mailcatcher\n```\n\n### Install Ruby \u0026 JS dependencies\n\nUsing [Bundler](https://github.com/bundler/bundler) and [npm](https://github.com/npm/cli):\n\n```shell\nbundle install \u0026\u0026 npm install\n```\n\n### Setup DB User\n\n```shell\nsudo su - postgres\ncreateuser cube_trainer -d -E -P\ncube_trainer\nexit\n```\n\n### Initialize the database\n\n```shell\nbundle exec rake db:create db:migrate\n```\n\n### Build the frontend\n\n```shell\nbundle exec rails npm:build\n```\n\n### Run tests\n\n```shell\nbundle exec rails spec\n```\n\n### Run frontend tests\n\n```shell\nbundle exec rails npm:test\n```\n\n### Run server\n\nThe best way to start all the necessary processes is to install [overmind](https://github.com/DarthSim/overmind) and then to simply run:\n\n```shell\novermind start\n```\n\nAlternatively, you can run these commands in separate terminals. Mailcatcher is optional and only needed if you want to debug emails.\n\n```shell\nbundle exec rails npm:start\nbundle exec rails server\nmailcatcher # optional\n```\n\nNow you can access the site at http://localhost:4200. Note that accessing it via http://localhost:3000 might also work, but you won't get automatic refreshes on TypeScript changes, so it's not recommended.\n\n## Dependencies\n\nFor the full list of dependencies, please check the [Gemfile](Gemfile) and the [package.json](package.json), but the most relevant ones are listed here:\n\n* [Ruby on Rails](https://rubyonrails.org/) is the backend framework.\n* Typescript with [Angular](https://angular.io/) is the frontend framework.\n* [Angular Material](https://material.angular.io/) for the UI components.\n* [PostgreSQL](https://www.postgresql.org/) for the backend database.\n* [NgRx Store](https://ngrx.io/guide/store) for the state management of the frontend.\n* [Devise Token Auth](https://github.com/lynndylanhurley/devise_token_auth) that is based on [Devise](https://github.com/heartcombo/devise) for authentication in the backend.\n* [Angular Token](https://github.com/neroniaky/angular-token) for the frontend parts of authentication.\n* [TwistyPuzzles](https://github.com/Lykos/twisty_puzzles) to deal with twisty puzzles (like the 3x3x3 cube) in the backend.\n* [cubing.js](https://github.com/cubing/cubing.js) to display twisty puzzles in the frontend.\n* [Redis](https://redis.io/) to run websockets for ActionCable. This is used to send notifications to the frontend.\n\nFor development, there are these relevant dependencies:\n\n* [Rubocop](https://github.com/rubocop/rubocop) is an amazing linter on steroids that helped us a lot to use more idiomatic and modern Ruby constructs.\n* [Rspec](https://rspec.info/) is our testing framework.\n* [Capybara](https://github.com/teamcapybara/capybara) for integration tests that run a browser and use both frontend and backend. They can be found in the [spec/system](spec/system) directory.\n* [Rantly](https://github.com/rantly-rb/rantly) to randomly generate test cases.\n\nNote that the way we combine Angular and Ruby is a bit self-baked. They basically live in different directories and the only connection is a hand-crafted Rails controller that serves the index.html file compiled by Angular. We previously tried to use various other ways to integrate them. Some of them worked, but they were a huge pain, so we went for this handcrafted solution. The problems we encountered with other integrations included:\n\n* We never got Angular components with separate HTML and TS files to work. This meant all the HTML was somehow inlined in a string in the TS file which was ugly and hard to work with.\n* For some setups we tried, we couldn't get our integration tests to work. These integration tests are very valuable and we don't want to lose them.\n* Somehow the setup forced us to depend on some old webpack versions with known security issues. It wasn't possible to upgrade because some dependencies really needed the old versions.\n\n## Production Setup\n\nThe website is hosted on Heroku and is automatically deployed if CI on the master branch on Github passes. It uses the following Heroku plugins.\n\n* It uses Mailgun Starter for sending mails. There's also some config on the Mailgun website.\n* It uses Heroku Postgres Basic for the database.\n* It uses Heroku Scheduler to regularly scrape sheets. It runs `bundle exec rails scheduler_scrape_sheets` once per day at 12:00 AM UTC.\n\nFormerly it also used Redis-to-go for ActionCable. Redis-to-go was removed from Heroku in August 2023 and we don't have a replacement yet. I.e. the ActionCable related things don't work at the moment. Luckily, they are only used to notify the user of achievements, so it's not removing a lot of functionality.\n\n## Using the Website\n\nNavigate to https://www.cubetrainer.org/signup to create an account. After the signup process, you can log in via https://www.cubetrainer.org/login and then create training sessions in https://www.cubetrainer.org/modes. What the website is best at is training blind algs with smart sampling that will show you algorithms more that you don't know well.\n\n## Background\n\nThis website started as a bunch of command line scripts that helped me practicing and eventually I added a database, than a small web frontend and eventually I turned it into a full website. The entire backstory can be found in https://www.cubetrainer.org/about.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flykos%2Fcube_trainer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flykos%2Fcube_trainer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flykos%2Fcube_trainer/lists"}