- 001
- 002
- 003
- 004
- 005
- 006
- 007
- 008
- 009
- 010
- 011
- 012
- 013
- 014
- 015
- 016
- 017
- 018
- 019
- 020
- 021
- 022
- 023
- 024
- 025
- 026
- 027
- 028
- 029
- 030
- 031
- 032
- 033
- 034
- 035
- 036
- 037
- 038
- 039
- 040
- 041
- 042
- 043
- 044
- 045
- 046
- 047
- 048
- 049
- 050
- 051
- 052
- 053
- 054
- 055
- 056
- 057
- 058
- 059
- 060
- 061
- 062
- 063
- 064
- 065
- 066
- 067
- 068
- 069
- 070
- 071
- 072
- 073
- 074
- 075
- 076
- 077
- 078
- 079
- 080
- 081
- 082
- 083
- 084
- 085
- 086
- 087
- 088
- 089
- 090
- 091
- 092
- 093
- 094
- 095
- 096
- 097
- 098
- 099
- 100
<?php
/* -= Developed by [email protected] =- */
// -= О П Ц И И =-
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
Фу, бойлерплейт!
>бойлерплейт
зато не глобальное говно.
Алсо, очень часто писать вручную вьюшки вообще не надо, бо в комплекте идет куча говна, интегрированного с ORM, формами итд: фулстек жи.
Это уже вопрос подходов, а не функциональности. В официальном туториале, кстати, всё аккуратно разнесено по разным файлам:
https://github.com/pallets/flask/tree/1.1.2/examples/tutorial/flaskr.
> зато не глобальное говно.
Так во фласке оно и не глобальное.
Ну да. В глобальном пространстве имён (пространстве имён текущего мудуля, если угодно) его не будет, если ты не попросишь. С тем же успехом «глобальным говном» можно назвать какое-нибудь «django.urls.path()».
> джанго гораздо более жестко диктует архитектуру
Я против фреймворков, в которых «Hello World» занимает шесть файлов.
А в чём проблема шести файлов, gost?
В оверинжиниринге и излишней сложности для простых задач.
Фреймворки же не делают для хелловордов.
Тем более, что эти файлы не надо руками писать в нормальных фреймворках.
> perekat.config
> perekat.schema
> perekat.log
> os.path.join(config.WORKING_DIR_PATH, 'templates')
- поясните мысль
Не, я тебя на самом деле отчасти понимаю. Сам в своё время плюнул на VIPER по этой причине, хотя у меня там и была кодогенерация.
Просто пусть будет хоть 106 файлов, если они реально нужны, а если у нас сущность ради сущности, то конечно, я с тобой только соглашусь, это ерунда
Ну так это же субъективное мнение. Вот не нравится мне она* и всё.
* А вот объективно я её рекомендую, разумеется. Если вдруг мне придётся писать гостевуху сложное веб-приложение — скорее всего, я буду это делать именно на ней.
Остальное это вариации MVC. И у тебя три сущности по итогу. Поменял бы на 5 + Service layer?
Если уж на то пошло, в «Python» любой объект хранит в себе состояние:
Там даже есть какие-то публичные атрибуты «func» и «keywords».
> Тогда тебе понарвится чистый PHP: там hello world занимает один файл.
А тебе нравится ЙАЖА и https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpriseEdition?
Что делать? Это «Питон» делает, а не я.
> И уж точно больше, чем написание одинакового говна.
Вроде лишнего параметра «request» даже там, где он не нужен?
> Фласк, вероятно, хорош, когда у тебя либо специфические задачи, либо очень простые.
Именно поэтому я за «простые задачи».
«path» — это не мудуль, это функция.
> какая из них лучше?
Смотря зачем они нужны и где используются. С религиозной точки зрения, конечно, лучше может быть любая.
> Гост, пройди туториал по джанге, правда.
Я пытался. Отвращение к фронту не позволило продвинуться дальше первой главы.
Чтобы показать, что любой объект в «Питоне» хранит состояние.
> Приведи пример, где лучше первая.
Ну, например, мне нужно написать функции с единообразным определением petuh1()-petuh999(), из которых макаку использует только петух номер 123.
> К какому именно фронту?
К фронту как к концепции. «Джанга» слишком сильно привязана к созданию веб-сайтов. Не то что бы это не было её основным назначением, конечно…
> Какой у тебя шаблонизатор во фласке?
«Jinja», ЕМНИП.
Я ж говорю — какое-то состояние есть у любых объектов. У того же «django.url.path» — публичные атрибуты «func» и «keywords».
> Не понял. А чего ты хочешь?
Писать бэк и никогда в глаза это дерьмо под названием «фронт» в общем и «HTML/CSS/JS» в частности не видеть! В гейдев податься, ёб.
Так шо если кто-то в профессии чисто ради бабла, то почему и нет
То есть смена языка не приводит к резкому изменению ЗП обычно
> мне не известны случаи, чтобы крествик работал пыхером по причине бабла
- ну мож он изначально было скилловый пыхух, а потом в отпуске изучил кресты от корки до корки
Конечно, если в конторе кап ограничен восьмьюстами долларами, то не так заметно
- так это и не 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, который умеет чуть более, чем нихуя. Хочешь больше модулей - указывай это явно при генерации.