├── .editorconfig ├── .gitignore ├── .htaccess ├── API.md ├── AUTHORS.md ├── CONTRIBUTING.md ├── LICENSE.txt ├── README.md ├── api ├── .htaccess └── index.php ├── assets ├── css │ ├── base.css │ └── bootstrap-3.4.1.min.css ├── fonts │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.svg │ ├── glyphicons-halflings-regular.ttf │ ├── glyphicons-halflings-regular.woff │ └── glyphicons-halflings-regular.woff2 ├── js │ ├── bootstrap-3.4.1.min.js │ └── jquery-3.7.0.slim.min.js ├── logo.svg └── logo_dark.svg ├── composer.json ├── composer.lock ├── data ├── .htaccess ├── data.sql ├── migration-1.sql ├── migration-2.sql ├── migration-3.sql ├── migration-4.sql ├── migration-5.sql ├── migration-6.sql └── migration-7.sql ├── index.php ├── logs └── .htaccess ├── src ├── .htaccess ├── Helpers │ ├── Tokens.php │ └── Utils.php ├── constants.php ├── dependencies.php ├── middleware.php ├── queries.php ├── routes │ ├── asset.php │ ├── asset_edit.php │ ├── auth.php │ └── user.php ├── settings-local-example.php └── settings.php └── templates ├── .htaccess ├── _asset_fields.phtml ├── _csrf.phtml ├── _footer.phtml ├── _header.phtml ├── _pagination.phtml ├── asset.phtml ├── asset_edit.phtml ├── asset_edits.phtml ├── assets.phtml ├── change_password.phtml ├── edit_asset.phtml ├── edit_asset_edit.phtml ├── error.phtml ├── feed.phtml ├── forgot_password.phtml ├── forgot_password_result.phtml ├── index.phtml ├── login.phtml ├── register.phtml ├── reset_password.phtml ├── reset_password_email.phtml └── submit_asset.phtml /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: http://EditorConfig.org 2 | root = true 3 | 4 | # Unix-style newlines with a newline ending every file 5 | [*] 6 | end_of_line = lf 7 | insert_final_newline = true 8 | trim_trailing_whitespace = true 9 | charset = utf-8 10 | 11 | # CSS 12 | [*.css] 13 | indent_style = space 14 | indent_size = 4 15 | 16 | # PHP 17 | [*.{php,phtml}] 18 | indent_style = space 19 | indent_size = 4 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | vendor/** 2 | logs/**/*.log 3 | src/settings-local.php -------------------------------------------------------------------------------- /.htaccess: -------------------------------------------------------------------------------- 1 | RewriteEngine On 2 | 3 | # Some hosts may require you to use the `RewriteBase` directive. 4 | # If you need to use the `RewriteBase` directive, it should be the 5 | # absolute physical path to the directory that contains this htaccess file. 6 | # 7 | 8 | RewriteBase /asset-library 9 | 10 | RewriteCond %{REQUEST_FILENAME} !-f 11 | RewriteRule ^ index.php [QSA,L] 12 | -------------------------------------------------------------------------------- /API.md: -------------------------------------------------------------------------------- 1 | # Asset library API 2 | 3 | All POST APIs accept JSON-encoded or formdata-encoded bodies. 4 | GET APIs accept standard query strings. 5 | 6 | ## Core 7 | 8 | The core part of the API is understood and used by the C++ frontend embedded in the Godot editor. It has to stay compatible with all versions of Godot. 9 | 10 | * [`GET /configure`](#api-get-configure) - get details such as category and login URL 11 | * [`GET /asset?…`](#api-get-asset) - list assets by filter 12 | * [`GET /asset/{id}`](#api-get-asset-id) - get asset by id 13 | 14 | ## Auth API 15 | 16 |
17 | 18 | ### `POST /register` 19 | ```json 20 | { 21 | "username": "(username)", 22 | "password": "(password)", 23 | "email": "(email)" 24 | } 25 | ``` 26 | Successful result: 27 | ```json 28 | { 29 | "username": "(username)", 30 | "registered": true 31 | } 32 | ``` 33 | 34 | 35 | Register a user, given a username, password, and email. 36 | 37 | 38 | 39 | ### `POST /login` 40 | ```json 41 | { 42 | "username": "(username)", 43 | "password": "(password)" 44 | } 45 | ``` 46 | Successful result: 47 | ```json 48 | { 49 | "authenticated": true, 50 | "username": "(username)", 51 | "token": "(token)" 52 | } 53 | ``` 54 | 55 | Login as a given user. Results in a token which can be used for authenticated requests. 56 | 57 | 58 | 59 | ### `POST /logout` 60 | ```json 61 | { 62 | "token": "(token)" 63 | } 64 | ``` 65 | Successful result: 66 | ```json 67 | { 68 | "authenticated": false, 69 | "token": "" 70 | } 71 | ``` 72 | 73 | Logout a user, given a token. The token is invalidated in the process. 74 | 75 | 76 | 77 | 78 | ### `POST /change_password` 79 | ```json 80 | { 81 | "token": "(token)", 82 | "old_password": "(password)", 83 | "new_password": "(new password)" 84 | } 85 | ``` 86 | Successful result: 87 | ```json 88 | { 89 | "token": "" 90 | } 91 | ``` 92 | 93 | Change a user's password. The token is invalidated in the process. 94 | 95 | 96 | 97 | 98 | ### `GET /configure` 99 | ```http 100 | ?type=(any|addon|project) 101 | &session 102 | ``` 103 | Example result: 104 | ```json 105 | { 106 | "categories": [ 107 | { 108 | "id": "1", 109 | "name": "2D Tools", 110 | "type": "0" 111 | }, 112 | { 113 | "id": "2", 114 | "name": "Templates", 115 | "type": "1" 116 | }, 117 | ], 118 | "token": "…", 119 | "login_url": "https://…" 120 | } 121 | ``` 122 | 123 | Get a list of categories (needed for filtering assets) and potentially a login URL which can be given to the user in order to authenticate him in the engine (currently unused and not working). 124 | 125 | ## Assets API 126 | 127 | 128 | 129 | ### `GET /asset?…` 130 | ```http 131 | ?type=(any|addon|project) 132 | &category=(category id) 133 | &support=(official|featured|community|testing) 134 | &filter=(search text) 135 | &user=(submitter username) 136 | &cost=(license) 137 | &godot_version=(major).(minor).(patch) 138 | &max_results=(number 1…500) 139 | &page=(number, pages to skip) OR &offset=(number, rows to skip) 140 | &sort=(rating|cost|name|updated) 141 | &reverse 142 | ``` 143 | Example response: 144 | ```json 145 | { 146 | "result": [ 147 | { 148 | "asset_id": "1", 149 | "title": "Snake", 150 | "author": "test", 151 | "author_id": "1", 152 | "category": "2D Tools", 153 | "category_id": "1", 154 | "godot_version": "2.1", 155 | "rating": "0", 156 | "cost": "GPLv3", 157 | "support_level": "testing", 158 | "icon_url": "https://….png", 159 | "version": "1", 160 | "version_string": "alpha", 161 | "modify_date": "2018-08-21 15:49:00" 162 | } 163 | ], 164 | "page": 0, 165 | "pages": 0, 166 | "page_length": 10, 167 | "total_items": 1 168 | } 169 | ``` 170 | 171 | Get a list of assets. 172 | 173 | Some notes: 174 | * Leading and trailing whitespace in `filter` is trimmed on the server side. 175 | * For legacy purposes, not supplying godot version would list only 2.1 assets, while not supplying type would list only addons. 176 | * To specify multiple support levels, join them with `+`, e.g. `support=featured+community`. 177 | * Godot version can be specified as you see fit, for example, `godot_version=3.1` or `godot_version=3.1.5`. Currently, the patch version is disregarded, but may be honored in the future. 178 | 179 | 180 | 181 | ### `GET /asset/{id}` 182 | No query params. 183 | Example result: 184 | ```json 185 | { 186 | "asset_id": "1", 187 | "type": "addon", 188 | "title": "Snake", 189 | "author": "test", 190 | "author_id": "1", 191 | "version": "1", 192 | "version_string": "alpha", 193 | "category": "2D Tools", 194 | "category_id": "1", 195 | "godot_version": "2.1", 196 | "rating": "0", 197 | "cost": "GPLv3", 198 | "description": "Lorem ipsum…", 199 | "support_level": "testing", 200 | "download_provider": "GitHub", 201 | "download_commit": "master", 202 | "download_hash": "(sha256 hash of the downloaded zip)", 203 | "browse_url": "https://github.com/…", 204 | "issues_url": "https://github.com/…/issues", 205 | "icon_url": "https://….png", 206 | "searchable": "1", 207 | "modify_date": "2018-08-21 15:49:00", 208 | "download_url": "https://github.com/…/archive/master.zip", 209 | "previews": [ 210 | { 211 | "preview_id": "1", 212 | "type": "video", 213 | "link": "https://www.youtube.com/watch?v=…", 214 | "thumbnail": "https://img.youtube.com/vi/…/default.jpg" 215 | }, 216 | { 217 | "preview_id": "2", 218 | "type": "image", 219 | "link": "https://….png", 220 | "thumbnail": "https://….png" 221 | } 222 | ] 223 | } 224 | ``` 225 | 226 | Notes: 227 | * The `cost` field is the license. Other asset libraries may put the price there and supply a download URL which requires authentication. 228 | * In the official asset library, the `download_hash` field is always empty and is kept for compatibility only. The editor will skip hash checks if `download_hash` is an empty string. Third-party asset libraries may specify a SHA-256 hash to be used by the editor to verify the download integrity. 229 | * The download URL is generated based on the download commit and the browse URL. 230 | 231 | 232 | 233 | ### `POST /asset/{id}/delete` 234 | ```json 235 | { 236 | "token": "…" 237 | } 238 | ``` 239 | Successful response: 240 | ```json 241 | { 242 | "changed": true 243 | } 244 | ``` 245 | 246 | Soft-delete an asset. Useable by moderators and the owner of the asset. 247 | 248 | 249 | 250 | ### `POST /asset/{id}/undelete` 251 | ```json 252 | { 253 | "token": "…" 254 | } 255 | ``` 256 | Successful response: 257 | ```json 258 | { 259 | "changed": true 260 | } 261 | ``` 262 | 263 | Revert a deletion of an asset. Useable by moderators and the owner of the asset. 264 | 265 | 266 | 267 | ### `POST /asset/{id}/support_level` 268 | ```json 269 | { 270 | "support_level": "official|featured|community|testing", 271 | "token": "…" 272 | } 273 | ``` 274 | Successful response: 275 | ```json 276 | { 277 | "changed": true 278 | } 279 | ``` 280 | 281 | API used by moderators to change the support level of an asset. 282 | 283 | ## Asset edits API 284 | 285 | 286 | 287 | ### `POST /asset`, `POST /asset/{id}`, `POST /asset/edit/{id}` 288 | ```json 289 | { 290 | "token": "…", 291 | 292 | "title": "Snake", 293 | "description": "Lorem ipsum…", 294 | "category_id": "1", 295 | "godot_version": "2.1", 296 | "version_string": "alpha", 297 | "cost": "GPLv3", 298 | "download_provider": "GitHub", 299 | "download_commit": "master", 300 | "browse_url": "https://github.com/…", 301 | "issues_url": "https://github.com/…/issues", 302 | "icon_url": "https://….png", 303 | "download_url": "https://github.com/…/archive/master.zip", 304 | "previews": [ 305 | { 306 | "enabled": true, 307 | "operation": "insert", 308 | "type": "image|video", 309 | "link": "…", 310 | "thumbnail": "…" 311 | }, 312 | { 313 | "enabled": true, 314 | "operation": "update", 315 | "edit_preview_id": "…", 316 | "type": "image|video", 317 | "link": "…", 318 | "thumbnail": "…" 319 | }, 320 | { 321 | "enabled": true, 322 | "operation": "delete", 323 | "edit_preview_id": "…" 324 | }, 325 | ] 326 | } 327 | ``` 328 | Successful result: 329 | ```json 330 | { 331 | "id": "(id of the asset edit)" 332 | } 333 | ``` 334 | 335 | Create a new edit or update an existing one. Fields are required when creating a new asset, and are optional otherwise. Same for previews -- required when creating a new preview, may be missing if updating one. 336 | 337 | Notes: 338 | * Not passing `"enabled": true` for previews will result in them not being included in the edit. This may be fixed in the future. 339 | * `version_string` is free-form text, but `major.minor` or `major.minor.patch` format is best. 340 | * Available download providers can be seen on the asset library fronted. 341 | 342 | 343 | 344 | ### `GET /asset/edit/{id}` 345 | No query params. 346 | Example result: 347 | ```json 348 | { 349 | "edit_id": "1", 350 | "asset_id": "1", 351 | "user_id": "1", 352 | "title": null, 353 | "description": null, 354 | "category_id": null, 355 | "godot_version": null, 356 | "version_string": null, 357 | "cost": null, 358 | "download_provider": null, 359 | "download_commit": null, 360 | "browse_url": "…", 361 | "issues_url": "…", 362 | "icon_url": null, 363 | "download_url": "…", 364 | "author": "test", 365 | "previews": [ 366 | { 367 | "operation": "insert", 368 | "edit_preview_id": "60", 369 | "preview_id": null, 370 | "type": "image", 371 | "link": "…", 372 | "thumbnail": "…", 373 | }, 374 | { 375 | "preview_id": "35", 376 | "type": "image", 377 | "link": "…", 378 | "thumbnail": "…" 379 | } 380 | ], 381 | "original": { 382 | … original asset fields … 383 | }, 384 | "status": "new", 385 | "reason": "", 386 | "warning": "…" 387 | } 388 | ``` 389 | 390 | Returns a previously-submitted asset edit. All fields with `null` are unchanged, and will stay the same as in the `original`. 391 | The `previews` array is merged from the new and original previews. 392 | 393 | 394 | 395 | ### `POST /asset/edit/{id}/review` 396 | ```json 397 | { 398 | "token": "…" 399 | } 400 | ``` 401 | Successful result: the asset edit, without the original asset. 402 | 403 | Moderator-only. Put an edit in review. It is impossible to change it after this. 404 | 405 | 406 | 407 | ### `POST /asset/edit/{id}/accept` 408 | ```json 409 | { 410 | "token": "…", 411 | } 412 | ``` 413 | Successful result: the asset edit, without the original asset. 414 | 415 | Moderator-only. Apply an edit previously put in review. 416 | 417 | 418 | 419 | ### `POST /asset/edit/{id}/reject` 420 | ```json 421 | { 422 | "token": "…", 423 | "reason": "…" 424 | } 425 | ``` 426 | Successful result: the asset edit, without the original asset. 427 | 428 | Moderator-only. Reject an edit previously put in review. 429 | -------------------------------------------------------------------------------- /AUTHORS.md: -------------------------------------------------------------------------------- 1 | Project maintainers: 2 | ==================== 3 | Alket Rexhepi (@alketii) 4 | Bojidar Marinov (@bojidar-bg) 5 | 6 | 7 | Contributors: 8 | ============= 9 | Rémi Verschelde (@akien-mga) 10 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to the Godot Asset Library 2 | 3 | First off, thanks for taking the time to contribute! :tada::+1: 4 | 5 | The following is a set of guidelines for contributing to the Godot Engine's [official asset library web front end](https://godotengine.org/asset-library) and its REST API. These are mostly guidelines, not rules. Use your best judgment, and feel free to propose changes to this document in a pull request. 6 | 7 | ### :warning: Two important notes before we dive into the details 8 | 9 | 1. Issues with the asset library front end included in the Godot Engine should be reported in the [Godot Engine repository](https://github.com/godotengine/godot/issues?q=is%3Aissue+is%3Aopen+asset+label%3Atopic%3Aassetlib). 10 | 2. Issues with individual assets should be reported in the separate issue trackers of the respective assets, usually linked on the asset pages under the "Submit an issue" button. 11 | 12 | ## Table Of Contents 13 | 14 | - [Code of Conduct](#code-of-conduct) 15 | 16 | - [I don't want to read this whole thing, I just have a question!](#i-dont-want-to-read-this-whole-thing-i-just-have-a-question) 17 | 18 | - [What should I know before I get started?](#what-should-i-know-before-i-get-started) 19 | - [The Godot Asset Library](#the-godot-asset-library) 20 | 21 | - [How Can I Contribute?](#how-can-i-contribute) 22 | - [Reporting Bugs](#reporting-bugs-and-suggesting-enhancements) 23 | - [Code Contributions and Pull Requests](#code-contributions-and-pull-requests) 24 | 25 | ## Code of Conduct 26 | 27 | This project and everyone participating in it is governed by the [Godot Code of Conduct](https://godotengine.org/code-of-conduct). By participating, you are expected to uphold this code. Please report unacceptable behavior to [Godot's Code of Conduct team](mailto:conduct@godotengine.org). 28 | 29 | ## I don't want to read this whole thing I just have a question! 30 | 31 | > **Note:** Please don't file an issue to ask a question. You'll get faster results by using the resources below. 32 | 33 | We have several forums, chats and groups where the community chimes in with helpful advice if you have questions: 34 | 35 | * [Questions & Answers](https://godotengine.org/qa/) — The official Godot message board 36 | * [Forum](https://godotforums.org/) — Community forum for all Godot developers 37 | 38 | Plus several groups at [Facebook](https://www.facebook.com/groups/godotengine/), [Reddit](https://www.reddit.com/r/godot), [Steam](https://steamcommunity.com/app/404790) and others. See [Godot Communities](https://godotengine.org/community) for a more complete list. And if chat is more your speed, you can join us at [IRC](http://webchat.freenode.net/?channels=#godotengine), [Discord](https://discord.gg/zH7NUgz) or [Matrix](https://matrix.to/#/#godotengine:matrix.org). 39 | 40 | ## What should I know before I get started? 41 | 42 | ### The Godot Asset Library 43 | 44 | The Godot Asset Library, otherwise known as the AssetLib, is a repository of user-submitted Godot addons, scripts, tools and other resources, collectively referred to as assets. They’re available to all Godot users for download directly from within the engine, but it can also be accessed at [Godot’s official website](https://godotengine.org/asset-library) via the PHP scripts and API functions maintained in this repository. 45 | 46 | Please note that the AssetLib is relatively young — it may have various pain points, bugs and usability issues. 47 | 48 | ## How can I contribute? 49 | 50 | ### Reporting Bugs and Suggesting Enhancements 51 | 52 | The golden rule is to **always open *one* issue for *one* bug**. If you notice 53 | several bugs and want to report them, make sure to create one new issue for 54 | each of them. 55 | 56 | If you're reporting a new bug, you'll make our life simpler (and the 57 | fix will come sooner) by following these guidelines: 58 | 59 | ### Search first in the existing database 60 | 61 | Issues are often reported several times by various users. It's good practice to 62 | **search first in the [issue tracker](https://github.com/godotengine/godot-asset-library/issues) 63 | before reporting your issue**. If you don't find a relevant match or if you're 64 | unsure, don't hesitate to **open a new issue**. The bugsquad will handle it 65 | from there if it's a duplicate. 66 | 67 | ### Code Contributions and Pull Requests 68 | 69 | If you want to add or improve asset library features, please make sure that: 70 | 71 | - This functionality is desired, which means that it solves a common use case 72 | that several users will need. 73 | - You talked to other developers on how to implement it best. 74 | - Even if it doesn't get merged, your PR is useful for future work by another 75 | developer. 76 | 77 | Similar rules can be applied when contributing bug fixes - it's always best to 78 | discuss the implementation in the bug report first if you are not 100% about 79 | what would be the best fix. 80 | 81 | The general [Godot Contributing docs](https://docs.godotengine.org/en/latest/community/contributing/index.html) 82 | also have important information on the PR workflow and the code style we use in this project. 83 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 The Godot Engine community 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Godot's Asset Library 2 | 3 | ___ 4 | 5 | **Note:** This asset library backend and frontend is now in maintenance mode. 6 | Feel free to submit bug fixes and small improvements, but please refrain from 7 | working on large features. In the future, the [Godot Foundation](https://godot.foundation/)'s asset store 8 | will deprecate this library. 9 | 10 | ___ 11 | 12 | REST API and frontend for Godot Engine's [official asset library](https://godotengine.org/asset-library). 13 | 14 | [Endpoints](./API.md) 15 | 16 | ## Installation 17 | 18 | Run the following commands to get a running installation of the project: 19 | 20 | ````bash 21 | composer install 22 | cp src/settings-local-example.php src/settings-local.php 23 | ```` 24 | 25 | Now you should proceed to update `src/settings-local.php` with your DB password and session secret. 26 | 27 | ## Browser support 28 | 29 | When working on new features, keep in mind this website only supports 30 | *evergreen browsers*: 31 | 32 | - Chrome (latest version and N-1 version) 33 | - Edge (latest version and N-1 version) 34 | - Firefox (latest version, N-1 version, and latest ESR version) 35 | - Opera (latest version and N-1 version) 36 | - Safari (latest version and N-1 version) 37 | 38 | Internet Explorer isn't supported. 39 | -------------------------------------------------------------------------------- /api/.htaccess: -------------------------------------------------------------------------------- 1 | RewriteEngine On 2 | 3 | # Some hosts may require you to use the `RewriteBase` directive. 4 | # If you need to use the `RewriteBase` directive, it should be the 5 | # absolute physical path to the directory that contains this htaccess file. 6 | # 7 | RewriteBase /asset-library/api 8 | 9 | RewriteCond %{REQUEST_FILENAME} !-f 10 | RewriteRule ^ index.php [QSA,L] 11 | -------------------------------------------------------------------------------- /api/index.php: -------------------------------------------------------------------------------- 1 | run(); 40 | -------------------------------------------------------------------------------- /assets/css/base.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --base-color-text: #333; 3 | --secondary-background-color: #f8f8f8; 4 | --highlight-background-color: #e7e7e7; 5 | } 6 | 7 | body { 8 | font-family: -apple-system, "BlinkMacSystemFont", "Segoe UI", "Roboto", "Helvetica Neue", "Arial", "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; 9 | display: flex; 10 | flex-direction: column; 11 | min-height: 100vh; 12 | } 13 | 14 | main { 15 | flex-grow: 1; 16 | } 17 | 18 | footer { 19 | padding-bottom: 12px; 20 | } 21 | 22 | .logo-dark { 23 | display: none; 24 | } 25 | 26 | .form-search .form-group { 27 | margin-bottom: 0.2em; 28 | margin-right: 40px; 29 | } 30 | 31 | @media screen and (max-width: 768px) { 32 | .form-search .form-group { 33 | margin-right: 0; 34 | } 35 | } 36 | 37 | @supports (display: flex) { 38 | @media screen and (min-width: 768px) { 39 | .form-search { 40 | display: flex; 41 | justify-content: space-between; 42 | flex-flow: wrap; 43 | } 44 | .form-search .form-group { 45 | margin-right: 1em; 46 | margin-left: 1em; 47 | flex-shrink: 0; 48 | display: block; 49 | } 50 | } 51 | } 52 | 53 | .required_mark::after { 54 | content: ' *'; 55 | color: #d9534f; 56 | } 57 | 58 | .media-object { 59 | overflow: hidden; 60 | text-overflow: ellipsis; 61 | flex-shrink: 0; 62 | } 63 | 64 | .nowrap { 65 | white-space: nowrap; 66 | display: inline-block; 67 | } 68 | 69 | .label { 70 | line-height: 1.8; 71 | } 72 | 73 | .asset-search-container { 74 | display: flex; 75 | flex-direction: row; 76 | gap: 24px; 77 | } 78 | 79 | @media (max-width: 768px) { 80 | .asset-search-container { 81 | flex-direction: column; 82 | } 83 | } 84 | 85 | .asset-search-container > form { 86 | display: flex; 87 | flex-direction: column; 88 | gap: 16px; 89 | width: 220px; 90 | min-width: 220px; 91 | } 92 | @media (max-width: 768px) { 93 | .asset-search-container > form { 94 | width: 100%; 95 | } 96 | } 97 | 98 | .asset-search-container > form > * + * { 99 | border-top: 1px solid black; 100 | padding-top: 16px; 101 | } 102 | 103 | .asset-search-container > form .form-actions > a { 104 | width: 100%; 105 | } 106 | 107 | .asset-search-container > form .form-search { 108 | display: flex; 109 | gap: 16px; 110 | flex-flow: column; 111 | } 112 | 113 | .asset-search-container > form .form-search .form-group { 114 | display: flex; 115 | flex-direction: column; 116 | gap: 6px; 117 | margin: 0; 118 | } 119 | 120 | .asset-search-container > form .form-search .form-group label:first-child { 121 | font-size: 106%; 122 | } 123 | 124 | .asset-search-container > form .form-search .form-checkbox { 125 | cursor: pointer; 126 | font-weight: 600; 127 | } 128 | 129 | .asset-search-container > form .form-search .form-checkbox input[type=checkbox] { 130 | vertical-align: text-top; 131 | } 132 | 133 | .asset-search-container > form .form-search select { 134 | cursor: pointer; 135 | } 136 | 137 | .asset-search-container > form .form-search .form-highlighted { 138 | border-radius: 4px; 139 | padding: 4px 8px; 140 | } 141 | 142 | .asset-search-container > form .form-search .form-highlighted > .form-checkbox { 143 | margin: 0; 144 | } 145 | 146 | .asset-search-results { 147 | display: flex; 148 | flex-direction: column; 149 | justify-content: flex-end; 150 | width: 100%; 151 | } 152 | 153 | .asset-list { 154 | display: grid; 155 | grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); 156 | grid-gap: 12px; 157 | padding: 0; 158 | list-style: none; 159 | } 160 | 161 | .asset-list .asset-header { 162 | flex: 1; 163 | } 164 | 165 | .asset-item { 166 | display: flex; 167 | flex-direction: column; 168 | } 169 | 170 | .asset-header { 171 | display: flex; 172 | gap: 12px; 173 | padding: 12px 12px 8px 12px; 174 | background-color: var(--secondary-background-color); 175 | border: 1px solid var(--highlight-background-color); 176 | } 177 | 178 | .asset-header:focus { 179 | outline: 1px solid var(--base-color-text); 180 | outline-offset: -1px; 181 | box-shadow: none; 182 | } 183 | 184 | .asset-header:hover, 185 | .asset-header:focus, 186 | .asset-header:active { 187 | text-decoration: none; 188 | background-color: var(--highlight-background-color); 189 | } 190 | 191 | .asset-header:hover .asset-title h4, 192 | .asset-header:focus .asset-title h4, 193 | .asset-header:active .asset-title h4 { 194 | text-decoration: underline; 195 | } 196 | 197 | .asset-footer { 198 | display: flex; 199 | justify-content: space-between; 200 | align-items: center; 201 | padding: 8px 12px; 202 | background-color: var(--secondary-background-color); 203 | border: 1px solid var(--highlight-background-color); 204 | } 205 | 206 | .asset-title { 207 | display: flex; 208 | flex-direction: column; 209 | flex: 1; 210 | gap: 12px; 211 | } 212 | 213 | .asset-title h4 { 214 | margin: 0; 215 | font-weight: bold; 216 | color: var(--base-color-text); 217 | } 218 | 219 | .table-tags .label { 220 | display: block; 221 | width: 100%; 222 | padding: 0; 223 | font-size: 14px; 224 | text-align: center; 225 | } 226 | 227 | .asset-tags .label { 228 | padding: 0 6px; 229 | font-size: 13px; 230 | } 231 | 232 | .asset-tags-container { 233 | display: flex; 234 | justify-content: space-between; 235 | align-items: center; 236 | flex: 1; 237 | gap: 6px; 238 | } 239 | 240 | .asset-tags { 241 | display: flex; 242 | flex-wrap: wrap; 243 | gap: 6px; 244 | } 245 | 246 | .pagination-container { 247 | flex: 1; 248 | display: flex; 249 | justify-content: center; 250 | align-items: flex-end; 251 | text-align: center; 252 | } 253 | 254 | .pagination-stats { 255 | display: flex; 256 | justify-content: space-between; 257 | gap: 8px; 258 | } 259 | 260 | @media (max-width: 768px) { 261 | .pagination-stats { 262 | flex-direction: column; 263 | } 264 | } 265 | 266 | .table-bordered.table-edit > tbody > tr > th { 267 | width: 1%; 268 | white-space: nowrap; 269 | text-align: center; 270 | vertical-align: middle; 271 | } 272 | 273 | .table-bordered.table-edit img { 274 | max-width: 100%; 275 | } 276 | 277 | @media(prefers-color-scheme: dark) { 278 | :root { 279 | --base-color-text: hsla(200, 00%, 100%, 0.85); 280 | --link-color: #80B0DB; 281 | --link-underline-color: #94c2ef; 282 | --primary-background-color: #25282b; 283 | --secondary-background-color: #333639; 284 | --highlight-background-color: #505356; 285 | --input-background-color: #3b3e40; 286 | --success-background-color: #567a48; 287 | --danger-background-color: #9c3d3b; 288 | --info-background-color: #41788B; 289 | --notice-background-color: #515e86; 290 | --warning-background-color: #b5761b; 291 | --default-background-color: #696969; 292 | --base-box-shadow: 0 0 4px rgba(0, 0, 0, 0.4); 293 | } 294 | 295 | body { 296 | background-color: var(--primary-background-color); 297 | color: var(--base-color-text) 298 | } 299 | 300 | footer { 301 | padding-top: 40px; 302 | margin-top: 20px; 303 | background-color: var(--secondary-background-color); 304 | border: none; 305 | } 306 | 307 | footer hr, 308 | .logo-light { 309 | display: none; 310 | } 311 | 312 | .logo-dark { 313 | display: initial; 314 | } 315 | 316 | .navbar-default { 317 | background-color: var(--secondary-background-color); 318 | border: none; 319 | box-shadow: var(--base-box-shadow); 320 | } 321 | 322 | .navbar-default .navbar-brand, 323 | .navbar-default .navbar-nav > li > a { 324 | color: var(--base-color-text) 325 | } 326 | 327 | .navbar-default .navbar-nav > li > a:focus, 328 | .navbar-default .navbar-nav > li > a:hover, 329 | .navbar-default .navbar-brand:focus, 330 | .navbar-default .navbar-brand:hover { 331 | color: white; 332 | text-decoration: underline; 333 | } 334 | 335 | .navbar-default .navbar-nav > .active > a, 336 | .navbar-default .navbar-nav > .active > a:focus, 337 | .navbar-default .navbar-nav > .active > a:hover { 338 | background-color: var(--highlight-background-color); 339 | color: var(--base-color-text) 340 | } 341 | 342 | .form-control { 343 | background-color: var(--input-background-color); 344 | color: var(--base-color-text) 345 | } 346 | 347 | .form-control:focus { 348 | border-color: white; 349 | } 350 | 351 | .img-thumbnail { 352 | background: none; 353 | border: none; 354 | } 355 | 356 | .asset-search-container > form > * + * { 357 | border-top-color: white; 358 | } 359 | 360 | legend, 361 | h4 small, 362 | .help-block, 363 | .text-muted { 364 | color: var(--base-color-text) 365 | } 366 | 367 | a, 368 | .btn-link { 369 | color: var(--link-color); 370 | } 371 | 372 | a:focus, 373 | a:hover, 374 | .btn-link:focus, 375 | .btn-link:hover { 376 | color: var(--link-underline-color); 377 | } 378 | 379 | .pagination > li > a, 380 | .btn-default { 381 | background-color: var(--input-background-color); 382 | border-color: var(--base-color-text); 383 | color: var(--base-color-text); 384 | } 385 | 386 | .pagination > li > a:hover, 387 | .pagination > li > a:focus, 388 | .pagination > li > a:active, 389 | .btn-default:focus, 390 | .btn-default:hover, 391 | .btn-default:active { 392 | background-color: var(--highlight-background-color); 393 | color: var(--base-color-text); 394 | } 395 | 396 | .pagination > .disabled > a, 397 | .pagination > .active > a, 398 | .btn-default.active { 399 | color: white; 400 | pointer-events: none; 401 | z-index: -1 !important; 402 | } 403 | 404 | .pagination > .disabled > a { 405 | background-color: var(--highlight-background-color); 406 | border-color: var(--highlight-background-color); 407 | } 408 | 409 | .pagination > .active > a, 410 | .btn-default.active { 411 | background-color: var(--notice-background-color); 412 | border-color: var(--notice-background-color); 413 | } 414 | 415 | .btn-danger { 416 | background-color: var(--danger-background-color); 417 | border-color: var(--danger-background-color); 418 | } 419 | 420 | .btn-success { 421 | background-color: var(--success-background-color); 422 | border-color: var(--success-background-color); 423 | } 424 | 425 | .btn-warning { 426 | background-color: var(--warning-background-color); 427 | border-color: var(--warning-background-color); 428 | } 429 | 430 | .btn-primary { 431 | background-color: var(--notice-background-color); 432 | border-color: var(--notice-background-color); 433 | } 434 | 435 | .btn-primary:hover, 436 | .btn-primary:focus, 437 | .btn-primary:active { 438 | background-color: var(--info-background-color); 439 | border-color: var(--info-background-color); 440 | } 441 | 442 | code, 443 | .bg-info, 444 | .label-primary { 445 | background-color: var(--notice-background-color); 446 | color: white; 447 | } 448 | 449 | .panel { 450 | background-color: var(--secondary-background-color); 451 | border: none; 452 | } 453 | 454 | .panel-default > .panel-heading { 455 | background-color: var(--highlight-background-color); 456 | color: white; 457 | } 458 | 459 | .label-default { 460 | background-color: var(--default-background-color); 461 | } 462 | 463 | .label-info, 464 | .panel-info > .panel-heading, 465 | .table > tbody > tr > td.info { 466 | background-color: var(--info-background-color); 467 | color: white; 468 | } 469 | 470 | .label-danger, 471 | .panel-danger > .panel-heading, 472 | .table > tbody > tr > td.danger { 473 | background-color: var(--danger-background-color); 474 | color: white; 475 | } 476 | 477 | .label-success, 478 | .panel-success > .panel-heading, 479 | .table > tbody > tr > td.success { 480 | background-color: var(--success-background-color); 481 | color: white; 482 | } 483 | 484 | .table > tbody > tr > td.active { 485 | background-color: var(--primary-background-color); 486 | } 487 | 488 | .asset-header, 489 | .asset-footer { 490 | border-color: var(--primary-background-color) 491 | } 492 | 493 | .table-bordered { 494 | border: 2px solid var(--secondary-background-color); 495 | } 496 | 497 | .table-bordered > thead > tr > th, 498 | .table-bordered:not(.table-edit) > tbody > tr > td, 499 | .table-bordered:not(.table-edit) > tbody > tr > th { 500 | border: none; 501 | } 502 | 503 | .table-bordered thead > tr > th { 504 | border: none; 505 | border-bottom: 2px solid var(--default-background-color); 506 | } 507 | 508 | .table-striped > tbody > tr:nth-of-type(2n+1) { 509 | background-color: var(--secondary-background-color); 510 | } 511 | 512 | .table-bordered.table-edit > tbody > tr > td, 513 | .table-bordered.table-edit > tbody > tr > th { 514 | border-color: var(--secondary-background-color); 515 | } 516 | 517 | .table-bordered.table-edit > thead > tr > th:first-child { 518 | border-bottom: 1px solid var(--secondary-background-color); 519 | } 520 | 521 | .table-bordered.table-edit > tbody > tr > th { 522 | background-color: var(--primary-background-color); 523 | border-right: 2px solid var(--default-background-color); 524 | } 525 | } 526 | -------------------------------------------------------------------------------- /assets/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/godotengine/godot-asset-library/1b9c58b9d824ad7c636e4e7d2785eade459def4d/assets/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /assets/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/godotengine/godot-asset-library/1b9c58b9d824ad7c636e4e7d2785eade459def4d/assets/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /assets/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/godotengine/godot-asset-library/1b9c58b9d824ad7c636e4e7d2785eade459def4d/assets/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /assets/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/godotengine/godot-asset-library/1b9c58b9d824ad7c636e4e7d2785eade459def4d/assets/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /assets/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /assets/logo_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": { 3 | "slim/slim": "^3.0", 4 | "dflydev/fig-cookies": "^1.0", 5 | "slim/csrf": "^0.7.0", 6 | "monolog/monolog": "^1.17", 7 | "slim/php-view": "^2.0", 8 | "phpmailer/phpmailer": "^6.8" 9 | }, 10 | 11 | "autoload": { 12 | "psr-4": { 13 | "Godot\\AssetLibrary\\": "src/" 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /data/.htaccess: -------------------------------------------------------------------------------- 1 | Order allow,deny 2 | Deny from all -------------------------------------------------------------------------------- /data/data.sql: -------------------------------------------------------------------------------- 1 | SET NAMES utf8; 2 | SET time_zone = '+00:00'; 3 | SET foreign_key_checks = 0; 4 | SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO'; 5 | 6 | DROP TABLE IF EXISTS `as_assets`; 7 | CREATE TABLE `as_assets` ( 8 | `asset_id` int(11) NOT NULL AUTO_INCREMENT, 9 | `user_id` int(11) NOT NULL DEFAULT '0', 10 | `title` varchar(255) NOT NULL, 11 | `description` text NOT NULL, 12 | `category_id` int(11) NOT NULL DEFAULT '6', 13 | `godot_version` int(7) NOT NULL, 14 | `version` int(11) NOT NULL, 15 | `version_string` varchar(20) NOT NULL, 16 | `cost` varchar(25) NOT NULL DEFAULT 'GPLv3', 17 | `rating` int(11) NOT NULL DEFAULT '1', 18 | `support_level` tinyint(4) NOT NULL, 19 | `download_provider` tinyint(4) NOT NULL, 20 | `download_commit` varchar(2048) NOT NULL, 21 | `browse_url` varchar(1024) NOT NULL, 22 | `issues_url` varchar(1024) NOT NULL, 23 | `icon_url` varchar(1024) NOT NULL, 24 | `searchable` tinyint(1) NOT NULL DEFAULT '0', 25 | `modify_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 26 | PRIMARY KEY (`asset_id`) 27 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 28 | 29 | DROP TABLE IF EXISTS `as_asset_edits`; 30 | CREATE TABLE `as_asset_edits` ( 31 | `edit_id` int(11) NOT NULL AUTO_INCREMENT, 32 | `asset_id` int(11) NOT NULL, 33 | `user_id` int(11) NOT NULL, 34 | `title` varchar(255) DEFAULT NULL, 35 | `description` text, 36 | `category_id` int(11) DEFAULT NULL, 37 | `godot_version` int(7) NOT NULL, 38 | `version_string` varchar(11) DEFAULT NULL, 39 | `cost` varchar(25) DEFAULT NULL, 40 | `download_provider` tinyint(4) DEFAULT NULL, 41 | `download_commit` varchar(2048) DEFAULT NULL, 42 | `browse_url` varchar(1024) DEFAULT NULL, 43 | `issues_url` varchar(1024) DEFAULT NULL, 44 | `icon_url` varchar(1024) DEFAULT NULL, 45 | `status` tinyint(4) NOT NULL DEFAULT '0', 46 | `reason` text NOT NULL, 47 | `submit_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 48 | `modify_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 49 | PRIMARY KEY (`edit_id`), 50 | KEY `asset_id` (`asset_id`), 51 | KEY `status` (`status`) 52 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 53 | DROP TABLE IF EXISTS `as_asset_edit_previews`; 54 | CREATE TABLE `as_asset_edit_previews` ( 55 | `edit_preview_id` int(11) NOT NULL AUTO_INCREMENT, 56 | `edit_id` int(11) NOT NULL, 57 | `preview_id` int(11) NOT NULL, 58 | `type` enum('image','video') DEFAULT NULL, 59 | `link` varchar(1024) DEFAULT NULL, 60 | `thumbnail` varchar(1024) DEFAULT NULL, 61 | `operation` tinyint(4) NOT NULL, 62 | PRIMARY KEY (`edit_preview_id`), 63 | KEY `asset_id` (`edit_id`), 64 | KEY `type` (`type`), 65 | KEY `preview_id` (`preview_id`) 66 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 67 | 68 | 69 | DROP TABLE IF EXISTS `as_asset_previews`; 70 | CREATE TABLE `as_asset_previews` ( 71 | `preview_id` int(11) NOT NULL AUTO_INCREMENT, 72 | `asset_id` int(11) NOT NULL, 73 | `type` enum('image','video') NOT NULL, 74 | `link` varchar(1024) NOT NULL, 75 | `thumbnail` varchar(1024) NOT NULL, 76 | PRIMARY KEY (`preview_id`), 77 | KEY `asset_id` (`asset_id`), 78 | KEY `type` (`type`) 79 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 80 | 81 | 82 | DROP TABLE IF EXISTS `as_categories`; 83 | CREATE TABLE `as_categories` ( 84 | `category_id` int(11) NOT NULL AUTO_INCREMENT, 85 | `category` varchar(25) NOT NULL, 86 | `category_type` tinyint(4) NOT NULL, 87 | PRIMARY KEY (`category_id`), 88 | UNIQUE KEY `name` (`category`) 89 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 90 | 91 | INSERT INTO `as_categories` (`category_id`, `category`, `category_type`) VALUES 92 | (1, '2D Tools', 0), 93 | (2, '3D Tools', 0), 94 | (3, 'Shaders', 0), 95 | (4, 'Materials', 0), 96 | (5, 'Tools', 0), 97 | (6, 'Scripts', 0), 98 | (7, 'Misc', 0), 99 | (8, 'Templates', 1), 100 | (9, 'Projects', 1), 101 | (10, 'Demos', 1); 102 | 103 | DROP TABLE IF EXISTS `as_users`; 104 | CREATE TABLE `as_users` ( 105 | `user_id` int(11) NOT NULL AUTO_INCREMENT, 106 | `username` varchar(100) NOT NULL, 107 | `email` varchar(1024) NOT NULL, 108 | `password_hash` varchar(64) NOT NULL, 109 | `type` tinyint(1) NOT NULL DEFAULT '0', 110 | `session_token` varbinary(24) DEFAULT NULL, 111 | `reset_token` binary(24) DEFAULT NULL, 112 | PRIMARY KEY (`user_id`), 113 | UNIQUE KEY `username` (`username`), 114 | UNIQUE KEY `session_token` (`session_token`), 115 | KEY `reset_token` (`reset_token`) 116 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 117 | 118 | -- add indexes 119 | ALTER TABLE `as_assets` ADD INDEX `godot_version_index` (`godot_version`); 120 | ALTER TABLE `as_asset_edits` ADD INDEX `godot_version_index` (`godot_version`); 121 | ALTER TABLE `as_users` ADD INDEX (`reset_token`); 122 | -------------------------------------------------------------------------------- /data/migration-1.sql: -------------------------------------------------------------------------------- 1 | -- Adminer 4.2.5 MySQL dump 2 | 3 | SET NAMES utf8; 4 | SET time_zone = '+00:00'; 5 | SET foreign_key_checks = 0; 6 | SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO'; 7 | 8 | DROP TABLE IF EXISTS `as_assets`; 9 | CREATE TABLE `as_assets` ( 10 | `asset_id` int(11) NOT NULL AUTO_INCREMENT, 11 | `user_id` int(11) NOT NULL DEFAULT '0', 12 | `title` varchar(255) NOT NULL, 13 | `description` text NOT NULL, 14 | `category_id` int(11) NOT NULL DEFAULT '6', 15 | `version` int(11) NOT NULL, 16 | `version_string` varchar(20) NOT NULL, 17 | `cost` varchar(25) NOT NULL DEFAULT 'GPLv3', 18 | `rating` int(11) NOT NULL DEFAULT '1', 19 | `support_level` tinyint(4) NOT NULL, 20 | `download_url` varchar(1024) NOT NULL, 21 | `download_hash` text NOT NULL, 22 | `browse_url` varchar(1024) NOT NULL, 23 | `icon_url` varchar(1024) NOT NULL, 24 | `searchable` tinyint(1) NOT NULL DEFAULT '0', 25 | `modify_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 26 | PRIMARY KEY (`asset_id`) 27 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 28 | 29 | 30 | DROP TABLE IF EXISTS `as_asset_edits`; 31 | CREATE TABLE `as_asset_edits` ( 32 | `edit_id` int(11) NOT NULL AUTO_INCREMENT, 33 | `asset_id` int(11) NOT NULL, 34 | `user_id` int(11) NOT NULL, 35 | `title` varchar(255) DEFAULT NULL, 36 | `description` text, 37 | `category_id` int(11) DEFAULT NULL, 38 | `version_string` varchar(11) DEFAULT NULL, 39 | `cost` varchar(25) DEFAULT NULL, 40 | `download_url` varchar(1024) DEFAULT NULL, 41 | `browse_url` varchar(1024) DEFAULT NULL, 42 | `icon_url` varchar(1024) DEFAULT NULL, 43 | `status` tinyint(4) NOT NULL DEFAULT '0', 44 | `reason` text NOT NULL, 45 | `submit_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 46 | `modify_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 47 | PRIMARY KEY (`edit_id`), 48 | KEY `asset_id` (`asset_id`), 49 | KEY `status` (`status`) 50 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 51 | 52 | 53 | DROP TABLE IF EXISTS `as_asset_edit_previews`; 54 | CREATE TABLE `as_asset_edit_previews` ( 55 | `edit_preview_id` int(11) NOT NULL AUTO_INCREMENT, 56 | `edit_id` int(11) NOT NULL, 57 | `preview_id` int(11) NOT NULL, 58 | `type` enum('image','video') DEFAULT NULL, 59 | `link` varchar(1024) DEFAULT NULL, 60 | `thumbnail` varchar(1024) DEFAULT NULL, 61 | `operation` tinyint(4) NOT NULL, 62 | PRIMARY KEY (`edit_preview_id`), 63 | KEY `asset_id` (`edit_id`), 64 | KEY `type` (`type`), 65 | KEY `preview_id` (`preview_id`) 66 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 67 | 68 | 69 | DROP TABLE IF EXISTS `as_asset_previews`; 70 | CREATE TABLE `as_asset_previews` ( 71 | `preview_id` int(11) NOT NULL AUTO_INCREMENT, 72 | `asset_id` int(11) NOT NULL, 73 | `type` enum('image','video') NOT NULL, 74 | `link` varchar(1024) NOT NULL, 75 | `thumbnail` varchar(1024) NOT NULL, 76 | PRIMARY KEY (`preview_id`), 77 | KEY `asset_id` (`asset_id`), 78 | KEY `type` (`type`) 79 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 80 | 81 | 82 | DROP TABLE IF EXISTS `as_categories`; 83 | CREATE TABLE `as_categories` ( 84 | `category_id` int(11) NOT NULL AUTO_INCREMENT, 85 | `category` varchar(25) NOT NULL, 86 | `category_type` tinyint(4) NOT NULL, 87 | PRIMARY KEY (`category_id`), 88 | UNIQUE KEY `name` (`category`) 89 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 90 | 91 | INSERT INTO `as_categories` (`category_id`, `category`, `category_type`) VALUES 92 | (1, '2D Tools', 0), 93 | (2, '3D Tools', 0), 94 | (3, 'Shaders', 0), 95 | (4, 'Materials', 0), 96 | (5, 'Tools', 0), 97 | (6, 'Scripts', 0), 98 | (7, 'Misc', 0), 99 | (8, 'Templates', 1), 100 | (9, 'Projects', 1), 101 | (10, 'Demos', 1); 102 | 103 | DROP TABLE IF EXISTS `as_users`; 104 | CREATE TABLE `as_users` ( 105 | `user_id` int(11) NOT NULL AUTO_INCREMENT, 106 | `username` varchar(100) NOT NULL, 107 | `email` varchar(1024) NOT NULL, 108 | `password_hash` varchar(64) NOT NULL, 109 | `type` tinyint(1) NOT NULL DEFAULT '0', 110 | `session_token` varbinary(24) DEFAULT NULL, 111 | PRIMARY KEY (`user_id`), 112 | UNIQUE KEY `username` (`username`), 113 | UNIQUE KEY `session_token` (`session_token`) 114 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 115 | 116 | 117 | -- 2016-07-25 18:15:07 118 | -------------------------------------------------------------------------------- /data/migration-2.sql: -------------------------------------------------------------------------------- 1 | 2 | 3 | ALTER TABLE `as_assets` ADD COLUMN `download_provider` TINYINT NOT NULL AFTER `download_url`; 4 | ALTER TABLE `as_assets` ADD `download_commit` VARCHAR(64) NOT NULL AFTER `download_provider`; 5 | 6 | UPDATE `as_assets` SET `download_provider`=0,`download_commit`= 7 | SUBSTRING(`download_url`, 8 | LOCATE('/',`download_url`,LOCATE('/',`download_url`,LOCATE('/',`download_url`,20)+1)+1)+1, 9 | -- Matching the last slash, which is V right below the `V` 10 | -- https://github.com/.../.../archive/....zip 11 | -- ^ This slash is the 19-th character 12 | LENGTH(`download_url`) - LOCATE('/',`download_url`,LOCATE('/',`download_url`,LOCATE('/',`download_url`,20)+1)+1) - 4 13 | -- Repeating locate formula :/ 14 | ) WHERE `download_url` RLIKE 'https:\/\/github.com\/[^\/]+\/[^\/]+\/archive\/[^\/]+.zip'; 15 | 16 | ALTER TABLE `as_assets` DROP COLUMN `download_url`; 17 | 18 | ALTER TABLE `as_asset_edits` ADD COLUMN `download_provider` TINYINT NULL AFTER `download_url`; 19 | ALTER TABLE `as_asset_edits` ADD `download_commit` VARCHAR(64) NULL AFTER `download_provider`; 20 | 21 | UPDATE `as_asset_edits` SET `download_provider`=0,`download_commit`= 22 | SUBSTRING(`download_url`, 23 | LOCATE('/',`download_url`,LOCATE('/',`download_url`,LOCATE('/',`download_url`,20)+1)+1)+1, 24 | -- Matching the last slash, which is V right below the `V` 25 | -- https://github.com/.../.../archive/....zip 26 | -- ^ This slash is the 19-th character 27 | LENGTH(`download_url`) - LOCATE('/',`download_url`,LOCATE('/',`download_url`,LOCATE('/',`download_url`,20)+1)+1) - 4 28 | -- Repeating locate formula :/ 29 | ) WHERE `download_url` RLIKE 'https:\/\/github.com\/[^\/]+\/[^\/]+\/archive\/[^\/]+.zip'; 30 | 31 | ALTER TABLE `as_asset_edits` DROP COLUMN `download_url`; 32 | -------------------------------------------------------------------------------- /data/migration-3.sql: -------------------------------------------------------------------------------- 1 | 2 | ALTER TABLE `as_assets` ADD `issues_url` VARCHAR(1024) NOT NULL AFTER `browse_url`; 3 | ALTER TABLE `as_asset_edits` ADD `issues_url` VARCHAR(1024) NULL DEFAULT NULL AFTER `browse_url`; -------------------------------------------------------------------------------- /data/migration-4.sql: -------------------------------------------------------------------------------- 1 | 2 | ALTER TABLE `as_users` ADD `reset_token` BINARY(32) NULL DEFAULT NULL AFTER `session_token`, ADD INDEX (`reset_token`); 3 | ALTER TABLE `as_users` CHANGE `session_token` `session_token` BINARY(24) NULL DEFAULT NULL; 4 | -------------------------------------------------------------------------------- /data/migration-5.sql: -------------------------------------------------------------------------------- 1 | 2 | ALTER TABLE `as_assets` ADD `godot_version` INT(7) NOT NULL AFTER `category_id`, ADD INDEX `godot_version_index` (`godot_version`); 3 | UPDATE `as_assets` SET `godot_version` = 20100 WHERE `godot_version` = 0; 4 | 5 | ALTER TABLE `as_asset_edits` ADD `godot_version` INT(7) NULL AFTER `category_id`, ADD INDEX `godot_version_index` (`godot_version`); 6 | UPDATE `as_asset_edits` SET `godot_version` = 20100 WHERE `asset_id` = -1; 7 | -------------------------------------------------------------------------------- /data/migration-6.sql: -------------------------------------------------------------------------------- 1 | 2 | ALTER TABLE `as_assets` CHANGE `download_commit` `download_commit` varchar(2048) NOT NULL; 3 | 4 | ALTER TABLE `as_asset_edits` CHANGE `download_commit` `download_commit` varchar(2048) NULL; 5 | -------------------------------------------------------------------------------- /data/migration-7.sql: -------------------------------------------------------------------------------- 1 | 2 | ALTER TABLE `as_assets` DROP `download_hash`; 3 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | &.git
), but give the one you use to browse your code.
109 | When using the Custom download provider, this is used for browsing only.
110 |