| Новости | FAQ | Авторы | Документация | В действии | Библиотека |
| Инструменты | Полезные ссылки | Хостинги | Скачать | Примеры | Форум |
Sumo 23.02.2015 17:36 / 23.02.2015 17:52
...проекта http://voda-uzao.ru@CLASS
hydCore
@USE
pf/types/pfClass.p
pf/tests/pfAssert.p
pf/debug/pfRuntime.p
hydBaseModel.p
@BASE
pfClass
@auto[aFilespec]
$[__^CLASS_NAME.upper[]_FILESPEC__][^aFilespec.match[^^(^taint[regex][$request:document-root])][][]]
$[__^CLASS_NAME.upper[]_ABSOLUTE_FILESPEC__][$aFilespec]
@create[aOptions]
^pfAssert:isTrue($aOptions.sql is pfSQL)[SQL-объект должен быть наследником pfSQL.]
^BASE:create[]
^cleanMethodArgument[]
$_sql[$aOptions.sql]
$_binPath[^file:dirname[$__HYDCORE_FILESPEC__]/../bin]
^defReadProperty[binPath]
$_coreRootPath[^file:dirname[$__HYDCORE_ABSOLUTE_FILESPEC__]]
^defReadProperty[coreRootPath]
$_storagePath[^file:dirname[$__HYDCORE_FILESPEC__]/../../../hydra-storage]
^defReadProperty[storagePath]
$_modules[^hash::create[]]
^addModule[regions;hydCoreRegions]
^addModule[counters;hydCoreCounters]
^addModule[mc;hydCoreManagementCompanies]
^addModule[vts;hydCoreVTS]
^addModule[feedback;hydCoreFeedback]
^addModule[payments;hydCorePayments]
^addModule[debts;hydCoreDebts]
^addModule[reports;hydCoreReports]
^addModule[logs;hydCoreLogs]
$_speechKitKey[...]
^addModule[utils;hydCoreUtils;
$.args[
$.yandexSpeechkitKey[$_speechKitKey]
]
]
^addModule[security;hydCoreSecurity;
$.args[
$.secretKey[...]
$.cryptKey[...]
]
]
$_sphinxDaemonAddress[127.0.0.1:9306]
^addModule[search;hydCoreSearch;
$.args[
$.sphinxAddress[$_sphinxDaemonAddress]
]
]
^addModule[settings;pfSQLSettings;
$.path[pf/sql/generics/settings/pfSQLSettings.p]
$.args[
$.sql[$_sql]
$.ignoreKeyCase(true)
]
]
$_uiTypes[
$._default[
$.id[0]
$.title[]
]
$.hydra[
$.id[1]
$.title[Гидра]
]
$.terminal[
$.id[2]
$.title[Терминал]
]
$.web[
$.id[3]
$.title[Интернет]
]
]
^defReadProperty[uiTypes]
@GET_CSQL[]
$result[$_sql]
@GET_speechKit[]
^if(!def $_speechKit){
^use[pf/api/yandex/speechkit/pfYandexSpeechKit.p]
$_speechKit[^pfYandexSpeechKit::create[$_speechKitKey]]
}
$result[$_speechKit]
@addModule[aModuleName;aClassName;aOptions]
## aOptions.path
## aOptions.args
^cleanMethodArgument[]
$_modules.[$aModuleName][$.className[$aClassName] $.object[] $.options[$aOptions]]
@getModule[aName]
^if(^_modules.contains[$aName]){
^if(!def $_modules.[$aName].object){
$_modules.[$aName].object[^_coreFabric[$_modules.[$aName].className;$_modules.[$aName].options]]
}
$result[$_modules.[$aName].object]
}{
^throw[hydCore.fail;Модуль "$aName" не найден.]
}
@GET_DEFAULT[aName]
$result[]
^if(^_modules.contains[$aName]){
^if(!def $_modules.[$aName].object){
$_modules.[$aName].object[^_coreFabric[$_modules.[$aName].className;$_modules.[$aName].options]]
}
$result[$_modules.[$aName].object]
}
@_coreFabric[aClass;aOptions]
^use[^if(def $aOptions.path){$aOptions.path}{hydra/${aClass}.p}]
$result[^reflection:create[$aClass;create;^hash::create[$aOptions.args] $.core[$self]]]app/models/hydBaseModel.p:
@USE
pf/types/pfClass.p
pf/sql/orm/pfSQLTable.p
## Базовая модель
@CLASS
hydBaseModel
@BASE
pfClass
@create[aOptions]
## aOptions.core
^cleanMethodArgument[]
^pfAssert:isTrue($aOptions.core is hydCore)[core должен быть наследником hydCore.]
$_options[$aOptions]
$_core[$aOptions.core]
$_now[^date::now[]]
$_today[^date::today[]]
$_modules[^hash::create[]]
#----- Properties -----
@GET_core[]
$result[$_core]
@GET_CSQL[]
$result[$core.CSQL]
@GET_precision[]
$result[%.3f]
#----- Modules -----
@GET_DEFAULT[aName][locals]
$result[^getModule[$aName]]
@addModule[aModuleName;aClassName;aOptions]
^cleanMethodArgument[]
$_modules.[$aModuleName][$.className[$aClassName] $.object[] $.options[$aOptions]]
@_moduleFabric[aClass;aOptions]
^unsafe{^use[hydra/${aClass}.p]}
$result[^reflection:create[^file:justname[$aClass];create;^hash::create[$aOptions] $.core[$_core]]]
@getModule[aName]
^if(^_modules.contains[$aName]){
^if(!def $_modules.[$aName].object){
$_modules.[$aName].object[^_moduleFabric[$_modules.[$aName].className;$_modules.[$aName].options]]
}
$result[$_modules.[$aName].object]
}{
^throw[hydBaseModel.fail;Модуль "$aName" не найден.]
}
# Модель, наследник pfSQLTable, но реализующая интерфейс hydBaseModel
@CLASS
hydDBTable
@BASE
pfSQLTable
@create[aOptions]
## aOptions.tableName
## aOptions.core
^cleanMethodArgument[]
^pfAssert:isTrue(def $aOptions.core && $aOptions.core is hydCore)[core должен быть наследником hydCore.]
$_core[$aOptions.core]
$_options[$aOptions]
$_now[^date::now[]]
$_today[^date::today[]]
^BASE:create[^if(def $aOptions.tableName){$aOptions.tableName};^hash::create[$aOptions] $.sql[$_core.CSQL]]
$_modules[^hash::create[]]
#----- Properties -----
@GET_core[]
$result[$_core]
@GET_precision[]
$result[%.3f]
#----- Modules -----
@GET_DEFAULT[aName][locals]
^if(^_modules.contains[$aName]){
$result[^getModule[$aName]]
}{
$result[^BASE:GET_DEFAULT[$aName]]
}
@addModule[aModuleName;aClassName;aOptions]
^cleanMethodArgument[]
$_modules.[$aModuleName][$.className[$aClassName] $.object[] $.options[$aOptions]]
@_moduleFabric[aClass;aOptions]
^unsafe{^use[hydra/${aClass}.p]}
$result[^reflection:create[^file:justname[$aClass];create;^hash::create[$aOptions] $.core[$_core]]]
@getModule[aName]
^if(^_modules.contains[$aName]){
^if(!def $_modules.[$aName].object){
$_modules.[$aName].object[^_moduleFabric[$_modules.[$aName].className;$_modules.[$aName].options]]
}
$result[$_modules.[$aName].object]
}{
^throw[hydDBTable.fail;Модуль "$aName" не найден.]
}Дальше пошло «мясо», которое и реализует бизнес-правила.
@CLASS
hydCoreRegions
@BASE
hydDBTable
@create[aOptions][locals]
^BASE:create[^hash::create[$aOptions]
$.tableName[regions]
$.tableAlias[reg]
# $.allAsTable(true)
]
^addFields[
$.regionID[$.dbField[region_id] $.primary(true) $.sequence(false) $.processor[uint] $.label[Код] $.plural[regions]]
$.name[$.label[Название района] $.default[___ Безымянный район __]]
$.districtID[$.dbField[district_id] $.plural[districts] $.processor[uint_null] $.label[Округ] $.widget[select]]
$.slug[$.widget[none]]
$.comment[$.label[Комментарий] $.widget[textarea]]
$.lastImport[$.dbField[last_import] $.processor[datetime] $.widget[none]]
$.allowWeb[$.dbField[allow_web] $.processor[bool] $.default(false) $.label[Доступ из веб-терминала] $.widget[checkbox]]
$.firstDay[$.dbField[first_day] $.processor[uint] $.default(0) $.label[Начало приема]]
$.deadlineDay[$.dbField[deadline_day] $.processor[uint] $.default(0) $.label[Окончание приема]]
$.waterDelta[$.dbField[water_delta] $.processor[uint] $.default(0) $.label[Максимальная разница]]
$.waterMonthes[$.dbField[water_monthes] $.processor[uint] $.default(0) $.label[Акт снятия каждые]]
$.firstActionDate[$.dbField[first_action_date] $.processor[date] $.label[]]
$.housesCnt[$.dbField[houses_cnt] $.processor[uint] $.widget[none]]
$.flatesCnt[$.dbField[flates_cnt] $.processor[uint] $.widget[none]]
$.accountsCnt[$.dbField[accounts_cnt] $.processor[uint] $.widget[none]]
$.waterCountersCnt[$.dbField[water_counters_cnt] $.processor[uint] $.widget[none]]
$.waterFlatesCnt[$.dbField[water_flates_cnt] $.processor[uint] $.widget[none]]
$.smsPhonesCnt[$.dbField[sms_phones_cnt] $.processor[uint] $.label[]]
$.title1[$.dbField[title_1] $.label[Что]]
$.title2[$.dbField[title_2] $.label[Где (в)]]
$.title3[$.dbField[title_3] $.label[Кого]]
$.titleSMS[$.dbField[title_sms] $.expression[(case when title_sms != "" then title_sms else title_2 end)] $.label[Для СМС, где (в)]]
$.phones[$.label[Телефоны]]
$.createdAt[$.dbField[created_at] $.processor[auto_now] $.skipOnUpdate(true) $.widget[none]]
$.updatedAt[$.dbField[updated_at] $.processor[auto_now] $.widget[none]]
]
$lFirstDayOfMonth[^date::create($_today.year;$_today.month;1)]
$lFirstDayOfMonth[^lFirstDayOfMonth.sql-string[date]]
^addFields[
$.deadlineDate[
$.expression[
(date_sub(case
when $deadlineDay > 0 and $deadlineDay < $firstDay then
date_add(date_add("$lFirstDayOfMonth", interval $deadlineDay - 1 day), interval 1 month)
when deadline_day > 0
and date_add("$lFirstDayOfMonth", interval $deadlineDay - 1 day) < last_day("^_today.sql-string[date]")
then
date_add("$lFirstDayOfMonth", interval $deadlineDay - 1 day)
else
last_day("^_today.sql-string[date]")
end, interval if($deadlineDay < $firstDay and $_today.day <= $deadlineDay, 1, 0) month))
]
$.widget[none]
]
$.firstDate[
$.expression[
(date_sub(case
when $firstDay > 0
and date_add("$lFirstDayOfMonth", interval $firstDay - 1 day) <= last_day("^_today.sql-string[date]")
then
date_add("$lFirstDayOfMonth", interval $firstDay - 1 day)
else
"$lFirstDayOfMonth"
end, interval if($deadlineDay < $firstDay and $_today.day <= $deadlineDay, 1, 0) month))
]
$.widget[none]
]
$.aggregateDate[
$.expression[
(case
when $deadlineDay < $firstDay and $_today.day <= $deadlineDay
then date_sub("$lFirstDayOfMonth", interval 1 month)
else
"$lFirstDayOfMonth"
end)
]
]
]
$lSettingsModule[^core.getModule[settings]]
$lDefaultWebSite[$lSettingsModule.web_site]
^addModule[districts;hydCoreRegionsDistricts]
$lDistricts[^getModule[districts]]
^addFields[
$.district[
$.expression[$lDistricts.name]
$.widget[none]
]
$.districtSlug[
$.expression[$lDistricts.slug]
$.widget[none]
]
$.districtOrder[
$.expression[$lDistricts.order]
$.widget[none]
]
$.districtTitle[
$.expression[$lDistricts.title]
$.widget[none]
]
$.smsSystem[
$.expression[$lDistricts.smsSystem]
$.widget[none]
]
$.webSite[
$.expression[if($lDistricts.webSite != "", $lDistricts.webSite, "^taint[$lDefaultWebSite]")]
$.widget[none]
]
]
$self._defaultOrderBy[$.districtOrder[asc] $.name[asc] $.regionID[asc]]
^addModule[streets;hydCoreRegionsStreets]
^addModule[houses;hydCoreRegionsHouses]
^addModule[flates;hydCoreRegionsFlates]
^addModule[accounts;hydCoreRegionsAccounts]
^addModule[terminals;hydCoreRegionsTerminals]
$self._asuCharset[windows-1251]
@_allJoin[aOptions]
$result[^BASE:_allJoin[$aOptions]
left join $districts.TABLE_EXPRESSION on $districtID = $districts.districtID
]
#---------------------------------------------------------------------------
@CLASS
hydCoreRegionsDistricts
@BASE
hydDBTable
@create[aOptions]
^BASE:create[^hash::create[$aOptions]
$.tableName[districts]
$.tableAlias[dstr]
$.allAsTable(true)
]
^addFields[
$.districtID[$.dbField[district_id] $.plural[districts] $.processor[uint] $.primary(true) $.widget[none]]
$.name[$.label[]]
$.title[$.label[]]
$.slug[$.label[]]
$.smsSystem[$.dbField[sms_system] $.label[]]
$.webSite[$.dbField[web_site] $.label[]]
$.order[$.processor[uint] $.label[]]
]
$_defaultOrderBy[$.order[asc] $.name[asc]]
#---------------------------------------------------------------------------
@CLASS
hydCoreRegionsStreets
@BASE
hydDBTable
@create[aOptions]
^BASE:create[^hash::create[$aOptions]
$.tableName[regions_streets]
$.tableAlias[str]
$.allAsTable(true)
]
^addFields[
$.streetID[$.dbField[street_id] $.primary(true) $.sequence(false) $.processor[uint] $.plural[streets]]
$.streetName[$.dbField[street_name]]
$.createdAt[$.dbField[created_at] $.processor[auto_now] $.skipOnUpdate(true)]
$.updatedAt[$.dbField[updated_at] $.processor[auto_now]]
]
$self._defaultOrderBy[$.streetName[asc] $.streetID[asc]]
#---------------------------------------------------------------------------
@CLASS
hydCoreRegionsHouses
@BASE
hydDBTable
@create[aOptions][locals]
^BASE:create[^hash::create[$aOptions]
$.tableName[regions_houses]
$.tableAlias[hs]
$.allAsTable(true)
]
$lRegions[^core.getModule[regions]]
$lStreets[^lRegions.getModule[streets]]
^addFields[
$.houseID[$.dbField[house_id] $.primary(true) $.sequence(false) $.processor[uint] $.plural[houses]]
$.houseBtiID[$.dbField[house_bti_id] $.processor[uint]]
$.streetID[$.dbField[street_id] $.processor[uint] $.plural[streets]]
$.houseNumber[$.dbField[house_number]]
$.houseStr[$.dbField[house_str]]
$.houseKorp[$.dbField[house_korp]]
$.regionID[$.dbField[region_id] $.plural[regions] $.processor[uint]]
$.createdAt[$.dbField[created_at] $.processor[auto_now] $.skipOnUpdate(true)]
$.updatedAt[$.dbField[updated_at] $.processor[auto_now]]
$.__houseKey[$.dbField[__house_key] $.widget[none]]
]
# Вычисляемые поля
^addField[streetName;$.expression[$lStreets.streetName]]
^addField[address;
$.expression[
concat($lStreets.streetName,
", д. ", $houseNumber,
if($houseKorp != "", concat(", корп. ", $houseKorp), ""),
if($houseStr != "", concat(", стр. ", $houseStr), "")
)
]
]
^addField[building;
$.expression[
concat($houseNumber,
if($houseKorp != "", concat(", корп. ", $houseKorp), ""),
if($houseStr != "", concat(", стр. ", $houseStr), "")
)
]
]
$self._defaultOrderBy[$.streetName[asc] $.houseNumber[asc] $.houseKorp[asc] $.houseStr[asc]]
@_allJoin[aOptions]
$result[join $core.regions.streets.TABLE_EXPRESSION on ($streetID = $core.regions.streets.streetID)]
#---------------------------------------------------------------------------
@CLASS
hydCoreRegionsFlates
@BASE
hydDBTable
@create[aOptions][locals]
^BASE:create[^hash::create[$aOptions]
$.tableName[regions_flates]
$.tableAlias[flt]
$.allAsTable(true)
]
$lRegions[^core.getModule[regions]]
$lStreets[^lRegions.getModule[streets]]
$lHouses[^lRegions.getModule[houses]]
$lAccounts[^lRegions.getModule[accounts]]
^addFields[
$.flatID[$.dbField[flat_id] $.primary(true) $.sequence(false) $.processor[uint] $.plural[flates]]
$.regionID[$.dbField[region_id] $.plural[regions] $.processor[uint] $.label[]]
$.asuFlatID[$.dbField[asu_flat_id] $.processor[uint] $.label[]]
$.houseID[$.dbField[house_id] $.processor[uint] $.plural[houses]]
$.flatNumber[$.dbField[flat_number]]
$.createdAt[$.dbField[created_at] $.processor[auto_now] $.skipOnUpdate(true)]
$.updatedAt[$.dbField[updated_at] $.processor[auto_now]]
$.__houseKey[$.dbField[__house_key] $.widget[none]]
# Поля для выборок
$.accountID[$.fieldExpression[$lAccounts.accountID] $.widget[none]]
]
# Вычисляемые поля
^addField[address;
$.expression[
concat($lStreets.streetName,
", д. ", $lHouses.houseNumber,
if($lHouses.houseKorp != "", concat(", корп. ", $lHouses.houseKorp), ""),
if($lHouses.houseStr != "", concat(", стр. ", $lHouses.houseStr), ""),
if($flatNumber != "", concat(", кв. ", $flatNumber), "")
)
]
]
^addField[house;
$.expression[
concat($lStreets.streetName,
", д. ", $lHouses.houseNumber,
if($lHouses.houseKorp != "", concat(", корп. ", $lHouses.houseKorp), ""),
if($lHouses.houseStr != "", concat(", стр. ", $lHouses.houseStr), "")
)
]
]
^addField[accounts;
$.expression[group_concat(distinct $lAccounts.accountID separator ", ")]
]
$self._defaultGroupBy[flatID]
$self._defaultOrderBy[flatID+1]
@_allJoin[aOptions]
$result[
join $core.regions.houses.TABLE_EXPRESSION on ($houseID = $core.regions.houses.houseID)
join $core.regions.streets.TABLE_EXPRESSION on ($core.regions.houses.streetID = $core.regions.streets.streetID)
left join $core.regions.accounts.TABLE_EXPRESSION on ($flatID = $core.regions.accounts.flatID)
]
@similarTo[aFlat;aOptions]
## Ищет квартиры, «похожие» на образец
## aOptions.includeSelf(false) — ыулючить в результат квартиру-источник
## aOptions.phones — номера телефонов
## aOptions.regions[] — доступные районы
^cleanMethodArgument[]
$result[^hash::create[]]
^if(^aOptions.contains[phones] && $aOptions.phones){
$result[^all[
^if($aOptions.regions){
$.regions[$aOptions.regions]
}
^if(!^aOptions.includeSelf.bool(false)){
$.[flatID !=][$aFlat.flatID]
}
$.[flatID in][^core.feedback.sms.phones.aggregate[_fields(flatID);
$.[number in][$aOptions.phones]
$.isActive(true)
]]
$.orderBy[$.address[asc]]
]]
}
#---------------------------------------------------------------------------
@CLASS
hydCoreRegionsAccounts
@BASE
hydDBTable
@create[aOptions][locals]
^BASE:create[^hash::create[$aOptions]
$.tableName[regions_accounts]
$.tableAlias[acc]
$.allAsTable(true)
]
^addFields[
$.accountID[$.dbField[account_id] $.widget[none]]
$.flatID[$.dbField[flat_id] $.processor[uint] $.widget[none]]
$.regionID[$.dbField[region_id] $.plural[regions] $.processor[uint] $.widget[none]]
$.asuFlatID[$.dbField[asu_flat_id] $.processor[uint] $.label[]]
$.createdAt[$.dbField[created_at] $.processor[auto_now] $.skipOnUpdate(true) $.widget[none]]
$.updatedAt[$.dbField[updated_at] $.processor[auto_now] $.widget[none]]
]
#---------------------------------------------------------------------------
@CLASS
hydCoreRegionsTerminals
@BASE
hydDBTable
@create[aOptions][locals]
^BASE:create[^hash::create[$aOptions]
$.tableName[regions_terminals]
$.tableAlias[reg_term]
$.allAsTable(true)
]
$self._statuses[
$.unset[$.id[0] $.title[Не установлен] $.badge[не установлен] $.class[] $.btnClass[]]
$.enabled[$.id[1] $.title[Работает] $.badge[работает] $.class[success] $.btnClass[success]]
$.disabled[$.id[2] $.title[Выключен] $.badge[выключен] $.class[important] $.btnClass[danger]]
$.repair[$.id[3] $.title[В ремонте] $.badge[в ремонте] $.class[warning] $.btnClass[warning]]
]
^defReadProperty[statuses]
$self._rdProtos[
$.rdp[$.id[1] $.title[Remote desktop (Windows)] $.uriPrefix[rdp://]]
$.vnc[$.id[2] $.title[VNC] $.uriPrefix[vnc://]]
$.ssh[$.id[3] $.title[Secure shell (SSH)] $.uriPrefix[ssh://]]
$.telnet[$.id[4] $.title[Telnet] $.uriPrefix[telnet://]]
]
^defReadProperty[rdProtos]
^addFields[
$.terminalID[$.dbField[terminal_id] $.plural[terminals] $.processor[uint] $.primary(true) $.widget[none]]
$.description[$.default[__Неизвестный терминал__] $.label[Место установки]]
$.ip[$.dbField[ip] $.expression{inet_ntoa(^_builder.quoteIdentifier[$TABLE_ALIAS].^_builder.quoteIdentifier[ip])} $.processor[inet_ip] $.label[IP-адрес]]
$.regionID[$.dbField[region_id] $.plural[regions] $.processor[uint_null] $.label[Район] $.widget[select]]
$.comment[$.label[Комментарий] $.widget[textarea]]
$.externalIP[$.dbField[external_ip] $.expression{inet_ntoa(^_builder.quoteIdentifier[$TABLE_ALIAS].^_builder.quoteIdentifier[external_ip])} $.processor[inet_ip] $.label[«Внешний» IP]]
$.rdPort[$.dbField[rd_port] $.processor[uint_null] $.label[Порт]]
$.isActive[$.dbField[is_active] $.processor[bool] $.default(1) $.widget[none]]
$.createdAt[$.dbField[created_at] $.processor[auto_now] $.skipOnUpdate(true) $.widget[none]]
$.updatedAt[$.dbField[updated_at] $.processor[auto_now] $.widget[none]]
]
^addFields[
$.status[
$.dbField[status] $.processor[uint] $.widget[none]
$.expression[(case ^_builder.quoteIdentifier[$TABLE_ALIAS].^_builder.quoteIdentifier[status] ^_statuses.foreach[k;v]{when ^v.id.int(-1) then "^taint[$k]"}[ ] else 0 end)]
]
]
^addFields[
$.rdProtocol[
$.dbField[rd_protocol] $.processor[uint] $.label[Протокол удаленного доступа] $.widget[select]
$.expression[(case ^_builder.quoteIdentifier[$TABLE_ALIAS].^_builder.quoteIdentifier[rd_protocol] ^_rdProtos.foreach[k;v]{when ^v.id.int(-1) then "^taint[$k]"}[ ] else 0 end)]
]
]
$self._defaultOrderBy[(case when $regionID is null then 100000 else $regionID end) asc, $description asc, $ip asc]
@delete[aTerminalID]
$result[^modify[$aTerminalID;
$.isActive(false)
$.status[$_statuses.unset.id]
]]
@restore[aTerminalID]
$result[^modify[$aTerminalID;$.isActive(true)]]И кусочек из сервисной модельки.
@CLASS
hydCoreUtils
## Полезные функции.
@USE
hlpFormater.p
pf/types/pfString.p
@BASE
hydBaseModel
@OPTIONS
locals
@create[aOptions]
## aOptions.yandexSpeechkitKey[]
^cleanMethodArgument[]
^BASE:create[$aOptions]
$self._whoisScript[$core.binPath/whois]
$self._regex[
$.numeric[^regex::create[^^\s*\-?\s*([\d\s]+)\s*(?:(?:[\.\,]\s*)(\d+))?.*^$]]
$.weight[^regex::create[^^[-+]?\s*(\d[\d\s]*)(?:[\.,ю]\s*(\d+))?\s*(\p{L})?][i]]
$.allSpaces[^regex::create[\s+][g]]
$.phone1[^regex::create[((?:\d\-)?[\d\-]+\d)][g]]
$.phone2[^regex::create[((?:\+?[78]\s*)?\(\d+\)\s*[\d\-]+\d)][g]]
$.phone3[^regex::create[(?:[78])(\d{10})][g]]
$.hexValue[^regex::create[^^[0-9a-zA-Z]*^$][n]]
]
$self._formater[^hlpFormater::create[]]
^defReadProperty[formater]
$self.parseFailException[core.utils.parse.fail]
^addModule[speechkit;utils/hydCoreUtilsSpeechkit;
$.yandexSpeechkitKey[$aOptions.yandexSpeechkitKey]
]
^addModule[phonesConverter;utils/hydCoreUtilsPhonesConverter]
#----- Strings -----
@cleanPhones[aPhones;aOptions]
## aOptions.removePrefix(false) - удалить ведущий префикс (7, 8)
$result[^aPhones.match[$_regex.phone1][]{^match.1.match[[\-]][g][]}]
$result[^result.match[$_regex.phone2][]{^match.1.match[[\-\+\(\)\s]][g][]}]
^if(^aOptions.removePrefix.bool(false)){
$result[^result.match[$_regex.phone3][]{$match.1}]
}
@cleanMAC[aMAC]
## Удаляет из МАК-адреса лишние символы
$result[]
$aMAC[^aMAC.match[[\s:\-_\.]+][gi][]]
^if(^aMAC.match[^^[a-fA-F0-9]{12}^$][n]){
$result[^aMAC.lower[]]
}
@buildTrigrams[aWord]
$aWord[__${aWord}__]
$result[^for[i](0;^aWord.length[]-3){^aWord.mid($i;3)}[ ]]
@levenshtein[aStr1;aStr2]
## Возвращает «расстояние Левеншетйна» между двумя строками
$result(^pfString:levenshteinDistance[$aStr1;$aStr2])
@levenshteinForTable[aStr;aTable;aColumnName]
## Возвращает расстояния Левенштейна между aStr и всеми значениями колонки aColumnName в aTable
## aColumnName[keyword] — имя колонки в таблице
^if(!def $aColumnName){$aColumnName[keyword]}
$result[^hash::create[]]
^aTable.menu{
$result.[^aTable.line[]][^levenshtein[$aTable.[$aColumnName]]]
}
@levenshteinRatio[aStr1;aStr2][locals]
## Возвращает «расстояние Левеншетйна» между двумя строками в процентах
$lLen1(^aStr1.length[])
$lLen2(^aStr2.length[])
$lMaxLen(^if($lLen1 > $lLen2){$lLen1}{$lLen2})
$result(^math:round((1 - (^levenshtein[$aStr1;$aStr2] / $lMaxLen)) * 100))
@splitByWord[aStr;aOptions][locals]
## Разбирает строку на слова
## aOptions.convertLayoutTo[] — преобразовать раскладку
## aOptions.stripSpecial(false) — удалить служебные символы
^cleanMethodArgument[]
$result[^hash::create[]]
$lConvertLayoutTo[$aOptions.convertLayoutTo]
$lStripSpecial(^aOptions.stripSpecial.bool(false))
^if(def $lConvertLayoutTo){
$aStr[^convertLayout[$lConvertLayoutTo;^aStr.trim[both]]]
}
$lParts[^aStr.split[ ;lv]]
^lParts.menu{
$lWord[^lParts.piece.trim[both]]
^if($lStripSpecial){
$lWord[^lWord.match[[\p{P}]+][g][ ]]
$lWord[^lWord.trim[both]]
}
$result.[^result._count[]][^lWord.lower[]]
}
@convertLayout[aLayout;aString][lRus;lEng;lFrom;lTo;lRegex]
## aLayout[lat|rus] - в какой раскладке хотим получить результат
$result[]
^if(def $aString){
$lEng[qwertyuiop[]asdfghjkl^;'zxcvbnm,.<>{}:"`~]
$lRus[йцукенгшщзхъфывапролджэячсмитьбюбюхъжэёё]
^if($aLayout eq "rus"){
$lFrom[$lEng^lEng.upper[]] $lTo[$lRus^lRus.upper[]] $lRegex[^taint[regex][$lEng]]
}{
$lFrom[$lRus^lRus.upper[]] $lTo[$lEng^lEng.upper[]] $lRegex[^taint[regex][$lRus]]
}
$result[^aString.match[([$lRegex])][gi]{^lTo.mid(^lFrom.pos[$match.1];1)}]
}
@parseHexValue[aString;aOptions]
## Возвращает число из строки с шестнадуцатиричным значением
## aOptions.maxWidth[] — максимальное количество цифр в числе
## aOptions.allowEmpty(true) — допустимы пустые значения (преобразуется в 0)
^cleanMethodArgument[]
$aString[^aString.match[[\p{P}\s]+][g][]]
^if(!^aString.match[$_regex.hexValue]
|| ($aOptions.maxWidth && ^aString.length[] > ^aOptions.maxWidth.int(0))
|| (!^aOptions.allowEmpty.bool(true) && !^aString.length[])
){
^throw[$parseFailException;Не удалось преобразовать $aString в число.]
}
$result(^if(def $aString){^math:convert[$aString](16;10)}{0})
#----- Dates -----
@monthRange[aDate][locals]
## Возвращает диапазон первую и конечную дату месяца для aDate
## result[$.first $.last]
$result[^hash::create[]]
$lDate[^date::create[$aDate]]
$result.first[^date::create($lDate.year;$lDate.month;1;0;0;0)]
$result.last[^date::create($lDate.year;$lDate.month;^lDate.last-day[];23;59;59)]
@weeks[aDate;aOptions][locals]
## Вычисляем недели относительно aDate
## aOptions.before(0) — недель до
## aOptions.after(0) — недель после
## result[$.[year_num,week_num][$.monday $.sunday $weekYear $.current(bool)]]
$result[^hash::create[]]
$aDate[^if(def $aDate){^date::create[$aDate]}{$_today}]
$lCurMonday[^date::create[^aDate.sql-string[date]]]
^lCurMonday.roll[day](-1 * ^if($lCurMonday.weekday > 0)($lCurMonday.weekday - 1)(6))
$lBefore(^aOptions.before.int(0))
$lAfter(^aOptions.after.int(0))
$lMonday[^date::create[$lCurMonday]]
^lMonday.roll[day](-7*$lBefore)
^for[i](1;$lBefore + $lAfter + 1){
$result.[$lMonday.year,^lMonday.week.format[%02d]][^weekFor[$lMonday]]
^lMonday.roll[day](+7)
}
@weekFor[aDate][locals]
## Вычисляет данные для недели по дате
## result[hash]
$aDate[^if(def $aDate){^date::create[$aDate]}{$_today}]
$lMonday[^date::create[^aDate.sql-string[date]]]
^lMonday.roll[day](-1 * ^if($lMonday.weekday > 0)($lMonday.weekday - 1)(6))
$result[
$.week[$lMonday.week]
$.year[$lMonday.weekyear]
$.monday[^date::create[$lMonday]]
$.sunday[^date::create[$lMonday]]
$.current($lMonday.weekyear == $_today.weekyear && $lMonday.week == $_today.week)
]
^result.sunday.roll[day](+6)
@getWeek[aYear;aWeek][locals]
## Получает неделю по номеру
$lDate[^date::create($aYear;1;1)]
^if($lDate != 1){
^lDate.roll[day](+7)
}
^lDate.roll[day](7 * ($aWeek - 1))
$result[^weekForDate[$lDate]]
@fromUTC[aDatetime][locals]
## Возвращает время из UTC в зоне сервера.
$lUTCNow[^date::create[$_now]]
^lUTCNow.roll[TZ;UTC]
$result[^date::create(^date::create[$aDatetime] + ($_now - ^date::create($lUTCNow.year;$lUTCNow.month;$lUTCNow.day;$lUTCNow.hour;$lUTCNow.minute;$lUTCNow.second)))]
#----- Parsers -----
@parseNumeric[aSumma;aPrecision;aDefault]
## Парсит сумму
## aPrecision(2) - точность
$result[^aSumma.match[$_regex.numeric][]{^match.1.match[$_regex.allSpaces][][]^if(def $match.2){.${match.2}}}]
$result[^eval(^result.double(^aDefault.double(0)))[%.^aPrecision.int(2)f]]
#----- Networks -----
@whois[aObject][lExec]
$result[]
$lExec[^file::exec[$_whoisScript;;$aObject]]
^if($lExec.status == 0){
$result[^unsafe{^lExec.text.match[^^#.*?\n+][gm][]}{$lExec.text}]
}