Compare commits

53 Commits

Author SHA1 Message Date
SDE
3020c6d7e6 0.6.0 switch off ru lang 2024-09-24 13:16:57 +03:00
SDE
7c5ebdcfbf 0.5.28 hide support button 2024-08-03 16:18:37 +03:00
SDE
7560354677 0.5.27 check translate for support 2024-07-25 20:04:59 +03:00
SDE
2dddcab2f2 0.5.26 docs admin add actions for assign version to docs list 2024-07-20 13:42:46 +03:00
SDE
3a4f9e5606 0.5.25 change settings for files 2024-07-19 11:57:43 +03:00
SDE
35f03282af 0.5.24 change settings 2024-07-19 04:21:44 +03:00
SDE
42b9925e60 0.5.23 fix pdf font 2024-07-19 01:32:12 +03:00
SDE
772db778b7 0.5.23 fix get_options_by_opt_types 2024-07-19 01:28:50 +03:00
SDE
1583da5816 0.5.22 fix get_options_by_opt_types 2024-07-19 01:26:24 +03:00
SDE
8e12c7e515 0.5.21 fix get_options_by_opt_types 2024-07-19 01:24:18 +03:00
SDE
be06cb0ef9 0.5.21 fix CKEDITOR_RESTRICT_BY_USER 2024-07-19 01:11:23 +03:00
SDE
4053d17981 0.5.20 fix encodings 2024-07-19 01:03:31 +03:00
SBD
7a95c5c3ef documentation page 2024-07-18 14:18:42 +03:00
SBD
c573d29eb1 documentation page 2024-07-18 14:03:05 +03:00
SBD
f2c3ffe87b documentation page 2024-07-18 13:46:19 +03:00
SBD
a28ebd1958 Merge remote-tracking branch 'origin/main' 2024-07-18 13:39:09 +03:00
SBD
97330ad8e5 documentation page 2024-07-18 13:37:41 +03:00
SDE
2a900c2726 0.5.19 fix next \ prev doc 2024-07-18 13:33:46 +03:00
SDE
fb6676c468 0.5.18 fix next \ prev doc 2024-07-18 13:30:29 +03:00
SDE
2e01e3eeb3 0.5.17 fix docs not allow 2024-07-18 13:04:00 +03:00
SDE
f6f1eefa82 0.5.16 add migration 2024-07-18 12:52:24 +03:00
SDE
442405735d 0.5.15 add migration 2024-07-18 12:46:39 +03:00
SDE
845518b3ef 0.5.14 pdf articles export 2024-07-17 01:50:03 +03:00
SDE
f11a3f0463 0.5.13 pdf articles export 2024-07-16 17:35:33 +03:00
SBD
b132b9e087 documentation page 2024-07-16 14:26:20 +03:00
SBD
1df287c122 documentation page 2024-07-16 13:28:14 +03:00
SBD
309bec8d77 documentation page 2024-07-16 13:16:56 +03:00
SBD
0bfae14abc documentation page 2024-07-16 13:00:01 +03:00
SBD
724e3c6342 documentation page 2024-07-15 17:26:25 +03:00
SBD
131d9dd9b1 documentation page 2024-07-15 16:20:23 +03:00
SBD
4faeb12156 documentation page 2024-07-15 16:17:47 +03:00
SBD
73ce9c0ce3 documentation page 2024-07-15 15:52:25 +03:00
SBD
e03fe21db3 documentation page 2024-07-15 15:38:29 +03:00
SBD
3b4e83a4e2 documentation page 2024-07-15 15:34:43 +03:00
SBD
2d0f98d36c documentation page 2024-07-15 15:26:44 +03:00
SDE
7d971710b5 0.5.12 get_tree_arts fix 2024-07-15 15:25:44 +03:00
SBD
9fa8403e95 documentation page 2024-07-15 15:13:51 +03:00
SBD
03b8f760dc documentation page 2024-07-15 14:53:08 +03:00
SBD
cd77473d5e documentation page 2024-07-15 14:50:36 +03:00
SBD
082e3107e6 documentation page 2024-07-15 14:21:54 +03:00
SBD
8f01426ea6 Merge remote-tracking branch 'origin/main' 2024-07-15 14:21:06 +03:00
SBD
3668d7a549 documentation page 2024-07-15 14:20:53 +03:00
SDE
83d50657ef 0.5.11 documentation file storage 2024-07-15 02:22:53 +03:00
SBD
5f207aed36 documentation page 2024-07-14 18:21:27 +03:00
SBD
b7ba22a56a documentation page 2024-07-14 18:10:09 +03:00
SBD
288c41800f documentation page 2024-07-14 18:09:31 +03:00
SBD
52478534fd documentation page 2024-07-14 17:23:04 +03:00
SBD
e04fef3ca4 documentation page 2024-07-14 17:15:13 +03:00
SDE
cd3be918e3 0.5.10 documentation insert video, file storage 2024-07-14 17:12:05 +03:00
SDE
7e9fb581c3 0.5.10 documentation insert video, file storage 2024-07-14 17:05:05 +03:00
SBD
391908c9ae documentation page 2024-07-14 16:42:20 +03:00
SDE
15938e1fc8 Merge remote-tracking branch 'origin/main' 2024-07-14 14:48:32 +03:00
SDE
65a06dff8e 0.5.9 documentation prev and next article navigation 2024-07-14 14:48:22 +03:00
43 changed files with 1380 additions and 201 deletions

View File

