Страницы

Поиск по вопросам

вторник, 13 ноября 2018 г.

Конфликт bootstrap 4 и angular 4 - некорректно вычисляется высота блоков

Как сделать страницу аналогично https://startbootstrap.com/template-overviews/3-col-portfolio/ с boostrap 4 и angular 4?
Изначально использовались boostrap 3 и angular 4, пытался сделать страницу по примеру, в котором используется bootstrap 4 https://startbootstrap.com/template-overviews/3-col-portfolio/ https://blackrockdigital.github.io/startbootstrap-3-col-portfolio/
вот мои попытки с моей версией boostrap 3 http://jsfiddle.net/96thessa/4/ здесь вроде бы все работает аналогично, но если добавляется angular, место под изображение растягивается на высоту всего блока, а текст съезжает. при использовании angular происходит следующее https://imgur.com/9IZ1Jvx размеры пустой картинки: https://imgur.com/z3sqNoe вначале блоки отображаются аналогично http://jsfiddle.net/96thessa/4/ но через мгновение пустая картинка занимает всю высоту блока и выталкивает текст ниже границы блока. С bootstrap 4 ситуация аналогичная.
Страница - компонент angular, соответственно, boostrap скрипт и стили подгружаются в индексе, а стиль самого компонента содержит правила для классов card, card-img-top и т.д. На jsfiddle.net не знаю, как эти все нюансы воспроизвести с учетом angular. Возможно, angular вносит смуту? Влияет ли порядок загрузки стилей на расчет размера картинки? Или boostrap не стоит подключать через link и script в html файле, а лучше каким-то другим способом? Влияет ли angular на отображение изображений таким образом? В стилях в инспекторе браузера не увидел ничего дополнительного, что бы могло исказить отображение. Пробовал использовать изображение, не обрамленное ссылкой a, результат тот же.
Update: архив тестовые исходники
Update: пока костыльное решение - не показывать несуществующие изображения (display: none), но блоки все равно почему-то растягиваются больше, чем нужно, в высоту. Пытался заменить margin-ы на padding-и, эффект не особо изменился, автоматический расчет высоты блока происходит неверно, я полагаю, проблема не в изображениях, а в самих блоках.
Update: пытаюсь устранить конфликт angular и bootstrap, используя ng-bootstrap. Выполнил установку npm install --save @ng-bootstrap/ng-bootstrap, убрал подключение bootstrap.min.js и jquery.min.js, оставив только подключение bootstrap.min.js (4.0.0-beta.2). В app.module.ts внес изменения:
import {NgbModule} from '@ng-bootstrap/ng-bootstrap'; ...
@NgModule({ ... imports: [ ... NgbModule.forRoot(), ... ], providers: [ ... ], bootstrap: [AppComponent] }) ...
Высота блоков по-прежнему рассчитывается некорректно.
Ссылка на страницу
Update: добавил стили
.h-100[_ngcontent-c3] { height: auto !important; } .h-100 { height: auto!important; } .h-100[_ngcontent-c4] { height: auto !important; } .container[_ngcontent-c3] .card[_ngcontent-c3] { height: auto !important; }
и убрал
.h-100 { height: 100%!important; }
результат: https://i.imgur.com/ULzNpFK.png Внешние дивы для блоков имеют корректную высоту, но .card сжимается по контенту по высоте, и соседние колонки не выравниваются в итоге по высоте, хотя стиль height: auto !important; применяется. Проверял в chrome, firefox. Искомая страница, с которой сделан скриншот Ссылка на страницу


Ответ

Вы не указали стили к классу .row
.row { display: -ms-flexbox; display: flex; -ms-flex-wrap: wrap; flex-wrap: wrap; margin-right: -15px; margin-left: -15px; }
Результат:

Обновление 0.0.1:
На предоставленном ресурсе возможно поправить верстку внеся вот такие изменения:
Удалите css код:
.h-100[_ngcontent-c3] { height: 100% !important; } .h-100 { height: 100%!important; }
Если нет возможности удалить, замените на height: auto important;
После для выравнивания вы можете написать:
.portfolio-item[_ngcontent-c3] { margin-bottom: 30px; display: flex; }
И если размер картинок будет всегда один сделать вот так:
.card.h-100 img { max-height: 200px; }
В итоге вы получите вот такой результат:
Вариант №1 С картинкой но битой ссылкой
Вариант №2 Полностью без картинки(без тега < img >)

Как выбрать и заблокировать 100 строк?

Несколько потоков модифицируют таблицу. Хочу выбрать из таблицы 100 не заблокированных строк и заблокировать их. Написал запрос:
select * from table where rownum <= 100 for update skip locked
Однако при таком варианте сначала применяется условие rownum<=100 и только потом выбрасываются заблокированные строки из результата запроса. Обернуть этот запрос не разрешается. Как можно выбрать первые 100 не заблокированных строк из таблицы и заблокировать их ?


Ответ

Существующее ограничения на for update не позволяют решить эту задачу только средствами SQL. В подзапросе этот конструкт недопустим, в 12c fetch first n rows only тоже не совместим с for update, т.е. такое не выполнится:
select * from (select * from table for update skip locked) where rownum <= 100;
Завернуть в табличную функцию также проблематично, так как она не может содержать DML операции, если её вызывать в запросе.
Исключение - автономные трансакции, но есть слабое место - выбранные строки между возвратом и основным запросом будут разлочены, что может привести к нежелательному результату. Следующий пример вроде решает задачу, но краш-тест с несколькими потоками в цикле без сомнения выявит недостатки:
create or replace type itemRow as object (id number, name varchar2 (32)); / create or replace type itemRows is table of itemRow; / drop table items; create table items (id number, name varchar2 (32)); / insert into items select level, 'item '||level from dual connect by level<=200 ; create or replace function getUnlockedItemsBlock return itemRows is pragma autonomous_transaction; cursor mycur is select itemRow(i.id, i.name) item from items i for update skip locked; ret itemRows; begin open mycur; fetch mycur bulk collect into ret limit 100; close mycur; commit; return ret; end; / update items set name=name||'*' where id between 5 and 104;
100 rows updated.
В другой сессии:
select i.id, i.name, count (1) over () "total locked by myself" from items i join table (getUnlockedItemsBlock) t on t.id = i.id for update of i.id ;
ID NAME total locked by myself ------ -------------------------------- ---------------------- 1 item 1 100 2 item 2 100 3 item 3 100 4 item 4 100 105 item 105 100 106 item 106 100 107 item 107 100 108 item 108 100 ...
Наиболее приемлиемое решение - надо, или отказаться от for update skip locked для разделения "зон влияния" между потоками, или как минимум от идеи "только одним SQL запросом" и остаться в PL/SQL контексте:
set serveroutput on size unlimited <> declare cursor mycur is select itemRow(i.id, i.name) item from items i for update skip locked; items itemRows; begin open mycur; fetch mycur bulk collect into items limit 100; close mycur; for idx in 1..items.count loop dbms_output.put_line ('processing item: '||items(idx).id||'/'||items(idx).name); end loop; end; /
processing item: 1/item 1 processing item: 2/item 2 processing item: 3/item 3 processing item: 4/item 4 processing item: 105/item 105 processing item: 106/item 106 processing item: 107/item 107 processing item: 108/item 108 ... /* всего 100 строк */
Также приемлимо завернуть подобный курсор в функцию возврающую результат в виде массива залоченых строк в клиент для дальнейшей обработки и завершения трансакции.

Странности приведения .Net 4.6.1

Чтобы не вдаваться в детали самого кода, приведу более абстрактную ситуацию. Как мы все прекрасно знаем, следующий код вполне себе рабочий:
int a = 1; double b = (double)a;
Рабочим он оставался и в таком случае:
int a = 1; object b = a; double c = (double)b;
(Ибо в объекте содержится int, a int к double приводится без проблем). Но каково же было моё удивление, когда аналогичный по сути кусок кода отказался работать на новом фреймворке. То есть на, грубо говоря, строке
double c = (double)b;
У меня вылетает ошибка, что такое приведение является недопустимым. Такое положение дел меня весьма расстроило и я, с грустным лицом временно запилив в ту строку Convert.ChangeType(), пошёл писать сюда сей вопрос дабы выяснить, что тут происходит.

Является ли данное "ужесточение" типизации не багом, а фичей, и лечится ли это как-нибудь более элегантно, нежели через вызов дополнительного метода из Convert?


Ответ

Понятно, что упаковка и распаковка/копирование снижают производитель- ность приложения (в плане как замедления, так и расходования дополнительной памяти), поэтому нужно знать, когда компилятор сам создает код для выполнения этих операций, и стараться свести их к минимуму. При распаковке упакованного значимого типа происходит следующее.
Если переменная, содержащая ссылку на упакованный значимый тип, равна null, генерируется исключение NullReferenceException. Если ссылка указывает на объект, не являющийся упакованным значением требуемого значимого типа, генерируется исключение InvalidCastException1
Из Рихтера "CLR VIA 4.5"

Хочу убрать стандартный скролл , а поставить не широкий красивый как на смартфонах

