avancé de dev
@@ -1,4 +1,4 @@
|
||||
"""
|
||||
"""
|
||||
Django settings for Reskreen project.
|
||||
|
||||
Generated by 'django-admin startproject' using Django 4.0.
|
||||
@@ -39,6 +39,9 @@ INSTALLED_APPS = [
|
||||
'django.contrib.staticfiles',
|
||||
'polls.apps.PollsConfig',
|
||||
'vehicles.apps.VehiclesConfig',
|
||||
'collabs.apps.CollabsConfig',
|
||||
|
||||
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
@@ -56,7 +59,7 @@ ROOT_URLCONF = 'Reskreen.urls'
|
||||
TEMPLATES = [
|
||||
{
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'DIRS': [],
|
||||
'DIRS': [BASE_DIR / 'templates'],
|
||||
'APP_DIRS': True,
|
||||
'OPTIONS': {
|
||||
'context_processors': [
|
||||
@@ -75,13 +78,24 @@ WSGI_APPLICATION = 'Reskreen.wsgi.application'
|
||||
# Database
|
||||
# https://docs.djangoproject.com/en/4.0/ref/settings/#databases
|
||||
|
||||
|
||||
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3',
|
||||
'NAME': BASE_DIR / 'db.sqlite3',
|
||||
}
|
||||
}
|
||||
|
||||
"""
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.mysql',
|
||||
'OPTIONS': {
|
||||
'read_default_file': 'my.cnf',
|
||||
},
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
# Password validation
|
||||
# https://docs.djangoproject.com/en/4.0/ref/settings/#auth-password-validators
|
||||
@@ -123,3 +137,135 @@ STATIC_URL = 'static/'
|
||||
# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field
|
||||
|
||||
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
||||
|
||||
JAZZMIN_SETTINGS = {
|
||||
# title of the window (Will default to current_admin_site.site_title if absent or None)
|
||||
"site_title": "Reskreen-Admin",
|
||||
|
||||
# Title on the login screen (19 chars max) (defaults to current_admin_site.site_header if absent or None)
|
||||
"site_header": "Reskreen",
|
||||
|
||||
# Title on the brand (19 chars max) (defaults to current_admin_site.site_header if absent or None)
|
||||
"site_brand": "Reskreen",
|
||||
|
||||
# Logo to use for your site, must be present in static files, used for brand on top left
|
||||
"site_logo": "books/img/logo.png",
|
||||
|
||||
# CSS classes that are applied to the logo above
|
||||
"site_logo_classes": "img-circle",
|
||||
|
||||
# Relative path to a favicon for your site, will default to site_logo if absent (ideally 32x32 px)
|
||||
"site_icon": None,
|
||||
|
||||
# Welcome text on the login screen
|
||||
"welcome_sign": "Welcome to the Reskreen admin",
|
||||
|
||||
# Copyright on the footer
|
||||
"copyright": "Resk-U",
|
||||
|
||||
# The model admin to search from the search bar, search bar omitted if excluded
|
||||
"search_model": "auth.User",
|
||||
|
||||
# Field name on user model that contains avatar ImageField/URLField/Charfield or a callable that receives the user
|
||||
"user_avatar": None,
|
||||
|
||||
############
|
||||
# Top Menu #
|
||||
############
|
||||
|
||||
# Links to put along the top menu
|
||||
"topmenu_links": [
|
||||
|
||||
# Url that gets reversed (Permissions can be added)
|
||||
{"name": "Home", "url": "admin:index", "permissions": ["auth.view_user"]},
|
||||
|
||||
# external url that opens in a new window (Permissions can be added)
|
||||
{"name": "Support", "url": "https://github.com/farridav/django-jazzmin/issues", "new_window": True},
|
||||
|
||||
# model admin to link to (Permissions checked against model)
|
||||
{"model": "auth.User"},
|
||||
|
||||
# App with dropdown menu to all its models pages (Permissions checked against models)
|
||||
{"app": "polls"},
|
||||
],
|
||||
|
||||
#############
|
||||
# User Menu #
|
||||
#############
|
||||
|
||||
# Additional links to include in the user menu on the top right ("app" url type is not allowed)
|
||||
"usermenu_links": [
|
||||
{"name": "Support", "url": "https://github.com/farridav/django-jazzmin/issues", "new_window": True},
|
||||
{"model": "auth.user"}
|
||||
],
|
||||
|
||||
#############
|
||||
# Side Menu #
|
||||
#############
|
||||
|
||||
# Whether to display the side menu
|
||||
"show_sidebar": True,
|
||||
|
||||
# Whether to aut expand the menu
|
||||
"navigation_expanded": True,
|
||||
|
||||
# Hide these apps when generating side menu e.g (auth)
|
||||
"hide_apps": [],
|
||||
|
||||
# Hide these models when generating side menu (e.g auth.user)
|
||||
"hide_models": [],
|
||||
|
||||
# List of apps (and/or models) to base side menu ordering off of (does not need to contain all apps/models)
|
||||
"order_with_respect_to": ["auth", "books", "books.author", "books.book"],
|
||||
|
||||
# Custom links to append to app groups, keyed on app name
|
||||
"custom_links": {
|
||||
"books": [{
|
||||
"name": "Make Messages",
|
||||
"url": "make_messages",
|
||||
"icon": "fas fa-comments",
|
||||
"permissions": ["books.view_book"]
|
||||
}]
|
||||
},
|
||||
|
||||
# Custom icons for side menu apps/models See https://fontawesome.com/icons?d=gallery&m=free&v=5.0.0,5.0.1,5.0.10,5.0.11,5.0.12,5.0.13,5.0.2,5.0.3,5.0.4,5.0.5,5.0.6,5.0.7,5.0.8,5.0.9,5.1.0,5.1.1,5.2.0,5.3.0,5.3.1,5.4.0,5.4.1,5.4.2,5.13.0,5.12.0,5.11.2,5.11.1,5.10.0,5.9.0,5.8.2,5.8.1,5.7.2,5.7.1,5.7.0,5.6.3,5.5.0,5.4.2
|
||||
# for the full list of 5.13.0 free icon classes
|
||||
"icons": {
|
||||
"auth": "fas fa-users-cog",
|
||||
"auth.user": "fas fa-user",
|
||||
"auth.Group": "fas fa-users",
|
||||
},
|
||||
# Icons that are used when one is not manually specified
|
||||
"default_icon_parents": "fas fa-chevron-circle-right",
|
||||
"default_icon_children": "fas fa-circle",
|
||||
|
||||
#################
|
||||
# Related Modal #
|
||||
#################
|
||||
# Use modals instead of popups
|
||||
"related_modal_active": False,
|
||||
|
||||
#############
|
||||
# UI Tweaks #
|
||||
#############
|
||||
# Relative paths to custom CSS/JS scripts (must be present in static files)
|
||||
"custom_css": None,
|
||||
"custom_js": None,
|
||||
# Whether to show the UI customizer on the sidebar
|
||||
"show_ui_builder": True,
|
||||
|
||||
###############
|
||||
# Change view #
|
||||
###############
|
||||
# Render out the change view as a single form, or in tabs, current options are
|
||||
# - single
|
||||
# - horizontal_tabs (default)
|
||||
# - vertical_tabs
|
||||
# - collapsible
|
||||
# - carousel
|
||||
"changeform_format": "horizontal_tabs",
|
||||
# override change forms on a per modeladmin basis
|
||||
"changeform_format_overrides": {"auth.user": "collapsible", "auth.group": "vertical_tabs"},
|
||||
# Add a language dropdown into the admin
|
||||
"language_chooser": False,
|
||||
}
|
||||
|
0
collabs/__init__.py
Normal file
43
collabs/admin.py
Normal file
@@ -0,0 +1,43 @@
|
||||
from django.contrib import admin
|
||||
|
||||
from collabs.models import Collabs_hour
|
||||
|
||||
|
||||
from django import forms
|
||||
|
||||
|
||||
class Collabs_hour_Form_admin(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Collabs_hour
|
||||
fields = ["user", "sRemarques", "bNoticed"]
|
||||
readonly_fields = ["user", "nHour", "nMinutes"]
|
||||
|
||||
|
||||
|
||||
class Collabs_hour_Admin(admin.ModelAdmin):
|
||||
list_display = ('user','dtCreated','bNoticed')
|
||||
list_editable = ['bNoticed']
|
||||
list_filter = ['dtCreated']
|
||||
search_fields = ['userName']
|
||||
readonly_fields = ['userName']
|
||||
|
||||
fields = ["user","nHour", "nMinutes", "sRemarques"]
|
||||
|
||||
def get_form(self, request, obj=None, **kwargs):
|
||||
#if request.user.has_perm("collabs.can_notice"):
|
||||
if request.user.is_superuser:
|
||||
kwargs['form'] = Collabs_hour_Form_admin # ModelForm
|
||||
print("PASS SUPERUSER")
|
||||
|
||||
return super().get_form(request, obj, **kwargs)
|
||||
|
||||
|
||||
|
||||
def save_model(self, request, obj, form, change):
|
||||
|
||||
|
||||
super().save_model(request, obj, form, change)
|
||||
|
||||
|
||||
admin.site.register(Collabs_hour, Collabs_hour_Admin)
|
||||
#admin.site.register(Collabs_hour)
|
6
collabs/apps.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class CollabsConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'collabs'
|
28
collabs/migrations/0001_initial.py
Normal file
@@ -0,0 +1,28 @@
|
||||
# Generated by Django 4.0 on 2022-01-31 15:05
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Collabs_hour',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('userName', models.CharField(max_length=100, verbose_name="Nom d'utilisateur")),
|
||||
('collab', models.CharField(max_length=10, verbose_name='Collaborateur')),
|
||||
('nHour', models.IntegerField(default=0, verbose_name='Heure')),
|
||||
('nMinutes', models.IntegerField(default=0, verbose_name='Minutes')),
|
||||
('sRemarques', models.TextField(verbose_name='Remarques')),
|
||||
('bNoticed', models.BooleanField(default=0, verbose_name='Pris en compte')),
|
||||
('dtUpdate', models.DateTimeField(auto_now=True, verbose_name='Date de modification')),
|
||||
('dtCreated', models.DateTimeField(auto_now_add=True)),
|
||||
],
|
||||
),
|
||||
]
|
20
collabs/migrations/0002_collabs_hour_user.py
Normal file
@@ -0,0 +1,20 @@
|
||||
# Generated by Django 4.0 on 2022-01-31 15:13
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('auth', '0012_alter_user_first_name_max_length'),
|
||||
('collabs', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='collabs_hour',
|
||||
name='user',
|
||||
field=models.ForeignKey(default=0, on_delete=django.db.models.deletion.DO_NOTHING, to='auth.user'),
|
||||
),
|
||||
]
|
17
collabs/migrations/0003_remove_collabs_hour_collab.py
Normal file
@@ -0,0 +1,17 @@
|
||||
# Generated by Django 4.0 on 2022-01-31 17:11
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('collabs', '0002_collabs_hour_user'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='collabs_hour',
|
||||
name='collab',
|
||||
),
|
||||
]
|
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.0 on 2022-01-31 17:13
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('collabs', '0003_remove_collabs_hour_collab'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameField(
|
||||
model_name='collabs_hour',
|
||||
old_name='user',
|
||||
new_name='Collaborateur',
|
||||
),
|
||||
]
|
@@ -0,0 +1,24 @@
|
||||
# Generated by Django 4.0 on 2022-01-31 17:14
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('auth', '0012_alter_user_first_name_max_length'),
|
||||
('collabs', '0004_rename_user_collabs_hour_collaborateur'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='collabs_hour',
|
||||
name='Collaborateur',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='collabs_hour',
|
||||
name='user',
|
||||
field=models.ForeignKey(default=0, on_delete=django.db.models.deletion.DO_NOTHING, to='auth.user', verbose_name='test'),
|
||||
),
|
||||
]
|
18
collabs/migrations/0006_alter_collabs_hour_username.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.0 on 2022-01-31 17:15
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('collabs', '0005_remove_collabs_hour_collaborateur_collabs_hour_user'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='collabs_hour',
|
||||
name='userName',
|
||||
field=models.CharField(max_length=100, verbose_name='auteur'),
|
||||
),
|
||||
]
|
@@ -0,0 +1,23 @@
|
||||
# Generated by Django 4.0 on 2022-01-31 17:16
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('collabs', '0006_alter_collabs_hour_username'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameField(
|
||||
model_name='collabs_hour',
|
||||
old_name='user',
|
||||
new_name='Collaborateur',
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='collabs_hour',
|
||||
name='userName',
|
||||
field=models.CharField(max_length=100, verbose_name='Auteur'),
|
||||
),
|
||||
]
|
@@ -0,0 +1,36 @@
|
||||
# Generated by Django 4.0 on 2022-01-31 17:28
|
||||
|
||||
import django.core.validators
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('auth', '0012_alter_user_first_name_max_length'),
|
||||
('collabs', '0008_rename_collaborateur_collabs_hour_user'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='collabs_hour',
|
||||
name='dtCreated',
|
||||
field=models.DateTimeField(auto_now_add=True, verbose_name='Date de création'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='collabs_hour',
|
||||
name='nHour',
|
||||
field=models.PositiveIntegerField(default=0, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(23)], verbose_name='Heure'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='collabs_hour',
|
||||
name='nMinutes',
|
||||
field=models.PositiveIntegerField(default=0, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(60)], verbose_name='Minutes'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='collabs_hour',
|
||||
name='user',
|
||||
field=models.ForeignKey(default=0, on_delete=django.db.models.deletion.DO_NOTHING, to='auth.user', verbose_name='Collaborateur'),
|
||||
),
|
||||
]
|
18
collabs/migrations/0010_alter_collabs_hour_bnoticed.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.0 on 2022-01-31 17:44
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('collabs', '0009_alter_collabs_hour_dtcreated_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='collabs_hour',
|
||||
name='bNoticed',
|
||||
field=models.BooleanField(blank=True, verbose_name='Pris en compte'),
|
||||
),
|
||||
]
|
@@ -0,0 +1,23 @@
|
||||
# Generated by Django 4.0 on 2022-01-31 17:47
|
||||
|
||||
import django.core.validators
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('collabs', '0010_alter_collabs_hour_bnoticed'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='collabs_hour',
|
||||
options={'permissions': (('can_notice', 'Peut noter comme traitée'),)},
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='collabs_hour',
|
||||
name='nHour',
|
||||
field=models.PositiveIntegerField(default=0, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(23)], verbose_name='Heures'),
|
||||
),
|
||||
]
|
0
collabs/migrations/__init__.py
Normal file
24
collabs/models.py
Normal file
@@ -0,0 +1,24 @@
|
||||
import datetime
|
||||
|
||||
from django.core.validators import MinValueValidator, MaxValueValidator
|
||||
from django.db import models
|
||||
from django.conf import settings
|
||||
from django.utils import timezone
|
||||
from django.contrib import admin
|
||||
|
||||
class Collabs_hour(models.Model):
|
||||
userName = models.CharField("Auteur", max_length=100)
|
||||
user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name="Collaborateur", on_delete=models.DO_NOTHING, default=0)
|
||||
nHour = models.PositiveIntegerField("Heures", default=0, validators=[MinValueValidator(0), MaxValueValidator(23)])
|
||||
nMinutes = models.PositiveIntegerField("Minutes", default=0, validators=[MinValueValidator(0), MaxValueValidator(60)])
|
||||
sRemarques = models.TextField("Remarques")
|
||||
bNoticed = models.BooleanField("Pris en compte", blank=True)
|
||||
dtUpdate = models.DateTimeField('Date de modification', auto_now=True)
|
||||
dtCreated = models.DateTimeField('Date de création', auto_now_add=True)
|
||||
|
||||
class Meta:
|
||||
permissions = (
|
||||
("can_notice", "Peut noter comme traitée"),
|
||||
|
||||
)
|
||||
|
3
collabs/tests.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
3
collabs/views.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.shortcuts import render
|
||||
|
||||
# Create your views here.
|
BIN
db.sqlite3
7
my.cnf
Normal file
@@ -0,0 +1,7 @@
|
||||
[client]
|
||||
database = django_dev
|
||||
user = django_usr
|
||||
password = YwVHV36ovBTXWugb
|
||||
default-character-set = utf8
|
||||
host =192.168.3.113
|
||||
port =3306
|
@@ -4,7 +4,19 @@ from polls.models import Question, Choice
|
||||
from vehicles.models import *
|
||||
|
||||
|
||||
# Register your models here.
|
||||
admin.site.register(Question)
|
||||
class ChoiceInline(admin.TabularInline):
|
||||
model = Choice
|
||||
extra = 3
|
||||
class QuestionAdmin(admin.ModelAdmin):
|
||||
fieldsets = [
|
||||
(None, {'fields': ['question_txt']}),
|
||||
('Date information', {'fields': ['pub_date']}),
|
||||
]
|
||||
inlines = [ChoiceInline]
|
||||
list_display = ('question_txt', 'pub_date', 'was_published_recently')
|
||||
list_filter = ['pub_date']
|
||||
search_fields = ['question_txt']
|
||||
|
||||
admin.site.register(Question, QuestionAdmin)
|
||||
admin.site.register(Choice)
|
||||
admin.site.register(Vehicles)
|
||||
|
@@ -0,0 +1,28 @@
|
||||
# Generated by Django 4.0 on 2022-01-31 14:55
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('polls', '0003_delete_vehicles'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='choice',
|
||||
name='choice_txt',
|
||||
field=models.CharField(max_length=200, verbose_name='Nom'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='question',
|
||||
name='pub_date',
|
||||
field=models.DateTimeField(verbose_name='Date de publication'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='question',
|
||||
name='question_txt',
|
||||
field=models.CharField(max_length=250, verbose_name='Description'),
|
||||
),
|
||||
]
|
@@ -1,23 +1,28 @@
|
||||
import datetime
|
||||
import datetime
|
||||
|
||||
from django.db import models
|
||||
from django.utils import timezone
|
||||
from django.contrib import admin
|
||||
|
||||
|
||||
# Create your models here.
|
||||
class Question(models.Model):
|
||||
question_txt = models.CharField( max_length=250)
|
||||
pub_date = models.DateTimeField('date published')
|
||||
question_txt = models.CharField('Description', max_length=250)
|
||||
|
||||
pub_date = models.DateTimeField('Date de publication')
|
||||
|
||||
def __str__(self):
|
||||
return self.question_txt
|
||||
|
||||
|
||||
@admin.display(boolean=True, ordering='pub_date', description='Publié récamment')
|
||||
def was_published_recently(self):
|
||||
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
|
||||
|
||||
|
||||
|
||||
class Choice(models.Model):
|
||||
question = models.ForeignKey(Question, on_delete=models.CASCADE)
|
||||
choice_txt = models.CharField( max_length=200)
|
||||
choice_txt = models.CharField("Nom", max_length=200)
|
||||
votes = models.IntegerField( default=0)
|
||||
|
||||
def __str__(self):
|
||||
|
@@ -1,6 +1,12 @@
|
||||
<h1>{{ question.question_txt }}</h1>
|
||||
<ul>
|
||||
{% for choice in question.choice_set.all %}
|
||||
<li>{{ choice.choice_txt }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<form action="{% url 'polls:vote' question.id %}" method="post">
|
||||
{%csrf_token%}
|
||||
<fieldset>
|
||||
<legend><h1>{{question.question_txt}}</h1></legend>
|
||||
{%if error_message%}<p><strong>{{error_message}}</strong></p>{%endif%}
|
||||
{%for choice in question.choice_set.all%}
|
||||
<input type="radio" name="choice" id="choice{{forloop.counter}}" value="{{choice.id}}" />
|
||||
<label for="choice{{forlopp.counter}}">{{choice.choice_txt}}</label><br>
|
||||
{% endfor %}
|
||||
</fieldset>
|
||||
<input type="submit" value="Vote">
|
||||
</form>
|
@@ -1,8 +1,11 @@
|
||||
{% load static %}
|
||||
<link rel="stylesheet" type="text/css" href="{% static 'polls/style.css' %}">
|
||||
|
||||
{% if latest_question_list %}
|
||||
<h1>Liste des questions:</h1>
|
||||
<ul>
|
||||
{% for question in latest_question_list %}
|
||||
<li><a href="{% url 'polls:detail' question.id %}/">{{ question.question_txt }}</a></li>
|
||||
<li><a href="{% url 'polls:detail' question.id %}">{{ question.question_txt }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% else %}
|
||||
|
@@ -5,11 +5,8 @@ from . import views
|
||||
|
||||
app_name = "polls"
|
||||
urlpatterns = [
|
||||
path('',views.index, name='index'),
|
||||
# ex: /polls/5/
|
||||
path('specifics/<int:question_id>/', views.detail, name='detail'),
|
||||
# ex: /polls/5/results/
|
||||
path('<int:question_id>/results/', views.results, name='results'),
|
||||
# ex: /polls/5/vote/
|
||||
path('', views.IndexView.as_view(), name='index'),
|
||||
path('<int:pk>/', views.DetailView.as_view(), name='detail'),
|
||||
path('<int:pk>/results/', views.ResultsView.as_view(), name='results'),
|
||||
path('<int:question_id>/vote/', views.vote, name='vote'),
|
||||
]
|
||||
]
|
@@ -1,10 +1,44 @@
|
||||
from django.shortcuts import get_object_or_404, render
|
||||
from django.http import Http404
|
||||
from django.http import HttpResponse
|
||||
from django.http import HttpResponse, HttpResponseRedirect
|
||||
from django.urls import reverse
|
||||
from django.views import generic
|
||||
|
||||
|
||||
from polls.models import *
|
||||
|
||||
class IndexView(generic.ListView):
|
||||
template_name = 'polls/index.html'
|
||||
context_object_name = 'latest_question_list'
|
||||
def get_queryset(self):
|
||||
return Question.objects.order_by('-pub_date')[:5]
|
||||
|
||||
class DetailView(generic.DetailView):
|
||||
model = Question
|
||||
template_name = 'polls/detail.html'
|
||||
|
||||
class ResultsView(generic.DetailView):
|
||||
model = Question
|
||||
template_name = 'polls/results.html'
|
||||
|
||||
def vote(request, question_id):
|
||||
question = get_object_or_404(Question, pk=question_id)
|
||||
try:
|
||||
selected_choice = question.choice_set.get(pk=request.POST['choice'])
|
||||
except (KeyError, Choice.DoesNotExist):
|
||||
# Redisplay the question voting form.
|
||||
return render(request, 'polls/detail.html', {
|
||||
'question': question,
|
||||
'error_message': "You didn't select a choice.",
|
||||
})
|
||||
else:
|
||||
selected_choice.votes += 1
|
||||
selected_choice.save()
|
||||
# Always return an HttpResponseRedirect after successfully dealing
|
||||
# with POST data. This prevents data from being posted twice if a
|
||||
# user hits the Back button.
|
||||
return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
|
||||
'''
|
||||
def index(request):
|
||||
latest_question_list = Question.objects.order_by("-pub_date")[:5]
|
||||
|
||||
@@ -22,5 +56,11 @@ def results(request, question_id):
|
||||
response = "You're looking at the results of question %s."
|
||||
return HttpResponse(response % question_id)
|
||||
|
||||
def vote(request, question_id):
|
||||
return HttpResponse("Tu réponds à la question %s." % question_id)
|
||||
|
||||
def results(request, question_id):
|
||||
question = get_object_or_404(Question, pk=question_id)
|
||||
return render(request, 'polls/results.html', {'question': question})
|
||||
|
||||
|
||||
|
||||
'''
|
6
requirements.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
asgiref==3.4.1
|
||||
Django==4.0
|
||||
django-baton==2.2.3
|
||||
django-jazzmin==2.4.8
|
||||
sqlparse==0.4.2
|
||||
tzdata==2021.5
|
170
venv/Lib/site-packages/MySQLdb/__init__.py
Normal file
@@ -0,0 +1,170 @@
|
||||
"""
|
||||
MySQLdb - A DB API v2.0 compatible interface to MySQL.
|
||||
|
||||
This package is a wrapper around _mysql, which mostly implements the
|
||||
MySQL C API.
|
||||
|
||||
connect() -- connects to server
|
||||
|
||||
See the C API specification and the MySQL documentation for more info
|
||||
on other items.
|
||||
|
||||
For information on how MySQLdb handles type conversion, see the
|
||||
MySQLdb.converters module.
|
||||
"""
|
||||
|
||||
try:
|
||||
from MySQLdb.release import version_info
|
||||
from . import _mysql
|
||||
|
||||
assert version_info == _mysql.version_info
|
||||
except Exception:
|
||||
raise ImportError(
|
||||
"this is MySQLdb version {}, but _mysql is version {!r}\n_mysql: {!r}".format(
|
||||
version_info, _mysql.version_info, _mysql.__file__
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
from ._mysql import (
|
||||
NotSupportedError,
|
||||
OperationalError,
|
||||
get_client_info,
|
||||
ProgrammingError,
|
||||
Error,
|
||||
InterfaceError,
|
||||
debug,
|
||||
IntegrityError,
|
||||
string_literal,
|
||||
MySQLError,
|
||||
DataError,
|
||||
DatabaseError,
|
||||
InternalError,
|
||||
Warning,
|
||||
)
|
||||
from MySQLdb.constants import FIELD_TYPE
|
||||
from MySQLdb.times import (
|
||||
Date,
|
||||
Time,
|
||||
Timestamp,
|
||||
DateFromTicks,
|
||||
TimeFromTicks,
|
||||
TimestampFromTicks,
|
||||
)
|
||||
|
||||
threadsafety = 1
|
||||
apilevel = "2.0"
|
||||
paramstyle = "format"
|
||||
|
||||
|
||||
class DBAPISet(frozenset):
|
||||
"""A special type of set for which A == x is true if A is a
|
||||
DBAPISet and x is a member of that set."""
|
||||
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, DBAPISet):
|
||||
return not self.difference(other)
|
||||
return other in self
|
||||
|
||||
|
||||
STRING = DBAPISet([FIELD_TYPE.ENUM, FIELD_TYPE.STRING, FIELD_TYPE.VAR_STRING])
|
||||
BINARY = DBAPISet(
|
||||
[
|
||||
FIELD_TYPE.BLOB,
|
||||
FIELD_TYPE.LONG_BLOB,
|
||||
FIELD_TYPE.MEDIUM_BLOB,
|
||||
FIELD_TYPE.TINY_BLOB,
|
||||
]
|
||||
)
|
||||
NUMBER = DBAPISet(
|
||||
[
|
||||
FIELD_TYPE.DECIMAL,
|
||||
FIELD_TYPE.DOUBLE,
|
||||
FIELD_TYPE.FLOAT,
|
||||
FIELD_TYPE.INT24,
|
||||
FIELD_TYPE.LONG,
|
||||
FIELD_TYPE.LONGLONG,
|
||||
FIELD_TYPE.TINY,
|
||||
FIELD_TYPE.YEAR,
|
||||
FIELD_TYPE.NEWDECIMAL,
|
||||
]
|
||||
)
|
||||
DATE = DBAPISet([FIELD_TYPE.DATE])
|
||||
TIME = DBAPISet([FIELD_TYPE.TIME])
|
||||
TIMESTAMP = DBAPISet([FIELD_TYPE.TIMESTAMP, FIELD_TYPE.DATETIME])
|
||||
DATETIME = TIMESTAMP
|
||||
ROWID = DBAPISet()
|
||||
|
||||
|
||||
def test_DBAPISet_set_equality():
|
||||
assert STRING == STRING
|
||||
|
||||
|
||||
def test_DBAPISet_set_inequality():
|
||||
assert STRING != NUMBER
|
||||
|
||||
|
||||
def test_DBAPISet_set_equality_membership():
|
||||
assert FIELD_TYPE.VAR_STRING == STRING
|
||||
|
||||
|
||||
def test_DBAPISet_set_inequality_membership():
|
||||
assert FIELD_TYPE.DATE != STRING
|
||||
|
||||
|
||||
def Binary(x):
|
||||
return bytes(x)
|
||||
|
||||
|
||||
def Connect(*args, **kwargs):
|
||||
"""Factory function for connections.Connection."""
|
||||
from MySQLdb.connections import Connection
|
||||
|
||||
return Connection(*args, **kwargs)
|
||||
|
||||
|
||||
connect = Connection = Connect
|
||||
|
||||
__all__ = [
|
||||
"BINARY",
|
||||
"Binary",
|
||||
"Connect",
|
||||
"Connection",
|
||||
"DATE",
|
||||
"Date",
|
||||
"Time",
|
||||
"Timestamp",
|
||||
"DateFromTicks",
|
||||
"TimeFromTicks",
|
||||
"TimestampFromTicks",
|
||||
"DataError",
|
||||
"DatabaseError",
|
||||
"Error",
|
||||
"FIELD_TYPE",
|
||||
"IntegrityError",
|
||||
"InterfaceError",
|
||||
"InternalError",
|
||||
"MySQLError",
|
||||
"NUMBER",
|
||||
"NotSupportedError",
|
||||
"DBAPISet",
|
||||
"OperationalError",
|
||||
"ProgrammingError",
|
||||
"ROWID",
|
||||
"STRING",
|
||||
"TIME",
|
||||
"TIMESTAMP",
|
||||
"Warning",
|
||||
"apilevel",
|
||||
"connect",
|
||||
"connections",
|
||||
"constants",
|
||||
"converters",
|
||||
"cursors",
|
||||
"debug",
|
||||
"get_client_info",
|
||||
"paramstyle",
|
||||
"string_literal",
|
||||
"threadsafety",
|
||||
"version_info",
|
||||
]
|
69
venv/Lib/site-packages/MySQLdb/_exceptions.py
Normal file
@@ -0,0 +1,69 @@
|
||||
"""Exception classes for _mysql and MySQLdb.
|
||||
|
||||
These classes are dictated by the DB API v2.0:
|
||||
|
||||
https://www.python.org/dev/peps/pep-0249/
|
||||
"""
|
||||
|
||||
|
||||
class MySQLError(Exception):
|
||||
"""Exception related to operation with MySQL."""
|
||||
|
||||
|
||||
class Warning(Warning, MySQLError):
|
||||
"""Exception raised for important warnings like data truncations
|
||||
while inserting, etc."""
|
||||
|
||||
|
||||
class Error(MySQLError):
|
||||
"""Exception that is the base class of all other error exceptions
|
||||
(not Warning)."""
|
||||
|
||||
|
||||
class InterfaceError(Error):
|
||||
"""Exception raised for errors that are related to the database
|
||||
interface rather than the database itself."""
|
||||
|
||||
|
||||
class DatabaseError(Error):
|
||||
"""Exception raised for errors that are related to the
|
||||
database."""
|
||||
|
||||
|
||||
class DataError(DatabaseError):
|
||||
"""Exception raised for errors that are due to problems with the
|
||||
processed data like division by zero, numeric value out of range,
|
||||
etc."""
|
||||
|
||||
|
||||
class OperationalError(DatabaseError):
|
||||
"""Exception raised for errors that are related to the database's
|
||||
operation and not necessarily under the control of the programmer,
|
||||
e.g. an unexpected disconnect occurs, the data source name is not
|
||||
found, a transaction could not be processed, a memory allocation
|
||||
error occurred during processing, etc."""
|
||||
|
||||
|
||||
class IntegrityError(DatabaseError):
|
||||
"""Exception raised when the relational integrity of the database
|
||||
is affected, e.g. a foreign key check fails, duplicate key,
|
||||
etc."""
|
||||
|
||||
|
||||
class InternalError(DatabaseError):
|
||||
"""Exception raised when the database encounters an internal
|
||||
error, e.g. the cursor is not valid anymore, the transaction is
|
||||
out of sync, etc."""
|
||||
|
||||
|
||||
class ProgrammingError(DatabaseError):
|
||||
"""Exception raised for programming errors, e.g. table not found
|
||||
or already exists, syntax error in the SQL statement, wrong number
|
||||
of parameters specified, etc."""
|
||||
|
||||
|
||||
class NotSupportedError(DatabaseError):
|
||||
"""Exception raised in case a method or database API was used
|
||||
which is not supported by the database, e.g. requesting a
|
||||
.rollback() on a connection that does not support transaction or
|
||||
has transactions turned off."""
|
BIN
venv/Lib/site-packages/MySQLdb/_mysql.cp310-win_amd64.pyd
Normal file
333
venv/Lib/site-packages/MySQLdb/connections.py
Normal file
@@ -0,0 +1,333 @@
|
||||
"""
|
||||
This module implements connections for MySQLdb. Presently there is
|
||||
only one class: Connection. Others are unlikely. However, you might
|
||||
want to make your own subclasses. In most cases, you will probably
|
||||
override Connection.default_cursor with a non-standard Cursor class.
|
||||
"""
|
||||
import re
|
||||
|
||||
from . import cursors, _mysql
|
||||
from ._exceptions import (
|
||||
Warning,
|
||||
Error,
|
||||
InterfaceError,
|
||||
DataError,
|
||||
DatabaseError,
|
||||
OperationalError,
|
||||
IntegrityError,
|
||||
InternalError,
|
||||
NotSupportedError,
|
||||
ProgrammingError,
|
||||
)
|
||||
|
||||
# Mapping from MySQL charset name to Python codec name
|
||||
_charset_to_encoding = {
|
||||
"utf8mb4": "utf8",
|
||||
"utf8mb3": "utf8",
|
||||
"latin1": "cp1252",
|
||||
"koi8r": "koi8_r",
|
||||
"koi8u": "koi8_u",
|
||||
}
|
||||
|
||||
re_numeric_part = re.compile(r"^(\d+)")
|
||||
|
||||
|
||||
def numeric_part(s):
|
||||
"""Returns the leading numeric part of a string.
|
||||
|
||||
>>> numeric_part("20-alpha")
|
||||
20
|
||||
>>> numeric_part("foo")
|
||||
>>> numeric_part("16b")
|
||||
16
|
||||
"""
|
||||
|
||||
m = re_numeric_part.match(s)
|
||||
if m:
|
||||
return int(m.group(1))
|
||||
return None
|
||||
|
||||
|
||||
class Connection(_mysql.connection):
|
||||
"""MySQL Database Connection Object"""
|
||||
|
||||
default_cursor = cursors.Cursor
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""
|
||||
Create a connection to the database. It is strongly recommended
|
||||
that you only use keyword parameters. Consult the MySQL C API
|
||||
documentation for more information.
|
||||
|
||||
:param str host: host to connect
|
||||
:param str user: user to connect as
|
||||
:param str password: password to use
|
||||
:param str passwd: alias of password (deprecated)
|
||||
:param str database: database to use
|
||||
:param str db: alias of database (deprecated)
|
||||
:param int port: TCP/IP port to connect to
|
||||
:param str unix_socket: location of unix_socket to use
|
||||
:param dict conv: conversion dictionary, see MySQLdb.converters
|
||||
:param int connect_timeout:
|
||||
number of seconds to wait before the connection attempt fails.
|
||||
|
||||
:param bool compress: if set, compression is enabled
|
||||
:param str named_pipe: if set, a named pipe is used to connect (Windows only)
|
||||
:param str init_command:
|
||||
command which is run once the connection is created
|
||||
|
||||
:param str read_default_file:
|
||||
file from which default client values are read
|
||||
|
||||
:param str read_default_group:
|
||||
configuration group to use from the default file
|
||||
|
||||
:param type cursorclass:
|
||||
class object, used to create cursors (keyword only)
|
||||
|
||||
:param bool use_unicode:
|
||||
If True, text-like columns are returned as unicode objects
|
||||
using the connection's character set. Otherwise, text-like
|
||||
columns are returned as bytes. Unicode objects will always
|
||||
be encoded to the connection's character set regardless of
|
||||
this setting.
|
||||
Default to True.
|
||||
|
||||
:param str charset:
|
||||
If supplied, the connection character set will be changed
|
||||
to this character set.
|
||||
|
||||
:param str auth_plugin:
|
||||
If supplied, the connection default authentication plugin will be
|
||||
changed to this value. Example values:
|
||||
`mysql_native_password` or `caching_sha2_password`
|
||||
|
||||
:param str sql_mode:
|
||||
If supplied, the session SQL mode will be changed to this
|
||||
setting.
|
||||
For more details and legal values, see the MySQL documentation.
|
||||
|
||||
:param int client_flag:
|
||||
flags to use or 0 (see MySQL docs or constants/CLIENTS.py)
|
||||
|
||||
:param bool multi_statements:
|
||||
If True, enable multi statements for clients >= 4.1.
|
||||
Defaults to True.
|
||||
|
||||
:param str ssl_mode:
|
||||
specify the security settings for connection to the server;
|
||||
see the MySQL documentation for more details
|
||||
(mysql_option(), MYSQL_OPT_SSL_MODE).
|
||||
Only one of 'DISABLED', 'PREFERRED', 'REQUIRED',
|
||||
'VERIFY_CA', 'VERIFY_IDENTITY' can be specified.
|
||||
|
||||
:param dict ssl:
|
||||
dictionary or mapping contains SSL connection parameters;
|
||||
see the MySQL documentation for more details
|
||||
(mysql_ssl_set()). If this is set, and the client does not
|
||||
support SSL, NotSupportedError will be raised.
|
||||
|
||||
:param bool local_infile:
|
||||
enables LOAD LOCAL INFILE; zero disables
|
||||
|
||||
:param bool autocommit:
|
||||
If False (default), autocommit is disabled.
|
||||
If True, autocommit is enabled.
|
||||
If None, autocommit isn't set and server default is used.
|
||||
|
||||
:param bool binary_prefix:
|
||||
If set, the '_binary' prefix will be used for raw byte query
|
||||
arguments (e.g. Binary). This is disabled by default.
|
||||
|
||||
There are a number of undocumented, non-standard methods. See the
|
||||
documentation for the MySQL C API for some hints on what they do.
|
||||
"""
|
||||
from MySQLdb.constants import CLIENT, FIELD_TYPE
|
||||
from MySQLdb.converters import conversions, _bytes_or_str
|
||||
from weakref import proxy
|
||||
|
||||
kwargs2 = kwargs.copy()
|
||||
|
||||
if "db" in kwargs2:
|
||||
kwargs2["database"] = kwargs2.pop("db")
|
||||
if "passwd" in kwargs2:
|
||||
kwargs2["password"] = kwargs2.pop("passwd")
|
||||
|
||||
if "conv" in kwargs:
|
||||
conv = kwargs["conv"]
|
||||
else:
|
||||
conv = conversions
|
||||
|
||||
conv2 = {}
|
||||
for k, v in conv.items():
|
||||
if isinstance(k, int) and isinstance(v, list):
|
||||
conv2[k] = v[:]
|
||||
else:
|
||||
conv2[k] = v
|
||||
kwargs2["conv"] = conv2
|
||||
|
||||
cursorclass = kwargs2.pop("cursorclass", self.default_cursor)
|
||||
charset = kwargs2.get("charset", "")
|
||||
use_unicode = kwargs2.pop("use_unicode", True)
|
||||
sql_mode = kwargs2.pop("sql_mode", "")
|
||||
self._binary_prefix = kwargs2.pop("binary_prefix", False)
|
||||
|
||||
client_flag = kwargs.get("client_flag", 0)
|
||||
client_flag |= CLIENT.MULTI_RESULTS
|
||||
multi_statements = kwargs2.pop("multi_statements", True)
|
||||
if multi_statements:
|
||||
client_flag |= CLIENT.MULTI_STATEMENTS
|
||||
kwargs2["client_flag"] = client_flag
|
||||
|
||||
# PEP-249 requires autocommit to be initially off
|
||||
autocommit = kwargs2.pop("autocommit", False)
|
||||
|
||||
super().__init__(*args, **kwargs2)
|
||||
self.cursorclass = cursorclass
|
||||
self.encoders = {k: v for k, v in conv.items() if type(k) is not int}
|
||||
|
||||
self._server_version = tuple(
|
||||
[numeric_part(n) for n in self.get_server_info().split(".")[:2]]
|
||||
)
|
||||
|
||||
self.encoding = "ascii" # overridden in set_character_set()
|
||||
|
||||
if not charset:
|
||||
charset = self.character_set_name()
|
||||
self.set_character_set(charset)
|
||||
|
||||
if sql_mode:
|
||||
self.set_sql_mode(sql_mode)
|
||||
|
||||
if use_unicode:
|
||||
for t in (
|
||||
FIELD_TYPE.STRING,
|
||||
FIELD_TYPE.VAR_STRING,
|
||||
FIELD_TYPE.VARCHAR,
|
||||
FIELD_TYPE.TINY_BLOB,
|
||||
FIELD_TYPE.MEDIUM_BLOB,
|
||||
FIELD_TYPE.LONG_BLOB,
|
||||
FIELD_TYPE.BLOB,
|
||||
):
|
||||
self.converter[t] = _bytes_or_str
|
||||
# Unlike other string/blob types, JSON is always text.
|
||||
# MySQL may return JSON with charset==binary.
|
||||
self.converter[FIELD_TYPE.JSON] = str
|
||||
|
||||
db = proxy(self)
|
||||
|
||||
def unicode_literal(u, dummy=None):
|
||||
return db.string_literal(u.encode(db.encoding))
|
||||
|
||||
self.encoders[str] = unicode_literal
|
||||
|
||||
self._transactional = self.server_capabilities & CLIENT.TRANSACTIONS
|
||||
if self._transactional:
|
||||
if autocommit is not None:
|
||||
self.autocommit(autocommit)
|
||||
self.messages = []
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_value, traceback):
|
||||
self.close()
|
||||
|
||||
def autocommit(self, on):
|
||||
on = bool(on)
|
||||
if self.get_autocommit() != on:
|
||||
_mysql.connection.autocommit(self, on)
|
||||
|
||||
def cursor(self, cursorclass=None):
|
||||
"""
|
||||
Create a cursor on which queries may be performed. The
|
||||
optional cursorclass parameter is used to create the
|
||||
Cursor. By default, self.cursorclass=cursors.Cursor is
|
||||
used.
|
||||
"""
|
||||
return (cursorclass or self.cursorclass)(self)
|
||||
|
||||
def query(self, query):
|
||||
# Since _mysql releases GIL while querying, we need immutable buffer.
|
||||
if isinstance(query, bytearray):
|
||||
query = bytes(query)
|
||||
_mysql.connection.query(self, query)
|
||||
|
||||
def _bytes_literal(self, bs):
|
||||
assert isinstance(bs, (bytes, bytearray))
|
||||
x = self.string_literal(bs) # x is escaped and quoted bytes
|
||||
if self._binary_prefix:
|
||||
return b"_binary" + x
|
||||
return x
|
||||
|
||||
def _tuple_literal(self, t):
|
||||
return b"(%s)" % (b",".join(map(self.literal, t)))
|
||||
|
||||
def literal(self, o):
|
||||
"""If o is a single object, returns an SQL literal as a string.
|
||||
If o is a non-string sequence, the items of the sequence are
|
||||
converted and returned as a sequence.
|
||||
|
||||
Non-standard. For internal use; do not use this in your
|
||||
applications.
|
||||
"""
|
||||
if isinstance(o, str):
|
||||
s = self.string_literal(o.encode(self.encoding))
|
||||
elif isinstance(o, bytearray):
|
||||
s = self._bytes_literal(o)
|
||||
elif isinstance(o, bytes):
|
||||
s = self._bytes_literal(o)
|
||||
elif isinstance(o, (tuple, list)):
|
||||
s = self._tuple_literal(o)
|
||||
else:
|
||||
s = self.escape(o, self.encoders)
|
||||
if isinstance(s, str):
|
||||
s = s.encode(self.encoding)
|
||||
assert isinstance(s, bytes)
|
||||
return s
|
||||
|
||||
def begin(self):
|
||||
"""Explicitly begin a connection.
|
||||
|
||||
This method is not used when autocommit=False (default).
|
||||
"""
|
||||
self.query(b"BEGIN")
|
||||
|
||||
def set_character_set(self, charset):
|
||||
"""Set the connection character set to charset."""
|
||||
super().set_character_set(charset)
|
||||
self.encoding = _charset_to_encoding.get(charset, charset)
|
||||
|
||||
def set_sql_mode(self, sql_mode):
|
||||
"""Set the connection sql_mode. See MySQL documentation for
|
||||
legal values."""
|
||||
if self._server_version < (4, 1):
|
||||
raise NotSupportedError("server is too old to set sql_mode")
|
||||
self.query("SET SESSION sql_mode='%s'" % sql_mode)
|
||||
self.store_result()
|
||||
|
||||
def show_warnings(self):
|
||||
"""Return detailed information about warnings as a
|
||||
sequence of tuples of (Level, Code, Message). This
|
||||
is only supported in MySQL-4.1 and up. If your server
|
||||
is an earlier version, an empty sequence is returned."""
|
||||
if self._server_version < (4, 1):
|
||||
return ()
|
||||
self.query("SHOW WARNINGS")
|
||||
r = self.store_result()
|
||||
warnings = r.fetch_row(0)
|
||||
return warnings
|
||||
|
||||
Warning = Warning
|
||||
Error = Error
|
||||
InterfaceError = InterfaceError
|
||||
DatabaseError = DatabaseError
|
||||
DataError = DataError
|
||||
OperationalError = OperationalError
|
||||
IntegrityError = IntegrityError
|
||||
InternalError = InternalError
|
||||
ProgrammingError = ProgrammingError
|
||||
NotSupportedError = NotSupportedError
|
||||
|
||||
|
||||
# vim: colorcolumn=100
|
27
venv/Lib/site-packages/MySQLdb/constants/CLIENT.py
Normal file
@@ -0,0 +1,27 @@
|
||||
"""MySQL CLIENT constants
|
||||
|
||||
These constants are used when creating the connection. Use bitwise-OR
|
||||
(|) to combine options together, and pass them as the client_flags
|
||||
parameter to MySQLdb.Connection. For more information on these flags,
|
||||
see the MySQL C API documentation for mysql_real_connect().
|
||||
|
||||
"""
|
||||
|
||||
LONG_PASSWORD = 1
|
||||
FOUND_ROWS = 2
|
||||
LONG_FLAG = 4
|
||||
CONNECT_WITH_DB = 8
|
||||
NO_SCHEMA = 16
|
||||
COMPRESS = 32
|
||||
ODBC = 64
|
||||
LOCAL_FILES = 128
|
||||
IGNORE_SPACE = 256
|
||||
CHANGE_USER = 512
|
||||
INTERACTIVE = 1024
|
||||
SSL = 2048
|
||||
IGNORE_SIGPIPE = 4096
|
||||
TRANSACTIONS = 8192 # mysql_com.h was WRONG prior to 3.23.35
|
||||
RESERVED = 16384
|
||||
SECURE_CONNECTION = 32768
|
||||
MULTI_STATEMENTS = 65536
|
||||
MULTI_RESULTS = 131072
|
105
venv/Lib/site-packages/MySQLdb/constants/CR.py
Normal file
@@ -0,0 +1,105 @@
|
||||
"""MySQL Connection Errors
|
||||
|
||||
Nearly all of these raise OperationalError. COMMANDS_OUT_OF_SYNC
|
||||
raises ProgrammingError.
|
||||
|
||||
"""
|
||||
|
||||
if __name__ == "__main__":
|
||||
"""
|
||||
Usage: python CR.py [/path/to/mysql/errmsg.h ...] >> CR.py
|
||||
"""
|
||||
import fileinput
|
||||
import re
|
||||
|
||||
data = {}
|
||||
error_last = None
|
||||
for line in fileinput.input():
|
||||
line = re.sub(r"/\*.*?\*/", "", line)
|
||||
m = re.match(r"^\s*#define\s+CR_([A-Z0-9_]+)\s+(\d+)(\s.*|$)", line)
|
||||
if m:
|
||||
name = m.group(1)
|
||||
value = int(m.group(2))
|
||||
if name == "ERROR_LAST":
|
||||
if error_last is None or error_last < value:
|
||||
error_last = value
|
||||
continue
|
||||
if value not in data:
|
||||
data[value] = set()
|
||||
data[value].add(name)
|
||||
for value, names in sorted(data.items()):
|
||||
for name in sorted(names):
|
||||
print("{} = {}".format(name, value))
|
||||
if error_last is not None:
|
||||
print("ERROR_LAST = %s" % error_last)
|
||||
|
||||
|
||||
ERROR_FIRST = 2000
|
||||
MIN_ERROR = 2000
|
||||
UNKNOWN_ERROR = 2000
|
||||
SOCKET_CREATE_ERROR = 2001
|
||||
CONNECTION_ERROR = 2002
|
||||
CONN_HOST_ERROR = 2003
|
||||
IPSOCK_ERROR = 2004
|
||||
UNKNOWN_HOST = 2005
|
||||
SERVER_GONE_ERROR = 2006
|
||||
VERSION_ERROR = 2007
|
||||
OUT_OF_MEMORY = 2008
|
||||
WRONG_HOST_INFO = 2009
|
||||
LOCALHOST_CONNECTION = 2010
|
||||
TCP_CONNECTION = 2011
|
||||
SERVER_HANDSHAKE_ERR = 2012
|
||||
SERVER_LOST = 2013
|
||||
COMMANDS_OUT_OF_SYNC = 2014
|
||||
NAMEDPIPE_CONNECTION = 2015
|
||||
NAMEDPIPEWAIT_ERROR = 2016
|
||||
NAMEDPIPEOPEN_ERROR = 2017
|
||||
NAMEDPIPESETSTATE_ERROR = 2018
|
||||
CANT_READ_CHARSET = 2019
|
||||
NET_PACKET_TOO_LARGE = 2020
|
||||
EMBEDDED_CONNECTION = 2021
|
||||
PROBE_SLAVE_STATUS = 2022
|
||||
PROBE_SLAVE_HOSTS = 2023
|
||||
PROBE_SLAVE_CONNECT = 2024
|
||||
PROBE_MASTER_CONNECT = 2025
|
||||
SSL_CONNECTION_ERROR = 2026
|
||||
MALFORMED_PACKET = 2027
|
||||
WRONG_LICENSE = 2028
|
||||
NULL_POINTER = 2029
|
||||
NO_PREPARE_STMT = 2030
|
||||
PARAMS_NOT_BOUND = 2031
|
||||
DATA_TRUNCATED = 2032
|
||||
NO_PARAMETERS_EXISTS = 2033
|
||||
INVALID_PARAMETER_NO = 2034
|
||||
INVALID_BUFFER_USE = 2035
|
||||
UNSUPPORTED_PARAM_TYPE = 2036
|
||||
SHARED_MEMORY_CONNECTION = 2037
|
||||
SHARED_MEMORY_CONNECT_REQUEST_ERROR = 2038
|
||||
SHARED_MEMORY_CONNECT_ANSWER_ERROR = 2039
|
||||
SHARED_MEMORY_CONNECT_FILE_MAP_ERROR = 2040
|
||||
SHARED_MEMORY_CONNECT_MAP_ERROR = 2041
|
||||
SHARED_MEMORY_FILE_MAP_ERROR = 2042
|
||||
SHARED_MEMORY_MAP_ERROR = 2043
|
||||
SHARED_MEMORY_EVENT_ERROR = 2044
|
||||
SHARED_MEMORY_CONNECT_ABANDONED_ERROR = 2045
|
||||
SHARED_MEMORY_CONNECT_SET_ERROR = 2046
|
||||
CONN_UNKNOW_PROTOCOL = 2047
|
||||
INVALID_CONN_HANDLE = 2048
|
||||
UNUSED_1 = 2049
|
||||
FETCH_CANCELED = 2050
|
||||
NO_DATA = 2051
|
||||
NO_STMT_METADATA = 2052
|
||||
NO_RESULT_SET = 2053
|
||||
NOT_IMPLEMENTED = 2054
|
||||
SERVER_LOST_EXTENDED = 2055
|
||||
STMT_CLOSED = 2056
|
||||
NEW_STMT_METADATA = 2057
|
||||
ALREADY_CONNECTED = 2058
|
||||
AUTH_PLUGIN_CANNOT_LOAD = 2059
|
||||
DUPLICATE_CONNECTION_ATTR = 2060
|
||||
AUTH_PLUGIN_ERR = 2061
|
||||
INSECURE_API_ERR = 2062
|
||||
FILE_NAME_TOO_LONG = 2063
|
||||
SSL_FIPS_MODE_ERR = 2064
|
||||
MAX_ERROR = 2999
|
||||
ERROR_LAST = 2064
|
827
venv/Lib/site-packages/MySQLdb/constants/ER.py
Normal file
@@ -0,0 +1,827 @@
|
||||
"""MySQL ER Constants
|
||||
|
||||
These constants are error codes for the bulk of the error conditions
|
||||
that may occur.
|
||||
"""
|
||||
|
||||
if __name__ == "__main__":
|
||||
"""
|
||||
Usage: python ER.py [/path/to/mysql/mysqld_error.h ...] >> ER.py
|
||||
"""
|
||||
import fileinput
|
||||
import re
|
||||
|
||||
data = {}
|
||||
error_last = None
|
||||
for line in fileinput.input():
|
||||
line = re.sub(r"/\*.*?\*/", "", line)
|
||||
m = re.match(r"^\s*#define\s+((ER|WARN)_[A-Z0-9_]+)\s+(\d+)\s*", line)
|
||||
if m:
|
||||
name = m.group(1)
|
||||
if name.startswith("ER_"):
|
||||
name = name[3:]
|
||||
value = int(m.group(3))
|
||||
if name == "ERROR_LAST":
|
||||
if error_last is None or error_last < value:
|
||||
error_last = value
|
||||
continue
|
||||
if value not in data:
|
||||
data[value] = set()
|
||||
data[value].add(name)
|
||||
for value, names in sorted(data.items()):
|
||||
for name in sorted(names):
|
||||
print("{} = {}".format(name, value))
|
||||
if error_last is not None:
|
||||
print("ERROR_LAST = %s" % error_last)
|
||||
|
||||
|
||||
ERROR_FIRST = 1000
|
||||
NO = 1002
|
||||
YES = 1003
|
||||
CANT_CREATE_FILE = 1004
|
||||
CANT_CREATE_TABLE = 1005
|
||||
CANT_CREATE_DB = 1006
|
||||
DB_CREATE_EXISTS = 1007
|
||||
DB_DROP_EXISTS = 1008
|
||||
DB_DROP_RMDIR = 1010
|
||||
CANT_FIND_SYSTEM_REC = 1012
|
||||
CANT_GET_STAT = 1013
|
||||
CANT_LOCK = 1015
|
||||
CANT_OPEN_FILE = 1016
|
||||
FILE_NOT_FOUND = 1017
|
||||
CANT_READ_DIR = 1018
|
||||
CHECKREAD = 1020
|
||||
DUP_KEY = 1022
|
||||
ERROR_ON_READ = 1024
|
||||
ERROR_ON_RENAME = 1025
|
||||
ERROR_ON_WRITE = 1026
|
||||
FILE_USED = 1027
|
||||
FILSORT_ABORT = 1028
|
||||
GET_ERRNO = 1030
|
||||
ILLEGAL_HA = 1031
|
||||
KEY_NOT_FOUND = 1032
|
||||
NOT_FORM_FILE = 1033
|
||||
NOT_KEYFILE = 1034
|
||||
OLD_KEYFILE = 1035
|
||||
OPEN_AS_READONLY = 1036
|
||||
OUTOFMEMORY = 1037
|
||||
OUT_OF_SORTMEMORY = 1038
|
||||
CON_COUNT_ERROR = 1040
|
||||
OUT_OF_RESOURCES = 1041
|
||||
BAD_HOST_ERROR = 1042
|
||||
HANDSHAKE_ERROR = 1043
|
||||
DBACCESS_DENIED_ERROR = 1044
|
||||
ACCESS_DENIED_ERROR = 1045
|
||||
NO_DB_ERROR = 1046
|
||||
UNKNOWN_COM_ERROR = 1047
|
||||
BAD_NULL_ERROR = 1048
|
||||
BAD_DB_ERROR = 1049
|
||||
TABLE_EXISTS_ERROR = 1050
|
||||
BAD_TABLE_ERROR = 1051
|
||||
NON_UNIQ_ERROR = 1052
|
||||
SERVER_SHUTDOWN = 1053
|
||||
BAD_FIELD_ERROR = 1054
|
||||
WRONG_FIELD_WITH_GROUP = 1055
|
||||
WRONG_GROUP_FIELD = 1056
|
||||
WRONG_SUM_SELECT = 1057
|
||||
WRONG_VALUE_COUNT = 1058
|
||||
TOO_LONG_IDENT = 1059
|
||||
DUP_FIELDNAME = 1060
|
||||
DUP_KEYNAME = 1061
|
||||
DUP_ENTRY = 1062
|
||||
WRONG_FIELD_SPEC = 1063
|
||||
PARSE_ERROR = 1064
|
||||
EMPTY_QUERY = 1065
|
||||
NONUNIQ_TABLE = 1066
|
||||
INVALID_DEFAULT = 1067
|
||||
MULTIPLE_PRI_KEY = 1068
|
||||
TOO_MANY_KEYS = 1069
|
||||
TOO_MANY_KEY_PARTS = 1070
|
||||
TOO_LONG_KEY = 1071
|
||||
KEY_COLUMN_DOES_NOT_EXITS = 1072
|
||||
BLOB_USED_AS_KEY = 1073
|
||||
TOO_BIG_FIELDLENGTH = 1074
|
||||
WRONG_AUTO_KEY = 1075
|
||||
READY = 1076
|
||||
SHUTDOWN_COMPLETE = 1079
|
||||
FORCING_CLOSE = 1080
|
||||
IPSOCK_ERROR = 1081
|
||||
NO_SUCH_INDEX = 1082
|
||||
WRONG_FIELD_TERMINATORS = 1083
|
||||
BLOBS_AND_NO_TERMINATED = 1084
|
||||
TEXTFILE_NOT_READABLE = 1085
|
||||
FILE_EXISTS_ERROR = 1086
|
||||
LOAD_INFO = 1087
|
||||
ALTER_INFO = 1088
|
||||
WRONG_SUB_KEY = 1089
|
||||
CANT_REMOVE_ALL_FIELDS = 1090
|
||||
CANT_DROP_FIELD_OR_KEY = 1091
|
||||
INSERT_INFO = 1092
|
||||
UPDATE_TABLE_USED = 1093
|
||||
NO_SUCH_THREAD = 1094
|
||||
KILL_DENIED_ERROR = 1095
|
||||
NO_TABLES_USED = 1096
|
||||
TOO_BIG_SET = 1097
|
||||
NO_UNIQUE_LOGFILE = 1098
|
||||
TABLE_NOT_LOCKED_FOR_WRITE = 1099
|
||||
TABLE_NOT_LOCKED = 1100
|
||||
BLOB_CANT_HAVE_DEFAULT = 1101
|
||||
WRONG_DB_NAME = 1102
|
||||
WRONG_TABLE_NAME = 1103
|
||||
TOO_BIG_SELECT = 1104
|
||||
UNKNOWN_ERROR = 1105
|
||||
UNKNOWN_PROCEDURE = 1106
|
||||
WRONG_PARAMCOUNT_TO_PROCEDURE = 1107
|
||||
WRONG_PARAMETERS_TO_PROCEDURE = 1108
|
||||
UNKNOWN_TABLE = 1109
|
||||
FIELD_SPECIFIED_TWICE = 1110
|
||||
INVALID_GROUP_FUNC_USE = 1111
|
||||
UNSUPPORTED_EXTENSION = 1112
|
||||
TABLE_MUST_HAVE_COLUMNS = 1113
|
||||
RECORD_FILE_FULL = 1114
|
||||
UNKNOWN_CHARACTER_SET = 1115
|
||||
TOO_MANY_TABLES = 1116
|
||||
TOO_MANY_FIELDS = 1117
|
||||
TOO_BIG_ROWSIZE = 1118
|
||||
STACK_OVERRUN = 1119
|
||||
WRONG_OUTER_JOIN_UNUSED = 1120
|
||||
NULL_COLUMN_IN_INDEX = 1121
|
||||
CANT_FIND_UDF = 1122
|
||||
CANT_INITIALIZE_UDF = 1123
|
||||
UDF_NO_PATHS = 1124
|
||||
UDF_EXISTS = 1125
|
||||
CANT_OPEN_LIBRARY = 1126
|
||||
CANT_FIND_DL_ENTRY = 1127
|
||||
FUNCTION_NOT_DEFINED = 1128
|
||||
HOST_IS_BLOCKED = 1129
|
||||
HOST_NOT_PRIVILEGED = 1130
|
||||
PASSWORD_ANONYMOUS_USER = 1131
|
||||
PASSWORD_NOT_ALLOWED = 1132
|
||||
PASSWORD_NO_MATCH = 1133
|
||||
UPDATE_INFO = 1134
|
||||
CANT_CREATE_THREAD = 1135
|
||||
WRONG_VALUE_COUNT_ON_ROW = 1136
|
||||
CANT_REOPEN_TABLE = 1137
|
||||
INVALID_USE_OF_NULL = 1138
|
||||
REGEXP_ERROR = 1139
|
||||
MIX_OF_GROUP_FUNC_AND_FIELDS = 1140
|
||||
NONEXISTING_GRANT = 1141
|
||||
TABLEACCESS_DENIED_ERROR = 1142
|
||||
COLUMNACCESS_DENIED_ERROR = 1143
|
||||
ILLEGAL_GRANT_FOR_TABLE = 1144
|
||||
GRANT_WRONG_HOST_OR_USER = 1145
|
||||
NO_SUCH_TABLE = 1146
|
||||
NONEXISTING_TABLE_GRANT = 1147
|
||||
NOT_ALLOWED_COMMAND = 1148
|
||||
SYNTAX_ERROR = 1149
|
||||
ABORTING_CONNECTION = 1152
|
||||
NET_PACKET_TOO_LARGE = 1153
|
||||
NET_READ_ERROR_FROM_PIPE = 1154
|
||||
NET_FCNTL_ERROR = 1155
|
||||
NET_PACKETS_OUT_OF_ORDER = 1156
|
||||
NET_UNCOMPRESS_ERROR = 1157
|
||||
NET_READ_ERROR = 1158
|
||||
NET_READ_INTERRUPTED = 1159
|
||||
NET_ERROR_ON_WRITE = 1160
|
||||
NET_WRITE_INTERRUPTED = 1161
|
||||
TOO_LONG_STRING = 1162
|
||||
TABLE_CANT_HANDLE_BLOB = 1163
|
||||
TABLE_CANT_HANDLE_AUTO_INCREMENT = 1164
|
||||
WRONG_COLUMN_NAME = 1166
|
||||
WRONG_KEY_COLUMN = 1167
|
||||
WRONG_MRG_TABLE = 1168
|
||||
DUP_UNIQUE = 1169
|
||||
BLOB_KEY_WITHOUT_LENGTH = 1170
|
||||
PRIMARY_CANT_HAVE_NULL = 1171
|
||||
TOO_MANY_ROWS = 1172
|
||||
REQUIRES_PRIMARY_KEY = 1173
|
||||
UPDATE_WITHOUT_KEY_IN_SAFE_MODE = 1175
|
||||
KEY_DOES_NOT_EXITS = 1176
|
||||
CHECK_NO_SUCH_TABLE = 1177
|
||||
CHECK_NOT_IMPLEMENTED = 1178
|
||||
CANT_DO_THIS_DURING_AN_TRANSACTION = 1179
|
||||
ERROR_DURING_COMMIT = 1180
|
||||
ERROR_DURING_ROLLBACK = 1181
|
||||
ERROR_DURING_FLUSH_LOGS = 1182
|
||||
NEW_ABORTING_CONNECTION = 1184
|
||||
MASTER = 1188
|
||||
MASTER_NET_READ = 1189
|
||||
MASTER_NET_WRITE = 1190
|
||||
FT_MATCHING_KEY_NOT_FOUND = 1191
|
||||
LOCK_OR_ACTIVE_TRANSACTION = 1192
|
||||
UNKNOWN_SYSTEM_VARIABLE = 1193
|
||||
CRASHED_ON_USAGE = 1194
|
||||
CRASHED_ON_REPAIR = 1195
|
||||
WARNING_NOT_COMPLETE_ROLLBACK = 1196
|
||||
TRANS_CACHE_FULL = 1197
|
||||
SLAVE_NOT_RUNNING = 1199
|
||||
BAD_SLAVE = 1200
|
||||
MASTER_INFO = 1201
|
||||
SLAVE_THREAD = 1202
|
||||
TOO_MANY_USER_CONNECTIONS = 1203
|
||||
SET_CONSTANTS_ONLY = 1204
|
||||
LOCK_WAIT_TIMEOUT = 1205
|
||||
LOCK_TABLE_FULL = 1206
|
||||
READ_ONLY_TRANSACTION = 1207
|
||||
WRONG_ARGUMENTS = 1210
|
||||
NO_PERMISSION_TO_CREATE_USER = 1211
|
||||
LOCK_DEADLOCK = 1213
|
||||
TABLE_CANT_HANDLE_FT = 1214
|
||||
CANNOT_ADD_FOREIGN = 1215
|
||||
NO_REFERENCED_ROW = 1216
|
||||
ROW_IS_REFERENCED = 1217
|
||||
CONNECT_TO_MASTER = 1218
|
||||
ERROR_WHEN_EXECUTING_COMMAND = 1220
|
||||
WRONG_USAGE = 1221
|
||||
WRONG_NUMBER_OF_COLUMNS_IN_SELECT = 1222
|
||||
CANT_UPDATE_WITH_READLOCK = 1223
|
||||
MIXING_NOT_ALLOWED = 1224
|
||||
DUP_ARGUMENT = 1225
|
||||
USER_LIMIT_REACHED = 1226
|
||||
SPECIFIC_ACCESS_DENIED_ERROR = 1227
|
||||
LOCAL_VARIABLE = 1228
|
||||
GLOBAL_VARIABLE = 1229
|
||||
NO_DEFAULT = 1230
|
||||
WRONG_VALUE_FOR_VAR = 1231
|
||||
WRONG_TYPE_FOR_VAR = 1232
|
||||
VAR_CANT_BE_READ = 1233
|
||||
CANT_USE_OPTION_HERE = 1234
|
||||
NOT_SUPPORTED_YET = 1235
|
||||
MASTER_FATAL_ERROR_READING_BINLOG = 1236
|
||||
SLAVE_IGNORED_TABLE = 1237
|
||||
INCORRECT_GLOBAL_LOCAL_VAR = 1238
|
||||
WRONG_FK_DEF = 1239
|
||||
KEY_REF_DO_NOT_MATCH_TABLE_REF = 1240
|
||||
OPERAND_COLUMNS = 1241
|
||||
SUBQUERY_NO_1_ROW = 1242
|
||||
UNKNOWN_STMT_HANDLER = 1243
|
||||
CORRUPT_HELP_DB = 1244
|
||||
AUTO_CONVERT = 1246
|
||||
ILLEGAL_REFERENCE = 1247
|
||||
DERIVED_MUST_HAVE_ALIAS = 1248
|
||||
SELECT_REDUCED = 1249
|
||||
TABLENAME_NOT_ALLOWED_HERE = 1250
|
||||
NOT_SUPPORTED_AUTH_MODE = 1251
|
||||
SPATIAL_CANT_HAVE_NULL = 1252
|
||||
COLLATION_CHARSET_MISMATCH = 1253
|
||||
TOO_BIG_FOR_UNCOMPRESS = 1256
|
||||
ZLIB_Z_MEM_ERROR = 1257
|
||||
ZLIB_Z_BUF_ERROR = 1258
|
||||
ZLIB_Z_DATA_ERROR = 1259
|
||||
CUT_VALUE_GROUP_CONCAT = 1260
|
||||
WARN_TOO_FEW_RECORDS = 1261
|
||||
WARN_TOO_MANY_RECORDS = 1262
|
||||
WARN_NULL_TO_NOTNULL = 1263
|
||||
WARN_DATA_OUT_OF_RANGE = 1264
|
||||
WARN_DATA_TRUNCATED = 1265
|
||||
WARN_USING_OTHER_HANDLER = 1266
|
||||
CANT_AGGREGATE_2COLLATIONS = 1267
|
||||
REVOKE_GRANTS = 1269
|
||||
CANT_AGGREGATE_3COLLATIONS = 1270
|
||||
CANT_AGGREGATE_NCOLLATIONS = 1271
|
||||
VARIABLE_IS_NOT_STRUCT = 1272
|
||||
UNKNOWN_COLLATION = 1273
|
||||
SLAVE_IGNORED_SSL_PARAMS = 1274
|
||||
SERVER_IS_IN_SECURE_AUTH_MODE = 1275
|
||||
WARN_FIELD_RESOLVED = 1276
|
||||
BAD_SLAVE_UNTIL_COND = 1277
|
||||
MISSING_SKIP_SLAVE = 1278
|
||||
UNTIL_COND_IGNORED = 1279
|
||||
WRONG_NAME_FOR_INDEX = 1280
|
||||
WRONG_NAME_FOR_CATALOG = 1281
|
||||
BAD_FT_COLUMN = 1283
|
||||
UNKNOWN_KEY_CACHE = 1284
|
||||
WARN_HOSTNAME_WONT_WORK = 1285
|
||||
UNKNOWN_STORAGE_ENGINE = 1286
|
||||
WARN_DEPRECATED_SYNTAX = 1287
|
||||
NON_UPDATABLE_TABLE = 1288
|
||||
FEATURE_DISABLED = 1289
|
||||
OPTION_PREVENTS_STATEMENT = 1290
|
||||
DUPLICATED_VALUE_IN_TYPE = 1291
|
||||
TRUNCATED_WRONG_VALUE = 1292
|
||||
INVALID_ON_UPDATE = 1294
|
||||
UNSUPPORTED_PS = 1295
|
||||
GET_ERRMSG = 1296
|
||||
GET_TEMPORARY_ERRMSG = 1297
|
||||
UNKNOWN_TIME_ZONE = 1298
|
||||
WARN_INVALID_TIMESTAMP = 1299
|
||||
INVALID_CHARACTER_STRING = 1300
|
||||
WARN_ALLOWED_PACKET_OVERFLOWED = 1301
|
||||
CONFLICTING_DECLARATIONS = 1302
|
||||
SP_NO_RECURSIVE_CREATE = 1303
|
||||
SP_ALREADY_EXISTS = 1304
|
||||
SP_DOES_NOT_EXIST = 1305
|
||||
SP_DROP_FAILED = 1306
|
||||
SP_STORE_FAILED = 1307
|
||||
SP_LILABEL_MISMATCH = 1308
|
||||
SP_LABEL_REDEFINE = 1309
|
||||
SP_LABEL_MISMATCH = 1310
|
||||
SP_UNINIT_VAR = 1311
|
||||
SP_BADSELECT = 1312
|
||||
SP_BADRETURN = 1313
|
||||
SP_BADSTATEMENT = 1314
|
||||
UPDATE_LOG_DEPRECATED_IGNORED = 1315
|
||||
UPDATE_LOG_DEPRECATED_TRANSLATED = 1316
|
||||
QUERY_INTERRUPTED = 1317
|
||||
SP_WRONG_NO_OF_ARGS = 1318
|
||||
SP_COND_MISMATCH = 1319
|
||||
SP_NORETURN = 1320
|
||||
SP_NORETURNEND = 1321
|
||||
SP_BAD_CURSOR_QUERY = 1322
|
||||
SP_BAD_CURSOR_SELECT = 1323
|
||||
SP_CURSOR_MISMATCH = 1324
|
||||
SP_CURSOR_ALREADY_OPEN = 1325
|
||||
SP_CURSOR_NOT_OPEN = 1326
|
||||
SP_UNDECLARED_VAR = 1327
|
||||
SP_WRONG_NO_OF_FETCH_ARGS = 1328
|
||||
SP_FETCH_NO_DATA = 1329
|
||||
SP_DUP_PARAM = 1330
|
||||
SP_DUP_VAR = 1331
|
||||
SP_DUP_COND = 1332
|
||||
SP_DUP_CURS = 1333
|
||||
SP_CANT_ALTER = 1334
|
||||
SP_SUBSELECT_NYI = 1335
|
||||
STMT_NOT_ALLOWED_IN_SF_OR_TRG = 1336
|
||||
SP_VARCOND_AFTER_CURSHNDLR = 1337
|
||||
SP_CURSOR_AFTER_HANDLER = 1338
|
||||
SP_CASE_NOT_FOUND = 1339
|
||||
FPARSER_TOO_BIG_FILE = 1340
|
||||
FPARSER_BAD_HEADER = 1341
|
||||
FPARSER_EOF_IN_COMMENT = 1342
|
||||
FPARSER_ERROR_IN_PARAMETER = 1343
|
||||
FPARSER_EOF_IN_UNKNOWN_PARAMETER = 1344
|
||||
VIEW_NO_EXPLAIN = 1345
|
||||
WRONG_OBJECT = 1347
|
||||
NONUPDATEABLE_COLUMN = 1348
|
||||
VIEW_SELECT_CLAUSE = 1350
|
||||
VIEW_SELECT_VARIABLE = 1351
|
||||
VIEW_SELECT_TMPTABLE = 1352
|
||||
VIEW_WRONG_LIST = 1353
|
||||
WARN_VIEW_MERGE = 1354
|
||||
WARN_VIEW_WITHOUT_KEY = 1355
|
||||
VIEW_INVALID = 1356
|
||||
SP_NO_DROP_SP = 1357
|
||||
TRG_ALREADY_EXISTS = 1359
|
||||
TRG_DOES_NOT_EXIST = 1360
|
||||
TRG_ON_VIEW_OR_TEMP_TABLE = 1361
|
||||
TRG_CANT_CHANGE_ROW = 1362
|
||||
TRG_NO_SUCH_ROW_IN_TRG = 1363
|
||||
NO_DEFAULT_FOR_FIELD = 1364
|
||||
DIVISION_BY_ZERO = 1365
|
||||
TRUNCATED_WRONG_VALUE_FOR_FIELD = 1366
|
||||
ILLEGAL_VALUE_FOR_TYPE = 1367
|
||||
VIEW_NONUPD_CHECK = 1368
|
||||
VIEW_CHECK_FAILED = 1369
|
||||
PROCACCESS_DENIED_ERROR = 1370
|
||||
RELAY_LOG_FAIL = 1371
|
||||
UNKNOWN_TARGET_BINLOG = 1373
|
||||
IO_ERR_LOG_INDEX_READ = 1374
|
||||
BINLOG_PURGE_PROHIBITED = 1375
|
||||
FSEEK_FAIL = 1376
|
||||
BINLOG_PURGE_FATAL_ERR = 1377
|
||||
LOG_IN_USE = 1378
|
||||
LOG_PURGE_UNKNOWN_ERR = 1379
|
||||
RELAY_LOG_INIT = 1380
|
||||
NO_BINARY_LOGGING = 1381
|
||||
RESERVED_SYNTAX = 1382
|
||||
PS_MANY_PARAM = 1390
|
||||
KEY_PART_0 = 1391
|
||||
VIEW_CHECKSUM = 1392
|
||||
VIEW_MULTIUPDATE = 1393
|
||||
VIEW_NO_INSERT_FIELD_LIST = 1394
|
||||
VIEW_DELETE_MERGE_VIEW = 1395
|
||||
CANNOT_USER = 1396
|
||||
XAER_NOTA = 1397
|
||||
XAER_INVAL = 1398
|
||||
XAER_RMFAIL = 1399
|
||||
XAER_OUTSIDE = 1400
|
||||
XAER_RMERR = 1401
|
||||
XA_RBROLLBACK = 1402
|
||||
NONEXISTING_PROC_GRANT = 1403
|
||||
PROC_AUTO_GRANT_FAIL = 1404
|
||||
PROC_AUTO_REVOKE_FAIL = 1405
|
||||
DATA_TOO_LONG = 1406
|
||||
SP_BAD_SQLSTATE = 1407
|
||||
STARTUP = 1408
|
||||
LOAD_FROM_FIXED_SIZE_ROWS_TO_VAR = 1409
|
||||
CANT_CREATE_USER_WITH_GRANT = 1410
|
||||
WRONG_VALUE_FOR_TYPE = 1411
|
||||
TABLE_DEF_CHANGED = 1412
|
||||
SP_DUP_HANDLER = 1413
|
||||
SP_NOT_VAR_ARG = 1414
|
||||
SP_NO_RETSET = 1415
|
||||
CANT_CREATE_GEOMETRY_OBJECT = 1416
|
||||
BINLOG_UNSAFE_ROUTINE = 1418
|
||||
BINLOG_CREATE_ROUTINE_NEED_SUPER = 1419
|
||||
STMT_HAS_NO_OPEN_CURSOR = 1421
|
||||
COMMIT_NOT_ALLOWED_IN_SF_OR_TRG = 1422
|
||||
NO_DEFAULT_FOR_VIEW_FIELD = 1423
|
||||
SP_NO_RECURSION = 1424
|
||||
TOO_BIG_SCALE = 1425
|
||||
TOO_BIG_PRECISION = 1426
|
||||
M_BIGGER_THAN_D = 1427
|
||||
WRONG_LOCK_OF_SYSTEM_TABLE = 1428
|
||||
CONNECT_TO_FOREIGN_DATA_SOURCE = 1429
|
||||
QUERY_ON_FOREIGN_DATA_SOURCE = 1430
|
||||
FOREIGN_DATA_SOURCE_DOESNT_EXIST = 1431
|
||||
FOREIGN_DATA_STRING_INVALID_CANT_CREATE = 1432
|
||||
FOREIGN_DATA_STRING_INVALID = 1433
|
||||
TRG_IN_WRONG_SCHEMA = 1435
|
||||
STACK_OVERRUN_NEED_MORE = 1436
|
||||
TOO_LONG_BODY = 1437
|
||||
WARN_CANT_DROP_DEFAULT_KEYCACHE = 1438
|
||||
TOO_BIG_DISPLAYWIDTH = 1439
|
||||
XAER_DUPID = 1440
|
||||
DATETIME_FUNCTION_OVERFLOW = 1441
|
||||
CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG = 1442
|
||||
VIEW_PREVENT_UPDATE = 1443
|
||||
PS_NO_RECURSION = 1444
|
||||
SP_CANT_SET_AUTOCOMMIT = 1445
|
||||
VIEW_FRM_NO_USER = 1447
|
||||
VIEW_OTHER_USER = 1448
|
||||
NO_SUCH_USER = 1449
|
||||
FORBID_SCHEMA_CHANGE = 1450
|
||||
ROW_IS_REFERENCED_2 = 1451
|
||||
NO_REFERENCED_ROW_2 = 1452
|
||||
SP_BAD_VAR_SHADOW = 1453
|
||||
TRG_NO_DEFINER = 1454
|
||||
OLD_FILE_FORMAT = 1455
|
||||
SP_RECURSION_LIMIT = 1456
|
||||
SP_WRONG_NAME = 1458
|
||||
TABLE_NEEDS_UPGRADE = 1459
|
||||
SP_NO_AGGREGATE = 1460
|
||||
MAX_PREPARED_STMT_COUNT_REACHED = 1461
|
||||
VIEW_RECURSIVE = 1462
|
||||
NON_GROUPING_FIELD_USED = 1463
|
||||
TABLE_CANT_HANDLE_SPKEYS = 1464
|
||||
NO_TRIGGERS_ON_SYSTEM_SCHEMA = 1465
|
||||
REMOVED_SPACES = 1466
|
||||
AUTOINC_READ_FAILED = 1467
|
||||
USERNAME = 1468
|
||||
HOSTNAME = 1469
|
||||
WRONG_STRING_LENGTH = 1470
|
||||
NON_INSERTABLE_TABLE = 1471
|
||||
ADMIN_WRONG_MRG_TABLE = 1472
|
||||
TOO_HIGH_LEVEL_OF_NESTING_FOR_SELECT = 1473
|
||||
NAME_BECOMES_EMPTY = 1474
|
||||
AMBIGUOUS_FIELD_TERM = 1475
|
||||
FOREIGN_SERVER_EXISTS = 1476
|
||||
FOREIGN_SERVER_DOESNT_EXIST = 1477
|
||||
ILLEGAL_HA_CREATE_OPTION = 1478
|
||||
PARTITION_REQUIRES_VALUES_ERROR = 1479
|
||||
PARTITION_WRONG_VALUES_ERROR = 1480
|
||||
PARTITION_MAXVALUE_ERROR = 1481
|
||||
PARTITION_WRONG_NO_PART_ERROR = 1484
|
||||
PARTITION_WRONG_NO_SUBPART_ERROR = 1485
|
||||
WRONG_EXPR_IN_PARTITION_FUNC_ERROR = 1486
|
||||
FIELD_NOT_FOUND_PART_ERROR = 1488
|
||||
INCONSISTENT_PARTITION_INFO_ERROR = 1490
|
||||
PARTITION_FUNC_NOT_ALLOWED_ERROR = 1491
|
||||
PARTITIONS_MUST_BE_DEFINED_ERROR = 1492
|
||||
RANGE_NOT_INCREASING_ERROR = 1493
|
||||
INCONSISTENT_TYPE_OF_FUNCTIONS_ERROR = 1494
|
||||
MULTIPLE_DEF_CONST_IN_LIST_PART_ERROR = 1495
|
||||
PARTITION_ENTRY_ERROR = 1496
|
||||
MIX_HANDLER_ERROR = 1497
|
||||
PARTITION_NOT_DEFINED_ERROR = 1498
|
||||
TOO_MANY_PARTITIONS_ERROR = 1499
|
||||
SUBPARTITION_ERROR = 1500
|
||||
CANT_CREATE_HANDLER_FILE = 1501
|
||||
BLOB_FIELD_IN_PART_FUNC_ERROR = 1502
|
||||
UNIQUE_KEY_NEED_ALL_FIELDS_IN_PF = 1503
|
||||
NO_PARTS_ERROR = 1504
|
||||
PARTITION_MGMT_ON_NONPARTITIONED = 1505
|
||||
FOREIGN_KEY_ON_PARTITIONED = 1506
|
||||
DROP_PARTITION_NON_EXISTENT = 1507
|
||||
DROP_LAST_PARTITION = 1508
|
||||
COALESCE_ONLY_ON_HASH_PARTITION = 1509
|
||||
REORG_HASH_ONLY_ON_SAME_NO = 1510
|
||||
REORG_NO_PARAM_ERROR = 1511
|
||||
ONLY_ON_RANGE_LIST_PARTITION = 1512
|
||||
ADD_PARTITION_SUBPART_ERROR = 1513
|
||||
ADD_PARTITION_NO_NEW_PARTITION = 1514
|
||||
COALESCE_PARTITION_NO_PARTITION = 1515
|
||||
REORG_PARTITION_NOT_EXIST = 1516
|
||||
SAME_NAME_PARTITION = 1517
|
||||
NO_BINLOG_ERROR = 1518
|
||||
CONSECUTIVE_REORG_PARTITIONS = 1519
|
||||
REORG_OUTSIDE_RANGE = 1520
|
||||
PARTITION_FUNCTION_FAILURE = 1521
|
||||
LIMITED_PART_RANGE = 1523
|
||||
PLUGIN_IS_NOT_LOADED = 1524
|
||||
WRONG_VALUE = 1525
|
||||
NO_PARTITION_FOR_GIVEN_VALUE = 1526
|
||||
FILEGROUP_OPTION_ONLY_ONCE = 1527
|
||||
CREATE_FILEGROUP_FAILED = 1528
|
||||
DROP_FILEGROUP_FAILED = 1529
|
||||
TABLESPACE_AUTO_EXTEND_ERROR = 1530
|
||||
WRONG_SIZE_NUMBER = 1531
|
||||
SIZE_OVERFLOW_ERROR = 1532
|
||||
ALTER_FILEGROUP_FAILED = 1533
|
||||
BINLOG_ROW_LOGGING_FAILED = 1534
|
||||
EVENT_ALREADY_EXISTS = 1537
|
||||
EVENT_DOES_NOT_EXIST = 1539
|
||||
EVENT_INTERVAL_NOT_POSITIVE_OR_TOO_BIG = 1542
|
||||
EVENT_ENDS_BEFORE_STARTS = 1543
|
||||
EVENT_EXEC_TIME_IN_THE_PAST = 1544
|
||||
EVENT_SAME_NAME = 1551
|
||||
DROP_INDEX_FK = 1553
|
||||
WARN_DEPRECATED_SYNTAX_WITH_VER = 1554
|
||||
CANT_LOCK_LOG_TABLE = 1556
|
||||
FOREIGN_DUPLICATE_KEY_OLD_UNUSED = 1557
|
||||
COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE = 1558
|
||||
TEMP_TABLE_PREVENTS_SWITCH_OUT_OF_RBR = 1559
|
||||
STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_FORMAT = 1560
|
||||
PARTITION_NO_TEMPORARY = 1562
|
||||
PARTITION_CONST_DOMAIN_ERROR = 1563
|
||||
PARTITION_FUNCTION_IS_NOT_ALLOWED = 1564
|
||||
NULL_IN_VALUES_LESS_THAN = 1566
|
||||
WRONG_PARTITION_NAME = 1567
|
||||
CANT_CHANGE_TX_CHARACTERISTICS = 1568
|
||||
DUP_ENTRY_AUTOINCREMENT_CASE = 1569
|
||||
EVENT_SET_VAR_ERROR = 1571
|
||||
PARTITION_MERGE_ERROR = 1572
|
||||
BASE64_DECODE_ERROR = 1575
|
||||
EVENT_RECURSION_FORBIDDEN = 1576
|
||||
ONLY_INTEGERS_ALLOWED = 1578
|
||||
UNSUPORTED_LOG_ENGINE = 1579
|
||||
BAD_LOG_STATEMENT = 1580
|
||||
CANT_RENAME_LOG_TABLE = 1581
|
||||
WRONG_PARAMCOUNT_TO_NATIVE_FCT = 1582
|
||||
WRONG_PARAMETERS_TO_NATIVE_FCT = 1583
|
||||
WRONG_PARAMETERS_TO_STORED_FCT = 1584
|
||||
NATIVE_FCT_NAME_COLLISION = 1585
|
||||
DUP_ENTRY_WITH_KEY_NAME = 1586
|
||||
BINLOG_PURGE_EMFILE = 1587
|
||||
EVENT_CANNOT_CREATE_IN_THE_PAST = 1588
|
||||
EVENT_CANNOT_ALTER_IN_THE_PAST = 1589
|
||||
NO_PARTITION_FOR_GIVEN_VALUE_SILENT = 1591
|
||||
BINLOG_UNSAFE_STATEMENT = 1592
|
||||
BINLOG_FATAL_ERROR = 1593
|
||||
BINLOG_LOGGING_IMPOSSIBLE = 1598
|
||||
VIEW_NO_CREATION_CTX = 1599
|
||||
VIEW_INVALID_CREATION_CTX = 1600
|
||||
TRG_CORRUPTED_FILE = 1602
|
||||
TRG_NO_CREATION_CTX = 1603
|
||||
TRG_INVALID_CREATION_CTX = 1604
|
||||
EVENT_INVALID_CREATION_CTX = 1605
|
||||
TRG_CANT_OPEN_TABLE = 1606
|
||||
NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENT = 1609
|
||||
SLAVE_CORRUPT_EVENT = 1610
|
||||
LOG_PURGE_NO_FILE = 1612
|
||||
XA_RBTIMEOUT = 1613
|
||||
XA_RBDEADLOCK = 1614
|
||||
NEED_REPREPARE = 1615
|
||||
WARN_NO_MASTER_INFO = 1617
|
||||
WARN_OPTION_IGNORED = 1618
|
||||
PLUGIN_DELETE_BUILTIN = 1619
|
||||
WARN_PLUGIN_BUSY = 1620
|
||||
VARIABLE_IS_READONLY = 1621
|
||||
WARN_ENGINE_TRANSACTION_ROLLBACK = 1622
|
||||
SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE = 1624
|
||||
NDB_REPLICATION_SCHEMA_ERROR = 1625
|
||||
CONFLICT_FN_PARSE_ERROR = 1626
|
||||
EXCEPTIONS_WRITE_ERROR = 1627
|
||||
TOO_LONG_TABLE_COMMENT = 1628
|
||||
TOO_LONG_FIELD_COMMENT = 1629
|
||||
FUNC_INEXISTENT_NAME_COLLISION = 1630
|
||||
DATABASE_NAME = 1631
|
||||
TABLE_NAME = 1632
|
||||
PARTITION_NAME = 1633
|
||||
SUBPARTITION_NAME = 1634
|
||||
TEMPORARY_NAME = 1635
|
||||
RENAMED_NAME = 1636
|
||||
TOO_MANY_CONCURRENT_TRXS = 1637
|
||||
WARN_NON_ASCII_SEPARATOR_NOT_IMPLEMENTED = 1638
|
||||
DEBUG_SYNC_TIMEOUT = 1639
|
||||
DEBUG_SYNC_HIT_LIMIT = 1640
|
||||
DUP_SIGNAL_SET = 1641
|
||||
SIGNAL_WARN = 1642
|
||||
SIGNAL_NOT_FOUND = 1643
|
||||
SIGNAL_EXCEPTION = 1644
|
||||
RESIGNAL_WITHOUT_ACTIVE_HANDLER = 1645
|
||||
SIGNAL_BAD_CONDITION_TYPE = 1646
|
||||
WARN_COND_ITEM_TRUNCATED = 1647
|
||||
COND_ITEM_TOO_LONG = 1648
|
||||
UNKNOWN_LOCALE = 1649
|
||||
SLAVE_IGNORE_SERVER_IDS = 1650
|
||||
SAME_NAME_PARTITION_FIELD = 1652
|
||||
PARTITION_COLUMN_LIST_ERROR = 1653
|
||||
WRONG_TYPE_COLUMN_VALUE_ERROR = 1654
|
||||
TOO_MANY_PARTITION_FUNC_FIELDS_ERROR = 1655
|
||||
MAXVALUE_IN_VALUES_IN = 1656
|
||||
TOO_MANY_VALUES_ERROR = 1657
|
||||
ROW_SINGLE_PARTITION_FIELD_ERROR = 1658
|
||||
FIELD_TYPE_NOT_ALLOWED_AS_PARTITION_FIELD = 1659
|
||||
PARTITION_FIELDS_TOO_LONG = 1660
|
||||
BINLOG_ROW_ENGINE_AND_STMT_ENGINE = 1661
|
||||
BINLOG_ROW_MODE_AND_STMT_ENGINE = 1662
|
||||
BINLOG_UNSAFE_AND_STMT_ENGINE = 1663
|
||||
BINLOG_ROW_INJECTION_AND_STMT_ENGINE = 1664
|
||||
BINLOG_STMT_MODE_AND_ROW_ENGINE = 1665
|
||||
BINLOG_ROW_INJECTION_AND_STMT_MODE = 1666
|
||||
BINLOG_MULTIPLE_ENGINES_AND_SELF_LOGGING_ENGINE = 1667
|
||||
BINLOG_UNSAFE_LIMIT = 1668
|
||||
BINLOG_UNSAFE_SYSTEM_TABLE = 1670
|
||||
BINLOG_UNSAFE_AUTOINC_COLUMNS = 1671
|
||||
BINLOG_UNSAFE_UDF = 1672
|
||||
BINLOG_UNSAFE_SYSTEM_VARIABLE = 1673
|
||||
BINLOG_UNSAFE_SYSTEM_FUNCTION = 1674
|
||||
BINLOG_UNSAFE_NONTRANS_AFTER_TRANS = 1675
|
||||
MESSAGE_AND_STATEMENT = 1676
|
||||
SLAVE_CANT_CREATE_CONVERSION = 1678
|
||||
INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_FORMAT = 1679
|
||||
PATH_LENGTH = 1680
|
||||
WARN_DEPRECATED_SYNTAX_NO_REPLACEMENT = 1681
|
||||
WRONG_NATIVE_TABLE_STRUCTURE = 1682
|
||||
WRONG_PERFSCHEMA_USAGE = 1683
|
||||
WARN_I_S_SKIPPED_TABLE = 1684
|
||||
INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_DIRECT = 1685
|
||||
STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_DIRECT = 1686
|
||||
SPATIAL_MUST_HAVE_GEOM_COL = 1687
|
||||
TOO_LONG_INDEX_COMMENT = 1688
|
||||
LOCK_ABORTED = 1689
|
||||
DATA_OUT_OF_RANGE = 1690
|
||||
WRONG_SPVAR_TYPE_IN_LIMIT = 1691
|
||||
BINLOG_UNSAFE_MULTIPLE_ENGINES_AND_SELF_LOGGING_ENGINE = 1692
|
||||
BINLOG_UNSAFE_MIXED_STATEMENT = 1693
|
||||
INSIDE_TRANSACTION_PREVENTS_SWITCH_SQL_LOG_BIN = 1694
|
||||
STORED_FUNCTION_PREVENTS_SWITCH_SQL_LOG_BIN = 1695
|
||||
FAILED_READ_FROM_PAR_FILE = 1696
|
||||
VALUES_IS_NOT_INT_TYPE_ERROR = 1697
|
||||
ACCESS_DENIED_NO_PASSWORD_ERROR = 1698
|
||||
SET_PASSWORD_AUTH_PLUGIN = 1699
|
||||
TRUNCATE_ILLEGAL_FK = 1701
|
||||
PLUGIN_IS_PERMANENT = 1702
|
||||
SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MIN = 1703
|
||||
SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MAX = 1704
|
||||
STMT_CACHE_FULL = 1705
|
||||
MULTI_UPDATE_KEY_CONFLICT = 1706
|
||||
TABLE_NEEDS_REBUILD = 1707
|
||||
WARN_OPTION_BELOW_LIMIT = 1708
|
||||
INDEX_COLUMN_TOO_LONG = 1709
|
||||
ERROR_IN_TRIGGER_BODY = 1710
|
||||
ERROR_IN_UNKNOWN_TRIGGER_BODY = 1711
|
||||
INDEX_CORRUPT = 1712
|
||||
UNDO_RECORD_TOO_BIG = 1713
|
||||
BINLOG_UNSAFE_INSERT_IGNORE_SELECT = 1714
|
||||
BINLOG_UNSAFE_INSERT_SELECT_UPDATE = 1715
|
||||
BINLOG_UNSAFE_REPLACE_SELECT = 1716
|
||||
BINLOG_UNSAFE_CREATE_IGNORE_SELECT = 1717
|
||||
BINLOG_UNSAFE_CREATE_REPLACE_SELECT = 1718
|
||||
BINLOG_UNSAFE_UPDATE_IGNORE = 1719
|
||||
PLUGIN_NO_UNINSTALL = 1720
|
||||
PLUGIN_NO_INSTALL = 1721
|
||||
BINLOG_UNSAFE_WRITE_AUTOINC_SELECT = 1722
|
||||
BINLOG_UNSAFE_CREATE_SELECT_AUTOINC = 1723
|
||||
BINLOG_UNSAFE_INSERT_TWO_KEYS = 1724
|
||||
TABLE_IN_FK_CHECK = 1725
|
||||
UNSUPPORTED_ENGINE = 1726
|
||||
BINLOG_UNSAFE_AUTOINC_NOT_FIRST = 1727
|
||||
CANNOT_LOAD_FROM_TABLE_V2 = 1728
|
||||
MASTER_DELAY_VALUE_OUT_OF_RANGE = 1729
|
||||
ONLY_FD_AND_RBR_EVENTS_ALLOWED_IN_BINLOG_STATEMENT = 1730
|
||||
PARTITION_EXCHANGE_DIFFERENT_OPTION = 1731
|
||||
PARTITION_EXCHANGE_PART_TABLE = 1732
|
||||
PARTITION_EXCHANGE_TEMP_TABLE = 1733
|
||||
PARTITION_INSTEAD_OF_SUBPARTITION = 1734
|
||||
UNKNOWN_PARTITION = 1735
|
||||
TABLES_DIFFERENT_METADATA = 1736
|
||||
ROW_DOES_NOT_MATCH_PARTITION = 1737
|
||||
BINLOG_CACHE_SIZE_GREATER_THAN_MAX = 1738
|
||||
WARN_INDEX_NOT_APPLICABLE = 1739
|
||||
PARTITION_EXCHANGE_FOREIGN_KEY = 1740
|
||||
RPL_INFO_DATA_TOO_LONG = 1742
|
||||
BINLOG_STMT_CACHE_SIZE_GREATER_THAN_MAX = 1745
|
||||
CANT_UPDATE_TABLE_IN_CREATE_TABLE_SELECT = 1746
|
||||
PARTITION_CLAUSE_ON_NONPARTITIONED = 1747
|
||||
ROW_DOES_NOT_MATCH_GIVEN_PARTITION_SET = 1748
|
||||
CHANGE_RPL_INFO_REPOSITORY_FAILURE = 1750
|
||||
WARNING_NOT_COMPLETE_ROLLBACK_WITH_CREATED_TEMP_TABLE = 1751
|
||||
WARNING_NOT_COMPLETE_ROLLBACK_WITH_DROPPED_TEMP_TABLE = 1752
|
||||
MTS_FEATURE_IS_NOT_SUPPORTED = 1753
|
||||
MTS_UPDATED_DBS_GREATER_MAX = 1754
|
||||
MTS_CANT_PARALLEL = 1755
|
||||
MTS_INCONSISTENT_DATA = 1756
|
||||
FULLTEXT_NOT_SUPPORTED_WITH_PARTITIONING = 1757
|
||||
DA_INVALID_CONDITION_NUMBER = 1758
|
||||
INSECURE_PLAIN_TEXT = 1759
|
||||
INSECURE_CHANGE_MASTER = 1760
|
||||
FOREIGN_DUPLICATE_KEY_WITH_CHILD_INFO = 1761
|
||||
FOREIGN_DUPLICATE_KEY_WITHOUT_CHILD_INFO = 1762
|
||||
SQLTHREAD_WITH_SECURE_SLAVE = 1763
|
||||
TABLE_HAS_NO_FT = 1764
|
||||
VARIABLE_NOT_SETTABLE_IN_SF_OR_TRIGGER = 1765
|
||||
VARIABLE_NOT_SETTABLE_IN_TRANSACTION = 1766
|
||||
SET_STATEMENT_CANNOT_INVOKE_FUNCTION = 1769
|
||||
GTID_NEXT_CANT_BE_AUTOMATIC_IF_GTID_NEXT_LIST_IS_NON_NULL = 1770
|
||||
MALFORMED_GTID_SET_SPECIFICATION = 1772
|
||||
MALFORMED_GTID_SET_ENCODING = 1773
|
||||
MALFORMED_GTID_SPECIFICATION = 1774
|
||||
GNO_EXHAUSTED = 1775
|
||||
BAD_SLAVE_AUTO_POSITION = 1776
|
||||
AUTO_POSITION_REQUIRES_GTID_MODE_NOT_OFF = 1777
|
||||
CANT_DO_IMPLICIT_COMMIT_IN_TRX_WHEN_GTID_NEXT_IS_SET = 1778
|
||||
GTID_MODE_ON_REQUIRES_ENFORCE_GTID_CONSISTENCY_ON = 1779
|
||||
CANT_SET_GTID_NEXT_TO_GTID_WHEN_GTID_MODE_IS_OFF = 1781
|
||||
CANT_SET_GTID_NEXT_TO_ANONYMOUS_WHEN_GTID_MODE_IS_ON = 1782
|
||||
CANT_SET_GTID_NEXT_LIST_TO_NON_NULL_WHEN_GTID_MODE_IS_OFF = 1783
|
||||
GTID_UNSAFE_NON_TRANSACTIONAL_TABLE = 1785
|
||||
GTID_UNSAFE_CREATE_SELECT = 1786
|
||||
GTID_UNSAFE_CREATE_DROP_TEMPORARY_TABLE_IN_TRANSACTION = 1787
|
||||
GTID_MODE_CAN_ONLY_CHANGE_ONE_STEP_AT_A_TIME = 1788
|
||||
MASTER_HAS_PURGED_REQUIRED_GTIDS = 1789
|
||||
CANT_SET_GTID_NEXT_WHEN_OWNING_GTID = 1790
|
||||
UNKNOWN_EXPLAIN_FORMAT = 1791
|
||||
CANT_EXECUTE_IN_READ_ONLY_TRANSACTION = 1792
|
||||
TOO_LONG_TABLE_PARTITION_COMMENT = 1793
|
||||
SLAVE_CONFIGURATION = 1794
|
||||
INNODB_FT_LIMIT = 1795
|
||||
INNODB_NO_FT_TEMP_TABLE = 1796
|
||||
INNODB_FT_WRONG_DOCID_COLUMN = 1797
|
||||
INNODB_FT_WRONG_DOCID_INDEX = 1798
|
||||
INNODB_ONLINE_LOG_TOO_BIG = 1799
|
||||
UNKNOWN_ALTER_ALGORITHM = 1800
|
||||
UNKNOWN_ALTER_LOCK = 1801
|
||||
MTS_CHANGE_MASTER_CANT_RUN_WITH_GAPS = 1802
|
||||
MTS_RECOVERY_FAILURE = 1803
|
||||
MTS_RESET_WORKERS = 1804
|
||||
COL_COUNT_DOESNT_MATCH_CORRUPTED_V2 = 1805
|
||||
SLAVE_SILENT_RETRY_TRANSACTION = 1806
|
||||
DISCARD_FK_CHECKS_RUNNING = 1807
|
||||
TABLE_SCHEMA_MISMATCH = 1808
|
||||
TABLE_IN_SYSTEM_TABLESPACE = 1809
|
||||
IO_READ_ERROR = 1810
|
||||
IO_WRITE_ERROR = 1811
|
||||
TABLESPACE_MISSING = 1812
|
||||
TABLESPACE_EXISTS = 1813
|
||||
TABLESPACE_DISCARDED = 1814
|
||||
INTERNAL_ERROR = 1815
|
||||
INNODB_IMPORT_ERROR = 1816
|
||||
INNODB_INDEX_CORRUPT = 1817
|
||||
INVALID_YEAR_COLUMN_LENGTH = 1818
|
||||
NOT_VALID_PASSWORD = 1819
|
||||
MUST_CHANGE_PASSWORD = 1820
|
||||
FK_NO_INDEX_CHILD = 1821
|
||||
FK_NO_INDEX_PARENT = 1822
|
||||
FK_FAIL_ADD_SYSTEM = 1823
|
||||
FK_CANNOT_OPEN_PARENT = 1824
|
||||
FK_INCORRECT_OPTION = 1825
|
||||
FK_DUP_NAME = 1826
|
||||
PASSWORD_FORMAT = 1827
|
||||
FK_COLUMN_CANNOT_DROP = 1828
|
||||
FK_COLUMN_CANNOT_DROP_CHILD = 1829
|
||||
FK_COLUMN_NOT_NULL = 1830
|
||||
DUP_INDEX = 1831
|
||||
FK_COLUMN_CANNOT_CHANGE = 1832
|
||||
FK_COLUMN_CANNOT_CHANGE_CHILD = 1833
|
||||
MALFORMED_PACKET = 1835
|
||||
READ_ONLY_MODE = 1836
|
||||
GTID_NEXT_TYPE_UNDEFINED_GTID = 1837
|
||||
VARIABLE_NOT_SETTABLE_IN_SP = 1838
|
||||
CANT_SET_GTID_PURGED_WHEN_GTID_EXECUTED_IS_NOT_EMPTY = 1840
|
||||
CANT_SET_GTID_PURGED_WHEN_OWNED_GTIDS_IS_NOT_EMPTY = 1841
|
||||
GTID_PURGED_WAS_CHANGED = 1842
|
||||
GTID_EXECUTED_WAS_CHANGED = 1843
|
||||
BINLOG_STMT_MODE_AND_NO_REPL_TABLES = 1844
|
||||
ALTER_OPERATION_NOT_SUPPORTED = 1845
|
||||
ALTER_OPERATION_NOT_SUPPORTED_REASON = 1846
|
||||
ALTER_OPERATION_NOT_SUPPORTED_REASON_COPY = 1847
|
||||
ALTER_OPERATION_NOT_SUPPORTED_REASON_PARTITION = 1848
|
||||
ALTER_OPERATION_NOT_SUPPORTED_REASON_FK_RENAME = 1849
|
||||
ALTER_OPERATION_NOT_SUPPORTED_REASON_COLUMN_TYPE = 1850
|
||||
ALTER_OPERATION_NOT_SUPPORTED_REASON_FK_CHECK = 1851
|
||||
ALTER_OPERATION_NOT_SUPPORTED_REASON_NOPK = 1853
|
||||
ALTER_OPERATION_NOT_SUPPORTED_REASON_AUTOINC = 1854
|
||||
ALTER_OPERATION_NOT_SUPPORTED_REASON_HIDDEN_FTS = 1855
|
||||
ALTER_OPERATION_NOT_SUPPORTED_REASON_CHANGE_FTS = 1856
|
||||
ALTER_OPERATION_NOT_SUPPORTED_REASON_FTS = 1857
|
||||
SQL_SLAVE_SKIP_COUNTER_NOT_SETTABLE_IN_GTID_MODE = 1858
|
||||
DUP_UNKNOWN_IN_INDEX = 1859
|
||||
IDENT_CAUSES_TOO_LONG_PATH = 1860
|
||||
ALTER_OPERATION_NOT_SUPPORTED_REASON_NOT_NULL = 1861
|
||||
MUST_CHANGE_PASSWORD_LOGIN = 1862
|
||||
ROW_IN_WRONG_PARTITION = 1863
|
||||
MTS_EVENT_BIGGER_PENDING_JOBS_SIZE_MAX = 1864
|
||||
BINLOG_LOGICAL_CORRUPTION = 1866
|
||||
WARN_PURGE_LOG_IN_USE = 1867
|
||||
WARN_PURGE_LOG_IS_ACTIVE = 1868
|
||||
AUTO_INCREMENT_CONFLICT = 1869
|
||||
WARN_ON_BLOCKHOLE_IN_RBR = 1870
|
||||
SLAVE_MI_INIT_REPOSITORY = 1871
|
||||
SLAVE_RLI_INIT_REPOSITORY = 1872
|
||||
ACCESS_DENIED_CHANGE_USER_ERROR = 1873
|
||||
INNODB_READ_ONLY = 1874
|
||||
STOP_SLAVE_SQL_THREAD_TIMEOUT = 1875
|
||||
STOP_SLAVE_IO_THREAD_TIMEOUT = 1876
|
||||
TABLE_CORRUPT = 1877
|
||||
TEMP_FILE_WRITE_FAILURE = 1878
|
||||
INNODB_FT_AUX_NOT_HEX_ID = 1879
|
||||
OLD_TEMPORALS_UPGRADED = 1880
|
||||
INNODB_FORCED_RECOVERY = 1881
|
||||
AES_INVALID_IV = 1882
|
||||
PLUGIN_CANNOT_BE_UNINSTALLED = 1883
|
||||
GTID_UNSAFE_BINLOG_SPLITTABLE_STATEMENT_AND_ASSIGNED_GTID = 1884
|
||||
SLAVE_HAS_MORE_GTIDS_THAN_MASTER = 1885
|
||||
MISSING_KEY = 1886
|
||||
ERROR_LAST = 1973
|
40
venv/Lib/site-packages/MySQLdb/constants/FIELD_TYPE.py
Normal file
@@ -0,0 +1,40 @@
|
||||
"""MySQL FIELD_TYPE Constants
|
||||
|
||||
These constants represent the various column (field) types that are
|
||||
supported by MySQL.
|
||||
"""
|
||||
|
||||
DECIMAL = 0
|
||||
TINY = 1
|
||||
SHORT = 2
|
||||
LONG = 3
|
||||
FLOAT = 4
|
||||
DOUBLE = 5
|
||||
NULL = 6
|
||||
TIMESTAMP = 7
|
||||
LONGLONG = 8
|
||||
INT24 = 9
|
||||
DATE = 10
|
||||
TIME = 11
|
||||
DATETIME = 12
|
||||
YEAR = 13
|
||||
# NEWDATE = 14 # Internal to MySQL.
|
||||
VARCHAR = 15
|
||||
BIT = 16
|
||||
# TIMESTAMP2 = 17
|
||||
# DATETIME2 = 18
|
||||
# TIME2 = 19
|
||||
JSON = 245
|
||||
NEWDECIMAL = 246
|
||||
ENUM = 247
|
||||
SET = 248
|
||||
TINY_BLOB = 249
|
||||
MEDIUM_BLOB = 250
|
||||
LONG_BLOB = 251
|
||||
BLOB = 252
|
||||
VAR_STRING = 253
|
||||
STRING = 254
|
||||
GEOMETRY = 255
|
||||
|
||||
CHAR = TINY
|
||||
INTERVAL = ENUM
|
23
venv/Lib/site-packages/MySQLdb/constants/FLAG.py
Normal file
@@ -0,0 +1,23 @@
|
||||
"""MySQL FLAG Constants
|
||||
|
||||
These flags are used along with the FIELD_TYPE to indicate various
|
||||
properties of columns in a result set.
|
||||
|
||||
"""
|
||||
|
||||
NOT_NULL = 1
|
||||
PRI_KEY = 2
|
||||
UNIQUE_KEY = 4
|
||||
MULTIPLE_KEY = 8
|
||||
BLOB = 16
|
||||
UNSIGNED = 32
|
||||
ZEROFILL = 64
|
||||
BINARY = 128
|
||||
ENUM = 256
|
||||
AUTO_INCREMENT = 512
|
||||
TIMESTAMP = 1024
|
||||
SET = 2048
|
||||
NUM = 32768
|
||||
PART_KEY = 16384
|
||||
GROUP = 32768
|
||||
UNIQUE = 65536
|
1
venv/Lib/site-packages/MySQLdb/constants/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
__all__ = ["CR", "FIELD_TYPE", "CLIENT", "ER", "FLAG"]
|
139
venv/Lib/site-packages/MySQLdb/converters.py
Normal file
@@ -0,0 +1,139 @@
|
||||
"""MySQLdb type conversion module
|
||||
|
||||
This module handles all the type conversions for MySQL. If the default
|
||||
type conversions aren't what you need, you can make your own. The
|
||||
dictionary conversions maps some kind of type to a conversion function
|
||||
which returns the corresponding value:
|
||||
|
||||
Key: FIELD_TYPE.* (from MySQLdb.constants)
|
||||
|
||||
Conversion function:
|
||||
|
||||
Arguments: string
|
||||
|
||||
Returns: Python object
|
||||
|
||||
Key: Python type object (from types) or class
|
||||
|
||||
Conversion function:
|
||||
|
||||
Arguments: Python object of indicated type or class AND
|
||||
conversion dictionary
|
||||
|
||||
Returns: SQL literal value
|
||||
|
||||
Notes: Most conversion functions can ignore the dictionary, but
|
||||
it is a required parameter. It is necessary for converting
|
||||
things like sequences and instances.
|
||||
|
||||
Don't modify conversions if you can avoid it. Instead, make copies
|
||||
(with the copy() method), modify the copies, and then pass them to
|
||||
MySQL.connect().
|
||||
"""
|
||||
from decimal import Decimal
|
||||
|
||||
from MySQLdb._mysql import string_literal
|
||||
from MySQLdb.constants import FIELD_TYPE, FLAG
|
||||
from MySQLdb.times import (
|
||||
Date,
|
||||
DateTimeType,
|
||||
DateTime2literal,
|
||||
DateTimeDeltaType,
|
||||
DateTimeDelta2literal,
|
||||
DateTime_or_None,
|
||||
TimeDelta_or_None,
|
||||
Date_or_None,
|
||||
)
|
||||
from MySQLdb._exceptions import ProgrammingError
|
||||
|
||||
import array
|
||||
|
||||
NoneType = type(None)
|
||||
|
||||
try:
|
||||
ArrayType = array.ArrayType
|
||||
except AttributeError:
|
||||
ArrayType = array.array
|
||||
|
||||
|
||||
def Bool2Str(s, d):
|
||||
return b"1" if s else b"0"
|
||||
|
||||
|
||||
def Set2Str(s, d):
|
||||
# Only support ascii string. Not tested.
|
||||
return string_literal(",".join(s))
|
||||
|
||||
|
||||
def Thing2Str(s, d):
|
||||
"""Convert something into a string via str()."""
|
||||
return str(s)
|
||||
|
||||
|
||||
def Float2Str(o, d):
|
||||
s = repr(o)
|
||||
if s in ("inf", "nan"):
|
||||
raise ProgrammingError("%s can not be used with MySQL" % s)
|
||||
if "e" not in s:
|
||||
s += "e0"
|
||||
return s
|
||||
|
||||
|
||||
def None2NULL(o, d):
|
||||
"""Convert None to NULL."""
|
||||
return b"NULL"
|
||||
|
||||
|
||||
def Thing2Literal(o, d):
|
||||
"""Convert something into a SQL string literal. If using
|
||||
MySQL-3.23 or newer, string_literal() is a method of the
|
||||
_mysql.MYSQL object, and this function will be overridden with
|
||||
that method when the connection is created."""
|
||||
return string_literal(o)
|
||||
|
||||
|
||||
def Decimal2Literal(o, d):
|
||||
return format(o, "f")
|
||||
|
||||
|
||||
def array2Str(o, d):
|
||||
return Thing2Literal(o.tostring(), d)
|
||||
|
||||
|
||||
# bytes or str regarding to BINARY_FLAG.
|
||||
_bytes_or_str = ((FLAG.BINARY, bytes), (None, str))
|
||||
|
||||
conversions = {
|
||||
int: Thing2Str,
|
||||
float: Float2Str,
|
||||
NoneType: None2NULL,
|
||||
ArrayType: array2Str,
|
||||
bool: Bool2Str,
|
||||
Date: Thing2Literal,
|
||||
DateTimeType: DateTime2literal,
|
||||
DateTimeDeltaType: DateTimeDelta2literal,
|
||||
set: Set2Str,
|
||||
Decimal: Decimal2Literal,
|
||||
FIELD_TYPE.TINY: int,
|
||||
FIELD_TYPE.SHORT: int,
|
||||
FIELD_TYPE.LONG: int,
|
||||
FIELD_TYPE.FLOAT: float,
|
||||
FIELD_TYPE.DOUBLE: float,
|
||||
FIELD_TYPE.DECIMAL: Decimal,
|
||||
FIELD_TYPE.NEWDECIMAL: Decimal,
|
||||
FIELD_TYPE.LONGLONG: int,
|
||||
FIELD_TYPE.INT24: int,
|
||||
FIELD_TYPE.YEAR: int,
|
||||
FIELD_TYPE.TIMESTAMP: DateTime_or_None,
|
||||
FIELD_TYPE.DATETIME: DateTime_or_None,
|
||||
FIELD_TYPE.TIME: TimeDelta_or_None,
|
||||
FIELD_TYPE.DATE: Date_or_None,
|
||||
FIELD_TYPE.TINY_BLOB: bytes,
|
||||
FIELD_TYPE.MEDIUM_BLOB: bytes,
|
||||
FIELD_TYPE.LONG_BLOB: bytes,
|
||||
FIELD_TYPE.BLOB: bytes,
|
||||
FIELD_TYPE.STRING: bytes,
|
||||
FIELD_TYPE.VAR_STRING: bytes,
|
||||
FIELD_TYPE.VARCHAR: bytes,
|
||||
FIELD_TYPE.JSON: bytes,
|
||||
}
|
489
venv/Lib/site-packages/MySQLdb/cursors.py
Normal file
@@ -0,0 +1,489 @@
|
||||
"""MySQLdb Cursors
|
||||
|
||||
This module implements Cursors of various types for MySQLdb. By
|
||||
default, MySQLdb uses the Cursor class.
|
||||
"""
|
||||
import re
|
||||
|
||||
from ._exceptions import ProgrammingError
|
||||
|
||||
|
||||
#: Regular expression for :meth:`Cursor.executemany`.
|
||||
#: executemany only supports simple bulk insert.
|
||||
#: You can use it to load large dataset.
|
||||
RE_INSERT_VALUES = re.compile(
|
||||
"".join(
|
||||
[
|
||||
r"\s*((?:INSERT|REPLACE)\b.+\bVALUES?\s*)",
|
||||
r"(\(\s*(?:%s|%\(.+\)s)\s*(?:,\s*(?:%s|%\(.+\)s)\s*)*\))",
|
||||
r"(\s*(?:ON DUPLICATE.*)?);?\s*\Z",
|
||||
]
|
||||
),
|
||||
re.IGNORECASE | re.DOTALL,
|
||||
)
|
||||
|
||||
|
||||
class BaseCursor:
|
||||
"""A base for Cursor classes. Useful attributes:
|
||||
|
||||
description
|
||||
A tuple of DB API 7-tuples describing the columns in
|
||||
the last executed query; see PEP-249 for details.
|
||||
|
||||
description_flags
|
||||
Tuple of column flags for last query, one entry per column
|
||||
in the result set. Values correspond to those in
|
||||
MySQLdb.constants.FLAG. See MySQL documentation (C API)
|
||||
for more information. Non-standard extension.
|
||||
|
||||
arraysize
|
||||
default number of rows fetchmany() will fetch
|
||||
"""
|
||||
|
||||
#: Max statement size which :meth:`executemany` generates.
|
||||
#:
|
||||
#: Max size of allowed statement is max_allowed_packet - packet_header_size.
|
||||
#: Default value of max_allowed_packet is 1048576.
|
||||
max_stmt_length = 64 * 1024
|
||||
|
||||
from ._exceptions import (
|
||||
MySQLError,
|
||||
Warning,
|
||||
Error,
|
||||
InterfaceError,
|
||||
DatabaseError,
|
||||
DataError,
|
||||
OperationalError,
|
||||
IntegrityError,
|
||||
InternalError,
|
||||
ProgrammingError,
|
||||
NotSupportedError,
|
||||
)
|
||||
|
||||
connection = None
|
||||
|
||||
def __init__(self, connection):
|
||||
self.connection = connection
|
||||
self.description = None
|
||||
self.description_flags = None
|
||||
self.rowcount = -1
|
||||
self.arraysize = 1
|
||||
self._executed = None
|
||||
|
||||
self.lastrowid = None
|
||||
self._result = None
|
||||
self.rownumber = None
|
||||
self._rows = None
|
||||
|
||||
def close(self):
|
||||
"""Close the cursor. No further queries will be possible."""
|
||||
try:
|
||||
if self.connection is None:
|
||||
return
|
||||
while self.nextset():
|
||||
pass
|
||||
finally:
|
||||
self.connection = None
|
||||
self._result = None
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, *exc_info):
|
||||
del exc_info
|
||||
self.close()
|
||||
|
||||
def _escape_args(self, args, conn):
|
||||
encoding = conn.encoding
|
||||
literal = conn.literal
|
||||
|
||||
def ensure_bytes(x):
|
||||
if isinstance(x, str):
|
||||
return x.encode(encoding)
|
||||
elif isinstance(x, tuple):
|
||||
return tuple(map(ensure_bytes, x))
|
||||
elif isinstance(x, list):
|
||||
return list(map(ensure_bytes, x))
|
||||
return x
|
||||
|
||||
if isinstance(args, (tuple, list)):
|
||||
ret = tuple(literal(ensure_bytes(arg)) for arg in args)
|
||||
elif isinstance(args, dict):
|
||||
ret = {
|
||||
ensure_bytes(key): literal(ensure_bytes(val))
|
||||
for (key, val) in args.items()
|
||||
}
|
||||
else:
|
||||
# If it's not a dictionary let's try escaping it anyways.
|
||||
# Worst case it will throw a Value error
|
||||
ret = literal(ensure_bytes(args))
|
||||
|
||||
ensure_bytes = None # break circular reference
|
||||
return ret
|
||||
|
||||
def _check_executed(self):
|
||||
if not self._executed:
|
||||
raise ProgrammingError("execute() first")
|
||||
|
||||
def nextset(self):
|
||||
"""Advance to the next result set.
|
||||
|
||||
Returns None if there are no more result sets.
|
||||
"""
|
||||
if self._executed:
|
||||
self.fetchall()
|
||||
|
||||
db = self._get_db()
|
||||
nr = db.next_result()
|
||||
if nr == -1:
|
||||
return None
|
||||
self._do_get_result(db)
|
||||
self._post_get_result()
|
||||
return 1
|
||||
|
||||
def _do_get_result(self, db):
|
||||
self._result = result = self._get_result()
|
||||
if result is None:
|
||||
self.description = self.description_flags = None
|
||||
else:
|
||||
self.description = result.describe()
|
||||
self.description_flags = result.field_flags()
|
||||
|
||||
self.rowcount = db.affected_rows()
|
||||
self.rownumber = 0
|
||||
self.lastrowid = db.insert_id()
|
||||
|
||||
def _post_get_result(self):
|
||||
pass
|
||||
|
||||
def setinputsizes(self, *args):
|
||||
"""Does nothing, required by DB API."""
|
||||
|
||||
def setoutputsizes(self, *args):
|
||||
"""Does nothing, required by DB API."""
|
||||
|
||||
def _get_db(self):
|
||||
con = self.connection
|
||||
if con is None:
|
||||
raise ProgrammingError("cursor closed")
|
||||
return con
|
||||
|
||||
def execute(self, query, args=None):
|
||||
"""Execute a query.
|
||||
|
||||
query -- string, query to execute on server
|
||||
args -- optional sequence or mapping, parameters to use with query.
|
||||
|
||||
Note: If args is a sequence, then %s must be used as the
|
||||
parameter placeholder in the query. If a mapping is used,
|
||||
%(key)s must be used as the placeholder.
|
||||
|
||||
Returns integer represents rows affected, if any
|
||||
"""
|
||||
while self.nextset():
|
||||
pass
|
||||
db = self._get_db()
|
||||
|
||||
if isinstance(query, str):
|
||||
query = query.encode(db.encoding)
|
||||
|
||||
if args is not None:
|
||||
if isinstance(args, dict):
|
||||
nargs = {}
|
||||
for key, item in args.items():
|
||||
if isinstance(key, str):
|
||||
key = key.encode(db.encoding)
|
||||
nargs[key] = db.literal(item)
|
||||
args = nargs
|
||||
else:
|
||||
args = tuple(map(db.literal, args))
|
||||
try:
|
||||
query = query % args
|
||||
except TypeError as m:
|
||||
raise ProgrammingError(str(m))
|
||||
|
||||
assert isinstance(query, (bytes, bytearray))
|
||||
res = self._query(query)
|
||||
return res
|
||||
|
||||
def executemany(self, query, args):
|
||||
# type: (str, list) -> int
|
||||
"""Execute a multi-row query.
|
||||
|
||||
:param query: query to execute on server
|
||||
:param args: Sequence of sequences or mappings. It is used as parameter.
|
||||
:return: Number of rows affected, if any.
|
||||
|
||||
This method improves performance on multiple-row INSERT and
|
||||
REPLACE. Otherwise it is equivalent to looping over args with
|
||||
execute().
|
||||
"""
|
||||
if not args:
|
||||
return
|
||||
|
||||
m = RE_INSERT_VALUES.match(query)
|
||||
if m:
|
||||
q_prefix = m.group(1) % ()
|
||||
q_values = m.group(2).rstrip()
|
||||
q_postfix = m.group(3) or ""
|
||||
assert q_values[0] == "(" and q_values[-1] == ")"
|
||||
return self._do_execute_many(
|
||||
q_prefix,
|
||||
q_values,
|
||||
q_postfix,
|
||||
args,
|
||||
self.max_stmt_length,
|
||||
self._get_db().encoding,
|
||||
)
|
||||
|
||||
self.rowcount = sum(self.execute(query, arg) for arg in args)
|
||||
return self.rowcount
|
||||
|
||||
def _do_execute_many(
|
||||
self, prefix, values, postfix, args, max_stmt_length, encoding
|
||||
):
|
||||
conn = self._get_db()
|
||||
escape = self._escape_args
|
||||
if isinstance(prefix, str):
|
||||
prefix = prefix.encode(encoding)
|
||||
if isinstance(values, str):
|
||||
values = values.encode(encoding)
|
||||
if isinstance(postfix, str):
|
||||
postfix = postfix.encode(encoding)
|
||||
sql = bytearray(prefix)
|
||||
args = iter(args)
|
||||
v = values % escape(next(args), conn)
|
||||
sql += v
|
||||
rows = 0
|
||||
for arg in args:
|
||||
v = values % escape(arg, conn)
|
||||
if len(sql) + len(v) + len(postfix) + 1 > max_stmt_length:
|
||||
rows += self.execute(sql + postfix)
|
||||
sql = bytearray(prefix)
|
||||
else:
|
||||
sql += b","
|
||||
sql += v
|
||||
rows += self.execute(sql + postfix)
|
||||
self.rowcount = rows
|
||||
return rows
|
||||
|
||||
def callproc(self, procname, args=()):
|
||||
"""Execute stored procedure procname with args
|
||||
|
||||
procname -- string, name of procedure to execute on server
|
||||
|
||||
args -- Sequence of parameters to use with procedure
|
||||
|
||||
Returns the original args.
|
||||
|
||||
Compatibility warning: PEP-249 specifies that any modified
|
||||
parameters must be returned. This is currently impossible
|
||||
as they are only available by storing them in a server
|
||||
variable and then retrieved by a query. Since stored
|
||||
procedures return zero or more result sets, there is no
|
||||
reliable way to get at OUT or INOUT parameters via callproc.
|
||||
The server variables are named @_procname_n, where procname
|
||||
is the parameter above and n is the position of the parameter
|
||||
(from zero). Once all result sets generated by the procedure
|
||||
have been fetched, you can issue a SELECT @_procname_0, ...
|
||||
query using .execute() to get any OUT or INOUT values.
|
||||
|
||||
Compatibility warning: The act of calling a stored procedure
|
||||
itself creates an empty result set. This appears after any
|
||||
result sets generated by the procedure. This is non-standard
|
||||
behavior with respect to the DB-API. Be sure to use nextset()
|
||||
to advance through all result sets; otherwise you may get
|
||||
disconnected.
|
||||
"""
|
||||
db = self._get_db()
|
||||
if isinstance(procname, str):
|
||||
procname = procname.encode(db.encoding)
|
||||
if args:
|
||||
fmt = b"@_" + procname + b"_%d=%s"
|
||||
q = b"SET %s" % b",".join(
|
||||
fmt % (index, db.literal(arg)) for index, arg in enumerate(args)
|
||||
)
|
||||
self._query(q)
|
||||
self.nextset()
|
||||
|
||||
q = b"CALL %s(%s)" % (
|
||||
procname,
|
||||
b",".join([b"@_%s_%d" % (procname, i) for i in range(len(args))]),
|
||||
)
|
||||
self._query(q)
|
||||
return args
|
||||
|
||||
def _query(self, q):
|
||||
db = self._get_db()
|
||||
self._result = None
|
||||
db.query(q)
|
||||
self._do_get_result(db)
|
||||
self._post_get_result()
|
||||
self._executed = q
|
||||
return self.rowcount
|
||||
|
||||
def _fetch_row(self, size=1):
|
||||
if not self._result:
|
||||
return ()
|
||||
return self._result.fetch_row(size, self._fetch_type)
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self.fetchone, None)
|
||||
|
||||
Warning = Warning
|
||||
Error = Error
|
||||
InterfaceError = InterfaceError
|
||||
DatabaseError = DatabaseError
|
||||
DataError = DataError
|
||||
OperationalError = OperationalError
|
||||
IntegrityError = IntegrityError
|
||||
InternalError = InternalError
|
||||
ProgrammingError = ProgrammingError
|
||||
NotSupportedError = NotSupportedError
|
||||
|
||||
|
||||
class CursorStoreResultMixIn:
|
||||
"""This is a MixIn class which causes the entire result set to be
|
||||
stored on the client side, i.e. it uses mysql_store_result(). If the
|
||||
result set can be very large, consider adding a LIMIT clause to your
|
||||
query, or using CursorUseResultMixIn instead."""
|
||||
|
||||
def _get_result(self):
|
||||
return self._get_db().store_result()
|
||||
|
||||
def _post_get_result(self):
|
||||
self._rows = self._fetch_row(0)
|
||||
self._result = None
|
||||
|
||||
def fetchone(self):
|
||||
"""Fetches a single row from the cursor. None indicates that
|
||||
no more rows are available."""
|
||||
self._check_executed()
|
||||
if self.rownumber >= len(self._rows):
|
||||
return None
|
||||
result = self._rows[self.rownumber]
|
||||
self.rownumber = self.rownumber + 1
|
||||
return result
|
||||
|
||||
def fetchmany(self, size=None):
|
||||
"""Fetch up to size rows from the cursor. Result set may be smaller
|
||||
than size. If size is not defined, cursor.arraysize is used."""
|
||||
self._check_executed()
|
||||
end = self.rownumber + (size or self.arraysize)
|
||||
result = self._rows[self.rownumber : end]
|
||||
self.rownumber = min(end, len(self._rows))
|
||||
return result
|
||||
|
||||
def fetchall(self):
|
||||
"""Fetches all available rows from the cursor."""
|
||||
self._check_executed()
|
||||
if self.rownumber:
|
||||
result = self._rows[self.rownumber :]
|
||||
else:
|
||||
result = self._rows
|
||||
self.rownumber = len(self._rows)
|
||||
return result
|
||||
|
||||
def scroll(self, value, mode="relative"):
|
||||
"""Scroll the cursor in the result set to a new position according
|
||||
to mode.
|
||||
|
||||
If mode is 'relative' (default), value is taken as offset to
|
||||
the current position in the result set, if set to 'absolute',
|
||||
value states an absolute target position."""
|
||||
self._check_executed()
|
||||
if mode == "relative":
|
||||
r = self.rownumber + value
|
||||
elif mode == "absolute":
|
||||
r = value
|
||||
else:
|
||||
raise ProgrammingError("unknown scroll mode %s" % repr(mode))
|
||||
if r < 0 or r >= len(self._rows):
|
||||
raise IndexError("out of range")
|
||||
self.rownumber = r
|
||||
|
||||
def __iter__(self):
|
||||
self._check_executed()
|
||||
result = self.rownumber and self._rows[self.rownumber :] or self._rows
|
||||
return iter(result)
|
||||
|
||||
|
||||
class CursorUseResultMixIn:
|
||||
|
||||
"""This is a MixIn class which causes the result set to be stored
|
||||
in the server and sent row-by-row to client side, i.e. it uses
|
||||
mysql_use_result(). You MUST retrieve the entire result set and
|
||||
close() the cursor before additional queries can be performed on
|
||||
the connection."""
|
||||
|
||||
def _get_result(self):
|
||||
return self._get_db().use_result()
|
||||
|
||||
def fetchone(self):
|
||||
"""Fetches a single row from the cursor."""
|
||||
self._check_executed()
|
||||
r = self._fetch_row(1)
|
||||
if not r:
|
||||
return None
|
||||
self.rownumber = self.rownumber + 1
|
||||
return r[0]
|
||||
|
||||
def fetchmany(self, size=None):
|
||||
"""Fetch up to size rows from the cursor. Result set may be smaller
|
||||
than size. If size is not defined, cursor.arraysize is used."""
|
||||
self._check_executed()
|
||||
r = self._fetch_row(size or self.arraysize)
|
||||
self.rownumber = self.rownumber + len(r)
|
||||
return r
|
||||
|
||||
def fetchall(self):
|
||||
"""Fetches all available rows from the cursor."""
|
||||
self._check_executed()
|
||||
r = self._fetch_row(0)
|
||||
self.rownumber = self.rownumber + len(r)
|
||||
return r
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def next(self):
|
||||
row = self.fetchone()
|
||||
if row is None:
|
||||
raise StopIteration
|
||||
return row
|
||||
|
||||
__next__ = next
|
||||
|
||||
|
||||
class CursorTupleRowsMixIn:
|
||||
"""This is a MixIn class that causes all rows to be returned as tuples,
|
||||
which is the standard form required by DB API."""
|
||||
|
||||
_fetch_type = 0
|
||||
|
||||
|
||||
class CursorDictRowsMixIn:
|
||||
"""This is a MixIn class that causes all rows to be returned as
|
||||
dictionaries. This is a non-standard feature."""
|
||||
|
||||
_fetch_type = 1
|
||||
|
||||
|
||||
class Cursor(CursorStoreResultMixIn, CursorTupleRowsMixIn, BaseCursor):
|
||||
"""This is the standard Cursor class that returns rows as tuples
|
||||
and stores the result set in the client."""
|
||||
|
||||
|
||||
class DictCursor(CursorStoreResultMixIn, CursorDictRowsMixIn, BaseCursor):
|
||||
"""This is a Cursor class that returns rows as dictionaries and
|
||||
stores the result set in the client."""
|
||||
|
||||
|
||||
class SSCursor(CursorUseResultMixIn, CursorTupleRowsMixIn, BaseCursor):
|
||||
"""This is a Cursor class that returns rows as tuples and stores
|
||||
the result set in the server."""
|
||||
|
||||
|
||||
class SSDictCursor(CursorUseResultMixIn, CursorDictRowsMixIn, BaseCursor):
|
||||
"""This is a Cursor class that returns rows as dictionaries and
|
||||
stores the result set in the server."""
|
4
venv/Lib/site-packages/MySQLdb/release.py
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
__author__ = "Inada Naoki <songofacandy@gmail.com>"
|
||||
version_info = (2,1,0,'final',0)
|
||||
__version__ = "2.1.0"
|
150
venv/Lib/site-packages/MySQLdb/times.py
Normal file
@@ -0,0 +1,150 @@
|
||||
"""times module
|
||||
|
||||
This module provides some Date and Time classes for dealing with MySQL data.
|
||||
|
||||
Use Python datetime module to handle date and time columns.
|
||||
"""
|
||||
from time import localtime
|
||||
from datetime import date, datetime, time, timedelta
|
||||
from MySQLdb._mysql import string_literal
|
||||
|
||||
Date = date
|
||||
Time = time
|
||||
TimeDelta = timedelta
|
||||
Timestamp = datetime
|
||||
|
||||
DateTimeDeltaType = timedelta
|
||||
DateTimeType = datetime
|
||||
|
||||
|
||||
def DateFromTicks(ticks):
|
||||
"""Convert UNIX ticks into a date instance."""
|
||||
return date(*localtime(ticks)[:3])
|
||||
|
||||
|
||||
def TimeFromTicks(ticks):
|
||||
"""Convert UNIX ticks into a time instance."""
|
||||
return time(*localtime(ticks)[3:6])
|
||||
|
||||
|
||||
def TimestampFromTicks(ticks):
|
||||
"""Convert UNIX ticks into a datetime instance."""
|
||||
return datetime(*localtime(ticks)[:6])
|
||||
|
||||
|
||||
format_TIME = format_DATE = str
|
||||
|
||||
|
||||
def format_TIMEDELTA(v):
|
||||
seconds = int(v.seconds) % 60
|
||||
minutes = int(v.seconds // 60) % 60
|
||||
hours = int(v.seconds // 3600) % 24
|
||||
return "%d %d:%d:%d" % (v.days, hours, minutes, seconds)
|
||||
|
||||
|
||||
def format_TIMESTAMP(d):
|
||||
"""
|
||||
:type d: datetime.datetime
|
||||
"""
|
||||
if d.microsecond:
|
||||
fmt = " ".join(
|
||||
[
|
||||
"{0.year:04}-{0.month:02}-{0.day:02}",
|
||||
"{0.hour:02}:{0.minute:02}:{0.second:02}.{0.microsecond:06}",
|
||||
]
|
||||
)
|
||||
else:
|
||||
fmt = " ".join(
|
||||
[
|
||||
"{0.year:04}-{0.month:02}-{0.day:02}",
|
||||
"{0.hour:02}:{0.minute:02}:{0.second:02}",
|
||||
]
|
||||
)
|
||||
return fmt.format(d)
|
||||
|
||||
|
||||
def DateTime_or_None(s):
|
||||
try:
|
||||
if len(s) < 11:
|
||||
return Date_or_None(s)
|
||||
|
||||
micros = s[20:]
|
||||
|
||||
if len(micros) == 0:
|
||||
# 12:00:00
|
||||
micros = 0
|
||||
elif len(micros) < 7:
|
||||
# 12:00:00.123456
|
||||
micros = int(micros) * 10 ** (6 - len(micros))
|
||||
else:
|
||||
return None
|
||||
|
||||
return datetime(
|
||||
int(s[:4]), # year
|
||||
int(s[5:7]), # month
|
||||
int(s[8:10]), # day
|
||||
int(s[11:13] or 0), # hour
|
||||
int(s[14:16] or 0), # minute
|
||||
int(s[17:19] or 0), # second
|
||||
micros, # microsecond
|
||||
)
|
||||
except ValueError:
|
||||
return None
|
||||
|
||||
|
||||
def TimeDelta_or_None(s):
|
||||
try:
|
||||
h, m, s = s.split(":")
|
||||
if "." in s:
|
||||
s, ms = s.split(".")
|
||||
ms = ms.ljust(6, "0")
|
||||
else:
|
||||
ms = 0
|
||||
if h[0] == "-":
|
||||
negative = True
|
||||
else:
|
||||
negative = False
|
||||
h, m, s, ms = abs(int(h)), int(m), int(s), int(ms)
|
||||
td = timedelta(hours=h, minutes=m, seconds=s, microseconds=ms)
|
||||
if negative:
|
||||
return -td
|
||||
else:
|
||||
return td
|
||||
except ValueError:
|
||||
# unpacking or int/float conversion failed
|
||||
return None
|
||||
|
||||
|
||||
def Time_or_None(s):
|
||||
try:
|
||||
h, m, s = s.split(":")
|
||||
if "." in s:
|
||||
s, ms = s.split(".")
|
||||
ms = ms.ljust(6, "0")
|
||||
else:
|
||||
ms = 0
|
||||
h, m, s, ms = int(h), int(m), int(s), int(ms)
|
||||
return time(hour=h, minute=m, second=s, microsecond=ms)
|
||||
except ValueError:
|
||||
return None
|
||||
|
||||
|
||||
def Date_or_None(s):
|
||||
try:
|
||||
return date(
|
||||
int(s[:4]),
|
||||
int(s[5:7]),
|
||||
int(s[8:10]),
|
||||
) # year # month # day
|
||||
except ValueError:
|
||||
return None
|
||||
|
||||
|
||||
def DateTime2literal(d, c):
|
||||
"""Format a DateTime object as an ISO timestamp."""
|
||||
return string_literal(format_TIMESTAMP(d))
|
||||
|
||||
|
||||
def DateTimeDelta2literal(d, c):
|
||||
"""Format a DateTimeDelta object as a time."""
|
||||
return string_literal(format_TIMEDELTA(d))
|
0
venv/Lib/site-packages/baton/__init__.py
Normal file
46
venv/Lib/site-packages/baton/admin.py
Normal file
@@ -0,0 +1,46 @@
|
||||
from django.contrib import admin
|
||||
from django.contrib.admin.filters import (
|
||||
SimpleListFilter,
|
||||
AllValuesFieldListFilter,
|
||||
ChoicesFieldListFilter,
|
||||
RelatedFieldListFilter,
|
||||
RelatedOnlyFieldListFilter
|
||||
)
|
||||
|
||||
|
||||
class InputFilter(admin.SimpleListFilter):
|
||||
template = 'baton/filters/input_filter.html'
|
||||
|
||||
def lookups(self, request, model_admin):
|
||||
# Dummy, required to show the filter.
|
||||
return ((),)
|
||||
|
||||
def choices(self, changelist):
|
||||
# Grab only the "all" option.
|
||||
all_choice = next(super(InputFilter, self).choices(changelist))
|
||||
all_choice['query_parts'] = (
|
||||
(k, v)
|
||||
for k, v in changelist.get_filters_params().items()
|
||||
if k != self.parameter_name
|
||||
)
|
||||
yield all_choice
|
||||
|
||||
|
||||
class SimpleDropdownFilter(SimpleListFilter):
|
||||
template = 'baton/filters/dropdown_filter.html'
|
||||
|
||||
|
||||
class DropdownFilter(AllValuesFieldListFilter):
|
||||
template = 'baton/filters/dropdown_filter.html'
|
||||
|
||||
|
||||
class ChoicesDropdownFilter(ChoicesFieldListFilter):
|
||||
template = 'baton/filters/dropdown_filter.html'
|
||||
|
||||
|
||||
class RelatedDropdownFilter(RelatedFieldListFilter):
|
||||
template = 'baton/filters/dropdown_filter.html'
|
||||
|
||||
|
||||
class RelatedOnlyDropdownFilter(RelatedOnlyFieldListFilter):
|
||||
template = 'baton/filters/dropdown_filter.html'
|
7
venv/Lib/site-packages/baton/apps.py
Normal file
@@ -0,0 +1,7 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class BatonConfig(AppConfig):
|
||||
name = 'baton'
|
41
venv/Lib/site-packages/baton/config.py
Normal file
@@ -0,0 +1,41 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from django.conf import settings
|
||||
from django.utils.html import mark_safe
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
default_config = {
|
||||
'SITE_TITLE': 'Baton',
|
||||
'SITE_HEADER': '<img src="%sbaton/img/logo.png" />' % settings.STATIC_URL,
|
||||
'INDEX_TITLE': _('Site administration'),
|
||||
'MENU_TITLE': _('Menu'),
|
||||
'SUPPORT_HREF': 'https://github.com/otto-torino/django-baton/issues',
|
||||
'COPYRIGHT': 'copyright © 2020 <a href="https://www.otto.to.it">Otto srl</a>', # noqa
|
||||
'POWERED_BY': '<a href="https://www.otto.to.it">Otto srl</a>',
|
||||
'CONFIRM_UNSAVED_CHANGES': True,
|
||||
'SHOW_MULTIPART_UPLOADING': True,
|
||||
'ENABLE_IMAGES_PREVIEW': True,
|
||||
'COLLAPSABLE_USER_AREA': False,
|
||||
'CHANGELIST_FILTERS_IN_MODAL': False,
|
||||
'CHANGELIST_FILTERS_ALWAYS_OPEN': False,
|
||||
'CHANGELIST_FILTERS_FORM': False,
|
||||
'MENU_ALWAYS_COLLAPSED': False,
|
||||
'MESSAGES_TOASTS': False,
|
||||
'GRAVATAR_DEFAULT_IMG': 'retro',
|
||||
'LOGIN_SPLASH': None,
|
||||
'SEARCH_FIELD': None,
|
||||
}
|
||||
|
||||
|
||||
def get_config(key):
|
||||
safe = ['SITE_HEADER', 'COPYRIGHT', 'POWERED_BY', ]
|
||||
user_settings = getattr(settings, 'BATON', None)
|
||||
|
||||
if user_settings is None:
|
||||
value = default_config.get(key, None)
|
||||
else:
|
||||
value = user_settings.get(key, default_config.get(key, None))
|
||||
|
||||
if key in safe:
|
||||
return mark_safe(value)
|
||||
|
||||
return value
|
BIN
venv/Lib/site-packages/baton/locale/it/LC_MESSAGES/django.mo
Normal file
134
venv/Lib/site-packages/baton/locale/it/LC_MESSAGES/django.po
Normal file
@@ -0,0 +1,134 @@
|
||||
# baton translations
|
||||
# Copyright (C) 2017 Otto srl
|
||||
# This file is distributed under the same license as the django-baton package.
|
||||
# Stefano Contini <abidibo@gmail.com>, 2017.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 0.1.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-12-03 16:44+0100\n"
|
||||
"PO-Revision-Date: 2017-02-12 17:00+0100\n"
|
||||
"Last-Translator: Stefano Contini <abidibo@gmail.com>\n"
|
||||
"Language-Team: it <LL@li.org>\n"
|
||||
"Language: it\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: config.py:9
|
||||
msgid "Site administration"
|
||||
msgstr "Amministrazione sito"
|
||||
|
||||
#: config.py:10
|
||||
msgid "Menu"
|
||||
msgstr "Menu"
|
||||
|
||||
#: templates/admin/base_site.html:5
|
||||
msgid "Django site admin"
|
||||
msgstr "Amministrazione sito django"
|
||||
|
||||
#: templates/admin/base_site.html:44
|
||||
msgid "Django administration"
|
||||
msgstr "Amministrazione django"
|
||||
|
||||
#: templates/admin/base_site.html:63
|
||||
msgid "close"
|
||||
msgstr "chiudi"
|
||||
|
||||
#: templates/admin/base_site.html:64
|
||||
msgid "save"
|
||||
msgstr "salva"
|
||||
|
||||
#: templates/admin/filer/folder/directory_listing.html:4
|
||||
msgid "Folders"
|
||||
msgstr "Cartelle"
|
||||
|
||||
#: templates/baton/analytics.html:24
|
||||
msgid "last 15 days"
|
||||
msgstr "ultimi 15 giorni"
|
||||
|
||||
#: templates/baton/analytics.html:25
|
||||
msgid "last month"
|
||||
msgstr "ultimo mese"
|
||||
|
||||
#: templates/baton/analytics.html:26
|
||||
msgid "last three months"
|
||||
msgstr "ultimi tre mesi"
|
||||
|
||||
#: templates/baton/analytics.html:27
|
||||
msgid "last year"
|
||||
msgstr "ultimo anno"
|
||||
|
||||
#: templates/baton/analytics.html:34
|
||||
msgid "Traffic"
|
||||
msgstr "Traffico"
|
||||
|
||||
#: templates/baton/analytics.html:35
|
||||
msgid "Sessions and Users"
|
||||
msgstr "Sessioni e utenti"
|
||||
|
||||
#: templates/baton/analytics.html:41
|
||||
msgid "Popular"
|
||||
msgstr "Popolare"
|
||||
|
||||
#: templates/baton/analytics.html:42
|
||||
msgid "Page views"
|
||||
msgstr "Visualizzazioni di pagina"
|
||||
|
||||
#: templates/baton/analytics.html:50
|
||||
msgid "Browsers"
|
||||
msgstr "Browser"
|
||||
|
||||
#: templates/baton/analytics.html:51
|
||||
msgid "Top used"
|
||||
msgstr "Più utilizzati"
|
||||
|
||||
#: templates/baton/analytics.html:57
|
||||
msgid "Acquisition"
|
||||
msgstr "Acquisizione"
|
||||
|
||||
#: templates/baton/analytics.html:58
|
||||
msgid "Referral Traffic"
|
||||
msgstr "Traffico da ricerca"
|
||||
|
||||
#: templates/baton/analytics.html:66
|
||||
msgid "Audience"
|
||||
msgstr "Visitatori"
|
||||
|
||||
#: templates/baton/analytics.html:67
|
||||
msgid "Countries"
|
||||
msgstr "Paesi"
|
||||
|
||||
#: templates/baton/analytics.html:73
|
||||
msgid "Social"
|
||||
msgstr "Social"
|
||||
|
||||
#: templates/baton/analytics.html:74
|
||||
msgid "Interactions"
|
||||
msgstr "Interazioni"
|
||||
|
||||
#: templates/baton/filters/dropdown_filter.html:3
|
||||
#: templates/baton/filters/input_filter.html:3
|
||||
#, python-format
|
||||
msgid " By %(filter_title)s "
|
||||
msgstr "Per %(filter_title)s"
|
||||
|
||||
#: templates/baton/filters/input_filter.html:16
|
||||
msgid "type and press enter..."
|
||||
msgstr "digita e premi invio..."
|
||||
|
||||
#: templates/baton/filters/input_filter.html:20
|
||||
msgid "Remove"
|
||||
msgstr "Rimuovi"
|
||||
|
||||
#: templates/baton/footer.html:7
|
||||
msgid "Support"
|
||||
msgstr "Supporto"
|
||||
|
||||
#: templates/baton/footer.html:18
|
||||
#, python-format
|
||||
msgid "Developed by %(powered_by)s"
|
||||
msgstr "Sviluppato da %(powered_by)s"
|
0
venv/Lib/site-packages/baton/models.py
Normal file
52
venv/Lib/site-packages/baton/static/admin/css/base.css
Normal file
@@ -0,0 +1,52 @@
|
||||
/* VARIABLE DEFINITIONS */
|
||||
:root {
|
||||
--primary: #79aec8;
|
||||
--secondary: #417690;
|
||||
--accent: #f5dd5d;
|
||||
--primary-fg: #fff;
|
||||
|
||||
--body-fg: #333;
|
||||
--body-bg: #fff;
|
||||
--body-quiet-color: #666;
|
||||
--body-loud-color: #000;
|
||||
|
||||
--header-color: #ffc;
|
||||
--header-branding-color: var(--accent);
|
||||
--header-bg: var(--secondary);
|
||||
--header-link-color: var(--primary-fg);
|
||||
|
||||
--breadcrumbs-fg: #c4dce8;
|
||||
--breadcrumbs-link-fg: var(--body-bg);
|
||||
--breadcrumbs-bg: var(--primary);
|
||||
|
||||
--link-fg: #447e9b;
|
||||
--link-hover-color: #036;
|
||||
--link-selected-fg: #5b80b2;
|
||||
|
||||
--hairline-color: #e8e8e8;
|
||||
--border-color: #ccc;
|
||||
|
||||
--error-fg: #ba2121;
|
||||
|
||||
--message-success-bg: #dfd;
|
||||
--message-warning-bg: #ffc;
|
||||
--message-error-bg: #ffefef;
|
||||
|
||||
--darkened-bg: #f8f8f8; /* A bit darker than --body-bg */
|
||||
--selected-bg: #e4e4e4; /* E.g. selected table cells */
|
||||
--selected-row: #ffc;
|
||||
|
||||
--button-fg: #fff;
|
||||
--button-bg: var(--primary);
|
||||
--button-hover-bg: #609ab6;
|
||||
--default-button-bg: var(--secondary);
|
||||
--default-button-hover-bg: #205067;
|
||||
--close-button-bg: #888; /* Previously #bbb, contrast 1.92 */
|
||||
--close-button-hover-bg: #747474;
|
||||
--delete-button-bg: #ba2121;
|
||||
--delete-button-hover-bg: #a41515;
|
||||
|
||||
--object-tools-fg: var(--button-fg);
|
||||
--object-tools-bg: var(--close-button-bg);
|
||||
--object-tools-hover-bg: var(--close-button-hover-bg);
|
||||
}
|
@@ -0,0 +1 @@
|
||||
/* empty */
|
@@ -0,0 +1 @@
|
||||
/* empty */
|
1
venv/Lib/site-packages/baton/static/admin/css/forms.css
Normal file
@@ -0,0 +1 @@
|
||||
/* empty */
|
@@ -0,0 +1 @@
|
||||
/* empty */
|
3
venv/Lib/site-packages/baton/static/baton/app/.babelrc
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"presets": ["@babel/preset-env"]
|
||||
}
|
@@ -0,0 +1,2 @@
|
||||
node_modules/**
|
||||
dist/**
|
24
venv/Lib/site-packages/baton/static/baton/app/.eslintrc
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"parser" : "babel-eslint",
|
||||
"extends" : [
|
||||
"standard"
|
||||
],
|
||||
"plugins" : [
|
||||
"flow-vars"
|
||||
],
|
||||
"env" : {
|
||||
"browser" : true
|
||||
},
|
||||
"globals" : {
|
||||
"Baton": {},
|
||||
"jQuery": {},
|
||||
"$": {},
|
||||
},
|
||||
"rules": {
|
||||
"semi" : [2, "never"],
|
||||
"max-len": [2, 120, 2],
|
||||
"comma-dangle": [2, "only-multiline"],
|
||||
"flow-vars/define-flow-type": 1,
|
||||
"flow-vars/use-flow-type": 1
|
||||
}
|
||||
}
|
13
venv/Lib/site-packages/baton/static/baton/app/.tern-project
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"libs": [
|
||||
"browser",
|
||||
"ecma5",
|
||||
"ecma6"
|
||||
],
|
||||
"plugins": {
|
||||
"node": { },
|
||||
"modules": { },
|
||||
"complete_strings": {},
|
||||
"es_modules": {}
|
||||
}
|
||||
}
|
BIN
venv/Lib/site-packages/baton/static/baton/app/dist/07c3313b24f7b1ca85ee.ttf
vendored
Normal file
5034
venv/Lib/site-packages/baton/static/baton/app/dist/13de59f1a36b6cb4bca0.svg
vendored
Normal file
After Width: | Height: | Size: 898 KiB |
3
venv/Lib/site-packages/baton/static/baton/app/dist/1d5b13020cf1d7efde67.svg
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="15" height="15" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="#555555" d="M1216 832q0-185-131.5-316.5t-316.5-131.5-316.5 131.5-131.5 316.5 131.5 316.5 316.5 131.5 316.5-131.5 131.5-316.5zm512 832q0 52-38 90t-90 38q-54 0-90-38l-343-342q-179 124-399 124-143 0-273.5-55.5t-225-150-150-225-55.5-273.5 55.5-273.5 150-225 225-150 273.5-55.5 273.5 55.5 225 150 150 225 55.5 273.5q0 220-124 399l343 343q37 37 37 90z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 458 B |
3717
venv/Lib/site-packages/baton/static/baton/app/dist/216edb96b562c79adc09.svg
vendored
Normal file
After Width: | Height: | Size: 730 KiB |
BIN
venv/Lib/site-packages/baton/static/baton/app/dist/28b74339da09e9f659af.ttf
vendored
Normal file
BIN
venv/Lib/site-packages/baton/static/baton/app/dist/329a95a9172fdb2cccb4.woff
vendored
Normal file
34
venv/Lib/site-packages/baton/static/baton/app/dist/62397fb22f9cf321cfcd.svg
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
<svg width="16" height="192" viewBox="0 0 1792 21504" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs>
|
||||
<g id="up">
|
||||
<path d="M1412 895q0-27-18-45l-362-362-91-91q-18-18-45-18t-45 18l-91 91-362 362q-18 18-18 45t18 45l91 91q18 18 45 18t45-18l189-189v502q0 26 19 45t45 19h128q26 0 45-19t19-45v-502l189 189q19 19 45 19t45-19l91-91q18-18 18-45zm252 1q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/>
|
||||
</g>
|
||||
<g id="down">
|
||||
<path d="M1412 897q0-27-18-45l-91-91q-18-18-45-18t-45 18l-189 189v-502q0-26-19-45t-45-19h-128q-26 0-45 19t-19 45v502l-189-189q-19-19-45-19t-45 19l-91 91q-18 18-18 45t18 45l362 362 91 91q18 18 45 18t45-18l91-91 362-362q18-18 18-45zm252-1q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/>
|
||||
</g>
|
||||
<g id="left">
|
||||
<path d="M1408 960v-128q0-26-19-45t-45-19h-502l189-189q19-19 19-45t-19-45l-91-91q-18-18-45-18t-45 18l-362 362-91 91q-18 18-18 45t18 45l91 91 362 362q18 18 45 18t45-18l91-91q18-18 18-45t-18-45l-189-189h502q26 0 45-19t19-45zm256-64q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/>
|
||||
</g>
|
||||
<g id="right">
|
||||
<path d="M1413 896q0-27-18-45l-91-91-362-362q-18-18-45-18t-45 18l-91 91q-18 18-18 45t18 45l189 189h-502q-26 0-45 19t-19 45v128q0 26 19 45t45 19h502l-189 189q-19 19-19 45t19 45l91 91q18 18 45 18t45-18l362-362 91-91q18-18 18-45zm251 0q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/>
|
||||
</g>
|
||||
<g id="clearall">
|
||||
<path transform="translate(336, 336) scale(0.75)" d="M1037 1395l102-102q19-19 19-45t-19-45l-307-307 307-307q19-19 19-45t-19-45l-102-102q-19-19-45-19t-45 19l-454 454q-19 19-19 45t19 45l454 454q19 19 45 19t45-19zm627-499q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/>
|
||||
</g>
|
||||
<g id="chooseall">
|
||||
<path transform="translate(336, 336) scale(0.75)" d="M845 1395l454-454q19-19 19-45t-19-45l-454-454q-19-19-45-19t-45 19l-102 102q-19 19-19 45t19 45l307 307-307 307q-19 19-19 45t19 45l102 102q19 19 45 19t45-19zm819-499q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/>
|
||||
</g>
|
||||
</defs>
|
||||
<use xlink:href="#up" x="0" y="0" fill="#666666" />
|
||||
<use xlink:href="#up" x="0" y="1792" fill="#447e9b" />
|
||||
<use xlink:href="#down" x="0" y="3584" fill="#666666" />
|
||||
<use xlink:href="#down" x="0" y="5376" fill="#447e9b" />
|
||||
<use xlink:href="#left" x="0" y="7168" fill="#666666" />
|
||||
<use xlink:href="#left" x="0" y="8960" fill="#447e9b" />
|
||||
<use xlink:href="#right" x="0" y="10752" fill="#666666" />
|
||||
<use xlink:href="#right" x="0" y="12544" fill="#447e9b" />
|
||||
<use xlink:href="#clearall" x="0" y="14336" fill="#666666" />
|
||||
<use xlink:href="#clearall" x="0" y="16128" fill="#447e9b" />
|
||||
<use xlink:href="#chooseall" x="0" y="17920" fill="#666666" />
|
||||
<use xlink:href="#chooseall" x="0" y="19712" fill="#447e9b" />
|
||||
</svg>
|
After Width: | Height: | Size: 3.2 KiB |
19
venv/Lib/site-packages/baton/static/baton/app/dist/7fd18804f2abd547c565.svg
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
<svg width="14" height="84" viewBox="0 0 1792 10752" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs>
|
||||
<g id="sort">
|
||||
<path d="M1408 1088q0 26-19 45l-448 448q-19 19-45 19t-45-19l-448-448q-19-19-19-45t19-45 45-19h896q26 0 45 19t19 45zm0-384q0 26-19 45t-45 19h-896q-26 0-45-19t-19-45 19-45l448-448q19-19 45-19t45 19l448 448q19 19 19 45z"/>
|
||||
</g>
|
||||
<g id="ascending">
|
||||
<path d="M1408 1216q0 26-19 45t-45 19h-896q-26 0-45-19t-19-45 19-45l448-448q19-19 45-19t45 19l448 448q19 19 19 45z"/>
|
||||
</g>
|
||||
<g id="descending">
|
||||
<path d="M1408 704q0 26-19 45l-448 448q-19 19-45 19t-45-19l-448-448q-19-19-19-45t19-45 45-19h896q26 0 45 19t19 45z"/>
|
||||
</g>
|
||||
</defs>
|
||||
<use xlink:href="#sort" x="0" y="0" fill="#999999" />
|
||||
<use xlink:href="#sort" x="0" y="1792" fill="#447e9b" />
|
||||
<use xlink:href="#ascending" x="0" y="3584" fill="#999999" />
|
||||
<use xlink:href="#ascending" x="0" y="5376" fill="#447e9b" />
|
||||
<use xlink:href="#descending" x="0" y="7168" fill="#999999" />
|
||||
<use xlink:href="#descending" x="0" y="8960" fill="#447e9b" />
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
14
venv/Lib/site-packages/baton/static/baton/app/dist/820a83e6dbb5ee491646.svg
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
<svg width="15" height="60" viewBox="0 0 1792 7168" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs>
|
||||
<g id="previous">
|
||||
<path d="M1037 1395l102-102q19-19 19-45t-19-45l-307-307 307-307q19-19 19-45t-19-45l-102-102q-19-19-45-19t-45 19l-454 454q-19 19-19 45t19 45l454 454q19 19 45 19t45-19zm627-499q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/>
|
||||
</g>
|
||||
<g id="next">
|
||||
<path d="M845 1395l454-454q19-19 19-45t-19-45l-454-454q-19-19-45-19t-45 19l-102 102q-19 19-19 45t19 45l307 307-307 307q-19 19-19 45t19 45l102 102q19 19 45 19t45-19zm819-499q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/>
|
||||
</g>
|
||||
</defs>
|
||||
<use xlink:href="#previous" x="0" y="0" fill="#333333" />
|
||||
<use xlink:href="#previous" x="0" y="1792" fill="#000000" />
|
||||
<use xlink:href="#next" x="0" y="3584" fill="#333333" />
|
||||
<use xlink:href="#next" x="0" y="5376" fill="#000000" />
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
BIN
venv/Lib/site-packages/baton/static/baton/app/dist/88591a33d733b344a8e3.ttf
vendored
Normal file
BIN
venv/Lib/site-packages/baton/static/baton/app/dist/89a52ae1d02b86d61439.eot
vendored
Normal file
BIN
venv/Lib/site-packages/baton/static/baton/app/dist/9e138496e8f1719c6ebf.ttf
vendored
Normal file
BIN
venv/Lib/site-packages/baton/static/baton/app/dist/ada6e6df937f7e5e8b79.woff2
vendored
Normal file
BIN
venv/Lib/site-packages/baton/static/baton/app/dist/b128f9e98de1bbea51b7.ttf
vendored
Normal file
2
venv/Lib/site-packages/baton/static/baton/app/dist/baton.min.js
vendored
Normal file
30
venv/Lib/site-packages/baton/static/baton/app/dist/baton.min.js.LICENSE.txt
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
/*!
|
||||
* Bootstrap v5.0.1 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Sizzle CSS Selector Engine v2.3.6
|
||||
* https://sizzlejs.com/
|
||||
*
|
||||
* Copyright JS Foundation and other contributors
|
||||
* Released under the MIT license
|
||||
* https://js.foundation/
|
||||
*
|
||||
* Date: 2021-02-16
|
||||
*/
|
||||
|
||||
/*!
|
||||
* jQuery JavaScript Library v3.6.0
|
||||
* https://jquery.com/
|
||||
*
|
||||
* Includes Sizzle.js
|
||||
* https://sizzlejs.com/
|
||||
*
|
||||
* Copyright OpenJS Foundation and other contributors
|
||||
* Released under the MIT license
|
||||
* https://jquery.org/license
|
||||
*
|
||||
* Date: 2021-03-02T17:08Z
|
||||
*/
|
BIN
venv/Lib/site-packages/baton/static/baton/app/dist/c1210e5ebe4344da5083.woff2
vendored
Normal file
BIN
venv/Lib/site-packages/baton/static/baton/app/dist/c6ec080084769a6d8a34.woff
vendored
Normal file
3
venv/Lib/site-packages/baton/static/baton/app/dist/ce6c392454ee4567292d.svg
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="13" height="13" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="#666666" d="M1024 1376v-192q0-14-9-23t-23-9h-192q-14 0-23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23-9t9-23zm256-672q0-88-55.5-163t-138.5-116-170-41q-243 0-371 213-15 24 8 42l132 100q7 6 19 6 16 0 25-12 53-68 86-92 34-24 86-24 48 0 85.5 26t37.5 59q0 38-20 61t-68 45q-63 28-115.5 86.5t-52.5 125.5v36q0 14 9 23t23 9h192q14 0 23-9t9-23q0-19 21.5-49.5t54.5-49.5q32-18 49-28.5t46-35 44.5-48 28-60.5 12.5-81zm384 192q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 655 B |
BIN
venv/Lib/site-packages/baton/static/baton/app/dist/efbd5d20e407bbf85f2b.eot
vendored
Normal file
8897
venv/Lib/site-packages/baton/static/baton/app/package-lock.json
generated
Normal file
54
venv/Lib/site-packages/baton/static/baton/app/package.json
Normal file
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"name": "baton",
|
||||
"version": "2.2.3",
|
||||
"description": "Django Baton App",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"stats": "npx webpack --config ./webpack.prod.js --json > stats.json",
|
||||
"compile": "BATON_REVISION=$(git rev-parse HEAD) npx webpack --config ./webpack.prod.js",
|
||||
"watch": "npx webpack --watch --config ./webpack.dev.js",
|
||||
"dev": "BATON_REVISION=$(git rev-parse HEAD) webpack serve --host 0.0.0.0 --progress --config ./webpack.dev.js",
|
||||
"lint": "./node_modules/eslint/bin/eslint.js ."
|
||||
},
|
||||
"author": "abidibo",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.14.3",
|
||||
"@babel/preset-env": "^7.14.4",
|
||||
"@babel/register": "^7.13.16",
|
||||
"@fortawesome/fontawesome-free": "^5.15.3",
|
||||
"autoprefixer": "^10.2.6",
|
||||
"babel-cli": "^6.26.0",
|
||||
"babel-loader": "^8.2.2",
|
||||
"babel-register": "^6.26.0",
|
||||
"bootstrap": "^5.0.1",
|
||||
"css-loader": "^5.2.6",
|
||||
"file-loader": "^6.2.0",
|
||||
"ini": "^2.0.0",
|
||||
"jquery": "^3.6.0",
|
||||
"js-event-dispatcher": "^0.1.0",
|
||||
"loader": "^2.1.1",
|
||||
"lodash": "^4.17.21",
|
||||
"mini-svg-data-uri": "^1.3.3",
|
||||
"node-sass": "^6.0.0",
|
||||
"postcss-loader": "^5.3.0",
|
||||
"sass": "^1.34.0",
|
||||
"sass-loader": "^11.1.1",
|
||||
"style-loader": "^2.0.0",
|
||||
"url-loader": "^4.1.1",
|
||||
"webpack": "^5.38.1",
|
||||
"webpack-dev-server": "^3.11.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-eslint": "^10.1.0",
|
||||
"eslint": "^7.27.0",
|
||||
"eslint-config-standard": "^16.0.3",
|
||||
"eslint-plugin-babel": "^5.3.1",
|
||||
"eslint-plugin-flow-vars": "^0.5.0",
|
||||
"eslint-plugin-promise": "^5.1.0",
|
||||
"eslint-plugin-standard": "^5.0.0",
|
||||
"webpack-bundle-analyzer": "^4.4.2",
|
||||
"webpack-cli": "^4.7.0",
|
||||
"webpack-merge": "^5.7.3"
|
||||
}
|
||||
}
|
@@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
plugins: [
|
||||
require('autoprefixer')
|
||||
]
|
||||
}
|
6
venv/Lib/site-packages/baton/static/baton/app/src/.vimrc
Normal file
@@ -0,0 +1,6 @@
|
||||
set smarttab
|
||||
set shiftwidth=2
|
||||
set softtabstop=2
|
||||
set tabstop=2
|
||||
set expandtab
|
||||
let syntastic_scss_checkers = ['scss_lint']
|
@@ -0,0 +1,14 @@
|
||||
import $ from 'jquery'
|
||||
|
||||
let ActionResult = {
|
||||
/**
|
||||
* Menu component
|
||||
*
|
||||
* Adds a sidebar menu to the document
|
||||
*/
|
||||
init: function () {
|
||||
$('body').addClass('actionresult')
|
||||
}
|
||||
}
|
||||
|
||||
export default ActionResult
|
@@ -0,0 +1,15 @@
|
||||
import $ from 'jquery'
|
||||
|
||||
let AdminDocs = {
|
||||
/**
|
||||
* Footer component
|
||||
*
|
||||
* Moves the footer inside the main external container
|
||||
*/
|
||||
init: function (opts) {
|
||||
let container = $('<div />', {'class': 'admindocs-body'})
|
||||
container.append($('#content > *:not(h1):not(.breadcrumbs)')).appendTo($('#content'))
|
||||
}
|
||||
}
|
||||
|
||||
export default AdminDocs
|
@@ -0,0 +1,214 @@
|
||||
import Translator from './i18n'
|
||||
|
||||
class Analytics {
|
||||
constructor (gapi, token, viewId, domIds) {
|
||||
this.gapi = gapi
|
||||
this.token = token
|
||||
this.domIds = domIds
|
||||
this.viewId = viewId
|
||||
this.t = new Translator($('html').attr('lang'))
|
||||
}
|
||||
|
||||
init (timedelta) {
|
||||
let self = this
|
||||
this.gapi.analytics.ready(function () { self.run(timedelta) })
|
||||
}
|
||||
|
||||
run (timedelta) {
|
||||
let self = this
|
||||
let gapi = this.gapi
|
||||
|
||||
let spinner = $('<div />').css({
|
||||
textAlign: 'center',
|
||||
padding: '3rem 0',
|
||||
color: '#aaa',
|
||||
}).append($('<i />', {'class': 'fa fa-spinner fa-spin fa-3x fa-fw'}))
|
||||
|
||||
for (let prop in this.domIds) {
|
||||
if (['traffic', 'popular', 'browsers', 'acquisition', 'audience', 'social'].indexOf(prop) !== -1) {
|
||||
$('#' + this.domIds[prop]).append(spinner.clone())
|
||||
}
|
||||
}
|
||||
|
||||
let errorCb = containerId => () => {
|
||||
$('#' + containerId).empty()
|
||||
|
||||
let message = $('<div />').css({
|
||||
textAlign: 'center',
|
||||
padding: '3rem 0',
|
||||
color: '#aaa',
|
||||
}).text(this.t.get('retrieveDataError'))
|
||||
|
||||
$('#' + containerId).append(message)
|
||||
}
|
||||
|
||||
gapi.analytics.ready(function () {
|
||||
/**
|
||||
* Authorize the user with an access token obtained server side.
|
||||
*/
|
||||
gapi.analytics.auth.authorize({
|
||||
'serverAuth': {
|
||||
'access_token': self.token
|
||||
}
|
||||
})
|
||||
/**
|
||||
* Create a new ViewSelector2 instance to be rendered inside of an
|
||||
* element with the id "view-selector-container".
|
||||
*/
|
||||
var viewSelector = new gapi.analytics.ViewSelector({
|
||||
container: self.domIds.viewSelector,
|
||||
})
|
||||
viewSelector.execute()
|
||||
|
||||
let baseQuery = {
|
||||
'ids': 'ga:' + self.viewId,
|
||||
'start-date': timedelta,
|
||||
'end-date': 'yesterday'
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new DataChart instance showing sessions over the past 15 days.
|
||||
*/
|
||||
let dataChart1 = new gapi.analytics.googleCharts.DataChart({
|
||||
query: {
|
||||
...baseQuery,
|
||||
'metrics': 'ga:sessions,ga:users',
|
||||
'dimensions': 'ga:date'
|
||||
},
|
||||
chart: {
|
||||
'container': self.domIds.traffic,
|
||||
'type': 'LINE',
|
||||
'options': {
|
||||
'width': '100%'
|
||||
}
|
||||
}
|
||||
})
|
||||
let trafficTimeout = setTimeout(errorCb(self.domIds.traffic), 20000)
|
||||
dataChart1.on('error', errorCb(self.domIds.traffic))
|
||||
dataChart1.on('success', () => clearTimeout(trafficTimeout))
|
||||
dataChart1.execute()
|
||||
/**
|
||||
* Creates a new DataChart instance showing top 5 most popular pages
|
||||
*/
|
||||
var dataChart2 = new gapi.analytics.googleCharts.DataChart({
|
||||
query: {
|
||||
...baseQuery,
|
||||
'metrics': 'ga:pageviews',
|
||||
'dimensions': 'ga:pagePath',
|
||||
'sort': '-ga:pageviews',
|
||||
'max-results': 7
|
||||
},
|
||||
chart: {
|
||||
'container': self.domIds.popular,
|
||||
'type': 'PIE',
|
||||
'options': {
|
||||
'width': '100%',
|
||||
'pieHole': 4 / 9,
|
||||
}
|
||||
}
|
||||
})
|
||||
let popularTimeout = setTimeout(errorCb(self.domIds.popular), 20000)
|
||||
dataChart2.on('error', errorCb(self.domIds.popular))
|
||||
dataChart2.on('success', () => clearTimeout(popularTimeout))
|
||||
dataChart2.execute()
|
||||
/**
|
||||
* Creates a new DataChart instance showing top borwsers
|
||||
*/
|
||||
var dataChart3 = new gapi.analytics.googleCharts.DataChart({
|
||||
query: {
|
||||
...baseQuery,
|
||||
'metrics': 'ga:sessions',
|
||||
'dimensions': 'ga:browser',
|
||||
'sort': '-ga:sessions',
|
||||
'max-results': 7
|
||||
},
|
||||
chart: {
|
||||
'container': self.domIds.browsers,
|
||||
'type': 'PIE',
|
||||
'options': {
|
||||
'width': '100%',
|
||||
'pieHole': 4 / 9,
|
||||
}
|
||||
}
|
||||
})
|
||||
let browsersTimeout = setTimeout(errorCb(self.domIds.browsers), 20000)
|
||||
dataChart3.on('error', errorCb(self.domIds.browsers))
|
||||
dataChart3.on('success', () => clearTimeout(browsersTimeout))
|
||||
dataChart3.execute()
|
||||
/**
|
||||
* Creates a new DataChart instance showing top referral
|
||||
*/
|
||||
var dataChart4 = new gapi.analytics.googleCharts.DataChart({
|
||||
query: {
|
||||
...baseQuery,
|
||||
'metrics': 'ga:sessions',
|
||||
'dimensions': 'ga:source',
|
||||
'sort': '-ga:sessions',
|
||||
'max-results': 7
|
||||
},
|
||||
chart: {
|
||||
'container': self.domIds.acquisition,
|
||||
'type': 'PIE',
|
||||
'options': {
|
||||
'width': '100%',
|
||||
'pieHole': 4 / 9,
|
||||
}
|
||||
}
|
||||
})
|
||||
let acquisitionTimeout = setTimeout(errorCb(self.domIds.acquisition), 20000)
|
||||
dataChart4.on('error', errorCb(self.domIds.acquisition))
|
||||
dataChart4.on('success', () => clearTimeout(acquisitionTimeout))
|
||||
dataChart4.execute()
|
||||
/**
|
||||
* Creates a new DataChart instance showing top visitors continents
|
||||
*/
|
||||
var dataChart5 = new gapi.analytics.googleCharts.DataChart({
|
||||
query: {
|
||||
...baseQuery,
|
||||
'metrics': 'ga:sessions',
|
||||
'dimensions': 'ga:country',
|
||||
'sort': '-ga:sessions',
|
||||
'max-results': 7
|
||||
},
|
||||
chart: {
|
||||
'container': self.domIds.audience,
|
||||
'type': 'PIE',
|
||||
'options': {
|
||||
'width': '100%',
|
||||
'pieHole': 4 / 9,
|
||||
}
|
||||
}
|
||||
})
|
||||
let audienceTimeout = setTimeout(errorCb(self.domIds.audience), 20000)
|
||||
dataChart5.on('error', errorCb(self.domIds.audience))
|
||||
dataChart5.on('success', () => clearTimeout(audienceTimeout))
|
||||
dataChart5.execute()
|
||||
/**
|
||||
* Creates a new DataChart instance showing social interactions over the past 15 days.
|
||||
*/
|
||||
var dataChart6 = new gapi.analytics.googleCharts.DataChart({
|
||||
query: {
|
||||
...baseQuery,
|
||||
'metrics': 'ga:socialInteractions',
|
||||
'dimensions': 'ga:socialInteractionNetwork',
|
||||
'sort': '-ga:socialInteractions',
|
||||
'max-results': 7
|
||||
},
|
||||
chart: {
|
||||
'container': self.domIds.social,
|
||||
'type': 'PIE',
|
||||
'options': {
|
||||
'width': '100%',
|
||||
'pieHole': 4 / 9,
|
||||
}
|
||||
}
|
||||
})
|
||||
let socialTimeout = setTimeout(errorCb(self.domIds.social), 20000)
|
||||
dataChart6.on('error', errorCb(self.domIds.social))
|
||||
dataChart6.on('success', () => clearTimeout(socialTimeout))
|
||||
dataChart6.execute()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export default Analytics
|
@@ -0,0 +1,7 @@
|
||||
export default {
|
||||
sm: 576,
|
||||
md: 768,
|
||||
lg: 992,
|
||||
xl: 1200,
|
||||
xxl: 1400
|
||||
}
|
@@ -0,0 +1,193 @@
|
||||
import $ from 'jquery'
|
||||
import Translator from './i18n'
|
||||
|
||||
let ChangeForm = {
|
||||
/**
|
||||
* ChangeForm component
|
||||
*
|
||||
* Alert unsaved changes stuff
|
||||
* Display loading spinner if multipart
|
||||
*/
|
||||
init: function (opts) {
|
||||
var self = this
|
||||
this.form = $('#content-main form')
|
||||
if (opts.confirmUnsavedChanges) {
|
||||
this.formSubmitting = false
|
||||
this.t = new Translator($('html').attr('lang'))
|
||||
// wait for django SelectFilter to do its job
|
||||
setTimeout(function () {
|
||||
self.initData = self.serializeData()
|
||||
self.activate()
|
||||
}, 500)
|
||||
}
|
||||
if (opts.showMultipartUploading) {
|
||||
this.spinner()
|
||||
}
|
||||
self.fixNewlines()
|
||||
setTimeout(function () {
|
||||
self.fixNewlines() // js inserted ones
|
||||
}, 50)
|
||||
this.fixWrappedFields()
|
||||
if (opts.enableImagesPreview) {
|
||||
this.lazyLoadImages()
|
||||
}
|
||||
this.activateEntryCollapsing()
|
||||
this.changeFieldsetCollapseStyle()
|
||||
this.fixExpandFirstErrorCollapsing()
|
||||
this.initTemplates()
|
||||
},
|
||||
activate: function () {
|
||||
this.form.on('submit', () => (this.formSubmitting = true))
|
||||
$(window).on('beforeunload', this.alertDirty.bind(this))
|
||||
},
|
||||
serializeData: function () {
|
||||
// form serialize does not detect filter_horizontal controllers because
|
||||
// in that case options are not selected, just added to the list of options,
|
||||
// and jquery form serialize only serializes values which are set!
|
||||
let data = this.form.serialize()
|
||||
$('select.filtered[multiple][id$=_to]').each(function (k, select) {
|
||||
let optionsValues = []
|
||||
$(select).children('option').each(function (kk, option) {
|
||||
optionsValues.push($(option).attr('value'))
|
||||
})
|
||||
data += `&${jQuery(select).attr('name')}=${optionsValues.sort().join(',')}`
|
||||
})
|
||||
return data
|
||||
},
|
||||
isDirty: function () {
|
||||
return this.serializeData() !== this.initData
|
||||
},
|
||||
alertDirty: function (e) {
|
||||
if (this.formSubmitting || !this.isDirty()) {
|
||||
return undefined
|
||||
}
|
||||
let confirmationMessage = this.t.get('unsavedChangesAlert');
|
||||
(e || window.event).returnValue = confirmationMessage // Gecko + IE
|
||||
return confirmationMessage // Gecko + Webkit, Safari, Chrome etc.
|
||||
},
|
||||
spinner: function () {
|
||||
if (this.form.attr('enctype') === 'multipart/form-data') {
|
||||
this.form.on('submit', () => this.showSpinner())
|
||||
}
|
||||
},
|
||||
showSpinner: function () {
|
||||
let run = false
|
||||
let inputFiles = $('input[type=file]')
|
||||
inputFiles.each(function (index, input) {
|
||||
if (input.files.length !== 0) {
|
||||
run = true
|
||||
}
|
||||
})
|
||||
if (run) {
|
||||
let overlay = $('<div />', {'class': 'spinner-overlay'}).appendTo(document.body)
|
||||
let spinner = $('<i />', {'class': 'fa fa-spinner fa-spin fa-3x fa-fw'})
|
||||
$('<div />').append(
|
||||
$('<p />').text(this.t.get('uploading')),
|
||||
spinner
|
||||
).appendTo(overlay)
|
||||
}
|
||||
},
|
||||
fixWrappedFields: function () {
|
||||
this.form.find('.form-row').each(function (index, row) {
|
||||
var fieldBoxes = $(row).children('.fieldBox')
|
||||
fieldBoxes.each(function (index, fbox) {
|
||||
if ($(fbox).hasClass('errors')) {
|
||||
$(row).addClass('errors')
|
||||
}
|
||||
})
|
||||
fieldBoxes.wrapAll('<div class="wrapped-fields-container" />')
|
||||
if (fieldBoxes.length) {
|
||||
$(row).addClass('with-wrapped-fields')
|
||||
}
|
||||
})
|
||||
// this.form.find('.wrapped-fields-container > .fieldBox:first-child').children().unwrap()
|
||||
},
|
||||
fixNewlines: function () {
|
||||
$('.form-row br').replaceWith('<span class="newline"></span>')
|
||||
},
|
||||
lazyLoadImages: function () {
|
||||
$('.file-upload').each(function (index, p) {
|
||||
let cur = $(p).find('a')
|
||||
if (cur.length) {
|
||||
let url = cur.attr('href')
|
||||
let ext = url.split('?')[0].split('.').pop()
|
||||
if (['jpg', 'jpeg', 'png', 'bmp', 'svg', 'gif', 'tif', 'webp'].indexOf(ext) !== -1) {
|
||||
let spinner = $('<i />', {'class': 'fa fa-spinner fa-spin fa-2x fa-fw'}).css('color', '#aaa')
|
||||
let preview = $('<div />', {'class': 'py-2'}).append(spinner)
|
||||
$(p).prepend(preview)
|
||||
let image = new Image()
|
||||
image.onload = function () {
|
||||
spinner.replaceWith($(image).addClass('baton-image-preview'))
|
||||
}
|
||||
image.onerror = function () {
|
||||
preview.remove()
|
||||
}
|
||||
image.src = url
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
activateEntryCollapsing: function () {
|
||||
$('.collapse-entry h3')
|
||||
.addClass('entry-collapsed entry-collapse-full-toggler')
|
||||
.append('<span />') // just to have the toggler right aligned
|
||||
.append('<span class="entry-collapse-toggler" />')
|
||||
$('.collapse-entry')
|
||||
.click(function (e) {
|
||||
let target = $(e.target)
|
||||
if (target.hasClass('entry-collapse-full-toggler')) {
|
||||
target.toggleClass('entry-collapsed')
|
||||
} else if (target.parent('.entry-collapse-full-toggler').length > 0) {
|
||||
target.parent('.entry-collapse-full-toggler').toggleClass('entry-collapsed')
|
||||
}
|
||||
})
|
||||
$('.form-row.errors').each(function (index, el) {
|
||||
if ($(el).parent('fieldset').prev('h3.entry-collapsed')) {
|
||||
$(el).parent('fieldset').prev('h3.entry-collapsed').removeClass('entry-collapsed')
|
||||
}
|
||||
})
|
||||
},
|
||||
fixExpandFirstErrorCollapsing: function () {
|
||||
$('.expand-first').each(function (index, el) {
|
||||
if ($(el).find('.inline-related[id$=0] .form-row.errors').length) {
|
||||
// inverse logic
|
||||
$(el).find('.inline-related[id$=0] .form-row.errors').parent('fieldset').prev('h3').addClass('entry-collapsed')
|
||||
}
|
||||
})
|
||||
},
|
||||
changeFieldsetCollapseStyle: function () {
|
||||
$(window).on('load', function () {
|
||||
$('fieldset.collapse > h2').each(function (index, title) {
|
||||
let text = $(title).text().replace(/\(.*\)/, '')
|
||||
setTimeout(function () {
|
||||
$(title).html(text).on('click', function () {
|
||||
$(this).parent('.collapse').toggleClass('collapsed')
|
||||
})
|
||||
}, 100)
|
||||
})
|
||||
})
|
||||
},
|
||||
initTemplates: function () {
|
||||
const positionMap = {
|
||||
above: 'before',
|
||||
below: 'after',
|
||||
top: 'prepend',
|
||||
bottom: 'append',
|
||||
right: 'after'
|
||||
}
|
||||
$('template').each(function (index, template) {
|
||||
let field = $(template).attr('id').replace('template-', '')
|
||||
let position = positionMap[$(template).attr('data-position')]
|
||||
if (position !== undefined) {
|
||||
let el = $(template).attr('data-position') === 'right'
|
||||
? $('.form-row.field-' + field + ' #id_' + field)
|
||||
: $('.form-row.field-' + field)
|
||||
el[position]($(template).html())
|
||||
} else {
|
||||
console.error('Baton: wrong form include position detected')
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export default ChangeForm
|
@@ -0,0 +1,203 @@
|
||||
import $ from 'jquery'
|
||||
import Translator from './i18n'
|
||||
import Modal from './Modal'
|
||||
import breakpoints from './Breakpoints'
|
||||
|
||||
let ChangeList = {
|
||||
/**
|
||||
* ChangeList component
|
||||
*
|
||||
* Filtering stuff
|
||||
*/
|
||||
init: function (opts) {
|
||||
this._filtersDiv = $('#changelist-filter')
|
||||
this.t = new Translator($('html').attr('lang'))
|
||||
this.filtersForm = opts.changelistFiltersForm
|
||||
this.filtersInModal = opts.changelistFiltersInModal
|
||||
this.filtersAlwaysOpen = opts.changelistFiltersAlwaysOpen
|
||||
this.initTemplates()
|
||||
if (this._filtersDiv.length) {
|
||||
var self = this
|
||||
setTimeout(function () {
|
||||
self.activate()
|
||||
}, 200) // select2
|
||||
this.fixRangeFilter()
|
||||
}
|
||||
},
|
||||
activate: function () {
|
||||
if ($('.changelist-form-container').length) {
|
||||
// django >= 3.1
|
||||
$('#changelist-filter').appendTo($('.changelist-form-container'))
|
||||
}
|
||||
let isModal = false
|
||||
if (this.filtersAlwaysOpen) {
|
||||
$(document.body).addClass(
|
||||
'changelist-filter-active changelist-filter-always-open'
|
||||
)
|
||||
} else {
|
||||
// filters active?
|
||||
let _activeFilters = /__[^=]+=/.test(location.search)
|
||||
// actions ?
|
||||
let _activeActions = $('#changelist-form > .actions').length !== 0
|
||||
let _changelistForm = $('#changelist-form')
|
||||
let _filtersToggler = $('<a />', {
|
||||
class:
|
||||
'changelist-filter-toggler' +
|
||||
(_activeFilters ? ' active' : '') +
|
||||
(_activeActions ? ' with-actions' : '')
|
||||
}).html(
|
||||
'<i class="fa fa-filter"></i> <span>' + this.t.get('filter') + '</span>'
|
||||
)
|
||||
|
||||
if (this.filtersInModal || parseInt($(window).width()) < breakpoints.lg) {
|
||||
let self = this
|
||||
isModal = true
|
||||
// wait for filters used js to exec
|
||||
$('#changelist-filter').prop('id', 'changelist-filter-modal')
|
||||
let titleEl = $('#changelist-filter-modal > h2')
|
||||
let title = titleEl.html()
|
||||
titleEl.remove()
|
||||
let content = $('#changelist-filter-modal')
|
||||
// remove from dom
|
||||
this.modal = new Modal({
|
||||
title,
|
||||
content,
|
||||
size: 'md',
|
||||
hideFooter: !this.filtersForm,
|
||||
actionBtnLabel: this.t.get('filter'),
|
||||
actionBtnCb: function () { self.filter(content) }
|
||||
})
|
||||
_filtersToggler.click(() => {
|
||||
self.modal.toggle()
|
||||
})
|
||||
} else {
|
||||
_filtersToggler.click(() => {
|
||||
$(document.body).toggleClass('changelist-filter-active')
|
||||
if (parseInt(this._filtersDiv.css('max-width')) === 100) {
|
||||
// diff between mobile and lg
|
||||
$('html,body').animate({
|
||||
scrollTop: this._filtersDiv.offset().top
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
_changelistForm.prepend(_filtersToggler)
|
||||
}
|
||||
|
||||
if (!isModal && this.filtersForm) {
|
||||
// add filters button
|
||||
let btn = $('<a />', {'class': 'btn btn-primary'}).html(this.t.get('filter'))
|
||||
.on('click', () => this.filter($('#changelist-filter')))
|
||||
$('#changelist-filter').append($('<div />', {'class': 'text-center mb-3'}).append(btn))
|
||||
}
|
||||
|
||||
if (/_popup=1/.test(location.href)) {
|
||||
$('#changelist-form .results').css('padding-top', '78px')
|
||||
}
|
||||
},
|
||||
getDropdownValue: function (dropdown) {
|
||||
let items = $(dropdown).find('option').attr('value').substr(1).split('&')
|
||||
let values = $(dropdown).val().substr(1).split('&').filter(item => items.indexOf(item) === -1)
|
||||
return values.length ? values.join('&') : null
|
||||
},
|
||||
filter: function (wrapper) {
|
||||
var self = this
|
||||
let qs = []
|
||||
|
||||
let dropdowns = wrapper.find('select')
|
||||
let textInputs = wrapper.find('input').not('[type=hidden]')
|
||||
|
||||
dropdowns
|
||||
.toArray()
|
||||
.map(el => self.getDropdownValue(el))
|
||||
.filter(v => v !== null)
|
||||
.forEach(v => qs.push(v))
|
||||
|
||||
textInputs.each((idx, el) => el.value !== '' ? qs.push(`${el.name}=${el.value}`) : null)
|
||||
|
||||
// console.log(location.pathname + (qs.length ? '?' + qs.filter(q => q !== '').join('&') : ''), qs)
|
||||
location.href = location.pathname + (qs.length ? '?' + qs.filter(q => q !== '').join('&') : '')
|
||||
},
|
||||
initTemplates: function () {
|
||||
const positionMap = {
|
||||
above: 'before',
|
||||
below: 'after',
|
||||
top: 'prepend',
|
||||
bottom: 'append'
|
||||
}
|
||||
|
||||
$('template[data-type=include]').each(function (index, template) {
|
||||
let position = positionMap[$(template).attr('data-position')]
|
||||
if (position !== undefined) {
|
||||
let el = $('#changelist-form')
|
||||
el[position]($(template).html())
|
||||
} else {
|
||||
console.error('Baton: wrong changelist include position detected')
|
||||
}
|
||||
})
|
||||
|
||||
$('template[data-type=filters-include]').each(function (index, template) {
|
||||
let position = positionMap[$(template).attr('data-position')]
|
||||
if (
|
||||
position !== undefined &&
|
||||
position !== 'before' &&
|
||||
position !== 'after'
|
||||
) {
|
||||
if (position === 'prepend' && $('#changelist-filter-clear').length) {
|
||||
$('#changelist-filter-clear').after($(template).html())
|
||||
} else if (
|
||||
position === 'prepend' &&
|
||||
$('#changelist-filter > h2').length
|
||||
) {
|
||||
$('#changelist-filter > h2').after($(template).html())
|
||||
} else {
|
||||
let el = $('#changelist-filter')
|
||||
el[position]($(template).html())
|
||||
}
|
||||
} else {
|
||||
console.error(
|
||||
'Baton: wrong changelist filters include position detected'
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
$('template[data-type=attributes]').each(function (index, template) {
|
||||
try {
|
||||
let data = JSON.parse($(template).html())
|
||||
|
||||
for (let key in data) {
|
||||
if (data.hasOwnProperty(key)) {
|
||||
let selector
|
||||
let getParent = 'tr'
|
||||
if (data[key]['selector']) {
|
||||
selector = data[key]['selector']
|
||||
delete data[key]['selector']
|
||||
} else {
|
||||
selector =
|
||||
'#result_list tr input[name=_selected_action][value=' +
|
||||
key +
|
||||
']'
|
||||
}
|
||||
if (data[key]['getParent'] !== undefined) {
|
||||
getParent = data[key]['getParent']
|
||||
delete data[key]['getParent']
|
||||
}
|
||||
|
||||
let el = getParent ? $(selector).parents(getParent) : $(selector)
|
||||
el.attr(data[key])
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
})
|
||||
},
|
||||
fixRangeFilter: function () {
|
||||
if (this.filtersForm) {
|
||||
$('.admindatefilter .controls').remove()
|
||||
$('.admindatefilter form').onSubmit = function () { return false }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default ChangeList
|
@@ -0,0 +1,30 @@
|
||||
import $ from 'jquery'
|
||||
import { copyTextToClipboard } from './Utils'
|
||||
|
||||
let Filer = {
|
||||
/**
|
||||
* ChangeList component
|
||||
*
|
||||
* Filtering stuff
|
||||
*/
|
||||
init: function (opts) {
|
||||
this.fixIcons()
|
||||
this.fixCopyToClipboard()
|
||||
},
|
||||
fixIcons: function () {
|
||||
$('.fa-pencil').addClass('fa-pencil-alt')
|
||||
},
|
||||
fixCopyToClipboard: function () {
|
||||
let copyBtns = $('.action-button .fa-link')
|
||||
copyBtns.on('click', function (evt) {
|
||||
evt.preventDefault()
|
||||
var link = $(this).parent('.action-button').attr('href')
|
||||
if (!link) {
|
||||
link = $(this).parent('.action-button').next('.action-button').attr('href')
|
||||
}
|
||||
copyTextToClipboard(link)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export default Filer
|
@@ -0,0 +1,17 @@
|
||||
import $ from 'jquery'
|
||||
|
||||
let Footer = {
|
||||
/**
|
||||
* Footer component
|
||||
*
|
||||
* Moves the footer inside the main external container
|
||||
*/
|
||||
init: function (opts) {
|
||||
$('#footer').appendTo('#content')
|
||||
if (opts.remove) {
|
||||
$('#footer').remove()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Footer
|
@@ -0,0 +1,47 @@
|
||||
import $ from 'jquery'
|
||||
|
||||
const Login = {
|
||||
init: function (config) {
|
||||
// splash
|
||||
if (config.loginSplash) {
|
||||
$('body.login').css({
|
||||
background: `url(${config.loginSplash}) no-repeat center center`,
|
||||
backgroundSize: 'cover'
|
||||
})
|
||||
}
|
||||
// form
|
||||
let inputUsername = $('#id_username')
|
||||
let inputPassword = $('#id_password')
|
||||
|
||||
const usernameField = $('<div />', { class: 'input-group mb-2' })
|
||||
.append(
|
||||
$('<span />', { class: 'input-group-text' }).append(
|
||||
'<i class="fa fa-user"></i>'
|
||||
)
|
||||
)
|
||||
.append(inputUsername.clone())
|
||||
|
||||
inputUsername.replaceWith(usernameField)
|
||||
|
||||
// adds show/hide password functionality
|
||||
let passwordInputField = inputPassword.clone()
|
||||
let viewPasswordIcon = $('<i />', {'class': 'fa fa-eye pwd-visibility-toggle'}).on('click', function () {
|
||||
let visible = $(this).hasClass('fa-eye-slash')
|
||||
$(this)[visible ? 'removeClass' : 'addClass']('fa-eye-slash')
|
||||
passwordInputField.attr('type', visible ? 'password' : 'text')
|
||||
})
|
||||
|
||||
const passwordField = $('<div />', { class: 'input-group mb-2' })
|
||||
.append(
|
||||
$('<span />', { class: 'input-group-text' }).append(
|
||||
'<i class="fa fa-key"></i>'
|
||||
)
|
||||
)
|
||||
.append(passwordInputField)
|
||||
.append(viewPasswordIcon)
|
||||
|
||||
inputPassword.replaceWith(passwordField)
|
||||
}
|
||||
}
|
||||
|
||||
export default Login
|
375
venv/Lib/site-packages/baton/static/baton/app/src/core/Menu.js
Normal file
@@ -0,0 +1,375 @@
|
||||
import $ from 'jquery'
|
||||
import Translator from './i18n'
|
||||
|
||||
let Menu = {
|
||||
/**
|
||||
* Menu component
|
||||
*
|
||||
* Adds a sidebar menu to the document
|
||||
*/
|
||||
init: function (config, Dispatcher) {
|
||||
this.Dispatcher = Dispatcher
|
||||
this.t = new Translator($('html').attr('lang'))
|
||||
this.collapsableUserArea = config.collapsableUserArea
|
||||
this.menuTitle = config.menuTitle
|
||||
this.searchField = config.searchField
|
||||
this.appListUrl = config.api.app_list
|
||||
this.gravatarUrl = config.api.gravatar
|
||||
this.gravatarDefaultImg = config.gravatarDefaultImg
|
||||
this.alwaysCollapsed = $('#header').hasClass('menu-always-collapsed')
|
||||
this.fixNodes()
|
||||
this.brandingClone = $('#branding').clone()
|
||||
this.manageBrandingUserTools()
|
||||
this.manageSearchField()
|
||||
this.fetchData()
|
||||
this.setHeight()
|
||||
let self = this
|
||||
$(window).on('resize', function () {
|
||||
self.setHeight()
|
||||
self.manageBrandingUserTools()
|
||||
})
|
||||
},
|
||||
fixNodes: function () {
|
||||
let container = $('<div/>', { class: 'container-fluid' })
|
||||
$('#footer').before(container)
|
||||
let row = $('<div/>', { class: 'row' }).appendTo(container)
|
||||
this.menu = $('<nav/>', { class: 'col-lg-2 sidebar-menu' }).appendTo(row)
|
||||
$('#content')
|
||||
.addClass('col-lg-10')
|
||||
.prepend($('.breadcrumbs'))
|
||||
.appendTo(row)
|
||||
|
||||
$('#content > h1').after($('.messagelist'))
|
||||
|
||||
let title = $('<h1 />', { class: 'd-block d-lg-none' }).text(
|
||||
this.menuTitle ? this.menuTitle : 'Menu'
|
||||
)
|
||||
$('<i/>', { class: 'fa fa-times' })
|
||||
.click(() => {
|
||||
$(document.body).removeClass('menu-open')
|
||||
})
|
||||
.appendTo(title)
|
||||
this.menu.append(title)
|
||||
|
||||
if (this.alwaysCollapsed) {
|
||||
let close = $('<i />', { class: 'fa fa-times toggle-menu' })
|
||||
.appendTo(this.menu)
|
||||
.click(() => {
|
||||
$(document.body).removeClass('menu-open')
|
||||
})
|
||||
}
|
||||
},
|
||||
manageBrandingUserTools: function () {
|
||||
if (parseInt($(window).width()) >= 992) {
|
||||
// move user tools
|
||||
this.menu.prepend($('#user-tools'))
|
||||
if (this.alwaysCollapsed) {
|
||||
// copy branding
|
||||
this.menu.prepend(this.brandingClone)
|
||||
} else {
|
||||
// move branding
|
||||
this.menu.prepend($('#branding'))
|
||||
}
|
||||
if ($('#user-tools-sidebar').length === 0) {
|
||||
this.renderUserTools()
|
||||
}
|
||||
} else {
|
||||
$('#header').append($('#user-tools'))
|
||||
if (this.alwaysCollapsed) {
|
||||
this.menu.find('#branding').remove()
|
||||
} else {
|
||||
$('#header .navbar-toggler').after($('#branding'))
|
||||
}
|
||||
if ($('#user-tools-sidebar').length === 0) {
|
||||
this.removeUserTools()
|
||||
}
|
||||
}
|
||||
},
|
||||
manageSearchField () {
|
||||
// unset
|
||||
if (!this.searchField || !this.searchField.url) {
|
||||
return
|
||||
}
|
||||
|
||||
let container = $('<div />', { class: 'search-field-tool' })
|
||||
|
||||
let field = $('<input />', {
|
||||
class: 'form-control form-control-sm',
|
||||
type: 'text',
|
||||
list: 'admin-search-datalist',
|
||||
placeholder: this.searchField.label || this.t('search')
|
||||
})
|
||||
let dataList = $('<div />', { id: 'admin-search-datalist' }).on('mouseover', e => {
|
||||
if ($(e.target).hasClass('datalist-option') || $(e.target).parent('.datalist-option').length) {
|
||||
dataList.find('.datalist-option').removeClass('selected')
|
||||
let item = $(e.target).hasClass('datalist-option') ? $(e.target) : $(e.target).parent('.datalist-option')
|
||||
item.addClass('selected')
|
||||
}
|
||||
})
|
||||
|
||||
let navigateDataList = code => {
|
||||
let target
|
||||
let active = dataList.find('.datalist-option.selected').first()
|
||||
if (!active.length) {
|
||||
target = dataList.find('.datalist-option')[code === 40 ? 'first' : 'last']()
|
||||
} else {
|
||||
if (code === 40) {
|
||||
let next = active.next()
|
||||
target = next.length ? next : dataList.find('.datalist-option').first()
|
||||
} else {
|
||||
let prev = active.prev()
|
||||
target = prev.length ? prev : dataList.find('.datalist-option').last()
|
||||
}
|
||||
}
|
||||
if (target) {
|
||||
active.removeClass('selected')
|
||||
$(target).addClass('selected')
|
||||
target[0].scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
block: 'end',
|
||||
inline: 'nearest'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
field.on('blur', e => setTimeout(() => dataList.hide(), 150))
|
||||
field.on('focus', e => dataList.show())
|
||||
field.on('keyup', e => {
|
||||
var code = e.keyCode || e.which
|
||||
|
||||
if (code === 13) {
|
||||
// goto url if there is an active voice
|
||||
let active = dataList.find('.datalist-option.selected').first()
|
||||
if (active.length) {
|
||||
location.href = active.attr('data-url')
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if ([40, 38].indexOf(code) !== -1) {
|
||||
// move
|
||||
navigateDataList(code)
|
||||
} else {
|
||||
// search
|
||||
if ($(field).val().length < 1) {
|
||||
dataList.empty()
|
||||
return
|
||||
}
|
||||
|
||||
container.addClass('loading')
|
||||
$.getJSON(this.searchField.url, { text: $(field).val() })
|
||||
.done(data => {
|
||||
container.removeClass('loading')
|
||||
dataList.empty()
|
||||
data.data.forEach((r, index) => dataList.append(`
|
||||
<div class="datalist-option${index === 0 ? ' selected' : ''}" onclick="location.href='${r.url}'" data-url="${r.url}"><a href="${r.url}">${r.label}</a>${r.icon ? `<i onclick="location.href='${r.url}'" class="${r.icon}"></i>` : ''}</div>`)
|
||||
)
|
||||
})
|
||||
.fail((jqxhr, textStatus, err) => {
|
||||
console.log(err)
|
||||
container.removeClass('loading')
|
||||
dataList.empty()
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
$('#user-tools-sidebar').after(container.append([field, dataList]))
|
||||
},
|
||||
renderUserTools: function () {
|
||||
let self = this
|
||||
let container = $('<div />', { id: 'user-tools-sidebar' })
|
||||
let expandUserArea = $('<i />', {'class': 'fa fa-angle-down user-area-toggler'}).on('click', function () {
|
||||
$(this).toggleClass('fa-angle-up')
|
||||
container.toggleClass('collapsed')
|
||||
})
|
||||
if (this.collapsableUserArea) {
|
||||
container.addClass('collapsed')
|
||||
}
|
||||
container.insertAfter('#user-tools')
|
||||
let userInfo = $('<div />', { class: 'user-info' })
|
||||
.html(
|
||||
'<div class="spinner-border text-primary" role="status"><span class="sr-only">Loading...</span></div><div>' +
|
||||
$('#user-tools .dropdown-toggle').text() +
|
||||
'</div>'
|
||||
)
|
||||
.appendTo(container)
|
||||
// gravatar
|
||||
$.getJSON(this.gravatarUrl, function (data) {
|
||||
let img = $('<img />', {
|
||||
class: 'gravatar-icon',
|
||||
src: 'https://www.gravatar.com/avatar/{hash}?s=50&d={default}'
|
||||
.replace('{hash}', data.hash)
|
||||
.replace('{default}', self.gravatarDefaultImg)
|
||||
})
|
||||
userInfo.find('.spinner-border').replaceWith(img)
|
||||
if (self.collapsableUserArea) {
|
||||
img.after(expandUserArea)
|
||||
}
|
||||
}).fail(function (err) {
|
||||
console.error(err.responseText)
|
||||
let img = $('<img />', {
|
||||
class: 'gravatar-icon',
|
||||
src: 'https://www.gravatar.com/avatar/{hash}?s=50&d={default}'
|
||||
.replace('{hash}', '')
|
||||
.replace('{default}', self.gravatarDefaultImg)
|
||||
})
|
||||
userInfo.find('.spinner-border').replaceWith(img)
|
||||
if (self.collapsableUserArea) {
|
||||
img.after(expandUserArea)
|
||||
}
|
||||
})
|
||||
let linksContainer = $('<div />', { class: 'user-links' }).appendTo(
|
||||
container
|
||||
)
|
||||
$('#user-tools .dropdown-menu a').each(function (index, el) {
|
||||
let cls = 'view-site'
|
||||
if (/password_change/.test($(el).attr('href'))) {
|
||||
cls = 'password'
|
||||
} else if (/logout/.test($(el).attr('href'))) {
|
||||
cls = 'logout'
|
||||
}
|
||||
let text = $(el).text()
|
||||
let clone = $(el)
|
||||
.clone()
|
||||
.html('')
|
||||
.attr('class', cls)
|
||||
.attr('title', text)
|
||||
if (cls === 'view-site') {
|
||||
clone.attr('target', '_blank')
|
||||
}
|
||||
linksContainer.append(clone)
|
||||
})
|
||||
},
|
||||
removeUserTools: function () {
|
||||
$('#user-tools-sidebar').remove()
|
||||
},
|
||||
fetchData: function () {
|
||||
let self = this
|
||||
$.getJSON(this.appListUrl, function (data) {
|
||||
self.render(data)
|
||||
self.Dispatcher.emit('onMenuReady')
|
||||
}).fail(function (err) {
|
||||
console.error(err.responseText)
|
||||
self.menu.remove()
|
||||
$('#content')
|
||||
.removeClass('col-md-9')
|
||||
.removeClass('col-lg-10')
|
||||
.css('flex-grow', 1)
|
||||
self.Dispatcher.emit('onMenuError')
|
||||
})
|
||||
},
|
||||
setHeight: function () {
|
||||
let height = $(window).height() - $('#header').height() - 19 // nav padding and border
|
||||
this.menu.css('min-height', height + 'px')
|
||||
$('#content').css('padding-bottom', $('#footer').height() + 20 + 'px')
|
||||
},
|
||||
render: function (data) {
|
||||
let self = this
|
||||
let mainUl = $('<ul/>', { class: 'depth-0' }).appendTo(self.menu)
|
||||
data.forEach((voice, index) => {
|
||||
let active = false
|
||||
if (voice.type === 'free') {
|
||||
if (voice.re) {
|
||||
let re = new RegExp(voice.re)
|
||||
active = re.test(location.pathname)
|
||||
} else {
|
||||
active = location.pathname === voice.url
|
||||
}
|
||||
} else {
|
||||
if (voice.url) {
|
||||
let pathRexp = new RegExp(voice.url)
|
||||
active = pathRexp.test(location.pathname)
|
||||
}
|
||||
}
|
||||
let li = $('<li />', {
|
||||
class:
|
||||
'top-level ' +
|
||||
voice.type +
|
||||
(voice.defaultOpen ? ' default-open' : '') +
|
||||
(active ? ' active' : '')
|
||||
})
|
||||
let a = $('<' + (voice.url ? 'a' : 'span') + ' />', {
|
||||
href: voice.url || '#'
|
||||
})
|
||||
.text(voice.label)
|
||||
.appendTo(li)
|
||||
// icon
|
||||
if (voice.icon) {
|
||||
$('<i />', { class: voice.icon }).prependTo(a)
|
||||
}
|
||||
let subUl
|
||||
if (voice.children && voice.children.length) {
|
||||
subUl = $('<ul />', { class: 'depth-1' }).appendTo(li)
|
||||
a.addClass('has-children')
|
||||
|
||||
voice.children.forEach((model, i) => {
|
||||
let active = false
|
||||
if (model.type === 'free') {
|
||||
if (model.re) {
|
||||
let re = new RegExp(model.re)
|
||||
active = re.test(location.pathname)
|
||||
} else {
|
||||
active = location.pathname === model.url
|
||||
}
|
||||
} else if (model.url) {
|
||||
let pathRexp = new RegExp(model.url)
|
||||
active = pathRexp.test(location.pathname)
|
||||
}
|
||||
let subLi = $('<li />')
|
||||
if (active) {
|
||||
subLi.addClass('active')
|
||||
li.addClass('with-active')
|
||||
}
|
||||
let a = $('<a />', {
|
||||
href: model.url
|
||||
})
|
||||
.text(model.label)
|
||||
.appendTo(subLi)
|
||||
// icon
|
||||
if (model.icon) {
|
||||
$('<i />', { class: model.icon }).prependTo(a)
|
||||
}
|
||||
subLi.appendTo(subUl)
|
||||
})
|
||||
}
|
||||
li.appendTo(mainUl)
|
||||
})
|
||||
|
||||
$('.has-children').on('click', function (evt) {
|
||||
evt.preventDefault()
|
||||
let self = this
|
||||
let p = $(this).parent()
|
||||
let depth0 = $('.depth-0')
|
||||
let depth1 = p.children('ul')
|
||||
if (
|
||||
p.hasClass('open') ||
|
||||
(p.hasClass('default-open') && !$('body').hasClass('menu-open'))
|
||||
) {
|
||||
p.removeClass('open default-open')
|
||||
depth1.children('.nav-back').remove()
|
||||
depth0.css('overflow', 'auto')
|
||||
} else {
|
||||
if (p.hasClass('top-level')) {
|
||||
$('.top-level').removeClass('open')
|
||||
$('.top-level')
|
||||
.find('.nav-back')
|
||||
.remove()
|
||||
}
|
||||
p.addClass('open')
|
||||
let back = $(
|
||||
'<li class="nav-item nav-back"><a href="#"><i class="fa fa-angle-double-left"></i> ' + // eslint-disable-line
|
||||
$(this).text() +
|
||||
'</a></li>'
|
||||
)
|
||||
back.on('click', function () {
|
||||
$(self).trigger('click')
|
||||
})
|
||||
depth1.prepend(back)
|
||||
depth0.css('overflow', 'hidden')
|
||||
depth0.scrollTop(0) // return to top
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export default Menu
|
@@ -0,0 +1,72 @@
|
||||
import $ from 'jquery'
|
||||
import bootstrap from 'bootstrap/dist/js/bootstrap.bundle'
|
||||
|
||||
let Messages = {
|
||||
/**
|
||||
* Messages
|
||||
*
|
||||
* If toast are enabled, moves messages ul lis in toasts
|
||||
*/
|
||||
init: function (opts) {
|
||||
if (opts.messagesToasts) {
|
||||
let toasts = []
|
||||
let all = true
|
||||
$('.messagelist li').each((index, el) => {
|
||||
let lv = $(el).attr('class')
|
||||
if (opts.messagesToasts === true || opts.messagesToasts.indexOf(lv) !== -1) {
|
||||
toasts.push(this.createToast($(el).attr('class'), $(el).html()))
|
||||
$(el).remove()
|
||||
} else {
|
||||
all = false
|
||||
}
|
||||
})
|
||||
if (toasts.length) {
|
||||
$('<div />', {'class': 'toast-container position-absolute top-0 end-0 p-3'})
|
||||
.append(toasts).appendTo($(document.body))
|
||||
}
|
||||
if (all) {
|
||||
$('.messagelist').remove()
|
||||
}
|
||||
}
|
||||
const toastElList = [].slice.call(document.querySelectorAll('.toast'))
|
||||
toastElList.map(function (toastEl) {
|
||||
new bootstrap.Toast(toastEl, { autohide: false }).show()
|
||||
})
|
||||
},
|
||||
levelsMap: {
|
||||
info: {
|
||||
bg: 'info',
|
||||
icon: 'fa fa-info-circle',
|
||||
iconColor: '#fff'
|
||||
},
|
||||
success: {
|
||||
bg: 'success',
|
||||
icon: 'fa fa-check-circle',
|
||||
iconColor: '#fff'
|
||||
},
|
||||
warning: {
|
||||
bg: 'warning',
|
||||
icon: 'fa fa-exclamation-circle',
|
||||
iconColor: '#fff'
|
||||
},
|
||||
error: {
|
||||
bg: 'danger',
|
||||
icon: 'fa fa-exclamation-circle',
|
||||
iconColor: '#fff'
|
||||
}
|
||||
},
|
||||
createToast (level, content) {
|
||||
let toast = `
|
||||
<div class="toast d-flex align-items-center text-white bg-${this.levelsMap[level].bg} border-0" role="alert" aria-live="assertive" aria-atomic="true">
|
||||
<div class="toast-body">
|
||||
<i class="${this.levelsMap[level].icon}" style="color: ${this.levelsMap[level].iconColor}; margin-right: .5rem"></i>
|
||||
${content}
|
||||
</div>
|
||||
<button type="button" class="btn-close btn-close-white ms-auto me-2" data-bs-dismiss="toast" aria-label="Close"></button>
|
||||
</div>
|
||||
`
|
||||
return $(toast)
|
||||
}
|
||||
}
|
||||
|
||||
export default Messages
|
155
venv/Lib/site-packages/baton/static/baton/app/src/core/Modal.js
Normal file
@@ -0,0 +1,155 @@
|
||||
import $ from 'jquery'
|
||||
import Translator from './i18n'
|
||||
import bootstrap from 'bootstrap/dist/js/bootstrap.bundle'
|
||||
|
||||
class Modal {
|
||||
constructor (config) {
|
||||
this.t = new Translator($('html').attr('lang'))
|
||||
|
||||
this.opts = {
|
||||
subtitle: '',
|
||||
hideFooter: false,
|
||||
showBackBtn: false,
|
||||
backBtnCb: function () {},
|
||||
actionBtnLabel: this.t.get('save'),
|
||||
actionBtnCb: null,
|
||||
onUrlLoaded: function () {},
|
||||
size: 'lg',
|
||||
onClose: function () {}
|
||||
}
|
||||
|
||||
this.isOpen = false
|
||||
this.create() // adds modal, modalObj and events
|
||||
this.update(config)
|
||||
}
|
||||
|
||||
create () {
|
||||
this.modalObj = $('<div />', {'class': 'modal fade'}).appendTo(document.body)
|
||||
this.modalObj.html(`
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title"></h5>
|
||||
<div style="display: flex;">
|
||||
<button type="button" class="back me-1" aria-label="Back">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</button>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">${this.t.get('close')}</button>
|
||||
<button type="button" class="btn btn-primary btn-action"></button>
|
||||
</div>
|
||||
</div><!-- /.modal-content -->
|
||||
</div><!-- /.modal-dialog -->
|
||||
`)
|
||||
|
||||
var self = this
|
||||
this.modalObj.on('hidden.bs.modal', function () {
|
||||
self.close()
|
||||
})
|
||||
|
||||
this.modal = new bootstrap.Modal(this.modalObj[0])
|
||||
}
|
||||
|
||||
update (config) {
|
||||
this.options = $.extend({}, this.opts, config)
|
||||
this.setSize()
|
||||
this.setHeader()
|
||||
this.setTitle()
|
||||
this.setSubtitle()
|
||||
this.setContent()
|
||||
this.setButtons()
|
||||
}
|
||||
|
||||
setSize () {
|
||||
this.modalObj.find('.modal-dialog').addClass('modal-' + this.options.size)
|
||||
}
|
||||
|
||||
setHeader () {
|
||||
if (this.options.showBackBtn) {
|
||||
this.modalObj.find('.modal-header .back').show()
|
||||
this.modalObj
|
||||
.find('.modal-header .back')
|
||||
.on('click', this.options.backBtnCb)
|
||||
} else {
|
||||
this.modalObj.find('.modal-header .back').hide()
|
||||
}
|
||||
}
|
||||
|
||||
setTitle () {
|
||||
if (typeof this.options.title !== 'undefined') {
|
||||
this.modalObj.find('.modal-title').html(this.options.title)
|
||||
}
|
||||
}
|
||||
|
||||
setSubtitle () {
|
||||
if (this.options.subtitle) {
|
||||
this.modalObj
|
||||
.find('.modal-subtitle')
|
||||
.show()
|
||||
.html(this.options.subtitle)
|
||||
} else {
|
||||
this.modalObj
|
||||
.find('.modal-subtitle')
|
||||
.hide()
|
||||
.html('')
|
||||
}
|
||||
}
|
||||
|
||||
setContent () {
|
||||
var self = this
|
||||
if (typeof this.options.url !== 'undefined') {
|
||||
this.method = 'request'
|
||||
$.get(this.options.url, function (response) {
|
||||
self.modalObj.find('.modal-body').html(response)
|
||||
self.options.onUrlLoaded(self)
|
||||
})
|
||||
} else if (this.options.content instanceof jQuery) {
|
||||
self.modalObj.find('.modal-body').append(this.options.content)
|
||||
} else if (typeof this.options.content !== 'undefined') {
|
||||
self.modalObj.find('.modal-body').html(this.options.content)
|
||||
}
|
||||
};
|
||||
|
||||
setButtons () {
|
||||
if (this.options.hideFooter) {
|
||||
this.modalObj.find('.modal-footer').hide()
|
||||
} else {
|
||||
if (this.options.actionBtnCb) {
|
||||
this.modalObj.find('.btn-action').text(this.options.actionBtnLabel)
|
||||
this.modalObj.find('.btn-action').on('click', this.options.actionBtnCb)
|
||||
} else {
|
||||
this.modalObj.find('.btn-action').hide()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open () {
|
||||
if (this.isOpen) {
|
||||
return
|
||||
}
|
||||
this.toggle()
|
||||
this.isOpen = true
|
||||
}
|
||||
|
||||
toggle () {
|
||||
this.modal[this.isOpen ? 'hide' : 'show']()
|
||||
this.isOpen = !this.isOpen
|
||||
}
|
||||
|
||||
close () {
|
||||
if (!this.isOpen) {
|
||||
return
|
||||
}
|
||||
|
||||
this.modal.hide()
|
||||
this.options.onClose()
|
||||
this.isOpen = false
|
||||
}
|
||||
}
|
||||
|
||||
export default Modal
|
@@ -0,0 +1,44 @@
|
||||
import $ from 'jquery'
|
||||
|
||||
let Navbar = {
|
||||
/**
|
||||
* Navbar component
|
||||
*
|
||||
* Adds a menu toggler for mobile and does some styling
|
||||
*/
|
||||
init: function (config) {
|
||||
this.menuAlwaysCollapsed = config.menuAlwaysCollapsed
|
||||
this.fixNodes()
|
||||
},
|
||||
fixNodes: function () {
|
||||
if (!this.menuAlwaysCollapsed) {
|
||||
$('#header').addClass('expand')
|
||||
} else {
|
||||
$('#header').addClass('menu-always-collapsed')
|
||||
}
|
||||
// insert burger
|
||||
$('#branding').before(
|
||||
$('<button/>', {
|
||||
'class': 'navbar-toggler navbar-toggler-right',
|
||||
'data-bs-toggle': 'collapse'
|
||||
}).html('<i class="fa fa-bars"></i>')
|
||||
.click(() => $(document.body).addClass('menu-open')))
|
||||
// remove only text
|
||||
$('#user-tools')
|
||||
.contents().filter(function () {
|
||||
return (this.nodeType === 3)
|
||||
}).remove()
|
||||
// dropdown
|
||||
let dropdown = $('<div/>', { 'class': 'dropdown' }).appendTo($('#user-tools'))
|
||||
let dropdownMenu = $('<div/>', { 'class': 'dropdown-menu dropdown-menu-right' }).appendTo(dropdown)
|
||||
$('#user-tools strong')
|
||||
.addClass('dropdown-toggle btn btn-default')
|
||||
.attr('data-bs-toggle', 'dropdown')
|
||||
.prependTo(dropdown)
|
||||
// @TODO find a way to mv view site from dropdown
|
||||
// password change view doesn't have it so breaks things
|
||||
$('#user-tools > a').addClass('dropdown-item').appendTo(dropdownMenu)
|
||||
}
|
||||
}
|
||||
|
||||
export default Navbar
|
@@ -0,0 +1,9 @@
|
||||
import $ from 'jquery'
|
||||
|
||||
let PasswordChange = {
|
||||
init: function () {
|
||||
$('body').addClass('passwordchange')
|
||||
}
|
||||
}
|
||||
|
||||
export default PasswordChange
|
163
venv/Lib/site-packages/baton/static/baton/app/src/core/Tabs.js
Normal file
@@ -0,0 +1,163 @@
|
||||
import $ from 'jquery'
|
||||
import bootstrap from 'bootstrap/dist/js/bootstrap.bundle'
|
||||
|
||||
let Tabs = {
|
||||
/**
|
||||
* Tabs component
|
||||
*/
|
||||
init: function (Dispatcher) {
|
||||
this.Dispatcher = Dispatcher
|
||||
if (this.shouldRun()) {
|
||||
console.info('Baton:', 'generating tabs')
|
||||
this.main.attr('data-baton-tab', 'main-tab')
|
||||
this.createNav()
|
||||
this.createPanes()
|
||||
this.checkHash()
|
||||
this.showErrors()
|
||||
this.Dispatcher.emit('onTabsReady')
|
||||
}
|
||||
},
|
||||
shouldRun: function () {
|
||||
this.main = $('#content-main form .baton-tabs-init')
|
||||
return this.main.length === 1
|
||||
},
|
||||
createNav: function () {
|
||||
this.mainOrder = 0
|
||||
this.tabsEl = []
|
||||
this.domTabsEl = []
|
||||
let classes = this.main.attr('class')
|
||||
classes.split(' ').forEach((cl) => {
|
||||
if (/baton-tab-/.test(cl)) {
|
||||
this.tabsEl.push(cl.substring(10))
|
||||
}
|
||||
if (/order-/.test(cl)) {
|
||||
this.mainOrder = parseInt(cl.replace('order-', ''))
|
||||
}
|
||||
})
|
||||
|
||||
let currentOrder = this.mainOrder ? 0 : this.mainOrder + 1
|
||||
|
||||
this.nav = $('<ul />', { 'class': 'nav nav-tabs' })
|
||||
$('<li />', { 'class': 'nav-item' })
|
||||
.css('order', this.mainOrder)
|
||||
.append($('<a />', {
|
||||
'class': 'nav-link' + (this.mainOrder === 0 ? ' active' : ''),
|
||||
'data-bs-toggle': 'tab',
|
||||
'data-bs-target': '#main-tab'
|
||||
// href: '#main-tab'
|
||||
}).text(this.main.children('h2').hide().text()))
|
||||
.appendTo(this.nav)
|
||||
|
||||
this.tabsEl.forEach((el) => {
|
||||
let domEl
|
||||
if (/^group-/.test(el)) {
|
||||
domEl = $('<div />').attr('data-baton-tab', el)
|
||||
let items = el.substr(6).split('--')
|
||||
items.forEach((item) => {
|
||||
let e
|
||||
if (/^inline-/.test(item)) {
|
||||
e = this.createInlineEl(item)
|
||||
} else {
|
||||
e = this.createFieldsetEl(item)
|
||||
}
|
||||
domEl.append(e)
|
||||
})
|
||||
} else if (/^inline-/.test(el)) {
|
||||
domEl = this.createInlineEl(el, true)
|
||||
} else {
|
||||
domEl = this.createFieldsetEl(el, true)
|
||||
}
|
||||
this.domTabsEl.push(domEl)
|
||||
$('<li />', { 'class': 'nav-item ' })
|
||||
.css('order', currentOrder)
|
||||
.append($('<a />', {
|
||||
'class': 'nav-link ' + (currentOrder === 0 ? ' active' : ''),
|
||||
'data-bs-toggle': 'tab',
|
||||
'data-bs-target': '#' + el
|
||||
// href: '#' + el
|
||||
}).text(domEl.find('h2:first-child').first().hide().text()))
|
||||
.appendTo(this.nav)
|
||||
currentOrder += 1
|
||||
if (currentOrder === this.mainOrder) {
|
||||
currentOrder += 1
|
||||
}
|
||||
})
|
||||
|
||||
this.main.before(this.nav)
|
||||
|
||||
$('a[data-bs-toggle="tab"]').on('shown.bs.tab', function (e) {
|
||||
// add hash to stay in same tab when save and continue
|
||||
const hash = $(e.target).attr('data-bs-target')
|
||||
window.location.replace(hash) // adding with replace won't add an history entry
|
||||
let tooltipTriggerList = [].slice.call($('[title]:not(iframe)'))
|
||||
tooltipTriggerList.map(function (tooltipTriggerEl) {
|
||||
return new bootstrap.Tooltip(tooltipTriggerEl)
|
||||
})
|
||||
})
|
||||
},
|
||||
createInlineEl: function (el, setDataTab = false) {
|
||||
let domEl
|
||||
if ($('#' + el.substring(7) + '_set-group').length) { // no related_name
|
||||
domEl = $('#' + el.substring(7) + '_set-group')
|
||||
} else {
|
||||
domEl = $('#' + el.substring(7) + '-group')
|
||||
}
|
||||
if (setDataTab) {
|
||||
domEl.attr('data-baton-tab', el)
|
||||
}
|
||||
return domEl
|
||||
},
|
||||
createFieldsetEl: function (el, setDataTab = false) {
|
||||
let domEl = $('.tab-' + el)
|
||||
if (setDataTab) {
|
||||
domEl.attr('data-baton-tab', el)
|
||||
}
|
||||
return domEl
|
||||
},
|
||||
createPanes: function () {
|
||||
let self = this
|
||||
this.tabContent = $('<div />', { 'class': 'tab-content' })
|
||||
this.tabMain = $('<div />', {
|
||||
'class': 'tab-pane fade' + (this.mainOrder === 0 ? ' active show' : ''),
|
||||
'id': 'main-tab'
|
||||
}).appendTo(this.tabContent)
|
||||
this.main.parent().children(':not(.nav-tabs):not(.submit-row):not(.errornote):not(.tab-fs-none)')
|
||||
.each((index, el) => {
|
||||
$(el).appendTo(self.tabMain)
|
||||
})
|
||||
this.nav.after(this.tabContent)
|
||||
|
||||
let currentOrder = this.mainOrder ? 0 : this.mainOrder + 1
|
||||
|
||||
this.domTabsEl.forEach((el, index) => {
|
||||
let tabPane = $('<div />', {
|
||||
'class': 'tab-pane' + (currentOrder === 0 ? ' active show' : ''),
|
||||
'id': self.tabsEl[index]
|
||||
}).appendTo(this.tabContent)
|
||||
el.appendTo(tabPane)
|
||||
currentOrder += 1
|
||||
if (currentOrder === this.mainOrder) {
|
||||
currentOrder += 1
|
||||
}
|
||||
})
|
||||
},
|
||||
showErrors: function () {
|
||||
let els = [this.main, ...this.domTabsEl]
|
||||
for (let i = 0, len = els.length; i < len; i++) {
|
||||
let el = els[i]
|
||||
if (el.find('.form-row.errors, .errorlist').length) {
|
||||
const tab = new bootstrap.Tab(this.nav.find('a[data-bs-target="#' + el.attr('data-baton-tab') + '"]')[0])
|
||||
tab.show()
|
||||
break
|
||||
}
|
||||
}
|
||||
},
|
||||
checkHash: function () {
|
||||
if (location.hash && this.nav.find('a[data-bs-target="' + location.hash + '"]').length) {
|
||||
const tab = new bootstrap.Tab(this.nav.find('a[data-bs-target="' + location.hash + '"]')[0])
|
||||
tab.show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Tabs
|
@@ -0,0 +1,600 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
|
||||
* This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||||
* The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||||
* The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||||
* Code distributed by Google as part of the polymer project is also
|
||||
* subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||||
*/
|
||||
|
||||
// minimal template polyfill
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
var needsTemplate = (typeof HTMLTemplateElement === 'undefined');
|
||||
var brokenDocFragment = !(document.createDocumentFragment().cloneNode() instanceof DocumentFragment);
|
||||
var needsDocFrag = false;
|
||||
|
||||
// NOTE: Replace DocumentFragment to work around IE11 bug that
|
||||
// causes children of a document fragment modified while
|
||||
// there is a mutation observer to not have a parentNode, or
|
||||
// have a broken parentNode (!?!)
|
||||
if (/Trident/.test(navigator.userAgent)) {
|
||||
(function() {
|
||||
|
||||
needsDocFrag = true;
|
||||
|
||||
var origCloneNode = Node.prototype.cloneNode;
|
||||
Node.prototype.cloneNode = function cloneNode(deep) {
|
||||
var newDom = origCloneNode.call(this, deep);
|
||||
if (this instanceof DocumentFragment) {
|
||||
newDom.__proto__ = DocumentFragment.prototype;
|
||||
}
|
||||
return newDom;
|
||||
};
|
||||
|
||||
// IE's DocumentFragment querySelector code doesn't work when
|
||||
// called on an element instance
|
||||
DocumentFragment.prototype.querySelectorAll = HTMLElement.prototype.querySelectorAll;
|
||||
DocumentFragment.prototype.querySelector = HTMLElement.prototype.querySelector;
|
||||
|
||||
Object.defineProperties(DocumentFragment.prototype, {
|
||||
'nodeType': {
|
||||
get: function () {
|
||||
return Node.DOCUMENT_FRAGMENT_NODE;
|
||||
},
|
||||
configurable: true
|
||||
},
|
||||
|
||||
'localName': {
|
||||
get: function () {
|
||||
return undefined;
|
||||
},
|
||||
configurable: true
|
||||
},
|
||||
|
||||
'nodeName': {
|
||||
get: function () {
|
||||
return '#document-fragment';
|
||||
},
|
||||
configurable: true
|
||||
}
|
||||
});
|
||||
|
||||
var origInsertBefore = Node.prototype.insertBefore;
|
||||
function insertBefore(newNode, refNode) {
|
||||
if (newNode instanceof DocumentFragment) {
|
||||
var child;
|
||||
while ((child = newNode.firstChild)) {
|
||||
origInsertBefore.call(this, child, refNode);
|
||||
}
|
||||
} else {
|
||||
origInsertBefore.call(this, newNode, refNode);
|
||||
}
|
||||
return newNode;
|
||||
}
|
||||
Node.prototype.insertBefore = insertBefore;
|
||||
|
||||
var origAppendChild = Node.prototype.appendChild;
|
||||
Node.prototype.appendChild = function appendChild(child) {
|
||||
if (child instanceof DocumentFragment) {
|
||||
insertBefore.call(this, child, null);
|
||||
} else {
|
||||
origAppendChild.call(this, child);
|
||||
}
|
||||
return child;
|
||||
};
|
||||
|
||||
var origRemoveChild = Node.prototype.removeChild;
|
||||
var origReplaceChild = Node.prototype.replaceChild;
|
||||
Node.prototype.replaceChild = function replaceChild(newChild, oldChild) {
|
||||
if (newChild instanceof DocumentFragment) {
|
||||
insertBefore.call(this, newChild, oldChild);
|
||||
origRemoveChild.call(this, oldChild);
|
||||
} else {
|
||||
origReplaceChild.call(this, newChild, oldChild);
|
||||
}
|
||||
return oldChild;
|
||||
};
|
||||
|
||||
Document.prototype.createDocumentFragment = function createDocumentFragment() {
|
||||
var frag = this.createElement('df');
|
||||
frag.__proto__ = DocumentFragment.prototype;
|
||||
return frag;
|
||||
};
|
||||
|
||||
var origImportNode = Document.prototype.importNode;
|
||||
Document.prototype.importNode = function importNode(impNode, deep) {
|
||||
deep = deep || false;
|
||||
var newNode = origImportNode.call(this, impNode, deep);
|
||||
if (impNode instanceof DocumentFragment) {
|
||||
newNode.__proto__ = DocumentFragment.prototype;
|
||||
}
|
||||
return newNode;
|
||||
};
|
||||
})();
|
||||
}
|
||||
|
||||
// NOTE: we rely on this cloneNode not causing element upgrade.
|
||||
// This means this polyfill must load before the CE polyfill and
|
||||
// this would need to be re-worked if a browser supports native CE
|
||||
// but not <template>.
|
||||
var capturedCloneNode = Node.prototype.cloneNode;
|
||||
var capturedCreateElement = Document.prototype.createElement;
|
||||
var capturedImportNode = Document.prototype.importNode;
|
||||
var capturedRemoveChild = Node.prototype.removeChild;
|
||||
var capturedAppendChild = Node.prototype.appendChild;
|
||||
var capturedReplaceChild = Node.prototype.replaceChild;
|
||||
var capturedParseFromString = DOMParser.prototype.parseFromString;
|
||||
var capturedHTMLElementInnerHTML = Object.getOwnPropertyDescriptor(window.HTMLElement.prototype, 'innerHTML') || {
|
||||
/**
|
||||
* @this {!HTMLElement}
|
||||
* @return {string}
|
||||
*/
|
||||
get: function() {
|
||||
return this.innerHTML;
|
||||
},
|
||||
/**
|
||||
* @this {!HTMLElement}
|
||||
* @param {string}
|
||||
*/
|
||||
set: function(text) {
|
||||
this.innerHTML = text;
|
||||
}
|
||||
};
|
||||
var capturedChildNodes = Object.getOwnPropertyDescriptor(window.Node.prototype, 'childNodes') || {
|
||||
/**
|
||||
* @this {!Node}
|
||||
* @return {!NodeList}
|
||||
*/
|
||||
get: function() {
|
||||
return this.childNodes;
|
||||
}
|
||||
};
|
||||
|
||||
var elementQuerySelectorAll = Element.prototype.querySelectorAll;
|
||||
var docQuerySelectorAll = Document.prototype.querySelectorAll;
|
||||
var fragQuerySelectorAll = DocumentFragment.prototype.querySelectorAll;
|
||||
|
||||
var scriptSelector = 'script:not([type]),script[type="application/javascript"],script[type="text/javascript"]';
|
||||
|
||||
function QSA(node, selector) {
|
||||
// IE 11 throws a SyntaxError with `scriptSelector` if the node has no children due to the `:not([type])` syntax
|
||||
if (!node.childNodes.length) {
|
||||
return [];
|
||||
}
|
||||
switch (node.nodeType) {
|
||||
case Node.DOCUMENT_NODE:
|
||||
return docQuerySelectorAll.call(node, selector);
|
||||
case Node.DOCUMENT_FRAGMENT_NODE:
|
||||
return fragQuerySelectorAll.call(node, selector);
|
||||
default:
|
||||
return elementQuerySelectorAll.call(node, selector);
|
||||
}
|
||||
}
|
||||
|
||||
// returns true if nested templates cannot be cloned (they cannot be on
|
||||
// some impl's like Safari 8 and Edge)
|
||||
// OR if cloning a document fragment does not result in a document fragment
|
||||
var needsCloning = (function() {
|
||||
if (!needsTemplate) {
|
||||
var t = document.createElement('template');
|
||||
var t2 = document.createElement('template');
|
||||
t2.content.appendChild(document.createElement('div'));
|
||||
t.content.appendChild(t2);
|
||||
var clone = t.cloneNode(true);
|
||||
return (clone.content.childNodes.length === 0 || clone.content.firstChild.content.childNodes.length === 0
|
||||
|| brokenDocFragment);
|
||||
}
|
||||
})();
|
||||
|
||||
var TEMPLATE_TAG = 'template';
|
||||
var PolyfilledHTMLTemplateElement = function() {};
|
||||
|
||||
if (needsTemplate) {
|
||||
|
||||
var contentDoc = document.implementation.createHTMLDocument('template');
|
||||
var canDecorate = true;
|
||||
|
||||
var templateStyle = document.createElement('style');
|
||||
templateStyle.textContent = TEMPLATE_TAG + '{display:none;}';
|
||||
|
||||
var head = document.head;
|
||||
head.insertBefore(templateStyle, head.firstElementChild);
|
||||
|
||||
/**
|
||||
Provides a minimal shim for the <template> element.
|
||||
*/
|
||||
PolyfilledHTMLTemplateElement.prototype = Object.create(HTMLElement.prototype);
|
||||
|
||||
|
||||
// if elements do not have `innerHTML` on instances, then
|
||||
// templates can be patched by swizzling their prototypes.
|
||||
var canProtoPatch =
|
||||
!(document.createElement('div').hasOwnProperty('innerHTML'));
|
||||
|
||||
/**
|
||||
The `decorate` method moves element children to the template's `content`.
|
||||
NOTE: there is no support for dynamically adding elements to templates.
|
||||
*/
|
||||
PolyfilledHTMLTemplateElement.decorate = function(template) {
|
||||
// if the template is decorated or not in HTML namespace, return fast
|
||||
if (template.content ||
|
||||
template.namespaceURI !== document.documentElement.namespaceURI) {
|
||||
return;
|
||||
}
|
||||
template.content = contentDoc.createDocumentFragment();
|
||||
var child;
|
||||
while ((child = template.firstChild)) {
|
||||
capturedAppendChild.call(template.content, child);
|
||||
}
|
||||
// NOTE: prefer prototype patching for performance and
|
||||
// because on some browsers (IE11), re-defining `innerHTML`
|
||||
// can result in intermittent errors.
|
||||
if (canProtoPatch) {
|
||||
template.__proto__ = PolyfilledHTMLTemplateElement.prototype;
|
||||
} else {
|
||||
template.cloneNode = function(deep) {
|
||||
return PolyfilledHTMLTemplateElement._cloneNode(this, deep);
|
||||
};
|
||||
// add innerHTML to template, if possible
|
||||
// Note: this throws on Safari 7
|
||||
if (canDecorate) {
|
||||
try {
|
||||
defineInnerHTML(template);
|
||||
defineOuterHTML(template);
|
||||
} catch (err) {
|
||||
canDecorate = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
// bootstrap recursively
|
||||
PolyfilledHTMLTemplateElement.bootstrap(template.content);
|
||||
};
|
||||
|
||||
// Taken from https://github.com/jquery/jquery/blob/73d7e6259c63ac45f42c6593da8c2796c6ce9281/src/manipulation/wrapMap.js
|
||||
var topLevelWrappingMap = {
|
||||
'option': ['select'],
|
||||
'thead': ['table'],
|
||||
'col': ['colgroup', 'table'],
|
||||
'tr': ['tbody', 'table'],
|
||||
'th': ['tr', 'tbody', 'table'],
|
||||
'td': ['tr', 'tbody', 'table']
|
||||
};
|
||||
|
||||
var getTagName = function(text) {
|
||||
// Taken from https://github.com/jquery/jquery/blob/73d7e6259c63ac45f42c6593da8c2796c6ce9281/src/manipulation/var/rtagName.js
|
||||
return ( /<([a-z][^/\0>\x20\t\r\n\f]+)/i.exec(text) || ['', ''])[1].toLowerCase();
|
||||
};
|
||||
|
||||
var defineInnerHTML = function defineInnerHTML(obj) {
|
||||
Object.defineProperty(obj, 'innerHTML', {
|
||||
get: function() {
|
||||
return getInnerHTML(this);
|
||||
},
|
||||
set: function(text) {
|
||||
// For IE11, wrap the text in the correct (table) context
|
||||
var wrap = topLevelWrappingMap[getTagName(text)];
|
||||
if (wrap) {
|
||||
for (var i = 0; i < wrap.length; i++) {
|
||||
text = '<' + wrap[i] + '>' + text + '</' + wrap[i] + '>';
|
||||
}
|
||||
}
|
||||
contentDoc.body.innerHTML = text;
|
||||
PolyfilledHTMLTemplateElement.bootstrap(contentDoc);
|
||||
while (this.content.firstChild) {
|
||||
capturedRemoveChild.call(this.content, this.content.firstChild);
|
||||
}
|
||||
var body = contentDoc.body;
|
||||
// If we had wrapped, get back to the original node
|
||||
if (wrap) {
|
||||
for (var j = 0; j < wrap.length; j++) {
|
||||
body = body.lastChild;
|
||||
}
|
||||
}
|
||||
while (body.firstChild) {
|
||||
capturedAppendChild.call(this.content, body.firstChild);
|
||||
}
|
||||
},
|
||||
configurable: true
|
||||
});
|
||||
};
|
||||
|
||||
var defineOuterHTML = function defineOuterHTML(obj) {
|
||||
Object.defineProperty(obj, 'outerHTML', {
|
||||
get: function() {
|
||||
return '<' + TEMPLATE_TAG + '>' + this.innerHTML + '</' + TEMPLATE_TAG + '>';
|
||||
},
|
||||
set: function(innerHTML) {
|
||||
if (this.parentNode) {
|
||||
contentDoc.body.innerHTML = innerHTML;
|
||||
var docFrag = this.ownerDocument.createDocumentFragment();
|
||||
while (contentDoc.body.firstChild) {
|
||||
capturedAppendChild.call(docFrag, contentDoc.body.firstChild);
|
||||
}
|
||||
capturedReplaceChild.call(this.parentNode, docFrag, this);
|
||||
} else {
|
||||
throw new Error("Failed to set the 'outerHTML' property on 'Element': This element has no parent node.");
|
||||
}
|
||||
},
|
||||
configurable: true
|
||||
});
|
||||
};
|
||||
|
||||
defineInnerHTML(PolyfilledHTMLTemplateElement.prototype);
|
||||
defineOuterHTML(PolyfilledHTMLTemplateElement.prototype);
|
||||
|
||||
/**
|
||||
The `bootstrap` method is called automatically and "fixes" all
|
||||
<template> elements in the document referenced by the `doc` argument.
|
||||
*/
|
||||
PolyfilledHTMLTemplateElement.bootstrap = function bootstrap(doc) {
|
||||
var templates = QSA(doc, TEMPLATE_TAG);
|
||||
for (var i=0, l=templates.length, t; (i<l) && (t=templates[i]); i++) {
|
||||
PolyfilledHTMLTemplateElement.decorate(t);
|
||||
}
|
||||
};
|
||||
|
||||
// auto-bootstrapping for main document
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
PolyfilledHTMLTemplateElement.bootstrap(document);
|
||||
});
|
||||
|
||||
// Patch document.createElement to ensure newly created templates have content
|
||||
Document.prototype.createElement = function createElement() {
|
||||
var el = capturedCreateElement.apply(this, arguments);
|
||||
if (el.localName === 'template') {
|
||||
PolyfilledHTMLTemplateElement.decorate(el);
|
||||
}
|
||||
return el;
|
||||
};
|
||||
|
||||
DOMParser.prototype.parseFromString = function() {
|
||||
var el = capturedParseFromString.apply(this, arguments);
|
||||
PolyfilledHTMLTemplateElement.bootstrap(el);
|
||||
return el;
|
||||
};
|
||||
|
||||
Object.defineProperty(HTMLElement.prototype, 'innerHTML', {
|
||||
get: function() {
|
||||
return getInnerHTML(this);
|
||||
},
|
||||
set: function(text) {
|
||||
capturedHTMLElementInnerHTML.set.call(this, text);
|
||||
PolyfilledHTMLTemplateElement.bootstrap(this);
|
||||
},
|
||||
configurable: true,
|
||||
enumerable: true
|
||||
});
|
||||
|
||||
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#escapingString
|
||||
var escapeAttrRegExp = /[&\u00A0"]/g;
|
||||
var escapeDataRegExp = /[&\u00A0<>]/g;
|
||||
|
||||
var escapeReplace = function(c) {
|
||||
switch (c) {
|
||||
case '&':
|
||||
return '&';
|
||||
case '<':
|
||||
return '<';
|
||||
case '>':
|
||||
return '>';
|
||||
case '"':
|
||||
return '"';
|
||||
case '\u00A0':
|
||||
return ' ';
|
||||
}
|
||||
};
|
||||
|
||||
var escapeAttr = function(s) {
|
||||
return s.replace(escapeAttrRegExp, escapeReplace);
|
||||
};
|
||||
|
||||
var escapeData = function(s) {
|
||||
return s.replace(escapeDataRegExp, escapeReplace);
|
||||
};
|
||||
|
||||
var makeSet = function(arr) {
|
||||
var set = {};
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
set[arr[i]] = true;
|
||||
}
|
||||
return set;
|
||||
};
|
||||
|
||||
// http://www.whatwg.org/specs/web-apps/current-work/#void-elements
|
||||
var voidElements = makeSet([
|
||||
'area',
|
||||
'base',
|
||||
'br',
|
||||
'col',
|
||||
'command',
|
||||
'embed',
|
||||
'hr',
|
||||
'img',
|
||||
'input',
|
||||
'keygen',
|
||||
'link',
|
||||
'meta',
|
||||
'param',
|
||||
'source',
|
||||
'track',
|
||||
'wbr'
|
||||
]);
|
||||
|
||||
var plaintextParents = makeSet([
|
||||
'style',
|
||||
'script',
|
||||
'xmp',
|
||||
'iframe',
|
||||
'noembed',
|
||||
'noframes',
|
||||
'plaintext',
|
||||
'noscript'
|
||||
]);
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @param {Node} parentNode
|
||||
* @param {Function=} callback
|
||||
*/
|
||||
var getOuterHTML = function(node, parentNode, callback) {
|
||||
switch (node.nodeType) {
|
||||
case Node.ELEMENT_NODE: {
|
||||
var tagName = node.localName;
|
||||
var s = '<' + tagName;
|
||||
var attrs = node.attributes;
|
||||
for (var i = 0, attr; (attr = attrs[i]); i++) {
|
||||
s += ' ' + attr.name + '="' + escapeAttr(attr.value) + '"';
|
||||
}
|
||||
s += '>';
|
||||
if (voidElements[tagName]) {
|
||||
return s;
|
||||
}
|
||||
return s + getInnerHTML(node, callback) + '</' + tagName + '>';
|
||||
}
|
||||
case Node.TEXT_NODE: {
|
||||
var data = /** @type {Text} */ (node).data;
|
||||
if (parentNode && plaintextParents[parentNode.localName]) {
|
||||
return data;
|
||||
}
|
||||
return escapeData(data);
|
||||
}
|
||||
case Node.COMMENT_NODE: {
|
||||
return '<!--' + /** @type {Comment} */ (node).data + '-->';
|
||||
}
|
||||
default: {
|
||||
window.console.error(node);
|
||||
throw new Error('not implemented');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @param {Function=} callback
|
||||
*/
|
||||
var getInnerHTML = function(node, callback) {
|
||||
if (node.localName === 'template') {
|
||||
node = /** @type {HTMLTemplateElement} */ (node).content;
|
||||
}
|
||||
var s = '';
|
||||
var c$ = callback ? callback(node) : capturedChildNodes.get.call(node);
|
||||
for (var i=0, l=c$.length, child; (i<l) && (child=c$[i]); i++) {
|
||||
s += getOuterHTML(child, node, callback);
|
||||
}
|
||||
return s;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// make cloning/importing work!
|
||||
if (needsTemplate || needsCloning) {
|
||||
|
||||
PolyfilledHTMLTemplateElement._cloneNode = function _cloneNode(template, deep) {
|
||||
var clone = capturedCloneNode.call(template, false);
|
||||
// NOTE: decorate doesn't auto-fix children because they are already
|
||||
// decorated so they need special clone fixup.
|
||||
if (this.decorate) {
|
||||
this.decorate(clone);
|
||||
}
|
||||
if (deep) {
|
||||
// NOTE: use native clone node to make sure CE's wrapped
|
||||
// cloneNode does not cause elements to upgrade.
|
||||
capturedAppendChild.call(clone.content, capturedCloneNode.call(template.content, true));
|
||||
// now ensure nested templates are cloned correctly.
|
||||
fixClonedDom(clone.content, template.content);
|
||||
}
|
||||
return clone;
|
||||
};
|
||||
|
||||
// Given a source and cloned subtree, find <template>'s in the cloned
|
||||
// subtree and replace them with cloned <template>'s from source.
|
||||
// We must do this because only the source templates have proper .content.
|
||||
var fixClonedDom = function fixClonedDom(clone, source) {
|
||||
// do nothing if cloned node is not an element
|
||||
if (!source.querySelectorAll) return;
|
||||
// these two lists should be coincident
|
||||
var s$ = QSA(source, TEMPLATE_TAG);
|
||||
if (s$.length === 0) {
|
||||
return;
|
||||
}
|
||||
var t$ = QSA(clone, TEMPLATE_TAG);
|
||||
for (var i=0, l=t$.length, t, s; i<l; i++) {
|
||||
s = s$[i];
|
||||
t = t$[i];
|
||||
if (PolyfilledHTMLTemplateElement && PolyfilledHTMLTemplateElement.decorate) {
|
||||
PolyfilledHTMLTemplateElement.decorate(s);
|
||||
}
|
||||
capturedReplaceChild.call(t.parentNode, cloneNode.call(s, true), t);
|
||||
}
|
||||
};
|
||||
|
||||
// make sure scripts inside of a cloned template are executable
|
||||
var fixClonedScripts = function fixClonedScripts(fragment) {
|
||||
var scripts = QSA(fragment, scriptSelector);
|
||||
for (var ns, s, i = 0; i < scripts.length; i++) {
|
||||
s = scripts[i];
|
||||
ns = capturedCreateElement.call(document, 'script');
|
||||
ns.textContent = s.textContent;
|
||||
var attrs = s.attributes;
|
||||
for (var ai = 0, a; ai < attrs.length; ai++) {
|
||||
a = attrs[ai];
|
||||
ns.setAttribute(a.name, a.value);
|
||||
}
|
||||
capturedReplaceChild.call(s.parentNode, ns, s);
|
||||
}
|
||||
};
|
||||
|
||||
// override all cloning to fix the cloned subtree to contain properly
|
||||
// cloned templates.
|
||||
var cloneNode = Node.prototype.cloneNode = function cloneNode(deep) {
|
||||
var dom;
|
||||
// workaround for Edge bug cloning documentFragments
|
||||
// https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/8619646/
|
||||
if (!needsDocFrag && brokenDocFragment && this instanceof DocumentFragment) {
|
||||
if (!deep) {
|
||||
return this.ownerDocument.createDocumentFragment();
|
||||
} else {
|
||||
dom = importNode.call(this.ownerDocument, this, true);
|
||||
}
|
||||
} else if (this.nodeType === Node.ELEMENT_NODE &&
|
||||
this.localName === TEMPLATE_TAG &&
|
||||
this.namespaceURI == document.documentElement.namespaceURI) {
|
||||
dom = PolyfilledHTMLTemplateElement._cloneNode(this, deep);
|
||||
} else {
|
||||
dom = capturedCloneNode.call(this, deep);
|
||||
}
|
||||
// template.content is cloned iff `deep`.
|
||||
if (deep) {
|
||||
fixClonedDom(dom, this);
|
||||
}
|
||||
return dom;
|
||||
};
|
||||
|
||||
// NOTE: we are cloning instead of importing <template>'s.
|
||||
// However, the ownerDocument of the cloned template will be correct!
|
||||
// This is because the native import node creates the right document owned
|
||||
// subtree and `fixClonedDom` inserts cloned templates into this subtree,
|
||||
// thus updating the owner doc.
|
||||
var importNode = Document.prototype.importNode = function importNode(element, deep) {
|
||||
deep = deep || false;
|
||||
if (element.localName === TEMPLATE_TAG) {
|
||||
return PolyfilledHTMLTemplateElement._cloneNode(element, deep);
|
||||
} else {
|
||||
var dom = capturedImportNode.call(this, element, deep);
|
||||
if (deep) {
|
||||
fixClonedDom(dom, element);
|
||||
fixClonedScripts(dom);
|
||||
}
|
||||
return dom;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (needsTemplate) {
|
||||
window.HTMLTemplateElement = PolyfilledHTMLTemplateElement;
|
||||
}
|
||||
|
||||
})();
|
@@ -0,0 +1,61 @@
|
||||
import Translator from './i18n'
|
||||
|
||||
export function copyTextToClipboard (text) {
|
||||
let t = new Translator($('html').attr('lang'))
|
||||
var textArea = document.createElement('textarea')
|
||||
|
||||
//
|
||||
// *** This styling is an extra step which is likely not required. ***
|
||||
//
|
||||
// Why is it here? To ensure:
|
||||
// 1. the element is able to have focus and selection.
|
||||
// 2. if element was to flash render it has minimal visual impact.
|
||||
// 3. less flakyness with selection and copying which **might** occur if
|
||||
// the textarea element is not visible.
|
||||
//
|
||||
// The likelihood is the element won't even render, not even a flash,
|
||||
// so some of these are just precautions. However in IE the element
|
||||
// is visible whilst the popup box asking the user for permission for
|
||||
// the web page to copy to the clipboard.
|
||||
//
|
||||
|
||||
// Place in top-left corner of screen regardless of scroll position.
|
||||
textArea.style.position = 'fixed'
|
||||
textArea.style.top = 0
|
||||
textArea.style.left = 0
|
||||
|
||||
// Ensure it has a small width and height. Setting to 1px / 1em
|
||||
// doesn't work as this gives a negative w/h on some browsers.
|
||||
textArea.style.width = '2em'
|
||||
textArea.style.height = '2em'
|
||||
|
||||
// We don't need padding, reducing the size if it does flash render.
|
||||
textArea.style.padding = 0
|
||||
|
||||
// Clean up any borders.
|
||||
textArea.style.border = 'none'
|
||||
textArea.style.outline = 'none'
|
||||
textArea.style.boxShadow = 'none'
|
||||
|
||||
// Avoid flash of white box if rendered for any reason.
|
||||
textArea.style.background = 'transparent'
|
||||
|
||||
textArea.value = text
|
||||
|
||||
document.body.appendChild(textArea)
|
||||
|
||||
textArea.select()
|
||||
|
||||
try {
|
||||
var successful = document.execCommand('copy')
|
||||
var msg = successful ? 'successful' : 'unsuccessful'
|
||||
console.log('Copying text command was ' + msg)
|
||||
} catch (err) {
|
||||
window.prompt(
|
||||
t.get('cannotCopyToClipboardMessage'),
|
||||
text
|
||||
)
|
||||
}
|
||||
|
||||
document.body.removeChild(textArea)
|
||||
}
|