@@ -124,8 +124,10 @@ def init_formfield_for_dbfield(class_model, self, db_field, request, **kwargs):
formfield.widget = admin.widgets.AdminTextareaWidget(attrs={'style': 'width: 80%'})
if db_field.name in ('lexems',):
formfield.widget = admin.widgets.AdminTextareaWidget(attrs={'style': 'width: 80%'})
# if db_field.name == 'answer':
# formfield.widget = admin.widgets.AdminTextareaWidget(attrs={'style': 'width: 80%'})
if db_field.name == 'answer':
formfield.widget = admin.widgets.AdminTextareaWidget(attrs={'style': 'width: 80%'})
# if db_field.name in ['file']:
# formfield.widget = admin.widgets.AdminTextInputWidget(attrs={'style': 'width: 80%'})
if db_field.name in ['question', 'FAQ_title']:
formfield.widget = admin.widgets.AdminTextInputWidget(attrs={'style': 'width: 80%'})
@@ -266,6 +268,20 @@ class Admin_BaseIconTabularModel(admin.TabularInline):
class Admin_BaseIconModel(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
# ckeditor + youtube фикс
for field in form.changed_data:
if 'RichTextUploading' in str(form.fields[field]):
val = getattr(obj, field, None)
if val and type(val) == str:
val = val.replace(' sandbox=""', '')
setattr(obj, field, val)
# setattr(form.instance, field, val)
# form.cleaned_data[field] = form.cleaned_data[field].replace(' sandbox=""', '')
# form.data[field] = form.data[field].replace(' sandbox=""', '')
super().save_model(request, obj, form, change)
def description_exists(self, obj):
if obj.description:

View File

@@ -148,6 +148,11 @@ class BaseModelViewPage(BaseModel):
class Meta:
abstract = True
def save(self, not_change_modifiedDT=False, *args, **kwargs):
if not not_change_modifiedDT:
self.modifiedDT = datetime.now()
super().save(*args, **kwargs)
def get_title(self):
if self.seo_title:
return self.seo_title

View File

@@ -96,27 +96,27 @@ def sortByLength(inputStr):
return len(inputStr)
def add_domain(request, url, add_lang=False):
domain = get_domain_by_request(request)
if add_lang:
cur_lang = get_cur_lang_by_request(request)
return '{0}/{1}/{2}'.format(domain, cur_lang, url)
else:
return '{0}{1}'.format(domain, url)
def get_domain_by_request(request):
from project_sets import domain
if request.query_params and 'domain' in request.query_params:
return request.query_params['domain']
return domain
def get_cur_lang_by_request(request):
from project_sets import lang
if request.query_params and 'cur_lang' in request.query_params:
return request.query_params['cur_lang']
return lang
# def add_domain(request, url, add_lang=False):
# domain = get_domain_by_request(request)
# if add_lang:
# cur_lang = get_cur_lang_by_request(request)
# return '{0}/{1}/{2}'.format(domain, cur_lang, url)
# else:
# return '{0}{1}'.format(domain, url)
#
#
# def get_domain_by_request(request):
# from pAerBim.project_sets import domain
# if request.query_params and 'domain' in request.query_params:
# return request.query_params['domain']
# return domain
#
#
# def get_cur_lang_by_request(request):
# from project_sets import lang
# if request.query_params and 'cur_lang' in request.query_params:
# return request.query_params['cur_lang']
# return lang
def get_img_type_by_request(request):

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,52 @@
/*
* Copyright 2010 wkhtmltopdf authors
*
* This file is part of wkhtmltopdf.
*
* wkhtmltopdf is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* wkhtmltopdf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with wkhtmltopdf. If not, see <http: *www.gnu.org/licenses/>.
*/
#ifndef __WKHTMLTOPDF_DLLBEGIN__
#define __WKHTMLTOPDF_DLLBEGIN__
#if defined _WIN32 || defined __CYGWIN__
#ifdef BUILDING_DLL
#define DLL_PUBLIC __declspec(dllexport)
#else
#define DLL_PUBLIC __declspec(dllimport)
#endif
#define DLL_LOCAL
#else
#if __GNUC__ >= 4
#define DLL_PUBLIC __attribute__ ((visibility("default")))
#define DLL_LOCAL __attribute__ ((visibility("hidden")))
#else
#define DLL_PUBLIC
#define DLL_LOCAL
#endif
#endif
#if defined _WIN32
#define CALLTYPE __stdcall
#else
#define CALLTYPE
#endif
#ifdef __cplusplus
#define CAPI(type) extern "C" DLL_PUBLIC type CALLTYPE
#else
#define CAPI(type) DLL_PUBLIC type CALLTYPE
#endif
#endif /*__WKHTMLTOPDF_DLLBEGIN__*/

View File

@@ -0,0 +1,28 @@
/*
* Copyright 2010 wkhtmltopdf authors
*
* This file is part of wkhtmltopdf.
*
* wkhtmltopdf is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* wkhtmltopdf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with wkhtmltopdf. If not, see <http: *www.gnu.org/licenses/>.
*/
#ifdef __WKHTMLTOPDF_DLLBEGIN__
#undef __WKHTMLTOPDF_DLLBEGIN__
#undef DLL_PUBLIC
#undef DLL_LOCAL
#undef CAPI
#undef CALLTYPE
#endif /*__WKHTMLTOPDF_DLLBEGIN__*/

View File

@@ -0,0 +1,64 @@
/*
* Copyright 2010 wkhtmltopdf authors
*
* This file is part of wkhtmltopdf.
*
* wkhtmltopdf is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* wkhtmltopdf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with wkhtmltopdf. If not, see <http: *www.gnu.org/licenses/>.
*/
#ifndef __IMAGE_H__
#define __IMAGE_H__
#include <wkhtmltox/dllbegin.inc>
struct wkhtmltoimage_global_settings;
typedef struct wkhtmltoimage_global_settings wkhtmltoimage_global_settings;
struct wkhtmltoimage_converter;
typedef struct wkhtmltoimage_converter wkhtmltoimage_converter;
typedef void (*wkhtmltoimage_str_callback)(wkhtmltoimage_converter * converter, const char * str);
typedef void (*wkhtmltoimage_int_callback)(wkhtmltoimage_converter * converter, const int val);
typedef void (*wkhtmltoimage_void_callback)(wkhtmltoimage_converter * converter);
CAPI(int) wkhtmltoimage_init(int use_graphics);
CAPI(int) wkhtmltoimage_deinit();
CAPI(int) wkhtmltoimage_extended_qt();
CAPI(const char *)wkhtmltoimage_version();
CAPI(wkhtmltoimage_global_settings *) wkhtmltoimage_create_global_settings();
CAPI(int) wkhtmltoimage_set_global_setting(wkhtmltoimage_global_settings * settings, const char * name, const char * value);
CAPI(int) wkhtmltoimage_get_global_setting(wkhtmltoimage_global_settings * settings, const char * name, char * value, int vs);
CAPI(wkhtmltoimage_converter *) wkhtmltoimage_create_converter(wkhtmltoimage_global_settings * settings, const char * data);
CAPI(void) wkhtmltoimage_destroy_converter(wkhtmltoimage_converter * converter);
CAPI(void) wkhtmltoimage_set_warning_callback(wkhtmltoimage_converter * converter, wkhtmltoimage_str_callback cb);
CAPI(void) wkhtmltoimage_set_error_callback(wkhtmltoimage_converter * converter, wkhtmltoimage_str_callback cb);
CAPI(void) wkhtmltoimage_set_phase_changed_callback(wkhtmltoimage_converter * converter, wkhtmltoimage_void_callback cb);
CAPI(void) wkhtmltoimage_set_progress_changed_callback(wkhtmltoimage_converter * converter, wkhtmltoimage_int_callback cb);
CAPI(void) wkhtmltoimage_set_finished_callback(wkhtmltoimage_converter * converter, wkhtmltoimage_int_callback cb);
CAPI(int) wkhtmltoimage_convert(wkhtmltoimage_converter * converter);
/* CAPI(void) wkhtmltoimage_begin_conversion(wkhtmltoimage_converter * converter); */
/* CAPI(void) wkhtmltoimage_cancel(wkhtmltoimage_converter * converter); */
CAPI(int) wkhtmltoimage_current_phase(wkhtmltoimage_converter * converter);
CAPI(int) wkhtmltoimage_phase_count(wkhtmltoimage_converter * converter);
CAPI(const char *) wkhtmltoimage_phase_description(wkhtmltoimage_converter * converter, int phase);
CAPI(const char *) wkhtmltoimage_progress_string(wkhtmltoimage_converter * converter);
CAPI(int) wkhtmltoimage_http_error_code(wkhtmltoimage_converter * converter);
CAPI(long) wkhtmltoimage_get_output(wkhtmltoimage_converter * converter, const unsigned char **);
#include <wkhtmltox/dllend.inc>
#endif /*__IMAGE_H__*/

View File

@@ -0,0 +1,76 @@
/*
* Copyright 2010 wkhtmltopdf authors
*
* This file is part of wkhtmltopdf.
*
* wkhtmltopdf is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* wkhtmltopdf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with wkhtmltopdf. If not, see <http: *www.gnu.org/licenses/>.
*/
#ifndef __PDF_H__
#define __PDF_H__
#include <wkhtmltox/dllbegin.inc>
struct wkhtmltopdf_global_settings;
typedef struct wkhtmltopdf_global_settings wkhtmltopdf_global_settings;
struct wkhtmltopdf_object_settings;
typedef struct wkhtmltopdf_object_settings wkhtmltopdf_object_settings;
struct wkhtmltopdf_converter;
typedef struct wkhtmltopdf_converter wkhtmltopdf_converter;
typedef void (*wkhtmltopdf_str_callback)(wkhtmltopdf_converter * converter, const char * str);
typedef void (*wkhtmltopdf_int_callback)(wkhtmltopdf_converter * converter, const int val);
typedef void (*wkhtmltopdf_void_callback)(wkhtmltopdf_converter * converter);
CAPI(int) wkhtmltopdf_init(int use_graphics);
CAPI(int) wkhtmltopdf_deinit();
CAPI(int) wkhtmltopdf_extended_qt();
CAPI(const char *) wkhtmltopdf_version();
CAPI(wkhtmltopdf_global_settings *) wkhtmltopdf_create_global_settings();
CAPI(void) wkhtmltopdf_destroy_global_settings(wkhtmltopdf_global_settings *);
CAPI(wkhtmltopdf_object_settings *) wkhtmltopdf_create_object_settings();
CAPI(void) wkhtmltopdf_destroy_object_settings(wkhtmltopdf_object_settings *);
CAPI(int) wkhtmltopdf_set_global_setting(wkhtmltopdf_global_settings * settings, const char * name, const char * value);
CAPI(int) wkhtmltopdf_get_global_setting(wkhtmltopdf_global_settings * settings, const char * name, char * value, int vs);
CAPI(int) wkhtmltopdf_set_object_setting(wkhtmltopdf_object_settings * settings, const char * name, const char * value);
CAPI(int) wkhtmltopdf_get_object_setting(wkhtmltopdf_object_settings * settings, const char * name, char * value, int vs);
CAPI(wkhtmltopdf_converter *) wkhtmltopdf_create_converter(wkhtmltopdf_global_settings * settings);
CAPI(void) wkhtmltopdf_destroy_converter(wkhtmltopdf_converter * converter);
CAPI(void) wkhtmltopdf_set_warning_callback(wkhtmltopdf_converter * converter, wkhtmltopdf_str_callback cb);
CAPI(void) wkhtmltopdf_set_error_callback(wkhtmltopdf_converter * converter, wkhtmltopdf_str_callback cb);
CAPI(void) wkhtmltopdf_set_phase_changed_callback(wkhtmltopdf_converter * converter, wkhtmltopdf_void_callback cb);
CAPI(void) wkhtmltopdf_set_progress_changed_callback(wkhtmltopdf_converter * converter, wkhtmltopdf_int_callback cb);
CAPI(void) wkhtmltopdf_set_finished_callback(wkhtmltopdf_converter * converter, wkhtmltopdf_int_callback cb);
/* CAPI(void) wkhtmltopdf_begin_conversion(wkhtmltopdf_converter * converter); */
/* CAPI(void) wkhtmltopdf_cancel(wkhtmltopdf_converter * converter); */
CAPI(int) wkhtmltopdf_convert(wkhtmltopdf_converter * converter);
CAPI(void) wkhtmltopdf_add_object(
wkhtmltopdf_converter * converter, wkhtmltopdf_object_settings * setting, const char * data);
CAPI(int) wkhtmltopdf_current_phase(wkhtmltopdf_converter * converter);
CAPI(int) wkhtmltopdf_phase_count(wkhtmltopdf_converter * converter);
CAPI(const char *) wkhtmltopdf_phase_description(wkhtmltopdf_converter * converter, int phase);
CAPI(const char *) wkhtmltopdf_progress_string(wkhtmltopdf_converter * converter);
CAPI(int) wkhtmltopdf_http_error_code(wkhtmltopdf_converter * converter);
CAPI(long) wkhtmltopdf_get_output(wkhtmltopdf_converter * converter, const unsigned char **);
#include <wkhtmltox/dllend.inc>
#endif /*__PDF_H__*/

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,54 @@
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: t; eval: (progn (c-set-style "stroustrup") (c-set-offset 'innamespace 0)); -*-
* vi:set ts=4 sts=4 sw=4 noet :
*
* Copyright 2010-2020 wkhtmltopdf authors
*
* This file is part of wkhtmltopdf.
*
* wkhtmltopdf is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* wkhtmltopdf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with wkhtmltopdf. If not, see <http: *www.gnu.org/licenses/>.
*/
#ifndef __WKHTMLTOPDF_DLLBEGIN__
#define __WKHTMLTOPDF_DLLBEGIN__
#if defined _WIN32 || defined __CYGWIN__
#ifdef BUILDING_DLL
#define DLL_PUBLIC __declspec(dllexport)
#else
#define DLL_PUBLIC __declspec(dllimport)
#endif
#define DLL_LOCAL
#else
#if __GNUC__ >= 4
#define DLL_PUBLIC __attribute__ ((visibility("default")))
#define DLL_LOCAL __attribute__ ((visibility("hidden")))
#else
#define DLL_PUBLIC
#define DLL_LOCAL
#endif
#endif
#if defined _WIN32
#define CALLTYPE __stdcall
#else
#define CALLTYPE
#endif
#ifdef __cplusplus
#define CAPI(type) extern "C" DLL_PUBLIC type CALLTYPE
#else
#define CAPI(type) DLL_PUBLIC type CALLTYPE
#endif
#endif /*__WKHTMLTOPDF_DLLBEGIN__*/

View File

@@ -0,0 +1,30 @@
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: t; eval: (progn (c-set-style "stroustrup") (c-set-offset 'innamespace 0)); -*-
* vi:set ts=4 sts=4 sw=4 noet :
*
* Copyright 2010-2020 wkhtmltopdf authors
*
* This file is part of wkhtmltopdf.
*
* wkhtmltopdf is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* wkhtmltopdf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with wkhtmltopdf. If not, see <http: *www.gnu.org/licenses/>.
*/
#ifdef __WKHTMLTOPDF_DLLBEGIN__
#undef __WKHTMLTOPDF_DLLBEGIN__
#undef DLL_PUBLIC
#undef DLL_LOCAL
#undef CAPI
#undef CALLTYPE
#endif /*__WKHTMLTOPDF_DLLBEGIN__*/

View File

@@ -0,0 +1,76 @@
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: t; eval: (progn (c-set-style "stroustrup") (c-set-offset 'innamespace 0)); -*-
* vi:set ts=4 sts=4 sw=4 noet :
*
* Copyright 2010-2020 wkhtmltopdf authors
*
* This file is part of wkhtmltopdf.
*
* wkhtmltopdf is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* wkhtmltopdf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with wkhtmltopdf. If not, see <http: *www.gnu.org/licenses/>.
*/
#ifndef __IMAGE_H__
#define __IMAGE_H__
#ifdef BUILDING_WKHTMLTOX
#include "dllbegin.inc"
#else
#include <wkhtmltox/dllbegin.inc>
#endif
struct wkhtmltoimage_global_settings;
typedef struct wkhtmltoimage_global_settings wkhtmltoimage_global_settings;
struct wkhtmltoimage_converter;
typedef struct wkhtmltoimage_converter wkhtmltoimage_converter;
typedef void (*wkhtmltoimage_str_callback)(wkhtmltoimage_converter * converter, const char * str);
typedef void (*wkhtmltoimage_int_callback)(wkhtmltoimage_converter * converter, const int val);
typedef void (*wkhtmltoimage_void_callback)(wkhtmltoimage_converter * converter);
CAPI(int) wkhtmltoimage_init(int use_graphics);
CAPI(int) wkhtmltoimage_deinit();
CAPI(int) wkhtmltoimage_extended_qt();
CAPI(const char *)wkhtmltoimage_version();
CAPI(wkhtmltoimage_global_settings *) wkhtmltoimage_create_global_settings();
CAPI(int) wkhtmltoimage_set_global_setting(wkhtmltoimage_global_settings * settings, const char * name, const char * value);
CAPI(int) wkhtmltoimage_get_global_setting(wkhtmltoimage_global_settings * settings, const char * name, char * value, int vs);
CAPI(wkhtmltoimage_converter *) wkhtmltoimage_create_converter(wkhtmltoimage_global_settings * settings, const char * data);
CAPI(void) wkhtmltoimage_destroy_converter(wkhtmltoimage_converter * converter);
CAPI(void) wkhtmltoimage_set_warning_callback(wkhtmltoimage_converter * converter, wkhtmltoimage_str_callback cb);
CAPI(void) wkhtmltoimage_set_error_callback(wkhtmltoimage_converter * converter, wkhtmltoimage_str_callback cb);
CAPI(void) wkhtmltoimage_set_phase_changed_callback(wkhtmltoimage_converter * converter, wkhtmltoimage_void_callback cb);
CAPI(void) wkhtmltoimage_set_progress_changed_callback(wkhtmltoimage_converter * converter, wkhtmltoimage_int_callback cb);
CAPI(void) wkhtmltoimage_set_finished_callback(wkhtmltoimage_converter * converter, wkhtmltoimage_int_callback cb);
CAPI(int) wkhtmltoimage_convert(wkhtmltoimage_converter * converter);
/* CAPI(void) wkhtmltoimage_begin_conversion(wkhtmltoimage_converter * converter); */
/* CAPI(void) wkhtmltoimage_cancel(wkhtmltoimage_converter * converter); */
CAPI(int) wkhtmltoimage_current_phase(wkhtmltoimage_converter * converter);
CAPI(int) wkhtmltoimage_phase_count(wkhtmltoimage_converter * converter);
CAPI(const char *) wkhtmltoimage_phase_description(wkhtmltoimage_converter * converter, int phase);
CAPI(const char *) wkhtmltoimage_progress_string(wkhtmltoimage_converter * converter);
CAPI(int) wkhtmltoimage_http_error_code(wkhtmltoimage_converter * converter);
CAPI(long) wkhtmltoimage_get_output(wkhtmltoimage_converter * converter, const unsigned char **);
#ifdef BUILDING_WKHTMLTOX
#include "dllend.inc"
#else
#include <wkhtmltox/dllend.inc>
#endif
#endif /*__IMAGE_H__*/

View File

@@ -0,0 +1,88 @@
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: t; eval: (progn (c-set-style "stroustrup") (c-set-offset 'innamespace 0)); -*-
* vi:set ts=4 sts=4 sw=4 noet :
*
* Copyright 2010-2020 wkhtmltopdf authors
*
* This file is part of wkhtmltopdf.
*
* wkhtmltopdf is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* wkhtmltopdf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with wkhtmltopdf. If not, see <http: *www.gnu.org/licenses/>.
*/
#ifndef __PDF_H__
#define __PDF_H__
#ifdef BUILDING_WKHTMLTOX
#include "dllbegin.inc"
#else
#include <wkhtmltox/dllbegin.inc>
#endif
struct wkhtmltopdf_global_settings;
typedef struct wkhtmltopdf_global_settings wkhtmltopdf_global_settings;
struct wkhtmltopdf_object_settings;
typedef struct wkhtmltopdf_object_settings wkhtmltopdf_object_settings;
struct wkhtmltopdf_converter;
typedef struct wkhtmltopdf_converter wkhtmltopdf_converter;
typedef void (*wkhtmltopdf_str_callback)(wkhtmltopdf_converter * converter, const char * str);
typedef void (*wkhtmltopdf_int_callback)(wkhtmltopdf_converter * converter, const int val);
typedef void (*wkhtmltopdf_void_callback)(wkhtmltopdf_converter * converter);
CAPI(int) wkhtmltopdf_init(int use_graphics);
CAPI(int) wkhtmltopdf_deinit();
CAPI(int) wkhtmltopdf_extended_qt();
CAPI(const char *) wkhtmltopdf_version();
CAPI(wkhtmltopdf_global_settings *) wkhtmltopdf_create_global_settings();
CAPI(void) wkhtmltopdf_destroy_global_settings(wkhtmltopdf_global_settings *);
CAPI(wkhtmltopdf_object_settings *) wkhtmltopdf_create_object_settings();
CAPI(void) wkhtmltopdf_destroy_object_settings(wkhtmltopdf_object_settings *);
CAPI(int) wkhtmltopdf_set_global_setting(wkhtmltopdf_global_settings * settings, const char * name, const char * value);
CAPI(int) wkhtmltopdf_get_global_setting(wkhtmltopdf_global_settings * settings, const char * name, char * value, int vs);
CAPI(int) wkhtmltopdf_set_object_setting(wkhtmltopdf_object_settings * settings, const char * name, const char * value);
CAPI(int) wkhtmltopdf_get_object_setting(wkhtmltopdf_object_settings * settings, const char * name, char * value, int vs);
CAPI(wkhtmltopdf_converter *) wkhtmltopdf_create_converter(wkhtmltopdf_global_settings * settings);
CAPI(void) wkhtmltopdf_destroy_converter(wkhtmltopdf_converter * converter);
CAPI(void) wkhtmltopdf_set_warning_callback(wkhtmltopdf_converter * converter, wkhtmltopdf_str_callback cb);
CAPI(void) wkhtmltopdf_set_error_callback(wkhtmltopdf_converter * converter, wkhtmltopdf_str_callback cb);
CAPI(void) wkhtmltopdf_set_phase_changed_callback(wkhtmltopdf_converter * converter, wkhtmltopdf_void_callback cb);
CAPI(void) wkhtmltopdf_set_progress_changed_callback(wkhtmltopdf_converter * converter, wkhtmltopdf_int_callback cb);
CAPI(void) wkhtmltopdf_set_finished_callback(wkhtmltopdf_converter * converter, wkhtmltopdf_int_callback cb);
/* CAPI(void) wkhtmltopdf_begin_conversion(wkhtmltopdf_converter * converter); */
/* CAPI(void) wkhtmltopdf_cancel(wkhtmltopdf_converter * converter); */
CAPI(int) wkhtmltopdf_convert(wkhtmltopdf_converter * converter);
CAPI(void) wkhtmltopdf_add_object(
wkhtmltopdf_converter * converter, wkhtmltopdf_object_settings * setting, const char * data);
CAPI(int) wkhtmltopdf_current_phase(wkhtmltopdf_converter * converter);
CAPI(int) wkhtmltopdf_phase_count(wkhtmltopdf_converter * converter);
CAPI(const char *) wkhtmltopdf_phase_description(wkhtmltopdf_converter * converter, int phase);
CAPI(const char *) wkhtmltopdf_progress_string(wkhtmltopdf_converter * converter);
CAPI(int) wkhtmltopdf_http_error_code(wkhtmltopdf_converter * converter);
CAPI(long) wkhtmltopdf_get_output(wkhtmltopdf_converter * converter, const unsigned char **);
#ifdef BUILDING_WKHTMLTOX
#include "dllend.inc"
#else
#include <wkhtmltox/dllend.inc>
#endif
#endif /*__PDF_H__*/

View File

@@ -7,6 +7,7 @@ from django.utils.translation import gettext as _
from django import forms
from django.utils.text import slugify
from django.db.models import Min
from django.contrib import messages
class DocArtForm(forms.ModelForm):
@@ -19,6 +20,26 @@ class DocArtForm(forms.ModelForm):
self.fields['parent'].queryset = DocArt.objects.exclude(id__exact=self.instance.id)
def make_assign_versions_action(version):
def assign_to_version(modeladmin, request, queryset):
for art in queryset:
if version not in art.versions.all():
art.versions.add(version) # Method on Order model
messages.info(request, f"Статье {art} назначена версия {version.name}")
assign_to_version.short_description = _(f"Назначить версию {version.name}")
# We need a different '__name__' for each action - Django
# uses this as a key in the drop-down box.
assign_to_version.__name__ = _(f"Назначить версию {version.name}")
return assign_to_version
class Admin_DocArt(SuperModelAdmin, Admin_Trans_BaseModelViewPage):
form = DocArtForm
@@ -93,6 +114,20 @@ class Admin_DocArt(SuperModelAdmin, Admin_Trans_BaseModelViewPage):
# inlines = [Admin_StackedInline_Block]
actions = ["create_copy_arts"]
def get_actions(self, request):
actions = super(Admin_DocArt, self).get_actions(request)
versions = DocVersion.objects.filter(enable=True)
for version in versions:
action = make_assign_versions_action(version)
actions[action.__name__] = (action,
action.__name__,
action.short_description)
return actions
@admin.action(description=_("Создать копии выбранных статей"))
def create_copy_arts(self, request, queryset):
from BaseModels.functions import create_url

View File

@@ -2,7 +2,7 @@ from django.db import models
from BaseModels.base_models import BaseModelViewPage, BaseModel
from ckeditor_uploader.fields import RichTextUploadingField
from django.utils.translation import gettext_lazy as _
from datetime import datetime
class DocVersion(BaseModel):
url = models.TextField(
@@ -43,11 +43,22 @@ class DocArt(BaseModelViewPage):
related_name='rel_docArts_for_version'
)
def get_last_child(self):
return self.rel_childArts_for_docArt.filter(enable=True).order_by('-order').first()
# def save(self, not_change_modifiedDT=False, *args, **kwargs):
# if not not_change_modifiedDT:
# self.modifiedDT = datetime.now()
# super().save(*args, **kwargs)
def get_first_child(self):
return self.rel_childArts_for_docArt.filter(enable=True).order_by('order').first()
def get_last_child(self, version):
return self.rel_childArts_for_docArt.filter(
versions=version,
enable=True
).order_by('-order').first()
def get_first_child(self, version):
return self.rel_childArts_for_docArt.filter(
versions=version,
enable=True
).order_by('order').first()
def get_last_version(self):
return self.versions.all().order_by('-order').first()
@@ -60,16 +71,21 @@ class DocArt(BaseModelViewPage):
if not version:
version = self.get_last_version()
art = DocArt.objects.filter(
enable=True,
versions=version,
order__lt=self.order,
parent=self.parent
).order_by('-order').first()
kwargs = {
'enable': True,
'versions': version,
'parent': self.parent
}
if self.order:
kwargs['order__lt'] = self.order
art = DocArt.objects.exclude(
id=self.id
).filter(**kwargs).order_by('-order').first()
if art:
while art.get_last_child():
art = art.get_last_child()
while art.get_last_child(version=version):
art = art.get_last_child(version=version)
if not art and self.parent:
art = self.parent
@@ -81,14 +97,20 @@ class DocArt(BaseModelViewPage):
if not version:
version = self.get_last_version()
art = self.get_first_child()
art = self.get_first_child(version=version)
if not art:
art = DocArt.objects.filter(
enable=True,
versions=version,
order__gt=self.order,
parent=self.parent
).order_by('order').first()
kwargs = {
'enable': True,
'versions': version,
'parent': self.parent
}
if self.order:
kwargs['order__gt'] = self.order
art = DocArt.objects.exclude(
id=self.id
).filter(**kwargs).order_by('order').first()
if not art and self.parent:
art = DocArt.objects.filter(

View File

@@ -1,4 +1,5 @@
import json
import os
from django.http import HttpResponse, Http404, FileResponse, HttpResponseRedirect
from django.template import loader, RequestContext
@@ -9,15 +10,18 @@ from GeneralApp.funcs import get_inter_http_respose
from django.utils.translation import gettext_lazy as _
from django.urls import reverse
from collections import OrderedDict
from django.template.loader import render_to_string
from urllib.parse import unquote
def get_tree_arts(art, arts, sel_arts_ids):
docs_tree = OrderedDict()
docs_tree.update({
art_item.name: {
art_item.id: {
'url': art_item.url,
'id': art_item.id,
'name': art_item.name,
# 'id': art_item.id,
'children': get_tree_arts(art_item, arts, sel_arts_ids),
'active': art_item.id in sel_arts_ids
} for art_item in arts.filter(parent=art)
@@ -25,22 +29,74 @@ def get_tree_arts(art, arts, sel_arts_ids):
return docs_tree
# def get_tree_arts(art, arts):
#
# docs_tree = OrderedDict()
# docs_tree.update({
# art['name']: {
# 'url': art['url'],
# 'id': art['id'],
# 'children': get_tree_arts(art, DocArt.objects.filter(parent=art)),
# } for art in arts.filter(parent=None)
# })
# return docs_tree
def _response_pdf(path):
filePDF = open(path, 'rb')
content = filePDF.read()
# content = str(content)
filePDF.close()
response = HttpResponse(content, content_type='application/pdf')
response['Content-Disposition'] = 'filename="{fn}"'.format(fn=os.path.basename(path))
return response
def pdf_render(request, template, context, file_name):
from BaseModels.functions import url_translit
from GeneralApp.funcs_options import get_options_by_opt_types
filename = url_translit(file_name)
html = render_to_string(template, context, request)
sets = get_options_by_opt_types(['domain'], only_vals=True, w_prefix=True)
if settings.DEBUG:
sets['domain'] = 'http://127.0.0.1:8019'
while 'src="/' in html:
html = html.replace('src="/', f'src="{sets["domain"]}/')
# html = unquote(html)
f = open(f'{settings.PDF_FOLDER}/{filename}.html', 'w')
f.write(html)
f.close()
os.system(
'{wkhtmltopdf} '
# '--margin-top 20mm '
# '--encoding windows-1250 '
'--enable-local-file-access '
'--load-error-handling ignore '
'--enable-internal-links '
'--keep-relative-links '
'--print-media-type '
'--encoding UTF-8 '
# '--default-header '
# '--minimum-font-size 20mm '
'{pdf_folder}/{file_name}.html '
'{pdf_folder}/{file_name}.pdf'.format(
wkhtmltopdf=settings.WKHTML_TO_PDF, pdf_folder=settings.PDF_FOLDER, file_name=filename)
)
path = settings.PDF_FOLDER + '/' + filename + '.pdf'
# os.system(u'{wkhtmltopdf} {print_folder}/order{filename}.html {print_folder}/order{filename}.pdf'.format(wkhtmltopdf=settings.WKHTML_TO_PDF, print_folder=settings.PRINT_FOLDER))
return _response_pdf(path)
def DocsView(request, version=None, art_url=None):
if art_url and version:
generate_pdf = False
if request.GET and 'pdf' in request.GET and request.GET['pdf'] == 'true':
generate_pdf = True
kwargs = {
'enable': True,
'url': art_url,
@@ -83,10 +139,19 @@ def DocsView(request, version=None, art_url=None):
'allow_versions': versions,
'breadcrumbs': breadcrumbs,
'prev_article': art.get_prev_article(version=vers_obj),
'next_article': art.get_next_article(version=vers_obj)
'next_article': art.get_next_article(version=vers_obj),
'pdf_render': generate_pdf
}
t = loader.get_template('pages/p_documentation.html')
if not generate_pdf:
tpl = 'pages/p_documentation.html'
t = loader.get_template(tpl)
return get_inter_http_respose(t, Dict, request)
else:
tpl = 'blocks/b_documentation_article.html'
# tpl = 'pages/p_documentation.html'
return pdf_render(request, tpl, Dict, art.name)
except DocArt.DoesNotExist:
raise Http404
@@ -110,11 +175,11 @@ def DocsView(request, version=None, art_url=None):
versions=None
).filter(
enable=True, parent=None
).order_by('-versions__order', 'order').first()
).order_by('-versions__order', '-versions__name', 'order').first()
if art:
url = reverse(
'docs_art_page',
kwargs={'version': art.versions.order_by('order').first().url, 'art_url': art.url}
kwargs={'version': art.versions.order_by('-order').first().url, 'art_url': art.url}
)
return HttpResponseRedirect(url)

View File

@@ -1,6 +1,10 @@
import copy
from django import forms
from django.contrib import admin
from sets.admin import *
from .models import *
from django.contrib import admin
from django.utils.translation import gettext_lazy as _
# from nested_inline.admin import NestedStackedInline, NestedTabularInline, NestedModelAdmin, NestedInline
from super_inlines.admin import SuperInlineModelAdmin, SuperModelAdmin
@@ -22,6 +26,50 @@ admin.site.register(LogEntry, LogEntryAdmin)
class Admin_FileUnit(Admin_Trans_BaseModelViewPage):
def fn(self, obj):
return obj.file.filename
fn.short_description = 'Файл'
def fn_full_path(self, obj):
from urllib.parse import unquote_plus
res = unquote_plus(obj.file.url, encoding="utf-8")
return res
fn_full_path.short_description = 'Линк для использования в HTML'
fieldsets = [
(None, {
'classes': [],
'fields': [
# ('name',),
('file',),
# 'image'
'order'
]
})
]
list_display = [
# 'image_thumb',
'id',
'fn',
'fn_full_path',
# 'title',
'order', 'modifiedDT', 'createDT'
]
list_display_links = ['id']
list_editable = ['order']
list_filter = ['modifiedDT', 'createDT']
search_fields = ['file']
admin.site.register(FileUnit, Admin_FileUnit)
class Admin_Inline_WidgetForBlock(SuperInlineModelAdmin, Admin_Trans_BaseIconStackedInline):
def formfield_for_dbfield(self, db_field, request, **kwargs):
@@ -40,6 +88,7 @@ class Admin_Inline_WidgetForBlock(SuperInlineModelAdmin, Admin_Trans_BaseIconSta
# 'title',
'name', 'description', 'text',
'picture',
# 'image'
),
'video_url',
('bg_color', ),
@@ -84,6 +133,77 @@ class Admin_StackedInline_Block(Admin_Trans_GenericBaseIconStackedInline, SuperI
class Admin_PageAddingBlocksTemplate(Admin_BaseIconModel):
from ServicesApp.admin import Admin_StackedInline_BlockPluginPresentation
from SlidesApp.admin import Admin_StackedInline_Slide
fieldsets = [
(None, {
'classes': ['wide'],
'fields': ('name',
# 'url',
# 'title',
# 'description', 'text',
# 'picture',
# 'order',
)
}),
# ('SEO', {
# 'classes': ['wide', 'collapse'],
# 'fields': (
# 'seo_title', 'seo_description', 'seo_keywords', 'seo_text',
# )
# }),
]
def get_list_display(self, request):
if request.user.is_superuser:
# self.list_display.append()
d_list = copy.copy(self.list_display)
d_list.append('name_plural')
return d_list
return self.list_display
def get_changelist_instance(self, request):
if request.user.is_superuser:
self.list_editable.append('name_plural')
return super(Admin_PageAddingBlocksTemplate, self).get_changelist_instance(request)
list_display = [
# 'image_thumb',
'id',
'name',
'enable',
# 'url',
# 'title',
# 'order',
'modifiedDT', 'createDT'
]
list_display_links = ['id', 'name']
list_editable = ['enable']
list_filter = ['modifiedDT', 'createDT']
search_fields = ['name']
# filter_horizontal = ['options']
inlines = [
Admin_StackedInline_Slide,
Admin_StackedInline_BlockPluginPresentation,
Admin_StackedInline_Block,
# AdminStacked_FAQitem,
]
def has_delete_permission(self, request, obj=None):
if request.user.is_superuser:
return True
if not obj or obj.name_plural in ['documentation', 'contacts']:
return False
admin.site.register(PageAddingBlocksTemplate, Admin_PageAddingBlocksTemplate)
class Admin_StaticPage(SuperModelAdmin, Admin_Trans_BaseModelViewPage):

View File

@@ -1,6 +1,9 @@
from django.http import HttpResponse, Http404, FileResponse
from admin_interface.templatetags.admin_interface_tags import get_admin_interface_theme
from BaseModels.functions import translit
def get_logo_url():
theme = get_admin_interface_theme()
return theme.logo.url
@@ -40,11 +43,15 @@ def get_inter_Dict(user, context_Dict):
feedback_form.initial = {'form_name': form_name}
Dict.update({'feedback_form': feedback_form})
from DocsApp.models import DocArt
arts_exists = DocArt.objects.filter(enable=True).exists()
Dict.update({
'sections': sections,
'logo': get_logo_url(),
'hide_form_field_description': hide_form_field_description,
'footer_contacts': get_footer_contacts(),
'allow_documentation': arts_exists,
})
# from SubscribesApp.funcs import get_cur_user_subscribe
# user_subscribe = get_cur_user_subscribe(user)

View File

@@ -1,6 +1,6 @@
from .models import *
def get_options_by_opt_types(opt_types, only_vals=False):
def get_options_by_opt_types(opt_types, only_vals=False, w_prefix=False):
if type(opt_types) == str:
kwargs = {'opt_type': opt_types}
elif type(opt_types) == dict:
@@ -10,8 +10,15 @@ def get_options_by_opt_types(opt_types, only_vals=False):
opts = Option.objects.filter(**kwargs)
if opts and only_vals:
opts = opts.values('opt_type', 'value')
opts = {item['opt_type']: item['value'] for item in opts}
opts = opts.values('opt_type', 'value', 'prefix')
res_Dict = {}
for item in opts:
val = item['value']
if w_prefix and item['prefix']:
val = item['prefix'] + val
res_Dict.update({item['opt_type']: val})
return res_Dict
return opts
def get_first_option_value_by_opt_type(opt_type):

View File

@@ -0,0 +1,66 @@
# Generated by Django 4.2.7 on 2024-07-14 13:22
import datetime
from django.db import migrations, models
import filebrowser.fields
class Migration(migrations.Migration):
dependencies = [
('GeneralApp', '0025_alter_office_work_time_from_and_more'),
]
operations = [
migrations.CreateModel(
name='FileUnit',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.TextField(blank=True, help_text='Название', null=True, verbose_name='Название')),
('name_ru', models.TextField(blank=True, help_text='Название', null=True, verbose_name='Название')),
('name_en', models.TextField(blank=True, help_text='Название', null=True, verbose_name='Название')),
('name_plural', models.TextField(blank=True, null=True, verbose_name='Название (множественное число)')),
('order', models.IntegerField(blank=True, null=True, verbose_name='Очередность отображения')),
('createDT', models.DateTimeField(auto_now_add=True, verbose_name='Дата и время создания')),
('modifiedDT', models.DateTimeField(blank=True, null=True, verbose_name='Дата и время последнего изменения')),
('enable', models.BooleanField(db_index=True, default=True, verbose_name='Включено')),
('json_data', models.JSONField(blank=True, default=dict, verbose_name='Дополнительные данные')),
('file', filebrowser.fields.FileBrowseField(max_length=250, verbose_name='Файл')),
('file_ru', filebrowser.fields.FileBrowseField(max_length=250, null=True, verbose_name='Файл')),
('file_en', filebrowser.fields.FileBrowseField(max_length=250, null=True, verbose_name='Файл')),
],
options={
'abstract': False,
},
),
migrations.AlterField(
model_name='office',
name='work_time_from',
field=models.TimeField(default=datetime.datetime(2024, 7, 14, 9, 0), verbose_name='Время работы с'),
),
migrations.AlterField(
model_name='office',
name='work_time_from_en',
field=models.TimeField(default=datetime.datetime(2024, 7, 14, 9, 0), null=True, verbose_name='Время работы с'),
),
migrations.AlterField(
model_name='office',
name='work_time_from_ru',
field=models.TimeField(default=datetime.datetime(2024, 7, 14, 9, 0), null=True, verbose_name='Время работы с'),
),
migrations.AlterField(
model_name='office',
name='work_time_to',
field=models.TimeField(default=datetime.datetime(2024, 7, 14, 18, 0), verbose_name='Время работы до'),
),
migrations.AlterField(
model_name='office',
name='work_time_to_en',
field=models.TimeField(default=datetime.datetime(2024, 7, 14, 18, 0), null=True, verbose_name='Время работы до'),
),
migrations.AlterField(
model_name='office',
name='work_time_to_ru',
field=models.TimeField(default=datetime.datetime(2024, 7, 14, 18, 0), null=True, verbose_name='Время работы до'),
),
]

View File

@@ -0,0 +1,65 @@
# Generated by Django 4.2.7 on 2024-07-15 17:00
import datetime
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('GeneralApp', '0026_fileunit_alter_office_work_time_from_and_more'),
]
operations = [
migrations.CreateModel(
name='PageAddingBlocksTemplate',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.TextField(blank=True, help_text='Название', null=True, verbose_name='Название')),
('name_plural', models.TextField(blank=True, null=True, verbose_name='Название (множественное число)')),
('order', models.IntegerField(blank=True, null=True, verbose_name='Очередность отображения')),
('createDT', models.DateTimeField(auto_now_add=True, verbose_name='Дата и время создания')),
('modifiedDT', models.DateTimeField(blank=True, null=True, verbose_name='Дата и время последнего изменения')),
('enable', models.BooleanField(db_index=True, default=True, verbose_name='Включено')),
('json_data', models.JSONField(blank=True, default=dict, verbose_name='Дополнительные данные')),
],
options={
'verbose_name': 'Шаблон настройки дополнительных блоков на странице',
'verbose_name_plural': 'Шаблоны настройки дополнительных блоков на странице',
},
),
migrations.AlterModelOptions(
name='fileunit',
options={'verbose_name': 'Файл', 'verbose_name_plural': 'Файлы'},
),
migrations.AlterField(
model_name='office',
name='work_time_from',
field=models.TimeField(default=datetime.datetime(2024, 7, 15, 9, 0), verbose_name='Время работы с'),
),
migrations.AlterField(
model_name='office',
name='work_time_from_en',
field=models.TimeField(default=datetime.datetime(2024, 7, 15, 9, 0), null=True, verbose_name='Время работы с'),
),
migrations.AlterField(
model_name='office',
name='work_time_from_ru',
field=models.TimeField(default=datetime.datetime(2024, 7, 15, 9, 0), null=True, verbose_name='Время работы с'),
),
migrations.AlterField(
model_name='office',
name='work_time_to',
field=models.TimeField(default=datetime.datetime(2024, 7, 15, 18, 0), verbose_name='Время работы до'),
),
migrations.AlterField(
model_name='office',
name='work_time_to_en',
field=models.TimeField(default=datetime.datetime(2024, 7, 15, 18, 0), null=True, verbose_name='Время работы до'),
),
migrations.AlterField(
model_name='office',
name='work_time_to_ru',
field=models.TimeField(default=datetime.datetime(2024, 7, 15, 18, 0), null=True, verbose_name='Время работы до'),
),
]

View File

@@ -1,3 +1,4 @@
from django.core.files.storage import FileSystemStorage
from django.db import models
from BaseModels.base_models import *
from django.utils.translation import gettext_lazy as _
@@ -8,6 +9,27 @@ from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.fields import GenericRelation
from colorfield.fields import ColorField
from filebrowser.fields import FileBrowseField
from filebrowser.base import FileObject
class PageAddingBlocksTemplate(BaseModel):
class Meta:
verbose_name = _('Шаблон настройки дополнительных блоков на странице')
verbose_name_plural = _('Шаблоны настройки дополнительных блоков на странице')
class FileUnit(BaseModel):
file = FileBrowseField(verbose_name=_('Файл'), max_length=250, directory="files/")
def __str__(self):
if self.file:
return self.file.filename
else:
return str(self.id)
class Meta:
verbose_name = _('Файл')
verbose_name_plural = _('Файлы')
class StaticPage(BaseModelViewPage):
promo_header = models.BooleanField(verbose_name='Промо-хэдер', default=False)
@@ -120,6 +142,11 @@ class WidgetForBlock(BaseModel):
validators=[validate_file_extension]
)
def image(self):
if self.picture:
return FileObject(self.picture.path)
return None
class Meta:
verbose_name = _('Виджет в блоке')

View File

@@ -2,6 +2,12 @@ from modeltranslation.translator import translator, TranslationOptions
from .models import *
class FileUnit_TranslationOptions(TranslationOptions):
fields = (
'name', 'file'
)
translator.register(FileUnit, FileUnit_TranslationOptions)
class StaticPage_TranslationOptions(TranslationOptions):
fields = (
'name', 'description', 'text', 'title', 'FAQ_title', 'seo_title', 'seo_description', 'seo_text'

View File

@@ -29,17 +29,24 @@ DEBUG = True
ALLOWED_HOSTS = ['*']
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
CSRF_TRUSTED_ORIGINS = ['https://aerbim.com', 'http://127.0.0.1:8019/']
CSRF_TRUSTED_ORIGINS = ['https://aerbim.com', 'http://127.0.0.1:8019/', 'https://www.youtube.com/']
X_FRAME_OPTIONS = 'SAMEORIGIN'
# Application definition
FILEBROWSER_SHOW_IN_DASHBOARD = False
LIST_PER_PAGE = 100
INSTALLED_APPS = [
'colorfield',
'modeltranslation',
"admin_interface",
'super_inlines',
# 'grappelli',
'filebrowser',
"admin_interface",
'modeltranslation',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
@@ -69,10 +76,11 @@ MIDDLEWARE = [
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'pAerBim.translate_middleware.LocaleMiddleware'
# 'AuthApp.middleware.ResponseInterceptionMiddleware',
]
X_FRAME_OPTIONS = 'SAMEORIGIN'
ROOT_URLCONF = 'pAerBim.urls'
@@ -141,7 +149,7 @@ AUTH_PASSWORD_VALIDATORS = [
# Internationalization
# https://docs.djangoproject.com/en/4.2/topics/i18n/
LANGUAGE_CODE = 'ru'
LANGUAGE_CODE = 'en'
TIME_ZONE = 'Europe/Minsk'
@@ -157,7 +165,9 @@ USE_TZ = False
# https://docs.djangoproject.com/en/4.2/howto/static-files/
MEDIA_URL = '/media/'
MEDIA_ROOT = 'media/'
# MEDIA_ROOT = 'media/'
import os
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
STATIC_URL = '/static/'
STATIC_ROOT = '/'
@@ -176,13 +186,14 @@ LOCALE_PATHS = (
gettext = lambda s: s
LANGUAGES = (
(u'ru', gettext(u'Russian')),
(u'en', gettext(u'English')),
(u'ru', gettext(u'Russian')),
)
MODELTRANSLATION_LANGUAGES = ('ru', 'en')
MODELTRANSLATION_LANGUAGES = ('en', 'ru')
MODELTRANSLATION_ENABLE_FALLBACKS = True
MODELTRANSLATION_FALLBACK_LANGUAGES = {
'default': ('ru','en'),
'default': ('en',),
}
# Add custom languages not provided by Django
@@ -191,6 +202,10 @@ LANG_INFO = dict(django.conf.locale.LANG_INFO.items()) #+ EXTRA_LANG_INFO.items(
django.conf.locale.LANG_INFO = LANG_INFO
from filebrowser.sites import site
site.directory = ""
# Default primary key field type
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field
@@ -201,7 +216,7 @@ DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
CKEDITOR_BASEPATH = "/static/ckeditor/ckeditor/"
CKEDITOR_UPLOAD_PATH = "uploads/"
CKEDITOR_RESTRICT_BY_DATE = False
CKEDITOR_RESTRICT_BY_USER = True
CKEDITOR_RESTRICT_BY_USER = False
CKEDITOR_BROWSE_SHOW_DIRS = True
CKEDITOR_IMAGE_BACKEND = "pillow"
@@ -220,8 +235,12 @@ CKEDITOR_CONFIGS = {
'toolbar': 'Custom',
'forcePasteAsPlainText': True,
'allowedContent': True,
'extraAllowedContent': 'iframe[*]',
# 'disallowedContent': 'img{width,height};img[width,height]',
# 'extraPlugins': 'image2',
'extraPlugins': ','.join([
'codesnippet',
# 'youtube'
]),
'enterMode': 2,
'basicEntities' : False,
@@ -250,11 +269,19 @@ CKEDITOR_CONFIGS = {
'/',
{'name': 'links', 'items': ['Link', 'Unlink', 'Anchor', '-', 'Blockquote' ]},
{'name': 'insert',
'items': ['Image', 'Update', 'Table', 'HorizontalRule', 'Smiley', 'SpecialChar', 'PageBreak', 'Iframe']},
'items': ['Image', 'Youtube', 'Table', 'HorizontalRule', 'Smiley', 'SpecialChar', 'PageBreak', 'Iframe']
},
# {
# 'name': 'youtube',
# 'items': ['Youtube',]
# }
],
}
}
PDF_FOLDER = 'media/pdf'
WKHTML_TO_PDF = 'BaseModels\wkhtmltopdf\{0}\wkhtmltopdf'.format(u'bin')
try:
import db_local_sets

View File

@@ -0,0 +1,18 @@
from django.utils import translation
class LocaleMiddleware(object):
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
language_code = 'en'
translation.activate(language_code)
response = self.get_response(request)
translation.deactivate()
return response

View File

@@ -3,6 +3,16 @@ from django.contrib import admin
from django.urls import path, include
from django.conf.urls.static import static
from django.conf import settings
from filebrowser.sites import site
# from django.core.files.storage import DefaultStorage
# from filebrowser.sites import FileBrowserSite
#
# site = FileBrowserSite(name="filebrowser", storage=DefaultStorage())
# customsite = FileBrowserSite(name='custom_filebrowser', storage=DefaultStorage())
# customsite.directory = "uploads/"
urlpatterns = [
path('ckeditor/', include('ckeditor_uploader.urls')),
@@ -14,6 +24,9 @@ urlpatterns = [
from django.conf.urls.i18n import i18n_patterns
urlpatterns += i18n_patterns(
path('admin/filebrowser/', site.urls),
# path('grappelli/', include('grappelli.urls')),
path('admin/', admin.site.urls),

View File

@@ -6,3 +6,5 @@ django-modeltranslation==0.18.11
Pillow==10.1.0
psycopg2-binary==2.9.9
django-super-inlines
# django-filebrowser-4.0.3
django-filebrowser-no-grappelli==4.0.2

View File

@@ -1656,6 +1656,8 @@ body.n_scroll{
font-size: 14px;
color: #7A8185FF;
cursor: pointer;
display: block;
text-decoration: unset;
}
.way_bread_crumb.last{
@@ -1688,7 +1690,7 @@ body.n_scroll{
.documentation_version{
display: flex;
align-items: center;
margin-bottom: 40px;
margin-bottom: 30px;
}
.documentation_version_switcher{
@@ -1730,6 +1732,7 @@ body.n_scroll{
display: flex;
align-items: center;
justify-content: center;
text-decoration: unset;
}
.one_item_documentation_switcher_content_part:hover{
@@ -1744,7 +1747,7 @@ body.n_scroll{
.tree_documentation_container{
width: 100%;
height: calc(100vh - 300px);
overflow-y: auto;
}
.tree_documentation_container.hide_scroll::-webkit-scrollbar{
@@ -1796,6 +1799,7 @@ body.n_scroll{
display: flex;
width: 100%;
cursor: pointer;
align-items: flex-start;
}
@@ -1812,9 +1816,9 @@ body.n_scroll{
}
.tree_documentation_arrow_img{
width: 12px;
height: 7px;
padding: 9px 6px;
width: 7px;
height: 12px;
padding: 6px 9px;
}
.tree_documentation_container_first_level_txt{
@@ -1822,12 +1826,18 @@ body.n_scroll{
font-weight: 700;
color: #000000;
margin-left: 3px;
display: block;
text-decoration: unset;
line-height: 25px;
}
.tree_documentation_container_second_level_txt{
font-size: 16px;
font-weight: 400;
color: #000000;
margin-left: 3px;
display: block;
text-decoration: unset;
line-height: 24px;
}
.tree_documentation_container_first_level_txt.chose{
color: #0C54A0FF;
@@ -1857,7 +1867,7 @@ body.n_scroll{
}
.elements_third_level_content_part_tree{
margin-left: 50px;
margin-left: 40px;
}
.element_third_level_content_part_tree{
@@ -1867,6 +1877,8 @@ body.n_scroll{
font-weight: 400;
margin: 5px 0;
cursor: pointer;
display: block;
text-decoration: unset;
}
.element_third_level_content_part_tree.chose{
@@ -1896,6 +1908,7 @@ body.n_scroll{
.content_part_tree_els h1{
font-size: 40px;
margin-top: 0!important;
}
.name_article_tree{
@@ -1947,6 +1960,8 @@ body.n_scroll{
font-weight: 400;
color: #7A8185FF;
border-bottom: 1px solid #7A8185FF;
display: block;
text-decoration: unset;
}
.control_content_part_tree_el.right .txt_control_content_part_tree_el{
margin-right: 7px;
@@ -1991,6 +2006,12 @@ body.n_scroll{
align-items: center;
justify-content: right;
width: 100%;
float: right;
position: sticky;
top: 61px;
background: #FFFFFF;
padding: 22px 22px;
z-index: 1000;
}
.container_open_doc_curtain_txt{
@@ -2011,3 +2032,17 @@ body.n_scroll{
height: 10px;
display: block;
}
.btn_download_in_pdf{
padding: 18px 90px;
background: #0C54A0;
color: #FFFFFF;
font-size: 16px;
font-weight: 600;
text-decoration: unset;
border-radius: 5px;
display: block;
margin-top: 20px;
width: fit-content;
text-transform: uppercase;
}

View File

@@ -6,7 +6,25 @@
}
@media(max-width: 1150px){
.flex_container_buttons_3d_security_designer{
display: block;
}
.flex_container_buttons_3d_security_designer .btn_download_plugin {
width: 100%;
margin-right: 0;
}
.flex_container_buttons_3d_security_designer .btn_inf_about_plugin {
width: 100%;
margin-top: 20px;
margin-left: 0;
}
}
@media (max-width: 1024px) {
.one_item_documentation_switcher_content_part{
font-size: 12px;
}
.cur_documentation_version{
font-size: 12px;
}
@@ -50,7 +68,7 @@
}
.tree_documentation_container {
width: unset;
height: 100vh;
height: calc(100vh - 172px);
overflow-y: auto;
padding: 0 15px;
@@ -61,6 +79,7 @@
}
.breadcrumbs_documentation_block{
margin-top: 90px;
margin-bottom: 2px;
}
.container_img_card_contacts{
height: 250px;

View File

@@ -16,6 +16,7 @@ $(document).ready(function (){
setInfInCurtainDocumentationMobile()
setButtonOpenMobileDocCurtain()
}
windowScrollDocPage()
})
function setButtonOpenMobileDocCurtain () {
@@ -55,7 +56,7 @@ function setButtonOpenMobileDocCurtain () {
$picture.appendChild($img)
$($cont).insertBefore($content)
$($cont).insertAfter($(".breadcrumbs_documentation_block"))
}
function setInfInCurtainDocumentationMobile () {
@@ -98,6 +99,7 @@ function setInfInCurtainDocumentationMobile () {
}
function openDocCurtainMobile () {
$("body").css({'overflow':'hidden'})
let $curtain = $(".left_curtain_documentation")
let $block_overlay = $(".block_overlay")
$curtain.css({left:0})
@@ -107,6 +109,7 @@ function openDocCurtainMobile () {
}
function closeDocCurtainMobile () {
$("body").css({'overflow':'unset'})
let $curtain = $(".left_curtain_documentation")
let $block_overlay = $(".block_overlay")
$curtain.css({left:'-320px'})
@@ -507,22 +510,28 @@ function transitToDocumentation() {
window.location.href = window.location.origin + '/' + getLang() + '/docs/3dsd/'
}
let switcherWorking = false
function openVersionSwitcher(el){
if (!switcherWorking){
switcherWorking = true
let $parent = el.closest(".documentation_version_switcher")
let $content_part = $parent.querySelector(".documentation_switcher_content_part")
let $arrow = $parent.querySelector(".documentation_switcher_arrow_picture")
$content_part.classList.toggle("hidden")
if ($arrow.style.rotate === '0deg' || $arrow.style.rotate === '') {
$($arrow).animate({rotate: '180deg'},200)
$($arrow).css({rotate: '180deg'})
let height = $content_part.offsetHeight
$content_part.style.bottom = '-' + height + "px"
$parent.style.borderBottom = '1px solid #fff'
} else {
$($arrow).animate({rotate: '0deg'},200)
$parent.style.borderBottom = '1px solid #CCCED1FF'
}
$("body")[0].setAttribute("onclick",'closeVersionSwitcherOnBody()')
} else {
$($arrow).css({rotate: '0deg'})
$parent.style.borderBottom = '1px solid #CCCED1FF'
$("body")[0].setAttribute("onclick",'')
}
switcherWorking = false
}
}
function closeVersionSwitcherOnBody () {
@@ -532,9 +541,19 @@ function closeVersionSwitcherOnBody () {
$version_switcher_container_content.addClass("hidden")
$(".documentation_version_switcher").css({borderBottom: '1px solid #CCCED1FF'})
if ($arrow.style.rotate !== '180deg'){
$($arrow).animate({rotate: '180deg'},200)
$($arrow).css({rotate: '180deg'})
} else {
$($arrow).animate({rotate: '0deg'},200)
$($arrow).css({rotate: '0deg'})
}
if ($('.documentation_switcher_arrow_picture')[1]){
let arrow1 = $('.documentation_switcher_arrow_picture')[1]
if (arrow1.style.rotate !== '180deg'){
$(arrow1).css({rotate: '180deg'})
} else {
$(arrow1).css({rotate: '0deg'})
}
}
$("body")[0].setAttribute("onclick",'')
}
@@ -578,13 +597,75 @@ function showContentPartTree (el) {
let $arrow = $parent.querySelector(".tree_documentation_arrow_img")
$content_part.classList.toggle("hidden")
if ($arrow.style.rotate === '0deg' || $arrow.style.rotate === ''){
$($arrow).animate({rotate: '180deg'})
$($arrow).css({rotate: '90deg'})
} else {
$($arrow).animate({rotate: '0deg'})
$($arrow).css({rotate: '0deg'})
}
let scroll = $(window)[0].scrollY
if ($(".left_curtain_documentation")[1]) {
$($(".left_curtain_documentation")[1]).find(".tree_documentation_container").css({height: 'fit-content'})
maxScroll = scroll + $(".documentation_block")[0].getBoundingClientRect().bottom - $(".left_curtain_documentation")[1].offsetHeight - 172
$($(".left_curtain_documentation")[1]).find(".tree_documentation_container").css({height: 'calc(100vh - 300px)'})
}
}
let waitingTop = null
let maxScroll = null
function windowScrollDocPage (){
if (getInfoAboutUser()[0] !== 'laptop' && getInfoAboutUser()[0] !== 'mobile'){
if (window.location.href.includes("docs")){
let $curtain = $(".left_curtain_documentation")
let scroll = $(window)[0].scrollY
if (scroll === 0){
waitingTop = $(".left_curtain_documentation")[0].getBoundingClientRect().top - 172
$(".left_curtain_documentation").find(".tree_documentation_container").css({height: 'fit-content'})
maxScroll = $(".documentation_block")[0].getBoundingClientRect().bottom - $(".left_curtain_documentation")[0].offsetHeight - 172
if (scroll !== 0){
maxScroll = scroll + $(".documentation_block")[0].getBoundingClientRect().bottom - $(".left_curtain_documentation")[0].offsetHeight - 172
}
$(".left_curtain_documentation").find(".tree_documentation_container").css({height: 'calc(100vh - 300px)'})
}
let $new_curtain = $($curtain[1])
if (scroll < maxScroll || !maxScroll){
if (!$curtain[1] && waitingTop){
$new_curtain = $curtain.clone()
$new_curtain.insertAfter($curtain)
let $new_curtain_tree = $new_curtain.find(".tree_documentation_container")
$new_curtain_tree.css({height: 'calc(100vh - 245px);'})
}
if (scroll >= waitingTop && waitingTop){
$new_curtain.css({position:'fixed',top: 166,bottom:"unset"})
$($curtain[0]).css({opacity:0})
$($curtain[0]).find(".tree_documentation_container").css({display:'none'})
} else if (scroll < waitingTop && waitingTop) {
$curtain.find(".tree_documentation_container")[0].innerHTML = $new_curtain.find(".tree_documentation_container")[0].innerHTML
$new_curtain.remove()
$($curtain[0]).css({opacity:1})
$($curtain[0]).find(".tree_documentation_container").css({display:'block'})
} else if (!waitingTop){
waitingTop = $(".left_curtain_documentation")[0].getBoundingClientRect().top - 172
$(".left_curtain_documentation").find(".tree_documentation_container").css({height: 'fit-content'})
maxScroll = $(".documentation_block")[0].getBoundingClientRect().bottom - $(".left_curtain_documentation")[0].offsetHeight - 172
if (scroll !== 0){
maxScroll = scroll + $(".documentation_block")[0].getBoundingClientRect().bottom - $(".left_curtain_documentation")[0].offsetHeight - 172
}
$(".left_curtain_documentation").find(".tree_documentation_container").css({height: 'calc(100vh - 300px)'})
}
} else {
if (!$curtain[1]){
$new_curtain = $curtain.clone()
$new_curtain.insertAfter($curtain)
let $new_curtain_tree = $new_curtain.find(".tree_documentation_container")
$new_curtain_tree.css({height: 'calc(100vh - 245px);'})
}
$new_curtain.find(".tree_documentation_container").css({height:'fit-content'})
$new_curtain.css({position:'absolute',bottom: 0,top: 'unset'})
$($curtain[0]).css({opacity:0})
}
}
}
}
$(window).scroll(function (){
if (getInfoAboutUser()[0] !== 'laptop' && getInfoAboutUser()[0] !== 'mobile'){
if (window.location.href.includes("docs")){
@@ -592,29 +673,48 @@ $(window).scroll(function (){
let scroll = $(window)[0].scrollY
if (scroll === 0){
waitingTop = $(".left_curtain_documentation")[0].getBoundingClientRect().top - 172
$(".left_curtain_documentation").find(".tree_documentation_container").css({height: 'fit-content'})
maxScroll = $(".documentation_block")[0].getBoundingClientRect().bottom - $(".left_curtain_documentation")[0].offsetHeight - 172
if (scroll !== 0){
maxScroll = scroll + $(".documentation_block")[0].getBoundingClientRect().bottom - $(".left_curtain_documentation")[0].offsetHeight - 172
}
$(".left_curtain_documentation").find(".tree_documentation_container").css({height: 'calc(100vh - 300px)'})
}
let $new_curtain = $($curtain[1])
if (scroll < maxScroll || !maxScroll){
if (!$curtain[1] && waitingTop){
$new_curtain = $curtain.clone()
$new_curtain.insertAfter($curtain)
let $new_curtain_tree = $new_curtain.find(".tree_documentation_container")
$new_curtain_tree.css({height: 'calc(100vh - 245px);'})
}
if (scroll >= waitingTop && waitingTop){
$new_curtain.css({position:'fixed',top: 166,bottom:"unset"})
$($curtain[0]).css({opacity:0})
$($curtain[0]).find(".tree_documentation_container").css({display:'none'})
} else if (scroll < waitingTop && waitingTop) {
$curtain.find(".tree_documentation_container")[0].innerHTML = $new_curtain.find(".tree_documentation_container")[0].innerHTML
$new_curtain.remove()
$($curtain[0]).css({opacity:1})
$($curtain[0]).find(".tree_documentation_container").css({display:'block'})
} else if (!waitingTop){
waitingTop = $(".left_curtain_documentation")[0].getBoundingClientRect().top - 172
$(".left_curtain_documentation").find(".tree_documentation_container").css({height: 'fit-content'})
maxScroll = $(".documentation_block")[0].getBoundingClientRect().bottom - $(".left_curtain_documentation")[0].offsetHeight - 172
if (scroll !== 0){
maxScroll = scroll + $(".documentation_block")[0].getBoundingClientRect().bottom - $(".left_curtain_documentation")[0].offsetHeight - 172
}
$(".left_curtain_documentation").find(".tree_documentation_container").css({height: 'calc(100vh - 300px)'})
}
} else {
if (!$curtain[1]){
$new_curtain = $curtain.clone()
$new_curtain.insertAfter($curtain)
let $new_curtain_tree = $new_curtain.find(".tree_documentation_container")
$new_curtain_tree.css({height: 'calc(100vh - 245px);'})
}
$new_curtain.find(".tree_documentation_container").css({height:'fit-content'})
$new_curtain.css({position:'absolute',bottom: 0,top: 'unset'})
$($curtain[0]).css({opacity:0})
}

View File

@@ -0,0 +1,3 @@
<svg width="7" height="12" viewBox="0 0 7 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.53362 6.53082L1.06056 12.0028L-4.63675e-08 10.942L4.94258 6.00043L-3.60497e-07 1.05882L1.06056 -0.00193982L6.53362 5.47005C6.67431 5.61071 6.75335 5.8015 6.75335 6.00043C6.75335 6.19937 6.67431 6.39016 6.53362 6.53082Z" fill="#0C54A0"/>
</svg>

After

Width:  |  Height:  |  Size: 390 B

View File

@@ -5,20 +5,20 @@
<div class="cut-width">
<div class="container_curtain_content">
<div class="container_first_line_curtain">
<div class="language_select close curtain">
<div class="first_line_language_select pointer" onclick="open_select_language()">
<div class="name_language standart_txt curtain">RU</div>
<div class="arrow_language_select">
<img class="img_arrow_language_select" src="{% static "images/language_icon.svg" %}">
</div>
<div class="clear_both"></div>
</div>
<div class="content_select_language">
<div class="standart_txt pointer" onclick="select_language(this)">RU</div>
<div class="splinner_select_language"></div>
<div class="standart_txt pointer" onclick="select_language(this)">EN</div>
</div>
</div>
{# <div class="language_select close curtain">#}
{# <div class="first_line_language_select pointer" onclick="open_select_language()">#}
{# <div class="name_language standart_txt curtain">RU</div>#}
{# <div class="arrow_language_select">#}
{# <img class="img_arrow_language_select" src="{% static "images/language_icon.svg" %}">#}
{# </div>#}
{# <div class="clear_both"></div>#}
{# </div>#}
{# <div class="content_select_language">#}
{# <div class="standart_txt pointer" onclick="select_language(this)">RU</div>#}
{# <div class="splinner_select_language"></div>#}
{# <div class="standart_txt pointer" onclick="select_language(this)">EN</div>#}
{# </div>#}
{# </div>#}
<div class="standart_txt orange curtain_txt_float">
{# {% translate "Личный кабинет" %}#}
</div>
@@ -30,6 +30,7 @@
</div>
<div class="container_els_curtain">
{# <a class="txt_curtain_el standart_txt">{% translate "Поддержка" %}</a>#}
{# <a href="{% url 'docs_main' %}" class="txt_curtain_el standart_txt">{% translate "Поддержка" %}</a>#}
<a href="{% url 'contacts' %}" class="txt_curtain_el standart_txt">{% translate "Контакты" %}</a>
</div>

View File

@@ -0,0 +1,56 @@
{% load static %}
{% load i18n %}
{% if pdf_render %}
<HEAD>
{# <meta charset="windows-1251">#}
<meta charset="UTF-8">
{% include 'head_includes/fonts_include.html' %}
<style>
* {
font-family: -apple-system, 'Roboto', sans-serif;
}
</style>
</HEAD>
{% endif %}
<div class="content_part_tree_els">
{# <div class="name_article_tree">#}
{# #}
{# </div>#}
{# <div class="description_article_tree">#}
{# {{ cur_article.text }}#}
{# </div>#}
{{ cur_article.text|safe }}
{% if not pdf_render %}
<div class="controls_content_part_tree_els">
<div class="control_content_part_tree_el left">
{% if prev_article %}
<picture class="arrow_control_content_part_tree_el_picture">
<source srcset="{% static "images/arrow_control_part_tree_el.svg" %}">
<img class="arrow_control_content_part_tree_el_img" src="{% static "images/arrow_control_part_tree_el.svg" %}" alt="">
</picture>
<div class="txt_control_content_part_tree_el" data-url="{% url 'docs_art_page' cur_version.url prev_article.url %}" onclick="changeCurArticle(this)">
{% trans "Предыдущий" %}
</div>
{% endif %}
</div>
<div class="control_content_part_tree_el right">
{% if next_article %}
<div class="txt_control_content_part_tree_el" data-url="{% url 'docs_art_page' cur_version.url next_article.url %}" onclick="changeCurArticle(this)">
{% trans "Следующий" %}
</div>
<picture class="arrow_control_content_part_tree_el_picture">
<source srcset="{% static "images/arrow_control_part_tree_el.svg" %}">
<img class="arrow_control_content_part_tree_el_img" src="{% static "images/arrow_control_part_tree_el.svg" %}" alt="">
</picture>
{% endif %}
</div>
</div>
<a class="btn_download_in_pdf" target="_blank" href="?pdf=true">{% trans "Скачать в PDF" %}</a>
{% endif %}
</div>

View File

@@ -10,22 +10,25 @@
</a>
<div class="right_part_header">
{# <a class="standart_txt text_header pointer">Поддержка</a>#}
{% if allow_documentation %}
{# <a href="{% url 'docs_main' %}" class="standart_txt text_header last_left pointer">{% trans "Поддержка" %}</a>#}
{% endif %}
<a href="{% url 'contacts' %}" class="standart_txt text_header last_left pointer">{% translate "Контакты" %}</a>
<div class="splitter_text_header"></div>
<div class="language_select close">
<div class="first_line_language_select pointer" onclick="open_select_language()">
<div class="name_language standart_txt">ru</div>
<div class="arrow_language_select">
<img class="img_arrow_language_select" src="{% static "images/language_icon.svg" %}">
</div>
<div class="clear_both"></div>
</div>
<div class="content_select_language">
<div class="standart_txt pointer" onclick="select_language(this)">ru</div>
<div class="splinner_select_language"></div>
<div class="standart_txt pointer" onclick="select_language(this)">en</div>
</div>
</div>
{# <div class="splitter_text_header"></div>#}
{# <div class="language_select close">#}
{# <div class="first_line_language_select pointer" onclick="open_select_language()">#}
{# <div class="name_language standart_txt">ru</div>#}
{# <div class="arrow_language_select">#}
{# <img class="img_arrow_language_select" src="{% static "images/language_icon.svg" %}">#}
{# </div>#}
{# <div class="clear_both"></div>#}
{# </div>#}
{# <div class="content_select_language">#}
{# <div class="standart_txt pointer" onclick="select_language(this)">ru</div>#}
{# <div class="splinner_select_language"></div>#}
{# <div class="standart_txt pointer" onclick="select_language(this)">en</div>#}
{# </div>#}
{# </div>#}
{# <a class="standart_txt text_header last_right orange pointer">Личный кабинет</a>#}
</div>
<div class="right_part_header_mobile">

View File

@@ -0,0 +1,30 @@
{% load i18n fb_versions %}
<input id="{{ final_attrs.id }}" type="text" class="vFileBrowseField{% if final_attrs.class %} {{ final_attrs.class }}{% endif %}" style="width: 80%;" name="{{ final_attrs.name }}" value="{{ value.path }}" {% for k, v in final_attrs.data_attrs.items %}{{k}}="{{v}}" {% endfor %}/>
<a href="#" onclick="FileBrowser.show(this.parentNode.getElementsByTagName('input')[0].id, '{{ url }}?pop=1{% if final_attrs.directory %}&amp;dir={{ final_attrs.directory|urlencode|urlencode }}{% endif %}{% if final_attrs.format %}&amp;filter={{ final_attrs.format }}{% endif %}');" class="fb_show">
<img src="{{ final_attrs.search_icon }}" style="margin: 5px 0 0 10px;" alt="{% trans "Change" %}" />
</a>
{% if value.filetype == "Image" and value.exists %}
{% version value.path final_attrs.ADMIN_THUMBNAIL as thumbnail_version %}
{% if thumbnail_version %}
<p class="preview" id="preview_{{ final_attrs.id }}">
<a href="{{ value.url }}" target="_blank" id="previewlink_{{ final_attrs.id }}">
<img id="previewimage_{{ final_attrs.id }}" src="{{ thumbnail_version.url }}" class="preview" />
</a>
</p>
{% else %}
<p class="preview" id="preview_{{ final_attrs.id }}" style="display: none;">
<a href="javascript://" target="_self" id="previewlink_{{ final_attrs.id }}">
<img id="previewimage_{{ final_attrs.id }}" class="preview" src="" />
</a>
</p>
{% endif %}
{% else %}
<p class="preview" id="preview_{{ final_attrs.id }}" style="display: none;">
<a href="javascript://" target="_self" id="previewlink_{{ final_attrs.id }}">
<img id="previewimage_{{ final_attrs.id }}" class="preview" src="" />
</a>
</p>
{% endif %}
{% if value and not value.exists %}
<ul class="errorlist"><li>{% trans "File not found" %}</li></ul>
{% endif %}

View File

@@ -4,7 +4,7 @@
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
{# <link href="https://fonts.googleapis.com/css2?family=Verdana&display=swap" rel="stylesheet">#}
<link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap" rel="stylesheet">
<link rel="preload" href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap" as="font" type="font/woff2" crossorigin>
{# <link rel="stylesheet" href="{% static "fonts/fonts.css" %}">#}
{#<link rel="stylesheet" href="{% static "fonts/Raleway-Black.ttf" %}">#}

View File

@@ -25,9 +25,9 @@
{# Документация для версии 1#}
{# </div>#}
{% for name,url in breadcrumbs.items %}
<div class="way_bread_crumb{% if forloop.last %} last{% endif %}" {% if not forloop.last %}data-url="{{ url }}"{% endif %} onclick="breadCrumbGo(this)">
<a class="way_bread_crumb{% if forloop.last %} last{% endif %}" {% if not forloop.last %}href="{{ url }}"{% endif %}>
{{ name }}
</div>
</a>
{% if not forloop.last %}
<picture class="breadcrumb_arrow_picture">
<source srcset="{% static "images/breadcrumb_arrow.svg" %}">
@@ -59,63 +59,54 @@
<div class="documentation_switcher_content_part hidden">
{% for item in allow_versions %}
<div class="one_item_documentation_switcher_content_part" data-url="{% url 'docs_version_page' item.url %}" data-title="{{ item.name }}" onclick="chooseVersionComplete(this)">
<a class="one_item_documentation_switcher_content_part" href="{% url 'docs_version_page' item.url %}" data-title="{{ item.name }}">
{{ item.name }}
</div>
</a>
{% endfor %}
</div>
</div>
</div>
<div class="tree_documentation_container">
{% for name, obj in doc_tree.items %}
{% for id, obj in doc_tree.items %}
<div class="tree_documentation_container_first_level">
<div class="tree_documentation_container_first_line">
{% if obj.children %}
<picture class="tree_documentation_arrow_picture" onclick="showContentPartTree(this)">
<source srcset="{% static "images/arrow_for_documentation_switcher.svg" %}">
<img class="tree_documentation_arrow_img" src="{% static "images/arrow_for_documentation_switcher.svg" %}" alt="">
<picture class="tree_documentation_arrow_picture" onclick="showContentPartTree(this)" {% if obj.active %}style="rotate: 90deg;"{% endif %}>
<source srcset="{% static "images/arrow_for_doc_tree.svg" %}">
<img class="tree_documentation_arrow_img" src="{% static "images/arrow_for_doc_tree.svg" %}" alt="">
</picture>
{% endif %}
<div class="tree_documentation_container_first_level_txt {% if not obj.children %}margin {% endif %}{% if cur_article.url == obj.url %}chose{% endif %}" onclick="choseItemTreeDocumentation(this)" data-url="{% url 'docs_art_page' cur_version.url obj.url %}">
{{ name }}
</div>
<a class="tree_documentation_container_first_level_txt {% if not obj.children %}margin {% endif %}{% if cur_article.url == obj.url %}chose{% endif %}" href="{% url 'docs_art_page' cur_version.url obj.url %}">
{{ obj.name }}
</a>
</div>
{% if obj.children %}
<div class="content_part_tree_documentation_container {% if not obj.active %}hidden{% endif %}">
{% for name, obj in obj.children.items %}
{% for id, obj in obj.children.items %}
<div class="tree_documentation_container_second_level">
<div class="tree_documentation_container_first_line">
{% if obj.children %}
<picture class="tree_documentation_arrow_picture" onclick="showContentPartTree(this)">
<source srcset="{% static "images/arrow_for_documentation_switcher.svg" %}">
<img class="tree_documentation_arrow_img" src="{% static "images/arrow_for_documentation_switcher.svg" %}" alt="">
<picture class="tree_documentation_arrow_picture" onclick="showContentPartTree(this)" {% if obj.active %}style="rotate: 90deg;"{% endif %}>
<source srcset="{% static "images/arrow_for_doc_tree.svg" %}">
<img class="tree_documentation_arrow_img" src="{% static "images/arrow_for_doc_tree.svg" %}" alt="">
</picture>
{% endif %}
<div class="tree_documentation_container_second_level_txt {% if not obj.children %}margin {% endif %}{% if cur_article.url == obj.url %}chose{% endif %}" data-url="{% url 'docs_art_page' cur_version.url obj.url %}" onclick="choseItemTreeDocumentation(this)">
{{ name }}
</div>
<a class="tree_documentation_container_second_level_txt {% if not obj.children %}margin {% endif %}{% if cur_article.url == obj.url %}chose{% endif %}" href="{% url 'docs_art_page' cur_version.url obj.url %}">
{{ obj.name }}
</a>
</div>
{% if obj.children %}
{% for name,obj in obj.children.items %}
<div class="content_part_tree_documentation_container min_padding hidden">
<div class="content_part_tree_documentation_container min_padding {% if not obj.active %}hidden{% endif %}">
<div class="elements_third_level_content_part_tree">
<div class="element_third_level_content_part_tree {% if cur_article.url == obj.url %}chose{% endif %}" onclick="choseItemTreeDocumentation(this)" data-url="{% url 'docs_art_page' cur_version.url obj.url %}">
{{ name }}
</div>
<div class="element_third_level_content_part_tree {% if cur_article.url == obj.url %}chose{% endif %}" onclick="choseItemTreeDocumentation(this)" data-url="{% url 'docs_art_page' cur_version.url obj.url %}">
{{ name }}
</div>
<div class="element_third_level_content_part_tree {% if cur_article.url == obj.url %}chose{% endif %}" onclick="choseItemTreeDocumentation(this)" data-url="{% url 'docs_art_page' cur_version.url obj.url %}">
{{ name }}
</div>
<div class="element_third_level_content_part_tree {% if cur_article.url == obj.url %}chose{% endif %}" onclick="choseItemTreeDocumentation(this)" data-url="{% url 'docs_art_page' cur_version.url obj.url %}">
{{ name }}
</div>
</div>
</div>
{% for id,obj in obj.children.items %}
<a class="element_third_level_content_part_tree {% if cur_article.url == obj.url %}chose{% endif %}" href="{% url 'docs_art_page' cur_version.url obj.url %}">
{{ obj.name }}
</a>
{% endfor %}
</div>
</div>
{% endif %}
</div>
@@ -126,35 +117,7 @@
{% endfor %}
</div>
</div>
<div class="content_part_tree_els">
{# <div class="name_article_tree">#}
{# #}
{# </div>#}
{# <div class="description_article_tree">#}
{# {{ cur_article.text }}#}
{# </div>#}
{{ cur_article.text|safe }}
<div class="controls_content_part_tree_els">
<div class="control_content_part_tree_el left">
<picture class="arrow_control_content_part_tree_el_picture">
<source srcset="{% static "images/arrow_control_part_tree_el.svg" %}">
<img class="arrow_control_content_part_tree_el_img" src="{% static "images/arrow_control_part_tree_el.svg" %}" alt="">
</picture>
<div class="txt_control_content_part_tree_el" data-url="{% url 'docs_art_page' cur_version.url prev_article.url %}" onclick="changeCurArticle(this)">
{% trans "Предыдущий" %}
</div>
</div>
<div class="control_content_part_tree_el right">
<div class="txt_control_content_part_tree_el" data-url="{% url 'docs_art_page' cur_version.url next_article.url %}" onclick="changeCurArticle(this)">
{% trans "Следующий" %}
</div>
<picture class="arrow_control_content_part_tree_el_picture">
<source srcset="{% static "images/arrow_control_part_tree_el.svg" %}">
<img class="arrow_control_content_part_tree_el_img" src="{% static "images/arrow_control_part_tree_el.svg" %}" alt="">
</picture>
</div>
</div>
</div>
{% include "blocks/b_documentation_article.html" %}
</div>
</div>
{% endblock %}