Хочу убрать стандартный скролл , поставить не широкий красивый как на смартфонах, чувствую решить проблему может js/jquery


Ответ

Можно сделать и с помощью css. Пример. P.S. Если я правильно понял задание, то уже настроите под себя:)
body { min-height: 250vh; } ::-webkit-scrollbar-button { width: 5px; height: 0px } /* Цвет дорожки, по которой двигается бегунок прокрутки. */ ::-webkit-scrollbar-track { background-color: #ecedee } /* Цвет бегунка полосы, а так же его закругление. */ ::-webkit-scrollbar-thumb { -webkit-border-radius: 0px; border-radius: 0px; background-color: #6dc0c8; } /* Цвет бегунка при наведении на него курсора. */ ::-webkit-scrollbar-thumb:hover { background-color: #56999f; } /* Основная ширина полосы прокрутки. */ ::-webkit-resizer { width: 4px; height: 0px } ::-webkit-scrollbar { width: 4px; }
ИЛИ:
Подробнее...
body { min-height: 250vh; }
It supports DIVs, IFrames, textarea, and document page (body) scrollbars. Compatible with all desktop browser: Firefox 4+, Chrome 5+, Safari 4+ (win/mac), Opera 10+, IE 6+. (all A-grade browsers)

Как задать имя ключа для связи многие ко многим?

Для разработки базы данных использую подход code first. Есть два класса
public class Assembly { public int Id {get;set;}
public virtual ICollection Items {get;set;} = new List(); }
public class OperationItem { public int Id {get;set;}
public virtual ICollection Assemblies {get;set;} = new List(); }
на основании этого entity framework генерирует следующую миграцию:
CreateTable( "dbo.AssemblyOperationItems", c => new { Assembly_Id = c.Int(nullable: false), OperationItem_Id = c.Int(nullable: false), }) .PrimaryKey(t => new { t.Assembly_Id, t.OperationItem_Id }) .ForeignKey("dbo.Assemblies", t => t.Assembly_Id) .ForeignKey("dbo.OperationItems", t => t.OperationItem_Id) .Index(t => t.Assembly_Id) .Index(t => t.OperationItem_Id);
сам скрипт миграции корректный, меня не устраивает присваиваемые имена: Assembly_Id & OperationItem_Id, а в во всех остальных таблицах ключи называются AssemblyId & OperationItemId
Можно ли сказать EF что бы он генерировал имена без использования _ в имени ключа при создании связи многие ко многим.
P.S. Я знаю про то что данную проблему можно решить если создать связь через fluent api, интересует иное решение, атрибуты аннотации и т.п.


Ответ

Когда используется связь many-to-many, то используется соглашение об именовании FK, которые перегрузить не имеется возможности с помощью аннотации. Согласно соглашению об именовании, FK формируется по следующему правилу
<имя таблицы>_<имя первичного ключа таблицы>
То, что мы и наблюдаем в примере.
Чтобы это перегрузить, можно сделать следующее:
Как вы отметили, использовать FluentAPI следующим образом:
protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity() .HasMany(s => s.Items) .WithMany(c => c.Assemblies) .Map(cs => { cs.MapLeftKey("ItemsRefId"); cs.MapRightKey("AssembliesRefId");
}); }
В результате, у нас получится следующая миграция:
CreateTable( "dbo.AssemblyOperationItems", c => new { ItemsRefId = c.Int(nullable: false), AssembliesRefId = c.Int(nullable: false), }) .PrimaryKey(t => new { t.ItemsRefId, t.AssembliesRefId }) .ForeignKey("dbo.Assemblies", t => t.ItemsRefId, cascadeDelete: true) .ForeignKey("dbo.OperationItems", t => t.AssembliesRefId, cascadeDelete: true) .Index(t => t.ItemsRefId) .Index(t => t.AssembliesRefId); Перегрузить соглашение по именованию вторичных ключей.
Когда нас не устраивает стандартное соглашение имен, мы можем это соглашение перегрузить. Пример взять отсюда Определим класс по переименованию имен для вторичных ключей, который будет удалять символ _, который генерируется согласно стандартному соглашению имен.
// Provides a convention for fixing the independent association (IA) foreign key column names. public class ForeignKeyNamingConvention : IStoreModelConvention {
public void Apply(AssociationType association, DbModel model) { // Identify ForeignKey properties (including IAs) if (association.IsForeignKey) { // rename FK columns var constraint = association.Constraint; if (DoPropertiesHaveDefaultNames(constraint.FromProperties, constraint.ToRole.Name, constraint.ToProperties)) { NormalizeForeignKeyProperties(constraint.FromProperties); } if (DoPropertiesHaveDefaultNames(constraint.ToProperties, constraint.FromRole.Name, constraint.FromProperties)) { NormalizeForeignKeyProperties(constraint.ToProperties); } } }
private bool DoPropertiesHaveDefaultNames(ReadOnlyMetadataCollection properties, string roleName, ReadOnlyMetadataCollection otherEndProperties) { if (properties.Count != otherEndProperties.Count) { return false; }
for (int i = 0; i < properties.Count; ++i) { if (!properties[i].Name.EndsWith("_" + otherEndProperties[i].Name)) { return false; } } return true; }
private void NormalizeForeignKeyProperties(ReadOnlyMetadataCollection properties) { for (int i = 0; i < properties.Count; ++i) { int underscoreIndex = properties[i].Name.IndexOf('_'); if (underscoreIndex > 0) { properties[i].Name = properties[i].Name.Remove(underscoreIndex, 1); } } } }
Включаем класс перегрузке именования вторичных ключей в нашу модель следующим образом
protected override void OnModelCreating(DbModelBuilder modelBuilder) { /*modelBuilder.Entity() .HasMany(s => s.Items) .WithMany(c => c.Assemblies) .Map(cs => { cs.MapLeftKey("ItemsRefId"); cs.MapRightKey("AssembliesRefId");
}); */
modelBuilder.Conventions.Add(); }
В результате, мы получаем следующую миграцию
CreateTable( "dbo.OperationItemAssemblies", c => new { OperationItemId = c.Int(nullable: false), AssemblyId = c.Int(nullable: false), }) .PrimaryKey(t => new { t.OperationItemId, t.AssemblyId }) .ForeignKey("dbo.OperationItems", t => t.OperationItemId, cascadeDelete: true) .ForeignKey("dbo.Assemblies", t => t.AssemblyId, cascadeDelete: true) .Index(t => t.OperationItemId, name: "IX_OperationItem_Id") .Index(t => t.AssemblyId, name: "IX_Assembly_Id");
Как вы могли заметить, имена вторичных ключей теперь стали без символа '_'.

BSOD при работе программы под .NET 4.6.2

Есть программа ("Электронной очереди") написанная на C# под фреймворк .NET 4.6.2 Программа должна постоянно крутится на сервере, но стали поступать жалобы, что компьютер перезагружается несколько раз в день, снял дамп, там присутствует постоянно 1 ошибка SYSTEM_SERVICE_EXCEPTION 0x0000003b. driver ntoskrnl.exe

Погуглив данную ошибку я нашел, что в причина скорее всего в железе (видео карты, память, HDD). Моя программа также использует железо. Я хотел спросить, может ли данный BSOD быть из за ошибок в коде, или это исключено и в любом случае будет только Exception уровня приложения.
1. Программа использует сетевую карту. 4 терминала по выдаче билетов, подключены по TCP/IP
2. Программа использует 2 USB порта: Конверторы RS-485 в USB, к ним подключены кассовые планшеты
3. Карта передающая видеобуфер. Через эту карту подключены табло, через спец программу (Mars) происходит захват видео буффера с областей экрана, эти области и идут на табло. Карта вставлена в PCI слот и подключается как монитор по DVI.
4. Вывод звука через встроенную звуковую карту. Из низкоуровневых библиотек я использую Naudio.dll (Подтягивал через Nuget).
Объект важный, хотелось бы услышать ваши мнения.


Ответ

Исключение SYSTEM_SERVICE_EXCEPTION означает проблему при переходе из кода уровня пользователя в код уровня ядра. Она может возникать например, из-за того, что данные, переданные модулю ядра, были каким-то образом повреждены и не было предусмотрено проверки их корректности. Parameter 1 у BSOD - код исключения, 0xC0000005 соответствует STATUS_ACCESS_VIOLATION, т.е. произошла попытка обратиться к защищенной области памяти.
Причиной может быть как дефект железа, так и ошибка в коде драйвера (ошибка в коде .Net приложений напрямую обычно не вызывает такое исключение). Поскольку драйвера видеоадаптеров в Windows разделены на модули уровня ядра и уровня пользователя, наибольшее подозрение падает именно на них.
Для диагностики проблемы можно попробовать следующее:
Настроить windbg на правильные символы и попытаться получить стек вызовов и список загруженных модулей. Это поможет выявить, какие именно драйвера вызывают проблему. Обновить драйвера до последних версий. Те драйвера, которые уже были недавно обновлены, наоборот попробовать откатить на предыдущую версию (т.к. в новой версии могла появится ошибка). Если проблема не исчезнет, вернуть новую версию. Заменять компоненты железа на заведомо исправные, и смотреть, на каком исчезнет ошибка.

