Finished the merge, Disabling comments, Community bans.
@@ -0,0 +1,16 @@
|
||||
Stuff that is done:
|
||||
- Disable comments button
|
||||
- merge with closedverse-video-support (mostly)
|
||||
- Prevent users from posting in communities created by blocked users.
|
||||
|
||||
Stuff that is in progress
|
||||
- Removing shitty code.
|
||||
- Finding and killing bugs!
|
||||
|
||||
Stuff that I want
|
||||
- Image and video file boxes in one.
|
||||
- Pinning posts????
|
||||
Not needed at all if I'm being honest.
|
||||
- Ways for mods to view who invited who.
|
||||
- Hide email password reset form if no SMTP server is set up.
|
||||
- Fix icon and banner uploads. Make that shit work with image_upload
|
||||
@@ -33,7 +33,6 @@ If you have an announcement community, each post will appear there.
|
||||
Can you rewrite this?
|
||||
|
||||
# YOU NEED
|
||||
- Cloudflare
|
||||
- A server (obviously)
|
||||
- Terminal access (also, obviously)
|
||||
- Python 3
|
||||
@@ -55,7 +54,7 @@ You need Pip
|
||||
|
||||
4.
|
||||
Get everything else you need.
|
||||
`pip3 install Django==3.2.2 urllib3 lxml passlib bcrypt pillow django-markdown-deux django-markdown2 whitenoise`
|
||||
`pip3 install Django==3.2.2 urllib3 lxml passlib bcrypt pillow django-markdown-deux django-markdown2 whitenoise django-xff`
|
||||
|
||||
5.
|
||||
Clone the clone!
|
||||
@@ -99,9 +98,6 @@ A: You forgot to migrate and make the database.
|
||||
Q: "Why is the page white, with no color or style at all?"
|
||||
A: You need to collect the static files as mentioned prior.
|
||||
|
||||
Q: "KeyError: HTTP_CF_CONNECTING_IP"
|
||||
A: Cloudflare is needed for this shit to work properly.
|
||||
|
||||
You may have to do some additional troubleshooting, and that's the joy of web-hosting.
|
||||
Fixing problems yourself is a great way to learn how this shit works.
|
||||
|
||||
@@ -148,8 +144,3 @@ Make sure it works too!
|
||||
```
|
||||
sudo systemctl status django
|
||||
```
|
||||
|
||||
18.
|
||||
The final stretch!
|
||||
Set up your server with Cloudflare. You need a domain name, and you need patience, as this can take some time to take effect.
|
||||
If you do this final step right, Cedar should be working fine, and it should have HTTPS working too!
|
||||
@@ -1,67 +1,74 @@
|
||||
"""
|
||||
Django settings for closedverse project.
|
||||
|
||||
Generated by 'django-admin startproject' using Django 1.10.7.
|
||||
Generated by 'django-admin startproject' using Django 2.2.13.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/1.10/topics/settings/
|
||||
https://docs.djangoproject.com/en/2.2/topics/settings/
|
||||
|
||||
For the full list of settings and their values, see
|
||||
https://docs.djangoproject.com/en/1.10/ref/settings/
|
||||
https://docs.djangoproject.com/en/2.2/ref/settings/
|
||||
"""
|
||||
# Django Settings
|
||||
|
||||
import os
|
||||
|
||||
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
||||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = False
|
||||
PROD = False
|
||||
|
||||
# Quick-start development settings - unsuitable for production
|
||||
# See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/
|
||||
# See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/
|
||||
|
||||
# SECURITY WARNING: keep the secret key used in production secret! (If you want a website that can generate key https://miniwebtool.com/django-secret-key-generator/ goto here.)
|
||||
SECRET_KEY = ''
|
||||
|
||||
# Change the ALLOWED_HOSTS to your liking.
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = False
|
||||
|
||||
# This is just a default value for testing
|
||||
# Do not include 127.0.0.1 or localhost
|
||||
# in production for security reasons.
|
||||
ALLOWED_HOSTS = [
|
||||
'domain.com'
|
||||
'127.0.0.1',
|
||||
]
|
||||
|
||||
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
|
||||
|
||||
STATIC_URL = '/s/'
|
||||
MEDIA_URL = '/i/'
|
||||
CLOSEDVERSE_PROD = True
|
||||
IMAGE_DELETE_SETTING = 2
|
||||
|
||||
# Application definition
|
||||
|
||||
INSTALLED_APPS = [
|
||||
'admin_interface',
|
||||
'colorfield',
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
'markdown_deux',
|
||||
'markdown_deux',
|
||||
'closedverse_main',
|
||||
'ban',
|
||||
'maintenance',
|
||||
]
|
||||
X_FRAME_OPTIONS='SAMEORIGIN'
|
||||
|
||||
MIDDLEWARE = [
|
||||
'django.middleware.security.SecurityMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
# use this middleware if you need x-forwarded-for support
|
||||
#'xff.middleware.XForwardedForMiddleware',
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||
|
||||
#'ban.middleware.BanManagement',
|
||||
'closedverse_main.middleware.ClosedMiddleware',
|
||||
'whitenoise.middleware.WhiteNoiseMiddleware'
|
||||
#'maintenance.middleware.MaintenanceManagement',
|
||||
]
|
||||
if not DEBUG:
|
||||
MIDDLEWARE += ['whitenoise.middleware.WhiteNoiseMiddleware']
|
||||
|
||||
ROOT_URLCONF = 'closedverse.urls'
|
||||
|
||||
@@ -76,6 +83,7 @@ TEMPLATES = [
|
||||
'django.template.context_processors.request',
|
||||
'django.contrib.auth.context_processors.auth',
|
||||
'django.contrib.messages.context_processors.messages',
|
||||
'closedverse_main.context_processors.brand_name_universal',
|
||||
],
|
||||
},
|
||||
},
|
||||
@@ -85,17 +93,41 @@ WSGI_APPLICATION = 'closedverse.wsgi.application'
|
||||
|
||||
|
||||
# Database
|
||||
# https://docs.djangoproject.com/en/1.10/ref/settings/#databases
|
||||
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases
|
||||
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3',
|
||||
'NAME': BASE_DIR + '/sql.sqlite3',
|
||||
'NAME': os.path.join(BASE_DIR, 'sql.sqlite3'),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
"""
|
||||
# log errors.
|
||||
LOGGING = {
|
||||
'version': 1,
|
||||
'disable_existing_loggers': False,
|
||||
'handlers': {
|
||||
'file': {
|
||||
'level': 'ERROR',
|
||||
'class': 'logging.FileHandler',
|
||||
'filename': 'logs/errors.log',
|
||||
},
|
||||
},
|
||||
'loggers': {
|
||||
'django': {
|
||||
'handlers': ['file'],
|
||||
'level': 'ERROR',
|
||||
'propagate': True,
|
||||
},
|
||||
},
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
# Password validation
|
||||
# https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators
|
||||
# https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators
|
||||
|
||||
AUTH_PASSWORD_VALIDATORS = [
|
||||
{
|
||||
@@ -114,67 +146,95 @@ AUTH_PASSWORD_VALIDATORS = [
|
||||
|
||||
|
||||
# Internationalization
|
||||
# https://docs.djangoproject.com/en/1.10/topics/i18n/
|
||||
|
||||
TIME_ZONE = 'PST8PDT'
|
||||
# https://docs.djangoproject.com/en/2.2/topics/i18n/
|
||||
|
||||
LANGUAGE_CODE = 'en-us'
|
||||
|
||||
USE_I18N = True
|
||||
# replace with your own timezone
|
||||
TIME_ZONE = 'PST8PDT'
|
||||
|
||||
USE_L10N = True
|
||||
# Disable internationalization because Closedverse doesn't use it
|
||||
USE_I18N = False
|
||||
|
||||
USE_L10N = False
|
||||
|
||||
USE_TZ = True
|
||||
|
||||
# You can use Mailtrap to get the email system working. Mailtrap is free and will work well for what you'll be doing with this.
|
||||
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
|
||||
EMAIL_HOST = 'send.smtp.mailtrap.io'
|
||||
EMAIL_HOST_USER = 'api'
|
||||
EMAIL_HOST_PASSWORD = ''
|
||||
EMAIL_PORT = ''
|
||||
EMAIL_USE_TLS = True
|
||||
DEFAULT_FROM_EMAIL = 'noreply@domain'
|
||||
YOUR_DOMAIN = 'yoursite.com'
|
||||
|
||||
# Static files (CSS, JavaScript, Images)
|
||||
# https://docs.djangoproject.com/en/2.2/howto/static-files/
|
||||
|
||||
#STATIC_URL = '/static/'
|
||||
if not DEBUG:
|
||||
# without this, this will not serve static for admin (and other apps potentially)
|
||||
WHITENOISE_USE_FINDERS = True
|
||||
STATICFILES_STORAGE = 'whitenoise.storage.CompressedStaticFilesStorage'
|
||||
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
|
||||
else:
|
||||
# Define static files in the base directory
|
||||
STATICFILES_DIRS = [
|
||||
os.path.join(BASE_DIR, 'static/'),
|
||||
]
|
||||
|
||||
# Closedverse models and routes for Django
|
||||
AUTH_USER_MODEL = 'closedverse_main.User'
|
||||
CSRF_FAILURE_VIEW = 'closedverse_main.views.csrf_fail'
|
||||
LOGIN_URL = '/login/'
|
||||
LOGIN_REDIRECT_URL = '/login/'
|
||||
|
||||
# Static files (CSS, JavaScript, Images)
|
||||
# https://docs.djangoproject.com/en/1.10/howto/static-files/
|
||||
STATICFILES_DIRS = [
|
||||
os.path.join(BASE_DIR, 'static/')
|
||||
]
|
||||
STATIC_URL = '/s/'
|
||||
STATIC_ROOT = os.path.join(BASE_DIR, 's/')
|
||||
STATICFILES_STORAGE = 'whitenoise.storage.CompressedStaticFilesStorage'
|
||||
|
||||
# Media root
|
||||
# This MUST end with a trailing slash and there must be an 'rm' folder in it
|
||||
# User-uploaded media paths for Closedverse
|
||||
#MEDIA_URL = '/media/'
|
||||
# Must end with a trailing slash
|
||||
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
|
||||
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
|
||||
# trailing slash.
|
||||
# Examples: "http://media.lawrence.com/media/", "http://example.com/media/"
|
||||
MEDIA_URL = '/i/'
|
||||
|
||||
# Cedar Three settings
|
||||
# reCAPTCHA v2 keys, None for no reCAPTCHA
|
||||
recaptcha_pub = ''
|
||||
recaptcha_priv = ''
|
||||
# Settings for markdown_deux, a module
|
||||
# that Closedverse uses in user messages
|
||||
MARKDOWN_DEUX_STYLES = {
|
||||
'default': {
|
||||
'extras': {
|
||||
'code-friendly': None,
|
||||
},
|
||||
'safe_mode': 'escape',
|
||||
},
|
||||
}
|
||||
|
||||
# NNID forbidden list. None for no passing.
|
||||
nnid_forbiddens = BASE_DIR + '/forbidden.json'
|
||||
# Initialize version and Git URL
|
||||
CLOSEDVERSE_GIT_VERSION = 'unknown'
|
||||
CLOSEDVERSE_GIT_URL = ''
|
||||
CLOSEDVERSE_GIT_HAS_CHANGES = False
|
||||
|
||||
# Memo title and message on communities list
|
||||
# I got rid of this setting because it was annoying i guess, edit the HTML to change it. -seedur
|
||||
# Only set git version/URL if .git folder exists
|
||||
if os.path.isdir(os.path.join(BASE_DIR, '.git')):
|
||||
# Get version from Git. This is shown in the layout
|
||||
git_process = os.popen('git rev-parse HEAD', 'r')
|
||||
CLOSEDVERSE_GIT_VERSION = git_process.read()[:-1]
|
||||
|
||||
# Client key to use for iphub.email, because we're using that
|
||||
# None for no IP checking (recommended since this is so slow)
|
||||
# if this command returns a non-zero exit code, then
|
||||
# there have been some changes so let's indicate that
|
||||
if os.system('git diff-index --quiet HEAD --'):
|
||||
CLOSEDVERSE_GIT_HAS_CHANGES = True
|
||||
|
||||
git_process = os.popen('git remote get-url origin', 'r')
|
||||
CLOSEDVERSE_GIT_URL = git_process.read()[:-1]
|
||||
|
||||
try:
|
||||
git_url_without_ext = CLOSEDVERSE_GIT_URL.split('.git')[0]
|
||||
except IndexError:
|
||||
pass
|
||||
else:
|
||||
CLOSEDVERSE_GIT_URL = git_url_without_ext + '/commit/' + CLOSEDVERSE_GIT_VERSION
|
||||
|
||||
# Google reCAPTCHA (v2) settings
|
||||
# This feature won't work if these fields are not populated.
|
||||
RECAPTCHA_PUBLIC_KEY = None
|
||||
RECAPTCHA_PRIVATE_KEY = None
|
||||
|
||||
# Key for IPHub service for Closedverse, which detects proxies.
|
||||
IPHUB_KEY = ""
|
||||
|
||||
# If IP can be checked, then use this to disallow any proxies
|
||||
disallow_proxy = False
|
||||
# If this is set to True, then users will receive an error
|
||||
# upon trying to sign up for the site behind a proxy.
|
||||
# Uses IPHub service and requires an API key defined above.
|
||||
DISALLOW_PROXY = False
|
||||
|
||||
# Setting this to True forces every user to log in/
|
||||
# sign up for the site to view any content.
|
||||
@@ -191,15 +251,10 @@ LOGIN_EXEMPT_URLS = {
|
||||
r'^help/login$',
|
||||
}
|
||||
|
||||
# MD
|
||||
MARKDOWN_DEUX_STYLES = {
|
||||
"default": {
|
||||
"extras": {
|
||||
"code-friendly": None,
|
||||
},
|
||||
"safe_mode": "escape",
|
||||
},
|
||||
}
|
||||
# Action to perform on images belonging to posts/
|
||||
# comments when they are deleted
|
||||
# 0: keep, 1: move to 'rm' folder, 2: delete
|
||||
IMAGE_DELETE_SETTING = 2
|
||||
|
||||
# allow sign ups.
|
||||
allow_signups = True
|
||||
@@ -226,20 +281,32 @@ max_banner_size = 1
|
||||
minimum_password_length = 7
|
||||
|
||||
# The hard limit for uploading, Will cause an error if this is exceeded. This is set to 15MB by default (15728640)
|
||||
DATA_UPLOAD_MAX_MEMORY_SIZE = 15728640
|
||||
DATA_UPLOAD_MAX_MEMORY_SIZE = 52428800
|
||||
|
||||
# Set the default theme here! Set this to None to use the normal Closedverse theme.
|
||||
# TODO, make this work for users who aren't logged in.
|
||||
# Example: site_wide_theme_hex = "#ff4159"
|
||||
# The site wide global theme cannot be deactivated by your users.
|
||||
site_wide_theme_hex = 'ff4159'
|
||||
|
||||
# The location to redirect to if a user's status is set to 2 (Redirect) (rickroll)
|
||||
inactive_redirect = "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
|
||||
|
||||
# Option to delete image if it's local
|
||||
# 0 - keep, 1 - move to 'rm' folder, 2 - DELETE
|
||||
IMAGE_DELETE_SETTING = 0
|
||||
image_delete_opt = 0
|
||||
|
||||
# age (minimal 13 due to C.O.P.P.A)
|
||||
age_allowed = "13"
|
||||
|
||||
# brand name currently being implemented throughout templates
|
||||
brand_name = "Cedar"
|
||||
|
||||
# This option enables some production-specific pages
|
||||
# and routines, such as HTTPS scheme redirection and
|
||||
# proxy detection via IPHub.
|
||||
CLOSEDVERSE_PROD = True
|
||||
|
||||
XFF_TRUSTED_PROXY_DEPTH = 1
|
||||
XFF_STRICT = True
|
||||
XFF_NO_SPOOFING = True
|
||||
XFF_ALWAYS_PROXY = True
|
||||
XFF_HEADER_REQUIRED = True
|
||||
|
||||
# uncomment this if you want miis to be retrieved on the server
|
||||
#mii_endpoint = '/origin?a='
|
||||
|
||||
@@ -1,30 +1,39 @@
|
||||
"""closedverse URL Configuration
|
||||
|
||||
The `urlpatterns` list routes URLs to views. For more information please see:
|
||||
https://docs.djangoproject.com/en/1.10/topics/http/urls/
|
||||
https://docs.djangoproject.com/en/2.2/topics/http/urls/
|
||||
Examples:
|
||||
Function views
|
||||
1. Add an import: from my_app import views
|
||||
2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
|
||||
2. Add a URL to urlpatterns: path('', views.home, name='home')
|
||||
Class-based views
|
||||
1. Add an import: from other_app.views import Home
|
||||
2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
|
||||
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
|
||||
Including another URLconf
|
||||
1. Import the include() function: from django.conf.urls import url, include
|
||||
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
|
||||
1. Import the include() function: from django.urls import include, path
|
||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||
"""
|
||||
from django.conf.urls import url, include
|
||||
|
||||
from django.contrib import admin
|
||||
from .settings import INSTALLED_APPS, MEDIA_ROOT, MEDIA_URL
|
||||
from django.conf.urls.static import static
|
||||
from django.urls import include, path, re_path
|
||||
from django.views.static import serve
|
||||
|
||||
#from closedverse_main import urls
|
||||
from closedverse.settings import STATIC_URL
|
||||
|
||||
# determine static root for admin app
|
||||
#admin_root = admin.__file__.replace('__init__.py', 'static/admin')
|
||||
# Set internal server error handler
|
||||
handler500 = 'closedverse_main.views.server_err'
|
||||
urlpatterns = [
|
||||
url(r'^admin/', admin.site.urls),
|
||||
url(r'^', include('closedverse_main.urls'))
|
||||
path('admin/', admin.site.urls),
|
||||
# edit - the below snippet and admin_root variable are only for if you don't want to use whitenoise
|
||||
# translation: i made all of this before realizing whitenoise could serve it lmao
|
||||
|
||||
# serve static for admin, in production? since admin is the only app now
|
||||
# accomodations might be needed for other apps (e.g silk?)
|
||||
# also the slice is meant to normalize e.g static_url being '/s/' to just 's/', etc. (is this necessary? prob not)
|
||||
#re_path(r'^'+STATIC_URL[1:]+'admin/(?P<path>.*)$', serve, {'document_root': admin_root}),
|
||||
|
||||
# URLs for Closedverse
|
||||
path('', include('closedverse_main.urls'))
|
||||
]
|
||||
|
||||
if 'silk' in INSTALLED_APPS:
|
||||
urlpatterns += [url(r'^silk/', include('silk.urls', namespace='silk'))]
|
||||
|
||||
urlpatterns += static(MEDIA_URL, document_root=MEDIA_ROOT)
|
||||
|
||||
@@ -4,13 +4,13 @@ WSGI config for closedverse project.
|
||||
It exposes the WSGI callable as a module-level variable named ``application``.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/1.10/howto/deployment/wsgi/
|
||||
https://docs.djangoproject.com/en/2.2/howto/deployment/wsgi/
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from django.core.wsgi import get_wsgi_application
|
||||
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "closedverse.settings")
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'closedverse.settings')
|
||||
|
||||
application = get_wsgi_application()
|
||||
|
||||
@@ -33,6 +33,12 @@ def Hide_content(modeladmin, request, queryset):
|
||||
@admin.action(description='Show selected items')
|
||||
def Show_content(modeladmin, request, queryset):
|
||||
queryset.update(is_rm = False)
|
||||
@admin.action(description='Disable comments')
|
||||
def Disable_comments(modeladmin, request, queryset):
|
||||
queryset.update(lock_comments = 2)
|
||||
@admin.action(description='Enable comments')
|
||||
def Enable_comments(modeladmin, request, queryset):
|
||||
queryset.update(lock_comments = 0)
|
||||
@admin.action(description='Feature selected communities')
|
||||
def Feature_community(modeladmin, request, queryset):
|
||||
queryset.update(is_feature = True)
|
||||
@@ -48,12 +54,16 @@ def unforce_login(modeladmin, request, queryset):
|
||||
@admin.action(description='Disable user')
|
||||
def Disable_user(modeladmin, request, queryset):
|
||||
queryset.update(active = False)
|
||||
@admin.action(description='Enable user')
|
||||
def Enable_user(modeladmin, request, queryset):
|
||||
queryset.update(active = True)
|
||||
|
||||
|
||||
class UserAdmin(admin.ModelAdmin):
|
||||
search_fields = ('id', 'unique_id', 'username', 'nickname', 'email', )
|
||||
list_display = ('id', 'username', 'nickname', 'warned', 'level', 'staff', 'active', )
|
||||
exclude = ('addr', 'signup_addr', 'password', )
|
||||
actions = [Disable_user]
|
||||
actions = [Disable_user, Enable_user]
|
||||
#exclude = ('staff', )
|
||||
# Not yet
|
||||
#form = UserForm
|
||||
@@ -73,7 +83,7 @@ class PostAdmin(admin.ModelAdmin):
|
||||
raw_id_fields = ('creator', 'poll', )
|
||||
search_fields = ('id', 'unique_id', 'body', 'creator__username', )
|
||||
list_display = ('id', 'creator', 'body', 'is_rm', )
|
||||
actions = [Hide_content, Show_content]
|
||||
actions = [Hide_content, Show_content, Disable_comments, Enable_comments]
|
||||
def get_queryset(self, request):
|
||||
return models.Post.real.get_queryset()
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
try:
|
||||
from closedverse.settings import brand_name
|
||||
except ImportError:
|
||||
# use default app name by default as brand name
|
||||
from closedverse_main import apps
|
||||
brand_name = apps.ClosedverseMainConfig.verbose_name
|
||||
|
||||
# the name of the function is merely what's imported into settings.py
|
||||
def brand_name_universal(request):
|
||||
# this returns what's actually newly available to the template
|
||||
# so the name of the key actually dictates what you put in the tmpl
|
||||
return {"brand_name": brand_name}
|
||||
@@ -31,12 +31,17 @@ class ClosedMiddleware(object):
|
||||
return redirect('https://{0}{1}'.format(request.get_host(), request.get_full_path()))
|
||||
"""
|
||||
if request.user.is_authenticated:
|
||||
"""
|
||||
if not request.user.is_active():
|
||||
if request.user.warned_reason:
|
||||
ban_msg = request.user.warned_reason
|
||||
else:
|
||||
ban_msg = 'You are banned.'
|
||||
return HttpResponseForbidden(ban_msg)
|
||||
"""
|
||||
# can just forbid post requests for the time being (but leav our funny logout message :3)
|
||||
if not request.user.is_active() and request.method != 'GET' and request.get_full_path() != '/logout/':
|
||||
return HttpResponseForbidden()
|
||||
# If there isn't a request.session
|
||||
if not request.session.get('passwd'):
|
||||
request.session['passwd'] = request.user.password
|
||||
@@ -44,5 +49,8 @@ class ClosedMiddleware(object):
|
||||
if request.session['passwd'] != request.user.password:
|
||||
logout(request)
|
||||
response = self.get_response(request)
|
||||
if request.user.is_authenticated:
|
||||
# for reverse proxy
|
||||
response['X-Username'] = request.user.username
|
||||
|
||||
return response
|
||||
|
||||
@@ -10,6 +10,7 @@ from django.core.exceptions import ValidationError
|
||||
from datetime import timedelta, datetime, date, time
|
||||
from passlib.hash import bcrypt_sha256
|
||||
from closedverse import settings
|
||||
from closedverse_main.context_processors import brand_name
|
||||
from . import util
|
||||
from random import getrandbits
|
||||
import uuid, json, base64
|
||||
@@ -98,6 +99,8 @@ class UserManager(BaseUserManager):
|
||||
return (user, 2)
|
||||
else:
|
||||
if not passwd:
|
||||
#if user.can_manage():
|
||||
# return None
|
||||
return (user, False)
|
||||
return (user, True)
|
||||
|
||||
@@ -117,7 +120,6 @@ class ColorField(models.CharField):
|
||||
def __init__(self, *args, **kwargs):
|
||||
kwargs['max_length'] = 18
|
||||
super(ColorField, self).__init__(*args, **kwargs)
|
||||
|
||||
#mii_domain = 'https://mii-secure.cdn.nintendo.net'
|
||||
# as of writing, mii-secure is unstable, nintendo please do not f*ck me for this
|
||||
mii_domain = 'https://s3.us-east-1.amazonaws.com/mii-images.account.nintendo.net/'
|
||||
@@ -137,7 +139,7 @@ class User(models.Model):
|
||||
# LEVEL: 0-1 is default, everything else is just levels
|
||||
level = models.SmallIntegerField(default=0)
|
||||
# ROLE: This doesn't have anything
|
||||
role = models.SmallIntegerField(default=0, choices=((0, 'normal'), (1, 'Bot'), (2, 'Administrator'), (3, 'Moderator'), (4, 'NO'), (5, 'Donator'), (6, 'Tester'), (7, 'Cools'), (8, 'Developer'), (9, 'SMF9-Django'), (10, 'Staff'), (11, 'GAY DOGWATER' ), ( 12, 'DUMB SNAIL' ), (13, 'Russian ADRIAN'), (14, 'Contest'), (15, 'Gamecon'), (16, 'Cedar'), ))
|
||||
role = models.SmallIntegerField(default=0, choices=((0, 'normal'), (1, 'bot'), (2, 'administrator'), (3, 'moderator'), (4, 'openverse'), (5, 'donator'), (6, 'cool'), (7, 'urapp'), (8, 'owner'), (9, 'badgedes'), (10, 'jack'), (11, 'verified'),))
|
||||
addr = models.CharField(max_length=64, null=True, blank=True)
|
||||
signup_addr = models.CharField(max_length=64, null=True, blank=True)
|
||||
user_agent = models.TextField(null=True, blank=True)
|
||||
@@ -150,7 +152,6 @@ class User(models.Model):
|
||||
color = ColorField(default='', null=True, blank=True)
|
||||
|
||||
staff = models.BooleanField(default=False)
|
||||
#active = models.SmallIntegerField(default=1, choices=((0, 'Redirect'), (1, 'Good'), (2, 'Disabled')))
|
||||
active = models.BooleanField(default=True)
|
||||
can_invite = models.BooleanField(default=True)
|
||||
warned = models.BooleanField(default=False)
|
||||
@@ -238,40 +239,30 @@ class User(models.Model):
|
||||
|
||||
def get_class(self):
|
||||
first = {
|
||||
1: 'tester',
|
||||
1: 'cool',
|
||||
2: 'administrator',
|
||||
3: 'moderator',
|
||||
4: 'openverse',
|
||||
5: 'donator',
|
||||
6: 'tester',
|
||||
6: 'cool',
|
||||
7: 'urapp',
|
||||
8: 'developer',
|
||||
9: 'pipinstalldjango',
|
||||
10: 'staff',
|
||||
11: 'kanna',
|
||||
12: 'verified',
|
||||
13: 'artcon',
|
||||
14: 'contest',
|
||||
15: 'gamecom',
|
||||
16: 'mp',
|
||||
9: 'badgedes',
|
||||
10: 'jack',
|
||||
11: 'verifiedd',
|
||||
}.get(self.role, '')
|
||||
second = {
|
||||
1: "Bot",
|
||||
2: "Administrator",
|
||||
3: "Moderator",
|
||||
4: "No",
|
||||
4: "O-PHP-enverse Man",
|
||||
5: "Donator",
|
||||
6: "Tester",
|
||||
7: "Cool Dude",
|
||||
8: "Wii U still best console.",
|
||||
9: "Rixy Installed Django!",
|
||||
10: "Staff",
|
||||
11: "GAY DOGWATER ETC",
|
||||
12: "THE STUPIDEST ROLE IN THE WORLD",
|
||||
13: "A D R I A N",
|
||||
14: "Contest Winner",
|
||||
15: "Game Contest Winner",
|
||||
16: "Cedar Inc.",
|
||||
6: "Cool Person",
|
||||
7: "cave story is okay",
|
||||
8: "owner guy",
|
||||
9: "Badge Designer",
|
||||
10: "stupid man",
|
||||
11: "Verified",
|
||||
}.get(self.role, '')
|
||||
if first:
|
||||
first = 'official ' + first
|
||||
@@ -555,15 +546,14 @@ class User(models.Model):
|
||||
def password_reset_email(self, request):
|
||||
htmlmsg = render_to_string('closedverse_main/help/email.html', {
|
||||
'menulogo': request.build_absolute_uri(settings.STATIC_URL + 'img/menu-logo.png'),
|
||||
'contact': 'something',
|
||||
'contact': request.build_absolute_uri(reverse('main:help-contact')),
|
||||
'link': request.build_absolute_uri(reverse('main:forgot-passwd')) + "?token=" + base64.urlsafe_b64encode(bytes(self.password, 'utf-8')).decode(),
|
||||
})
|
||||
subj = 'Closedverse password reset for "{0}"'.format(self.username)
|
||||
subj = '{1} password reset for "{0}"'.format(self.username, brand_name)
|
||||
return send_mail(
|
||||
subject='Reset password',
|
||||
subject=subj,
|
||||
html_message=htmlmsg,
|
||||
message=htmlmsg,
|
||||
from_email="noreply@" + settings.YOUR_DOMAIN,
|
||||
from_email="{1} <{0}>".format(settings.DEFAULT_FROM_EMAIL, brand_name),
|
||||
recipient_list=[self.email],
|
||||
fail_silently=False)
|
||||
def find_related(self):
|
||||
@@ -711,7 +701,19 @@ class Community(models.Model):
|
||||
#print(str(post) + ' to ' + str(self.creator) + ':' + str(post.user_is_blocked))
|
||||
post.recent_comment = post.recent_comment()
|
||||
return posts
|
||||
|
||||
def Community_block(self, request):
|
||||
# This goes both ways.
|
||||
if request.user.is_authenticated and not request.user.can_manage():
|
||||
if UserBlock.find_block(self.creator, request.user):
|
||||
return True
|
||||
return False
|
||||
|
||||
def post_perm(self, request):
|
||||
if not request.user.active:
|
||||
return False
|
||||
if self.Community_block(request):
|
||||
return False
|
||||
if request.user.level >= self.rank_needed_to_post:
|
||||
return True
|
||||
elif request.user.staff == True:
|
||||
@@ -766,7 +768,7 @@ class Community(models.Model):
|
||||
URLValidator()(value=request.POST['url'])
|
||||
except ValidationError:
|
||||
return 5
|
||||
if not request.user.has_freedom() and (request.POST.get('url') or request.FILES.get('screen')):
|
||||
if not request.user.has_freedom() and (request.POST.get('url') or request.FILES.get('screen') or request.FILES.get('video')):
|
||||
return 6
|
||||
if not request.user.is_active():
|
||||
return 6
|
||||
@@ -774,14 +776,19 @@ class Community(models.Model):
|
||||
return 1
|
||||
upload = None
|
||||
drawing = None
|
||||
video = None
|
||||
body = request.POST.get('body')
|
||||
for c in body:
|
||||
if unicodedata.combining(c):
|
||||
return 11
|
||||
return 12
|
||||
if request.FILES.get('screen'):
|
||||
upload = util.image_upload(request.FILES['screen'], True)
|
||||
if upload == 1:
|
||||
return 2
|
||||
if request.FILES.get('video'):
|
||||
video = util.video_upload(request.FILES['video'])
|
||||
if video == 1:
|
||||
return 11
|
||||
if request.POST.get('_post_type') == 'painting':
|
||||
if not request.POST.get('painting'):
|
||||
return 2
|
||||
@@ -796,7 +803,7 @@ class Community(models.Model):
|
||||
return 9
|
||||
if body.isspace() and not drawing:
|
||||
return 10
|
||||
new_post = self.post_set.create(body=body, creator=request.user, community=self, feeling=int(request.POST.get('feeling_id', 0)), spoils=bool(request.POST.get('is_spoiler')), screenshot=upload, drawing=drawing, url=request.POST.get('url'))
|
||||
new_post = self.post_set.create(body=body, creator=request.user, community=self, feeling=int(request.POST.get('feeling_id', 0)), spoils=bool(request.POST.get('is_spoiler')), screenshot=upload, drawing=drawing, url=request.POST.get('url'), video=video)
|
||||
new_post.is_mine = True
|
||||
return new_post
|
||||
|
||||
@@ -826,9 +833,11 @@ class Post(models.Model):
|
||||
body = models.TextField(null=True)
|
||||
drawing = models.CharField(max_length=200, null=True, blank=True)
|
||||
screenshot = models.CharField(max_length=1200, null=True, blank=True, default='')
|
||||
video = models.CharField(max_length=256, null=True, blank=True, default='')
|
||||
url = models.URLField(max_length=1200, null=True, blank=True, default='')
|
||||
spoils = models.BooleanField(default=False)
|
||||
disable_yeah = models.BooleanField(default=False)
|
||||
lock_comments = models.SmallIntegerField(default=0, choices=((0, 'Not locked'), (1, 'Locked by user'), (2, 'Locked by mod')))
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
edited = models.DateTimeField(auto_now=True)
|
||||
befores = models.TextField(null=True, blank=True)
|
||||
@@ -892,10 +901,12 @@ class Post(models.Model):
|
||||
else:
|
||||
return False
|
||||
def can_yeah(self, request):
|
||||
if not request.user.is_authenticated or not request.user.is_active():
|
||||
if not request.user.is_authenticated:
|
||||
return False
|
||||
if not request.user.is_active():
|
||||
return False
|
||||
if self.community.Community_block(request):
|
||||
return False
|
||||
# why did cedar-django do this? god knows
|
||||
#return True
|
||||
if self.is_mine(request.user) or UserBlock.find_block(self.creator, request.user):
|
||||
return False
|
||||
return True
|
||||
@@ -923,12 +934,44 @@ class Post(models.Model):
|
||||
def get_yeahs(self, request):
|
||||
return Yeah.objects.filter(type=0, post=self).order_by('-created')[0:30]
|
||||
def can_comment(self, request):
|
||||
# TODO: Make this so that if a post's comments exceeds 100, make the user able to close the comments section
|
||||
if self.number_comments() > 500:
|
||||
return False
|
||||
if not request.user.active:
|
||||
return False
|
||||
# yeah this is fucking nuts. It's basically a ban from an entire community.
|
||||
if self.community.Community_block(request):
|
||||
return False
|
||||
if self.lock_comments != 0:
|
||||
return False
|
||||
if UserBlock.find_block(self.creator, request.user):
|
||||
return False
|
||||
return True
|
||||
|
||||
def can_lock_comments(self, request):
|
||||
if self.lock_comments != 0:
|
||||
return False
|
||||
# If you are a mod, you can bypass the timer
|
||||
# The timer is a personal choice of mine, I don't want users to pussy out of a fight too early or whatever.
|
||||
# Always annoys me when someone has a dumb ass take only for them to turn off the comments immediately.
|
||||
if self.created < timezone.now() - timedelta(hours=24) or request.user.can_manage():
|
||||
if self.creator == request.user:
|
||||
return True
|
||||
if not self.creator.has_authority(request.user) and request.user.can_manage():
|
||||
return True
|
||||
return False
|
||||
|
||||
def lock_the_comments_up(self, request):
|
||||
if request and self.can_lock_comments(request):
|
||||
if self.is_mine(request.user):
|
||||
self.lock_comments = 1
|
||||
else:
|
||||
self.lock_comments = 2
|
||||
AuditLog.objects.create(type=3, post=self, user=self.creator, by=request.user)
|
||||
self.save()
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def get_comments(self, request=None, limit=0, offset=0):
|
||||
if request.user.is_authenticated:
|
||||
blocked_me = request.user.block_target.filter().values('source')
|
||||
@@ -967,7 +1010,7 @@ class Post(models.Model):
|
||||
return 6
|
||||
for c in request.POST['body']:
|
||||
if unicodedata.combining(c):
|
||||
return 11
|
||||
return 12
|
||||
if not request.user.is_active():
|
||||
return 6
|
||||
if len(request.POST['body']) > 2200 or (len(request.POST['body']) < 1 and not request.POST.get('_post_type') == 'painting'):
|
||||
@@ -1269,7 +1312,7 @@ class Profile(models.Model):
|
||||
if self.let_friendrequest == 2:
|
||||
return False
|
||||
#if user.is_authenticated and UserBlock.find_block(self.user, user):
|
||||
# return False
|
||||
# return False
|
||||
elif self.let_friendrequest == 1:
|
||||
if not user.is_following(self.user):
|
||||
return False
|
||||
@@ -1709,7 +1752,7 @@ class UserBlock(models.Model):
|
||||
class AuditLog(models.Model):
|
||||
id = models.AutoField(primary_key=True)
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
type = models.SmallIntegerField(choices=((0, "Post delete"), (1, "Comment delete"), (2, "User edit"), (3, "Generate passwd reset"), (4, "User delete"), (5, "Image delete"), (6, "Purge 1"), (7, "Purge 2"), (8, "Purge 3"), (9, "Purge 4"), (10, "Purge 5"), (11, "Un-purge 1"), (12, 'Changed server settings'), ))
|
||||
type = models.SmallIntegerField(choices=((0, "Post delete"), (1, "Comment delete"), (2, "User edit"), (3, "Disable comments"), (4, "User delete"), (5, "Image delete"), (6, "Purge 1"), (7, "Purge 2"), (8, "Purge 3"), (9, "Purge 4"), (10, "Purge 5"), (11, "Un-purge 1"), (12, 'Changed server settings'), ))
|
||||
post = models.ForeignKey(Post, related_name='audit_post', null=True, on_delete=models.CASCADE)
|
||||
comment = models.ForeignKey(Comment, related_name='audit_comment', null=True, on_delete=models.CASCADE)
|
||||
user = models.ForeignKey(User, related_name='audit_user', null=True, on_delete=models.CASCADE)
|
||||
@@ -1762,6 +1805,9 @@ class Ads(models.Model):
|
||||
adsavailable = False
|
||||
return adsavailable
|
||||
|
||||
class Meta:
|
||||
verbose_name_plural = "ads"
|
||||
|
||||
def __str__(self):
|
||||
return "Ad with id " + str(self.id) + ", created at " + str(self.created) + ", with url " + str(self.url) + ", and imageurl " + str(self.imageurl)
|
||||
|
||||
@@ -1787,6 +1833,9 @@ class ProfileHistory(models.Model):
|
||||
def __str__(self):
|
||||
return str(self.user) + ' changed profile details'
|
||||
|
||||
class Meta:
|
||||
verbose_name_plural = "profile histories"
|
||||
|
||||
# blah blah blah
|
||||
# this method will be executed when...
|
||||
def rm_post_image(sender, instance, **kwargs):
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
<div id="js-main">
|
||||
<div class="activity-feed content-loading-window">
|
||||
<div>
|
||||
{% discordapp_spinner %}
|
||||
{% loading_spinner %}
|
||||
<p class="tleft"><span>Loading activity feed...</span></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{% extends "closedverse_main/layout.html" %}
|
||||
{% load closedverse_tags %}{% load closedverse_community %}{% block main-body %}
|
||||
{% load closedverse_tags %}{% load closedverse_community %}{% load closedverse_user %}{% block main-body %}
|
||||
<div class="community-main">
|
||||
<div id="community-eyecatch"></div>
|
||||
</div>
|
||||
@@ -7,8 +7,13 @@
|
||||
<form action="{% url "main:community-search" %}" class="search">
|
||||
<input maxlength="32" name="query" placeholder="Search all communities" type="text"><input title="Search" type="submit" value="q">
|
||||
</form>
|
||||
<!--<div class="close-announce-container">
|
||||
<div class="close-announce-link">
|
||||
<a class="title" id="close-text-ann" href="/posts/1186"><b>Closedverse is still in indefinite maintenance.</b></a>
|
||||
</div>
|
||||
</div>-->
|
||||
|
||||
{% if user.is_warned %}
|
||||
{% if user.is_warned and user.is_active %}
|
||||
<div class="notice" style="background-color: #ffc783;border: 1px solid #ffb358;">
|
||||
<p><b>WARNING</b>: You have been issued a warning by an administrator.
|
||||
<div>
|
||||
@@ -18,23 +23,35 @@
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if not user.is_active and user.is_authenticated %}
|
||||
<div class="notice" style="background-color: #ff9797;border: 1px solid #ff5252;">
|
||||
<p><b>Oops</b>: You've been smacked by an admin. Better luck next time.
|
||||
<div>
|
||||
{% if user.get_warned_reason %}
|
||||
<p>Reason: "{{ user.get_warned_reason }}"</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if announcements and request.user.is_authenticated %}
|
||||
<div class="Announcements">
|
||||
{% for announcements in announcements %}
|
||||
<div class='Announcement-content'>
|
||||
{% user_icon_container announcements.creator announcements.feeling %}
|
||||
<a class='user-name' href={% url "main:user-view" announcements.creator.username %} {% if announcements.creator.color %}style=color:{{ announcements.creator.color }}{% endif %}>{{ announcements.creator }}</a><a class='timestamp"'> - {{ announcements.created }}</a>
|
||||
<p>{{ announcements.body|linebreaksbr|urlize }}</p>
|
||||
{% if announcements.screenshot %}<image class='Announcement-image' src={{ announcements.screenshot }}></image>{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="tleft">
|
||||
<div class="post-list-outline">
|
||||
<h2 class="label">Latest Announcements</h2>
|
||||
<div class="post-body">
|
||||
<div class="list multi-timeline-post-list">
|
||||
{% for announcement in announcements %}
|
||||
{% profile_post announcement True %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if WelcomeMSG and not request.user.is_authenticated %}
|
||||
<div class="post-list-outline index-memo">
|
||||
<h2 class="label">Welcome to Cedar!</h2>
|
||||
<h2 class="label">Welcome to {{ brand_name }}!</h2>
|
||||
{% for WelcomeMSG in WelcomeMSG %}
|
||||
<h2>{{ WelcomeMSG.Title }}</h2>
|
||||
<p>{{ WelcomeMSG.message|linebreaksbr|urlize }}</p>
|
||||
@@ -51,7 +68,7 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="community-main">
|
||||
<div class="community-main" id="communities">
|
||||
{% if favorites %}
|
||||
<h3 class="community-title symbol community-favorite-title">Favorite communities</h3>
|
||||
<div class="card" id="community-favorite">
|
||||
@@ -74,12 +91,12 @@
|
||||
{% if feature %}
|
||||
{% community_page_element feature "Featured Communities" True %}
|
||||
{% endif %}
|
||||
{% if general %}{% community_page_element general "General Communities" %}{% endif %}
|
||||
{% if game %}{% community_page_element game "Game Communities" %}{% endif %}
|
||||
{% if special %}{% community_page_element special "Special Communities" %}{% endif %}
|
||||
{% if user_communities %}{% community_page_element user_communities "Popular User-Created Communities" %}{% endif %}
|
||||
{% if my_communities %}{% community_page_element my_communities "My Communities" %}{% endif %}
|
||||
<a href="{% url "main:community-viewall" "gen" %}" class="big-button">Show more</a>
|
||||
{% community_page_element general "General Communities" False "general" %}
|
||||
{% community_page_element game "Game Communities" False "game" %}
|
||||
{% community_page_element special "Special Communities" False "special" %}
|
||||
{% community_page_element user_communities "Popular User-Created Communities" False "usr" %}
|
||||
{% if user_communities %}<a href="{% url "main:community-viewall" "usr" %}" class="big-button">Show more</a>{% endif %}
|
||||
{% community_page_element my_communities "My Communities" %}
|
||||
</div>
|
||||
<div id="community-guide-footer">
|
||||
<div id="guide-menu">
|
||||
|
||||
@@ -1,18 +1,8 @@
|
||||
{% extends "closedverse_main/layout.html" %}{% block main-body %}{% load closedverse_community %}
|
||||
{% community_sidebar community request %}
|
||||
<div class="main-column">
|
||||
{% if user.is_warned %}
|
||||
<div class="notice" style="background-color: #ffc783;border: 1px solid #ffb358;">
|
||||
<p><b>WARNING</b>: You have been issued a warning by an administrator.
|
||||
<div>
|
||||
{% if user.get_warned_reason %}
|
||||
<p>Reason: "{{ user.get_warned_reason }}"</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="post-list-outline">
|
||||
<h2 class="label">{{ community.name }}:</h2>
|
||||
<h2 class="label">{{ community.name }}</h2>
|
||||
{% if request.user.is_authenticated and community.post_perm %}
|
||||
{% post_form request.user community %}
|
||||
{% endif %}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
{% load closedverse_community %}
|
||||
{% if user.is_active %}
|
||||
<form id="reply-form" class="for-identified-user" method="post" action="{% url "main:post-comments" post.id %}">
|
||||
{% csrf_token %}
|
||||
{% if not user.limit_remaining is False %}
|
||||
@@ -31,6 +30,8 @@
|
||||
</div>
|
||||
{% if user.has_freedom %}
|
||||
{% file_button %}
|
||||
<!-- hack to temporarily hide video input, for now... -->
|
||||
<style>div.file-button-container{display:none;}</style>
|
||||
{% endif %}
|
||||
|
||||
<div class="post-form-footer-options">
|
||||
@@ -47,8 +48,3 @@
|
||||
<input type="submit" class="black-button reply-button disabled" value="Send" data-community-id="{{ post.community.unique_id }}" data-url-id="{{ post.id }}" data-post-content-type="text" data-post-with-screenshot="nodata" disabled="">
|
||||
</div>
|
||||
</form>
|
||||
{% endif %}
|
||||
|
||||
{% if not user.is_active %}
|
||||
<p class="center">Your account has been disabled.</p>
|
||||
{% endif %}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{% load closedverse_tags %}{% if title %}<h3 class="community-title">{{ title }}</h3>
|
||||
{% endif %}{% if communities %}
|
||||
{% load closedverse_tags %}{% if communities %}
|
||||
{% if title %}<h3 class="community-title">{{ title }}</h3>
|
||||
{% endif %}
|
||||
<ul class="list community-list{% if title %} community-card-list {% if feature %}test-community-list-item{% else %}device-new-community-list{% endif %}{% endif %}">
|
||||
{% for community in communities %}
|
||||
<li class="trigger" data-href="{% url "main:community-view" community.id %}"{% if not title %} class="test-community-list-item"{% endif %}>
|
||||
@@ -21,12 +22,15 @@
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% if url_name and communities.count >= 12 %}
|
||||
<a href="{% url "main:community-viewall" url_name %}" class="big-button">Show more</a>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% if title %}<div class="post-list-outline">{% endif %}
|
||||
<!--{% if title %}<div class="post-list-outline">{% endif %}-->
|
||||
{% if title %}
|
||||
{% nocontent "No communities of this type have been created yet." %}
|
||||
<!--{% nocontent "No communities of this type have been created yet." %}-->
|
||||
{% else %}
|
||||
{% nocontent "You haven't favorited any communities yet. Use the favorite button in a community to add it here." %}
|
||||
{% endif %}
|
||||
{% if title %}</div>{% endif %}
|
||||
<!--{% if title %}</div>{% endif %}-->
|
||||
{% endif %}
|
||||
@@ -44,7 +44,8 @@
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if post.screenshot %}<a class="screenshot-container still-image" href="{% if post.is_reply %}{% url "main:comment-view" post.id %}{% else %}{% url "main:post-view" post.id %}{% endif %}"><img src="{{ post.screenshot }}"></a>{% endif %}
|
||||
{% if post.spoils and post.creator.is_active %}
|
||||
{% if post.video %}<div class="screenshot-container still-image"><video class="vidya" controls src="{{ post.video }}" style="max-width:100%;max-height: 450px;"></video></div>{% endif %}
|
||||
{% if post.spoils and not post.is_mine and post.creator.is_active %}
|
||||
<div class="hidden-content"><p>This post contains spoilers.</p>
|
||||
<button type="button" class="hidden-content-button">View Post</button>
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
<div id="sidebar">
|
||||
{% if Community_block %}
|
||||
<div class="notice" style="background-color: #ff9797;border: 1px solid #ff5252;">
|
||||
<p><b>Oops</b>: You're either blocked by, or blocking {{ community.creator }}, who owns this community. You cannot Yeah, Reply, or Post here.
|
||||
</div>
|
||||
{% endif %}
|
||||
<section class="sidebar-container" id="sidebar-community">
|
||||
{% if community.banner %}
|
||||
<span id="sidebar-cover">
|
||||
@@ -22,8 +27,6 @@
|
||||
<span class="news-community-badge">Announcement Community</span>
|
||||
{% elif community.tags == 'changelog' %}
|
||||
<span class="news-community-badge">Changelog Community</span>
|
||||
{% elif community.tags == 'general' %}
|
||||
<span class="news-community-badge">General</span>
|
||||
{% endif %}
|
||||
<h1 class="community-name">
|
||||
<a href="{% url "main:community-view" community.id %}">{{ community.name }}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
<p>I'm loading it !</p>
|
||||
@@ -7,10 +7,16 @@
|
||||
<label class="file-button-container">
|
||||
<span class="input-label">Image <span id="image-dimensions">PNG and JPEG are allowed.</span></span>
|
||||
<span class="button file-upload-button">Upload</span>
|
||||
<input accept="image/gif, image/png, image/jpeg, image/jpg, image/svg+xml, image/bmp" type="file" style="display: none;" id="upload-file">
|
||||
<input type="hidden" id="upload-input" name="screen">
|
||||
<input accept="image/gif, image/png, image/jpeg, image/jpg, image/svg+xml, image/bmp" type="file" style="display: none;" id="upload-file" name="screen">
|
||||
<div id="upload-preview-container" class="screenshot-container still-image" style="display: none;">
|
||||
<img id="upload-preview">
|
||||
<!-- not functional currently
|
||||
<video id="video-upload-preview"></video>
|
||||
-->
|
||||
</div>
|
||||
</label>
|
||||
<div class="file-button-container">
|
||||
<span class="input-label">Video <span>MP4s and WEBMs are allowed. (50MB size limit)</span></span>
|
||||
<input type="file" class="file-button" name="video" accept="video/mp4, video/webm">
|
||||
</div>
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<span class="open-spin"></span>
|
||||
@@ -1,5 +1,4 @@
|
||||
{% load closedverse_community %}
|
||||
{% if user.is_active %}
|
||||
<form id="post-form" method="post" action="{% url "main:messages-view" friend.username %}" class="folded">
|
||||
{% csrf_token %}
|
||||
{% feeling_selector %}
|
||||
@@ -29,14 +28,7 @@
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="form-buttons">
|
||||
<input type="submit" class="black-button post-button disabled" value="Send" data-post-content-type="text" disabled="">
|
||||
</div>
|
||||
</form>
|
||||
{% endif %}
|
||||
{% if not user.is_active %}
|
||||
<p class="center">Your account has been disabled.</p>
|
||||
{% endif %}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
{% load closedverse_community %}
|
||||
{% if user.is_active %}
|
||||
<form id="post-form" method="post" action="{% url "main:post-create" community.id %}" class="folded for-identified-user" data-post-subtype="default" name="test-post-default-form">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="community" value="{{ community.unique_id }}">
|
||||
@@ -63,8 +62,3 @@
|
||||
<input type="submit" class="black-button post-button disabled" value="Send" data-community-id="{{ community.unique_id }}" data-post-content-type="text" data-post-with-screenshot="nodata" disabled="">
|
||||
</div>
|
||||
</form>
|
||||
{% endif %}
|
||||
|
||||
{% if not user.is_active %}
|
||||
<p class="center">Your account has been disabled.</p>
|
||||
{% endif %}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{% load closedverse_tags %}<div id="{{ post.unique_id }}" {% if post.spoils and not post.is_mine or not post.creator.is_active %}data-href-hidden{% else %}data-href{% endif %}="{% url "main:post-view" post.id %}" class="post trigger{% if post.screenshot %} with-image{% endif %}{% if post.spoils and not post.is_mine or not post.creator.is_active %} hidden test-hidden{% endif %}" tabindex="0">
|
||||
{% load closedverse_tags %}<div {% if post.spoils and not post.is_mine or not post.creator.is_active %}data-href-hidden{% else %}data-href{% endif %}="{% url "main:post-view" post.id %}" class="post trigger{% if post.screenshot and not for_announcements %} with-image{% endif %}{% if post.spoils and not post.is_mine or not post.creator.is_active %} hidden test-hidden{% endif %}" tabindex="0">
|
||||
|
||||
<p class="community-container"><a {% if post.community.clickable %}href="{% url "main:community-view" post.community_id %}"{% endif %}><img src="{{ post.community.icon }}" class="community-icon">{{ post.community.name }}</a></p>
|
||||
|
||||
<div class="body">
|
||||
<div {% if not for_announcements %}class="body"{% endif %}>
|
||||
<div class="post-content">
|
||||
{% user_icon_container post.creator post.feeling %}
|
||||
|
||||
@@ -26,7 +26,10 @@
|
||||
<div class="screenshot-container video"><video src="{{ post.url }}" width="50" height="48"></video></div>
|
||||
{% endif %}
|
||||
{% if post.screenshot %}
|
||||
<a href="{% url "main:post-view" post.id %}" class="screenshot-container still-image"><img src="{{ post.screenshot }}"></a>
|
||||
<a href="{% url "main:post-view" post.id %}" class="{% if not for_announcements %}screenshot-container {% endif %}still-image"><img src="{{ post.screenshot }}"></a>
|
||||
{% endif %}
|
||||
{% if post.video %}
|
||||
<div class="screenshot-container video"><video src="{{ post.video }}" width="50" height="48"></video></div>
|
||||
{% endif %}
|
||||
{% if post.drawing %}
|
||||
<p class="post-content-memo"><img src="{{ post.drawing }}" class="post-memo"></p>
|
||||
@@ -50,6 +53,7 @@
|
||||
<button type="button" class="hidden-content-button">View Anyway</button>
|
||||
</p></div>
|
||||
{% endif %}
|
||||
{% if not for_announcements %}
|
||||
<div class="post-meta">
|
||||
<button type="button"{% if not post.can_yeah %} disabled{% endif %} class="symbol submit yeah-button
|
||||
{% if post.has_yeah %}empathy-added{% endif %}
|
||||
@@ -60,6 +64,7 @@
|
||||
<div class="empathy symbol"><span class="symbol-label">Yeahs</span><span class="empathy-count">{{ post.number_yeahs }}</span></div>
|
||||
<div class="reply symbol"><span class="symbol-label">Comments</span><span class="reply-count">{{ post.number_comments }}</span></div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -21,11 +21,16 @@
|
||||
<li>My notifications: <span> {{ notifications }}
|
||||
</ul>
|
||||
<h3>Restrictions:</h3>
|
||||
{% if request.user.active %}
|
||||
<ul>
|
||||
<li>Sending images and creating new accounts: <span> {% if user.has_freedom %}Good standing{% else %}Restricted{% endif %}
|
||||
<li>Post limit: <span> {% if request.user.profile.limit_post == 0 %}Good standing{% else %}{{ user.profile.limit_post }}{% endif %}
|
||||
<li>Editing your profile: <span> {% if not user.profile.cannot_edit %}Good standing{% else %}Restricted{% endif %}
|
||||
<li>Creating invites: <span> {% if user.can_invite %}Good standing{% else %}Restricted{% endif %}
|
||||
</ul>
|
||||
{% else %}
|
||||
<p class='center'>You've been fucking banned lmao</p>
|
||||
{% endif %}
|
||||
<h3>Collected data:</h3>
|
||||
<div class="user-data">
|
||||
<p class="label">Account login history:</p>
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
{% endif %}
|
||||
<title>{% if title %}{{ title }} - Cedar{% else %}Cedar{% endif %}</title>
|
||||
<title>{% if title %}{{ title }} - {{ brand_name }} {% else %}{{ brand_name }}{% endif %}</title>
|
||||
{% if not request.META.HTTP_X_PJAX %}
|
||||
<meta http-equiv="content-style-type" content="text/css">
|
||||
<meta http-equiv="content-script-type" content="text/javascript">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
<meta name="apple-mobile-web-app-title" content="Cedar">
|
||||
<meta name="description" content="It's Closedverse but Cedar!">
|
||||
<meta name="apple-mobile-web-app-title" content="{{ brand_name }}">
|
||||
<meta name="description" content="{{ brand_name }} is a social network: designed by PF2M, programmed by Arian Kordi. With Miiverse DNA, style and familiar assets such as Miiverse's interface and Miis, you're sure to have fun here!">
|
||||
<meta property="og:locale" content="en_US">
|
||||
{% if ogdata %}
|
||||
<meta property="og:title" content="{{ ogdata.title }}">
|
||||
@@ -19,7 +19,7 @@
|
||||
<meta property="og:url" content="{{ request.build_absolute_uri }}">
|
||||
<meta property="og:image" content="{{ ogdata.image }}">
|
||||
<meta property="og:description" content="{{ ogdata.description|truncatechars:150 }}">
|
||||
<meta property="og:site_name" content="Cedar">
|
||||
<meta property="og:site_name" content="{{ brand_name }}">
|
||||
<meta property="article:published_time" content="{{ ogdata.date }}">
|
||||
{% endif %}
|
||||
<link rel="shortcut icon" type="image/png" href="{% static "img/favicon.png" %}">
|
||||
@@ -62,6 +62,7 @@
|
||||
document.documentElement.style.setProperty("--theme-slightly-dark", slightlyDarkColor);
|
||||
document.documentElement.style.setProperty("--theme-darker", darkerColor);
|
||||
document.documentElement.style.setProperty("--theme-light", lightColor);
|
||||
{% if not request.user.bg_url %}document.documentElement.style.setProperty("--background", "url('img/indigo-pattern.png')");{% endif %}
|
||||
}
|
||||
|
||||
// hex -> rgb
|
||||
@@ -80,18 +81,19 @@
|
||||
}
|
||||
|
||||
function toDefault() {
|
||||
document.documentElement.style.setProperty("--theme", "initial");
|
||||
document.documentElement.style.setProperty("--theme", "");
|
||||
document.documentElement.style.setProperty("--theme-dark", "initial");
|
||||
document.documentElement.style.setProperty("--theme-slightly-dark", "initial");
|
||||
document.documentElement.style.setProperty("--theme-darker", "initial");
|
||||
document.documentElement.style.setProperty("--theme-light", "initial");
|
||||
document.documentElement.style.setProperty("--background", "");
|
||||
}
|
||||
|
||||
changeThemeColor();
|
||||
</script>{% endif %}
|
||||
<style>
|
||||
:root {
|
||||
{% if request.user.bg_url %}--background: url({{ request.user.bg_url }});{% elif not theme %}--background: url({% static 'img/Background.png' %}){% endif %}
|
||||
{% if request.user.bg_url %}--background: url({{ request.user.bg_url }});{% endif %}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
@@ -102,12 +104,12 @@
|
||||
<div id="wrapper"{% if not request.user.is_authenticated %} class="guest"{% endif %}>
|
||||
<div id="sub-body">
|
||||
<menu id="global-menu">
|
||||
<li id="global-menu-logo"><h1><a href="/"><img src="{% static "img/menu-logo.svg" %}" alt="Cedar"></a></h1></li>
|
||||
<li id="global-menu-logo"><h1><a href="/"><img src="{% static "img/menu-logo.svg" %}" alt="{{ brand_name }}"></a></h1></li>
|
||||
{% if request.user.unique_id %}
|
||||
{% invite_only request as inv %}
|
||||
<li id="global-menu-list">
|
||||
<ul>
|
||||
<li id="global-menu-mymenu"><a href="{% url "main:user-view" request.user.username %}"><span class="icon-container {% user_class request.user %}"><img src="{% avatar request.user %}" alt="My Profile"></span><span>My Profile</span></a></li>
|
||||
<li id="global-menu-mymenu"><a href="{% url "main:user-view" request.user.username %}"><span class="icon-container {% user_class request.user %}"><img src="{% avatar request.user %}" alt="User Page"></span><span>User Page</span></a></li>
|
||||
<li id="global-menu-feed"><a href="{% url "main:activity" %}" class="symbol"><span>Activity Feed</span></a></li>
|
||||
<li id="global-menu-community"><a href="/" class="symbol"><span>Communities</span></a></li>
|
||||
<li id="global-menu-message"><a href="{% url "main:messages" %}" class="symbol"><span>Messages</span></a></li>
|
||||
@@ -117,9 +119,10 @@
|
||||
<li><a href="{% url "main:profile-settings" %}" class="symbol my-menu-profile-setting"><span>Profile settings</span></a></li>
|
||||
<li><a href="#" class="symbol my-menu-account-setting"><span>Account preferences</span></a></li>
|
||||
{% if inv %}<li><a href="{% url "main:invites" %}" class="symbol my-menu-guide"><span>Invites</span></a></li>{% endif %}
|
||||
<li><a href="{% url "main:special-community-tag" "announcements" %}" class="symbol my-menu-openman"><span>Cedar Announcements</span></a></li>
|
||||
<li><a href="{% url "main:special-community-tag" "announcements" %}" class="symbol my-menu-openman"><span>{{ brand_name }} Announcements</span></a></li>
|
||||
<li><a href="{% url "main:special-community-tag" "changelog" %}" class="symbol my-menu-openman"><span>{{ brand_name }} Changelog</span></a></li>
|
||||
<li><a href="{% url "main:help-faq" %}" class="symbol my-menu-guide"><span>Frequently Asked Questions (FAQ)</span></a></li>
|
||||
<li><a href="{% url "main:help-rules" %}" class="symbol my-menu-guide"><span>Cedar Rules</span></a></li>
|
||||
<li><a href="{% url "main:help-rules" %}" class="symbol my-menu-guide"><span>{{ brand_name }} Rules</span></a></li>
|
||||
<li><a href="#" class="symbol my-menu-white-power"><span>Feedback/bug report</span></a></li>
|
||||
<li><a href="{% url "main:server-stat" %}" class="symbol my-menu-openman"><span>Server Statistics</span></a></li>
|
||||
<li>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<form method="post">
|
||||
<img src="{% static "img/menu-logo.svg" %}">
|
||||
<h1 class="lh">Sign In</h1>
|
||||
<h2 class="lh">Please sign in to access Cedar.</h2>
|
||||
<h2 class="lh">Please sign in to access {{ brand_name }}.</h2>
|
||||
<div class="login-box">
|
||||
<h3 class="label"><input type="text" class="auth-input" name="username" maxlength="32" placeholder="Username"></h3>
|
||||
<h3 class="label"><input type="password" class="auth-input" name="password" maxlength="32" placeholder="Password"></h3>
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
</h1>
|
||||
</header>
|
||||
{% if post.is_mine or post.can_rm %}
|
||||
{% if user.is_active %}
|
||||
<div class="edit-buttons-content">
|
||||
<button type="button" class="symbol button edit-button rm-post-button" data-action="{% url "main:post-rm" post.id %}"><span class="symbol-label">Delete</span></button>
|
||||
{% if post.is_mine and not post.has_edit %}
|
||||
@@ -19,8 +18,10 @@
|
||||
{% if post.is_mine and post.screenshot %}
|
||||
<button type="button" class="symbol button edit-button profile-post-button{% if post.is_favorite %} done {% endif %}" data-action="{% if post.is_favorite %}{% url "main:post-unset-profile" post.id %}{% else %}{% url "main:post-set-profile" post.id %}{% endif %}"><span class="symbol-label">Set as profile post</span></button>
|
||||
{% endif %}
|
||||
{% if post.can_lock_comments %}
|
||||
<button type="button" class="symbol button edit-button lock-comments-button" data-action="{% url "main:lock-the-comments" post.id %}"><span class="symbol-label">Lock comments</span></button>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
<div class="user-content">
|
||||
@@ -83,12 +84,14 @@
|
||||
{% elif post.screenshot %}<div class="screenshot-container still-image"><img src="{{ post.screenshot }}"></div>{% endif %}
|
||||
|
||||
{% if post.yt_vid %}
|
||||
<div class="screenshot-container video"><iframe class="youtube-player" type="text/html" width="490" height="276" src="https://www.youtube.com/embed/{{ post.yt_vid }}?rel=0&modestbranding=1&iv_load_policy=3" frameborder="0"></iframe></div>
|
||||
{% elif post.discord_vid %}
|
||||
<div class="DiscordCDN-container video">
|
||||
<video class="discord-player" src="{{ post.url }}" style='max-width:100%;' controls></video>
|
||||
</div>
|
||||
<a>Discord embedded video</a>
|
||||
<div class="screenshot-container video"><iframe class="youtube-player" type="text/html" style="max-width:100%;max-height: 450px;" src="https://www.youtube.com/embed/{{ post.yt_vid }}?rel=0&modestbranding=1&iv_load_policy=3" frameborder="0"></iframe></div>
|
||||
{% elif post.video %}
|
||||
<div class="screenshot-container video"><video class="vidya" controls src="{{ post.video }}" style="max-width:100%;max-height: 450px;"></video></div>
|
||||
{% elif post.discord_vid %}
|
||||
<div class="DiscordCDN-container video">
|
||||
<video class="discord-player" src="{{ post.url }}" style="max-width:100%;max-height: 450px;" controls></video>
|
||||
</div>
|
||||
<a>Discord embedded video</a>
|
||||
{% elif post.url %}
|
||||
<p class="url-link"><a class="link-confirm" href="{{ post.url }}" target="_blank">{{ post.url }}</a></p>
|
||||
{% endif %}
|
||||
@@ -126,13 +129,19 @@
|
||||
<h2 class="reply-label">Add a Comment</h2>
|
||||
{% if not request.user.is_authenticated %}
|
||||
<div class="guest-message">
|
||||
<p>You must sign in to post a comment.<br><br>Sign in using a Cedar account to make posts and comments, as well as give Yeahs and follow users.</p>
|
||||
<p>You must sign in to post a comment.<br><br>Sign in using a {{ brand_name }} account to make posts and comments, as well as give Yeahs and follow users.</p>
|
||||
<a href="{% url "main:signup" %}" class="arrow-button"><span>Create an account</span></a>
|
||||
<a href="{% url "main:help-faq" %}" class="arrow-button"><span>FAQ/Frequently Asked Questions</span></a>
|
||||
</div>
|
||||
{% elif not post.can_comment %}
|
||||
<div class="cannot-reply"><div>
|
||||
{% if post.lock_comments == 1 %}
|
||||
<p>{{ post.creator.nickname }} has locked the comments.</p>
|
||||
{% elif post.lock_comments == 2 %}
|
||||
<p>The comments have been locked up tight.</p>
|
||||
{% else %}
|
||||
<p>You cannot comment on this post.</p>
|
||||
{% endif %}
|
||||
</div></div>
|
||||
{% else %}
|
||||
{% comment_form post request.user %}
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
<li class="setting-profile-comment">
|
||||
<p class="settings-label">Profile comment</p>
|
||||
<textarea class="textarea" name="profile_comment" maxlength="2200" placeholder="Write about yourself here.">{{ profile.comment }}</textarea>
|
||||
<p class="note">Anything you write here will appear on your profile. Remember to keep it brief. Please don't write anything that'll violate <a href="{% url "main:help-rules" %}">Cedar's rules</a>.</p>
|
||||
|
||||
<p class="note">Anything you write here will appear on your profile. Remember to keep it brief. Please don't write anything that'll violate <a href="{% url "main:help-rules" %}">{{ brand_name }}'s rules</a>.</p>
|
||||
</li>
|
||||
<!--
|
||||
<li>
|
||||
@@ -128,12 +129,12 @@
|
||||
<div class="select-content">
|
||||
<div class="select-button">
|
||||
<select name="pronoun_dot_is" id="pronoun_dot_is">
|
||||
<option value="0"{% if profile.pronoun_is == 0 %} selected{% endif %}>I don't know</option>
|
||||
<option value="1"{% if profile.pronoun_is == 1 %} selected{% endif %}>He/him</option>
|
||||
<option value="2"{% if profile.pronoun_is == 2 %} selected{% endif %}>She/her</option>
|
||||
<option value="3"{% if profile.pronoun_is == 3 %} selected{% endif %}>He/she</option>
|
||||
<option value="4"{% if profile.pronoun_is == 4 %} selected{% endif %}>It</option>
|
||||
<option value="5"{% if profile.pronoun_is == 5 %} selected{% endif %}>They/Them</option>
|
||||
<option value="0"{% if profile.pronoun_is == 0 %} selected{% endif %}>I don't know</option>
|
||||
<option value="1"{% if profile.pronoun_is == 1 %} selected{% endif %}>He/him</option>
|
||||
<option value="2"{% if profile.pronoun_is == 2 %} selected{% endif %}>She/her</option>
|
||||
<option value="3"{% if profile.pronoun_is == 3 %} selected{% endif %}>He/she</option>
|
||||
<option value="4"{% if profile.pronoun_is == 4 %} selected{% endif %}>It</option>
|
||||
<option value="5"{% if profile.pronoun_is == 5 %} selected{% endif %}>They/Them</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
<form method="post" onload="">
|
||||
<img src="{% static "img/menu-logo.svg" %}">
|
||||
<p class="lh">Sign Up</p>
|
||||
<p>Create a Cedar account on this instance to access this instance.</p><br>
|
||||
<p>Create a {{ brand_name }} account to make posts and comments to various communities, give Yeahs to other users' content, and interact with other members of the {{ brand_name }} community.</p><br>
|
||||
<p>Please follow <a href="{% url "main:help-rules" %}">our rules</a>. If you don't, be careful with your behavior.<br><br>You <strong>must</strong> be {{ age }} years of age or older to join, no exceptions.<br>If you are suspected to be younger than {{ age }} years old, we will ban you until you're {{ age }}.</p>
|
||||
{% if invite_only %}<h3 class="label"><label><span class="red">*</span> Invite code: <input type="text" class="auth-input" name="invite_code" maxlength="64" minlength="4" placeholder="Invite code"></label></h3>{% endif %}
|
||||
<h3 class="label"><label><span class="red">*$</span> User ID: <input type="text" class="auth-input" name="username" maxlength="32" minlength="4" placeholder="ID"></label></h3>
|
||||
<h3 class="label"><label>Nickname: <input type="text" class="auth-input" name="nickname" maxlength="32" placeholder="Nick/Mii name?"></label></h3>
|
||||
<h3 class="label"><label><span class="red">*$</span> Username: <input type="text" class="auth-input" name="username" maxlength="32" minlength="4" placeholder="Username"></label></h3>
|
||||
<h3 class="label"><label><span class="red">*</span>Nickname: <input type="text" class="auth-input" name="nickname" maxlength="32" placeholder="Nick/Mii name?"></label></h3>
|
||||
<h3 class="label nnid"><label>Nintendo Network ID: <input type="text" class="auth-input" name="origin_id" maxlength="16" minlength="6" placeholder="NNID" data-mii-domain="{{ mii_domain }}" data-action="{{ mii_endpoint }}">
|
||||
<img class="none">
|
||||
</label></h3>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{% extends "closedverse_main/layout.html" %}
|
||||
{% load closedverse_tags %}{% block main-body %}
|
||||
{% nocontent "Sign Ups are disabled for now. Please contact the administrator using the contact page." %}
|
||||
{% nocontent "Sign ups are disabled for now. Please contact the administrator using the contact page." %}
|
||||
{% endblock %}
|
||||
@@ -6,6 +6,7 @@ def community_sidebar(community, request):
|
||||
return {
|
||||
'community': community,
|
||||
'can_edit': community.can_edit_community(request),
|
||||
'Community_block': community.Community_block(request),
|
||||
'request': request,
|
||||
}
|
||||
@register.inclusion_tag('closedverse_main/elements/community_post.html')
|
||||
@@ -64,9 +65,10 @@ def file_button():
|
||||
|
||||
}
|
||||
@register.inclusion_tag('closedverse_main/elements/community_page_elem.html')
|
||||
def community_page_element(communities, text='General Communities', feature=False):
|
||||
def community_page_element(communities, text='General Communities', feature=False, url_name=''):
|
||||
return {
|
||||
'communities': communities,
|
||||
'title': text,
|
||||
'feature': feature,
|
||||
'url_name': url_name,
|
||||
}
|
||||
|
||||
@@ -97,8 +97,8 @@ def print_names(names):
|
||||
'nameallmn': len(names) - 4,
|
||||
'names': names,
|
||||
}
|
||||
@register.inclusion_tag('closedverse_main/elements/discordapp-spinner.html')
|
||||
def discordapp_spinner():
|
||||
@register.inclusion_tag('closedverse_main/elements/loading-spinner.html')
|
||||
def loading_spinner():
|
||||
return {
|
||||
|
||||
}
|
||||
|
||||
@@ -69,9 +69,10 @@ def u_post_list(posts, next_offset=None, type=2, nf_text='', time=None):
|
||||
'type': type,
|
||||
}
|
||||
@register.inclusion_tag('closedverse_main/elements/profile-post.html')
|
||||
def profile_post(post):
|
||||
def profile_post(post, for_announcements=False):
|
||||
return {
|
||||
'post': post,
|
||||
'for_announcements': for_announcements,
|
||||
}
|
||||
@register.inclusion_tag('closedverse_main/elements/profile-user-list.html')
|
||||
def profile_user_list(users, next_offset=None, request=None):
|
||||
|
||||
@@ -61,7 +61,7 @@ urlpatterns = [
|
||||
url(r'posts/'+ post +'/yeah$', views.post_add_yeah, name='post-add-yeah'),
|
||||
url(r'posts/'+ post +'/yeahu$', views.post_delete_yeah, name='post-delete-yeah'),
|
||||
url(r'posts/'+ post +'/comments$', views.post_comments, name='post-comments'),
|
||||
url(r'posts/'+ post +'/comments$', views.post_comments, name='post-comments'),
|
||||
url(r'posts/'+ post +'/lock-comments$', views.lock_the_comments, name='lock-the-comments'),
|
||||
url(r'posts/'+ post +'/change$', views.post_change, name='post-change'),
|
||||
url(r'posts/'+ post +'/profile$', views.post_setprofile, name='post-set-profile'),
|
||||
url(r'posts/'+ post +'/profile_rm', views.post_unsetprofile, name='post-unset-profile'),
|
||||
@@ -115,4 +115,6 @@ urlpatterns = [
|
||||
#url(r'openverse.png', views.openverse_logo, name='openverse-logo'),
|
||||
|
||||
]
|
||||
# + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||
# serve static and media i think???? mighTTT???????
|
||||
urlpatterns += [re_path(r'^i/(?P<path>.*)$', serve, {'document_root': MEDIA_ROOT, }), ]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Todo: move all requests to using requests instead of urllib3
|
||||
import urllib.request, urllib.error
|
||||
import requests
|
||||
# requests is only used for get_mii which is not being used currently
|
||||
#import requests
|
||||
from lxml import etree
|
||||
from random import choice
|
||||
import json
|
||||
@@ -38,35 +38,41 @@ def HumanTime(date, full=False):
|
||||
unit_name += 's'
|
||||
return f'{number_of_units} {unit_name} ago'
|
||||
|
||||
# the current source as of now uses AJAX to get mii data
|
||||
def get_mii(id):
|
||||
# Using AccountWS
|
||||
dmca = {
|
||||
'X-Nintendo-Client-ID': 'a2efa818a34fa16b8afbc8a74eba3eda',
|
||||
'X-Nintendo-Client-Secret': 'c91cdb5658bd4954ade78533a339cf9a',
|
||||
}
|
||||
# TODO: Make this, the gravatar request, and reCAPTCHA request escape (or plainly use) URL params
|
||||
nnid = requests.get('https://accountws.nintendo.net/v1/api/admin/mapped_ids?input_type=user_id&output_type=pid&input=' + id, headers=dmca)
|
||||
nnid_dec = etree.fromstring(nnid.content)
|
||||
del(nnid)
|
||||
|
||||
# Perform the first request to get pid
|
||||
url_pid = 'https://accountws.nintendo.net/v1/api/admin/mapped_ids?input_type=user_id&output_type=pid&input=' + id
|
||||
request_pid = urllib.request.Request(url_pid, headers=dmca)
|
||||
with urllib.request.urlopen(request_pid) as nnid_response:
|
||||
nnid_content = nnid_response.read()
|
||||
nnid_dec = etree.fromstring(nnid_content)
|
||||
pid = nnid_dec[0][1].text
|
||||
if not pid:
|
||||
return False
|
||||
del(nnid_dec)
|
||||
mii = requests.get('https://accountws.nintendo.net/v1/api/miis?pids=' + pid, headers=dmca)
|
||||
|
||||
# Perform the second request to get mii information
|
||||
url_mii = 'https://accountws.nintendo.net/v1/api/miis?pids=' + pid
|
||||
request_mii = urllib.request.Request(url_mii, headers=dmca)
|
||||
with urllib.request.urlopen(request_mii) as mii_response:
|
||||
mii_content = mii_response.read()
|
||||
try:
|
||||
mii_dec = etree.fromstring(mii.content)
|
||||
# Can't be fucked to put individual exceptions to catch here
|
||||
mii_dec = etree.fromstring(mii_content)
|
||||
except:
|
||||
return False
|
||||
del(mii)
|
||||
|
||||
try:
|
||||
miihash = mii_dec[0][2][0][0].text.split('.net/')[1].split('_')[0]
|
||||
except IndexError:
|
||||
miihash = None
|
||||
screenname = mii_dec[0][3].text
|
||||
nnid = mii_dec[0][6].text
|
||||
del(mii_dec)
|
||||
# Also todo: Return the NNID based on what accountws returns, not the user's input!!!
|
||||
|
||||
return [miihash, screenname, nnid]
|
||||
|
||||
def recaptcha_verify(request, key):
|
||||
@@ -78,6 +84,26 @@ def recaptcha_verify(request, key):
|
||||
return False
|
||||
return True
|
||||
|
||||
def video_upload(video):
|
||||
hash = sha1()
|
||||
for chunk in video.chunks():
|
||||
hash.update(chunk)
|
||||
imhash = hash.hexdigest()
|
||||
# only either webm or mp4
|
||||
extension = video.name[-4:]
|
||||
if extension == '.mp4':
|
||||
fname = imhash + '.mp4'
|
||||
elif extension == 'webm':
|
||||
fname = imhash + '.webm'
|
||||
else:
|
||||
return 1
|
||||
# simply only write image if the hashed path doesn't already exist
|
||||
if not os.path.exists(settings.MEDIA_ROOT + fname):
|
||||
with open(settings.MEDIA_ROOT + fname, "wb+") as destination:
|
||||
for chunk in video.chunks():
|
||||
destination.write(chunk)
|
||||
return settings.MEDIA_URL + fname
|
||||
|
||||
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
||||
def image_upload(img, stream=False, drawing=False, avatar=False):
|
||||
if stream:
|
||||
@@ -212,11 +238,28 @@ def getipintel(addr):
|
||||
else:
|
||||
return 0
|
||||
"""
|
||||
|
||||
# not ideal, switch this to use a real cache when caching for everything else is implemented (never?)
|
||||
iphub_cache = dict()
|
||||
|
||||
# Now using iphub
|
||||
def iphub(addr):
|
||||
def iphub(addr, want_asn=False):
|
||||
# hack to exclude my private network at the time (security flaw?)
|
||||
if settings.IPHUB_KEY and not '192.168' in addr:
|
||||
get = requests.get('http://v2.api.iphub.info/ip/' + addr, headers={'X-Key': settings.IPHUB_KEY})
|
||||
if get.json()['block'] == 1:
|
||||
return True
|
||||
if addr in iphub_cache:
|
||||
get_r = iphub_cache[addr]
|
||||
#print('getting ip ' + addr + ' from cache 😌')
|
||||
else:
|
||||
return False
|
||||
#print('GETTING IP ' + addr + ' FROM IPHUB😤😤😤😤😤😤')
|
||||
req = urllib.request.Request('http://v2.api.iphub.info/ip/' + addr, headers={'X-Key': settings.IPHUB_KEY})
|
||||
response = urllib.request.urlopen(req)
|
||||
data = response.read().decode()
|
||||
get_r = json.loads(data)
|
||||
iphub_cache[addr] = get_r
|
||||
if want_asn:
|
||||
return get_r.get('asn', '0')
|
||||
if get_r.get('block', 0) == 1:
|
||||
return True
|
||||
# should just return falsey when returning nothing anyway?
|
||||
#else:
|
||||
# return False
|
||||
|
||||
@@ -3,16 +3,15 @@ from django.template import loader
|
||||
from django.shortcuts import render, redirect, get_object_or_404
|
||||
from django.http import Http404
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
from django.db.models import Q, QuerySet, Max, F, Count, Case, When, Exists, OuterRef
|
||||
from django.contrib.auth import login, logout
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.views.decorators.http import require_http_methods
|
||||
from django.core.validators import EmailValidator
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.db.models import Q, Count, Exists, OuterRef
|
||||
from django.db.models.functions import Now
|
||||
from .models import *
|
||||
from .util import *
|
||||
from .serializers import CommunitySerializer
|
||||
from closedverse import settings
|
||||
import re
|
||||
from django.urls import reverse
|
||||
@@ -22,14 +21,19 @@ from json import dumps, loads
|
||||
import sys, traceback
|
||||
import base64
|
||||
import subprocess
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timedelta
|
||||
from django.utils import timezone
|
||||
import django.utils.dateformat
|
||||
from binascii import hexlify
|
||||
from os import urandom
|
||||
|
||||
#from silk.profiling.profiler import silk_profile
|
||||
|
||||
# client-side mii fetch GET endpoint (like pf2m.com/hash if it supported cors)
|
||||
mii_endpoint = 'https://nnidlt.murilo.eu.org/api.php?output=hash_only&env=production&user_id='
|
||||
#mii_endpoint = '/origin?a='
|
||||
if hasattr(settings, 'mii_endpoint'):
|
||||
mii_endpoint = settings.mii_endpoint
|
||||
|
||||
def json_response(msg='', code=0, httperr=400):
|
||||
thing = {
|
||||
@@ -46,9 +50,10 @@ def json_response(msg='', code=0, httperr=400):
|
||||
'code': httperr,
|
||||
}
|
||||
return JsonResponse(thing, safe=False, status=httperr)
|
||||
|
||||
def community_list(request):
|
||||
"""Lists communities / main page."""
|
||||
popularity = Community.popularity
|
||||
#popularity = Community.popularity
|
||||
obj = Community.objects
|
||||
if request.user.is_authenticated:
|
||||
classes = ['guest-top']
|
||||
@@ -64,7 +69,8 @@ def community_list(request):
|
||||
ad = "no ads"
|
||||
|
||||
WelcomeMSG = welcomemsg.objects.filter(show=True).order_by('-order', '-id')
|
||||
announcements = Post.objects.filter(community__tags='announcements').order_by('-id')[:6]
|
||||
# announcements within the past week-ish
|
||||
announcements = Post.objects.filter(community__tags='announcements', created__gte=Now()-timedelta(days=5)).order_by('-created')[:6]
|
||||
if request.user.is_authenticated:
|
||||
my_communities = obj.filter(creator=request.user).order_by('-created')[0:12]
|
||||
else:
|
||||
@@ -206,7 +212,7 @@ def login_page(request):
|
||||
else:
|
||||
# Todo: I might want to do some things relating to making models take care of object stuff like this instead of the view, it's totally messed up now.
|
||||
successful = False if user[1] is False or not user[0].is_active() else True
|
||||
LoginAttempt.objects.create(user=user[0], success=successful, user_agent=request.META.get('HTTP_USER_AGENT'), addr=request.META.get('HTTP_CF_CONNECTING_IP'))
|
||||
LoginAttempt.objects.create(user=user[0], success=successful, user_agent=request.META.get('HTTP_USER_AGENT'), addr=request.META.get('REMOTE_ADDR'))
|
||||
if user[1] == False:
|
||||
return HttpResponse("Invalid password.", status=401)
|
||||
elif user[1] == 2:
|
||||
@@ -219,7 +225,7 @@ def login_page(request):
|
||||
# Then, let's get the referrer and either return that or the root.
|
||||
# Actually, let's not for now.
|
||||
#if request.META['HTTP_REFERER'] and "login" not in request.META['HTTP_REFERER'] and request.META['HTTP_HOST'] in request.META['HTTP_REFERER']:
|
||||
# location = request.META['HTTP_REFERER']
|
||||
# location = request.META['HTTP_REFERER']
|
||||
#else:
|
||||
location = '/'
|
||||
if request.GET.get('next'):
|
||||
@@ -243,8 +249,8 @@ def signup_page(request):
|
||||
if request.user.is_authenticated:
|
||||
return redirect('/')
|
||||
if request.method == 'POST':
|
||||
if settings.recaptcha_pub:
|
||||
if not recaptcha_verify(request, settings.recaptcha_priv):
|
||||
if settings.RECAPTCHA_PUBLIC_KEY:
|
||||
if not recaptcha_verify(request, settings.RECAPTCHA_PRIVATE_KEY):
|
||||
return HttpResponse("The reCAPTCHA validation has failed.", status=402)
|
||||
if not (request.POST.get('username') and request.POST.get('password') and request.POST.get('password_again')):
|
||||
return HttpResponseBadRequest("You didn't fill in all of the required fields.")
|
||||
@@ -263,15 +269,42 @@ def signup_page(request):
|
||||
return HttpResponseBadRequest("The provided invite code has been used or is void. Please ask for another code.")
|
||||
invited = True
|
||||
|
||||
|
||||
if not re.compile(r'^[A-Za-z0-9-._]{1,32}$').match(request.POST['username']) or not re.compile(r'[A-Za-z0-9]').match(request.POST['username']):
|
||||
return HttpResponseBadRequest("Your username either contains invalid characters or is too long (only letters + numbers, dashes, dots and underscores are allowed")
|
||||
for keyword in ['admin', 'admln', 'adrnin', 'admn', ]:
|
||||
if keyword in request.POST['username'].lower():
|
||||
return HttpResponseForbidden("You aren't funny. Please use a funny name.")
|
||||
for keyword in ['nigger', 'nigga', 'faggot', 'kile', ]:
|
||||
if keyword in request.POST['username'].lower():
|
||||
return HttpResponseForbidden("Nigga test failed, invalid pass.")
|
||||
|
||||
# forbidden keywords
|
||||
groups = [
|
||||
[
|
||||
'admin', 'admln', 'adrnin', 'admn', 'closedverse',
|
||||
'arian', 'kordi', 'windowscj', 'gab', 'term',
|
||||
'penis', 'nazi', 'hitler', 'hitlre', 'ihtler', 'heil', 'kkk'
|
||||
'nigg', 'niger', 'fag',
|
||||
'smf9', 'dakux', 'dacucks', 'adrian'
|
||||
],
|
||||
['adam', 'nintendotom'],
|
||||
['funny'],
|
||||
['doeggs', 'do_eggs', 'do-eggs', 'do.eggs'],
|
||||
]
|
||||
messages = [
|
||||
"That username isn't funny. Please pick a funny username.",
|
||||
"Adam, no.",
|
||||
"I'm laughing so hard right now!! No seriously. Pick a better username.",
|
||||
"the world may never know",
|
||||
]
|
||||
for id in range(len(groups)):
|
||||
for keyword in groups[id]:
|
||||
if keyword in request.POST['username'].lower() or keyword in request.POST['nickname'].lower():
|
||||
# perhaps warn admins at a later time
|
||||
return HttpResponseForbidden(messages[id])
|
||||
|
||||
# this is such a miniscule amount of NNIDs that either an admin or a person could
|
||||
# claim all of them, in which case they could not be reused
|
||||
#for keyword in ['windowscj', 'gabalt']:
|
||||
# if keyword in request.POST['origin_id'].lower():
|
||||
# return HttpResponseForbidden("You're very funny. Unfortunately your funniness blah blah blah fuck off.")
|
||||
|
||||
# end of forbidden keywords
|
||||
|
||||
conflicting_user = User.objects.filter(Q(username__iexact=request.POST['username']) | Q(username__iexact=request.POST['username'].replace(' ', '')))
|
||||
if conflicting_user:
|
||||
return HttpResponseBadRequest("A user with that username already exists.")
|
||||
@@ -280,11 +313,11 @@ def signup_page(request):
|
||||
# do the length check
|
||||
if len(request.POST['password']) < settings.minimum_password_length:
|
||||
return HttpResponseBadRequest('The password must be at least ' + str(settings.minimum_password_length) + ' characters long.')
|
||||
if not (request.POST['nickname'] or request.POST['origin_id']):
|
||||
return HttpResponseBadRequest("You didn't fill in an NNID, so you need a nickname.")
|
||||
if not request.POST['nickname']:
|
||||
return HttpResponseBadRequest("You need a nickname. What else are we gonna call you????? Ghosty?")
|
||||
if request.POST['nickname'] and len(request.POST['nickname']) > 32:
|
||||
return HttpResponseBadRequest("Your nickname is either too long or too short (1-32 characters)")
|
||||
if request.POST['origin_id'] and (len(request.POST['origin_id']) > 16 or len(request.POST['origin_id']) < 6):
|
||||
if request.POST.get('origin_id') and (len(request.POST['origin_id']) > 16 or len(request.POST['origin_id']) < 6):
|
||||
return HttpResponseBadRequest("The NNID provided is either too short or too long.")
|
||||
if request.POST.get('email'):
|
||||
if User.email_in_use(request.POST['email']):
|
||||
@@ -293,46 +326,50 @@ def signup_page(request):
|
||||
EmailValidator()(value=request.POST['email'])
|
||||
except ValidationError:
|
||||
return HttpResponseBadRequest("Your e-mail address is invalid. Input an e-mail address, or input nothing.")
|
||||
check_others = Profile.objects.filter(user__addr=request.META['HTTP_CF_CONNECTING_IP'], let_freedom=False).exists()
|
||||
check_others = Profile.objects.filter(user__addr=request.META['REMOTE_ADDR'], let_freedom=False).exists()
|
||||
if check_others:
|
||||
return HttpResponseBadRequest("Unfortunately, you cannot make any accounts at this time. This restriction was set for a reason, please contact the administration. Please don't bypass this, as if you do, you are just being ignorant. If you have not made any accounts, contact the administration and this restriction will be removed for you.")
|
||||
check_othersban = User.objects.filter(addr=request.META['HTTP_CF_CONNECTING_IP'], active=False).exists()
|
||||
check_othersban = User.objects.filter(addr=request.META['REMOTE_ADDR'], active=False).exists()
|
||||
if check_othersban:
|
||||
return HttpResponseBadRequest("You cannot sign up while banned.")
|
||||
check_signupban = User.objects.filter(signup_addr=request.META['HTTP_CF_CONNECTING_IP'], active=False).exists()
|
||||
check_signupban = User.objects.filter(signup_addr=request.META['REMOTE_ADDR'], active=False).exists()
|
||||
if check_signupban:
|
||||
return HttpResponseBadRequest("Get on your hands and knees")
|
||||
if iphub(request.META['HTTP_CF_CONNECTING_IP']):
|
||||
if settings.disallow_proxy:
|
||||
return HttpResponseBadRequest("You cannot sign up with a proxy.")
|
||||
if request.POST['origin_id']:
|
||||
if iphub(request.META['REMOTE_ADDR']):
|
||||
if settings.DISALLOW_PROXY:
|
||||
return HttpResponseBadRequest("please do not use a vpn ok thanks")
|
||||
if request.POST.get('origin_id'):
|
||||
if not request.POST.get('mh'):
|
||||
return HttpResponseBadRequest("sorry didn't get the mii image attribute. you might need to wait or just refresh, sorry")
|
||||
if User.nnid_in_use(request.POST['origin_id']):
|
||||
return HttpResponseBadRequest("That Nintendo Network ID is already in use, that would cause confusion.")
|
||||
mii = get_mii(request.POST['origin_id'])
|
||||
if not mii:
|
||||
return HttpResponseBadRequest("The NNID provided doesn't exist.")
|
||||
nick = mii[1]
|
||||
#mii = get_mii(request.POST['origin_id'])
|
||||
#if not mii:
|
||||
# return HttpResponseBadRequest("The NNID provided doesn't exist.")
|
||||
#nick = mii[1]
|
||||
nick = request.POST['nickname']
|
||||
mii = [request.POST.get('mh'), 'if you see this then something is wrong', request.POST['origin_id']]
|
||||
gravatar = False
|
||||
else:
|
||||
nick = request.POST['nickname']
|
||||
mii = None
|
||||
gravatar = True
|
||||
make = User.objects.closed_create_user(username=request.POST['username'], password=request.POST['password'], email=request.POST.get('email'), addr=request.META['HTTP_CF_CONNECTING_IP'], user_agent=request.META['HTTP_USER_AGENT'], signup_addr=request.META['HTTP_CF_CONNECTING_IP'], nick=nick, nn=mii, gravatar=gravatar)
|
||||
make = User.objects.closed_create_user(username=request.POST['username'], password=request.POST['password'], email=request.POST.get('email'), addr=request.META['REMOTE_ADDR'], user_agent=request.META['HTTP_USER_AGENT'], signup_addr=request.META['REMOTE_ADDR'], nick=nick, nn=mii, gravatar=gravatar)
|
||||
if invited == True:
|
||||
invite.used = True
|
||||
invite.used_by = make
|
||||
invite.save()
|
||||
|
||||
LoginAttempt.objects.create(user=make, success=True, user_agent=request.META.get('HTTP_USER_AGENT'), addr=request.META.get('HTTP_CF_CONNECTING_IP'))
|
||||
LoginAttempt.objects.create(user=make, success=True, user_agent=request.META.get('HTTP_USER_AGENT'), addr=request.META.get('REMOTE_ADDR'))
|
||||
login(request, make)
|
||||
request.session['passwd'] = make.password
|
||||
return HttpResponse("/")
|
||||
else:
|
||||
if not settings.recaptcha_pub:
|
||||
settings.recaptcha_pub = None
|
||||
if not settings.RECAPTCHA_PUBLIC_KEY:
|
||||
settings.RECAPTCHA_PUBLIC_KEY = None
|
||||
return render(request, 'closedverse_main/signup_page.html', {
|
||||
'title': 'Sign up',
|
||||
'recaptcha': settings.recaptcha_pub,
|
||||
'recaptcha': settings.RECAPTCHA_PUBLIC_KEY,
|
||||
'invite_only': settings.invite_only,
|
||||
'age': settings.age_allowed,
|
||||
'mii_domain': mii_domain,
|
||||
@@ -374,10 +411,15 @@ def forgot_passwd(request):
|
||||
|
||||
def logout_page(request):
|
||||
"""Password email page / post endpoint."""
|
||||
if not request.user.is_active():
|
||||
r = HttpResponseForbidden("You can't log out while you're inactive. According to me and God, you'll just have to sit here and suffer for now. Go contemplate your actions. You will be redirected to Wario Land 4 momentarily.", content_type='text/plain')
|
||||
r['Refresh'] = '7; url=https://gba.js.org/player#warioland4'
|
||||
return r
|
||||
logout(request)
|
||||
if request.GET.get('next'):
|
||||
return redirect(request.GET['next'])
|
||||
return redirect('/')
|
||||
|
||||
def user_view(request, username):
|
||||
"""The user view page, has recent posts/yeahs."""
|
||||
user = get_object_or_404(User, username__iexact=username)
|
||||
@@ -423,11 +465,15 @@ def user_view(request, username):
|
||||
if len(request.POST.get('bg_url')) > 300:
|
||||
return json_response('Background URL is too long (length '+str(len(request.POST.get('bg_url')))+', max 300)')
|
||||
if len(request.POST.get('whatareyou')) > 300:
|
||||
return json_response('Big brother it\'s too big, I can\'t take it! (length '+str(len(request.POST.get('whatareyou')))+', max 300)')
|
||||
return json_response('"What Are You" is too long (length '+str(len(request.POST.get('whatareyou')))+', max 300)')
|
||||
if len(request.POST.get('external')) > 255:
|
||||
return json_response('Big brother it\'s too big, I can\'t take it! (length '+str(len(request.POST.get('external')))+', max 300)')
|
||||
return json_response('Discord Tag is too long (length '+str(len(request.POST.get('external')))+', max 300)')
|
||||
if len(request.POST.get('email')) > 500:
|
||||
return json_response('Big brother it\'s too big, I can\'t take it! (length '+str(len(request.POST.get('email')))+', max 500)')
|
||||
return json_response('Email is too long (length '+str(len(request.POST.get('email')))+', max 500)')
|
||||
# Kinda unneeded but gdsjkgdfsg
|
||||
if request.POST.get('website') == 'Web URL' or request.POST.get('country') == 'Region' or request.POST.get('external') == 'Discord Tag':
|
||||
return json_response("I'm laughing right now.")
|
||||
|
||||
if len(request.POST.get('avatar')) > 255:
|
||||
return json_response('Avatar is too long (length '+str(len(request.POST.get('avatar')))+', max 255)')
|
||||
if request.POST.get('email') and not request.POST.get('email') == 'None':
|
||||
@@ -615,11 +661,11 @@ def user_posts(request, username):
|
||||
next_offset = offset + 50
|
||||
|
||||
if request.META.get('HTTP_X_AUTOPAGERIZE'):
|
||||
return (debug(request, username) if 'HTTP_DIS' in request.META else render(request, 'closedverse_main/elements/u-post-list.html', {
|
||||
return render(request, 'closedverse_main/elements/u-post-list.html', {
|
||||
'posts': posts,
|
||||
'next': next_offset,
|
||||
'time': offset_time.isoformat(),
|
||||
}))
|
||||
})
|
||||
else:
|
||||
return render(request, 'closedverse_main/user_posts.html', {
|
||||
'user': user,
|
||||
@@ -1079,7 +1125,7 @@ def community_create_action(request):
|
||||
def post_create(request, community):
|
||||
if request.method == 'POST':
|
||||
# Wake
|
||||
request.user.wake(request.META['HTTP_CF_CONNECTING_IP'])
|
||||
request.user.wake(request.META['REMOTE_ADDR'])
|
||||
# Required
|
||||
if not (request.POST.get('community')):
|
||||
return HttpResponseBadRequest()
|
||||
@@ -1106,7 +1152,8 @@ def post_create(request, community):
|
||||
7: "Please don't spam.",
|
||||
9: "You're very funny. Unfortunately your funniness blah blah blah fuck off.",
|
||||
10: "No mr white, you can't make a post entirely consistant of spaces",
|
||||
11: "Please don't post Zalgo text.",
|
||||
11: "The video you've uploaded is invalid.",
|
||||
12: "Please don't post Zalgo text.",
|
||||
}.get(new_post))
|
||||
# Render correctly whether we're posting to Activity Feed
|
||||
if community.is_activity():
|
||||
@@ -1134,6 +1181,7 @@ def post_view(request, post):
|
||||
post.can_rm = post.can_rm(request)
|
||||
post.is_favorite = post.is_favorite(request.user)
|
||||
post.can_comment = post.can_comment(request)
|
||||
post.can_lock_comments = post.can_lock_comments(request)
|
||||
if post.is_mine:
|
||||
title = 'Your post'
|
||||
else:
|
||||
@@ -1183,6 +1231,12 @@ def post_change(request, post):
|
||||
return HttpResponse()
|
||||
@require_http_methods(['POST'])
|
||||
@login_required
|
||||
def lock_the_comments(request, post):
|
||||
the_post = get_object_or_404(Post, id=post)
|
||||
the_post.lock_the_comments_up(request)
|
||||
return HttpResponse()
|
||||
@require_http_methods(['POST'])
|
||||
@login_required
|
||||
def post_setprofile(request, post):
|
||||
the_post = get_object_or_404(Post, id=post)
|
||||
the_post.favorite(request.user)
|
||||
@@ -1215,11 +1269,9 @@ def comment_rm(request, comment):
|
||||
@login_required
|
||||
def post_comments(request, post):
|
||||
post = get_object_or_404(Post, id=post)
|
||||
if not request.is_ajax():
|
||||
raise Http404()
|
||||
if request.method == 'POST':
|
||||
# Wake
|
||||
request.user.wake(request.META['HTTP_CF_CONNECTING_IP'])
|
||||
request.user.wake(request.META['REMOTE_ADDR'])
|
||||
# Method of Post
|
||||
new_post = post.create_comment(request)
|
||||
if not new_post:
|
||||
@@ -1234,7 +1286,7 @@ def post_comments(request, post):
|
||||
2: "The image you've uploaded is invalid.",
|
||||
3: "You're making comments too fast, wait a few seconds and try again.",
|
||||
6: "Not allowed.",
|
||||
11: "Please don't post Zalgo text.",
|
||||
12: "Please don't post Zalgo text.",
|
||||
}.get(new_post))
|
||||
# Give the notification!
|
||||
if post.is_mine(request.user):
|
||||
@@ -1327,17 +1379,15 @@ def user_follow(request, username):
|
||||
if user.follow(request.user):
|
||||
# Give the notification!
|
||||
Notification.give_notification(request.user, 4, user)
|
||||
followct = request.user.num_following()
|
||||
followct = user.num_followers()
|
||||
return JsonResponse({'following_count': followct})
|
||||
@require_http_methods(['POST'])
|
||||
@login_required
|
||||
def user_unfollow(request, username):
|
||||
user = get_object_or_404(User, username=username)
|
||||
user.unfollow(request.user)
|
||||
return HttpResponse()
|
||||
followct = request.user.num_following()
|
||||
followct = user.num_followers()
|
||||
return JsonResponse({'following_count': followct})
|
||||
|
||||
@require_http_methods(['POST'])
|
||||
@login_required
|
||||
def user_friendrequest_create(request, username):
|
||||
@@ -1397,7 +1447,7 @@ def check_notifications(request):
|
||||
all_count = request.user.get_frs_notif() + n_count
|
||||
msg_count = request.user.msg_count()
|
||||
# Let's update the user's online status
|
||||
request.user.wake(request.META['HTTP_CF_CONNECTING_IP'])
|
||||
request.user.wake(request.META['REMOTE_ADDR'])
|
||||
# Let's just now return the JSON only for Accept: HTML
|
||||
if 'html' in request.META.get('HTTP_ACCEPT'):
|
||||
return JsonResponse({'success': True, 'n': all_count, 'msg': msg_count})
|
||||
@@ -1414,14 +1464,6 @@ def check_notifications(request):
|
||||
return HttpResponse(binary_notifications, content_type='application/octet-stream')
|
||||
@require_http_methods(['POST'])
|
||||
@login_required
|
||||
def notification_setread(request):
|
||||
if request.GET.get('fr'):
|
||||
update = request.user.read_fr()
|
||||
else:
|
||||
update = request.user.notification_read()
|
||||
return HttpResponse()
|
||||
@require_http_methods(['POST'])
|
||||
@login_required
|
||||
def notification_delete(request, notification):
|
||||
if not request.method == 'POST':
|
||||
raise Http404()
|
||||
@@ -1559,7 +1601,7 @@ def messages_view(request, username):
|
||||
conversation = friendship.conversation()
|
||||
if request.method == 'POST':
|
||||
# Wake
|
||||
request.user.wake(request.META['HTTP_CF_CONNECTING_IP'])
|
||||
request.user.wake(request.META['REMOTE_ADDR'])
|
||||
new_post = conversation.make_message(request)
|
||||
if not new_post:
|
||||
return HttpResponseBadRequest()
|
||||
@@ -1637,46 +1679,6 @@ def prefs(request):
|
||||
arr = [profile.let_yeahnotifs, lights, request.user.hide_online]
|
||||
return JsonResponse(arr, safe=False)
|
||||
|
||||
@login_required
|
||||
def post_list(request):
|
||||
if not request.user.is_staff():
|
||||
return JsonResponse({"err": "Not authorized"})
|
||||
if not request.GET.get('s') or not request.GET.get('e'):
|
||||
return JsonResponse({"err": "Start time required with 's' query param and end required with 'e' param (epoch)"})
|
||||
if not request.GET.get('l'):
|
||||
return JsonResponse({"err": "Limit required via 'l' query param"})
|
||||
else:
|
||||
limit = int(request.GET['l'])
|
||||
if not request.GET.get('o'):
|
||||
return JsonResponse({"err": "Offset required via 'o' query param"})
|
||||
else:
|
||||
offset = int(request.GET['o'])
|
||||
|
||||
if limit > 250:
|
||||
return JsonResponse({"err": "Limit cannot be higher than 250"})
|
||||
|
||||
dateone = datetime.fromtimestamp(int(request.GET['s']))
|
||||
datetwo = datetime.fromtimestamp(int(request.GET['e']))
|
||||
iable = Post.objects.filter(created__range=(dateone, datetwo)).order_by('-created')[offset:offset + limit]
|
||||
resparr = []
|
||||
|
||||
for post in iable:
|
||||
resparr.append({
|
||||
'id': post.id,
|
||||
'created': django.utils.dateformat.format(post.created, 'U'),
|
||||
'user': post.creator.username,
|
||||
'community': post.community_id,
|
||||
'feeling': post.feeling,
|
||||
'spoiler': post.spoils,
|
||||
'content': (post.body or None),
|
||||
'drawing': (post.drawing or None),
|
||||
'screenshot': (post.screenshot or None),
|
||||
'url': (post.url or None),
|
||||
})
|
||||
|
||||
#return HttpResponse(msgpack.packb(resparr), content_type='application/x-msgpack')
|
||||
return JsonResponse(resparr, safe=False)
|
||||
|
||||
def user_tools(request, username):
|
||||
if not request.user.is_authenticated:
|
||||
raise Http404()
|
||||
@@ -1840,15 +1842,15 @@ def create_invite(request):
|
||||
else:
|
||||
raise Http404()
|
||||
|
||||
@require_http_methods(['POST'])
|
||||
#@require_http_methods(['POST'])
|
||||
# Disabling login requirement since it's in signup now. Regret?
|
||||
#@login_required
|
||||
def origin_id(request):
|
||||
if not request.headers.get('x-requested-with') == 'XMLHttpRequest':
|
||||
return HttpResponse("<a href='https://github.com/ariankordi/closedverse/blob/master/closedverse_main/util.py#L44-L86'>Please do not use this as an API!</a>")
|
||||
if not request.POST.get('a'):
|
||||
if not request.GET.get('a'):
|
||||
return HttpResponseBadRequest()
|
||||
mii = get_mii(request.POST['a'])
|
||||
mii = get_mii(request.GET['a'])
|
||||
if not mii:
|
||||
return HttpResponseBadRequest("The NNID provided doesn't exist.")
|
||||
return HttpResponse(mii[0])
|
||||
@@ -1954,17 +1956,17 @@ def whatads(request):
|
||||
return render(request, 'closedverse_main/help/whatads.html', {'title': 'What are user-generated ads?'})
|
||||
@login_required
|
||||
def help_rules(request):
|
||||
return render(request, 'closedverse_main/help/rules.html', {'title': 'Cedar Three Rules', 'age': settings.age_allowed})
|
||||
return render(request, 'closedverse_main/help/rules.html', {'title': 'Rules', 'age': settings.age_allowed})
|
||||
def help_faq(request):
|
||||
return render(request, 'closedverse_main/help/faq.html', {'title': 'FAQ'})
|
||||
def help_legal(request):
|
||||
if not settings.PROD:
|
||||
if not settings.CLOSEDVERSE_PROD:
|
||||
return HttpResponseForbidden()
|
||||
return render(request, 'closedverse_main/help/legal.html', {})
|
||||
return render(request, 'closedverse_main/help/legal.html', {'title': "Legal Information"})
|
||||
def help_contact(request):
|
||||
return render(request, 'closedverse_main/help/contact.html', {'title': "Contact Info"})
|
||||
return render(request, 'closedverse_main/help/contact.html', {'title': "Contact info"})
|
||||
def help_why(request):
|
||||
return render(request, 'closedverse_main/help/why.html', {'title': "Why even join Cedar Three?"})
|
||||
return render(request, 'closedverse_main/help/why.html', {'title': "Why even join this site?"})
|
||||
def help_login(request):
|
||||
return render(request, 'closedverse_main/help/login-help.html', {'title': "Login help"})
|
||||
|
||||
|
||||
@@ -476,10 +476,10 @@ border-top: 1px solid #222;
|
||||
border: 1px solid rgba(221, 221, 221, 0);
|
||||
}
|
||||
#wrapper, #image-header-content {
|
||||
background: var(--theme, #2f2f58) var(--background, url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAEpElEQVR4nO2dW3LiQBAEE8kmOPae2w7j/ZjFa0CAHi1N16jqABMZlf2pKB1Op9MfgnI8Hun7Puq5q5zPZz4+Pvj+/g55z6yFs4t6zIWWqLBeOEMOwIWWqLD+5lx8AC60RIX1lnPRAbjQEhXWIc7ZB+BCS1RYH3HOOgAXWqLC+oxz8gG40BIV1leckw7AhZaosI7hHH0ALrREhXUs56gDcKElKqxTOF8egAstUWGdyvn0AFxoiQrrHM6HB+BCS1RY53IOHoALLVFhXcJ5dwAutESFdSnn1QG40BIV1gjOnwNwoSUqrFGcHbjQS1RYIzk7F1qiwhrN2e29UNBhXYPzLeSlm3x9ffH5+Zm+UNi3/L7v4z4KvcTydeTDwk/CbmP5WvIh8AAsX08+BB2A5WvKh4ADOJ/Plh+cLTkXHYBKoaDDujXn7ANQKRR0WGtwzjoAlUJBh7UW5+QDUCkUdFhrck46AJVCQYe1NufoA6gNOiUqrBk4Rx1ABtCxUWHNwvnyALKAjokKaybOpweQCfRVVFizcT48gGygz6LCmpFz8AAygj6KCmtWzrsDyAo6FBXWzJxXB5AZ9DYqrNk5fw4gO+jvqLAqcHagAXqJCqsKZ6cCCjqlqnACdCqgKqWqcEL5kqtTAFUpVYUTinxPxQZGhRP+y4eAbwItX4cTruWDp2IXR4UT7uWDp2IXRYUThuWDp2JnR4UTHssHT8XOigonPJcPnoqdHBVOeC0fPBU7KSqcME4+eCp2dFQ4Ybx88FTsqKhwwjT54KnYl1HhhOnywVOxT6PCCfPkg6diH0aFE+bLB0/FDkaFE5bJB0/F3kWFE5bLB0/FXkWFE2Lkg6dif6LCCXHywVOxgA4nxMo/HA6eilXhhHj5x+MxfikUdEpV4YSV5Hdd/AGolKrCCevJh+CpWJVSVThhXfkQeAAqpapwwvryIegAVEpV4YRt5EPQVKxCqSqcsJ182MlUrAonbCsfdjAVq8IJ28uHxqdiVTihjnxoeCpWhRPqyYdGp2JVOKGufGhwKlaFE+rLh8amYlU4IYd8aGgqVoUT8siHRqZiVTghl3xoYCpWhRPyyQfxqVgVTsgpH4SnYlU4Ia98EJ2KVeGE3PJBcCpWhRPyywexqVgVTtCQD/Cm8t9fy1/l+106y4+NknyJqVjLX09++qlYy19XPiSeirX89eVD0qlYy99GPiScirX87eRDsqlYy99WPiSairX87eVDkqlYy68jHxJMxVp+PflQeSrW8uvKh4pTsZZfXz5Umoq1/BzyocJUrOXnkQ8bT8Vafi75sOFUrOXnkw8bTcVafk75sMFUrOXnlQ8rT8Vafm75sOJUrOXnl7/aVKzla8h/f3/f71IoWH7f97yFvPgvlq8hf5WpWMvXkw87WwoFyw+firV8Xfmwk6VQsPzwqVjL15cPjS+FguWHT8VafjvyodGlULD88KlYy29PPjS2FAr1C52SDKzNLIVCjkLHJgtrE0uhkKfQMcnEKr8UCrkKfZVsrNJLoZCv0GfJyCq7FAo5C32UrKySS6GQt9ChZGaVWwqF3IXeJjur1FIo5C/0dxRYO8vfr3yAv3rECG2I4F0DAAAAAElFTkSuQmCC')) !important;
|
||||
background: var(--theme, #eeeeee) var(--background, url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHgAAAB4CAIAAAC2BqGFAAAABmJLR0QAFgAWACbcRYNiAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QkQChoXcqytowAAATpJREFUeNrt3MEJwzAQRFFn8MlVuIT0X5jPqSEgLVr5/QLC7DskYII/9/095vQ8z9Gt67omfXIOlQQaNGiBBg0aAWjQAg0atECDFmjQoAUatECDBi3QoLUIdMd/z0ydHco140O55oRQrjkklGvOOct05v1Rc57mQJy8WblyWN6sXDkvL1cuGxnKNVNDuWawZx1FgQYNWqBBg0YAGrRAgwYt0KAFGjRogQYt0KBBCzRogQYNWqBBCzRo0AINWqBBgxZo0AINGrRAgxZo0KAFGrSWgG73Grypg9N3eq+p6X5Al5HZ44z152WnY1Yedg58B1nZez7LGoiTNWdtpjz+q2Mb6+GHZP2JGyjP+jFsbT1pfHrNbap8eNZRFmjQoAUaNGgEoEELNGjQAg1aoEGDFmjQAg0atECD1p/9AKkzTyh2EOP+AAAAAElFTkSuQmCC')) !important;
|
||||
}
|
||||
#empathy-content:before {
|
||||
background: url(/s/img/rks.png) no-repeat 0 0 !important;
|
||||
background: url(img/rks.png) no-repeat 0 0 !important;
|
||||
}
|
||||
.community-switcher .community-switcher-tab {
|
||||
background-color: var(--theme-dark, #202030);
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
@charset 'UTF-8';
|
||||
@font-face {
|
||||
font-family: 'MiiverseSymbols';
|
||||
src: url('/s/img/font/Symbols.eot');
|
||||
src: url('/s/img/font/Symbols-IEFix.eot') format('embedded-opentype'), url('/s/img/font/Symbols.woff') format('woff'), url('/s/img/font/Symbols.ttf') format('truetype');
|
||||
src: url('img/font/Symbols.eot');
|
||||
src: url('img/font/Symbols-IEFix.eot') format('embedded-opentype'), url('img/font/Symbols.woff') format('woff'), url('img/font/Symbols.ttf') format('truetype');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'MiiverseSymbols';
|
||||
src: url('/s/img/font/Symbols.eot');
|
||||
src: url('/s/img/font/Symbols-IEFix.eot') format('embedded-opentype'), url('/s/img/font/Symbols.woff') format('woff'), url('/s/img/font/Symbols.ttf') format('truetype');
|
||||
src: url('img/font/Symbols.eot');
|
||||
src: url('img/font/Symbols-IEFix.eot') format('embedded-opentype'), url('img/font/Symbols.woff') format('woff'), url('img/font/Symbols.ttf') format('truetype');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
@@ -81,19 +81,6 @@ button {
|
||||
font-size: 20px;
|
||||
width: 175px;
|
||||
}
|
||||
.Announcement-content {
|
||||
border: 1px solid #00000045;
|
||||
border-radius: 6px;
|
||||
padding: 6px;
|
||||
padding-bottom: 6px;
|
||||
margin-bottom: 12px;
|
||||
text-align: left;
|
||||
padding-bottom: 22px;
|
||||
background: white;
|
||||
}
|
||||
.Announcement-content .Announcement-image {
|
||||
padding-top: 6px;
|
||||
}
|
||||
.none {
|
||||
display: none !important;
|
||||
}
|
||||
@@ -220,8 +207,7 @@ body {
|
||||
min-width: 320px;
|
||||
margin: auto 0;
|
||||
text-align: left;
|
||||
background-color: #f4f4f4;
|
||||
background-image: var(--background, url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAArUlEQVQoFYWQuwrCQBBFd42FlaYQRMRCO3vBNpA/8HNtBbt04gcItnaKoLKegRnYTRYzcLjzuLNh4kMILooh+SeqO6kYJOawhzE0cIBsDLRboRPwsIUFZMMWTM1UWNJWMx4ZPHV4Rq9to9U+OlpeHcHDhjmNF3LzHc01yBdPEOwvkXdiQ6fW7gp9QWM3aD+RWVI5N5X638KF+VuXvqjUru+GEs8SbnCH3gXxJPEDtBsiPW8IwCQAAAAASUVORK5CYII='));
|
||||
background: var(--theme, #eee) var(--background, url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHgAAAB4CAIAAAC2BqGFAAADF0lEQVR4nO2dwW7bMBAFuRLz/5+bgyWyhwUE13ELtN43EIE3pyQHZj1YUoRMPcX393fT8Hg8zvOcc4rGryUi9n3/+voSjb+Jxm2tbdsWEbrxa4mIbVPa0A1tnrFoCIuGsGgIi4awaAiLhrBoCIuGsGgIi4awaAiLhrBoCIuGsGgIi4awaAiLhrBoCKHoOecqX4E3fbUS0RGxluUkaxZ9c6/q6DnnGEM0uIgxhq456kVnO+fRmYWaOqvNshVNXS96znkcx0JnlC5S9HEcisorRWcjnOd5nmfhsDBX/bV93UtGyZrGGFnl20XjqvsO58Su8l7qzF+zqfd9z0NiJQ1eIzovI1cv/KwsK87zbTcRnTVHxMtF+8V1RJQU3B+Px4eH+66i2zvFWeW2bYVFl/B89Wu/V54/jzHGGCXNMcbo53l+uA/70zRsraXZfd9rp2EJ1ySLiLcTMS1nG30oes7ZdZuw/Ay99+zl+yhOsp7s1og4jqP9Ycn++ff/QHuvI3u53amRX8jCrjp1qETnitF7v8+i/BeeZ57oX6judaToG64Yb8nth/Ryrerom2zj/gnp0xXCpWOVdk6yqZdcOhQjq1lv6TAvWDSERUNYNIRFQ1g0hEVDWDSERUNYNIRFQ1g0hEVDWDSERUNYNIRFQ1g0hEVDWDSERUNYNIRFQ1g0hEVDWDSERUNYNIRFQ1g0hEVDWDSERUNYNIRFQ1g0hEVDWDSERUNYNIRFQ1g0hEVDSESvFS34jK5yYWSmLudTgTpPVSVamvMpQpqnKlw6dDmf5QB5qsKlQ5fzWQ6Qp6rddYhyPgvB8lT755krfM5nCWSe6pyzXwo+GQXO+SyBzFMdY/SSd7uTOZ8lwHmq+77XpO2SOZ8l8HmqNaLhnE8dujzVyl0HlvMpRZSnKnmZgjrnU4Q0T1XyMgV1zqcCdZ6qMDJTl/MpQrojUt3rWKudE2meqrDp1nKtrnax2b0uFg1h0RAWDWHREBYNYdEQFg1h0RAWDWHREBYNYdEQFg1h0RAWDWHREBYNYdEQFg0hFL3W0xXS5ypaa78A+zg9ngAQ62UAAAAASUVORK5CYII='));
|
||||
background-attachment: fixed;
|
||||
}
|
||||
#sub-body {
|
||||
@@ -853,7 +839,7 @@ left: 10% !important;
|
||||
content: "Z";
|
||||
}
|
||||
#global-menu #global-my-menu .my-menu-white-power:before {
|
||||
content: url(/s/img/font/wp.svg);
|
||||
content: url(img/font/wp.svg);
|
||||
width: 20px;
|
||||
}
|
||||
#global-menu #global-my-menu .my-menu-account-setting:before {
|
||||
@@ -870,7 +856,7 @@ left: 10% !important;
|
||||
#global-menu #global-my-menu form input:hover,
|
||||
#global-menu #global-my-menu form input:active {
|
||||
text-indent: 27px;
|
||||
}
|
||||
}
|
||||
}
|
||||
h2.label {
|
||||
border-bottom: 3px solid var(--theme, #5ac800);
|
||||
@@ -1116,7 +1102,7 @@ h2.label-topic .with-filter-right {
|
||||
padding: 10px 10px 8px;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
background: url("/s/img/button-bg.gif") repeat-x 0 bottom #ffffff;
|
||||
background: url("img/button-bg.gif") repeat-x 0 bottom #ffffff;
|
||||
background-color: #ffffff;
|
||||
background: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#e6e6e6), color-stop(0.5, #ffffff));
|
||||
background: -webkit-linear-gradient(top, #ffffff 0%, #ffffff 50%, #e6e6e6 100%);
|
||||
@@ -1206,7 +1192,7 @@ h2.label-topic .with-filter-right {
|
||||
.tab2 a.selected,
|
||||
.tab3 a.selected {
|
||||
color: #FFF;
|
||||
background: url("/s/img/color-button-bg.gif") repeat-x 0 bottom #257811;
|
||||
background: url("img/color-button-bg.gif") repeat-x 0 bottom var(--theme, #2e81e5);
|
||||
background-color: #81e52e;
|
||||
background: -webkit-gradient(linear, left top, left bottom, from(var(--theme, #257811)), to(var(--theme-slightly-dark, #1e610e)));
|
||||
background: -webkit-linear-gradient(top, #257811 #1e610e);
|
||||
@@ -1301,28 +1287,34 @@ span.owner-label {
|
||||
height: 22px;
|
||||
}
|
||||
.icon-container.administrator:after {
|
||||
content: url("/s/img/administrator.png");
|
||||
content: url("img/administrator.png");
|
||||
}
|
||||
.icon-container.developer:after {
|
||||
content: url("/s/img/developer.png");
|
||||
content: url("img/developer.png");
|
||||
}
|
||||
.icon-container.badgedes:after {
|
||||
content: url("img/badgedes.png");
|
||||
}
|
||||
.icon-container.openverse:after {
|
||||
content: url("/s/img/open-dev.png");
|
||||
content: url("img/open-dev.png");
|
||||
}
|
||||
.icon-container.urapp:after {
|
||||
content: url("/s/img/open-zsdev.png");
|
||||
content: url("img/open-zsdev.png");
|
||||
}
|
||||
.icon-container.moderator:after {
|
||||
content: url("/s/img/moderator.png");
|
||||
content: url("img/moderator.png");
|
||||
}
|
||||
.icon-container.donator:after {
|
||||
content: url("/s/img/donator.png");
|
||||
content: url("img/donator.png");
|
||||
}
|
||||
.icon-container.tester:after {
|
||||
content: url("/s/img/tester.png");
|
||||
.icon-container.cool:after {
|
||||
content: url("img/cool.png");
|
||||
}
|
||||
.icon-container.verified:after {
|
||||
content: url("/s/img/verified.png");
|
||||
.icon-container.jack:after {
|
||||
content: url("img/jack.png");
|
||||
}
|
||||
.icon-container.verifiedd:after {
|
||||
content: url("img/verified.png");
|
||||
}
|
||||
|
||||
.multi-timeline-post-list .post .icon-container.offline:before,
|
||||
@@ -1390,6 +1382,9 @@ span.owner-label {
|
||||
.post-permalink-feeling-icon.developer {
|
||||
position: relative;
|
||||
}
|
||||
.post-permalink-feeling-icon.badgedes {
|
||||
position: relative;
|
||||
}
|
||||
.post-permalink-feeling-icon.openverse {
|
||||
position: relative;
|
||||
}
|
||||
@@ -1402,14 +1397,17 @@ span.owner-label {
|
||||
.post-permalink-feeling-icon.donator {
|
||||
position: relative;
|
||||
}
|
||||
.post-permalink-feeling-icon.tester {
|
||||
.post-permalink-feeling-icon.cool {
|
||||
position: relative;
|
||||
}
|
||||
.post-permalink-feeling-icon.staff {
|
||||
.post-permalink-feeling-icon.jack {
|
||||
position: relative;
|
||||
}
|
||||
.post-permalink-feeling-icon.verifiedd {
|
||||
position: relative;
|
||||
}
|
||||
.post-permalink-feeling-icon.administrator:after {
|
||||
content: url("/s/img/administrator.png");
|
||||
content: url("img/administrator.png");
|
||||
position: absolute;
|
||||
display: block;
|
||||
top: 0;
|
||||
@@ -1418,7 +1416,16 @@ span.owner-label {
|
||||
height: 22px;
|
||||
}
|
||||
.post-permalink-feeling-icon.developer:after {
|
||||
content: url("/s/img/developer.png");
|
||||
content: url("img/developer.png");
|
||||
position: absolute;
|
||||
display: block;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
}
|
||||
.post-permalink-feeling-icon.badgedes:after {
|
||||
content: url("img/badgedes.png");
|
||||
position: absolute;
|
||||
display: block;
|
||||
top: 0;
|
||||
@@ -1427,7 +1434,7 @@ span.owner-label {
|
||||
height: 22px;
|
||||
}
|
||||
.post-permalink-feeling-icon.openverse:after {
|
||||
content: url("/s/img/open-dev.png");
|
||||
content: url("img/open-dev.png");
|
||||
position: absolute;
|
||||
display: block;
|
||||
top: 0;
|
||||
@@ -1436,7 +1443,7 @@ span.owner-label {
|
||||
height: 22px;
|
||||
}
|
||||
.post-permalink-feeling-icon.moderator:after {
|
||||
content: url("/s/img/moderator.png");
|
||||
content: url("img/moderator.png");
|
||||
position: absolute;
|
||||
display: block;
|
||||
top: 0;
|
||||
@@ -1445,7 +1452,7 @@ span.owner-label {
|
||||
height: 22px;
|
||||
}
|
||||
.post-permalink-feeling-icon.donator:after {
|
||||
content: url("/s/img/donator.png");
|
||||
content: url("img/donator.png");
|
||||
position: absolute;
|
||||
display: block;
|
||||
top: 0;
|
||||
@@ -1453,8 +1460,8 @@ span.owner-label {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
}
|
||||
.post-permalink-feeling-icon.verified:after {
|
||||
content: url("/s/img/verified.png");
|
||||
.post-permalink-feeling-icon.verifiedd:after {
|
||||
content: url("img/verified.png");
|
||||
position: absolute;
|
||||
display: block;
|
||||
top: 0;
|
||||
@@ -1462,8 +1469,8 @@ span.owner-label {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
}
|
||||
.post-permalink-feeling-icon.tester:after {
|
||||
content: url("/s/img/tester.png");
|
||||
.post-permalink-feeling-icon.cool:after {
|
||||
content: url("img/cool.png");
|
||||
position: absolute;
|
||||
display: block;
|
||||
top: 0;
|
||||
@@ -1471,8 +1478,8 @@ span.owner-label {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
}
|
||||
.post-permalink-feeling-icon.Staff:after {
|
||||
content: url("/s/img/splus.png");
|
||||
.post-permalink-feeling-icon.jack:after {
|
||||
content: url("img/jack.png");
|
||||
position: absolute;
|
||||
display: block;
|
||||
top: 0;
|
||||
@@ -1525,6 +1532,9 @@ span.owner-label {
|
||||
.button.edit-post-button:before {
|
||||
content: "J" !important;
|
||||
}
|
||||
.button.lock-comments-button:before {
|
||||
content: "p" !important;
|
||||
}
|
||||
.button.rm-post-button:before {
|
||||
content: "d" !important;
|
||||
}
|
||||
@@ -1598,7 +1608,7 @@ span.owner-label {
|
||||
clear: both;
|
||||
display: block;
|
||||
padding: 11px 20px 9px 15px;
|
||||
background: url('/s/img/icon-arrow-right.png') no-repeat 97.5% center;
|
||||
background: url('img/icon-arrow-right.png') no-repeat 97.5% center;
|
||||
color: #323232;
|
||||
-webkit-background-size: 9px 15px;
|
||||
-moz-background-size: 9px 15px;
|
||||
@@ -1709,7 +1719,7 @@ font-size: 18px;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.5);
|
||||
background: url("/s/img/black-button-bg.gif") repeat-x 0 bottom #646464;
|
||||
background: url("img/black-button-bg.gif") repeat-x 0 bottom #646464;
|
||||
background-color: #646464;
|
||||
background: -webkit-gradient(linear, left top, left bottom, from(#646464), to(#323232), color-stop(0.96, #434343));
|
||||
background: -webkit-linear-gradient(top, #646464 0%, #434343 96%, #323232 100%);
|
||||
@@ -1767,7 +1777,7 @@ font-size: 18px;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
text-shadow: 0 1px 0 #fff;
|
||||
background: url("/s/img/gray-button-bg.gif") repeat-x 0 bottom #ffffff;
|
||||
background: url("img/gray-button-bg.gif") repeat-x 0 bottom #ffffff;
|
||||
background-color: #ffffff;
|
||||
background: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#bbbbbb), color-stop(0.96, #dddddd));
|
||||
background: -webkit-linear-gradient(top, #ffffff 0%, #dddddd 96%, #bbbbbb 100%);
|
||||
@@ -2947,7 +2957,7 @@ input.file-button {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
background: url('/s/img/mask-bg-white.png');
|
||||
background: url('img/mask-bg-white.png');
|
||||
background: rgba(240, 240, 240, 0.6);
|
||||
z-index: 31;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
@@ -3149,7 +3159,7 @@ border-top: 1px solid var(--theme, #94ff3d);
|
||||
clear: both;
|
||||
display: block;
|
||||
padding: 11px 20px 9px 15px;
|
||||
background: url('/s/img/icon-arrow-right.png') no-repeat 97.5% center;
|
||||
background: url('img/icon-arrow-right.png') no-repeat 97.5% center;
|
||||
color: #323232;
|
||||
-webkit-background-size: 9px 15px;
|
||||
-moz-background-size: 9px 15px;
|
||||
@@ -3247,7 +3257,7 @@ border-top: 1px solid var(--theme, #94ff3d);
|
||||
.sidebar-setting a {
|
||||
clear: both;
|
||||
padding: 11px 20px 9px 15px;
|
||||
background: url('/s/img/icon-arrow-right.png') no-repeat 97.5% center;
|
||||
background: url('img/icon-arrow-right.png') no-repeat 97.5% center;
|
||||
color: #323232;
|
||||
-webkit-background-size: 9px 15px;
|
||||
-moz-background-size: 9px 15px;
|
||||
@@ -3478,7 +3488,7 @@ border-top: 1px solid var(--theme, #94ff3d);
|
||||
}
|
||||
#sidebar-profile-status li a.selected {
|
||||
font-weight: bold;
|
||||
background-image: url('/s/img/bg-select.png');
|
||||
background-image: url('img/bg-select.png');
|
||||
background-size: 6px auto;
|
||||
}
|
||||
#sidebar-profile-status .number {
|
||||
@@ -3667,13 +3677,13 @@ border-top: 1px solid var(--theme, #94ff3d);
|
||||
background-size: 26px auto;
|
||||
}
|
||||
.user-data .game-skill span.beginner:before {
|
||||
background-image: url('/s/img/skill-beginner.png');
|
||||
background-image: url('img/skill-beginner.png');
|
||||
}
|
||||
.user-data .game-skill span.intermediate:before {
|
||||
background-image: url('/s/img/skill-intermediate.png');
|
||||
background-image: url('img/skill-intermediate.png');
|
||||
}
|
||||
.user-data .game-skill span.expert:before {
|
||||
background-image: url('/s/img/skill-expert.png');
|
||||
background-image: url('img/skill-expert.png');
|
||||
}
|
||||
.user-data .game .note > div {
|
||||
display: inline-block;
|
||||
@@ -4408,7 +4418,7 @@ div#activity-feed-tutorial.no-content p.tleft {
|
||||
clear: both;
|
||||
display: block;
|
||||
padding: 11px 20px 9px 15px;
|
||||
background: url('/s/img/icon-arrow-right.png') no-repeat 97.5% center;
|
||||
background: url('img/icon-arrow-right.png') no-repeat 97.5% center;
|
||||
color: #323232;
|
||||
-webkit-background-size: 9px 15px;
|
||||
-moz-background-size: 9px 15px;
|
||||
@@ -4588,7 +4598,7 @@ div#activity-feed-tutorial.no-content p.tleft {
|
||||
text-align: left;
|
||||
}
|
||||
#identified-user-banner a:before {
|
||||
background: url(/s/img/identified-user-banner.png);
|
||||
background: url(img/identified-user-banner.png);
|
||||
background-size: 100px 50px;
|
||||
content: '';
|
||||
height: 50px;
|
||||
@@ -4903,7 +4913,7 @@ div#activity-feed-tutorial.no-content p.tleft {
|
||||
font-weight: bold;
|
||||
color: #323232;
|
||||
}
|
||||
.news-list .nick-namea:hover {
|
||||
.news-list .nick-name a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.news-list a.link {
|
||||
@@ -5914,7 +5924,7 @@ h2.label-topic_post .label-topic_post-msgid {
|
||||
display: inline-block;
|
||||
width: 22px;
|
||||
height: 10px;
|
||||
background: url('/s/img/tutorial-window-balloon.png');
|
||||
background: url('img/tutorial-window-balloon.png');
|
||||
background-size: 22px 10px;
|
||||
position: absolute;
|
||||
top: -10px;
|
||||
@@ -6132,7 +6142,7 @@ h2.label-topic_post .label-topic_post-msgid {
|
||||
height: 7px;
|
||||
top: -6px;
|
||||
left: 22px;
|
||||
background: url('/s/img/balloon-part-empathy.png') no-repeat 0 0;
|
||||
background: url('img/balloon-part-empathy.png') no-repeat 0 0;
|
||||
-webkit-background-size: 10px 7px;
|
||||
-moz-background-size: 10px 7px;
|
||||
-ms-background-size: 10px 7px;
|
||||
@@ -6300,7 +6310,7 @@ h2.label-topic_post .label-topic_post-msgid {
|
||||
text-align: center;
|
||||
}
|
||||
.post-permalink-button {
|
||||
background: #ffffff url('/s/img/icon-arrow-left.png') no-repeat 15px center;
|
||||
background: #ffffff url('img/icon-arrow-left.png') no-repeat 15px center;
|
||||
color: #323232;
|
||||
display: table;
|
||||
width: 100%;
|
||||
@@ -6547,7 +6557,7 @@ h2.label-topic_post .label-topic_post-msgid {
|
||||
#diary-container #diary-user-content {
|
||||
padding: 5px 10px 10px;
|
||||
text-align: center;
|
||||
background-image: url('/s/img/bg-gray-dot.png');
|
||||
background-image: url('img/bg-gray-dot.png');
|
||||
background-size: 14px auto;
|
||||
border-bottom: 1px solid #dddddd;
|
||||
border-top: 4px solid #04c9db;
|
||||
@@ -6609,7 +6619,7 @@ h2.label-topic_post .label-topic_post-msgid {
|
||||
background-position: center bottom;
|
||||
background-repeat: repeat-x;
|
||||
background-size: 14px auto;
|
||||
background-image: url('/s/img/bg-gray.png');
|
||||
background-image: url('img/bg-gray.png');
|
||||
min-height: 140px;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
@@ -7573,49 +7583,63 @@ margin: 10px 0px 15px !important;
|
||||
#empathy-content .icon-container.donator:after,
|
||||
#reply-content .icon-container.donator:after,
|
||||
.news-list .icon-container.donator:after {
|
||||
content: url(/s/img/donator.png);
|
||||
content: url(img/donator.png);
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
}
|
||||
#empathy-content .icon-container.verified:after,
|
||||
#reply-content .icon-container.verified:after,
|
||||
.news-list .icon-container.verified:after {
|
||||
content: url(/s/img/verified.png);
|
||||
#empathy-content .icon-container.verifiedd:after,
|
||||
#reply-content .icon-container.verifiedd:after,
|
||||
.news-list .icon-container.verifiedd:after {
|
||||
content: url(img/.png);
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
}
|
||||
#empathy-content .icon-container.tester:after,
|
||||
#reply-content .icon-container.tester:after,
|
||||
.news-list .icon-container.tester:after {
|
||||
content: url(/s/img/tester.png);
|
||||
#empathy-content .icon-container.cool:after,
|
||||
#reply-content .icon-container.cool:after,
|
||||
.news-list .icon-container.cool:after {
|
||||
content: url(img/cool.png);
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
}
|
||||
#empathy-content .icon-container.jack:after,
|
||||
#reply-content .icon-container.jack:after,
|
||||
.news-list .icon-container.jack:after {
|
||||
content: url(img/jack.png);
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
}
|
||||
#empathy-content .icon-container.moderator:after,
|
||||
#reply-content .icon-container.moderator:after,
|
||||
.news-list .icon-container.moderator:after {
|
||||
content: url(/s/img/moderator.png);
|
||||
content: url(img/moderator.png);
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
}
|
||||
#empathy-content .icon-container.administrator:after,
|
||||
#reply-content .icon-container.administrator:after,
|
||||
.news-list .icon-container.administrator:after {
|
||||
content: url("/s/img/administrator.png");
|
||||
content: url("img/administrator.png");
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
}
|
||||
#empathy-content .icon-container.developer:after,
|
||||
#reply-content .icon-container.developer:after,
|
||||
.news-list .icon-container.developer:after {
|
||||
content: url("/s/img/developer.png");
|
||||
content: url("img/developer.png");
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
}
|
||||
#empathy-content .icon-container.badgedes:after,
|
||||
#reply-content .icon-container.badgedes:after,
|
||||
.news-list .icon-container.badgedes:after {
|
||||
content: url("img/badgedes.png");
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
}
|
||||
#empathy-content .icon-container.openverse:after,
|
||||
#reply-content .icon-container.openverse:after,
|
||||
.news-list .icon-container.openverse:after {
|
||||
content: url("/s/img/open-dev.png");
|
||||
content: url("img/open-dev.png");
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
}
|
||||
@@ -8427,7 +8451,7 @@ margin: 10px 0px 15px !important;
|
||||
font-size: 14px;
|
||||
}
|
||||
.post-permalink-button {
|
||||
background: #ffffff url('/s/img/icon-arrow-left.png') no-repeat 10px center;
|
||||
background: #ffffff url('img/icon-arrow-left.png') no-repeat 10px center;
|
||||
min-height: 56px;
|
||||
}
|
||||
.post-permalink-button > span {
|
||||
@@ -8699,7 +8723,7 @@ margin: 10px 0px 15px !important;
|
||||
.textarea-with-menu .textarea-menu-memo:before,
|
||||
.textarea-with-menu .textarea-menu-poll:before {
|
||||
content: "";
|
||||
background: url(/s/img/form-icons.png);
|
||||
background: url(img/form-icons.png);
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
left: 50%;
|
||||
@@ -8708,7 +8732,7 @@ margin: 10px 0px 15px !important;
|
||||
.textarea-with-menu.active-text .textarea-menu-text,
|
||||
.textarea-with-menu.active-memo .textarea-menu-memo,
|
||||
.textarea-with-menu.active-poll .textarea-menu-poll {
|
||||
background: -webkit-gradient(linear, left top, left bottom, from(var(--theme, #257811)), to(var(--theme-slightly-dark, #1e610e))) 0 0;
|
||||
background: -webkit-gradient(linear, left top, left bottom, from(var(--theme, #2e81e5)), to(var(--theme-slightly-dark, #005ac8))) 0 0;
|
||||
}
|
||||
.textarea-with-menu .textarea-menu-text.disabled,
|
||||
.textarea-with-menu .textarea-menu-memo.disabled,
|
||||
@@ -8836,6 +8860,9 @@ font-size: 20px;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.login-page a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.login-page .g-recaptcha {
|
||||
margin: 10px auto 15px;
|
||||
display: block;
|
||||
@@ -8942,7 +8969,7 @@ display: block !important;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
z-index: 2000;
|
||||
background: transparent url("/s/img/load.png") 0 0 no-repeat;
|
||||
background: transparent url("img/load.png") 0 0 no-repeat;
|
||||
animation: woomy 0.36s steps(17) infinite;
|
||||
}
|
||||
@keyframes woomy {
|
||||
@@ -9451,7 +9478,7 @@ See http://bgrins.github.io/spectrum/themes/ for instructions.
|
||||
.open-spin {
|
||||
width: 40px;
|
||||
margin: -2px 0 -2px 0;
|
||||
content: url(/s/img/favicon.png);
|
||||
content: url(img/favicon.png);
|
||||
animation: spin 1.6s linear infinite;
|
||||
}
|
||||
@keyframes spin { 100% { -webkit-transform: rotate(360deg); transform:rotate(360deg); } }
|
||||
@@ -9500,6 +9527,7 @@ See http://bgrins.github.io/spectrum/themes/ for instructions.
|
||||
background-color: #fffce4;
|
||||
}
|
||||
.close-announce-link:before {
|
||||
font-family: "MiiverseSymbols";
|
||||
font-size: 14px;
|
||||
content: 'A';
|
||||
color: #FF9100;
|
||||
|
||||
@@ -835,14 +835,15 @@ var Olv = Olv || {};
|
||||
},
|
||||
submit: function(b, c) {
|
||||
b.trigger("olv:form:submit", [c || a()]);
|
||||
if(a('input[type=file]').length) {
|
||||
var d = new FormData(b[0]);
|
||||
/*if(a('input[type=file]').length) {
|
||||
var d = new FormData(b[0])
|
||||
d.append('screen', $('input[type=file]')[0].files[0])
|
||||
sucky = true
|
||||
} else {
|
||||
var d = b.serializeArray()
|
||||
sucky = false
|
||||
}
|
||||
}*/
|
||||
var e = c && c.is("input, button") && c.prop("name");
|
||||
e && d.push({
|
||||
name: e,
|
||||
@@ -853,10 +854,10 @@ var Olv = Olv || {};
|
||||
url: b.attr("action"),
|
||||
data: d
|
||||
};
|
||||
if(sucky) {
|
||||
//if(sucky) {
|
||||
f.processData = false;
|
||||
f.contentType = false;
|
||||
}
|
||||
//}
|
||||
return this.send(f, c)
|
||||
},
|
||||
get: function(a, b, c) {
|
||||
@@ -947,7 +948,7 @@ var Olv = Olv || {};
|
||||
b.router.connect("", b.Form.setupForPage),
|
||||
b.Guest = {
|
||||
isGuest: function() {
|
||||
return a("main-body").hasClass("guest")
|
||||
return a("#main-body").hasClass("guest")
|
||||
}
|
||||
},
|
||||
b.DecreasingTimer = function(a, b, c) {
|
||||
@@ -1855,7 +1856,8 @@ var Olv = Olv || {};
|
||||
}),
|
||||
e()
|
||||
}*/
|
||||
function h() {
|
||||
// original function source is lost media
|
||||
/*function h() {
|
||||
/*var e = a(d.target).siblings().filter("input")
|
||||
, f = d.target.files[0];
|
||||
if (!f)
|
||||
@@ -1869,7 +1871,7 @@ var Olv = Olv || {};
|
||||
}
|
||||
,*/
|
||||
/*b.Form.toggleDisabled(j, !0),
|
||||
g.readAsDataURL(f)*/
|
||||
g.readAsDataURL(f)
|
||||
var e = $("#upload-file"),
|
||||
h = $("#upload-input"),
|
||||
f = $("#upload-preview"),
|
||||
@@ -1879,7 +1881,7 @@ var Olv = Olv || {};
|
||||
var n = function(a) {
|
||||
/*window.anus = a
|
||||
console.log(a)
|
||||
*/switch (!0) {
|
||||
switch (!0) {
|
||||
case void 0 !== a.target.files:
|
||||
var c = a.target.files;
|
||||
break;
|
||||
@@ -1901,6 +1903,7 @@ var Olv = Olv || {};
|
||||
h.val("");
|
||||
f.attr("src", "");
|
||||
m.text("...");
|
||||
window.ass = e
|
||||
var e = new FileReader,
|
||||
n = function() {
|
||||
f.attr("src", e.result);
|
||||
@@ -1913,6 +1916,7 @@ var Olv = Olv || {};
|
||||
};
|
||||
a.addEventListener("load", c);
|
||||
l.show();
|
||||
console.log('...now!')
|
||||
h.val(e.result.split(";base64,")[1]);
|
||||
e.removeEventListener("load", n)
|
||||
};
|
||||
@@ -1933,6 +1937,100 @@ var Olv = Olv || {};
|
||||
h.val("")
|
||||
Olv.fuUUckFiles = null;
|
||||
})
|
||||
}*/
|
||||
function h() {
|
||||
var uploadFile = $("#upload-file"),
|
||||
uploadInput = $("#upload-input"),
|
||||
uploadPreview = $("#upload-preview"),
|
||||
uploadPreviewContainer = $("#upload-preview-container"),
|
||||
imageDimensions = $("#image-dimensions");
|
||||
|
||||
b.EntryForm.tempPollutionButImageFormAllowedText = imageDimensions.text();
|
||||
|
||||
var handleFileChange = function(event) {
|
||||
//var fileList;
|
||||
console.log('handleFileChange: files is being assigned...');
|
||||
switch(true) {
|
||||
case event.target.files !== undefined:
|
||||
uploadFile[0].files = event.target.files;
|
||||
break;
|
||||
case event.originalEvent.dataTransfer !== undefined:
|
||||
uploadFile[0].files = event.originalEvent.dataTransfer.files;
|
||||
break;
|
||||
case event.originalEvent.clipboardData !== undefined:
|
||||
uploadFile[0].files = event.originalEvent.clipboardData.files;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(null === uploadFile[0].files || uploadFile[0].files.length < 1 || void 0 === uploadFile[0].files[0] || uploadFile[0].files[0].type.indexOf("image") < 0)) {
|
||||
event.preventDefault();
|
||||
Olv.Form.toggleDisabled($("input.black-button"), false);
|
||||
uploadPreview.hide();
|
||||
uploadPreviewContainer.hide();
|
||||
uploadInput.val("");
|
||||
uploadPreview.attr("src", "");
|
||||
imageDimensions.text("...");
|
||||
|
||||
/*window.ass = uploadFile[0].files;window.uploadFile = uploadFile
|
||||
console.log('here is your fileList, and uploadFile')
|
||||
*/
|
||||
var blobURL = URL.createObjectURL(uploadFile[0].files[0]);
|
||||
console.log(uploadFile[0].files[0])
|
||||
uploadPreview.attr("src", blobURL);
|
||||
uploadPreview.show();
|
||||
|
||||
var handleImageLoad = function() {
|
||||
imageDimensions.text(uploadPreview[0].width + " x " + uploadPreview[0].height);
|
||||
uploadPreview[0].removeEventListener("load", handleImageLoad);
|
||||
};
|
||||
|
||||
uploadPreview[0].addEventListener("load", handleImageLoad);
|
||||
uploadPreviewContainer.show();
|
||||
|
||||
|
||||
/*var fileReader = new FileReader();
|
||||
var handleReaderLoad = function() {
|
||||
uploadPreview.attr("src", fileReader.result);
|
||||
uploadPreview.show();
|
||||
|
||||
var image = new Image();
|
||||
image.src = fileReader.result;
|
||||
|
||||
var handleImageLoad = function() {
|
||||
imageDimensions.text(image.width + " x " + image.height);
|
||||
image.removeEventListener("load", handleImageLoad);
|
||||
};
|
||||
|
||||
image.addEventListener("load", handleImageLoad);
|
||||
uploadPreviewContainer.show();
|
||||
console.log('...now!')
|
||||
uploadInput.val(fileReader.result.split(";base64,")[1]);
|
||||
fileReader.removeEventListener("load", handleReaderLoad);
|
||||
};
|
||||
|
||||
fileReader.addEventListener("load", handleReaderLoad);
|
||||
fileReader.readAsDataURL(fileList[0]);
|
||||
*/
|
||||
}
|
||||
};
|
||||
|
||||
uploadFile.change(handleFileChange);
|
||||
c.on("dragover dragenter", function(event) {
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
c.on("drop paste", handleFileChange);
|
||||
|
||||
c.on("olv:entryform:post:done", function() {
|
||||
imageDimensions.text(b.EntryForm.tempPollutionButImageFormAllowedText);
|
||||
uploadPreview.hide();
|
||||
uploadPreviewContainer.hide();
|
||||
uploadPreview.attr("src", "");
|
||||
uploadInput.val("");
|
||||
});
|
||||
|
||||
}
|
||||
function i(a) {
|
||||
k.siblings().filter("input[type=hidden]").val(""),
|
||||
@@ -2263,7 +2361,9 @@ var Olv = Olv || {};
|
||||
b.Global.setupMyMenu()
|
||||
}),
|
||||
b.init.done(function(a) {
|
||||
if (a("#global-menu-news").length) {
|
||||
// don't check notifications if there's no news icon
|
||||
// why didn't this always use isGuest but now it does
|
||||
if (a("#global-menu-news").length && !Olv.Guest.isGuest()) {
|
||||
a("#global-menu-news > a").on("click", function(b) {
|
||||
a(b.currentTarget).find(".badge").hide()
|
||||
});
|
||||
@@ -2840,6 +2940,15 @@ $('.post-poll .poll-votes').on('click', function() {
|
||||
})
|
||||
})
|
||||
}
|
||||
lock_comments_button = $('.lock-comments-button')
|
||||
if(lock_comments_button.length) {
|
||||
lock_comments_button.on('click',function(){
|
||||
b.showConfirm("Lock comments", "Really lock up the comments? This cannot be undone.")
|
||||
$('.ok-button').on('click',function(){
|
||||
b.Form.post(lock_comments_button.attr('data-action')).done
|
||||
})
|
||||
})
|
||||
}
|
||||
fav_btn = $('.profile-post-button')
|
||||
if(fav_btn.length) {
|
||||
if(fav_btn.hasClass('done')) {
|
||||
@@ -3355,9 +3464,6 @@ mode_post = 0;
|
||||
$('input[name=color]').val(color);
|
||||
}
|
||||
});
|
||||
$('div.form-buttons > input').click(function(a) {
|
||||
$('.color-thing').spectrum('destroy');
|
||||
});
|
||||
});
|
||||
$('.color-thing2').click(function(a) {
|
||||
a.preventDefault();
|
||||
@@ -3365,15 +3471,17 @@ mode_post = 0;
|
||||
color: $('input[name=theme]'),
|
||||
preferredFormat: "hex",
|
||||
showInput: true,
|
||||
//clickoutFiresChange: false,
|
||||
flat: true,
|
||||
change: function(color) {
|
||||
$('.current-theme').attr('style', 'color:' + color);
|
||||
$('input[name=theme]').val(color);
|
||||
if(!$('.color-thing2').is(':visible')) {
|
||||
$('.current-theme').attr('style', 'color:' + color);
|
||||
$('input[name=theme]').val(color);
|
||||
window.mainColor = color.toString().substring(1);
|
||||
changeThemeColor();
|
||||
}
|
||||
}
|
||||
});
|
||||
$('div.form-buttons > input').click(function(a) {
|
||||
$('.color-thing2').spectrum('destroy');
|
||||
});
|
||||
});
|
||||
// }
|
||||
}
|
||||
@@ -3383,9 +3491,18 @@ mode_post = 0;
|
||||
, e = d.closest("form");
|
||||
b.Form.isDisabled(d) || c.isDefaultPrevented() || (c.preventDefault(),
|
||||
b.Form.submit(e, d).done(function() {
|
||||
b.Net.reload()
|
||||
$('.color-thing').spectrum();
|
||||
$('.color-thing2').spectrum();
|
||||
b.Net.reload();
|
||||
var updateAvatar = function() {
|
||||
a('#global-menu-mymenu .icon-container img').attr('src', a('#sidebar-profile-body .icon').attr('src'));
|
||||
var them = a('[name=theme]').val();
|
||||
if(them === 'None') {
|
||||
toDefault();
|
||||
} else {
|
||||
window.mainColor = them.substring(1);
|
||||
changeThemeColor();
|
||||
}
|
||||
a(document).off("pjax:complete", updateAvatar);
|
||||
}
|
||||
a(document).on("pjax:complete", updateAvatar);
|
||||
|
||||
@@ -1,141 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
width="130"
|
||||
height="130"
|
||||
viewBox="0 0 130 130"
|
||||
sodipodi:docname="backgroundclear.svg"
|
||||
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
|
||||
xml:space="preserve"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||
id="defs1"><inkscape:path-effect
|
||||
effect="fillet_chamfer"
|
||||
id="path-effect5"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
nodesatellites_param="C,0,0,1,0,8,0,1 @ C,0,0,1,0,8,0,1 @ C,0,0,1,0,8,0,1 @ C,0,0,1,0,8,0,1"
|
||||
radius="8"
|
||||
unit="px"
|
||||
method="auto"
|
||||
mode="F"
|
||||
chamfer_steps="1"
|
||||
flexible="false"
|
||||
use_knot_distance="true"
|
||||
apply_no_radius="true"
|
||||
apply_with_radius="true"
|
||||
only_selected="false"
|
||||
hide_knots="false" /><inkscape:path-effect
|
||||
effect="fillet_chamfer"
|
||||
id="path-effect4"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
nodesatellites_param="C,0,0,1,0,8,0,1 @ C,0,0,1,0,8,0,1 @ C,0,0,1,0,8,0,1 @ C,0,0,1,0,8,0,1"
|
||||
radius="8"
|
||||
unit="px"
|
||||
method="auto"
|
||||
mode="F"
|
||||
chamfer_steps="1"
|
||||
flexible="false"
|
||||
use_knot_distance="true"
|
||||
apply_no_radius="true"
|
||||
apply_with_radius="true"
|
||||
only_selected="false"
|
||||
hide_knots="false" /><inkscape:path-effect
|
||||
effect="fillet_chamfer"
|
||||
id="path-effect3"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
nodesatellites_param="F,0,0,1,0,11,0,1 @ F,0,0,1,0,11,0,1 @ F,0,0,1,0,11,0,1 @ F,0,0,1,0,11,0,1"
|
||||
radius="11"
|
||||
unit="px"
|
||||
method="auto"
|
||||
mode="F"
|
||||
chamfer_steps="1"
|
||||
flexible="false"
|
||||
use_knot_distance="true"
|
||||
apply_no_radius="true"
|
||||
apply_with_radius="true"
|
||||
only_selected="false"
|
||||
hide_knots="false" /></defs><sodipodi:namedview
|
||||
id="namedview1"
|
||||
pagecolor="#505050"
|
||||
bordercolor="#ffffff"
|
||||
borderopacity="1"
|
||||
inkscape:showpageshadow="0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="1"
|
||||
inkscape:deskcolor="#505050"
|
||||
inkscape:zoom="5.08125"
|
||||
inkscape:cx="63.468635"
|
||||
inkscape:cy="55.694957"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1011"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="g1"
|
||||
showgrid="false"
|
||||
showguides="false" /><g
|
||||
inkscape:groupmode="layer"
|
||||
inkscape:label="Image"
|
||||
id="g1"><rect
|
||||
style="opacity:1;fill:#000000;fill-opacity:0.40000001;stroke-width:0.8125"
|
||||
id="rect2"
|
||||
width="130"
|
||||
height="130"
|
||||
x="0"
|
||||
y="0" /><path
|
||||
style="fill:#000000;fill-opacity:0.11323686"
|
||||
id="rect1"
|
||||
width="65"
|
||||
height="65"
|
||||
x="0"
|
||||
y="0"
|
||||
sodipodi:type="rect"
|
||||
inkscape:path-effect="#path-effect4"
|
||||
d="m 8,0 h 49 l 8,8 v 49 l -8,8 H 8 L 0,57 V 8 Z" /><path
|
||||
style="fill:#000000;fill-opacity:0.11323686"
|
||||
id="rect1-3"
|
||||
width="65"
|
||||
height="65"
|
||||
x="65"
|
||||
y="65"
|
||||
inkscape:path-effect="#path-effect5"
|
||||
sodipodi:type="rect"
|
||||
d="m 73,65 h 49 l 8,8 v 49 l -8,8 H 73 l -8,-8 V 73 Z" /><image
|
||||
width="128"
|
||||
height="128"
|
||||
preserveAspectRatio="none"
|
||||
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAEpElEQVR4nO2dW3LiQBAEE8kmOPae
|
||||
2w7j/ZjFa0CAHi1N16jqABMZlf2pKB1Op9MfgnI8Hun7Puq5q5zPZz4+Pvj+/g55z6yFs4t6zIWW
|
||||
qLBeOEMOwIWWqLD+5lx8AC60RIX1lnPRAbjQEhXWIc7ZB+BCS1RYH3HOOgAXWqLC+oxz8gG40BIV
|
||||
1leckw7AhZaosI7hHH0ALrREhXUs56gDcKElKqxTOF8egAstUWGdyvn0AFxoiQrrHM6HB+BCS1RY
|
||||
53IOHoALLVFhXcJ5dwAutESFdSnn1QG40BIV1gjOnwNwoSUqrFGcHbjQS1RYIzk7F1qiwhrN2e29
|
||||
UNBhXYPzLeSlm3x9ffH5+Zm+UNi3/L7v4z4KvcTydeTDwk/CbmP5WvIh8AAsX08+BB2A5WvKh4AD
|
||||
OJ/Plh+cLTkXHYBKoaDDujXn7ANQKRR0WGtwzjoAlUJBh7UW5+QDUCkUdFhrck46AJVCQYe1Nufo
|
||||
A6gNOiUqrBk4Rx1ABtCxUWHNwvnyALKAjokKaybOpweQCfRVVFizcT48gGygz6LCmpFz8AAygj6K
|
||||
CmtWzrsDyAo6FBXWzJxXB5AZ9DYqrNk5fw4gO+jvqLAqcHagAXqJCqsKZ6cCCjqlqnACdCqgKqWq
|
||||
cEL5kqtTAFUpVYUTinxPxQZGhRP+y4eAbwItX4cTruWDp2IXR4UT7uWDp2IXRYUThuWDp2JnR4UT
|
||||
HssHT8XOigonPJcPnoqdHBVOeC0fPBU7KSqcME4+eCp2dFQ4Ybx88FTsqKhwwjT54KnYl1HhhOny
|
||||
wVOxT6PCCfPkg6diH0aFE+bLB0/FDkaFE5bJB0/F3kWFE5bLB0/FXkWFE2Lkg6dif6LCCXHywVOx
|
||||
gA4nxMo/HA6eilXhhHj5x+MxfikUdEpV4YSV5Hdd/AGolKrCCevJh+CpWJVSVThhXfkQeAAqpapw
|
||||
wvryIegAVEpV4YRt5EPQVKxCqSqcsJ182MlUrAonbCsfdjAVq8IJ28uHxqdiVTihjnxoeCpWhRPq
|
||||
yYdGp2JVOKGufGhwKlaFE+rLh8amYlU4IYd8aGgqVoUT8siHRqZiVTghl3xoYCpWhRPyyQfxqVgV
|
||||
TsgpH4SnYlU4Ia98EJ2KVeGE3PJBcCpWhRPyywexqVgVTtCQD/Cm8t9fy1/l+106y4+NknyJqVjL
|
||||
X09++qlYy19XPiSeirX89eVD0qlYy99GPiScirX87eRDsqlYy99WPiSairX87eVDkqlYy68jHxJM
|
||||
xVp+PflQeSrW8uvKh4pTsZZfXz5Umoq1/BzyocJUrOXnkQ8bT8Vafi75sOFUrOXnkw8bTcVafk75
|
||||
sMFUrOXnlQ8rT8Vafm75sOJUrOXnl7/aVKzla8h/f3/f71IoWH7f97yFvPgvlq8hf5WpWMvXkw87
|
||||
WwoFyw+firV8Xfmwk6VQsPzwqVjL15cPjS+FguWHT8VafjvyodGlULD88KlYy29PPjS2FAr1C52S
|
||||
DKzNLIVCjkLHJgtrE0uhkKfQMcnEKr8UCrkKfZVsrNJLoZCv0GfJyCq7FAo5C32UrKySS6GQt9Ch
|
||||
ZGaVWwqF3IXeJjur1FIo5C/0dxRYO8vfr3yAv3rECG2I4F0DAAAAAElFTkSuQmCC
|
||||
"
|
||||
id="image3405"
|
||||
x="-149.11778"
|
||||
y="16" /></g></svg>
|
||||
|
Before Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 429 B |
@@ -1,129 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
width="160"
|
||||
height="160"
|
||||
viewBox="0 0 160 160"
|
||||
sodipodi:docname="background.svg"
|
||||
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs1">
|
||||
<inkscape:path-effect
|
||||
effect="fillet_chamfer"
|
||||
id="path-effect5"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
nodesatellites_param="C,0,0,1,0,8,0,1 @ C,0,0,1,0,8,0,1 @ C,0,0,1,0,8,0,1 @ C,0,0,1,0,8,0,1"
|
||||
radius="8"
|
||||
unit="px"
|
||||
method="auto"
|
||||
mode="F"
|
||||
chamfer_steps="1"
|
||||
flexible="false"
|
||||
use_knot_distance="true"
|
||||
apply_no_radius="true"
|
||||
apply_with_radius="true"
|
||||
only_selected="false"
|
||||
hide_knots="false" />
|
||||
<inkscape:path-effect
|
||||
effect="fillet_chamfer"
|
||||
id="path-effect4"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
nodesatellites_param="C,0,0,1,0,8,0,1 @ C,0,0,1,0,8,0,1 @ C,0,0,1,0,8,0,1 @ C,0,0,1,0,8,0,1"
|
||||
radius="8"
|
||||
unit="px"
|
||||
method="auto"
|
||||
mode="F"
|
||||
chamfer_steps="1"
|
||||
flexible="false"
|
||||
use_knot_distance="true"
|
||||
apply_no_radius="true"
|
||||
apply_with_radius="true"
|
||||
only_selected="false"
|
||||
hide_knots="false" />
|
||||
<inkscape:path-effect
|
||||
effect="fillet_chamfer"
|
||||
id="path-effect3"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
nodesatellites_param="F,0,0,1,0,11,0,1 @ F,0,0,1,0,11,0,1 @ F,0,0,1,0,11,0,1 @ F,0,0,1,0,11,0,1"
|
||||
radius="11"
|
||||
unit="px"
|
||||
method="auto"
|
||||
mode="F"
|
||||
chamfer_steps="1"
|
||||
flexible="false"
|
||||
use_knot_distance="true"
|
||||
apply_no_radius="true"
|
||||
apply_with_radius="true"
|
||||
only_selected="false"
|
||||
hide_knots="false" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="namedview1"
|
||||
pagecolor="#505050"
|
||||
bordercolor="#ffffff"
|
||||
borderopacity="1"
|
||||
inkscape:showpageshadow="0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="1"
|
||||
inkscape:deskcolor="#505050"
|
||||
inkscape:zoom="2.540625"
|
||||
inkscape:cx="-35.621156"
|
||||
inkscape:cy="65.535055"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1011"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="g1" />
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
inkscape:label="Image"
|
||||
id="g1">
|
||||
<image
|
||||
width="160"
|
||||
height="160"
|
||||
preserveAspectRatio="none"
|
||||
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHgAAAB4CAIAAAC2BqGFAAAABmJLR0QAFgAWACbcRYNiAAAACXBI WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QkQChoXcqytowAAATpJREFUeNrt3MEJwzAQRFFn8MlV uIT0X5jPqSEgLVr5/QLC7DskYII/9/095vQ8z9Gt67omfXIOlQQaNGiBBg0aAWjQAg0atECDFmjQ oAUatECDBi3QoLUIdMd/z0ydHco140O55oRQrjkklGvOOct05v1Rc57mQJy8WblyWN6sXDkvL1cu GxnKNVNDuWawZx1FgQYNWqBBg0YAGrRAgwYt0KAFGjRogQYt0KBBCzRogQYNWqBBCzRo0AINWqBB gxZo0AINGrRAgxZo0KAFGrSWgG73Grypg9N3eq+p6X5Al5HZ44z152WnY1Yedg58B1nZez7LGoiT NWdtpjz+q2Mb6+GHZP2JGyjP+jFsbT1pfHrNbap8eNZRFmjQoAUaNGgEoEELNGjQAg1aoEGDFmjQ Ag0atECD1p/9AKkzTyh2EOP+AAAAAElFTkSuQmCC "
|
||||
id="image1"
|
||||
x="-167.89395"
|
||||
y="0" />
|
||||
<rect
|
||||
style="fill:#161626;fill-opacity:1"
|
||||
id="rect2"
|
||||
width="160"
|
||||
height="160"
|
||||
x="0"
|
||||
y="0" />
|
||||
<path
|
||||
style="fill:#202030;fill-opacity:1"
|
||||
id="rect1"
|
||||
width="80"
|
||||
height="80"
|
||||
x="0"
|
||||
y="0"
|
||||
sodipodi:type="rect"
|
||||
inkscape:path-effect="#path-effect4"
|
||||
d="m 8,0 h 64 l 8,8 v 64 l -8,8 H 8 L 0,72 V 8 Z" />
|
||||
<path
|
||||
style="fill:#202030;fill-opacity:1"
|
||||
id="rect1-3"
|
||||
width="80"
|
||||
height="80"
|
||||
x="80"
|
||||
y="80"
|
||||
inkscape:path-effect="#path-effect5"
|
||||
sodipodi:type="rect"
|
||||
d="m 88,80 h 64 l 8,8 v 64 l -8,8 H 88 l -8,-8 V 88 Z" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 523 B |
|
Before Width: | Height: | Size: 359 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 669 B |
|
Before Width: | Height: | Size: 339 B |
|
After Width: | Height: | Size: 381 B |
|
Before Width: | Height: | Size: 538 B |
|
Before Width: | Height: | Size: 409 B |
|
Before Width: | Height: | Size: 367 B |
|
Before Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 519 B |
|
Before Width: | Height: | Size: 524 B |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 527 B |
|
Before Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 9.1 KiB |
|
Before Width: | Height: | Size: 389 B |
|
Before Width: | Height: | Size: 319 B |
|
Before Width: | Height: | Size: 116 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 387 B |
|
Before Width: | Height: | Size: 631 B |