| @@ -0,0 +1,168 @@ | ||
|
|
||
| .manager-table { | ||
| font-size: 12px; | ||
| table-layout: fixed; | ||
| width: 738px; | ||
| } | ||
|
|
||
| .manager-table th { | ||
| text-align: left; | ||
| vertical-align: top; | ||
| width: 120px; | ||
| } | ||
|
|
||
| .manager-table td { | ||
| border-bottom: 1px solid #FFFFFF; | ||
| border-top: 1px solid #FFFFFF; | ||
| padding: 1px 3px 1px 3px; | ||
| text-align: left; | ||
| } | ||
|
|
||
| .depList { | ||
| margin-top: 0px; | ||
| margin-bottom: 0px; | ||
| padding-left: 20px; | ||
| } | ||
|
|
||
| #bananas-table { | ||
| font-size: 12px; | ||
| width: 100%; | ||
| } | ||
|
|
||
| #bananas-table th { | ||
| text-align: left; | ||
| text-decoration: underline; | ||
| } | ||
|
|
||
| #bananas-table td { | ||
| border-bottom: 1px solid #FFFFFF; | ||
| border-top: 1px solid #FFFFFF; | ||
| padding: 1px 3px 1px 3px; | ||
| text-align: left; | ||
| vertical-align: top; | ||
| } | ||
|
|
||
| #bananas-table .odd { | ||
| background-color: #EEEEEE; | ||
| } | ||
| #bananas-table .even { | ||
| background-color: #FFFFFF; | ||
| } | ||
| #bananas-table tr.odd:hover, #bananas-table tr.even:hover, #bananas-table tr.odd:hover td, #bananas-table tr.even:hover td { | ||
| background-color: #CCCCCC; | ||
| border-bottom: 1px dashed #000000; | ||
| border-top: 1px dashed #000000; | ||
| } | ||
|
|
||
| #bananas-table .name { | ||
| width: 250px; | ||
| } | ||
| #bananas-table .type { | ||
| width: 80px; | ||
| } | ||
| #bananas-table .version { | ||
| width: 80px; | ||
| } | ||
| #bananas-table .grf { | ||
| width: 70px; | ||
| } | ||
| #bananas-table .downloads { | ||
| width: 70px; | ||
| } | ||
| #bananas-table .date { | ||
| width: 70px; | ||
| } | ||
| #bananas-table .author { | ||
| width: 70px; | ||
| } | ||
| #bananas-table .deps { | ||
| width: 70px; | ||
| } | ||
| #bananas-table .license { | ||
| width: 100px; | ||
| } | ||
|
|
||
| /* the package table declarations are repetitive and can possibly be consolidated, they were written in a situation where JFDI > DRY */ | ||
| .package-info-table { | ||
| width: 100%; | ||
| } | ||
| .package-info-table th { | ||
| width: 150px; | ||
| vertical-align: top; | ||
| padding-top: 7px; | ||
| padding-bottom: 7px; | ||
| } | ||
| .package-info-table .tag-list { | ||
| margin: 0; | ||
| padding: 0; | ||
| } | ||
| .package-info-table .tag-list li { | ||
| display: inline-block; | ||
| padding-right: 10px; | ||
| margin-right: 10px; | ||
| border-right: solid 1px #ddd; | ||
| } | ||
| .package-info-table .author-list { | ||
| margin: 0; | ||
| padding: 0; | ||
| } | ||
| .package-info-table .author-list li { | ||
| list-style-type: none; | ||
| } | ||
|
|
||
| .package-edit-table th { | ||
| width: 150px; | ||
| vertical-align: top; | ||
| padding-top: 7px; | ||
| padding-bottom: 7px; | ||
| } | ||
| .package-edit-table .author-list { | ||
| margin: 0; | ||
| padding: 0; | ||
| } | ||
| .package-edit-table .author-list li { | ||
| list-style-type: none; | ||
| } | ||
|
|
||
| .package-upload-table th { | ||
| width: 150px; | ||
| vertical-align: top; | ||
| padding-top: 7px; | ||
| padding-bottom: 7px; | ||
| } | ||
| .package-upload-table .author-list { | ||
| margin: 0; | ||
| padding: 0; | ||
| } | ||
| .package-upload-table .author-list li { | ||
| list-style-type: none; | ||
| } | ||
|
|
||
| .package-version-edit-table th { | ||
| width: 150px; | ||
| vertical-align: top; | ||
| padding-top: 7px; | ||
| padding-bottom: 7px; | ||
| } | ||
| .package-version-edit-table .author-list { | ||
| margin: 0; | ||
| padding: 0; | ||
| } | ||
| .package-version-edit-table .author-list li { | ||
| list-style-type: none; | ||
| } | ||
|
|
||
| .package-version-info-table th { | ||
| width: 150px; | ||
| vertical-align: top; | ||
| padding-top: 7px; | ||
| padding-bottom: 7px; | ||
| } | ||
| .package-version-info-table .author-list { | ||
| margin: 0; | ||
| padding: 0; | ||
| } | ||
| .package-version-info-table .author-list li { | ||
| list-style-type: none; | ||
| } | ||
|
|
| @@ -0,0 +1,213 @@ | ||
| body { | ||
| margin: 0px; | ||
| padding: 0px; | ||
| text-align: center; | ||
| } | ||
| html { | ||
| background: url("/static/img/background.png") repeat; | ||
| color: black; | ||
| font-family: "Trebuchet MS", Arial, Verdana, Sans-Serif; | ||
| font-size: 12px; | ||
| } | ||
| select { | ||
| color: black; | ||
| } | ||
| img { | ||
| border: 0px; | ||
| } | ||
| a { | ||
| color: #DD6000; | ||
| } | ||
| hr { | ||
| background: url("/static/img/hr.png") repeat-x; | ||
| border: none; | ||
| height: 2px; | ||
| width: 95%; | ||
| } | ||
| h3, .h3 { | ||
| font-weight: normal; | ||
| font-size: 16px; | ||
| margin: 0px; | ||
| text-decoration: underline; | ||
| } | ||
| h4, .h4 { | ||
| font-weight: normal; | ||
| font-size: 14px; | ||
| margin: 0px; | ||
| } | ||
| h5, .h5 { | ||
| font-weight: normal; | ||
| font-size: 12px; | ||
| margin: 0px; | ||
| } | ||
|
|
||
| .nowrap { | ||
| overflow: hidden; | ||
| white-space: nowrap; | ||
|
|
||
| /* The following elements are not part of CSS2, but are required for some | ||
| * (broken) browsers who do not understand the former definitions. */ | ||
| text-overflow: ellipsis; | ||
| -o-text-overflow: ellipsis; | ||
| } | ||
|
|
||
| #header { | ||
| background: url("/static/img/header-bg.png") repeat; | ||
| height: 90px; | ||
| margin: 0px auto; | ||
| width: 940px; | ||
| } | ||
| #header-left { | ||
| background: url("/static/img/header-bg-left.png") repeat-y; | ||
| float: left; | ||
| height: 90px; | ||
| width: 15px; | ||
| } | ||
| #header-right { | ||
| background: url("/static/img/header-bg-right.png") repeat-y; | ||
| float: right; | ||
| height: 90px; | ||
| width: 15px; | ||
| } | ||
|
|
||
| #header-logo { | ||
| float: right; | ||
| width: 400px; | ||
| } | ||
|
|
||
| #ovh-header { | ||
| float: right; | ||
| height: 90px; | ||
| line-height: 11px; | ||
| margin-top: -2px; | ||
| margin-right: -6px; | ||
| padding: 0px; | ||
| width: 90px; | ||
| } | ||
| #openttd-logo { | ||
| background: url("/static/img/openttd-64.gif") no-repeat; | ||
| background-position: left center; | ||
| float: right; | ||
| height: 75px; | ||
| margin-top: 6px; | ||
| width: 250px; | ||
| } | ||
| #openttd-logo-text { | ||
| height: 29px; | ||
| margin: 36px 0px 0px 77px; | ||
| width: 151px; | ||
| } | ||
| #openttd-logo-text-noai { | ||
| height: 29px; | ||
| margin: 15px 0px 0px 75px; | ||
| width: 151px; | ||
| } | ||
| #openttd-logo-text-bananas { | ||
| height: 29px; | ||
| margin: 18px 0px 0px 75px; | ||
| width: 151px; | ||
| } | ||
| #openttd-logo-text-security { | ||
| height: 29px; | ||
| margin: 18px 0px 0px 75px; | ||
| width: 151px; | ||
| } | ||
| #openttd-logo-text-binaries { | ||
| height: 29px; | ||
| margin: 36px 0px 0px 77px; | ||
| width: 151px; | ||
| } | ||
| #openttd-logo-text-translator { | ||
| height: 29px; | ||
| margin: 28px 0px 0px 75px; | ||
| width: 151px; | ||
| } | ||
|
|
||
| #navigation { | ||
| background: url("/static/img/navigation-bg.png") repeat-x; | ||
| height: auto !important; | ||
| height: 32px; | ||
| margin: 0px auto; | ||
| min-height: 32px; | ||
| overflow: hidden; | ||
| width: 940px; | ||
| } | ||
| #navigation-left { | ||
| background: url("/static/img/navigation-bg-left.png") no-repeat; | ||
| float: left; | ||
| height: 32px; | ||
| width: 15px; | ||
| } | ||
| #navigation-right { | ||
| background: url("/static/img/navigation-bg-right.png") no-repeat; | ||
| float: right; | ||
| height: 32px; | ||
| width: 15px; | ||
| } | ||
| #navigation-bar { | ||
| float: left; | ||
| margin: 0px; | ||
| padding: 0px; | ||
| } | ||
| #navigation-bar li { | ||
| font-size: 12px; | ||
| float: left; | ||
| line-height: 32px; | ||
| list-style-type: none; | ||
| } | ||
| #navigation-bar li a { | ||
| color: #DDDDDD; | ||
| display: block; | ||
| padding: 0px 7px 0px 7px; | ||
| text-decoration: none; | ||
| } | ||
| #navigation-bar li a:hover { | ||
| background: url("/static/img/navigation-bg-hover.png") repeat-x; | ||
| color: #444444; | ||
| } | ||
| #navigation-bar li.selected { | ||
| background: url("/static/img/navigation-bg-selected.png") repeat-x; | ||
| } | ||
| #navigation-bar li.selected a { | ||
| color: #444444; | ||
| } | ||
|
|
||
| #content-main { | ||
| background-color: white; | ||
| margin: 7px auto; | ||
| width: 916px; | ||
| padding: 7px; | ||
| border-radius: 4px; | ||
| box-shadow: 0 0 3px rgba(0, 0, 0, 0.5); | ||
| } | ||
| #content-bottom-links { | ||
| float: left; | ||
| font-size: 11px; | ||
| padding: 7px 5px 0px 5px; | ||
| } | ||
| #content-bottom-copyright { | ||
| float: right; | ||
| font-size: 11px; | ||
| padding: 7px 5px 0px 5px; | ||
| } | ||
| #content { | ||
| margin: 0px 12px 0px 12px; | ||
| padding-top: 12px; | ||
| } | ||
| body > footer { | ||
| background-color: white; | ||
| margin: 12px auto 36px auto; | ||
| padding: 7px 7px 6px 7px; | ||
| overflow: hidden; | ||
| border-radius: 5px; | ||
| box-shadow: 0 0 3px 3px rgba(0, 0, 0, 0.11); | ||
| width: 916px; | ||
| } | ||
|
|
||
| #hr-clear { | ||
| clear: both; | ||
| } | ||
|
|
||
| .mono { | ||
| font-family: 'Courier New', monospace; | ||
| } |
| @@ -0,0 +1,57 @@ | ||
|
|
||
| #section, #section-full { | ||
| text-align: left; | ||
| } | ||
| .section-header { | ||
| background: url("/static/img/section-bg.png") no-repeat; | ||
| color: #365800; | ||
| line-height: 38px; | ||
| height: 38px; | ||
| padding: 0px 0px 0px 10px; | ||
| text-align: left; | ||
| width: 500px; | ||
| } | ||
| .section-header h1 { | ||
| font-size: 18px; | ||
| margin-right: 20px; | ||
| margin-top: 0; | ||
| text-decoration: none; | ||
| } | ||
|
|
||
| .section-item { | ||
| padding-top: 10px; | ||
| } | ||
| .section-item .title { | ||
| font-size: 16px; | ||
| float: left; | ||
| padding-top: 5px; | ||
| } | ||
| .section-item .title h3, .section-list li .header, .section-item .title a { | ||
| color: #000000; | ||
| font-size: 18px; | ||
| font-weight: bold; | ||
| text-decoration: none; | ||
| } | ||
| .section-item .date { | ||
| text-align: right; | ||
| } | ||
| .section-item .user { | ||
| text-align: right; | ||
| padding-bottom: 5px; | ||
| } | ||
| .section-item .content { | ||
| border-top: 1px solid #EEEEEE; | ||
| font-size: 14px; | ||
| padding-top: 15px; | ||
| padding-bottom: 30px; | ||
| } | ||
|
|
||
| .section-list { | ||
| list-style-type: none; | ||
| } | ||
|
|
||
| .right { | ||
| float: right; | ||
| margin-bottom: 20px; | ||
| } | ||
|
|
| @@ -0,0 +1,109 @@ | ||
| "use strict"; | ||
|
|
||
| var file_list = document.querySelector("ul[id='file_list']"); | ||
| var tus_url = file_list.dataset.tusUrl; | ||
| var upload_token = file_list.dataset.uploadToken; | ||
|
|
||
| for (let file of file_list.getElementsByTagName("li")) { | ||
| let filename = file.dataset.filename; | ||
| if (filename == null) continue; | ||
|
|
||
| let button = file.querySelector("button"); | ||
| button.addEventListener('click', function() { | ||
| remove_file(filename); | ||
| }); | ||
| } | ||
|
|
||
| var more_files = document.querySelector("li[id='more_files']"); | ||
| var file_selector = document.querySelector("input[id='file_selector']"); | ||
| var button_start = document.querySelector("button[id='start_upload']"); | ||
| var removed_files = document.querySelector("input[id='removed_files']"); | ||
| var button_validate = document.querySelector("button[id='validate']"); | ||
| var button_publish = document.querySelector("button[id='publish']"); | ||
| button_start.addEventListener("click", add_upload); | ||
|
|
||
| var upload_queue = []; | ||
| var upload_file = null; | ||
| var upload_id = null; | ||
| var upload_instance = null; | ||
|
|
||
| function get_uuid() { | ||
| let url = upload_instance.url; | ||
| return url.substr(url.lastIndexOf("/") + 1); | ||
| } | ||
|
|
||
| function get_file(filename) { | ||
| for (let file of file_list.getElementsByTagName("li")) { | ||
| if (file.dataset.filename == filename) return file; | ||
| } | ||
| return null; | ||
| } | ||
|
|
||
| function remove_file(filename) { | ||
| upload_queue = upload_queue.filter(file => file.name != filename); | ||
| if (upload_instance != null && upload_file.name == filename) { | ||
| upload_instance.abort(); | ||
| } | ||
| let file = get_file(filename); | ||
| if (file != null) { | ||
| let uuid = file.dataset.uuid; | ||
| if (uuid != null) { | ||
| removed_files.value = removed_files.value.concat(",", uuid); | ||
| } | ||
| file.remove(); | ||
| } | ||
| } | ||
|
|
||
| function add_file(filename, status) { | ||
| let new_li = document.createElement("li"); | ||
| new_li.dataset.filename = filename; | ||
| new_li.appendChild(document.createTextNode(filename + " ")); | ||
|
|
||
| let new_status = document.createElement("span"); | ||
| new_status.appendChild(document.createTextNode(status)); | ||
| new_li.appendChild(new_status); | ||
| new_li.appendChild(document.createTextNode(" ")); | ||
|
|
||
| let new_button = document.createElement("button"); | ||
| new_button.type = "button"; | ||
| new_button.addEventListener('click', function() { | ||
| remove_file(filename); | ||
| }); | ||
| new_button.appendChild(document.createTextNode("Delete file")); | ||
| new_li.appendChild(new_button); | ||
|
|
||
| file_list.insertBefore(new_li, more_files); | ||
| } | ||
|
|
||
| function set_file_status(filename, uuid, status) { | ||
| let file = get_file(filename); | ||
| if (file != null) { | ||
| file.dataset.uuid = uuid; | ||
| let old_status = file.querySelector("span"); | ||
| old_status.textContent = status; | ||
| } | ||
| } | ||
|
|
||
| function add_upload() { | ||
| if (file_selector.value == "") return; | ||
| for (let i = 0; i < file_selector.files.length; i++) { | ||
| let file = file_selector.files[i]; | ||
| if (get_file(file.name) != null) continue; | ||
| upload_queue.push(file); | ||
| add_file(file.name, "queued..."); | ||
| } | ||
| file_selector.value = ""; | ||
| if (upload_instance == null) start_next_upload(); | ||
| } | ||
|
|
||
| function start_next_upload() { | ||
| button_validate.disabled = upload_queue.length > 0; | ||
| button_publish.disabled = upload_queue.length > 0; | ||
| if (upload_queue.length == 0) return; | ||
|
|
||
| upload_file = upload_queue[0]; | ||
| upload_queue.shift(); | ||
|
|
||
| set_file_status(upload_file.name, "abcd", "(" + Math.floor(123456 / 1024) + " kB)"); | ||
| start_next_upload(); | ||
| } |
| @@ -1,55 +1,70 @@ | ||
| {% extends 'base.html' %} | ||
| {% block header %} | ||
| <h1>{% block title %}{{ package["name"] }}{% endblock %}</h1> | ||
| <h3>{{ package["content-type"] }}/{{ package["unique-id"] }}</h3> | ||
| {% endblock %} | ||
| {% block content %} | ||
|
|
||
| <a href="/manager/{{ package["content-type"] }}/{{ package["unique-id"] }}/edit">Edit package meta data</a> | ||
| <table> | ||
| <tr><td>Content Id</td><td>{{ package["content-type"] }}/{{ package["unique-id"] }}</td></tr> | ||
| <tr><td>Name</td><td>{{ package["name"] }}</td></tr> | ||
| <tr><td>Project site</td><td> | ||
| {% if package["url"] %} | ||
| <a href="{{ package["url"] }}" target="_blank">{{ package["url"] }}</a> | ||
| {% endif %} | ||
| </td></tr> | ||
| <tr><td>Tags</td><td><ul> | ||
| {% for t in package["tags"] %} | ||
| <li>{{ t }}</li> | ||
| {% endfor %} | ||
| </ul></td></tr> | ||
| <tr><td>Authors</td><td><ul> | ||
| {% for a in package["authors"] %} | ||
| <li>{{ a["display-name"] }}</li> | ||
| {% endfor %} | ||
| </ul></td></tr> | ||
| <tr><td>Description</td><td> | ||
| {% for l in package["description"].splitlines() %} | ||
| {{ l }}<br/> | ||
| {% endfor %} | ||
| </td></tr> | ||
| <p><a href="/manager/{{ package["content-type"] }}/{{ package["unique-id"] }}/edit">Edit package meta data</a></p> | ||
|
|
||
| <table class="package-info-table"> | ||
| <tbody> | ||
| <tr><th>Content Id</th><td>{{ package["content-type"] }}/{{ package["unique-id"] }}</td></tr> | ||
| <tr><th>Name</th><td>{{ package["name"] }}</td></tr> | ||
| <tr><th>Project site</th><td> | ||
| {% if package["url"] %} | ||
| <a href="{{ package["url"] }}" target="_blank">{{ package["url"] }}</a> | ||
| {% endif %} | ||
| {% if not package["url"] %} | ||
| - | ||
| {% endif %} | ||
| </td></tr> | ||
| <tr><th>Tags</th><td> | ||
| <ul class="tag-list"> | ||
| {% for t in package["tags"] %} | ||
| <li>{{ t }}</li> | ||
| {% endfor %} | ||
| </ul> | ||
| </td></tr> | ||
| <tr><th>Authors</th><td> | ||
| <ul class="author-list"> | ||
| {% for a in package["authors"] %} | ||
| <li>{{ a["display-name"] }}</li> | ||
| {% endfor %} | ||
| </ul> | ||
| </td></tr> | ||
| <tr><th>Description</th><td> | ||
| {% for l in package.get("description", "").splitlines() %} | ||
| {{ l }}<br/> | ||
| {% endfor %} | ||
| </td></tr> | ||
| </tbody> | ||
| </table> | ||
|
|
||
| <table> | ||
| <tr> | ||
| <th>Version</th> | ||
| <th>Upload date</th> | ||
| <th>MD5 (partial)</th> | ||
| <th>License</th> | ||
| <th>Availability</th> | ||
| <th>Edit meta data</th> | ||
| </tr> | ||
| <hr /> | ||
|
|
||
| <table id="bananas-table"> | ||
| <thead> | ||
| <tr> | ||
| <th>Version</th> | ||
| <th>Upload date</th> | ||
| <th>MD5 (partial)</th> | ||
| <th>License</th> | ||
| <th>Availability</th> | ||
| <th>Edit meta data</th> | ||
| </tr> | ||
| </thead> | ||
| <tbody> | ||
| {% for version in package["versions"] %} | ||
| <tr> | ||
| <td><a href="/manager/{{ package["content-type"] }}/{{ package["unique-id"] }}/{{ version["upload-date"] }}">{{ version["version"] }}</a></td> | ||
| <td>{{ version["upload-date"] }}</td> | ||
| <td>{{ version["md5sum-partial"] }}</td> | ||
| <td>{{ version["license"] }}</td> | ||
| <td>{{ version["availability"] }}</td> | ||
| <td><a href="/manager/{{ package["content-type"] }}/{{ package["unique-id"] }}/{{ version["upload-date"] }}/edit">Edit</a></td> | ||
| </tr> | ||
| <tr> | ||
| <td><a href="/manager/{{ package["content-type"] }}/{{ package["unique-id"] }}/{{ version["upload-date"] }}">{{ version["version"] }}</a></td> | ||
| <td>{{ version["upload-date"] }}</td> | ||
| <td>{{ version["md5sum-partial"] }}</td> | ||
| <td>{{ version["license"] }}</td> | ||
| <td>{{ version["availability"] }}</td> | ||
| <td><a href="/manager/{{ package["content-type"] }}/{{ package["unique-id"] }}/{{ version["upload-date"] }}/edit">Edit</a></td> | ||
| </tr> | ||
| {% endfor %} | ||
| </tbody> | ||
| </table> | ||
|
|
||
| {% endblock %} |
| @@ -1,64 +1,74 @@ | ||
| {% extends 'base.html' %} | ||
| {% block header %} | ||
| <h1>{% block title %}{{ package["name"] }}{% endblock %}</h1> | ||
| <h3>{{ package["content-type"] }}/{{ package["unique-id"] }}</h3> | ||
| <p>{{ package["content-type"] }}/{{ package["unique-id"] }}</p> | ||
| {% endblock %} | ||
| {% block content %} | ||
|
|
||
| {% if package.get("archived") %} | ||
| <p><b> This content is archived and is no longer available for new games. </b></p> | ||
| {% endif %} | ||
| {% if package.get("replaced-by") %} | ||
| <p><b> This content is deprecated. Please use <a href="/package/{{ package["content-type"] }}/{{ package["replaced-by"]["unique-id"] }}">{{ package["replaced-by"]["name"] }} ({{ package["replaced-by"]["unique-id"] }})</a> instead. </b></p> | ||
| <p><b> This content is deprecated. Please use <a href="/package/{{ package["replaced-by"]["content-type"] }}/{{ package["replaced-by"]["unique-id"] }}">{{ package["replaced-by"]["name"] }} ({{ package["replaced-by"]["unique-id"] }})</a> instead. </b></p> | ||
| {% endif %} | ||
|
|
||
| <table> | ||
| <tr><td>Content type</td><td>{{ package["content-type"] }}</td></tr> | ||
| <tr><td>Content Id</td><td>{{ package["unique-id"] }}</td></tr> | ||
| <tr><td>Name</td><td>{{ package["name"] }}</td></tr> | ||
| <tr><td>Project site</td><td> | ||
| {% if package["url"] %} | ||
| <a href="{{ package["url"] }}" target="_blank">{{ package["url"] }}</a> | ||
| {% endif %} | ||
| </td></tr> | ||
| <tr><td>Tags</td><td><ul> | ||
| {% for t in package["tags"] %} | ||
| <li>{{ t }}</li> | ||
| {% endfor %} | ||
| </ul></td></tr> | ||
| <tr><td>Authors</td><td><ul> | ||
| {% for a in package["authors"] %} | ||
| <li>{{ a["display-name"] }}</li> | ||
| {% endfor %} | ||
| </ul></td></tr> | ||
| <tr><td>Description</td><td> | ||
| {% for l in package["description"].splitlines() %} | ||
| {{ l }}<br/> | ||
| <tbody> | ||
| <tr><th>Content type</th><td>{{ package["content-type"] }}</td></tr> | ||
| <tr><th>Content Id</th><td>{{ package["unique-id"] }}</td></tr> | ||
| <tr><th>Name</th><td>{{ package["name"] }}</td></tr> | ||
| <tr><th>Project site</th><td> | ||
| {% if package["url"] %} | ||
| <a href="{{ package["url"] }}" target="_blank">{{ package["url"] }}</a> | ||
| {% endif %} | ||
| </td></tr> | ||
| <tr><th>Tags</th><td> | ||
| <ul> | ||
| {% for t in package["tags"] %} | ||
| <li>{{ t }}</li> | ||
| {% endfor %} | ||
| </td></tr> | ||
| </ul> | ||
| </td></tr> | ||
| <tr><th>Authors</th><td> | ||
| <ul> | ||
| {% for a in package["authors"] %} | ||
| <li>{{ a["display-name"] }}</li> | ||
| {% endfor %} | ||
| </ul> | ||
| </td></tr> | ||
| <tr><th>Description</th><td> | ||
| {% for l in package.get("description", "").splitlines() %} | ||
| {{ l }}<br/> | ||
| {% endfor %} | ||
| </td></tr> | ||
| </tbody> | ||
| </table> | ||
|
|
||
| <table> | ||
| <tr> | ||
| <th>Version</th> | ||
| <th>Upload date</th> | ||
| <th>MD5 (partial)</th> | ||
| <th>License</th> | ||
| <th>Download</th> | ||
| </tr> | ||
| <thead> | ||
| <tr> | ||
| <th>Version</th> | ||
| <th>Upload date</th> | ||
| <th>MD5 (partial)</th> | ||
| <th>License</th> | ||
| <th>Download</th> | ||
| </tr> | ||
| </thead> | ||
| <tbody> | ||
| {% for version in package["versions"] %} | ||
| <tr> | ||
| <td><a href="/package/{{ package["content-type"] }}/{{ package["unique-id"] }}/{{ version["upload-date"] }}">{{ version["version"] }}</a></td> | ||
| <td>{{ version["upload-date"] }}</td> | ||
| <td>{{ version["md5sum-partial"] }}</td> | ||
| <td>{{ version["license"] }}</td> | ||
| {% if version["download-url"] %} | ||
| <td><a href="{{ version["download-url"] }}">{{ (version["filesize"] | int) // 1024 }} kB</a></td> | ||
| {% else %} | ||
| <td>Not available</td> | ||
| {% endif %} | ||
| </tr> | ||
| <tr> | ||
| <td><a href="/package/{{ package["content-type"] }}/{{ package["unique-id"] }}/{{ version["upload-date"] }}">{{ version["version"] }}</a></td> | ||
| <td>{{ version["upload-date"] }}</td> | ||
| <td>{{ version["md5sum-partial"] }}</td> | ||
| <td>{{ version["license"] }}</td> | ||
| {% if version["download-url"] %} | ||
| <td><a href="{{ version["download-url"] }}">{{ (version["filesize"] | int) // 1024 }} kB</a></td> | ||
| {% else %} | ||
| <td>Not available</td> | ||
| {% endif %} | ||
| </tr> | ||
| {% endfor %} | ||
| </tbody> | ||
| </table> | ||
|
|
||
| {% endblock %} |
| @@ -0,0 +1,37 @@ | ||
| {% extends 'base.html' %} | ||
| {% block header %} | ||
| <h1>{% block title %}Terms of Service{% endblock %}</h1> | ||
| <p>Version 1.0, 2009-01-17</p> | ||
| {% endblock %} | ||
| {% block content %} | ||
| <ol type="1"> | ||
| <li>You will only upload content of which you are (one of) the original author(s).</li> | ||
| <li>You grant the OpenTTD team the rights to distribute the last version of your content from a central server. We will assign a globally unique identifier to each upload and everyone can download the content when they know that identifier.</li> | ||
| <li>You grant the OpenTTD team to distribute your latest content via our website.</li> | ||
| <li>You grant the OpenTTD team to retain older versions of your content for the purpose of loading save games with said older version.</li> | ||
| <li>You grant the OpenTTD team the rights to distribute your content from a central server when specifically asked for it by its unique identifier and MD5 checksum. The origin of the unique identifier and MD5 checksum differs per type of content: | ||
| <ol type="a"> | ||
| <li>Base graphics: unique identifier is constructed from the four character short name defined in the .obg file. The MD5 checksum is the exclusive or of the MD5 checksum of the 6 GRFs that are part of the graphics pack.</li> | ||
| <li>NewGRFs: unique identifier is constructed from the GRF ID. The MD5 checksum is the MD5 checksum of the .grf file.</li> | ||
| <li>AIs and AI Libraries: unique identifier is constructed from the four character short name defined in the info.nut. The MD5 checksum is the exclusive or of the MD5 checksums of all scripting files that are part of the AI or AI Library.</li> | ||
| <li>Heightmaps and scenarios: unique identifier is automatically generated when you upload the content. The MD5 checksum is the MD5 checksum of the scenario/heightmap.</li> | ||
| </ol> | ||
| </li> | ||
| <li>You grant the OpenTTD team the rights to repackage your content before publishing it. The repackaging: | ||
| <ol type="a"> | ||
| <li>keeps files called "readme", "license" and "copying" with .txt or .pdf as extension or without an extension.</li> | ||
| <li>requires a "license" or "copying" file in the package file or requires that you selected a non-custom license when uploading the package. In the latter case that license will be added to the package.</li> | ||
| <li>renames files called "copying" to "license" retaining the extension.</li> | ||
| <li>requires exactly one .grf file in NewGRF packages.</li> | ||
| <li>requires exactly one .obg file and exactly six .grf files in Base graphics packages as named in the .obg file and with the same MD5 checksums as defined in the .obg file.</li> | ||
| <li>requires .nut files in AI and AI Library packages.</li> | ||
| <li>changes newlines from .txt files to "DOS" (\r\n) newlines.</li> | ||
| <li>changes newlines from .nut and .obg files to "unix" (\n) newlines.</li> | ||
| <li>requires a "main.nut" and "info.nut" in AI packages.</li> | ||
| <li>requires a "main.nut" and "library.nut" in AI Library packages.</li> | ||
| <li>requires exactly one .scn or one .sv0 or one .ss0 file in Scenario packages.</li> | ||
| <li>requires exactly one .png or one .bmp file in Heightmap packages.</li> | ||
| </ol> | ||
| </li> | ||
| </ol> | ||
| {% endblock %} |
| @@ -0,0 +1,39 @@ | ||
| {% extends 'base.html' %} | ||
| {% block header %} | ||
| <h1>{% block title %}Terms of Service{% endblock %}</h1> | ||
| <p>Version 1.1, 2009-08-10</p> | ||
| {% endblock %} | ||
| {% block content %} | ||
| <ol type="1"> | ||
| <li>You will only upload content of which you are (one of) the original author(s).</li> | ||
| <li>You grant the OpenTTD team the rights to distribute the last version of your content from a central server. We will assign a globally unique identifier to each upload and everyone can download the content when they know that identifier.</li> | ||
| <li>You grant the OpenTTD team to distribute your latest content via our website.</li> | ||
| <li>You grant the OpenTTD team to retain older versions of your content for the purpose of loading save games with said older version.</li> | ||
| <li>You grant the OpenTTD team the rights to distribute your content from a central server when specifically asked for it by its unique identifier and MD5 checksum. The origin of the unique identifier and MD5 checksum differs per type of content: | ||
| <ol type="a"> | ||
| <li>Base graphics: unique identifier is constructed from the four character short name defined in the .obg file. The MD5 checksum is the exclusive or of the MD5 checksum of the 6 GRFs that are part of the graphics pack.</li> | ||
| <li>NewGRFs: unique identifier is constructed from the GRF ID. The MD5 checksum is the MD5 checksum of the .grf file.</li> | ||
| <li>AIs and AI Libraries: unique identifier is constructed from the four character short name defined in the info.nut. The MD5 checksum is the exclusive or of the MD5 checksums of all scripting files that are part of the AI or AI Library.</li> | ||
| <li>Heightmaps and scenarios: unique identifier is automatically generated when you upload the content. The MD5 checksum is the MD5 checksum of the scenario/heightmap.</li> | ||
| <li>Base sound: unique identifier is constructed from the four character short name defined in the .obs file. The MD5 checksum is the MD5 checksum of the cat file that is part of the sound pack.</li> | ||
| </ol> | ||
| </li> | ||
| <li>You grant the OpenTTD team the rights to repackage your content before publishing it. The repackaging: | ||
| <ol type="a"> | ||
| <li>keeps files called "readme", "license" and "copying" with .txt or .pdf as extension or without an extension.</li> | ||
| <li>requires a "license" or "copying" file in the package file or requires that you selected a non-custom license when uploading the package. In the latter case that license will be added to the package.</li> | ||
| <li>renames files called "copying" to "license" retaining the extension.</li> | ||
| <li>requires exactly one .grf file in NewGRF packages.</li> | ||
| <li>requires exactly one .obg file and exactly six .grf files in Base graphics packages as named in the .obg file and with the same MD5 checksums as defined in the .obg file.</li> | ||
| <li>requires .nut files in AI and AI Library packages.</li> | ||
| <li>changes newlines from .txt files to "DOS" (\r\n) newlines.</li> | ||
| <li>changes newlines from .nut, .obg and .obs files to "unix" (\n) newlines.</li> | ||
| <li>requires a "main.nut" and "info.nut" in AI packages.</li> | ||
| <li>requires a "main.nut" and "library.nut" in AI Library packages.</li> | ||
| <li>requires exactly one .scn or one .sv0 or one .ss0 file in Scenario packages.</li> | ||
| <li>requires exactly one .png or one .bmp file in Heightmap packages.</li> | ||
| <li>requires exactly one .obs file and exactly one .cat file in Base sound packages as named in the .obs file and with the same MD5 checksum as defined in the .obs file.</li> | ||
| </ol> | ||
| </li> | ||
| </ol> | ||
| {% endblock %} |
| @@ -0,0 +1,41 @@ | ||
| {% extends 'base.html' %} | ||
| {% block header %} | ||
| <h1>{% block title %}Terms of Service{% endblock %}</h1> | ||
| <p>Version 1.3, 2020-04-23</p> | ||
| {% endblock %} | ||
| {% block content %} | ||
| <ol type="1"> | ||
| <li>You will only upload content of which you are (one of) the original author(s).</li> | ||
| <li>You grant the OpenTTD team the rights to distribute the last version of your content from a central server. We will assign a globally unique identifier to each upload and everyone can download the content when they know that identifier.</li> | ||
| <li>You grant the OpenTTD team to distribute your latest content via our website.</li> | ||
| <li>You grant the OpenTTD team to retain older versions of your content for the purpose of loading save games with said older version.</li> | ||
| <li>You grant the OpenTTD team the rights to distribute your content from a central server when specifically asked for it by its unique identifier and MD5 checksum. The origin of the unique identifier and MD5 checksum differs per type of content: | ||
| <ol type="a"> | ||
| <li>Base graphics: unique identifier is constructed from the four character short name defined in the .obg file. The MD5 checksum is the exclusive or of the MD5 checksum of the 6 GRFs that are part of the graphics pack.</li> | ||
| <li>NewGRFs: unique identifier is constructed from the GRF ID. The MD5 checksum is the MD5 checksum of the .grf file.</li> | ||
| <li>AIs and AI Libraries: unique identifier is constructed from the four character short name defined in the info.nut. The MD5 checksum is the exclusive or of the MD5 checksums of all scripting files that are part of the AI or AI Library.</li> | ||
| <li>Heightmaps and scenarios: unique identifier is automatically generated when you upload the content. The MD5 checksum is the MD5 checksum of the scenario/heightmap.</li> | ||
| <li>Base sound: unique identifier is constructed from the four character short name defined in the .obs file. The MD5 checksum is the MD5 checksum of the cat file that is part of the sound pack.</li> | ||
| <li>Base music: unique identifier is constructed from the four character short name defined in the .obm file. The MD5 checksum is the exclusive or of MD5 checksum of the music files that are part of the music pack. If they are mentioned multiple times in the .obm file they are exclusive or-ed multiple times. </li> | ||
| </ol> | ||
| </li> | ||
| <li>You grant the OpenTTD team the rights to repackage your content before publishing it. The repackaging: | ||
| <ol type="a"> | ||
| <li>keeps files called "readme", "license" and "changelog" with .txt as extension.</li> | ||
| <li>requires a "license.txt" file in the package file or requires that you selected a non-custom license when uploading the package. In the latter case that license will be added to the package.</li> | ||
| <li>(deleted)</li> | ||
| <li>requires exactly one .grf file in NewGRF packages.</li> | ||
| <li>requires exactly one .obg file and exactly six .grf files in Base graphics packages as named in the .obg file and with the same MD5 checksums as defined in the .obg file.</li> | ||
| <li>requires .nut files in AI and AI Library packages.</li> | ||
| <li>(deleted)</li> | ||
| <li>(deleted)</li> | ||
| <li>requires a "main.nut" and "info.nut" in AI packages.</li> | ||
| <li>requires a "main.nut" and "library.nut" in AI Library packages.</li> | ||
| <li>requires exactly one .scn file in Scenario packages.</li> | ||
| <li>requires exactly one .png file in Heightmap packages.</li> | ||
| <li>requires exactly one .obs file and exactly one .cat file in Base sound packages as named in the .obs file and with the same MD5 checksum as defined in the .obs file.</li> | ||
| <li>requires exactly one .obm file and a number of music files in Base music packages as named in the .obm file and with the same MD5 checksum as defined in the .obm file.</li> | ||
| </ol> | ||
| </li> | ||
| </ol> | ||
| {% endblock %} |