Python script, Unicode text, UTF-8 text executable
        
            1
            import os 
        
            2
            from dotenv import load_dotenv 
        
            3
            load_dotenv("secrets.env") 
        
            5
            DB_PASSWORD: str = os.environ.get("DB_PASSWORD") 
        
            7
            DB_URI: str = f"postgresql://root:{DB_PASSWORD}@localhost/roundabout" 
        
            8
            REDIS_URI: str = "redis://localhost" 
        
            9
            MAIL_SERVER: str = "localhost" 
        
            10
            NOTIFICATION_EMAIL: str = "notifications@roundabout-host.com" 
        
            11
            CONTACT_EMAIL: str = "root@roundabout-host.com" 
        
            12
            REPOS_PATH: str = "./repos" 
        
            14
            USERDATA_PATH: str = "./userdata" 
        
            15
            DEFAULT_AVATARS_PATH: str = "default_avatars" 
        
            16
            BASE_DOMAIN: str = "localhost" 
        
            17
            SERVER_IPS: set = {"127.0.0.1", "localhost", "0.0.0.0"} 
        
            18
            AUTH_REALM: str = "roundabout" 
        
            19
            MAX_PAYLOAD_SIZE: int = 4 * 1024**3 
        
            20
            AVATAR_SIZE: tuple = (192, 192) 
        
            22
            HASHING_ROUNDS: int = 11 
        
            24
            RESERVED_NAMES: tuple = ("git", "settings", "logout", "accounts", "info", "notifications", "about", "newrepo", "favourites",) 
        
            25
            suggest_https: bool = True 
        
            27
            available_locales: list[str] = ["ro_RO", "en_GB"] 
        
            29
            folder_icon: str = "mdi:folder" 
        
            31
            unknown_icon: str = "mdi:file" 
        
            32
            file_icons: dict = { 
        
            33
                "text/plain": "ic:baseline-text-snippet", 
        
            34
                "text/css": "simple-icons:css3", 
        
            35
                "text/csv": "mdi:table", 
        
            36
                "text/html": "simple-icons:html5", 
        
            37
                "text/calendar": "mdi:calendar", 
        
            38
                "text/javascript": "simple-icons:javascript", 
        
            39
                "text/xml": "mdi:xml", 
        
            40
                "text/markdown": "simple-icons:markdown", 
        
            41
                "application/octet-stream": "mdi:numeric-10-box", 
        
            43
                "application/x-abiword": "mdi:file-document", 
        
            44
                "application/x-msword": "mdi:file-document", 
        
            45
                "application/vnd.openxmlformats-officedocument.wordprocessingml.document": "mdi:file-document", 
        
            46
                "application/vnd.oasis.opendocument.text": "mdi:file-document", 
        
            47
                "application/rtf": "mdi:file-document", 
        
            48
                "application/x-dvi": "mdi:file-document", 
        
            49
                "application/epub+zip": "mdi:book-open-variant", 
        
            50
                "application/pdf": "mdi:book-open-variant", 
        
            51
                "application/x-freearc": "mdi:archive", 
        
            52
                "application/x-bzip": "mdi:archive", 
        
            53
                "application/x-bzip2": "mdi:archive", 
        
            54
                "application/gzip": "mdi:archive", 
        
            55
                "application/x-tar": "mdi:archive", 
        
            56
                "application/zip": "mdi:archive", 
        
            57
                "application/x-7z-compressed": "mdi:archive", 
        
            58
                "application/vnd.rar": "mdi:archive", 
        
            59
                "application/x-rar-compressed": "mdi:archive", 
        
            60
                "application/java-archive": "simple-icons:openjdk", 
        
            61
                "application/vnd.amazon.ebook": "mdi:cellphone-text", 
        
            62
                "application/x-cdf": "mdi:disc-player", 
        
            63
                "application/x-csh": "ic:baseline-terminal", 
        
            64
                "application/x-sh": "ic:baseline-terminal", 
        
            65
                "application/xml": "mdi:xml", 
        
            66
                "application/json": "mdi:code-json", 
        
            67
                "application/ld+json": "mdi:code-json", 
        
            68
                "application/vnd.apple.installer+xml": "simple-icons:apple", 
        
            69
                "application/vnd.oasis.opendocument.presentation": "mdi:presentation", 
        
            70
                "application/vnd.ms-powerpoint": "mdi:presentation", 
        
            71
                "application/vnd.openxmlformats-officedocument.presentationml.presentation": "mdi:presentation", 
        
            72
                "application/vnd.oasis.opendocument.spreadsheet": "mdi:table-large", 
        
            73
                "application/vnd.ms-excel": "mdi:table-large", 
        
            74
                "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "mdi:table-large", 
        
            75
                "application/x-httpd-php": "mdi:server", 
        
            76
                "application/xhtml+xml": "simple-icons:html5", 
        
            77
                "application/vnd.android.package-archive": "bi:android2", 
        
            78
                "application/x-x509-ca-cert": "mdi:certificate", 
        
            79
                "application/x-shockwave-flash": "simple-icons:adobe", 
        
            80
                "application/font-woff": "mdi:format-text", 
        
            81
                "application/x-font-truetype": "mdi:format-text", 
        
            82
                "application/x-font-opentype": "mdi:format-text", 
        
            83
                "application/vnd.ms-fontobject": "mdi:format-text", 
        
            84
                "audio/aac": "mdi:music", 
        
            86
                "audio/mp3": "mdi:music", 
        
            87
                "audio/ogg": "mdi:music", 
        
            88
                "audio/opus": "mdi:music", 
        
            89
                "audio/wav": "mdi:music", 
        
            90
                "audio/webm": "mdi:music", 
        
            91
                "audio/3gpp": "mdi:music", 
        
            92
                "audio/3gpp2": "mdi:music", 
        
            93
                "audio/midi": "mdi:piano", 
        
            94
                "audio/x-midi": "mdi:piano", 
        
            95
                "audio/flac": "mdi:music", 
        
            96
                "audio/x-ms-wma": "mdi:music", 
        
            97
                "image/avif": "mdi:image", 
        
            99
                "image/jpeg": "mdi:image", 
        
            100
                "image/png": "mdi:image", 
        
            101
                "image/tiff": "mdi:image", 
        
            102
                "image/webp": "mdi:image", 
        
            103
                "image/gif": "mdi:image-multiple", 
        
            104
                "image/vnd.microsoft.icon": "mdi:bookmark-multiple", 
        
            105
                "image/x-icon": "simple-icons:windowsxp", 
        
            106
                "image/bmp": "mdi:brush", 
        
            107
                "image/svg+xml": "mdi:vector-curve", 
        
            108
                "video/mp4": "mdi:video", 
        
            110
                "video/mpeg": "mdi:video", 
        
            111
                "video/ogg": "mdi:video", 
        
            112
                "video/webm": "mdi:video", 
        
            113
                "video/3gpp": "mdi:video", 
        
            114
                "video/3gpp2": "mdi:video", 
        
            115
                "video/x-flv": "mdi:video", 
        
            116
                "video/mp2t": "ic:baseline-live-tv", 
        
            117
                "video/x-msvideo": "mdi:video-vintage", 
        
            118
            } 
        
            119
            def match_icon(name): 
        
            122
                if name.startswith(("LICENCE", "LICENSE", "COPYING")): 
        
            123
                    return "ic:gavel" 
        
            124
                if name.startswith("README"): 
        
            125
                    return "mdi:book-information-variant" 
        
            126
                if name.startswith(".gitignore"): 
        
            127
                    return "simple-icons:git" 
        
            128
            footer = """ 
        
            131
            <x-hbox> 
        
            132
                <a href="/help">Help</a> 
        
            133
                <a href="mailto:{{ config.CONTACT_EMAIL }}">Contact Us</a> 
        
            134
            </x-hbox> 
        
            135
            <hr> 
        
            136
            <p> 
        
            137
                Alpha testing. Not for production use. 
        
            138
            </p> 
        
            139
            <p> 
        
            140
                Application © 2023 Roundabout developers. Content belongs to the repository contributors, 
        
            141
                unless otherwise stated. 
        
            142
            </p> 
        
            143
            <p> 
        
            144
                Made in Romania 🇷🇴 
        
            145
            </p> 
        
            146
            <p> 
        
            147
                <a href="/about">Powered by Roundabout (alpha testing)</a> 
        
            148
            </p> 
        
            149
            """ 
        
            150
            mail_footer = """ 
        
            152
            <small> 
        
            153
                For any inquiries, write to <a href="mailto:{{ config.CONTACT_EMAIL }}"></a><br>. To adjust your email 
        
            154
                notification preferences, log in to your account in a browser and visit 
        
            155
                <a href="{{ config.web_protocol }}://{{ config.BASE_DOMAIN }}/settings">your user settings</a>. 
        
            156
            </small> 
        
            157
            """ 
        
            158
            mail_header = """ 
        
            160
            <img src="{{ config.web_protocol }}://{{ config.BASE_DOMAIN }}/static/logo.svg" width="48"> 
        
            161
            """ 
        
            162
            mail_footer_plain = """ 
        
            164
            For any inquiries, write to <{{ config.CONTACT_EMAIL }}>. 
        
            165
            To adjust your email notification preferences, log in to your account in a browser and visit your user settings at 
        
            166
            <{{ config.web_protocol }}://{{ config.BASE_DOMAIN }}/settings>. 
        
            167
            """ 
        
            168
            www_protocol = f"http{'s' if suggest_https else ''}" 
        
            170
            faqs = """ 
        
            172
            <h1>FAQs and rules</h1> 
        
            173
            <dl> 
        
            174
                <dt><h2>How do I add my project?</h2></dt> 
        
            175
                <dd> 
        
            176
                    <p> 
        
            177
                        It's easy. Click the sign-up button, then click Create in the corner, give it a name, and you're all 
        
            178
                        set. 
        
            179
                    </p> 
        
            180
                </dd> 
        
            181
                <dt><h2>Do I need to have an account?</h2></dt> 
        
            182
                <dd> 
        
            183
                    <p> 
        
            184
                        No, using the service is allowed without registering. However, to post your own material, as well as 
        
            185
                        to contribute to other projects, you need an account to identify you. 
        
            186
                    </p> 
        
            187
                </dd> 
        
            188
                <dt><h2>Do you collect personal information?</h2></dt> 
        
            189
                <dd> 
        
            190
                    <p> 
        
            191
                        Not at all. We do not log analytics or actions, and all you need to make an account is a username 
        
            192
                        (which can be fictional) and a password. 
        
            193
                    </p> 
        
            194
                </dd> 
        
            195
                <dt><h2>Who is the service targeted at?</h2></dt> 
        
            196
                <dd> 
        
            197
                    <p> 
        
            198
                        The service is primarily targeted at enthusiasts 
        
            199
                        (the modern version of <a href="//en.wikipedia.org/wiki/Hacker_culture">hackers</a> but not security 
        
            200
                        breakers!), and while we will optimise for corporate use, large free software projects and even just 
        
            201
                        personal file storage as well, as an enthusiast myself I try to make it better for my use. 
        
            202
                    </p> 
        
            203
                </dd> 
        
            204
                <dt><h2>What projects do you host?</h2></dt> 
        
            205
                <dd> 
        
            206
                    <p> 
        
            207
                        Anything, as long as it's free software. <i>Free</i> means all users should have the 
        
            208
                        <a href="https://www.gnu.org/philosophy/free-sw.html.en#four-freedoms">Four Freedoms</a>. 
        
            209
                        It does not mean everyone has to be a user, so private projects are <strong>allowed</strong>, 
        
            210
                        but if it's private you may not share it without giving these Four Freedoms. 
        
            211
                    </p> 
        
            212
                    <p> 
        
            213
                        <b>In short — either you share freely, or you don't share.</b> 
        
            214
                    </p> 
        
            215
                    <p> 
        
            216
                        Additionally, projects designed to operate with nonfree programs or that depend on nonfree libraries 
        
            217
                        are generally allowed, but keep in mind they are useless in the Free World. However, it is advisable 
        
            218
                        to share them, so others could change them to remove the nonfree dependency. It is recommended to 
        
            219
                        add a disclaimer to the top of an important document, just so others won't get too excited about it 
        
            220
                        and realise it's not for them. 
        
            221
                    </p> 
        
            222
                    <p> 
        
            223
                        “Source-available” projects that don't respect the Four Freedoms are considered nonfree and banned 
        
            224
                        from this site. 
        
            225
                    </p> 
        
            226
                    <p> 
        
            227
                        Using this site as a discussion forum for nonfree software is also not allowed, unless it's for 
        
            228
                        a collaborative effort to reverse-engineer it. Forums for more general topics, as well as free 
        
            229
                        software, are allowed though. 
        
            230
                    </p> 
        
            231
                    <p> 
        
            232
                        Moreover, all <em>public</em> material shared here must be appropriate for all ages and not contain 
        
            233
                        any illegal, pornographic, sexual, political, terrorist or other inappropriate material. Mild 
        
            234
                        swearing is allowed, but it must not be used to refer to sex. 
        
            235
                    </p> 
        
            236
                    <p> 
        
            237
                        For private material though, we have no business as long as you're not abusing the site by hosting 
        
            238
                        illegal content or overloading the server. 
        
            239
                    </p> 
        
            240
                    <p> 
        
            241
                        Nonfree <em>artistic, non-functional</em> works are also fine, but due to the nature of the service, the 
        
            242
                        nonfree terms will not be enforced. 
        
            243
                    </p> 
        
            244
                </dd> 
        
            245
                <dt><h2>What does it cost?</h2></dt> 
        
            246
                <dd> 
        
            247
                    <p> 
        
            248
                        Currently, it is zero-price, besides being free software. However, we may start charging for some 
        
            249
                        features in the future, but <strong>only for those that cost us</strong>, and not for the features 
        
            250
                        we already have, assuming a normal usage. We will not put stupid limits such as three collaborators 
        
            251
                        per repository for free accounts, as more doesn't cost us anything. 
        
            252
                    </p> 
        
            253
                    <p> 
        
            254
                        Advertisements may also get added, but they will be only for logged-out users, and won't use 
        
            255
                        JavaScript or animation, most importantly they won't track you either. 
        
            256
                    </p> 
        
            257
                </dd> 
        
            258
                <dt><h2>What stack does this instance use?</h2></dt> 
        
            259
                <dd> 
        
            260
                    <p> 
        
            261
                        Currently, it's a Raspberry Pi 4 (8GB) running Debian, Nginx, Gunicorn and Python with Flask, on top 
        
            262
                        of Postgres and Redis. 
        
            263
                    </p> 
        
            264
                </dd> 
        
            265
                <dt><h2>Is email integration supported?</h2></dt> 
        
            266
                <dd> 
        
            267
                    <p> 
        
            268
                        Mailing lists aren't currently supported, but it would be a nice feature, so we're working on it. 
        
            269
                    </p> 
        
            270
                </dd> 
        
            271
                <dt><h2>Is SSH supported?</h2></dt> 
        
            272
                <dd> 
        
            273
                    <p> 
        
            274
                        Not currently. While SSH is used in many workflows, we currently only support the Git Smart HTTP 
        
            275
                        protocol including with SSL. It does everything Git SSH does. We encourage you to try it, and let us 
        
            276
                        know if SSH is still important to you. 
        
            277
                    </p> 
        
            278
                    <p> 
        
            279
                        We also do not support the <code>git://</code> or Dumb HTTP protocols as they are insecure and don't 
        
            280
                        have any authentication. 
        
            281
                    </p> 
        
            282
                    <p> 
        
            283
                        For credential memory, GitHub's 
        
            284
                        <a href="https://github.com/git-ecosystem/git-credential-manager">Git Credential Manager</a> 
        
            285
                        also works with our app without extra setup. 
        
            286
                    </p> 
        
            287
                </dd> 
        
            288
                <dt><h2>Is some form of CI or workflow, or robots supported?</h2></dt> 
        
            289
                <dd> 
        
            290
                    <p> 
        
            291
                        No, but we are working on it. 
        
            292
                    </p> 
        
            293
                </dd> 
        
            294
                <dt><h2>What licence does the app have?</h2></dt> 
        
            295
                <dd> 
        
            296
                    <p> 
        
            297
                        <a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL 3.0</a>, or any later version. 
        
            298
                    </p> 
        
            299
                </dd> 
        
            300
                <dt><h2>Where does the name come from?</h2></dt> 
        
            301
                <dd> 
        
            302
                    <p> 
        
            303
                        The name is a play on the word <i>branch</i>, because a roundabout connects many branching roads. 
        
            304
                        It also aligns with our goals to become federated and support collaboration across instances, which 
        
            305
                        we'll call roundabouts. 
        
            306
                    </p> 
        
            307
                    <p> 
        
            308
                        The name is to always be treated like a common noun, so it uses regular capitalisation, articles and 
        
            309
                        plurals. 
        
            310
                    </p> 
        
            311
                </dd> 
        
            312
                <dt><h2>What about that logo?</h2></dt> 
        
            313
                <dd> 
        
            314
                    <p> 
        
            315
                        That is a roundabout sign design commonly used in Europe; it may not be familiar if you live on the 
        
            316
                        other side of the Atlantic. 
        
            317
                    </p> 
        
            318
                    <p> 
        
            319
                        It can also take other meanings, with blue being associated with stability and purity, the arrows 
        
            320
                        could also represent collaboration, a cycle of development and even code reuse and remixing due to 
        
            321
                        the resemblance to the recycling logo. 
        
            322
                    </p> 
        
            323
                    <p> 
        
            324
                        The logo is to be treated as public domain. 
        
            325
                    </p> 
        
            326
                </dd> 
        
            327
            </dl> 
        
            328
            """ 
        
            329