├── .gitignore ├── .gitlab-ci.yml ├── .woodpecker ├── .build.yml └── .test.yml ├── Dockerfile ├── LICENSE ├── README.md ├── docker-compose.yml ├── fediverser ├── apps │ ├── core │ │ ├── __init__.py │ │ ├── adapters.py │ │ ├── admin.py │ │ ├── apps.py │ │ ├── authentication.py │ │ ├── choices.py │ │ ├── factories.py │ │ ├── filters.py │ │ ├── forms.py │ │ ├── handlers.py │ │ ├── management │ │ │ └── commands │ │ │ │ └── pull_from_reddit.py │ │ ├── migrations │ │ │ ├── 0001_initial.py │ │ │ ├── 0002_person_useraccount_lemmy_account.py │ │ │ ├── 0003_fediversedinstance_creates_reddit_mirror_bots_and_more.py │ │ │ ├── 0004_alter_fediversedinstance_instance_endorsement_and_more.py │ │ │ ├── 0005_rename_endorsemement_endorsemententry_endorsement_and_more.py │ │ │ ├── 0006_alter_fediversedinstance_portal_url.py │ │ │ ├── 0007_community_url_person_url_and_more.py │ │ │ ├── 0008_add_url.py │ │ │ ├── 0009_break_recommendation_changefeed.py │ │ │ ├── 0010_remove_reddittocommunityrecommendationentry_recommendation_and_more.py │ │ │ ├── 0011_alter_changefeedentry_options_alter_community_url_and_more.py │ │ │ ├── 0012_setinstancecountry_instanceextrainformation_and_more.py │ │ │ ├── 0013_useraccount_tracked_subreddits.py │ │ │ ├── 0014_connectedredditaccountentry_actor_and_more.py │ │ │ ├── 0015_mergedentry.py │ │ │ ├── 0016_connectedactivitypubaccount.py │ │ │ ├── 0017_remove_community_tags_remove_instance_category_and_more.py │ │ │ ├── 0018_communityannotation_instanceannotation_and_more.py │ │ │ ├── 0019_remove_useraccount_reddit_account.py │ │ │ ├── 0020_alter_entry_feed_redditapplicationkey_and_more.py │ │ │ ├── 0021_invitetemplate_redditaccountauthorizedscope_and_more.py │ │ │ ├── 0022_redditordeclinedinvite.py │ │ │ ├── 0023_alter_instance_software.py │ │ │ ├── 0024_setinstanceasclosed_setinstanceasabandoned.py │ │ │ └── __init__.py │ │ ├── models │ │ │ ├── __init__.py │ │ │ ├── accounts.py │ │ │ ├── activitypub.py │ │ │ ├── cms.py │ │ │ ├── common.py │ │ │ ├── feeds.py │ │ │ ├── invites.py │ │ │ ├── mapping.py │ │ │ ├── mirroring.py │ │ │ ├── network.py │ │ │ └── reddit.py │ │ ├── serializers.py │ │ ├── settings.py │ │ ├── signals.py │ │ ├── static │ │ │ ├── fediverser │ │ │ │ ├── css │ │ │ │ │ └── site.css │ │ │ │ └── images │ │ │ │ │ ├── fediverse-logo.ico │ │ │ │ │ └── fediverse-logo.png │ │ │ └── flags │ │ │ │ ├── ad.svg │ │ │ │ ├── ae.svg │ │ │ │ ├── af.svg │ │ │ │ ├── ag.svg │ │ │ │ ├── ai.svg │ │ │ │ ├── al.svg │ │ │ │ ├── am.svg │ │ │ │ ├── ao.svg │ │ │ │ ├── aq.svg │ │ │ │ ├── ar.svg │ │ │ │ ├── arab.svg │ │ │ │ ├── as.svg │ │ │ │ ├── at.svg │ │ │ │ ├── au.svg │ │ │ │ ├── aw.svg │ │ │ │ ├── ax.svg │ │ │ │ ├── az.svg │ │ │ │ ├── ba.svg │ │ │ │ ├── bb.svg │ │ │ │ ├── bd.svg │ │ │ │ ├── be.svg │ │ │ │ ├── bf.svg │ │ │ │ ├── bg.svg │ │ │ │ ├── bh.svg │ │ │ │ ├── bi.svg │ │ │ │ ├── bj.svg │ │ │ │ ├── bl.svg │ │ │ │ ├── bm.svg │ │ │ │ ├── bn.svg │ │ │ │ ├── bo.svg │ │ │ │ ├── bq.svg │ │ │ │ ├── br.svg │ │ │ │ ├── bs.svg │ │ │ │ ├── bt.svg │ │ │ │ ├── bv.svg │ │ │ │ ├── bw.svg │ │ │ │ ├── by.svg │ │ │ │ ├── bz.svg │ │ │ │ ├── ca.svg │ │ │ │ ├── cc.svg │ │ │ │ ├── cd.svg │ │ │ │ ├── cefta.svg │ │ │ │ ├── cf.svg │ │ │ │ ├── cg.svg │ │ │ │ ├── ch.svg │ │ │ │ ├── ci.svg │ │ │ │ ├── ck.svg │ │ │ │ ├── cl.svg │ │ │ │ ├── cm.svg │ │ │ │ ├── cn.svg │ │ │ │ ├── co.svg │ │ │ │ ├── cp.svg │ │ │ │ ├── cr.svg │ │ │ │ ├── cu.svg │ │ │ │ ├── cv.svg │ │ │ │ ├── cw.svg │ │ │ │ ├── cx.svg │ │ │ │ ├── cy.svg │ │ │ │ ├── cz.svg │ │ │ │ ├── de.svg │ │ │ │ ├── dg.svg │ │ │ │ ├── dj.svg │ │ │ │ ├── dk.svg │ │ │ │ ├── dm.svg │ │ │ │ ├── do.svg │ │ │ │ ├── dz.svg │ │ │ │ ├── eac.svg │ │ │ │ ├── ec.svg │ │ │ │ ├── ee.svg │ │ │ │ ├── eg.svg │ │ │ │ ├── eh.svg │ │ │ │ ├── er.svg │ │ │ │ ├── es-ct.svg │ │ │ │ ├── es-ga.svg │ │ │ │ ├── es-pv.svg │ │ │ │ ├── es.svg │ │ │ │ ├── et.svg │ │ │ │ ├── eu.svg │ │ │ │ ├── fi.svg │ │ │ │ ├── fj.svg │ │ │ │ ├── fk.svg │ │ │ │ ├── fm.svg │ │ │ │ ├── fo.svg │ │ │ │ ├── fr.svg │ │ │ │ ├── ga.svg │ │ │ │ ├── gb-eng.svg │ │ │ │ ├── gb-nir.svg │ │ │ │ ├── gb-sct.svg │ │ │ │ ├── gb-wls.svg │ │ │ │ ├── gb.svg │ │ │ │ ├── gd.svg │ │ │ │ ├── ge.svg │ │ │ │ ├── gf.svg │ │ │ │ ├── gg.svg │ │ │ │ ├── gh.svg │ │ │ │ ├── gi.svg │ │ │ │ ├── gl.svg │ │ │ │ ├── gm.svg │ │ │ │ ├── gn.svg │ │ │ │ ├── gp.svg │ │ │ │ ├── gq.svg │ │ │ │ ├── gr.svg │ │ │ │ ├── gs.svg │ │ │ │ ├── gt.svg │ │ │ │ ├── gu.svg │ │ │ │ ├── gw.svg │ │ │ │ ├── gy.svg │ │ │ │ ├── hk.svg │ │ │ │ ├── hm.svg │ │ │ │ ├── hn.svg │ │ │ │ ├── hr.svg │ │ │ │ ├── ht.svg │ │ │ │ ├── hu.svg │ │ │ │ ├── ic.svg │ │ │ │ ├── id.svg │ │ │ │ ├── ie.svg │ │ │ │ ├── il.svg │ │ │ │ ├── im.svg │ │ │ │ ├── in.svg │ │ │ │ ├── io.svg │ │ │ │ ├── iq.svg │ │ │ │ ├── ir.svg │ │ │ │ ├── is.svg │ │ │ │ ├── it.svg │ │ │ │ ├── je.svg │ │ │ │ ├── jm.svg │ │ │ │ ├── jo.svg │ │ │ │ ├── jp.svg │ │ │ │ ├── ke.svg │ │ │ │ ├── kg.svg │ │ │ │ ├── kh.svg │ │ │ │ ├── ki.svg │ │ │ │ ├── km.svg │ │ │ │ ├── kn.svg │ │ │ │ ├── kp.svg │ │ │ │ ├── kr.svg │ │ │ │ ├── kw.svg │ │ │ │ ├── ky.svg │ │ │ │ ├── kz.svg │ │ │ │ ├── la.svg │ │ │ │ ├── lb.svg │ │ │ │ ├── lc.svg │ │ │ │ ├── li.svg │ │ │ │ ├── lk.svg │ │ │ │ ├── lr.svg │ │ │ │ ├── ls.svg │ │ │ │ ├── lt.svg │ │ │ │ ├── lu.svg │ │ │ │ ├── lv.svg │ │ │ │ ├── ly.svg │ │ │ │ ├── ma.svg │ │ │ │ ├── mc.svg │ │ │ │ ├── md.svg │ │ │ │ ├── me.svg │ │ │ │ ├── mf.svg │ │ │ │ ├── mg.svg │ │ │ │ ├── mh.svg │ │ │ │ ├── mk.svg │ │ │ │ ├── ml.svg │ │ │ │ ├── mm.svg │ │ │ │ ├── mn.svg │ │ │ │ ├── mo.svg │ │ │ │ ├── mp.svg │ │ │ │ ├── mq.svg │ │ │ │ ├── mr.svg │ │ │ │ ├── ms.svg │ │ │ │ ├── mt.svg │ │ │ │ ├── mu.svg │ │ │ │ ├── mv.svg │ │ │ │ ├── mw.svg │ │ │ │ ├── mx.svg │ │ │ │ ├── my.svg │ │ │ │ ├── mz.svg │ │ │ │ ├── na.svg │ │ │ │ ├── nc.svg │ │ │ │ ├── ne.svg │ │ │ │ ├── nf.svg │ │ │ │ ├── ng.svg │ │ │ │ ├── ni.svg │ │ │ │ ├── nl.svg │ │ │ │ ├── no.svg │ │ │ │ ├── np.svg │ │ │ │ ├── nr.svg │ │ │ │ ├── nu.svg │ │ │ │ ├── nz.svg │ │ │ │ ├── om.svg │ │ │ │ ├── pa.svg │ │ │ │ ├── pc.svg │ │ │ │ ├── pe.svg │ │ │ │ ├── pf.svg │ │ │ │ ├── pg.svg │ │ │ │ ├── ph.svg │ │ │ │ ├── pk.svg │ │ │ │ ├── pl.svg │ │ │ │ ├── pm.svg │ │ │ │ ├── pn.svg │ │ │ │ ├── pr.svg │ │ │ │ ├── ps.svg │ │ │ │ ├── pt.svg │ │ │ │ ├── pw.svg │ │ │ │ ├── py.svg │ │ │ │ ├── qa.svg │ │ │ │ ├── re.svg │ │ │ │ ├── ro.svg │ │ │ │ ├── rs.svg │ │ │ │ ├── ru.svg │ │ │ │ ├── rw.svg │ │ │ │ ├── sa.svg │ │ │ │ ├── sb.svg │ │ │ │ ├── sc.svg │ │ │ │ ├── sd.svg │ │ │ │ ├── se.svg │ │ │ │ ├── sg.svg │ │ │ │ ├── sh-ac.svg │ │ │ │ ├── sh-hl.svg │ │ │ │ ├── sh-ta.svg │ │ │ │ ├── sh.svg │ │ │ │ ├── si.svg │ │ │ │ ├── sj.svg │ │ │ │ ├── sk.svg │ │ │ │ ├── sl.svg │ │ │ │ ├── sm.svg │ │ │ │ ├── sn.svg │ │ │ │ ├── so.svg │ │ │ │ ├── sr.svg │ │ │ │ ├── ss.svg │ │ │ │ ├── st.svg │ │ │ │ ├── sv.svg │ │ │ │ ├── sx.svg │ │ │ │ ├── sy.svg │ │ │ │ ├── sz.svg │ │ │ │ ├── tc.svg │ │ │ │ ├── td.svg │ │ │ │ ├── tf.svg │ │ │ │ ├── tg.svg │ │ │ │ ├── th.svg │ │ │ │ ├── tj.svg │ │ │ │ ├── tk.svg │ │ │ │ ├── tl.svg │ │ │ │ ├── tm.svg │ │ │ │ ├── tn.svg │ │ │ │ ├── to.svg │ │ │ │ ├── tr.svg │ │ │ │ ├── tt.svg │ │ │ │ ├── tv.svg │ │ │ │ ├── tw.svg │ │ │ │ ├── tz.svg │ │ │ │ ├── ua.svg │ │ │ │ ├── ug.svg │ │ │ │ ├── um.svg │ │ │ │ ├── un.svg │ │ │ │ ├── us.svg │ │ │ │ ├── uy.svg │ │ │ │ ├── uz.svg │ │ │ │ ├── va.svg │ │ │ │ ├── vc.svg │ │ │ │ ├── ve.svg │ │ │ │ ├── vg.svg │ │ │ │ ├── vi.svg │ │ │ │ ├── vn.svg │ │ │ │ ├── vu.svg │ │ │ │ ├── wf.svg │ │ │ │ ├── ws.svg │ │ │ │ ├── xk.svg │ │ │ │ ├── xx.svg │ │ │ │ ├── ye.svg │ │ │ │ ├── yt.svg │ │ │ │ ├── za.svg │ │ │ │ ├── zm.svg │ │ │ │ └── zw.svg │ │ ├── tasks.py │ │ ├── templates │ │ │ ├── account │ │ │ │ ├── login.html │ │ │ │ └── signup.html │ │ │ ├── admin │ │ │ │ ├── redditaccount_change_form.html │ │ │ │ ├── redditcommunity_change_form.html │ │ │ │ └── redditsubmission_change_form.html │ │ │ ├── fediverser │ │ │ │ └── messages │ │ │ │ │ └── mirrored_post_disclosure.tmpl.md │ │ │ ├── invites │ │ │ │ ├── already_accepted.tmpl.txt │ │ │ │ ├── direct_message.tmpl.md │ │ │ │ └── expired.tmpl.txt │ │ │ └── portal │ │ │ │ ├── base.tmpl.html │ │ │ │ ├── change_request │ │ │ │ └── list.tmpl.html │ │ │ │ ├── community │ │ │ │ ├── create.tmpl.html │ │ │ │ ├── detail.tmpl.html │ │ │ │ └── list.tmpl.html │ │ │ │ ├── community_proposal │ │ │ │ └── create.tmpl.html │ │ │ │ ├── generic │ │ │ │ ├── base.tmpl.html │ │ │ │ ├── create.tmpl.html │ │ │ │ ├── detail.tmpl.html │ │ │ │ ├── form.tmpl.html │ │ │ │ └── listing.tmpl.html │ │ │ │ ├── home │ │ │ │ ├── header.tmpl.html │ │ │ │ ├── instance_finder.tmpl.html │ │ │ │ ├── invite.tmpl.html │ │ │ │ └── page.tmpl.html │ │ │ │ ├── instance │ │ │ │ ├── create.tmpl.html │ │ │ │ ├── detail.tmpl.html │ │ │ │ ├── header.tmpl.html │ │ │ │ ├── list.tmpl.html │ │ │ │ └── signup.tmpl.html │ │ │ │ ├── pages │ │ │ │ └── about.tmpl.html │ │ │ │ ├── partials │ │ │ │ ├── header.tmpl.html │ │ │ │ └── home_header.tmpl.html │ │ │ │ ├── reddit_community │ │ │ │ ├── create.tmpl.html │ │ │ │ ├── detail.tmpl.html │ │ │ │ ├── header.tmpl.html │ │ │ │ └── list.tmpl.html │ │ │ │ ├── reddit_submission │ │ │ │ └── detail.tmpl.html │ │ │ │ └── redditor │ │ │ │ ├── decline_invite.tmpl.html │ │ │ │ ├── detail.tmpl.html │ │ │ │ ├── header.tmpl.html │ │ │ │ └── list.tmpl.html │ │ ├── templatetags │ │ │ └── fediverser.py │ │ ├── tests │ │ │ ├── __init__.py │ │ │ ├── common.py │ │ │ ├── test_api.py │ │ │ ├── test_models.py │ │ │ └── test_views.py │ │ ├── urls.py │ │ └── views │ │ │ ├── __init__.py │ │ │ ├── ambassadors.py │ │ │ ├── auth.py │ │ │ ├── common.py │ │ │ ├── mapping.py │ │ │ ├── network.py │ │ │ ├── onboarding.py │ │ │ └── reddit.py │ └── lemmy │ │ ├── __init__.py │ │ ├── admin.py │ │ ├── apps.py │ │ ├── authentication.py │ │ ├── choices.py │ │ ├── forms.py │ │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_upgrade_to_019.py │ │ ├── 0003_imagedetails_delete_imageupload.py │ │ └── __init__.py │ │ ├── models.py │ │ ├── serializers.py │ │ ├── services.py │ │ └── settings.py └── services │ ├── admin │ └── urls.py │ ├── base │ ├── __init__.py │ ├── asgi.py │ ├── celery.py │ ├── database_router.py │ ├── settings.py │ └── wsgi.py │ └── portal │ └── urls.py ├── poetry.lock ├── pyproject.toml ├── pytest.ini └── setup.cfg /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | *.pyc 3 | 4 | # configuration files 5 | .env 6 | .env.* 7 | 8 | # Docker context data 9 | .docker 10 | 11 | # IDEs and OS files 12 | .idea 13 | .vscode 14 | .DS_Store 15 | -------------------------------------------------------------------------------- /.woodpecker/.build.yml: -------------------------------------------------------------------------------- 1 | steps: 2 | publish: 3 | image: woodpeckerci/plugin-docker-buildx 4 | settings: 5 | repo: ${FEDIVERSER_DOCKER_IMAGE:-mushroomlabs/fediverser} 6 | platforms: linux/amd64,linux/arm64 7 | registry: ${FEDIVERSER_DOCKER_REGISTRY:-https://index.docker.io/v1/} 8 | username: 9 | from_secret: docker_registry_user 10 | password: 11 | from_secret: docker_registry_pass 12 | tags: 13 | - ${CI_COMMIT_TAG:-latest} 14 | - ${CI_COMMIT_BRANCH} 15 | 16 | when: 17 | branch: 18 | - master 19 | 20 | event: 21 | - manual 22 | - tag 23 | 24 | depends_on: 25 | - test 26 | -------------------------------------------------------------------------------- /.woodpecker/.test.yml: -------------------------------------------------------------------------------- 1 | steps: 2 | lint: 3 | image: python:3.12-slim 4 | commands: 5 | - pip install flake8 6 | - flake8 7 | 8 | test: 9 | image: python:3.12-slim 10 | environment: 11 | DJANGO_SETTINGS_MODULE: fediverser.services.base.settings 12 | FEDIVERSER_ROOT_URLCONF: fediverser.services.portal.urls 13 | FEDIVERSER_BROKER_URL: redis://broker:6379/0 14 | FEDIVERSER_CACHE_BACKEND: django_redis.cache.RedisCache 15 | FEDIVERSER_CACHE_LOCATION: redis://cache:6379/0 16 | FEDIVERSER_DATABASE_NAME: fediverser_ci 17 | FEDIVERSER_DATABASE_USER: fediverser 18 | FEDIVERSER_DATABASE_PASSWORD: fediverser_pass 19 | FEDIVERSER_DATABASE_HOST: database 20 | FEDIVERSER_EMAIL_MAILER_ADDRESS: noreply@gitlab.example.com 21 | FEDIVERSER_MEDIA_ROOT: /var/fediverser/media 22 | FEDIVERSER_STATIC_ROOT: /var/fediverser/static 23 | FEDIVERSER_SECRET_KEY: base-fediverser-secret-key 24 | LEMMY_DATABASE_ENGINE: django.db.backends.sqlite3 25 | LEMMY_DATABASE_NAME: ":memory:" 26 | 27 | commands: 28 | - apt update 29 | - apt install build-essential cargo -y 30 | - pip install poetry 31 | - poetry install 32 | - poetry run pytest --nomigrations 33 | volumes: 34 | - /var/run/docker.sock:/var/run/docker.sock 35 | 36 | services: 37 | cache: 38 | image: redis:7-alpine 39 | 40 | broker: 41 | image: redis:7-alpine 42 | 43 | database: 44 | image: postgres:16-alpine 45 | environment: 46 | POSTGRES_DB: fediverser_ci 47 | POSTGRES_USER: fediverser 48 | POSTGRES_PASSWORD: fediverser_pass 49 | 50 | when: 51 | event: 52 | - push 53 | - pull_request 54 | - tag 55 | - manual 56 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Start with a Python image. 2 | FROM python:3.12-slim-bookworm AS fediverser_base 3 | 4 | # Install poetry 5 | RUN pip install poetry 6 | 7 | ENV PYTHONFAULTHANDLER=1 \ 8 | PYTHONUNBUFFERED=1 \ 9 | PIP_NO_CACHE_DIR=off \ 10 | PIP_DISABLE_PIP_VERSION_CHECK=on \ 11 | POETRY_VIRTUALENVS_CREATE=false \ 12 | POETRY_CACHE_DIR='/var/cache/pypoetry' 13 | 14 | RUN apt-get update 15 | RUN apt-get install build-essential cargo -y 16 | 17 | WORKDIR /app 18 | COPY ./pyproject.toml /app 19 | COPY ./poetry.lock /app 20 | 21 | RUN poetry install --without dev --no-root && rm -rf $POETRY_CACHE_DIR 22 | 23 | # Copy all relevant files into the image. 24 | COPY ./fediverser /app/fediverser 25 | COPY ./pytest.ini /app 26 | COPY ./README.md /app 27 | COPY ./setup.cfg /app/fediverse 28 | 29 | FROM fediverser_base AS release 30 | RUN poetry install --without dev 31 | 32 | FROM fediverser_base AS development 33 | RUN poetry install 34 | -------------------------------------------------------------------------------- /fediverser/apps/core/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mushroomlabs/fediverser/d85b9c459b2bc976e955d34c577e2a1b4303ce57/fediverser/apps/core/__init__.py -------------------------------------------------------------------------------- /fediverser/apps/core/adapters.py: -------------------------------------------------------------------------------- 1 | from allauth.socialaccount.adapter import DefaultSocialAccountAdapter 2 | from django.urls import reverse 3 | 4 | 5 | class FediverserSocialAccountAdapter(DefaultSocialAccountAdapter): 6 | def get_connect_redirect_url(self, request, socialaccount): 7 | return reverse("fediverser-core:portal-home") 8 | -------------------------------------------------------------------------------- /fediverser/apps/core/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class CoreConfig(AppConfig): 5 | default_auto_field = "django.db.models.BigAutoField" 6 | name = "fediverser.apps.core" 7 | 8 | def ready(self): 9 | from . import handlers # noqa 10 | -------------------------------------------------------------------------------- /fediverser/apps/core/authentication.py: -------------------------------------------------------------------------------- 1 | from django.contrib.auth import get_user_model 2 | from django.contrib.auth.models import AnonymousUser 3 | from rest_framework.authentication import BaseAuthentication 4 | 5 | from fediverser.apps.lemmy.models import LocalUser 6 | 7 | User = get_user_model() 8 | 9 | 10 | class LemmyAuthentication(BaseAuthentication): 11 | def authenticate(self, request): 12 | token = request.COOKIES.get("jwt") 13 | local_user = ( 14 | LocalUser.objects.filter(logintoken__token=token).select_related("person").first() 15 | ) 16 | user = ( 17 | local_user 18 | and User.objects.filter(account__lemmy_local_username=local_user.person.name).first() 19 | or AnonymousUser() 20 | ) 21 | return (user, None) 22 | -------------------------------------------------------------------------------- /fediverser/apps/core/migrations/0002_person_useraccount_lemmy_account.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.2.13 on 2024-07-17 20:11 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | import fediverser.apps.core.models.activitypub 6 | 7 | 8 | class Migration(migrations.Migration): 9 | dependencies = [ 10 | ("core", "0001_initial"), 11 | ] 12 | 13 | operations = [ 14 | migrations.CreateModel( 15 | name="Person", 16 | fields=[ 17 | ( 18 | "id", 19 | models.BigAutoField( 20 | auto_created=True, primary_key=True, serialize=False, verbose_name="ID" 21 | ), 22 | ), 23 | ("name", models.CharField(max_length=255)), 24 | ( 25 | "instance", 26 | models.ForeignKey( 27 | on_delete=django.db.models.deletion.CASCADE, 28 | related_name="users", 29 | to="core.instance", 30 | ), 31 | ), 32 | ], 33 | bases=(models.Model, fediverser.apps.core.models.activitypub.ActorMixin), 34 | ), 35 | migrations.AddField( 36 | model_name="useraccount", 37 | name="lemmy_account", 38 | field=models.OneToOneField( 39 | blank=True, 40 | null=True, 41 | on_delete=django.db.models.deletion.SET_NULL, 42 | related_name="portal_account", 43 | to="core.person", 44 | ), 45 | ), 46 | ] 47 | -------------------------------------------------------------------------------- /fediverser/apps/core/migrations/0003_fediversedinstance_creates_reddit_mirror_bots_and_more.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.2.13 on 2024-07-17 23:49 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | dependencies = [ 8 | ("core", "0002_person_useraccount_lemmy_account"), 9 | ] 10 | 11 | operations = [ 12 | migrations.AddField( 13 | model_name="fediversedinstance", 14 | name="creates_reddit_mirror_bots", 15 | field=models.BooleanField(default=False), 16 | ), 17 | migrations.AddField( 18 | model_name="fediversedinstance", 19 | name="portal_url", 20 | field=models.URLField(blank=True, null=True), 21 | ), 22 | ] 23 | -------------------------------------------------------------------------------- /fediverser/apps/core/migrations/0006_alter_fediversedinstance_portal_url.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.2.13 on 2024-07-19 20:43 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | dependencies = [ 8 | ("core", "0005_rename_endorsemement_endorsemententry_endorsement_and_more"), 9 | ] 10 | 11 | operations = [ 12 | migrations.AlterField( 13 | model_name="fediversedinstance", 14 | name="portal_url", 15 | field=models.URLField(unique=True), 16 | ), 17 | ] 18 | -------------------------------------------------------------------------------- /fediverser/apps/core/migrations/0008_add_url.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.2.13 on 2024-07-19 23:40 2 | 3 | from django.db import migrations 4 | 5 | from fediverser.apps.core.models.common import AP_SERVER_SOFTWARE 6 | 7 | 8 | def populate_person_url(apps, schema_editor): 9 | Person = apps.get_model("core", "Person") 10 | 11 | for person in Person.objects.all(): 12 | person.url = f"https://{person.instance.domain}/u/{person.name}" 13 | person.save() 14 | 15 | 16 | def populate_community_url(apps, schema_editor): 17 | Community = apps.get_model("core", "Community") 18 | 19 | for c in Community.objects.all(): 20 | c.url = { 21 | AP_SERVER_SOFTWARE.lemmy: f"https://{c.instance.domain}/c/{c.name}", 22 | AP_SERVER_SOFTWARE.kbin: f"https://{c.instance.domain}/m/{c.name}", 23 | }.get(c.instance.software) 24 | c.save() 25 | 26 | 27 | class Migration(migrations.Migration): 28 | dependencies = [ 29 | ("core", "0007_community_url_person_url_and_more"), 30 | ] 31 | 32 | operations = [ 33 | migrations.RunPython(populate_person_url, reverse_code=migrations.RunPython.noop), 34 | migrations.RunPython(populate_community_url, reverse_code=migrations.RunPython.noop), 35 | ] 36 | -------------------------------------------------------------------------------- /fediverser/apps/core/migrations/0009_break_recommendation_changefeed.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.2.13 on 2024-07-19 23:46 2 | 3 | from django.db import migrations 4 | 5 | 6 | def split_recommendation_feed_entries(apps, schema_editor): 7 | RedditToCommunityRecommendationEntry = apps.get_model( 8 | "core", "RedditToCommunityRecommendationEntry" 9 | ) 10 | 11 | for entry in RedditToCommunityRecommendationEntry.objects.all(): 12 | entry.subreddit = entry.recommendation.subreddit 13 | entry.community = entry.recommendation.community 14 | entry.save() 15 | 16 | 17 | class Migration(migrations.Migration): 18 | dependencies = [ 19 | ("core", "0008_add_url"), 20 | ] 21 | 22 | operations = [ 23 | migrations.RunPython( 24 | split_recommendation_feed_entries, reverse_code=migrations.RunPython.noop 25 | ), 26 | ] 27 | -------------------------------------------------------------------------------- /fediverser/apps/core/migrations/0010_remove_reddittocommunityrecommendationentry_recommendation_and_more.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.2.13 on 2024-07-19 23:50 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | dependencies = [ 9 | ("core", "0009_break_recommendation_changefeed"), 10 | ] 11 | 12 | operations = [ 13 | migrations.RemoveField( 14 | model_name="reddittocommunityrecommendationentry", 15 | name="recommendation", 16 | ), 17 | migrations.AlterField( 18 | model_name="reddittocommunityrecommendationentry", 19 | name="community", 20 | field=models.ForeignKey( 21 | on_delete=django.db.models.deletion.CASCADE, 22 | related_name="recommendation_feed_entries", 23 | to="core.community", 24 | ), 25 | ), 26 | migrations.AlterField( 27 | model_name="reddittocommunityrecommendationentry", 28 | name="subreddit", 29 | field=models.ForeignKey( 30 | on_delete=django.db.models.deletion.CASCADE, 31 | related_name="recommendation_feed_entries", 32 | to="core.redditcommunity", 33 | ), 34 | ), 35 | ] 36 | -------------------------------------------------------------------------------- /fediverser/apps/core/migrations/0011_alter_changefeedentry_options_alter_community_url_and_more.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.2.13 on 2024-07-20 10:53 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | dependencies = [ 8 | ("core", "0010_remove_reddittocommunityrecommendationentry_recommendation_and_more"), 9 | ] 10 | 11 | operations = [ 12 | migrations.AlterModelOptions( 13 | name="changefeedentry", 14 | options={"verbose_name_plural": "Change Entries"}, 15 | ), 16 | migrations.AlterField( 17 | model_name="community", 18 | name="url", 19 | field=models.URLField(unique=True), 20 | ), 21 | migrations.AlterField( 22 | model_name="person", 23 | name="url", 24 | field=models.URLField(unique=True), 25 | ), 26 | ] 27 | -------------------------------------------------------------------------------- /fediverser/apps/core/migrations/0013_useraccount_tracked_subreddits.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.2.13 on 2024-07-20 21:56 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | dependencies = [ 8 | ("core", "0012_setinstancecountry_instanceextrainformation_and_more"), 9 | ] 10 | 11 | operations = [ 12 | migrations.AddField( 13 | model_name="useraccount", 14 | name="tracked_subreddits", 15 | field=models.ManyToManyField(to="core.redditcommunity"), 16 | ), 17 | ] 18 | -------------------------------------------------------------------------------- /fediverser/apps/core/migrations/0015_mergedentry.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.2.13 on 2024-07-22 16:26 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | import django.utils.timezone 6 | import model_utils.fields 7 | 8 | 9 | class Migration(migrations.Migration): 10 | dependencies = [ 11 | ("core", "0014_connectedredditaccountentry_actor_and_more"), 12 | ] 13 | 14 | operations = [ 15 | migrations.CreateModel( 16 | name="MergedEntry", 17 | fields=[ 18 | ( 19 | "id", 20 | models.BigAutoField( 21 | auto_created=True, primary_key=True, serialize=False, verbose_name="ID" 22 | ), 23 | ), 24 | ( 25 | "created", 26 | model_utils.fields.AutoCreatedField( 27 | default=django.utils.timezone.now, editable=False, verbose_name="created" 28 | ), 29 | ), 30 | ( 31 | "modified", 32 | model_utils.fields.AutoLastModifiedField( 33 | default=django.utils.timezone.now, editable=False, verbose_name="modified" 34 | ), 35 | ), 36 | ( 37 | "entry", 38 | models.OneToOneField( 39 | on_delete=django.db.models.deletion.CASCADE, 40 | related_name="merge_info", 41 | to="core.changefeedentry", 42 | ), 43 | ), 44 | ], 45 | options={ 46 | "abstract": False, 47 | }, 48 | ), 49 | ] 50 | -------------------------------------------------------------------------------- /fediverser/apps/core/migrations/0016_connectedactivitypubaccount.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.2.13 on 2024-07-22 21:57 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | dependencies = [ 9 | ("core", "0015_mergedentry"), 10 | ] 11 | 12 | operations = [ 13 | migrations.CreateModel( 14 | name="ConnectedActivityPubAccount", 15 | fields=[ 16 | ( 17 | "id", 18 | models.BigAutoField( 19 | auto_created=True, primary_key=True, serialize=False, verbose_name="ID" 20 | ), 21 | ), 22 | ( 23 | "account", 24 | models.ForeignKey( 25 | on_delete=django.db.models.deletion.CASCADE, 26 | related_name="connected_activitypub_accounts", 27 | to="core.useraccount", 28 | ), 29 | ), 30 | ( 31 | "actor", 32 | models.ForeignKey( 33 | on_delete=django.db.models.deletion.CASCADE, 34 | related_name="connected_portal_accounts", 35 | to="core.person", 36 | ), 37 | ), 38 | ], 39 | ), 40 | ] 41 | -------------------------------------------------------------------------------- /fediverser/apps/core/migrations/0019_remove_useraccount_reddit_account.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.2.13 on 2024-07-25 11:59 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | dependencies = [ 8 | ("core", "0018_communityannotation_instanceannotation_and_more"), 9 | ] 10 | 11 | operations = [ 12 | migrations.RemoveField( 13 | model_name="useraccount", 14 | name="reddit_account", 15 | ), 16 | ] 17 | -------------------------------------------------------------------------------- /fediverser/apps/core/migrations/0023_alter_instance_software.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.2.13 on 2024-08-23 18:48 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | dependencies = [ 8 | ("core", "0022_redditordeclinedinvite"), 9 | ] 10 | 11 | operations = [ 12 | migrations.AlterField( 13 | model_name="instance", 14 | name="software", 15 | field=models.CharField( 16 | choices=[ 17 | ("lemmy", "Lemmy"), 18 | ("kbin", "Kbin"), 19 | ("mbin", "Mbin"), 20 | ("mastodon", "Mastodon"), 21 | ("PieFed", "PieFed"), 22 | ], 23 | max_length=30, 24 | ), 25 | ), 26 | ] 27 | -------------------------------------------------------------------------------- /fediverser/apps/core/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mushroomlabs/fediverser/d85b9c459b2bc976e955d34c577e2a1b4303ce57/fediverser/apps/core/migrations/__init__.py -------------------------------------------------------------------------------- /fediverser/apps/core/models/__init__.py: -------------------------------------------------------------------------------- 1 | from .accounts import * # noqa 2 | from .activitypub import * # noqa 3 | from .cms import * # noqa 4 | from .common import * # noqa 5 | from .feeds import * # noqa 6 | from .invites import * # noqa 7 | from .mapping import * # noqa 8 | from .mirroring import * # noqa 9 | from .network import * # noqa 10 | from .reddit import * # noqa 11 | -------------------------------------------------------------------------------- /fediverser/apps/core/models/cms.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from modelcluster.fields import ParentalKey 3 | from wagtail.admin.panels import FieldPanel, InlinePanel, MultiFieldPanel 4 | from wagtail.blocks import RichTextBlock, TextBlock 5 | from wagtail.fields import StreamField 6 | from wagtail.images.blocks import ImageChooserBlock 7 | from wagtail.models import Orderable, Page 8 | from wagtail.search import index 9 | 10 | 11 | class Article(Page): 12 | content = StreamField( 13 | [ 14 | ("text", RichTextBlock()), 15 | ("image", ImageChooserBlock()), 16 | ("warning", TextBlock()), 17 | ("info", TextBlock()), 18 | ], 19 | use_json_field=True, 20 | ) 21 | 22 | search_fields = Page.search_fields + [ 23 | index.FilterField("content"), 24 | ] 25 | 26 | content_panels = Page.content_panels + [ 27 | FieldPanel("content"), 28 | InlinePanel("related", label="Related"), 29 | ] 30 | 31 | promote_panels = [ 32 | MultiFieldPanel(Page.promote_panels, "Common page configuration"), 33 | ] 34 | 35 | template = "portal/pages/article.tmpl.html" 36 | 37 | 38 | class PageRelatedLink(Orderable): 39 | page = ParentalKey(Article, on_delete=models.CASCADE, related_name="related") 40 | name = models.CharField(max_length=255) 41 | url = models.URLField() 42 | 43 | panels = [FieldPanel("name"), FieldPanel("url")] 44 | 45 | 46 | __all__ = ("Article", "PageRelatedLink") 47 | -------------------------------------------------------------------------------- /fediverser/apps/core/models/common.py: -------------------------------------------------------------------------------- 1 | import os 2 | import uuid 3 | 4 | import cloudscraper 5 | from django.db import models 6 | from django.utils.deconstruct import deconstructible 7 | from model_utils import Choices 8 | from tree_queries.models import TreeNode 9 | 10 | AP_CLIENT_REQUEST_HEADERS = {"Accept": "application/ld+json"} 11 | 12 | COMMUNITY_STATUSES = Choices( 13 | ("active", "Active"), 14 | ("inactive", "Inactive (Lingering community or Infrequent Content posted)"), 15 | ("abandoned", "Abandoned"), 16 | ("closed", "Closed"), 17 | ) 18 | 19 | INSTANCE_STATUSES = Choices( 20 | ("active", "Active"), 21 | ("abandoned", "Abandoned"), 22 | ("closed", "Closed"), 23 | ) 24 | 25 | AP_SERVER_SOFTWARE = Choices( 26 | ("lemmy", "Lemmy"), 27 | ("kbin", "Kbin"), 28 | ("mbin", "Mbin"), 29 | ("mastodon", "Mastodon"), 30 | ("PieFed", "PieFed"), 31 | ) 32 | 33 | 34 | def make_http_client(): 35 | return cloudscraper.create_scraper( 36 | browser={"browser": "firefox", "platform": "linux", "mobile": False} 37 | ) 38 | 39 | 40 | @deconstructible 41 | class UserUpload: 42 | def __init__(self, root_folder): 43 | self.root_folder = root_folder 44 | 45 | def __call__(self, instance, filename): 46 | return os.path.join(self.root_folder, str(uuid.uuid1()), filename) 47 | 48 | 49 | class Category(TreeNode): 50 | name = models.CharField(max_length=80, unique=True) 51 | description = models.TextField(null=True, blank=True) 52 | 53 | @property 54 | def full_name(self): 55 | return " : ".join([str(n.name) for n in self.ancestors(include_self=True)]) 56 | 57 | def __str__(self): 58 | return self.name 59 | 60 | class Meta: 61 | verbose_name_plural = "Categories" 62 | 63 | 64 | __all__ = ("Category",) 65 | -------------------------------------------------------------------------------- /fediverser/apps/core/signals.py: -------------------------------------------------------------------------------- 1 | from django.dispatch import Signal 2 | 3 | redditor_migrated = Signal(["reddit_username", "activitypub_actor"]) 4 | instance_closed = Signal(["instance"]) 5 | instance_abandoned = Signal(["instance"]) 6 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/fediverser/css/site.css: -------------------------------------------------------------------------------- 1 | dl dd { 2 | line-height: 2vh; 3 | display: flex; 4 | align-items: center; 5 | } 6 | 7 | img.flag { 8 | max-height: 1.2vh; 9 | margin: auto 0.5rem; 10 | } 11 | 12 | ul.instance-selector-options, ul.instance-selector-options ul { 13 | list-style-type: none; 14 | padding-left: 0; 15 | width: 100%; 16 | } 17 | 18 | ul.instance-selector-options li { 19 | padding-left: 0; 20 | } 21 | 22 | ul.instance-selector-options > li.option { 23 | border-bottom: 1px dashed #444; 24 | padding: 2vh 1rem; 25 | } 26 | 27 | ul.countries { 28 | display: flex; 29 | flex-wrap: wrap; 30 | } 31 | ul.instance-selector-options ul.countries li.country-option img { 32 | min-width: 80px; 33 | } 34 | 35 | li.topic { 36 | margin: 1vh auto; 37 | } 38 | 39 | li.country-option { 40 | min-width: 120px; 41 | display: flex; 42 | justify-content: center; 43 | align-items: center; 44 | border: hidden; 45 | cursor: pointer; 46 | } 47 | 48 | li.country-option figcaption{ 49 | text-align: center; 50 | display: none; 51 | } 52 | 53 | li.country-option.selected figcaption, li.country-option:hover figcaption { 54 | display: block; 55 | } 56 | 57 | ul.countries li.country-option img.flag { 58 | max-height: 4vh !important; 59 | margin: 1vh 3rem; 60 | filter: grayscale(75%); 61 | } 62 | 63 | ul.countries li.country-option.selected img.flag, ul.countries li.country-option:hover img.flag { 64 | filter: grayscale(0%) !important; 65 | } 66 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/fediverser/images/fediverse-logo.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mushroomlabs/fediverser/d85b9c459b2bc976e955d34c577e2a1b4303ce57/fediverser/apps/core/static/fediverser/images/fediverse-logo.ico -------------------------------------------------------------------------------- /fediverser/apps/core/static/fediverser/images/fediverse-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mushroomlabs/fediverser/d85b9c459b2bc976e955d34c577e2a1b4303ce57/fediverser/apps/core/static/fediverser/images/fediverse-logo.png -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/ae.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/ag.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/am.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/ao.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/at.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/au.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/ax.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/az.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/ba.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/bb.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/bd.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/be.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/bf.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/bg.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/bh.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/bi.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/bj.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/bl.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/bq.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/bs.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/bv.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/bw.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/by.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/ca.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/cd.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/cefta.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/cf.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/cg.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/ch.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/ci.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/ck.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/cl.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/cm.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/cn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/co.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/cp.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/cr.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/cu.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/cv.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/cw.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/cz.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/de.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/dj.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/dk.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/dz.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/ee.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/eh.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/es-ct.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/es-pv.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/et.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/eu.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/fi.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/fm.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/fo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/fr.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/ga.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/gb-eng.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/gb-sct.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/gb.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/gd.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/ge.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/gf.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/gg.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/gh.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/gl.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/gm.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/gn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/gp.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/gr.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/gw.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/gy.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/hk.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/hm.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/hn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/hu.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/ic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/id.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/ie.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/il.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/in.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/iq.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/is.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/it.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/jm.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/jo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/jp.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/ke.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/km.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/kn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/kp.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/kr.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/kw.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/la.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/lc.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/lr.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/ls.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/lt.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/lu.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/lv.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/ly.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/ma.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/mc.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/mf.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/mg.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/mh.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/mk.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/ml.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/mm.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/mn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/mo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/mq.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/mr.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/mu.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/mv.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/my.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/na.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/nc.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/ne.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/ng.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/nl.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/no.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/np.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/nr.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/nu.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/nz.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/pa.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/pe.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/pg.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/ph.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/pk.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/pl.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/pm.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/pr.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/ps.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/pw.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/qa.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/re.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/ro.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/ru.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/rw.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/sb.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/sc.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/sd.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/se.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/sg.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/sh.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/si.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/sj.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/sk.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/sl.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/sn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/so.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/sr.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/ss.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/st.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/sy.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/td.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/tf.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/tg.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/th.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/tj.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/tk.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/tl.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/tn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/to.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/tr.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/tt.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/tv.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/tz.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/ua.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/um.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/us.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/uy.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/uz.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/vc.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/ve.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/vn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/vu.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/wf.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/ws.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/xx.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/ye.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/yt.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /fediverser/apps/core/static/flags/za.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /fediverser/apps/core/templates/admin/redditaccount_change_form.html: -------------------------------------------------------------------------------- 1 | {% extends "admin/change_form.html" %} 2 | 3 | {% block object-tools-items %} 4 |
  • 5 | View on Reddit 6 |
  • 7 | {{ block.super }} 8 | {% endblock %} 9 | -------------------------------------------------------------------------------- /fediverser/apps/core/templates/admin/redditcommunity_change_form.html: -------------------------------------------------------------------------------- 1 | {% extends "admin/change_form.html" %} 2 | 3 | {% block object-tools-items %} 4 |
  • 5 | View on Reddit 6 |
  • 7 | {{ block.super }} 8 | {% endblock %} 9 | -------------------------------------------------------------------------------- /fediverser/apps/core/templates/admin/redditsubmission_change_form.html: -------------------------------------------------------------------------------- 1 | {% extends "admin/change_form.html" %} 2 | 3 | {% block object-tools-items %} 4 |
  • 5 | View on Reddit 6 |
  • 7 | {{ block.super }} 8 | {% endblock %} 9 | -------------------------------------------------------------------------------- /fediverser/apps/core/templates/fediverser/messages/mirrored_post_disclosure.tmpl.md: -------------------------------------------------------------------------------- 1 | This post is an automated archive from a submission made on [{{ mirrored_post.reddit_submission.subreddit }}]({{ mirrored_post.reddit_submission.url }}), powered by [Fediverser](https://fediverser.network) software running on {{ mirror_instance.domain }}. Responses to this submission will not be seen by the [original author](https://reddit.com/u/{{ mirrored_post.reddit_submission.author.username}}) until they claim ownership of their {{ mirror_instance.domain }} account. Please consider reaching out to them let them know about this post and help them migrate to Lemmy. 2 | 3 | Lemmy users: you are still very much encouraged to participate in the discussion. There are still many other subscribers on !{{ mirrored_post.lemmy_community.fqdn }} that can benefit from your contribution and join in the conversation. 4 | 5 | {% if portal_url %} 6 | Reddit users: you can also join the fediverse right away by getting by visiting {{ portal_url }}. If you are looking for a Reddit alternative made for and by an independent community, check out [Fediverser](https://fediverser.network). 7 | {% endif %} 8 | -------------------------------------------------------------------------------- /fediverser/apps/core/templates/invites/already_accepted.tmpl.txt: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | {% autoescape off %} 3 | {% blocktrans %}{{ redditor.username }} has already accepted the invite.{% endblocktrans %} 4 | {% endautoescape %} 5 | -------------------------------------------------------------------------------- /fediverser/apps/core/templates/invites/direct_message.tmpl.md: -------------------------------------------------------------------------------- 1 | We are building the next generation of social media, and we are 2 | looking for people like you. Join the millions of people who are 3 | participating in the [Fediverse](https://fediverse.party), where you 4 | are free to choose the best apps to browse without getting pushed 5 | around by big corporations. 6 | 7 | 8 | By accepting the invite, you will have access to our portal and 9 | will make it [easy to migrate your account preferences to a new server, 10 | where you'll be able to follow the communities and your interests 11 | right away]({{ invite_accept_url }}). You can also just [tell us that you do not want to join]({{ invite_decline_url }}) and we won't bother you again. 12 | 13 | Hope to see you there soon! 14 | -------------------------------------------------------------------------------- /fediverser/apps/core/templates/invites/expired.tmpl.txt: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | {% autoescape off %} 3 | {% blocktrans %}The invitation for {{ redditor.username }} has expired.{% endblocktrans %} 4 | {% endautoescape %} 5 | -------------------------------------------------------------------------------- /fediverser/apps/core/templates/portal/change_request/list.tmpl.html: -------------------------------------------------------------------------------- 1 | {% extends "portal/generic/listing.tmpl.html" %} 2 | 3 | {% block listing %} 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | {% for change_request in object_list %} 14 | 15 | 18 | 19 | 20 | 21 | {% endfor %} 22 | 23 |
    ActionStatusTime
    16 |
    {{ change_request.description }}
    17 |
    {{ change_request.status }}{{ change_request.status_changed }}
    24 | {% endblock %} 25 | -------------------------------------------------------------------------------- /fediverser/apps/core/templates/portal/community/create.tmpl.html: -------------------------------------------------------------------------------- 1 | {% extends "portal/generic/form.tmpl.html" %} 2 | 3 | {% block actions %} 4 | 5 | {% endblock %} 6 | -------------------------------------------------------------------------------- /fediverser/apps/core/templates/portal/community/list.tmpl.html: -------------------------------------------------------------------------------- 1 | {% extends "portal/generic/listing.tmpl.html" %} 2 | {% load wagtailadmin_tags %} 3 | 4 | {% block listing %} 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | {% for community in object_list %} 15 | 16 | 24 | 31 | 32 | 33 | {% endfor %} 34 | 35 |
    CommunityAlternative toCategory
    17 | 23 | 25 | {% for recommendation in community.recommendations.all %} 26 | {{ recommendation.subreddit }} 27 | {% empty %} 28 | No recommendation yet 29 | {% endfor %} 30 | {{ community.category.full_name|default:"Not categorized yet" }}
    36 | {% endblock %} 37 | -------------------------------------------------------------------------------- /fediverser/apps/core/templates/portal/community_proposal/create.tmpl.html: -------------------------------------------------------------------------------- 1 | {% extends "portal/generic/form.tmpl.html" %} 2 | 3 | {% block actions %} 4 | 5 | {% endblock %} 6 | -------------------------------------------------------------------------------- /fediverser/apps/core/templates/portal/generic/base.tmpl.html: -------------------------------------------------------------------------------- 1 | {% extends "portal/base.tmpl.html" %} 2 | 3 | {% load i18n wagtailadmin_tags %} 4 | 5 | {% block content %} 6 | {% block header %} 7 | {% block slim_header %} 8 | {% if breadcrumbs_items %} 9 | {% include "wagtailadmin/shared/headers/slim_header.html" %} 10 | {% endif %} 11 | {% endblock %} 12 | {% block main_header %} 13 | {% include "wagtailadmin/shared/header.html" with title=page_title subtitle=page_subtitle icon=header_icon only %} 14 | {% endblock %} 15 | {% endblock %} 16 | 17 |
    18 | {% block main_content %}{% endblock %} 19 |
    20 | {% endblock %} 21 | -------------------------------------------------------------------------------- /fediverser/apps/core/templates/portal/generic/create.tmpl.html: -------------------------------------------------------------------------------- 1 | {% extends "portal/generic/form.tmpl.html" %} 2 | 3 | {% block actions %} 4 | 5 | {% endblock %} 6 | -------------------------------------------------------------------------------- /fediverser/apps/core/templates/portal/generic/detail.tmpl.html: -------------------------------------------------------------------------------- 1 | {% extends "portal/base.tmpl.html" %} 2 | {% load fediverser %} 3 | 4 | {% block main_content %}{{ object }}{% endblock %} 5 | -------------------------------------------------------------------------------- /fediverser/apps/core/templates/portal/generic/form.tmpl.html: -------------------------------------------------------------------------------- 1 | {% extends "portal/base.tmpl.html" %} 2 | {% load i18n wagtailadmin_tags %} 3 | 4 | {% block main_content %} 5 | {% block before_form %}{% endblock %} 6 |
    7 | {% csrf_token %} 8 | 9 | {% block non_field_errors %} 10 | {% for error in form.non_field_errors %} 11 | {% help_block status="critical" %}{{ error }}{% endhelp_block %} 12 | {% endfor %} 13 | {% endblock %} 14 | 15 | {% block hidden_fields %} 16 | {% for field in form.hidden_fields %}{{ field }}{% endfor %} 17 | {% endblock %} 18 | 19 | 34 |
    35 | {% endblock %} 36 | 37 | {% block extra_js %} 38 | {{ block.super }} 39 | {{ form.media.js }} 40 | {% endblock %} 41 | 42 | {% block extra_css %} 43 | {{ block.super }} 44 | {{ form.media.css }} 45 | {% endblock %} 46 | -------------------------------------------------------------------------------- /fediverser/apps/core/templates/portal/generic/listing.tmpl.html: -------------------------------------------------------------------------------- 1 | {% extends "portal/base.tmpl.html" %} 2 | {% load i18n %} 3 | 4 | {% block main_content_wrapper %} 5 |
    6 |
    7 | {% block listing %} 8 | {% include view.results_template_name|default:"wagtailadmin/generic/listing_results.html" %} 9 | {% endblock %} 10 | 11 | {% if is_paginated %} 12 | {% include "wagtailadmin/shared/pagination_nav.html" with items=page_obj linkurl=index_url %} 13 | {% endif %} 14 |
    15 | {% if filters %} 16 | {% include "wagtailadmin/shared/filters.html" %} 17 | {% endif %} 18 | 19 |
    20 | {% endblock %} 21 | -------------------------------------------------------------------------------- /fediverser/apps/core/templates/portal/home/header.tmpl.html: -------------------------------------------------------------------------------- 1 | {% extends "portal/partials/header.tmpl.html" %} 2 | {% load wagtailadmin_tags fediverser %} 3 | 4 | {% block right_column %} 5 | {% fediverser_portal_settings as site %} 6 | {% if site.is_network_portal %} 7 |
    8 | {% if user.is_authenticated and not user.account.has_connected_activitypub_accounts %} 9 | 10 | {% icon name='search' wrapped=1 %}Find a Lemmy Instance 11 | 12 | {% endif %} 13 |
    14 | {% endif %} 15 | {% endblock %} 16 | -------------------------------------------------------------------------------- /fediverser/apps/core/templates/portal/home/invite.tmpl.html: -------------------------------------------------------------------------------- 1 | {% extends "portal/base.tmpl.html" %} 2 | {% load fediverser wagtailadmin_tags %} 3 | 4 | 5 | {% block main_header %} 6 | {% fediverser_portal_settings as site %} 7 | {% include "portal/home/header.tmpl.html" with title=site.Portal.name subtitle=None action_url=None action_text=None icon=None %} 8 | {% endblock %} 9 | 10 | 11 | {% block main_content %} 12 | {% fediverser_portal_settings as site %} 13 |
    14 |

    15 | Congrats! You are one click away from joining our ranks of people who are 16 | tired of social media networks controlled by soulless 17 | corporations. By joining now, you'll be able to: 18 |

    19 | 20 | 31 | 32 |
    33 | {% csrf_token %} 34 | 35 |
    36 |
    37 | {% endblock %} 38 | -------------------------------------------------------------------------------- /fediverser/apps/core/templates/portal/instance/create.tmpl.html: -------------------------------------------------------------------------------- 1 | {% extends "portal/generic/form.tmpl.html" %} 2 | 3 | {% block actions %} 4 | 5 | {% endblock %} 6 | -------------------------------------------------------------------------------- /fediverser/apps/core/templates/portal/instance/detail.tmpl.html: -------------------------------------------------------------------------------- 1 | {% extends "portal/generic/base.tmpl.html" %} 2 | {% load fediverser %} 3 | 4 | {% block main_header %} 5 | {% include "portal/instance/header.tmpl.html" with title=page_title subtitle=page_subtitle action_url=None action_text=None icon=None instance=object %} 6 | {% endblock %} 7 | 8 | {% block main_content %} 9 |
    10 |
    Instance URL
    11 |
    {{ object.url }}
    12 | {% if object.related_countries.exists %} 13 |
    Recommended for people in
    14 |
    15 | {% for related_country in object.related_countries.all %} 16 | {{ related_country.country.name }} 17 | 18 | Flag of {{ related_country.country.name }} 19 |
    20 | {% endfor %} 21 |
    22 | {% endif %} 23 |
    24 |
    25 | 26 |

    Local Groups?

    27 | {% if not user|pending_instance_country_proposal:object %} 28 |

    If this instance is for users of a country or common region, you can indicate it here:

    29 |
    30 | {% csrf_token %} 31 | 41 |
    42 | {% else %} 43 |

    You already recommended a country! Please check your activity page for more information.

    44 | {% endif %} 45 | 46 | {% endblock %} 47 | 48 | {% block extra_js %} 49 | {{ block.super }} 50 | {{ status_picker_form.media.js }} 51 | {{ category_picker_form.media.js }} 52 | {% endblock %} 53 | 54 | {% block extra_css %} 55 | {{ block.super }} 56 | {{ status_picker_form.media.css }} 57 | {{ category_picker_form.media.css }} 58 | {% endblock %} 59 | -------------------------------------------------------------------------------- /fediverser/apps/core/templates/portal/instance/header.tmpl.html: -------------------------------------------------------------------------------- 1 | {% extends "portal/partials/header.tmpl.html" %} 2 | {% load wagtailadmin_tags fediverser %} 3 | 4 | {% block right_column %} 5 |
    6 | {% if instance|is_active_instance %} 7 |
    8 | {% csrf_token %} 9 | 10 |
    11 | {% elif instance|is_abandoned_instance %} 12 |
    13 | {% csrf_token %} 14 | 15 |
    16 | {% endif %} 17 |
    18 | {% endblock %} 19 | -------------------------------------------------------------------------------- /fediverser/apps/core/templates/portal/instance/list.tmpl.html: -------------------------------------------------------------------------------- 1 | {% extends "portal/generic/listing.tmpl.html" %} 2 | {% load wagtailadmin_tags %} 3 | 4 | {% block listing %} 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | {% for instance in object_list %} 15 | 16 | 24 | 25 | 26 | 27 | {% endfor %} 28 | 29 |
    DomainSoftwareStatus
    17 | 23 | {{ instance.get_software_display }}{{ instance.annotation.get_status_display|default:"Unknown" }}
    30 | {% endblock %} 31 | -------------------------------------------------------------------------------- /fediverser/apps/core/templates/portal/instance/signup.tmpl.html: -------------------------------------------------------------------------------- 1 | {% extends "portal/generic/form.tmpl.html" %} 2 | {% load fediverser %} 3 | 4 | {% block before_form %} 5 | {% fediversed_lemmy as fediversed_lemmy_configuration %} 6 |

    Please fill the form below to complete your registration on {{ fediversed_lemmy_configuration.instance.domain }}.

    7 | {% endblock %} 8 | -------------------------------------------------------------------------------- /fediverser/apps/core/templates/portal/pages/about.tmpl.html: -------------------------------------------------------------------------------- 1 | {% extends "portal/base.tmpl.html" %} 2 | 3 | {% block main_contents %} 4 | 5 |

    We believe that the big traditional social media platforms have 6 | become to big for their own good. Too much power concentrated in the 7 | hands of a few oligarchs in Silicon Valley is leading to an internet 8 | that is closed and not with the best interests of the people in 9 | mind. 10 |

    11 | 12 |

    We also understand that network effects make it difficult for 13 | people to leave those platforms. For better or worse, these 14 | platforms still have an incredible amount of amazing content and it 15 | is hard to let go of the connections that hundreds of millions of 16 | people have made it through these platforms throughout the years. 17 |

    18 | 19 |

    20 | Fediverser wants to solve these problems with a two-pronged 21 | approach. First, we want to make the content from the current 22 | platforms available in the equivalent fediverse platform. After the 23 | content is available, more people will be able to make the switch. 24 |

    25 | 26 | {% endblock %} 27 | -------------------------------------------------------------------------------- /fediverser/apps/core/templates/portal/partials/home_header.tmpl.html: -------------------------------------------------------------------------------- 1 | {% extends "portal/partials/header.tmpl.html" %} 2 | {% load wagtailadmin_tags %} 3 | 4 | {% block right_column %} 5 |
    6 | {% if user.is_authenticated and not user.account.has_connected_activitypub_accounts %} 7 | 8 | {% icon name='search' wrapped=1 %}Find a Lemmy Instance 9 | 10 | {% endif %} 11 |
    12 | {% endblock %} 13 | -------------------------------------------------------------------------------- /fediverser/apps/core/templates/portal/reddit_community/create.tmpl.html: -------------------------------------------------------------------------------- 1 | {% extends "portal/generic/form.tmpl.html" %} 2 | 3 | {% block actions %} 4 | 5 | {% endblock %} 6 | -------------------------------------------------------------------------------- /fediverser/apps/core/templates/portal/reddit_community/header.tmpl.html: -------------------------------------------------------------------------------- 1 | {% extends "portal/partials/header.tmpl.html" %} 2 | {% load wagtailadmin_tags fediverser %} 3 | 4 | {% block right_column %} 5 |
    6 |
    7 | {% csrf_token %} 8 | {% with header_action_icon as action_icon_name %} 9 | 10 | {% endwith %} 11 |
    12 |
    13 | {% endblock %} 14 | -------------------------------------------------------------------------------- /fediverser/apps/core/templates/portal/reddit_submission/detail.tmpl.html: -------------------------------------------------------------------------------- 1 | {% extends "portal/base.tmpl.html" %} 2 | {% load humanize fediverser %} 3 | 4 | 5 | {% block main_header %} 6 | {% with object.title|truncatewords:6 as title %} 7 | {% include "portal/redditor/header.tmpl.html" with title=title subtitle=page_subtitle action_url=None action_text=None redditor=object.author %} 8 | {% endwith %} 9 | {% endblock %} 10 | 11 | {% block main_content %} 12 |
    13 |
    Reddit Submission
    14 |
    {{ object.title }}
    15 |
    Subreddit
    16 |
    {{ object.subreddit }}
    17 |
    Author
    18 |
    {{ object.author }}
    19 |
    Posted
    20 |
    {{ object.created|naturaltime }} 21 |
    22 | 23 |
    24 | {% endblock %} 25 | -------------------------------------------------------------------------------- /fediverser/apps/core/templates/portal/redditor/decline_invite.tmpl.html: -------------------------------------------------------------------------------- 1 | {% extends "portal/generic/form.tmpl.html" %} 2 | {% load fediverser %} 3 | 4 | {% block before_form %} 5 | {% fediverser_portal_settings as site %} 6 |

    7 | We at {{ site.Portal.name }} are committed to help get people out of legacy social networks and into the party of the Open Social Web. However, we understand that this might not be for everyone. Please fill in the form below to decline our invite and we will not be sending any more messages. 8 |

    9 | {% endblock %} 10 | 11 | {% block actions %} 12 | 13 | {% endblock %} 14 | -------------------------------------------------------------------------------- /fediverser/apps/core/templates/portal/redditor/detail.tmpl.html: -------------------------------------------------------------------------------- 1 | {% extends "portal/base.tmpl.html" %} 2 | {% load humanize fediverser %} 3 | 4 | {% block main_header %} 5 | {% include "portal/redditor/header.tmpl.html" with title=page_title subtitle=page_subtitle action_url=header_action_url action_text=header_action_label icon=header_icon redditor=object %} 6 | {% endblock %} 7 | 8 | 9 | {% block main_content %} 10 |
    11 |
    Reddit Page
    12 |
    {{ object }}
    13 |
    Joined
    14 |
    {{ object.created|naturaltime }}
    15 |
    Migration status
    16 |
    17 | {% if object|has_joined_portal %} 18 | Migrated 19 | {% elif object|has_pending_invites %} 20 | Invite was sent, but has not responded yet. 21 | {% else %} 22 | Not migrated. 23 | {% endif %} 24 |
    25 |
    Fediverse identities
    26 |
    27 | {% for connection in object.connected_activitypub_accounts.all %} 28 | {{ connection.actor.url }} 29 | {% empty %} 30 | No Fediverse identity connected, yet. 31 | {% endfor %} 32 |
    33 |
    34 | 35 |
    36 | 37 |

    38 | 39 |

    40 | {% endblock %} 41 | -------------------------------------------------------------------------------- /fediverser/apps/core/templates/portal/redditor/header.tmpl.html: -------------------------------------------------------------------------------- 1 | {% extends "portal/partials/header.tmpl.html" %} 2 | {% load wagtailadmin_tags fediverser %} 3 | 4 | {% block right_column %} 5 | {% if user.is_authenticated and redditor|should_be_invited %} 6 |
    7 | {% if user.account.can_send_reddit_private_messages %} 8 |
    9 | {% csrf_token %} 10 | 11 | 15 |
    16 | {% else %} 17 | 18 | {% icon name="mail" wrapped=1 %} 19 | Send Invite to {{ redditor }} 20 | 21 | {% endif %} 22 |
    23 | {% endif %} 24 | {% endblock %} 25 | -------------------------------------------------------------------------------- /fediverser/apps/core/templates/portal/redditor/list.tmpl.html: -------------------------------------------------------------------------------- 1 | {% extends "portal/generic/listing.tmpl.html" %} 2 | {% load humanize %} 3 | 4 | {% block listing %} 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | {% for redditor in object_list %} 15 | 16 | 23 | 25 | 26 | {% endfor %} 27 | 28 |
    NameFediverse IdentitiesActions
    17 | 22 | 24 |
    29 | {% endblock %} 30 | -------------------------------------------------------------------------------- /fediverser/apps/core/tests/__init__.py: -------------------------------------------------------------------------------- 1 | from .test_models import * # noqa 2 | -------------------------------------------------------------------------------- /fediverser/apps/core/tests/common.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from django.test import TestCase 3 | 4 | 5 | @pytest.mark.django_db(transaction=True) 6 | class BaseTestCase(TestCase): 7 | pass 8 | -------------------------------------------------------------------------------- /fediverser/apps/core/tests/test_api.py: -------------------------------------------------------------------------------- 1 | from rest_framework.test import APIClient 2 | 3 | from fediverser.apps.core import factories 4 | from fediverser.apps.core.settings import app_settings 5 | 6 | from .common import BaseTestCase 7 | 8 | 9 | class APITestCase(BaseTestCase): 10 | def setUp(self): 11 | self.client = APIClient() 12 | 13 | 14 | class SubredditAPITestCase(APITestCase): 15 | def test_can_list_subreddits(self): 16 | factories.RedditCommunityFactory() 17 | 18 | response = self.client.get("/api/subreddits") 19 | self.assertEqual(response.status_code, 200) 20 | self.assertEqual(len(response.data), 1) 21 | 22 | def test_can_list_subreddit_recommendations(self): 23 | subreddit = factories.RedditCommunityFactory(name="testing_api") 24 | community = factories.CommunityFactory() 25 | factories.RedditToCommunityRecommendationFactory(subreddit=subreddit, community=community) 26 | 27 | response = self.client.get("/api/subreddits/testing_api/alternatives") 28 | self.assertEqual(response.status_code, 200) 29 | self.assertEqual(len(response.data), 1) 30 | 31 | 32 | class ChangeFeedAPITestCase(APITestCase): 33 | 34 | def test_can_get_connected_account_entry(self): 35 | feed_entry = factories.ConnectedRedditAccountEntryFactory( 36 | published_by__portal_url=app_settings.Portal.url 37 | ) 38 | feed_entry.merge() 39 | response = self.client.get("/api/changes") 40 | self.assertEqual(response.status_code, 200) 41 | 42 | 43 | __all__ = ( 44 | "SubredditAPITestCase", 45 | "ChangeFeedAPITestCase", 46 | ) 47 | -------------------------------------------------------------------------------- /fediverser/apps/core/tests/test_views.py: -------------------------------------------------------------------------------- 1 | from django.test import Client 2 | from django.urls import resolve 3 | 4 | from fediverser.apps.core import factories 5 | 6 | from .common import BaseTestCase 7 | 8 | 9 | class CommunityViewTestCase(BaseTestCase): 10 | def setUp(self): 11 | self.community = factories.CommunityFactory() 12 | self.client = Client() 13 | 14 | def test_can_resolve_url(self): 15 | resolver = resolve(f"/communities/{self.community.fqdn}") 16 | self.assertEqual(resolver.view_name, "fediverser-core:community-detail") 17 | 18 | def test_anonymous_user_can_see_community_page(self): 19 | url = f"/communities/{self.community.fqdn}" 20 | response = self.client.get(url) 21 | self.assertEqual(response.status_code, 200) 22 | 23 | 24 | class SignupViewTestCase(BaseTestCase): 25 | def test_anonymous_user_can_see_page(self): 26 | response = self.client.get("/accounts/signup/") 27 | self.assertEqual(response.status_code, 200) 28 | 29 | 30 | __all__ = ("CommunityViewTestCase", "SignupViewTestCase") 31 | -------------------------------------------------------------------------------- /fediverser/apps/core/views/__init__.py: -------------------------------------------------------------------------------- 1 | from .ambassadors import * # noqa 2 | from .auth import * # noqa 3 | from .mapping import * # noqa 4 | from .network import * # noqa 5 | from .onboarding import * # noqa 6 | from .reddit import * # noqa 7 | -------------------------------------------------------------------------------- /fediverser/apps/lemmy/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mushroomlabs/fediverser/d85b9c459b2bc976e955d34c577e2a1b4303ce57/fediverser/apps/lemmy/__init__.py -------------------------------------------------------------------------------- /fediverser/apps/lemmy/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class LemmyConfig(AppConfig): 5 | default_auto_field = "django.db.models.BigAutoField" 6 | name = "fediverser.apps.lemmy" 7 | -------------------------------------------------------------------------------- /fediverser/apps/lemmy/authentication.py: -------------------------------------------------------------------------------- 1 | from django.contrib.auth import get_user_model 2 | from django.contrib.auth.models import AnonymousUser 3 | from rest_framework.authentication import BaseAuthentication 4 | 5 | from .models import LocalUser 6 | 7 | User = get_user_model() 8 | 9 | 10 | class LemmyAuthentication(BaseAuthentication): 11 | def authenticate(self, request): 12 | token = request.COOKIES.get("jwt") 13 | local_user = ( 14 | LocalUser.objects.filter(logintoken__token=token).select_related("person").first() 15 | ) 16 | user = ( 17 | local_user 18 | and User.objects.filter(account__lemmy_local_username=local_user.person.name).first() 19 | or AnonymousUser() 20 | ) 21 | return (user, None) 22 | -------------------------------------------------------------------------------- /fediverser/apps/lemmy/choices.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | 4 | class ActorTypes(models.TextChoices): 5 | SITE = "site" 6 | COMMUNITY = "community" 7 | PERSON = "person" 8 | 9 | 10 | class CommunityVisibilityTypes(models.TextChoices): 11 | PUBLIC = "Public" 12 | LOCAL = "LocalOnly" 13 | 14 | 15 | class ListingTypes(models.TextChoices): 16 | ALL = "All" 17 | LOCAL = "Local" 18 | SUBSCRIBED = "Subscribed" 19 | MODERATOR = "ModeratorView" 20 | 21 | 22 | class PostListingModes(models.TextChoices): 23 | LIST = "List" 24 | CARD = "Card" 25 | SMALLCARD = "SmallCard" 26 | 27 | 28 | class RegistrationModels(models.TextChoices): 29 | CLOSED = "Closed" 30 | REQUIRE_APPLICATION = "RequireApplication" 31 | OPEN = "Open" 32 | 33 | 34 | class SortOrderTypes(models.TextChoices): 35 | ACTIVE = "Active" 36 | HOT = "Hot" 37 | NEW = "New" 38 | OLD = "Old" 39 | TOP_DAY = "TopDay" 40 | TOP_WEEK = "TopWeek" 41 | TOP_MONTH = "TopMonth" 42 | TOP_YEAR = "TopYear" 43 | TOP_ALL = "TopAll" 44 | MOST_COMMENTS = "MostComments" 45 | NEW_COMMENTS = "NewComments" 46 | TOP_HOUR = "TopHour" 47 | TOP_SIXHOUR = "TopSixHour" 48 | TOP_TWELVEHOUR = "TopTwelveHour" 49 | TOP_THREEMONTHS = "TopThreeMonths" 50 | TOP_SIXMONTHS = "TopSixMonths" 51 | TOP_NINEMONTHS = "TopNineMonths" 52 | CONTROVERSIAL = "Controversial" 53 | SCALED = "Scaled" 54 | -------------------------------------------------------------------------------- /fediverser/apps/lemmy/migrations/0003_imagedetails_delete_imageupload.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 5.2.1 on 2025-05-16 16:50 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | dependencies = [ 8 | ("lemmy", "0002_upgrade_to_019"), 9 | ] 10 | 11 | operations = [ 12 | migrations.CreateModel( 13 | name="ImageDetails", 14 | fields=[ 15 | ("link", models.TextField(primary_key=True, serialize=False)), 16 | ("width", models.IntegerField()), 17 | ("height", models.IntegerField()), 18 | ("content_type", models.TextField()), 19 | ], 20 | options={ 21 | "db_table": "image_details", 22 | "managed": False, 23 | }, 24 | ), 25 | migrations.DeleteModel( 26 | name="ImageUpload", 27 | ), 28 | ] 29 | -------------------------------------------------------------------------------- /fediverser/apps/lemmy/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mushroomlabs/fediverser/d85b9c459b2bc976e955d34c577e2a1b4303ce57/fediverser/apps/lemmy/migrations/__init__.py -------------------------------------------------------------------------------- /fediverser/apps/lemmy/serializers.py: -------------------------------------------------------------------------------- 1 | from django.db.models import Q 2 | from rest_framework import serializers 3 | 4 | from .services import LocalUserProxy 5 | 6 | 7 | class LemmyLoginSerializer(serializers.Serializer): 8 | username_or_email = serializers.CharField(write_only=True) 9 | totp_2fa_token = serializers.CharField(required=False, write_only=True) 10 | password = serializers.CharField(write_only=True) 11 | jwt = serializers.CharField(read_only=True) 12 | registration_created = serializers.BooleanField(read_only=True) 13 | verify_email_sent = serializers.BooleanField(read_only=True) 14 | 15 | def validate(self, attrs): 16 | try: 17 | username_q = Q(person__name=attrs["username_or_email"]) 18 | email_q = Q(email=attrs["username_or_email"]) 19 | local_user = LocalUserProxy.objects.select_related("person").get(username_q | email_q) 20 | attrs["local_user"] = local_user 21 | otp_code = attrs.get("totp_2fa_token") 22 | 23 | if local_user.totp_2fa_enabled and not otp_code: 24 | raise serializers.ValidationError("missing_totp_token") 25 | 26 | if local_user.totp_2fa_enabled and otp_code: 27 | assert local_user.check_totp(otp_code), "incorrect_login" 28 | assert local_user.check_password(attrs["password"]), "incorrect_login" 29 | except LocalUserProxy.DoesNotExist: 30 | raise serializers.ValidationError("incorrect_login") 31 | except AssertionError as exc: 32 | raise serializers.ValidationError(str(exc)) 33 | return attrs 34 | 35 | def create(self, validated_data): 36 | local_user = validated_data["local_user"] 37 | login_token = local_user.make_login_token() 38 | return { 39 | "jwt": login_token.token, 40 | "registration_created": False, 41 | "verify_email_sent": False, 42 | } 43 | -------------------------------------------------------------------------------- /fediverser/apps/lemmy/settings.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | import environ 4 | 5 | logger = logging.getLogger(__name__) 6 | env = environ.Env() 7 | environ.Env.read_env() 8 | 9 | 10 | class AppSettings: 11 | class Instance: 12 | domain = env.str("FEDIVERSER_CONNECTED_LEMMY_INSTANCE", default=None) 13 | reddit_mirror_bots_enabled = env.bool("REDDIT_MIRROR_BOTS_ENABLED", default=False) 14 | 15 | class Bot: 16 | username = env.str("FEDIVERSER_BOT_USERNAME", default=None) 17 | password = env.str("FEDIVERSER_BOT_PASSWORD", default=None) 18 | 19 | @property 20 | def integration_enabled(self): 21 | enabled = env.bool("FEDIVERSER_ENABLE_LEMMY", default=True) 22 | return enabled and self.Instance.domain is not None 23 | 24 | 25 | app_settings = AppSettings() 26 | -------------------------------------------------------------------------------- /fediverser/services/admin/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | from django.conf.urls.static import static 3 | from django.contrib import admin 4 | from django.urls import include, path 5 | from wagtail.admin import urls as wagtailadmin_urls 6 | 7 | urlpatterns = static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) + [ 8 | path("cms/", include(wagtailadmin_urls)), 9 | path("", admin.site.urls), 10 | ] 11 | -------------------------------------------------------------------------------- /fediverser/services/base/__init__.py: -------------------------------------------------------------------------------- 1 | from .celery import app as celery_app 2 | 3 | __all__ = ["celery_app"] 4 | -------------------------------------------------------------------------------- /fediverser/services/base/asgi.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from django.core.asgi import get_asgi_application 4 | 5 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "fediverser.services.base.settings") 6 | os.environ.setdefault("FEDIVERSER_ROOT_URLCONF", "fediverser.services.admin.urls") 7 | 8 | application = get_asgi_application() 9 | -------------------------------------------------------------------------------- /fediverser/services/base/celery.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from celery import Celery 4 | from celery.schedules import crontab 5 | from django.conf import settings 6 | 7 | 8 | class FediverserCeleryConfig(object): 9 | name = "fediverser" 10 | 11 | broker_url = "memory" if settings.TEST_MODE else settings.CELERY_BROKER_URL 12 | broker_use_ssl = "FEDIVERSER_BROKER_USE_SSL" in os.environ 13 | beat_scheduler = "django_celery_beat.schedulers:DatabaseScheduler" 14 | beat_schedule = { 15 | "fetch_content_feeds": { 16 | "task": "fediverser.apps.core.tasks.fetch_feeds", 17 | "schedule": crontab(), 18 | }, 19 | "clear_old_feed_entries": { 20 | "task": "fediverser.apps.core.tasks.clear_old_feed_entries", 21 | "schedule": crontab(minute=0, hour=0), 22 | }, 23 | "sync_change_feeds": { 24 | "task": "fediverser.apps.core.tasks.sync_change_feeds", 25 | "schedule": crontab(), 26 | }, 27 | "push_lemmy_submissions": { 28 | "task": "fediverser.apps.core.tasks.push_new_submissions_to_lemmy", 29 | "schedule": crontab(), 30 | }, 31 | "push_lemmy_comments": { 32 | "task": "fediverser.apps.core.tasks.push_new_comments_to_lemmy", 33 | "schedule": crontab(), 34 | }, 35 | } 36 | 37 | task_always_eager = settings.TEST_MODE 38 | task_eager_propagates = settings.TEST_MODE 39 | 40 | 41 | app = Celery() 42 | app.config_from_object(FediverserCeleryConfig) 43 | app.autodiscover_tasks() 44 | -------------------------------------------------------------------------------- /fediverser/services/base/database_router.py: -------------------------------------------------------------------------------- 1 | class InternalRouter: 2 | """ 3 | A router to control all database operations except the one from the lemmy db 4 | """ 5 | 6 | route_app_labels = {"lemmy"} 7 | 8 | def db_for_read(self, model, **hints): 9 | """ 10 | Attempts to read auth and contenttypes models go to auth_db. 11 | """ 12 | if model._meta.app_label in self.route_app_labels: 13 | return "lemmy" 14 | return "default" 15 | 16 | def db_for_write(self, model, **hints): 17 | """ 18 | Attempts to write auth and contenttypes models go to auth_db. 19 | """ 20 | if model._meta.app_label in self.route_app_labels: 21 | return "lemmy" 22 | return "default" 23 | 24 | def allow_relation(self, obj1, obj2, **hints): 25 | """ 26 | Allow relations if a model in the auth or contenttypes apps is 27 | involved. 28 | """ 29 | return self.db_for_write(obj1) == self.db_for_write(obj2) 30 | 31 | def allow_migrate(self, db, app_label, model_name=None, **hints): 32 | return app_label not in self.route_app_labels 33 | -------------------------------------------------------------------------------- /fediverser/services/base/wsgi.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from django.core.wsgi import get_wsgi_application 4 | 5 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "fediverser.services.base.settings") 6 | os.environ.setdefault("FEDIVERSER_ROOT_URLCONF", "fediverser.services.admin.urls") 7 | 8 | application = get_wsgi_application() 9 | -------------------------------------------------------------------------------- /fediverser/services/portal/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | from django.conf.urls.static import static 3 | from django.urls import include, path 4 | from django.views.generic.base import RedirectView 5 | from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView 6 | from wagtail import urls as wagtail_urls 7 | from wagtail.admin import urls as wagtailadmin_urls 8 | from wagtailautocomplete.urls.admin import urlpatterns as autocomplete_admin_urls 9 | 10 | urlpatterns = [ 11 | path("_ui/", include(wagtailadmin_urls)), # We are using UI components from wagtail 12 | path("accounts/", include("allauth.urls")), 13 | path("api/auth/", include("allauth.headless.urls")), 14 | path("api/docs", SpectacularSwaggerView.as_view(url_name="schema"), name="swagger-ui"), 15 | path("api/docs/schema", SpectacularAPIView.as_view(), name="schema"), 16 | path("invitations/", include("invitations.urls", namespace="invitations")), 17 | path("autocomplete/", include(autocomplete_admin_urls)), 18 | path("login/", RedirectView.as_view(url="/accounts/login/"), name="login-redirect"), 19 | path("", include("fediverser.apps.core.urls", namespace="fediverser-core")), 20 | path("", include(wagtail_urls)), 21 | ] 22 | 23 | if settings.DEBUG: 24 | urlpatterns.extend(static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)) 25 | urlpatterns.extend(static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)) 26 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.black] 2 | line-length = 99 3 | target-version = ['py310', 'py311', 'py312'] 4 | include = '\.pyi?$' 5 | exclude = ''' 6 | /( 7 | \.git 8 | | \.mypy_cache 9 | | \.tox 10 | | build 11 | | dist 12 | )/ 13 | ''' 14 | 15 | [tool.isort] 16 | py_version = 311 17 | line_length = 99 18 | default_section = "THIRDPARTY" 19 | combine_as_imports = true 20 | order_by_type = true 21 | profile = "black" 22 | known_first_party = "fediverser" 23 | 24 | [tool.poetry] 25 | name = "fediverser" 26 | version = "0.2.0" 27 | description = "Tools to help bring content from legacy networks to the Fediverse" 28 | authors = ["Raphael Lullis "] 29 | readme = "README.md" 30 | 31 | [tool.poetry.dependencies] 32 | python = ">=3.10,<4" 33 | praw = "^7.7.1" 34 | pythorhead = "^0.25.2" 35 | requests = "^2" 36 | langdetect = "^1.0" 37 | django = "^5.2.1" 38 | django-environ = "^0.10" 39 | django-allauth = "^65.8.0" 40 | celery = "^5.5.2" 41 | uvicorn = {extras = ["standard"], version = "^0.30.1"} 42 | django-celery-beat = "^2.8.1" 43 | psycopg2-binary = "^2.9" 44 | redis = "^5.0.7" 45 | requests-cache = "^1.1" 46 | factory-boy = "^3.3.0" 47 | django-redis = "^5.4.0" 48 | django-extensions = "^3.2.3" 49 | django-model-utils = "^4.3" 50 | django-celery-results = "^2.5.1" 51 | bcrypt = "^4.0" 52 | pycryptodome = "^3" 53 | pysass = "^0.1.0" 54 | pyjwt = "^2.8.0" 55 | pyotp = "^2.9.0" 56 | cloudscraper = "^1.2.71" 57 | wagtail = "^7.0" 58 | wagtail-autocomplete = "^0.11.0" 59 | django-filter = "^24.2" 60 | django-tree-queries = "^0.19.0" 61 | feedparser = "^6.0.11" 62 | djangorestframework-link-header-pagination = "^0.1.1" 63 | django-rest-polymorphic = "^0.1.10" 64 | django-countries = "^7.6.1" 65 | django-invitations = "^2.1.0" 66 | django-cors-headers = "^4.4.0" 67 | drf-spectacular = {extras = ["sidecar"], version = "^0.27.2"} 68 | djangorestframework = "^3.16.0" 69 | 70 | [tool.poetry.group.dev.dependencies] 71 | ipython = "^8.14.0" 72 | black = "^23.7.0" 73 | isort = "^5.12.0" 74 | flake8 = "^6.1.0" 75 | pytest = "^7.4" 76 | pytest-env = "^1.1.3" 77 | pytest-django = "^4.8.0" 78 | 79 | [build-system] 80 | requires = ["poetry-core"] 81 | build-backend = "poetry.core.masonry.api" 82 | -------------------------------------------------------------------------------- /pytest.ini: -------------------------------------------------------------------------------- 1 | [pytest] 2 | python_files = tests.py test_*.py 3 | 4 | env = 5 | TEST_MODE = "true" 6 | FEDIVERSER_BROKER_URL = memory:// 7 | FEDIVERSER_CACHE_BACKEND = django.core.cache.backends.locmem.LocMemCache 8 | FEDIVERSER_PORTAL_URL = http://portal-test.example.org 9 | FEDIVERSER_CONNECTED_LEMMY_INSTANCE = 10 | 11 | filterwarnings = 12 | ignore:the imp module is deprecated in favour of importlib:DeprecationWarning 13 | ignore:The loop argument is deprecated:DeprecationWarning 14 | ignore:'pkgutil.find_loader' is deprecated:DeprecationWarning 15 | ignore:'locale.getdefaultlocale' is deprecated:DeprecationWarning 16 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [flake8] 2 | max-line-length = 99 3 | 4 | [pep8] 5 | max-line-length = 99 6 | 7 | [isort] 8 | line_length = 99 9 | known_first_party = fediverser 10 | profile = "black" --------------------------------------------------------------------------------