PHP: все ли части обрабатываются в составном логическом выражении или обработка прекращается после первого false?

Допустим, в выражении
if (0 == 1 && (2+2) == 5 && $object->getValue() == true) { ... }
Будет ли высчитываться 2+2 и $object->getValue() или логическое выражение сразу вернет ложь из-за 0 == 1 ?


Ответ

Есть такое понятие, как Short-circuit evaluation (оно же minimal evaluation, оно же McCarthy evaluation).
Суть Short-circuit evaluation состоит в том, что для логических выражений, использующих определенные логические операторы (в русской документации оно переведено, как "шунтирующие операторы"), вычисление результата всего выражения происходит последовательно, слева направо и прекращается тогда, когда вычисление последующих частей выражения не повлияет на конечный результат.
Например
$a = false && expression2 && expression3 && ....; $b = false || true || expression2 || expression3 || ....;
Вычисление значения для $a остановится сразу же после первого false. expression2 и expression3 даже не будут вычисляться/исполняться, поскольку уже не смогут повлиять на конечный результат.
Вычисление $b остановится после первого выражения, вернувшего true, по тем же причинам.
В PHP, шунтирующими операторами(т.е. для которых будет выполняться подобный алгоритм вычисления) являются &&, ||, and и or

Лидирующий “0” в std::atoi

Вот такой код выводит "10" в консоль (VS2017):
#include
int main() { int a = std::atoi("010"); std::cout << a << std::endl; }
Т.е. ведущий ноль игнорируется, но на сколько это стандартизировано? Здесь и здесь не нашел.


Ответ

Согласно стандарту С11 функция int atoi(const char *nptr); эквивалентна (int)strtol(nptr, (char **)NULL, 10) за исключением поведения при ошибке.
В описании последней помимо прочего сказано:
... only letters and digits whose ascribed values are less than that of base are permitted.
0 является валидной десятичной цифрой, таким образом наличие предшествующих нулей не должно влиять на результат вызова.
Наличие нуля в начале могло бы влиять при автоматическом определении основания системы счисления, т.е. при указании base = 0, но для atoi это не актуально.

BlockingCollection - как не блокировать поток

Применение BlockingCollection, используя подход, когда элементы вытаскиваются из очереди(например ConcurrentQueue), используя метод Take в цикле - всегда блокирует поток. Очевидно, что процессорное время не занимается, однако поток все же занят и не может использоваться для выполнения других задач. Какая есть альтернатива, когда нужно последовательно вычитывать элементы из очереди и при этом не блокировать поток? Конечно, можно сделать велосипед, накрутить событий или чего-нибудь еще, но хотелось бы понять, нет ли каких-либо стандартных способов это сделать, кроме как использовать BlockingCollection и метод Take
P.S. Есть метод TryTake, но я не могу найти решение с его использованием, эквивалентное использованию Take и при этом неблокирующее поток.


Ответ

Вам на самом деле нужен класс BufferBlock из библиотеки Dataflow (nuget-пакет Microsoft.Tpl.Dataflow).
Этот класс заменяет собой BlockingCollection, и позволяет асинхронный доступ:
await queue.ReceiveAsync()
Таким образом, поток не будет заблокирован. Но у вас получится async-интерфейс.
Больше примеров с работающим кодом есть в этом ответе

Ещё одним вариантом является async-обёртка над IProducerCosumerCollection из AsyncEx Стивена Клири: https://github.com/StephenCleary/AsyncEx/wiki/AsyncCollection

Удаление строки таблицы JS

