- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
<?php
/* -= Developed by <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="54357a277a20273138212d3f3b143339353d387a373b39">[email protected]</a> =- */
// -= О П Ц И И =-
require("config.php");
// Технические настройки скрипта
header('Content-Type: text/html; charset=utf-8');
ini_set('memory_limit', '-1');
// -=-=-=-=-=-=-=-
// -= Функции инкапсуляции технических аспектов =-
// Функция печати логов, добавляет "date n time now" и перенос строки
function printLog($text) { echo sprintf("[%s] %s", date("Y-m-d H:i:s"), $text) . "\n"; }
// Функция преобразования текста в ключ индекса, убирает пробелы, переводит в верхний регистр и добавляет префикс "_"
function str2idx($str) { return "_" . strtoupper( str_replace(' ', '', (string)$str) ); }
// Функция генерации ассоциативного массива индексов, использует str2idx
function genIdxs($array, $val_key, $idx_keys, $filter_func=NULL) {
$idxs = [];
foreach ($array as $item) {
if ($filter_func && !$filter_func($item)) { continue; }
if (is_string($idx_keys)){
foreach (preg_split("/\s?;\s?/", $item[$idx_keys]) as $idx) {
if ($idx) { $idxs[str2idx($idx)] = str2idx((string)$item[$val_key]); }
} unset($idx);
} else {
foreach ($idx_keys as $idx_key) {
foreach (preg_split("/\s?;\s?/", $item[$idx_key]) as $idx) {
if ($idx) { $idxs[str2idx($idx)] = str2idx((string)$item[$val_key]); }
}
} unset($idx_key);
}
} unset($item);
return $idxs;
}
// Функция сравнения изображений
function compareImages($image1, $image2) {
$compare_result = $image1->compareImages($image2, IMAGICK_METRIC);
return (int)$compare_result[1] > THRESHOLD_SIMILARITY_VALUE;
}
// Функция исполнения SQL-запросов в БД, инкапсулирующая все ужасы взаимодействия с БД MySQL на PHP
function execSQL($sql, $mode="fetch_assoc") {
// Проверяем коннект к БД, в случае проблем - пытаемся переподключ
if (!$GLOBALS["mysqli"] || $GLOBALS["mysqli"]->connect_errno) {
$GLOBALS["mysqli"] = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
if ($GLOBALS["mysqli"]->connect_errno) {
throw new Exception("Can't connect to DB: (".$GLOBALS["mysqli"]->connect_errno.") ".$GLOBALS["mysqli"]->connect_error);
}
printf("default charset: %s\n", $GLOBALS["mysqli"]->character_set_name());
/* изменение набора символов на utf8 */
if (!$GLOBALS["mysqli"]->set_charset("utf8")) {
throw new Exception("set charset utf8 error: %s\n", $GLOBALS["mysqli"]->error);
} else { printf("current charset: %s\n", $GLOBALS["mysqli"]->character_set_name()); }
}
$_result = $GLOBALS["mysqli"]->query($sql);
if (!$_result) { printLog("SQL ERROR: ". $GLOBALS["mysqli"]->error . "\n executable SQL: " . $sql . "\n\n"); }
if (is_bool($_result)) { return $_result; }
elseif ($mode==="num_rows") { return $_result->num_rows; }
elseif ($mode==="fetch_assoc") {
$result = [];
while($row = $_result->fetch_assoc()) {
reset($row);
$key = str2idx($row[key($row)]);
$result[$key] = $row;
} unset($row);
return $result;
}
throw new Exception("Recieved unexpected mode (".$mode.") or query result by execute SQL: ".$sql );
}
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
// -= Старт работы скрипта =-
$start = microtime(true);
printLog("Updater script started");
// Инициализация глобальных переменных, счетчиков
$GLOBALS["mysqli"] = NULL;
$kingsilk_offers_count = 0;
// Проверка хранилища фотографий
if (!is_dir(IMAGES_PATH)) throw new Exception("ERROR: images path not found!");
$IMAGES_FULL_PATH = IMAGES_PATH . IMAGE_PATH_PREFIX;
if (!is_dir($IMAGES_FULL_PATH)) mkdir($IMAGES_FULL_PATH);
// -=-=-=-=-=-=-=-=-=-=-=-=-=-
// -= Получение YML-данных от поставщика Кингсилк, формирование индексов =-
$yml_catalog = new SimpleXMLElement(
file_get_contents(YML_URL_KINGSILK)
);
// Формирование индекса импортируемых категорий по id'шнику категории поставщика
$GLOBALS['cats_outer_idxs'] = [];
foreach ($yml_catalog->categories->category as $cat){
$GLOBALS['cats_outer_idxs'][str2idx((string)$cat["id"])] = $cat;
} unset($cat);
// Группировка предложений поставщика по схожести картинок,
// формирование древовидного индекса по md5 хэшу картинок
$offers_groups_idxs = [];
foreach ($yml_catalog->offers->offer as $offer) {
// Отсеиваем не опубликованные товары
if ((string)$offer["available"] != "true"){
continue;
}
$kingsilk_offers_count++;
$hash = NULL;
не похоже, чтоб оно чья-то девушка
Это ещё ладно, тут хотя бы в тему, а то встречается и Нива Лада.
хахаха
Может быть на питоне Целко писал и неплохо, но как только коснулся пыхомусора, так сразу
if (!$GLOBALS["mysqli"]->set_charset("utf8")) {
Вон, к слову, в том же flask'е параметры запроса через тред-локал глобалки передаются.
Там же не совсем чистая глобалка, она в мудуль завёрнута — flask.request. Так что неявно ничего в глобальном неймспейсе не появляется.
Но глобалка не перестаёт быть глобалкой если к ней префикс приписать. Так то я и в няшной я могу написать flask_request и радоваться.
Т.е. проблемы с реентерабельностью, внезапными побочными эффектами и т.п. никто не отменял.
Юзаю я, к примеру, ctypes.windll.user32.MessageBoxW. И хочу описать типы аргументов для него. Заафектит ли это соседние модули, которые тоже его юзают?
А это неважно. Я думаю 99.9% питонистов, которые с этим работали, ничего ответить не смогут.
Т.е. ctypes.windll.user32 возвращает один и тот же объект. Этот вариант не работает для линукса т.к. нужно полное имя so'шки.
При этом ctypes.WinDLL('user32.dll') всегда возвращает новый.
Functions exported by the shared library can be accessed as attributes or by index. Please note that accessing the function through an attribute caches the result and therefore accessing it repeatedly returns the same object each time. On the other hand, accessing it through an index returns a new object each time.
Т.е. user32.MessageBoxW всегда возвращает один и тот же объект.
Но user32['MessageBoxW'] вернёт отдельную копию, которую уже можно спокойно настраивать.
Всё это описано где-то в подвале документации. А туториал вверху страницы предлагает самый опасный вариант, когда и модуль и функция закешированы и расшарены.
Какие тонкости )))
Ох уж эта перегрузка операторов… Нет бы взять и сделать нормальный, человеческий «user32.load_function('MessageBoxW')», обязательно надо выёбываться.
И ещё везде эта любовь к кешированию в глобалках чтобы юзер уж точно наступил на грабли юзеру не пришлось писать свои переменные.
>>> On Windows, ctypes uses win32 structured exception handling to prevent crashes from general protection faults when functions are called with invalid argument values:
>>> There are, however, enough ways to crash Python with ctypes, so you should be careful anyway. The faulthandler module can be helpful in debugging crashes (e.g. from segmentation faults produced by erroneous C library calls).
Как раз недавно обсуждали, что будет, если поток в процессе убить прямо во время выполнения. Тут та же самая картина, только ещё хуже: своим «OSError» они делают вид, что всё хорошо, когда на самом деле после AC внутри системного вызова можно только сложить лапки и тихонько помереть.
Угу, это вообще уязвимость. Разрешили хакеру тыкаться в память, пока не повезёт. Даже meltdown можно реализовать!
SEH лучше вообще не обрабатывать. Как и соответствующие сигналы на линухе.
В джанге можно так
А вообще, у путей во фляжке есть крутая фишка:
Разница в том, что во-первых маппинг вынесен в отдельный файл, во-вторых первый параметр всегда request, а потом остальеые, и наконец есть ООПышки вокруг этого для фомочек там итд
Дык во фляжке тоже спокойно можно вынести.
> во-вторых первый параметр всегда request
Фу, бойлерплейт!
>бойлерплейт
зато не глобальное говно.
Алсо, очень часто писать вручную вьюшки вообще не надо, бо в комплекте идет куча говна, интегрированного с ORM, формами итд: фулстек жи.
Это уже вопрос подходов, а не функциональности. В официальном туториале, кстати, всё аккуратно разнесено по разным файлам:
https://github.com/pallets/flask/tree/1.1.2/examples/tutorial/flaskr.
> зато не глобальное говно.
Так во фласке оно и не глобальное.
>вопрос подходов
джанго гораздо более жестко диктует архитектуру
Ну да. В глобальном пространстве имён (пространстве имён текущего мудуля, если угодно) его не будет, если ты не попросишь. С тем же успехом «глобальным говном» можно назвать какое-нибудь «django.urls.path()».
> джанго гораздо более жестко диктует архитектуру
Я против фреймворков, в которых «Hello World» занимает шесть файлов.
Функция, зависящая только от своих аргументов, более чиста, и легче поддается тестированию.
>анимает шесть файлов.
Тогда тебе понарвится чистый PHP: там hello world занимает один файл.
А в чём проблема шести файлов, gost?
В оверинжиниринге и излишней сложности для простых задач.
Фреймворки же не делают для хелловордов.
Тем более, что эти файлы не надо руками писать в нормальных фреймворках.
> perekat.config
> perekat.schema
> perekat.log
> os.path.join(config.WORKING_DIR_PATH, 'templates')
- поясните мысль
Не, я тебя на самом деле отчасти понимаю. Сам в своё время плюнул на VIPER по этой причине, хотя у меня там и была кодогенерация.
Просто пусть будет хоть 106 файлов, если они реально нужны, а если у нас сущность ради сущности, то конечно, я с тобой только соглашусь, это ерунда
Если тебе нужно выдать по HTTP результат вызова одной функции, то конечно нужно брать flask: зачем тут джанга?
Если тебе нужно хранить в базе десять объектов, связанных между собой какими-то отношениями, и предоставлять UI для заполнения это базы через админику, то логичнее взять django.
Без привязок к конкретной задаче сравнивать трудно.
Но говрить "джанго говно, потому что там нужно шесть файлов" это как сказать "линукс хуже доса, потому что в линуксе больше файлов"
Ну так это же субъективное мнение. Вот не нравится мне она* и всё.
* А вот объективно я её рекомендую, разумеется. Если вдруг мне придётся писать гостевуху сложное веб-приложение — скорее всего, я буду это делать именно на ней.
* Template (шаблон)
* View (код, специфичный для отображения в html)
* Service layer (общий API системы, не специфичный для веба)
* Модели
В джанге вот сервис леера нету из коробки, остальное есть.
Остальное это вариации MVC. И у тебя три сущности по итогу. Поменял бы на 5 + Service layer?
>Поменял бы на 5 + Service layer?
надо смотреть как именно сделано.
В тяжелых случаях можно ввести еще ViewModel, и растянуть всё на еще большее число сущностей.
На нем можно писать веб приложения же).
Фласк с питоном позволяет делать это намного удобнее, но ведь и фласк надо ставить.
Это же всегда трейдофф: чем больше функциональности из коробки, тем питушня сложнее.
Если уж на то пошло, в «Python» любой объект хранит в себе состояние:
Там даже есть какие-то публичные атрибуты «func» и «keywords».
> Тогда тебе понарвится чистый PHP: там hello world занимает один файл.
А тебе нравится ЙАЖА и https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpriseEdition?
конечно, но ты не обязан это делать, правда?
>А тебе нравится ЙАЖА
Больше, чем ПХП.
И уж точно больше, чем написание одинакового говна.
Фласк, вероятно, хорош, когда у тебя либо специфические задачи, либо очень простые.
Когда же у тебя обычный энтерпрарйз с кучей объектов в бд, и кучей форрмочек для их заполнения, то вдруг внезапно оказывается, что достаточно описать модели, и получить из коробки готовую админку, готовые формочки с валидацией и сохранением созданных объектов, готовый ORM, и еще охулион django apps вроде поддержки oauth.
Ругать джангу за шесть файлов, это примерно как ругать питон за то, что в нем файлов больше, чем в lua
Что делать? Это «Питон» делает, а не я.
> И уж точно больше, чем написание одинакового говна.
Вроде лишнего параметра «request» даже там, где он не нужен?
> Фласк, вероятно, хорош, когда у тебя либо специфические задачи, либо очень простые.
Именно поэтому я за «простые задачи».
хранить в модуле состояние и ходить туда.
Жили были две функции:
какая из них лучше?
>Вроде лишнего параметра «request» даже там, где он не нужен?
Часто писать view вообще не обязательно.
https://docs.djangoproject.com/en/3.1/topics/class-based-views/generic-display/
>Именно поэтому я за «простые задачи».
К сожалению, не все задачи бывают простые.
Гост, пройди туториал по джанге, правда. Это займет у тебя не более часа, и наша беседа станет немного более предметной, не?)
«path» — это не мудуль, это функция.
> какая из них лучше?
Смотря зачем они нужны и где используются. С религиозной точки зрения, конечно, лучше может быть любая.
> Гост, пройди туториал по джанге, правда.
Я пытался. Отвращение к фронту не позволило продвинуться дальше первой главы.
еще лучше. Ты можешь навесить любой атрибут на функцию, но зачем?
> С религиозной точки зрения, конечно, лучше может быть любая.
Приведи пример, где лучше первая.
>Отвращение к фронту
К какому именно фронту? К языку шаблонизции? Он правда блевотный (как и все не xml-based), но его можно поменять.
Какой у тебя шаблонизатор во фласке?
Чтобы показать, что любой объект в «Питоне» хранит состояние.
> Приведи пример, где лучше первая.
Ну, например, мне нужно написать функции с единообразным определением petuh1()-petuh999(), из которых макаку использует только петух номер 123.
> К какому именно фронту?
К фронту как к концепции. «Джанга» слишком сильно привязана к созданию веб-сайтов. Не то что бы это не было её основным назначением, конечно…
> Какой у тебя шаблонизатор во фласке?
«Jinja», ЕМНИП.
может хранить, но ты не обязан это использовать, да?
>например
Я не очень понял юзкейс, можешь подробнее написать ЗАЧЕМ?
> «Джанга» слишком сильно привязана к созданию веб-сайтов.
Не понял. А чего ты хочешь? веб api?
Так есть Django REST, и там тоже самое все, только json вместо фронта.*
Шаблоны и статика не обязательны в Django.
>Jinja
Джанго её умеет из коробки, кстати.
template_engine можно поменять
*
https://www.django-rest-framework.org/
Я ж говорю — какое-то состояние есть у любых объектов. У того же «django.url.path» — публичные атрибуты «func» и «keywords».
> Не понял. А чего ты хочешь?
Писать бэк и никогда в глаза это дерьмо под названием «фронт» в общем и «HTML/CSS/JS» в частности не видеть! В гейдев податься, ёб.
Так в джанге ты не обязан же))
Я ж грю: ты можешь сделать приложение чисто с REST API.
Ну да, ты не используешь 20% возможностей джанги, но и пофиг.
Формочки с ORM у тебя всё равно будут, просто сабмититься они будут через REST API (и будут они не формочками, а json).
>гейдев
Я почему-то думал, что ты на работе крестовик, а вебпараша у тебя только для себя, не?
Собеседование: а можете переписать алгоритм, чтобы работал за логарифм от n?
Первый рабочий день: добавьте в отчет поле "страна", и выделите его красным
Так шо если кто-то в профессии чисто ради бабла, то почему и нет
То есть смена языка не приводит к резкому изменению ЗП обычно
> мне не известны случаи, чтобы крествик работал пыхером по причине бабла
- ну мож он изначально было скилловый пыхух, а потом в отпуске изучил кресты от корки до корки
Боюсь, что для изучения крестов пыхеру понадобится много отпусков, и еще потом года три практики, но это не точно
Конечно, если в конторе кап ограничен восьмьюстами долларами, то не так заметно
Кажется, что дело всё таки в процентах.
Если ты получаешь 10 долларов, то повышение на 20 долларов это очень много, правда?
> кап ограничен восьмьюстами долларами
хочется верить, что сеньоры столько не получают даже в Усть-Каменогорсках
- так это и не 20%.
Если мы говорим про сеньоров, неважно, пыхеров или крестовиков, в крупных городах, то зп в 4 и даже 5 косарей зелёных не кажется чем-то удивительным. При чём тут 10 долларов?
Если сенор получает 5К, то 1К для него не безумные деньги.
Если джун получает 1К, то разумеется 1К для него безумные деньги. А вот 200 баксов -- нет.
Потому что важен процент, а не абсолютное число.
Вот, что я пытался сказать.
Мы начали с того, что ты сказал, что +/- 20% это почти одинаково.
Вот возьмём ставку в 4500 и определим интервал по твоим процентам. Это от 3600 до 5400 баксов. 1800 разницы между минимумом и максимумом. Это копейки что ли?
Прикинь, ты дохуя сеньор и вдруг узнаёшь, что Вася из соседнего угла не только пялит по четвергам Катю из эйчарни, а ещё и получает на 1800 баксов больше. Твоя реакция?
Вот именно потому у нас в конторе зарплаты обсуждать и запрещено
Что будет, если разгласить?
Татьяныч, например, увольняет нахуй, если узнаёт.
это должно быть четко прописано, например, в приложении к трудовому договору о неразглашении, которое подписывает работник
если работник не хочет увольняться, то ты тупо заебешься его увольнять, проще будет сократить штатную единицу и заплатить 3 оклада
теперь ты думаешь в правильном направлении
он обязан выполнять то, что написано в условиях трудового договора (режим работы, характер работы), и он не обязан выполнять то, чего не написано
если он не хочет увольняться, он начнет писать кляузы в трудовую инспекцию, а сам ходить строго минуту в минуту на работу и делать не более того, что написано, чтобы у тебя был минимум шансов доебаться
трудовая инспекция не любит, когда в неё пишут, будет ходить на проверки, обязательно что-нибудь найдет (кадровый учет это полный пиздос, его точно не программисты разрабатывали, трактовки могут быть иногда диаметральные)
т.е. не надо ссориться со своими работниками, и надо расставаться полюбовно
можно сделать сердитое лицо и пригрозить, что ты дико заебешь его - но в подавляющем большинстве случаев суд всё равно встанет на его сторону, если до него дойдет
так что проще будет расстаться полюбовно
(если что, все страшилки я рассказываю не из личного опыта, но в курсе о том, что такой головняк работодателю нахер не сдался, лучше не попадать в эти ситуации)
в США могут выпиздить работника в любой момент, куча способов и культура чуть ли не почасовой оплаты, и даже если ты резко заболел, то ты уже под угрозой
дикие люди
Да и хуй с ней. Зачем нужна такая жена? Он же не в мешок её засунул и увёз в свой осетинский аул.
Когда сохраняются чисто рабочие отношения, то и рабочие вопросы решать проще.
Ну и зачем лишний повод давать для обвинений в фаворитизме
Бухать всей командой тоже нельзя? Ну и руководитель может уйти, а на его место с высокой вероятностью станет кто-то из команды, и что, разрывать нерабочее общение?
> Это же не служба
- а что это, хобби за зарплату?
Тут либо несовместимость, косяки с моей стороны и т.п. И тогда чела в общем-то не в чем обвинять.
Либо у этой бывшей жены какие-то странные приоритеты, и чела можно только пожалеть.
Жена не велик, просто так не уведут.
Тред не об этом, я для примера привёл. Вопрос был в том как выпиздить сотрудника.
И да, ничего не сработает, если сотрудник беременная или в декретном отпуске (по родам или уходу за ребенком), кроме закрытия конторы.
Попробуйте выйти и зайти.
Блин, даже тут это работает.
1) прежде всего стоит признать, что это проеб менеджера/начальника, любую поебень можно детектить на относительно раннем этапе, пресекать, принимать меры, не доводить до крайностей
если дошло до крайностей - работник даже не на половину виноват
2) любая подобная хуита будет дизморалить коллектив, дизмораленный коллектив - эффективность ниже средней по больнице, с таким настроением горы не свернуть
т.к. я всегда ставлю высокие цели, а решаем мы нестандартные вещи, на низкой морали это никак, фейл
поэтому надо оградить остальных в первую очередь, минимизировать ущерб
3) если коллектив настроен однозначно, что работник - мудак, то он его сожрет сам, работодатель же должен быть выше всего этого, строго в правовом поле
если в вертикальных взаимоотношениях начинается хуйня, то это кто-то самоутверждается, и точно вредит бизнесу
если коллектив неоднозначно оценивает кто мудак, а кто нет, значит работодатель мудак, он должен признать это и расстаться полюбовно, с выплатой нужного числа окладов, и сделать это как можно быстрее
Большинство самцов проявляет агрессию к тем, кому дала их самка, хотя это очевидно глупо: выпёздывание с работы любовника жены не приводит к возврату жены. Но люди живут эмоциями, а не мозгом
Именно поэтому я за подушку.
Доебаться всегда есть до чего.
Но сотрудник может пойти в суд, и заебать тебя в ответ.
Так что лучше уговорить его уволиться самому
Не представляю, каким надо быть чмом, чтобы работать на этого анального самодура.
Что будет у нас -- я не знаю, скоее всего начальник вызовет на тет-а-тет, и очень сильно попросит так больше не делать. Большинству людей этого будет достаточно, потому что зачем ссориться с начальником?
Да и хуй с ними.
Меня моя зарплата и работа устраивает - значит норм.
Иначе можно крышей поехать от всех этих сравнений кто больше хуи пинал, а кто лучше код пишет.
Получать больше лучше, чем получать меньше.
Если коллега на такой же должности получает почти на два косаря больше, это повод задуматься.
Но, в общем, спорить тут не о чем, это дело каждого.
быть богатым и здоровым лучше, чем бедным и больным
Прикинь, ты дохуя сеньор и вдруг узнаёшь, что Вася из соседнего угла не только пялит по четвергам Катю из эйчарни, а ещё и получает на 1800 баксов больше. Твоя реакция?
- сильно зависит от географии. В моём родном зажопье сеньоры получали от полутора косарей, а 800 это была зарплата мидла-дева.
Если питон встраивать в приложуху, то там доступны все стандартные либы? То есть скрипты такой приложухи могут рассылать реквесты со спамом и майнить крипту помимо прочего в тайне от пользователя?
В старом питоне да, скрипт работает на правах самой приложухи и может делать всё что хочет. Что-то можно обрезать, но всё равно дофига дыр останется. Т.е. недоверенное говно лучше не запускать.
Если хочешь более-менее секьюрный сендбокс - лучше lua, может быть js ещё. Там про это изначально думали, в отличие от питона.
Там тулза генерит сишный файл, в котором транслированы все доступные дефиниции. И по умолчанию там только racket/base, который умеет чуть более, чем нихуя. Хочешь больше модулей - указывай это явно при генерации.
Вообще это логично: не плати за то, что не используешь