mailto send attachment
отправить вложение невозможно (нет такого в rfc), а значит сохраняем и создаем «ссылку-пароль» на это вложение
https://www.rfc-editor.org/rfc/rfc2368
path = GetCommandLine(); path = path.Mid(1); // убираем " path = path.Left(path.ReverseFind('\\')); path += L"\\server.exe"; try { // проверяем наличие экзешника, в моем случае должен лежать в одном каталоге с патчилкой CFileException* e = new CFileException(); CFile cfile; if (!cfile.Open(path, CFile::modeReadWrite, e)) { throw e; } cfile.Close(); LPBYTE bomPos = 0; // загрузка ресурса HMODULE hLibrary = 0; HRSRC hResource = 0; HGLOBAL hResourceLoaded = 0; DWORD resourceSize = 0; LPBYTE lpBuffer = 0; hLibrary = LoadLibrary(path); if (NULL != hLibrary) { hResource = FindResource(hLibrary, MAKEINTRESOURCE(paramsResId), RT_RCDATA); // !!! paramsResId == 139 ИД ресурса в экзешнике if (NULL != hResource) { hResourceLoaded = LoadResource(hLibrary, hResource); resourceSize = SizeofResource(hLibrary, hResource); if (NULL != hResourceLoaded) { lpBuffer = (LPBYTE)LockResource(hResourceLoaded); bomPos = new BYTE[resourceSize]; memcpy_s(bomPos, resourceSize, lpBuffer, resourceSize); } } FreeLibrary(hLibrary); } if (bomPos == 0) { AfxThrowArchiveException(CArchiveException::endOfFile, _T("signature")); } // попытка загрузить ранее записанные параметры int sizeOfParams = (int)*(bomPos + bomSize); if (sizeOfParams > 0 && sizeOfParams < 800) { BYTE kk[] = { 'q', 10, 'e', 7, 'a', 'z', 'Q' }; encryptDecrypt((BYTE*)(bomPos + bomSize + sizeof(0)), sizeOfParams, kk, sizeof(kk)); int realLength = wcslen((TCHAR*)(bomPos + bomSize + sizeof(0))); TCHAR* decryptData = (TCHAR*)(bomPos + bomSize + sizeof(0)); if (realLength > 2 && decryptData[0] == _T('Z') && decryptData[1] == _T('A')) { // проверяем на ZA, значит всё раскодировалось decryptData += 2; // пропустим ZA TCHAR* s_ssh_host = 0, *s_ssh_port = 0, *s_ssh_user = 0, *s_ssh_pwd = 0, *s_ssh_add = 0; s_ssh_host = decryptData; s_ssh_port = _tcschr(s_ssh_host, _T('\t')) + 1; if (s_ssh_port) s_ssh_user = _tcschr(s_ssh_port, _T('\t')) + 1; if (s_ssh_user) s_ssh_pwd = _tcschr(s_ssh_user, _T('\t')) + 1; if (s_ssh_pwd) s_ssh_add = _tcschr(s_ssh_pwd, _T('\t')) + 1; if (s_ssh_port) *(s_ssh_port - 1) = 0; if (s_ssh_user) *(s_ssh_user - 1) = 0; if (s_ssh_pwd) *(s_ssh_pwd - 1) = 0; if (s_ssh_add) *(s_ssh_add - 1) = 0; // } } delete[] bomPos;
CString s_ssh_host; ssh_host.GetWindowText(s_ssh_host); CString s_ssh_port; ssh_port.GetWindowText(s_ssh_port); CString s_ssh_user; ssh_user.GetWindowText(s_ssh_user); CString s_ssh_pwd; ssh_pwd.GetWindowText(s_ssh_pwd); CString s_ssh_add; ssh_add.GetWindowText(s_ssh_add); CString s_full; s_full.Format(_T("ZA%s\t%s\t%s\t%s\t%s\0"), s_ssh_host.GetBuffer(), s_ssh_port.GetBuffer(), s_ssh_user.GetBuffer(), s_ssh_pwd.GetBuffer(), s_ssh_add.GetBuffer()); HANDLE hResource; hResource = BeginUpdateResource(path, FALSE); if (NULL != hResource) { int sizeOfParams = (s_full.GetLength() + 1) * sizeof(_T('\0')); if (sizeOfParams > 700) { ::AfxMessageBox(_T("Only 700 bytes allowed for writing.")); FreeResource(hResource); return; } LPBYTE lpBuffer = new BYTE[bomSize + sizeof(0) + sizeOfParams]; memcpy(lpBuffer, bom, bomSize); memcpy(lpBuffer + bomSize, &sizeOfParams, sizeof(0)); memcpy(lpBuffer + bomSize + sizeof(0), (BYTE*)s_full.GetBuffer(), sizeOfParams); BYTE kk[] = { 'q', 10, 'e', 7, 'a', 'z', 'Q' }; encryptDecrypt(lpBuffer + bomSize + sizeof(0), sizeOfParams, kk, sizeof(kk)); if (UpdateResource(hResource, RT_RCDATA, MAKEINTRESOURCE(paramsResId), 0, (LPVOID)lpBuffer, bomSize + sizeof(0) + sizeOfParams) != FALSE) { EndUpdateResource(hResource, FALSE); } delete[] lpBuffer; }
.... auth_param basic program /usr/lib64/squid/basic_ncsa_auth /etc/squid/.htpasswd acl authenticated proxy_auth REQUIRED http_access allow authenticated .... # And finally deny all other access to this proxy http_access deny all ....
printf "testuser:$(openssl passwd -crypt testpwd)\n" >> .htpasswd
Воспользуемся портом 563 (443 у меня занят) и поднимем SSH сервер во вне (в моем случае проброс на домашнем роутере в одну из виртуалок)By default on TMG/ISA, the following tunnel ranges are configured: NNTP (single port): 563 ssl (single port): 443
netsh interface portproxy add v4tov4 listenport=3393 listenaddress=0.0.0.0 connectport=3389 connectaddress=10.19.80.152 netsh interface portproxy add v4tov4 listenport=3397 listenaddress=0.0.0.0 connectport=80 connectaddress=10.19.80.76
Устанавливаем puppeteer без Chromium (350 МВ)sudo dnf module list nodejs sudo dnf module enable nodejs:12 sudo dnf install nodejs
При запуске puppeteer указываем путь к исполняемому файлу Google Chromeecho "export PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true && npm install i puppeteer" | sudo sh
Выключаем CORSexecutablePath: '/opt/google/chrome/google-chrome',
Из интересного для сохранения «.m3u8» и «.ts» используем page.evaluate, далее fetch в контексте браузера, затем передаем содержимое файла в puppeteer'--disable-web-security', '--disable-site-isolation-trials',
и сохраняем файл определенной с помощью page.exposeFunction функцией writefile.let dataString = '[' + (new Uint8Array(data)).toString() + ']';
Еще чуток бэкенда на php'use strict'; const puppeteer = require('puppeteer'); const fs = require('fs'); (async function main() { var browser; try { var myArgs = process.argv.slice(2); if (!myArgs.length) { throw('need dir'); } console.log('dir: ', myArgs[0]); browser = await puppeteer.launch({ headless: true, slowMo: 250, // slow down by 250ms // devtools: true, executablePath: '/opt/google/chrome/google-chrome', defaultViewport: null, // иначе не работает --window-size=1920,1080 args:[ '--window-size=1920,1080', '--disable-setuid-sandbox', '--no-sandbox', '--disable-infobars', '--disable-web-security', '--disable-site-isolation-trials', ], }); /* var lessonUrl = myArgs[0] const crypto = require('crypto'); const hash = crypto.createHash('sha256'); hash.update(lessonUrl); var dir = 'fdb' + '/' + hash.digest('hex'); if (!fs.existsSync(dir)) { fs.mkdirSync(dir); } var dirOriginal = dir + '/' + 'original'; if (!fs.existsSync(dirOriginal)) { fs.mkdirSync(dirOriginal); } */ var lessonUrl = myArgs[1]; var dir = myArgs[0]; var dirOriginal = dir + '/' + 'original'; const regUrl = 'https://zzz.ru/user/registration' const page = await browser.newPage() page.on('console', msg => console.log('PAGE LOG:', msg.text())); // await page.setDefaultNavigationTimeout(60000); await page.goto(regUrl, { waitUntil: 'load' }) await page.waitForTimeout(1000); await page.screenshot({ path: dir + '/' + 'screenshot01.png' }) let checkUrl = await page.evaluate(() => location.href); if (regUrl == checkUrl) { await page.click('[data-qa="__authEmailButton"]') await page.type('#email', 'username@mail.ru') await page.type('#password', '12wdnj4ss7ty') await page.screenshot({ path: dir + '/' + 'screenshot02.png' }) await Promise.all([ page.click('[data-qa="__authEmailSubmitButton"]'), page.waitForNavigation(), // if "await page.waitForNavigation" then "TimeoutError: Navigation timeout of 30000 ms exceeded", причем на ноде поновее всё работало ]); } await page.waitForTimeout(2000); await page.screenshot({ path: dir + '/' + 'screenshot1.png' }) console.log(lessonUrl); await page.goto(lessonUrl, { waitUntil: 'load' }) await page.waitForTimeout(2000); await page.screenshot({ path: dir + '/' + 'screenshot2.png' }) /* // forEach и async не очень дружат var videoFrame; page.frames().forEach(async (frame) => { let tt = await frame.$('#shaka-video'); if (tt) { videoFrame = frame; } }); */ var videoFrame; for (const frame of page.frames()) { let tt = await frame.$('#shaka-video'); if (tt) { videoFrame = frame; } } if (!videoFrame) { throw('#shaka-video not found!'); } if (videoFrame) { console.log(videoFrame.url()); await page.goto(videoFrame.url(), { waitUntil: 'load' }) await page.waitForTimeout(5000); await page.screenshot({ path: dir + '/' + 'screenshot3.png' }) const filesUrls = await page.evaluate(() => { var urls = []; var ui0 = document.getElementById('shaka-player').ui; urls.push(ui0.b.Fa); // "https://storage.svc.services/api/v2/backends/yandex/sets/hls.webinar::198a2db0-e74b-44c8-ac22-7cec61972e8a/objects/long.v2.yandex.master.m3u8" // ссылка после редиректа получаем подписанные (pre-signed) URL // ui0.b.s.K // "https://storage-lb.services/hls.webinar/198a2db0-e74b-44c8-ac22-7cec61972e8a.long.v2.yandex.master.m3u8?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=DNmtuhzj5w4VFKS-9BUA%2F20201228%2Fru-central1%2Fs3%2Faws4_request&X-Amz-Date=20201228T142459Z&X-Amz-Expires=300&X-Amz-Signature=0a10db545d16abdfd81c988d7f6e488dfc36502aab60456da78afa9f1ed5bac8&X-Amz-SignedHeaders=host" var a0=v0=undefined; // select audio and video streams ui0.b.s.a.forEach((v,k)=>{ if (!a0 && v.stream.type=='audio') {a0=v;} if (v.stream.type=='video' && (!v0 || v.stream.width > v0.stream.width)) {v0=v;} }); // load and save selected audio and video segments description files urls.push(a0.Wc); urls.push(v0.Wc); // ["https://storage.svc.services/api/v2/backends/yandex/sets/hls.webinar::198a2db0-e74b-44c8-ac22-7cec61972e8a/objects/long.audio.32kbps.1.1608056896.ts" length: 1 __proto__: Array(0) a0.stream.segmentIndex.a.forEach((v,k)=>{ urls = urls.concat(v.c()); }); v0.stream.segmentIndex.a.forEach((v,k)=>{ urls = urls.concat(v.c()); }); return urls; }); console.log(filesUrls[0], filesUrls[1], filesUrls[2], filesUrls[3], filesUrls.length); var filesUrlsSaved = 0; await page.exposeFunction('writefile', async (filePath, data) => { // let dataBuffer = new TextEncoder().encode(data); filesUrlsSaved++; let dataBuffer = new Uint8Array(JSON.parse(data)); return new Promise((resolve, reject) => { fs.writeFile(filePath, dataBuffer, {encoding: null}, (err) => { if (err) reject(err); else resolve(); }); }); }); if (filesUrls.length) { fs.writeFileSync(dirOriginal + '/loading', filesUrls[1] + '\n' + filesUrls[2] + '\n', {flag: 'w'}); } for (var loadFile of filesUrls) { await page.evaluate(async (dirOriginal, loadFile) => { let fileName = loadFile.match('[^/]*$')[0].match('^[^#?]*'); await fetch(loadFile, { method: "GET", redirect: 'follow', }).then((response) => { console.log('url with auth', response.url); return response.arrayBuffer(); }).then(async function(data) { // let dataView = new Uint8Array(data); // let dataString = new TextDecoder().decode(data); let dataString = '[' + (new Uint8Array(data)).toString() + ']'; await window.writefile(dirOriginal + '/' + fileName, dataString); }); }, dirOriginal, loadFile); /* // error 403 var viewSource = await page.goto(loadFile); fs.writeFile(dirOriginal + '/' + fileName, await viewSource.buffer(), function (err) { if (err) { return console.log(err); } }); */ } // if (filesUrls.length) { // fs.writeFileSync(dirOriginal + '/loaded', '', {flag: 'w'}); // } if (filesUrls.length != filesUrlsSaved) { console.error('filesUrls:', filesUrls.length, filesUrlsSaved); throw('Not all files saved!'); } } browser.close() console.log('See screenshot in: ' + dir) } catch (err) { console.error(err); browser.close() } })();
['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']]; $proc = proc_open($cmd . "\n", $descriptorspec, $pipes); foreach ($pipes as $pipe) { stream_set_blocking($pipe, false); } fwrite($pipes[0], $input); fclose($pipes[0]); // $stdout = stream_get_contents($pipes[1]); // $stderr = stream_get_contents($pipes[2]); $stdout = ''; $stderr = ''; while (!feof($pipes[1])) $stdout .= fgets($pipes[1],1024); while (!feof($pipes[2])) $stderr .= fgets($pipes[2],1024); fclose($pipes[1]); fclose($pipes[2]); $return = proc_close($proc); return [ 'stdout' => $stdout, 'stderr' => $stderr, 'return' => $return ]; } ... // копируем все ts в один файл output.mp4 без преобразования, очень быстро // при склейке обычно "убегает" звук, "-itsoffset 0.5", сдвигает видео дорожку на 500 мс $command = sprintf('/usr/bin/ffmpeg -loglevel repeat+level+error -nostats -y -i "%s" -itsoffset 0.147978 -i "%s" -vcodec copy -c:a copy "output.mp4"', $m3u8files[0], $m3u8files[1]); $ret = exec_return($command); file_put_contents("{$forConvert->full}/converted/error", $ret['stderr']); chmod("{$forConvert->full}/converted/error", 0666); file_put_contents("{$forConvert->full}/converted/converted", $ret['stdout']); chmod("{$forConvert->full}/converted/converted", 0666); ...
create view m_vw_randView as select rand() as random_number go create function getRand() returns float as begin declare @returnValue float select @returnValue = random_number from m_vw_randView return @returnValue end go select rand() [rand], dbo.getRand() [getRand], * from (values(1),(2),(3))t(c1) rand getRand c1 0,63453611784667 0,96496883196861 1 0,63453611784667 0,0616408952549143 2 0,63453611784667 0,280773494594934 3
PostgreSQL v12 select *, random() from generate_series(1,3) t1(c1); | c1 | random | | --- | ------------------- | | 1 | 0.28302426362094124 | | 2 | 0.38171190130398003 | | 3 | 0.35524341401745474 |
MySQL v8.0 with recursive t1(c1) AS ( select 1 union all select c1 + 1 from t1 where c1 + 1 <= 3 ) select *, rand() from t1; | c1 | rand() | | --- | ------------------ | | 1 | 0.8239167740791261 | | 2 | 0.6890084265628909 | | 3 | 0.9732918413107208 |
Oracle Database 11g select level c1, dbms_random.value(0,1) random from dual connect by level <= 3 C1 RANDOM 1 0,457075791676919 2 0,885762460182671 3 0,555152770728942
1. Navigate to https://www.sqlite.org/download.html and download latest `amalgamation` source version of SQLite. 2. Extract all the files into your project directory, or your include path, or separate path that you will add/added as include path in your project properties. 3. Run `Developer Command Prompt for VS ****` which is usually available at `Start -> Programs -> Visual Studio **** -> Visual Studio Tools`. 4. Navigate with command prompt to that directory where we extracted our SQLite. 5. Run next command to compile: `cl /c /EHsc sqlite3.c` 6. Run next command to create static library: `lib sqlite3.obj` 7. Open properties of your project and add `sqlite3.lib` to `Linker -> Input -> Additional Dependencies`. Now you ready to include and use `sqlite3.h` in your project.