Всем здравствуйте, столкнулся со следующей проблемой. Необходимо при нажатии на чекбокс в конкретной строке таблицы удалять эту строку из таблицы. Использую конструкцию
checkbox.addEventListener("click", function () { var row1 = document.getElementById("checkbox_id").parentNode.parentNode; });
Так я получаю строку. Но получаю не ту строку, в которой жму чекбокс, а первую. Это первый мой косяк. А второй - не могу понять как ее удалить. Понимаю, что нужно использовать removeChild, но собрать это воедино не выходит. Помогите пожалуйста.
function insertRow(id) { var tbody = document.getElementById(id).getElementsByTagName("tbody")[0]; var row; row = document.createElement("tr"); row.setAttribute("id", "tr_id"); var cellCounter = document.getElementById("myTable").rows.length; var td1 = document.createElement("td"); td1.setAttribute("id", "td1_id"); td1.appendChild(document.createTextNode(cellCounter)); var td2 = document.createElement("td"); td2.setAttribute("id", "td2_id"); var checkbox = document.createElement("input"); checkbox.setAttribute("type", "checkbox"); checkbox.setAttribute("id", "checkbox_id"); checkbox.addEventListener("click", function() { var row1 = document.getElementById("checkbox_id").parentNode.parentNode; // row1.parentNode.removeChild(row1); console.log(row1); }); td2.appendChild(checkbox); var td3 = document.createElement("td"); td3.setAttribute("id", "td3_id"); td3.appendChild(document.createTextNode(document.getElementById("add_id").value)); var td4 = document.createElement("td"); td4.setAttribute("id", "td4_id"); td4.appendChild(document.createTextNode(document.getElementById("quant_id").value)); var td5 = document.createElement("td"); td5.setAttribute("id", "td5_id"); td5.appendChild(document.createTextNode(document.getElementById("price_id").value)); var td6 = document.createElement("td"); td6.setAttribute("id", "td6_id"); var btnEdit = document.createElement("input"); btnEdit.setAttribute("class", "btnEdit"); btnEdit.src = "icons/edit.png"; btnEdit.type = "image"; btnEdit.addEventListener('click', function() { editButton(); return false; }); td6.appendChild(btnEdit); var deleteButton = document.createElement("input"); deleteButton.setAttribute("class", "deleteButton"); deleteButton.src = "icons/delete.png"; deleteButton.type = "image"; deleteButton.addEventListener('click', function() { delButton(); return false; }); td6.appendChild(deleteButton); td6.setAttribute("colspan", "2"); row.appendChild(td1); row.appendChild(td2); row.appendChild(td3); row.appendChild(td4); row.appendChild(td5); row.appendChild(td6); tbody.appendChild(row); localStorage.setItem("ShoppingList", document.getElementById("myTable").innerHTML); }

# Done Item Quantity Price $ Action


Ответ

Что бы вам получить доступ к элементу, который вызвал функцию вам надо
checkbox.addEventListener("click", function (e) { var checkboxElement = e.target; // элемент который вызвал функцию });
либо
checkbox.addEventListener("click", function () { var checkboxElement = this; // элемент который вызвал функцию });
Что бы удалить элемент надо
ell.parentElement.removeChild(ell);
в вашем случае
ell = checkboxElement.parent.parent; // tr element (ваша строчка) ell.parentElement.removeChild(ell); // удаляем всю строку
или более красиво
ell = checkboxElement.closest("tr"); // tr element (ваша строчка) ell.parentElement.removeChild(ell); // удаляем всю строку

Как проверить у файла наличие защиты?

При скачивании файла с интернета он маркируется для защиты таким образом:

Как с помощью своего приложения отслеживать файлы с такой пометкой защиты? Например при перетаскивании файла на приложение.


Ответ

Скорее всего, вам нужно просто разблокировать файл в случае, если он заблокирован.
Официальный путь — вызовите Powershell-cmdlet Unblock-File. Для этого установите nuget-пакет System.Management.Automation, и воспользуйтесь таким кодом:
using (var ps = PowerShell.Create()) { ps.AddCommand("Unblock-File", true); ps.AddParameter("LiteralPath", fullPath); ps.Invoke(); }

Альтернативный путь — можно воспользоваться знанием о том, что в текущих версиях Windows данные о заблокированном файле содержатся в альтернативном потоке данных NTFS под названием Zone.Identifier, и убрать его через P/Invoke (код одолжен на en.SO):
[DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool DeleteFile(string name );
public bool Unblock(string fileName) { return DeleteFile(fileName + ":Zone.Identifier"); }

Окей, если вам и правда нужно лишь проверить, есть ли защита, придётся поработать с COM-объектами. За блокировку отвечает COM-объект PersistentZoneIdentifier. Код одолжен здесь и здесь, и адаптирован.
using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes;
static class BlockChecker { public static bool IsBlocked(string path) { object persistZoneId = Activator.CreateInstance( Type.GetTypeFromCLSID(Guid.Parse(CLSID_PersistentZoneIdentifier))); var zoneIdentifier = (IZoneIdentifier)persistZoneId; var persistFile = (IPersistFile)persistZoneId; try { persistFile.Load(path, 0); // STGM_READ var id = zoneIdentifier.GetId(); return id == URLZONE.URLZONE_INTERNET || id == URLZONE.URLZONE_UNTRUSTED; } catch { return false; } finally { if (persistZoneId != null) Marshal.FinalReleaseComObject(persistZoneId); } }
const string CLSID_PersistentZoneIdentifier = "0968e258-16c7-4dba-aa86-462dd61e31a3"; const string IID_IZoneIdentifier = "cd45f185-1b21-48e2-967b-ead743a8914e";
[ComImport] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] [Guid(IID_IZoneIdentifier)] public interface IZoneIdentifier { URLZONE GetId(); void SetId(URLZONE zone); void Remove(); }
public enum URLZONE : uint { URLZONE_LOCAL_MACHINE = 0, URLZONE_INTRANET = 1, URLZONE_TRUSTED = 2, URLZONE_INTERNET = 3, URLZONE_UNTRUSTED = 4, } }
Пользоваться очевидным образом: BlockChecker.IsBlocked(fullPath)
Если файла не существует, то будет возвращено true, так что проверяйте самостоятельно.
Если что, вы можете и удалить блокировку при помощи
zoneIdentifier.Remove(); persistFile.Save(path, true);

Какими способами можно решить проблему с шириной строк?

Прошу Ваших советов в реализации данной задачи.

Я реализовал анимацию с помощью svg, но тут-то и возникла проблема с шириной строк.
svg { width: 315px; height: 44px; top: 0; left: 0; fill: none; stroke: black; stroke-width: 1; overflow: visible } .btn_wrap { display: block; width: 315px; border: 1px solid black; color: red; padding: 12px 20px; margin-top: 50px; } .animated-line { stroke-dashoffset: 1000; stroke-dasharray: 1000; animation: dash 5s linear forwards; } @keyframes dash { to { stroke-dashoffset: 0; } } Каталог Каталог
stroke-width отличается от border, а при адаптиве или при увеличении/уменьшении масштаба некоторые элементы svg рамки, становятся как border


Ответ

Короткий ответ:
SVG stroke рисуется от осевой линии симметрично: если ширина линии - stroke-width="1px", то полпикселя будет выше осевой, вторая половина пикселя будет ниже осевой. Это для горизонтальной линии. Для вертикальной линии соответственно будет полпикселя влево и вправо от осевой. У вас форма фигуры совпадает с границами SVG и поэтому от трех линий вычитается по полпикселя, а хвостик, который вы обвели красным показывается целиком, поэтому он выглядит более жирным.
Я открыл ваш файл (без анимаций, чисто svg код) в векторном редакторе

серая линия это граница svg, что выходит за её пределы,- будет отрезано. Вы видите три линии шириной только по полпикселя. Вертикальный хвостик получается шириной 1px. Тут ещё вмешивается эффект полупиксельного размытия для трех сторон, которые идут по границе SVG документа, поэтому линии не чёрные, а серые.
Решение
Увеличить высоту документа SVG минимум на 2px - height: 46px; так как фигура всё равно останется прилипать кверху и влево, сдвинуть её вправо и вниз на 1px
transform="translate(1 1)"
Ниже полный код решения:
svg { width: 315px; height: 46px; top: 0; left: 0; fill: none; stroke: black; stroke-width: 1px; overflow: visible; } .btn_wrap { display: block; width: 315px; border: 1px solid black; color: red; padding: 12px 20px; margin-top: 50px; } .animated-line { stroke-dashoffset: 1000; stroke-dasharray: 1000; animation: dash 5s linear forwards; } @keyframes dash { to { stroke-dashoffset: 0; } } Каталог Каталог
Более подробно
Для того, чтобы не было потом проблем с кроссбраузерностью и мучений с позиционированием, когда встречаются svg и css элементы, в вашем случае это рамка svg и надпись css - каталог, а также ссылка на каталог, лучше всего это сделать внутри svg.
Поверьте, это не трудно, зато у вас никогда не распадется вёрстка и вам не придется мучительно долго искать причину.
Для добавления текста в svg имеется команда . Параметры текста вы можете задавать на выбор, как внутри svg, так и во внешней таблице css. Но определитесь сразу, лучше не дублировать стили.
В этом примере стили задаются внутри svg
КАТАЛОГ
Для управлениями стилями из внешней таблицы CSS необходимо добавить в первую строчку svg файла полный путь до внешней таблицы стилей.

Ссылку можно разместить внутри svg, например ссылкой будет текст.
Update
по комментариям автора вопроса
Добавлено масштабирование, то есть адаптивность к любому размеру экрана
width:25%; height:25%;
Уменьшая, увеличивая эти проценты вы можете увеличивать, уменьшать изображение svg и тем самым изменять визуально толщину линий. Скопируйте код из этого сниппета на свой ПК, так как сниппет немного искажает восприятие реального изображения.
Ниже полный код приложения с текстом в качестве ссылки внутри SVG
svg { width:25%; height:25%; top: 0; left: 0; fill: none; stroke: black; stroke-width: 1px; overflow: visible; } svg #textK { font-size:24px; font-family:serif; font-weight:500; stroke:none; fill:black; vector-effect:non-scaling-stroke; } .animated-line { stroke-dashoffset: 1000; stroke-dasharray: 1000; animation: dash 5s linear forwards; } @keyframes dash { to { stroke-dashoffset: 0; } } КАТАЛОГ
Дополнительный бонус,- текст ссылки внутри svg индексируется поисковиками.
Ссылку можно сделать на весь блок SVG

КАТАЛОГ

Структуры в C и C++

Пишу на C++. Случайно наткнулся на такой код, хотелось бы узнать что здесь происходит и можно ли такое повторить на C++.
static struct pci_driver my_driver = { .name = "my_pci_driver", .id_table = my_driver_id_table, .probe = my_driver_probe, .remove = my_driver_remove };
И еще - зачем перед объявлением экземпляра структуры в C нужно указывать ключевое слово struct, а в C++ - нет?


Ответ

И еще - зачем перед объявлением экземпляра структуры в C нужно указывать ключевое слово struct, а в C++ - нет?
С и С++ - разные языки с разными правилами.
хотелось бы узнать что здесь происходит
Это синтаксис инициализации с тегами (tagged initializers), введенный в язык С в стандарте С99. Что именно там происходит по-моему довольно очевидно: вы явно указываете какой член структуры хотите инициализировать каждым значением, тем самым делая инициализатор независимым от порядка объявления полей в структуре.
можно ли такое повторить на C++
C++ пока не поддерживает синтаксис инициализации с тегами, и прямого аналога на уровне ядра языка нет. Если я не ошибаюсь, поддержка этого синтаксиса в некоей модифицированной/урезанной форме - в планах для C++20. Ранее предложения поддержки этого синтаксиса в С++ упорно отвергались комитетом из-за сопутствующих сложностей, возникающих в контексте С++ инициализации.

Как сделать так, чтобы при каждом Generate Signed APK автоматически увеличивался на единицу versionCode?

Как сделать так, чтобы при каждом Generate Signed APK... автоматически увеличивался на единицу versionCode, чтобы не делать это вручную,.. просто, иногда забываешь об этом и загружаешь в Google Play Console версию со старым versionCode (что не допустимо!)
android:versionCode="X"


Ответ

Решение 1
android { compileSdkVersion 18 buildToolsVersion "18.1.0"
def versionPropsFile = file('version.properties')
if (versionPropsFile.canRead()) { def Properties versionProps = new Properties()
versionProps.load(new FileInputStream(versionPropsFile))
def code = versionProps['VERSION_CODE'].toInteger() + 1
versionProps['VERSION_CODE']=code.toString() versionProps.store(versionPropsFile.newWriter(), null)
defaultConfig { versionCode code versionName "1.1" minSdkVersion 14 targetSdkVersion 18 } } else { throw new GradleException("Could not read version.properties!") }
// rest of android block goes here }
Решение 2 (использовать время)
def date = new Date() def formattedDate = date.format('yyMMddHHmm') def code = formattedDate.toInteger()
defaultConfig { minSdkVersion 10 targetSdkVersion 21 versionCode code }

Запись бинарных данных в реестр

Пытаюсь изменить значение реестра типа reg_binary
type TBuffer = array[0..11] of byte; const InputData:TBuffer=($07,$00,$00,$00,$6F,$2B,$15,$00,$40,$AB,$D3,$01); var Reg: TRegistry; InputBuffer: TBuffer; begin InputBuffer := InputData;
Reg := TRegistry.Create(); try Reg.RootKey := HKEY_LOCAL_MACHINE; if Reg.OpenKey('....', True) then begin Reg.WriteBinaryData('Health',InputBuffer, SizeOf(InputBuffer));//пробовал и InputBuffer[0] Reg.CloseKey; end; finally Reg.Free; end;
Пробовал и так :
var Data: array of Byte;
....
SetLength(Data, 12); Data[0] := $07; Data[1] := $00; Data[2] := $00; Data[3] := $00; Data[4] := $6F; Data[5] := $2B; Data[6] := $15; Data[7] := $00; Data[8] := $40; Data[9] := $AB; Data[10] := $D3; Data[11] := $01;
Reg := TRegistry.Create(KEY_SET_VALUE); try Reg.RootKey := HKEY_LOCAL_MACHINE; if Reg.OpenKey('....', True) then begin Reg.WriteBinaryData('Health',Data, 12); //пробовал и Data[0] Reg.CloseKey; end; finally Reg.Free; end; end;
Но изменений никаких нет, написал подобное на c#
RegistryKey currentUserKey = Registry.LocalMachine; RegistryKey helloKey = currentUserKey.OpenSubKey(@"...", true); helloKey.SetValue("Health", new byte[] { 07, 00, 00, 00, 0x6F, 0x2B, 15, 00, 40, 0xAB, 0xD3, 01, }); helloKey.Close();
и значение изменилось. Где я в delphi ошибся ?
п.с от админа запускаю


Ответ

В 64-х битной Windows для 32-х битных приложений есть т.н. виртуализация, из-за которой эти приложения видят свою, 32-х битную версию реестра (Alternate Registry View).
Для того, чтобы 32-х битное приложение смогло увидеть системную 64-х битную версию реестра, надо использовать флаг KEY_WOW64_64KEY (0x0100)
KEY_WOW64_64KEY Indicates that an application on 64-bit Windows should operate on the 64-bit registry view. This flag is ignored by 32-bit Windows. This flag must be combined using the OR operator with the other flags in this table that either query or access registry values.
То есть, нужно делать так:
Reg := TRegistry.Create(KEY_WRITE OR KEY_WOW64_64KEY); try ... finally ... end;

Как найти остатки вредоносного кода?

ситуация следующая: сайт на друпал-7 и некоторое время назад его основная страница (только она одна!) стала отображаться в гугле иероглифами. простым поиском grep по слову "googlebot" был найден вредоносный пхп-код типа japanese keyword, который сидел в файле bootstrap.inc (папка /www/includes в корне сайта, код был добавлен прямо в начало файла), он был удален, все нормально заработало, но через несколько дней опять выехало то же самое и теперь тот же самый код был добавлен в файл default.settings.php в пути /www/sites/default. он был удален и опять через день появился тот же код только уже в файле template.php стандартной темы оформления. никаких новых файлов, папок и прочего не появляется, изменения касаются только какого-то одного файла, куда просто "самодобавляется" этот пхп-код. пароли учёток админов сменены, пароль фтп тоже. если используется дыра в каком-то стороннем модуле, то как его вычислить, кто подскажет? заранее спасибо.


Ответ

Если он "самодобавляется" - значит вирус имеет право записи в файлы. Значит он уже в системе. Вычистите код и скопируйте локально, дампаните БД, и снесите ОС. Обновите cms. Затем всем PHP-исполняемым файлам отберите права записи файлов(на случай дыр в коде) - у пользователя, под которым выполняется PHP (например):
find . -iname "*.php" | xargs chown deployuser find . -iname "*.php" | xargs chmod 644 find . -iname "*.inc" | xargs chown deployuser find . -iname "*.inc" | xargs chmod 644
Затем запретите в настройках PHP небезопасные функции, с помощью которых можно SSH тунель прокинуть. Проанализируйте открытые порты:
netstat -lntu
Например порт mysql (3306) стоит закрывать с помощью штатного фаервола ОС, подробнее про анализ портов выходит за рамки вопроса.
И если известен конкретный вирус - о его природе проникновения тоже известно в интернете. Тем не менее общие рекомендации по безопасности (читай выше) - выполнять стоит, иначе голова будет постоянно болеть. Может помочь антивирус, но не 100%.
P.S. Если бы ваш проект был добавлен в репозиторий - git: то такие проблемы было бы гораздо проще решать, по команде git status - вы бы видели все изменённые не вами файлы, а git checkout * возвращал бы все правки файлов до вашей версии кода.
UPD
Если же доступ к серверу не полный тогда всё весьма ограничено в плане безопасности: нужно найти по access логам странные запросы - и выявить место, через которое к вам встраивается код, закрыть его.
Как это сделать: первым делом перенести весь код в git-репу, и склониться в свой каталог проекта(гит то там должен быть на сервере! Не забудьте при этом правильно сделать .gitignore файл) - потом когда бот опять придёт, одной командой вы увидите файлы, которые он поменял. У этих файлов будет дата модификации. Теперь вы сможете увидеть по access логу - каким точно запросом к вам проникли (просмотрев запросы по логу секундой раньше даты модификации). Ну и в коде закрыть этот дырявый запрос! А так-же увидите IP-адрес бота - мало ли найдётся и сам злоумышленник.
Если нравится тот-же хостер: так сделайте у него ещё аккаунт, и на него всё перенесите. Но думаю дело не в хостере, а в том что бот запомнил что у вас дыра - и периодически посещает вас. Тем не менее - если хотите годную web-безопасность, нужен минимум VDS.

Алгоритмы активного шумоподавления

Меня интересуют алгоритмы активного шумоподавления. Углубляясь в детали реализации, выполняется спектральное вычитание "на ходу".
Имеется некоторый профиль шума и небольшой длины запись, из которой этот шум нужно удалить ("вычесть").
Так у меня вопрос по конкретному алгоритму спектрального вычитания: как оно выполняется и, собственно, над чем? В общих чертах я себе это представляю как вычитание из спектра (соответствие частот амплитудам гармоник) сигнала спектра шума и обратное преобразование Фурье. Вообще, вроде как, применяемое здесь FFT даёт не соответствие частот амплитудам, а просто массив комплексных чисел. Как тут вычитать что из чего не представляю...
P.S.: Не нужно давать ссылки на курсы по обработке звука и спектральному анализу сигналов. Просто вопрос - просто ясный ответ.

Есть такие специализированные программы, как, например, Noise Gator. Так вот, если кому известно, подскажите, какие алгоритмы шумоподавления ими используются (в частности, используется ли спектральное вычитание; если да, то откуда программа берёт слепок шума).


Ответ

Алгоритмы удаления шума невозможно рассмотреть без углубления в математику, акустику и теорию спектрального анализа сигналов.
Любой анализ сигнала с помощью преобразований Фурье предполагает, что сигнал является стационарным на исследуемом отрезке. Поэтому, если сигнал нестационарный, он разбивается на отдельные отрезки, называемые окнами. Выбор размера окна зависит от типа исследуемого сигнала, обычно около 25 - 50 мс для звукового сигнала (меньшие значения - для человеческой речи, большие - для музыки, особенно состоящей из струнных смычковых инструментов). Можно использовать перекрывающиеся окна, для повышения точности анализа.
Однако, просто так применить преобразование Фурье к обрезанным окнам нельзя, при этом некорректно обрабатываются граничные области отрезков. Для решения этой проблемы сигнал предварительно умножают на специальную весовую функцию ("оконную"). Примеры оконных функций см. в статье Оконное преобразование Фурье
Далее выполняется непосредственно преобразование Фурье. Оно дает в результате спектр сигнала, т.е. значение комплексной амплитуды для различных диапазонов частот. Из него и надо вычитать спектр шума. Из модуля комплексной амплитуды сигнала вычитается модуль комплексной амплитуды шума, умноженный на некий коэффициент; если результат отрицательный, он заменяется на ноль. Фазовый компонент оставляется нетронутым. К результату вычитания можно применить обратное преобразование Фурье, и получить "очищенный" сигнал.
Итоговый алгоритм шумоподавления при наличии известного образца шума:
Разделение сигнала на окна Применение оконного преобразования Фурье к окнам Вычитание (по модулю) спектра амплитуды шума из спектра амплитуды сигнала:
A = Max ( A с. - k * А ш. ; 0)
где k - коэффициент, подбираемый опытным путем
Применение обратного преобразования Фурье к результату
Размер окна, перекрытие окон, тип применяемой оконной функции подбираются опытным путем.
Ссылки
Removing noise from audio using Fourier transform in Matlab
How can I select an optimal window for Short Time Fourier Transform?
How to select frequency resolution and window size in FFT?

Вёрстка блока с 2-мя треугольниками

Доброго времени суток! Помогите разобраться, каким образом с помощью css можно сверстать данный блок, что бы избежать вставки картинок. Поробывалось делать с помощью before, after но получился только треугольник с правой стороны.
Заранее спасибо


Ответ

Без вставки картинок, но с парой лишних блоков и псевдоэлементов:
.d1 { height: 300px; width: 300px; margin: 35px 20px 0 0; background: green; position: relative; } .d1:before { content: ""; height: 0; width: 0; position: absolute; top: 0; right: -100px; border-left: 100px solid green; border-top: 150px solid transparent; border-bottom: 150px solid transparent; } .d2 { height: 0; width: 0; background: red; position: relative; } .d2:before { content: ""; height: 0; width: 0; position: absolute; top: 0; left: 280px; border-left: 100px solid red; border-top: 150px solid transparent; border-bottom: 150px solid transparent; } .d2:after { content: ""; height: 0; width: 0; position: absolute; top: 0; left: 260px; border-left: 100px solid green; border-top: 150px solid transparent; border-bottom: 150px solid transparent; } .d3:before { content: ""; height: 30px; width: 100px; position: absolute; top: 0; left: 200px; background: green; } .d3:after{ content: ""; height: 30px; width: 100px; position: absolute; bottom: 0; left: 200px; background: green; }


Android Studio. После изменения хотя бы одной строчки поведение приложения не меняется. Это нормально?

В приложении есть несколько Activity. Есть кнопка, у неё установлен вот такой ClickListener:
private View.OnClickListener buttonClickListener = new View.OnClickListener() { @Override public void onClick(View v) { button.setText("Hello!"); //button.setText("Bye!"); } };
Нажимаю Debug . Приложение запускаю(дебажу) на телефоне.
В приложении изначальный текст на кнопке "Welcome". После нажатия на кнопку текст меняется на "Hello!". Всё хорошо.
Раскоменчиваю строчку //button.setText("Bye!"); и нажимаю Debug
После нажатия на кнопку текст меняется на "Hello!". Почему? Ставлю breakpoint на button.setText("Hello!"); нажимаю ещё раз ловится breakpoint нажимаю F8 и указатель пролетает мимо button.setText("Bye!");. Это нормально?
Помогает только Rebuild Project.
Я не заметил с какого момента это стало проявляться, но сейчас так постоянно. Возможно, что это нормально и нужно просто где-то поставить галочку чтобы Android Studio делала Rebuild Project по нажатию на Run и Debug.
UPD: Версия студии
Android Studio 3.1 Build #AI-173.4670197, built on March 22, 2018 JRE: 1.8.0_152-release-1024-b02 amd64 JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o Windows 7 6.1


Ответ

Это баг в новой версии студии 3.1 (точнее - в проектах, обновлённых до новой версии). Из конфигурации скрипта запуска пропала инструкция пересборки проекта при запуске. Чтобы это починить надо открыть Run > Edit Configuration и посмотреть что есть под Before launch:, если там нет Gradle-aware Make как на картинке:

то добавьте это, в меню создания оставив пустым поле с заданием. В итоге получится так:

Перезапуск SVG анимации через удаление animateTransform

Всем привет. Возникла проблема с svg анимацией. Мне нужно чтобы js останавливал анимацию круга ( для этого я удаляю тег ), а затем возобновлял ее ( возвращаю тег обратно), и анимация начиналась либо с начала, либо, что еще лучше, с того места где остановилась.
Но при возвращении тега анимация продолжается с того момента, где был бы круг если бы я не удалял анимацию. Собственно вопрос в том, что я делаю неправильно.
Заранее спасибо!
const circle = document.getElementsByTagName('circle')[0], animate = ``; let b = true; setInterval(() => { b ? circle.innerHTML = '' : circle.innerHTML = animate; b = !b }, 1000);


Ответ

Добавляем кнопки "GO" и "STOP" старта и остановки анимации. На которые вешаем события onclick='start()' и onclick='pause()'
GO STOP
Добавляем в анимацию команду запуска begin="gO1.click" при клике на кнопке с идентификатором id="gO1" Добавляем скрипт, который управляет остановкой анимации и запуска её вновь с остановленного места.
Ниже полный код приложения:
let flag = 0, svg = document.querySelector('svg'); // Необходимо поймать второй клик (если на первом удалить атрибуты, анимация не начнётся), потом подменяем функцию на вызов по "разморозке" анимации let start = function(){ if(flag === 1){ // Убираем у animateTransform триггер, чтобы не сбрасывалась анимация на ноль Array.from(svg.querySelectorAll('animateTransform')).forEach(e => e.removeAttribute('begin')); start = _ => svg.unpauseAnimations(); start(); } flag++; } const pause = function(){ svg.pauseAnimations(); } GO STOP
Скрипт и комментарии к нему не мои. Особая благодарность @Other, который в своё время нашёл его на просторах интернета.
Второй пример анимации отрисовки спирали
let flag = 0, svg = document.querySelector('svg'); let start = function(){ if(flag === 1){ Array.from(svg.querySelectorAll('animateMotion')).forEach(e => e.removeAttribute('begin')); start = _ => svg.unpauseAnimations(); start(); } flag++; } const pause = function(){ svg.pauseAnimations(); } GO STOP
Третий пример анимации с animateMotion
let flag = 0, svg = document.querySelector('svg'); let start = function(){ if(flag === 1){ Array.from(svg.querySelectorAll('animateMotion')).forEach(e => e.removeAttribute('begin')); start = _ => svg.unpauseAnimations(); start(); } flag++; } const pause = function(){ svg.pauseAnimations(); } GO STOP

Entity Framework создаёт лишнюю таблицу

К примеру, имеется у меня контекст из двух сетов:
public class ConfigurationContext : DbContext { public ConfigurationContext() : base("ConfigurationContext") { Database.SetInitializer(new MigrateDatabaseToLatestVersion()); }
public DbSet Tags { get; set; } public DbSet Sources { get; set; } }
Таблица успешно генерируется, но почему-то содержит вместо двух таблиц - три! При этом у меня нет в проекте никаких сущностей, которые имели бы имя User, свойство Age или связь с такими объектами.

Эта лишняя таблица следует за мной повсюду. Стоит мне создать новый проект, изменить строку подключения, название или содержимое классов - она всегда создаётся.
В данный момент классы не содержат никаких свойств, кроме intового ключа. Таблица Users всё равно создается при каждой миграции.
Класс Configuration, отвечающий за миграцию также привожу ниже:
internal sealed class Configuration : DbMigrationsConfiguration { public Configuration() { AutomaticMigrationsEnabled = true; AutomaticMigrationDataLossAllowed = true; } }
Как ликвидировать лишнюю таблицу?


Ответ

Эту таблицу создает вовсе не Entity Framework, она создается сама при создании базы данных.
Дело в том, что в MS SQL Server есть такая штука как системная БД под названием model. При создании новой БД в нее копируются все объекты из model, и если в model есть какая-то таблица - она будет вас вот так преследовать. Просто удалите таблицу из model и больше не создавайте ее там.
Аналогичное поведение возможно и в PostgreSQL, там в таких случаях нужно проверить БД template1.

Почему следующая операция выдает -1?

double m = (byte) 110_987_654_6299.123_34;


Ответ

Справедливости ради стоит отметить, что результатом (значением m) будет -1.0, а не -1
Происходят 3 действия:
double число 110_987_654_6299.123_34 приводится к int. Результатом будет 2147483647 int число 2147483647 приводится к byte. Результатом будет -1 byte число -1 приводится к double. Результатом будет -1.0
Почему приведение работает именно так - можно прочитать в документации. Если вкратце, то:
при приведении double к byte (правая часть выражения) сначала происходит приведение double к int, и только затем - int к byte приведение double к int в случае превышения допустимого int значения возвращает максимальное значение int приведение int к byte просто берёт последние 8 бит из int

Поведенческий полиморфизм подтипов

Цитата из википедии: Наследование, — даже в языках программирования, которые поддерживают применение наследования как механизма, обеспечивающего полиморфизм подтипов, — не гарантирует поведенческий полиморфизм подтипов; смотри: «Принцип подстановки» Барбары Лисков.
Что же здесь подразумевают под поведенческим полиморфизмом подтипов? Как грамотно и лаконично ответить на этот вопрос?
Я же понимаю это так: Опять же цитата из википедии: Более простыми словами можно сказать, что поведение наследуемых классов не должно противоречить поведению, заданному базовым классом, то есть поведение наследуемых классов должно быть ожидаемым для кода, использующего переменную базового типа. Из этого следует, что наследование не защищает программиста, от того, что он может изменить поведение в переопределенном методе. Например метод add() в базовом классе добавляет объект, а его можно легко переопределить и этот метод станет удалять некий объект. Сохранение поведения базового метода и есть поведенческий полиморфизм.
Прав ли я?


Ответ

Вы все верно понимаете. Поведенческий полиморфизм это когда дочерний класс не меняет поведения родительского. Например представьте ситуацию, у нас есть класс
class Rechtangle { protected int width; protected int height;
public void setWidth(int w) { this.width = w; }
public void setHeight(int h) { this.height = h; }
public int area() { return width * height; } }
И мы добавляем новый класс "Квадрат", чем он отличается от прямоугольника, тем что его стороны должны изменяться одновременно, если мы меняем высоту, то и должна меняться ширина, пример
class Square extends Rechtangle { @Override public void setWidth(int w) { this.width = w; this.height = w; }
@Override public void setHeight(int h) { this.width = h; this.height = h; } }
А теперь представьте, что какой-то программист написал следующий код
void mainProcedure(Rechtangle figure) { figure.setWidth(5); figure.setHeight(3);
assert figure.area() == 15; }
Давайте теперь вызовем эту функцию с реализацией квадрата
mainProcedure(new Square())
Будет выброшено AssertionError, вот вам наглядное нарушение принципа LSP и поведенческого полиморфизма. Потому что фактически квадрат это не прямоугольник и разработчик процедуры mainProcedure не ожидал что он может получить квадрат маскирующийся за прямоугольником. Программист который написал процедуру прав. Он проверил контракт который должен был соблюдаться прямоугольником, но был нарушен квадратом.

Как работает данная XXE атака?

Здесь репорт, демонстрирующий атаку XXE.
Если вкратце, атакующий разместил у себя на сервере xml
]> &localfile;&remotedoc; email settings SMTP 52.34.103.214 1191 off account@obmhld.com yandex.ru off off off
в определённой директории, и после этого попытался авторизоваться на сайте mail.ru со следующими данными:
@
И после этого с мэйловского сервера прилетают запросы на сервер атакующего:
1:
5.61.237.44 - - [14/Feb/2018:01:05:14 +0000] "GET /autodiscover/autodiscover.xml HTTP/1.0" 200 955 "http://obmhld.com/autodiscover/autodiscover.xml" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; Win64; x64; Trident/6.0; .NET CLR 2.0.50727; SLCC2; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; InfoPath.3; Tablet PC 2.0; Microsoft Outlook 15.0.4481; ms-office; MSOffice 15)"
2:
5.61.237.44 - - [14/Feb/2018:01:05:15 +0000] "GET /pocs/?token=xmlsdfgdg5454g54&doc1=2 HTTP/1.0" 200 10 "-" "-"
Хотелось бы понять механизм работы этой чудной атаки. Спасибо!


Ответ

Атака состоит из двух частей.
В первой части Mail.ru пытается узнать данные для получения почты с неизвестного домена, загружая autodiscover.xml. Понятно, зачем это им нужно: можно сразу дать человеку все данные для настройки сбора почты, останется только ввести пароль. Сам механизм известный, в нём самом каких-то проблем. Примерный вид файла. Не исключаю что они до сих пор запрашивают этот файл.
Во второй части начинается интересное: парсер Mail.ru загружает внешние сущности (вида   или &custom;), которые объявляются в начале документа:

В общем случае можно вставить сущность прямо в документ, получим содержимое файла, на которую она ссылается, прямо на экран. В данном случае это не работает, но всё равно можно увидеть получается распарсить файл или нет. Например, если первая сущность &localfile; ссылается на несуществующий файл, то вторая сущность &remotedoc; не приведет к HTTP запросу на сервер атакующего. Если же файл есть, то будет запрос к серверу атакующего.
Если говорить об общем случае, то возьмём такой XML:
]> &hostname;
Пропустим его через xmllint:
xmllint --noent xxe.xml
И увидим у себя на экране имя вашего компьютера:
mysuperhostname
Как защититься от этого? Отключить загрузку внешних сущностей. Например, в PHP для этого есть функция libxml_disable_entity_loader(). Документация.

Событие на каждом элементе

Решил сделать такой эффект("живой" пример):

Цель: У меня есть три элемента и мне нужно, чтобы на каждом элементе срабатывало это событие(показанное выше). Пробовал в цикле, но всё тщетно.
var el = document.querySelector('.magnetic-button'); var options = { ease: 0.1, magneticForce: 0.6 }; var mouse = { x: 0, y: 0 }; var pos = { cx: 0, cy: 0, tx: 0, ty: 0, x: 0, y: 0 }; var sizes = el.getBoundingClientRect(); observe(); update(); function observe() { window.addEventListener('resize', resizeHandler, false); el.addEventListener('mousemove', mouseMoveHandler, false); el.addEventListener('mouseleave', mouseLeaveHandler, false); } function resizeHandler() { sizes = el.getBoundingClientRect(); } function mouseMoveHandler(e) { //sizes mouse.x = e.pageX; mouse.y = e.pageY; // center pos.cx = sizes.left + sizes.width / 2; pos.cy = sizes.top + sizes.height / 2; // dist var distX = mouse.x - sizes.left - sizes.width / 2; var distY = mouse.y - sizes.top - sizes.height / 2; pos.tx = distX - distX * (1 - options.magneticForce); pos.ty = distY - distY * (1 - options.magneticForce); } function mouseLeaveHandler(e) { pos.tx = 0; pos.ty = 0; } function render() { pos.x += (pos.tx - pos.x) * options.ease; pos.y += (pos.ty - pos.y) * options.ease; var transform2 = 'translateX(' + pos.x + 'px) translateY(' + pos.y + 'px)'; el.style.webkitTransform = transform2; el.style.MozTransform = transform2; el.style.msTransform = transform2; el.style.OTransform = transform2; el.style.transform = transform2; } function update() { render(); window.requestAnimationFrame(update); } .social-nets { display: flex; } .magnetic-button { margin-left: 1rem; position: relative; width: 3.3333333333rem; height: 3.3333333333rem; background-color: #b3b3b3; color: rgba(0, 0, 0, 0.8); border-radius: 50%; display: flex; justify-content: center; align-items: center; cursor: pointer; } .magnetic-button::before, .magnetic-button:after { content: ""; position: absolute; width: 100%; height: 100%; border-radius: 50%; transition: transform 800ms cubic-bezier(0.19, 1, 0.22, 1) 0ms; will-change: transform; z-index: -1; } .magnetic-button::before { background-color: red; } .magnetic-button:hover::before { transform: scale(0.95); } .magnetic-button:hover::after { transform: scale(0.85); }



Ответ

Мышь - одна, опции - тоже одни на всех. Но размер и позиция у каждого свои.
var options = { ease: 0.1, magneticForce: 0.6 }; var mouse = { x: 0, y: 0 }; observe(); update(); function observe() { window.addEventListener('resize', resizeHandler, false); var els = document.querySelectorAll('.magnetic-button'); for(var i = 0; i < els.length; i++) { els[i].addEventListener('mousemove', mouseMoveHandler, false); els[i].addEventListener('mouseleave', mouseLeaveHandler, false); els[i].pos = { cx: 0, cy: 0, tx: 0, ty: 0, x: 0, y: 0 }; els[i].sizes = els[i].getBoundingClientRect(); } } function resizeHandler() { var els = document.querySelectorAll('.magnetic-button'); for(var i = 0; i < els.length; i++) { els[i].sizes = els[i].getBoundingClientRect(); } } function mouseMoveHandler(e) { //sizes mouse.x = e.pageX; mouse.y = e.pageY; // center this.pos.cx = this.sizes.left + this.sizes.width / 2; this.pos.cy = this.sizes.top + this.sizes.height / 2; // dist var distX = mouse.x - this.sizes.left - this.sizes.width / 2; var distY = mouse.y - this.sizes.top - this.sizes.height / 2; this.pos.tx = distX - distX * (1 - options.magneticForce); this.pos.ty = distY - distY * (1 - options.magneticForce); } function mouseLeaveHandler(e) { this.pos.tx = 0; this.pos.ty = 0; } function render(el) { el.pos.x += (el.pos.tx - el.pos.x) * options.ease; el.pos.y += (el.pos.ty - el.pos.y) * options.ease; var transform2 = 'translateX(' + el.pos.x + 'px) translateY(' + el.pos.y + 'px)'; el.style.webkitTransform = transform2; el.style.MozTransform = transform2; el.style.msTransform = transform2; el.style.OTransform = transform2; el.style.transform = transform2; } function update() { var els = document.querySelectorAll('.magnetic-button'); for(var i = 0; i < els.length; i++) { render(els[i]); } window.requestAnimationFrame(update); } .social-nets { display: flex; } .magnetic-button { margin-left: 1rem; position: relative; width: 3.3333333333rem; height: 3.3333333333rem; background-color: #b3b3b3; color: rgba(0, 0, 0, 0.8); border-radius: 50%; display: flex; justify-content: center; align-items: center; cursor: pointer; } .magnetic-button::before, .magnetic-button:after { content: ""; position: absolute; width: 100%; height: 100%; border-radius: 50%; transition: transform 800ms cubic-bezier(0.19, 1, 0.22, 1) 0ms; will-change: transform; z-index: -1; } .magnetic-button::before { background-color: red; } .magnetic-button:hover::before { transform: scale(0.95); } .magnetic-button:hover::after { transform: scale(0.85); }


Динамическое подключение к другой Oracle БД из PL/SQL или SQL

Надо организовать динамическое подключение к любой из удаленных БД, данные о которых есть в таблице средствами PL/SQL кода.
Можно ли имея таблицу с настроечными параметрами (имя, пароль, TNS), в зависимости от переданного в процедуру параметра (ключа этой таблицы), в коде менять подключение и использовать один и тот же запрос для выборки из одинаковых структур то одной, то другой удаленной БД?


Ответ

TL;DR: Нельзя. Подключение к БД (connect) невозможно выполнить динамически:
exec execute immediate 'connect user/pass@localhost/oradb'; --ORA-00900: invalid SQL statement
так, как это недействительное SQL выражение.

Для выполнения запросов или хранимых функций на удалённой БД используются линки (database links). Например, для задачи как в вопросе:
create database link loopback1 connect to user identified by pass using 'localhost/pdb1'; create database link loopback2 connect to user identified by pass using 'localhost/pdb1'; create database link loopback3 connect to user identified by pass using 'localhost/pdb1';
set serveroutput on size unlimited declare function printRemoteData (dbLink varchar2) return varchar2 is dummy char (1); begin execute immediate 'select dummy from dual@'||dbLink into dummy; -- do something with remote data return 'remote connection using @'||dbLink; end; begin for r in ( select * from user_db_links where regexp_like (db_link, 'loopback\d', 'i')) loop dbms_output.put_line (printRemoteData (r.db_link)); end loop; end; /
Вывод:
remote connection using @LOOPBACK1 remote connection using @LOOPBACK3 remote connection using @LOOPBACK2
Пример решения более реальной задачи см. также по ссылке спроси Тома любезно предоставленной @MaxU.

Не получается сложить JS


$("#bonus").text(sum + 20); так получается сложить, а так $("#bonus").text(sum + bonus ); а так не получается ?


Ответ

$("#bonus").text(sum + bonus);
$("#bonus").text(sum + +bonus);

Хотя лучше вместо этого править здесь:
var bonus = $('#sum_bonus').val();
var bonus = +$('#sum_bonus').val();

Как сделать button в виде треугольника в WPF?

Нашел множество примеров как сделать круглые кнопки, но не одного решения о том как сделать в виде треугольника. Возможно ли это, или лучше использовать изображение для этой цели?


Ответ

Чтобы кнопка была действительно треугольной, необходимо переопределить ее шаблон.
Чтобы не писать шаблон с нуля полностью, я возьму за основу стандартный, для этого в Visual Studio в дизайнере щелкаем правой по кнопке и выбираем Edit Template-Edit a Copy... и вводим желаемое название шаблона и выбираем место его расположения (можно просто нажать OK и переместить/переименовать позже вручную).
Студия добавит стандартный шаблон кнопки, редактируем его: ищем у меня там такой шаблон:

В другой ОС он может отличаться, правим его:

Кнопка будет простая и не будет уметь содержать контент, поэтому одного Path достаточно.
Смотрим теперь те места, что подчеркнуты синим, наименования свойств у Border и Path отличаются, поэтому надо эти места поправить, кисть для границы называется Stroke (вместо BorderBrush), а кисть для заливки — Fill (вместо Background). Контента нет, поэтому строчку удаляю полностью.
Триггеры поправлены, синих подчеркиваний не должно остаться, дизайнер должен заработать, можно запустить и проект. Кнопка, в принципе, уже функционирует нормально, но если с помощью клавиши Tab установить на нее фокус, то мы увидим, что он прямоугольный. За фокус отвечает свойство FocusVisualStyle, видим в стиле, что он устанавливается так: , т.е. необходимо отредактировать также ресурс FocusVisual, там сейчас находится Rectangle, мы возьмем наш уже готовый Path, но без заливки и с прерывистой границей (как и было у Rectangle):

Видим, что геометрия Path повторяется дважды, чтобы избежать дублирования, вынесем ее отдельным ресурсом:
M12,24 L36,0 L36,48 Z
Тогда в Path достаточно будет указать Data="{StaticResource Geometry}"
Ну и напоследок можно поудалять ненужные сеттеры из стиля, которые касаются контента.
Еще, для того, чтобы иметь возможность получить кнопки со стрелками еще и вниз/вверх/вправо, добавим в ресурсы следующие трансформации:

В итоге весь пример целиком выглядит следующим образом:
M12,24 L36,0 L36,48 Z

Получить значение по ключу из JSON строки

Есть поле, которое хранит json текст. Внутри есть переменная id {"Id":25680,"Code":.... Нужно из json взять Id объекта и поместить значение в поле. Как вырезать значение Id? Кол-во цифр разное.


Ответ

Воспользуйтесь JSON_VALUE(...) (доступна начиная с SQL Server 2016):
SELECT JSON_VALUE(field_name, '$.Id') FROM table_name

CLion не воспринимает запись вида `T const& a` при описании функции

Есть некоторый класс Vector2 с перегруженным оператором (возможно аналогичное поведение и с обычными ф-циями, но из-за непредсказуемого поведения (об этом позже) достоверно проверить не удалось):
template class Vector2 { ... template // объявляем дружественную ф-цию шаблонной friend Vector2 operator +(Vector2 const& l_v, Vector2 const& r_v); ... }
Обращу внимание на форму записи константной ссылки - T const& a, а не const T& val. Потом это будет играть важную роль.
Но при попытке описать эту ф-цию, а именно:
template Vector2 operator +(Vector2 const& l_v, Vector2 const& r_v) { ... }
начинается самое интересное, а именно абсолютно непредсказуемое поведение анализа кода "на лету", от подобных генераций кода при попытке автоматической реализации объявленной ф-ции:
template Vector2 operator+(Vector2 < T >
const & l_v,
Vector2 const& r_v
) { return Vector2(); } // да-да, именно в таком виде, со всеми отступами
до категоричного отказа анализировать код, подчёркивая каждое второе слово красным цветом.
В целом, иногда (очень редко), CLion воспринимает всё правильно, но через время снова начинает деградировать.
А теперь к T const& a. Дело в том, что если поменять именно в описании ф-ции запись на const T& a, то всё будет работать более чем нормально. Вид записи в объявлении ф-ции никак не влияет.

Безусловно, можно было бы просто перейти на запись вида const T& a, да и код-то компилируется, и это лишь визуальная помощь от данной IDE, но я бы не стал писать этот вопрос, если бы не хотел решить эту проблему, поэтому хотелось бы понять, как это возможно сделать.

P.S. CLion версии 2018.1, но также проверялось на 2018.1.6, на другом устройстве, где результат был таким же.


Ответ

Так как в функции и левый операнд и правый имеют тип класса, то такую функцию другом обьявить бессмысленно.
Во вторых, если работа ыункции никак не связана с состоянием обьекта, и результатом функции является совершенно другой обьект, то вообше лучше избавить интерфейс класса от этой функции и определить ее отдельно (но в одном модуле). Например:
class Integer { int k; public: Integer(int n = 0) : k(n){} //модификаторы //т.е. мы изменяем состояние обьекта *this Integer& operator +=(const Integer& r_v) { k += r_v.k; return *this; } //... //селекторы int get_data() const { return k; } // функция выдает состояние обьекта }; // operator+ (и подобные методы) определяем вне класса inline Integer operator +(const Integer& l_v, const Integer& r_v) { Integer t(l_v); t += r_v; return t; }
Такой подход избавляет класс от лишнего интерфейса и наиболее логичен. И если этот подход применить в написании вашего класса, то все становится гораздо проще...
template class Vector2 { //... public: Vector2& operator +=(Vector2 const& r_v);
}; template inline Vector2 operator +(Vector2 const& l_v, Vector2 const& r_v) {...}

Посчитать статистику

Есть таблицы articles(id, section_id) и sections(id) связанные соответственно связью один ко многим (одна секция имеет много статей). Я хочу узнать сколько минимально, в среднем и максимально статей во всех секциях. Не доводилось делать таких агрегирующих запросов с MIN, MAX, AVG... Помогите пожалуйста составить запрос!


Ответ

В первую очередь придётся посчитать статьи:
SELECT COUNT(a.id) FROM Articles a GROUP BY a.section_id
Из этого можно получить агрегаты:
SELECT min(agg.cnt) mincnt, max(agg.cnt) maxcnt, avg(agg.cnt) avgcnt FROM ( SELECT COUNT(a.id) cnt FROM Articles a GROUP BY a.section_id ) agg

Не работает jquery tabs

Есть такой код для навигации .При нажати на service должно открыватся нужное окно.Есть задача использовать только jquery код.Активные кнопки справляются с задачей хорошо а вот с блоками проблема.Помогите разобратся.Заранее спасибо
Вот код
$(document).ready(function() { $(".tabtext").click(function() { $(".tabtext").removeClass("active"); $(this).addClass("active"); }); }); $(document).ready(function() { $(".tabtext").click(function() { $(".content").hasClass("visible"); $(".content").removeClass("visible"); $(".content").addClass("visible"); }); }); .tabs { width: 30em; height: auto; display: inline-block; text-align: center; margin: 0 auto; box-sizing: border-box; padding: 1em; background-color: silver; } .tabtext { display: inline; font-size: 1em; padding: 1em; margin: 0 0.2em 0 0.2em; } .active { color: red; } .content { width: 30em; display: block; text-align: center; margin: 0 auto; box-sizing: border-box; background-color: gray; } .context { width: 100%; height: auto; padding: 2em; display: none; text-align: center; box-sizing: border-box; } .context>h1 { font-size: 1em; } .visible { display: block; }

Service 1

Service 2

Service 3

Text 1

Text 2

Text 3



Ответ

$(document).ready(function() { $(".tabs .tabtext").click(function() { $(".tabs .tabtext").removeClass("active"); $(this).addClass("active"); $(".content .context").removeClass("visible"); $(".content .context").eq($(this).index()).addClass("visible"); }); }); .tabs { width: 30em; height: auto; display: inline-block; text-align: center; margin: 0 auto; box-sizing: border-box; padding: 1em; background-color: silver; } .tabtext { display: inline; font-size: 1em; padding: 1em; margin: 0 0.2em 0 0.2em; } .active { color: red; } .content { width: 30em; display: block; text-align: center; margin: 0 auto; box-sizing: border-box; background-color: gray; } .context { width: 100%; height: auto; padding: 2em; display: none; text-align: center; box-sizing: border-box; } .context>h1 { font-size: 1em; } .visible { display: block; }

Service 1

Service 2

Service 3

Text 1

Text 2

Text 3