ip:
awk '{print $1}' /var/log/httpd/site.ru_access.log | sort | uniq -c | sort -nr | head -20
User-Agent
awk -F\" '{print $6}' /var/log/httpd/site.ru_access.log | sort | uniq -c | sort -nr | head -20
ip:
awk '{print $1}' /var/log/httpd/site.ru_access.log | sort | uniq -c | sort -nr | head -20
User-Agent
awk -F\" '{print $6}' /var/log/httpd/site.ru_access.log | sort | uniq -c | sort -nr | head -20
/site/ready.php
$wire->addHook('ProcessPageAdd::execute', function($event) { $process = $event->object; $event->return .= <<<JS <script> document.addEventListener("DOMContentLoaded", function() { var form = document.querySelector('form#ProcessPageAdd'); if(!form) return; form.addEventListener('submit', function() { var titleInput = document.querySelector('input[name="title"]'); if(titleInput && !titleInput.value) { titleInput.value = 'NotPublished'; } var nameInput = document.querySelector('input[name="_pw_page_name"]'); if(nameInput && !nameInput.value) { nameInput.value = 'np-' + Math.floor(Date.now() / 1000); } }); }); </script> JS; });
Список статей, например, /site/templates/page-category.php
$allPosts = $pages->find('limit=9, template=blog-post, sort=-publish_from, status=published, category='.$page->id.', title!=NotPublished');
Страница публикации, например, /site/templates/blog-post.php
if($user->language->isDefault() && $page->title == 'NotPublished') { throw new Wire404Exception(); }
Список статей в админке, например, /site/templates/template-parts/dashboard/_dashboard_post_page.php
<a href="<?= $blogPost->editUrl() ?>"> <?php if($blogPost->title == 'NotPublished'): ?> <strike><?= $blogPost->title ?></strike> <?php else: ?> <?= $blogPost->title ?> <?php endif;?> <?php $title_en=$blogPost->getLanguageValue('en', 'title'); if($title_en!=$blogPost->title){ echo '<br/>'.$title_en; } ?> </a>
Задача: FlexSlider 2 — при клике на крайний видимый (правый) слайд прокручивать слайдер дальше вправо, как будто нажали стрелку «next», чтобы было понятно, что там есть ещё элементы.
var thumbWidth=function(){ return(window.innerWidth<480)?80:190; } var thumbMargin=function(){ return(window.innerWidth<480)?10:20; } $('#detail_gallery_thumbs').flexslider({ animation:"slide", controlNav:false, animationLoop:false, slideshow:false, itemWidth:thumbWidth(), itemMargin:thumbMargin(), asNavFor:'#detail_gallery_photos' }); var slider=$('#detail_gallery_thumbs'); slider.on('click','.slides > li',function(){ var flex=slider.data('flexslider'); var index=$(this).index(); var visibleCount=flex.visible; var lastVisibleIndex=flex.currentSlide+visibleCount-1; if(index===lastVisibleIndex&&flex.currentSlide+visibleCount<flex.count){ flex.flexAnimate(flex.currentSlide+1); } }); $('#detail_gallery_photos').flexslider({ animation:"slide", controlNav:false, animationLoop:false, slideshow:false, sync:"#detail_gallery_thumbs" });
1. Подготовить файлы и sql запросы — скрипт на php (запускать дважды, первый раз файлам устанавливается дата из exif):
$pk=200; — значение должно быть больше текущего максимального в ZGENERICASSET
<?php ini_set('date.timezone','Etc/GMT-4'); $dir=__DIR__.'/photos'; $files=scandir($dir); $files=array_diff(scandir($dir),array('.','..')); usort($files,function($a,$b) use ($dir){ return filemtime($dir.'/'.$a)<=>filemtime($dir.'/'.$b); }); $outputFile='insert_photos.sql'; $sql="BEGIN TRANSACTION;\n"; $pk=200; $z_ent=15; $z_opt=1; $sql.="DELETE FROM \"ZGENERICASSET\" WHERE Z_PK>=".$pk.";\n"; $sql.="DELETE FROM \"ZADDITIONALASSETATTRIBUTES\" WHERE Z_PK>=".$pk.";\n"; $sql.="DELETE FROM \"Z_8ASSETS\" WHERE Z_14ASSETS>=".$pk.";\n"; $pk+=100; foreach($files as $file){ $path=$dir.'/'.$file; $ext=strtolower(pathinfo($file,PATHINFO_EXTENSION)); $isVideo=($ext==='mov'); $isImage=($ext==='jpg'||$ext==='jpeg'); if(!$isVideo&&!$isImage)continue; $filename=$file; $title=pathinfo($file,PATHINFO_FILENAME); $directory='DCIM/100APPLE'; $zuuid="X'".bin2hex(random_bytes(16))."'"; if($isImage){ $width=getimagesize($path)[0]; $height=getimagesize($path)[1]; $ZUNIFORMTYPEIDENTIFIER='public.jpeg'; $orientation=($width>$height)?3:6; $add_orientation=$orientation; $ZKIND=0; $ZHIGHDYNAMICRANGETYPE=1; $ZORIGINALHEIGHT=($width>$height)?$height:$width; $ZORIGINALWIDTH=($width>$height)?$width:$height; $ZDURATION='0.0'; $exif=@exif_read_data($path); if(!empty($exif['DateTimeOriginal'])){ $shootTimeStr=$exif['DateTimeOriginal']; } elseif(!empty($exif['CreateDate'])){ $shootTimeStr=$exif['CreateDate']; } elseif(!empty($exif['DateTimeDigitized'])){ $shootTimeStr=$exif['DateTimeDigitized']; } else{ $shootTimeStr=null; } if($shootTimeStr){ $shootUnix=strtotime(str_replace(':','-',substr($shootTimeStr,0,10)).substr($shootTimeStr,10)); } else{ $shootUnix=filemtime($path); } } else{ $width=640; $height=480; $ZUNIFORMTYPEIDENTIFIER='com.apple.quicktime-movie'; $orientation=1; $add_orientation=0; $ZKIND=1; $ZHIGHDYNAMICRANGETYPE=null; $ZORIGINALHEIGHT=0; $ZORIGINALWIDTH=0; $ZDURATION='4.0'; $shootUnix=filemtime($path); } touch($path,$shootUnix,$shootUnix); $macEpoch=strtotime('2001-01-01 00:00:00'); $macTime=round(($shootUnix-$macEpoch)+(rand(10,99999)/100000),5); $originalSize=filesize($path); $zgenericasset=[ 'Z_PK'=>$pk, 'Z_ENT'=>$z_ent, 'Z_OPT'=>$z_opt, 'ZCLOUDHASCOMMENTSBYME'=>NULL, 'ZCLOUDHASCOMMENTSCONVERSATION'=>NULL, 'ZCLOUDHASUNSEENCOMMENTS'=>NULL, 'ZCLOUDPLACEHOLDERKIND'=>0, 'ZCOMPLETE'=>1, 'ZFLAGGED'=>0, 'ZHEIGHT'=>$height, 'ZKIND'=>$ZKIND, 'ZORIENTATION'=>$orientation, 'ZSAVEDASSETTYPE'=>3, 'ZTHUMBNAILINDEX'=>1, 'ZWIDTH'=>$width, 'ZADDITIONALATTRIBUTES'=>$pk, 'ZCLOUDBATCHPUBLISHDATE'=>NULL, 'ZCLOUDLASTVIEWEDCOMMENTDATE'=>NULL, 'ZDATECREATED'=>$macTime, 'ZMODIFICATIONDATE'=>ceil($macTime), 'ZSORTTOKEN'=>$macTime, 'ZCLOUDASSETGUID'=>NULL, 'ZCLOUDASSETKIND'=>NULL, 'ZCLOUDBATCHID'=>NULL, 'ZCLOUDCOLLECTIONGUID'=>NULL, 'ZDIRECTORY'=>$directory, 'ZFILENAME'=>$filename, 'ZTITLE'=>$title, 'ZUNIFORMTYPEIDENTIFIER'=>$ZUNIFORMTYPEIDENTIFIER, 'ZCLOUDMETADATA'=>NULL, 'ZFACERECTANGLES'=>NULL, 'ZUUID'=>$zuuid, 'ZLOCATIONDATA'=>NULL, 'ZIMAGEURLDATA'=>NULL, 'ZTHUMBNAILURLDATA'=>NULL, ]; $zadditional=[ 'Z_PK'=>$pk, 'Z_ENT'=>1, 'Z_OPT'=>2, 'ZEMBEDDEDTHUMBNAILHEIGHT'=>0, 'ZEMBEDDEDTHUMBNAILLENGTH'=>0, 'ZEMBEDDEDTHUMBNAILOFFSET'=>0, 'ZEMBEDDEDTHUMBNAILWIDTH'=>0, 'ZHIGHDYNAMICRANGETYPE'=>$ZHIGHDYNAMICRANGETYPE, 'ZORIGINALFILESIZE'=>$originalSize, 'ZORIGINALHEIGHT'=>$ZORIGINALHEIGHT, 'ZORIGINALORIENTATION'=>$orientation, 'ZORIGINALWIDTH'=>$ZORIGINALWIDTH, 'ZASSET'=>$pk, 'Z14_ASSET'=>15, 'ZDURATION'=>$ZDURATION, 'ZCREATORBUNDLEID'=>NULL, 'ZORIGINALFILENAME'=>$filename, 'ZORIGINALPATH'=>$directory, 'ZIMPORTSESSIONID'=>NULL, 'ZORIGINALASSETSUUID'=>NULL, ]; $album=[ 'Z_8ALBUMS'=>4, 'Z_14ASSETS'=>$pk, 'Z_FOK_14ASSETS'=>2048, ]; $columns=implode(',',array_keys($zgenericasset)); $values=implode(',',array_map(fn($v)=>is_null($v)?'NULL':(is_numeric($v)?$v:"'$v'"),$zgenericasset)); $sql.=str_replace("'',NULL","',NULL",str_replace("NULL,'X'","NULL,X'","INSERT INTO \"ZGENERICASSET\"($columns)VALUES($values);"))."\n"; $columns=implode(',',array_keys($zadditional)); $values=implode(',',array_map(fn($v)=>is_null($v)?'NULL':(is_numeric($v)?$v:"'$v'"),$zadditional)); $sql.="INSERT INTO \"ZADDITIONALASSETATTRIBUTES\"($columns)VALUES($values);\n"; $columns=implode(',',array_keys($album)); $values=implode(',',array_map(fn($v)=>is_null($v)?'NULL':(is_numeric($v)?$v:"'$v'"),$album)); $sql.="INSERT INTO \"Z_8ASSETS\"($columns)VALUES($values);\n"; $pk++; } $sql.="UPDATE \"Z_PRIMARYKEY\" SET Z_MAX='".$pk."' WHERE Z_NAME='AdditionalAssetAttributes';\n"; $sql.="UPDATE \"Z_PRIMARYKEY\" SET Z_MAX='".$pk."' WHERE Z_NAME='GenericAsset';\n"; $sql.="COMMIT;\n"; file_put_contents($outputFile,$sql); echo "SQL file generated: $outputFile\n"; ?>
2. В локальную резервную копию через iBackupBot импортировать фото и видео после обработки скриптом в /System Files/CameraRollDomain/Media/DCIM/100APPLE
3. Из локальной резервной копии через iBackupBot экспортировать /System Files/CameraRollDomain/Media/PhotoData/Photos.sqlite
4. В DB Browser for SQLite выполнить подготовленные запросы, записать изменения.
5. В iBackupBot импортировать БД обратно.
6. Восстановить резервную копию через iTunes
1. Из локальной резервной копии через iBackupBot экспортировать /System Files/WirelessDomain/Library/CallHistory/call_history.db
2. Подготовить csv для загрузки в формате (выгружено через iPhoneBackupBrowser, важно: в длительности здесь важны только секунды, т.к. это полное кол-во секунд)
"From","To","Start date","Duration" "Me","+79210000000","2013-03-01 20:00:42","0h 26m 1611s" "+79210000000","Me","2013-03-02 10:41:52","0h 05m 335s"
3. Подготовить sql запросы — скрипт на php:
<?php $csvFile='calls.csv'; $outputFile='insert_calls.sql'; $handle=fopen($csvFile,'r'); if(!$handle){ die("Cannot open CSV file.\n"); } $sql="BEGIN TRANSACTION;\n"; $header=fgetcsv($handle); $rowId=1; ini_set('date.timezone','Etc/GMT-3'); while(($data=fgetcsv($handle))!==false){ list($from,$to,$startDate,$duration)=$data; $from=trim($from,'"'); $to=trim($to,'"'); $startDate=trim($startDate,'"'); $duration=trim($duration,'"'); preg_match('/(\d+)s$/',$duration,$matches); $totalSeconds=isset($matches[1])?intval($matches[1]):0; if($from==='Me'){ $flags=5; $address=$to; } else{ $flags=4; $address=$from; } $timestamp=strtotime($startDate); $mcc='255'; $mnc='01'; $sql.="INSERT INTO call VALUES($rowId,'$address',$timestamp,$totalSeconds,$flags,-1,'','$mcc','$mnc',1,0,NULL,NULL);\n"; $rowId++; } $sql.="COMMIT;\n"; fclose($handle); file_put_contents($outputFile,$sql); echo "SQL file generated: $outputFile\n"; ?>
4. В DB Browser for SQLite выполнить подготовленные запросы, записать изменения.
5. В iBackupBot импортировать БД обратно.
6. Восстановить резервную копию через iTunes
если установлен squid без OpenSSL полностью удалить
sudo apt remove --purge squid squid-common squid-langpack sudo apt autoremove which squid
установить squid с поддержкой OpenSSL
sudo apt install squid-openssl squid -v | grep -i ssl
создать каталог и самоподписанный CA (корневой сертификат для MITM) для динамической генерации сертификатов под сайты
sudo mkdir -p /etc/squid/ssl openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 \ -keyout /etc/squid/ssl/ca.key \ -out /etc/squid/ssl/ca.crt \ -subj "/CN=Squid-CA/" chmod 600 /etc/squid/ssl/ca.key
конфиг
mcedit /etc/squid/squid.conf
на 3128 прокси как было для всех с авторизацией, на 3130 специально для телефона с SSL-bump и без авторизации + MITM (с авторизацией он не может работать)
http_port 3128 auth_param basic program /usr/lib/squid/basic_ncsa_auth /etc/squid/passwords auth_param basic children 5 auth_param basic realm Proxy Authentication auth_param basic credentialsttl 2 hours acl authenticated proxy_auth REQUIRED http_port 3130 ssl-bump \ generate-host-certificates=on dynamic_cert_mem_cache_size=4MB \ cert=/etc/squid/ssl/ca.crt key=/etc/squid/ssl/ca.key acl iphone_port myport 3130 acl step1 at_step SslBump1 ssl_bump peek step1 ssl_bump bump iphone_port ssl_bump splice all http_access allow iphone_port http_access allow authenticated http_access deny all access_log /var/log/squid/access.log cache_log /var/log/squid/cache.log
пароли для пользователей с авторизацией
htpasswd -c /etc/squid/passwords user cat /etc/squid/passwords
инициализация SSL DB
security_file_certgen -c -s /var/spool/squid/ssl_db sudo /usr/lib/squid/security_file_certgen -c -s /var/spool/squid/ssl_db -M 4MB
права
chown proxy:proxy /etc/squid/passwords chmod 640 /etc/squid/passwords sudo chown -R proxy:proxy /var/spool/squid sudo chmod -R 755 /var/spool/squid
перезапуск
squid -k parse squid -k reconfigure systemctl restart squid
проверки
systemctl status squid.service sudo tail -f /var/log/squid/cache.log sudo tail -f /var/log/squid/access.log
ca.crt установить на iphone, передать, например, с помощью встроенного e-mail клиента
в текущем подключении wi-fi — сервер и порт, без авторизации
function getSingleIfRepeatedTwiceWithSpace($text){ if(preg_match('/^(.+)\s\1$/',$text,$matches)){ return $matches[1]; } return $text; }