This commit is contained in:
2026-10-04 18:11:59 +03:30
parent d7054eeb73
commit e673d11a68
103 changed files with 522651 additions and 149 deletions
+1
View File
@@ -29,6 +29,7 @@ https://github.com/mozilla-ai/llamafile
------------------- -------------------
Uncesored Qwen 3.5 Coder GGUF: Uncesored Qwen 3.5 Coder GGUF:
also download mmproj files for providing visioning:
https://huggingface.co/DavidAU/Qwen3.5-9B-The-Defiant-Fable-Uncensored-Heretic-NEO-IMATRIX-MAX-MTP-GGUF https://huggingface.co/DavidAU/Qwen3.5-9B-The-Defiant-Fable-Uncensored-Heretic-NEO-IMATRIX-MAX-MTP-GGUF
File diff suppressed because one or more lines are too long
+178 -146
View File
@@ -481,15 +481,6 @@
"checkboxes": [], "checkboxes": [],
"comments": [] "comments": []
}, },
{
"id": "17bbcc83-4330-4631-a08a-521c99047ebc",
"listId": "1706107f-ace2-4240-aa32-3d2031264a41",
"title": "Try to Implement Audio, Video and Document Content Extraction in XAi Service ...",
"description": "",
"labels": [],
"checkboxes": [],
"comments": []
},
{ {
"id": "7785aecc-0b27-4428-a50b-03c046c5a0d6", "id": "7785aecc-0b27-4428-a50b-03c046c5a0d6",
"listId": "1706107f-ace2-4240-aa32-3d2031264a41", "listId": "1706107f-ace2-4240-aa32-3d2031264a41",
@@ -498,15 +489,6 @@
"labels": [], "labels": [],
"checkboxes": [], "checkboxes": [],
"comments": [] "comments": []
},
{
"id": "5f8a8b2f-06ce-46a9-8101-f14e34b51249",
"listId": "1706107f-ace2-4240-aa32-3d2031264a41",
"title": "implement Api Key Mechanism using IDServer and Clients sides ...",
"description": "",
"labels": [],
"checkboxes": [],
"comments": []
} }
] ]
}, },
@@ -515,18 +497,44 @@
"title": "InProgress", "title": "InProgress",
"cards": [ "cards": [
{ {
"id": "9757ac0e-2aff-44a1-a0db-7ee4468def1b", "id": "5f8a8b2f-06ce-46a9-8101-f14e34b51249",
"listId": "171f43f3-ae73-49b7-9239-9f3fb695cc2b", "listId": "171f43f3-ae73-49b7-9239-9f3fb695cc2b",
"title": "Detect a Very Good GGUF Model for Performing OCR on Bynary Contents ...", "title": "implement Api Key Mechanism using IDServer and Clients sides ...",
"description": "", "description": "",
"labels": [], "labels": [],
"checkboxes": [], "checkboxes": [
{
"id": "66cf978d-2d2f-4bbc-a97c-504ba0ddba65",
"title": "R&D about how i can attach a Custom Entity in IDS Dbs;",
"checked": true
},
{
"id": "1ef7dc8c-5b19-499e-803e-500885eb3bb9",
"title": "Add Entites Related in XIdentityModels ...",
"checked": true
},
{
"id": "1509ec76-9372-40a1-b387-1f8e005d507e",
"title": "Add DbContext DbSets and Model Builder Configurations ...",
"checked": true
},
{
"id": "b4ed3da1-d967-4a11-b2c3-88a3c0aca5ad",
"title": "Test Migration Identity Dbs ...",
"checked": true
},
{
"id": "13dc96e9-dd74-48e0-a254-23818bd3750c",
"title": "Follow Next Steps ...",
"checked": false
}
],
"comments": [] "comments": []
}, },
{ {
"id": "38a94972-d86a-49a3-8917-9b2d958df660", "id": "17bbcc83-4330-4631-a08a-521c99047ebc",
"listId": "171f43f3-ae73-49b7-9239-9f3fb695cc2b", "listId": "171f43f3-ae73-49b7-9239-9f3fb695cc2b",
"title": "Complete Audio Transcript ...", "title": "Try to Implement Audio, Video and Document Content Extraction in XAi Service ...",
"description": "", "description": "",
"labels": [], "labels": [],
"checkboxes": [], "checkboxes": [],
@@ -596,33 +604,6 @@
} }
], ],
"comments": [] "comments": []
},
{
"id": "bbefacad-f6e5-42cf-866f-7ce4fa38a549",
"listId": "171f43f3-ae73-49b7-9239-9f3fb695cc2b",
"title": "Implement Content Provider Base actions for add or update Content using resources ...",
"description": "",
"labels": [],
"checkboxes": [],
"comments": []
},
{
"id": "07747425-25d1-478b-ba84-c56e978574b3",
"listId": "171f43f3-ae73-49b7-9239-9f3fb695cc2b",
"title": "Add Support for Add/Update Content by Providing Locales in Content Service ...",
"description": "",
"labels": [],
"checkboxes": [],
"comments": []
},
{
"id": "d3e18512-b4a6-4049-974b-af1b0f27cc47",
"listId": "171f43f3-ae73-49b7-9239-9f3fb695cc2b",
"title": "add Support for reading Tags in Content Enrichers ...",
"description": "",
"labels": [],
"checkboxes": [],
"comments": []
} }
] ]
}, },
@@ -631,8 +612,153 @@
"title": "Test", "title": "Test",
"cards": [ "cards": [
{ {
"id": "5cccaa60-c985-4a99-93eb-adb38a1f79db", "id": "07747425-25d1-478b-ba84-c56e978574b3",
"listId": "8c15334f-3b2e-4eca-999e-4c887cb628e9", "listId": "8c15334f-3b2e-4eca-999e-4c887cb628e9",
"title": "Add Support for Add/Update Content by Providing Locales in Content Service ...",
"description": "",
"labels": [],
"checkboxes": [],
"comments": []
},
{
"id": "bbefacad-f6e5-42cf-866f-7ce4fa38a549",
"listId": "8c15334f-3b2e-4eca-999e-4c887cb628e9",
"title": "Implement Content Provider Base actions for add or update Content using resources ...",
"description": "",
"labels": [],
"checkboxes": [],
"comments": []
},
{
"id": "d3e18512-b4a6-4049-974b-af1b0f27cc47",
"listId": "8c15334f-3b2e-4eca-999e-4c887cb628e9",
"title": "add Support for reading Tags in Content Enrichers ...",
"description": "",
"labels": [],
"checkboxes": [],
"comments": []
},
{
"id": "9757ac0e-2aff-44a1-a0db-7ee4468def1b",
"listId": "8c15334f-3b2e-4eca-999e-4c887cb628e9",
"title": "Detect a Very Good GGUF Model for Performing OCR on Bynary Contents ...",
"description": "",
"labels": [],
"checkboxes": [],
"comments": [
{
"id": "3b3491c8-8f59-4b9e-b05f-51eccab7fd54",
"comment": "this is done by do R&D about this.\ni found my default Thinking model is support Vissioning.\nfor this we have to download gguf for mmproj and attach it to serving command.\ni permor downloading actions and then try to update running files."
}
]
}
]
},
{
"id": "91b2b60d-a61b-4d81-bfc8-44ca4ad152ba",
"title": "Done",
"cards": [
{
"id": "d5e2e05d-4205-452f-9899-5ad6f95007a6",
"listId": "91b2b60d-a61b-4d81-bfc8-44ca4ad152ba",
"title": "Add Support for Tags in Content Service ...",
"description": "",
"labels": [],
"checkboxes": [],
"comments": []
},
{
"id": "58804ad9-952c-4685-9d59-ca4b67188240",
"listId": "91b2b60d-a61b-4d81-bfc8-44ca4ad152ba",
"title": "Add Support for ZeroMQ in xEventService ...",
"description": "",
"labels": [],
"checkboxes": [],
"comments": []
},
{
"id": "a42dd42b-8fe0-4853-955e-e06770784e41",
"listId": "91b2b60d-a61b-4d81-bfc8-44ca4ad152ba",
"title": "Add Support for Kafka in xEvent Service ...",
"description": "",
"labels": [],
"checkboxes": [],
"comments": []
},
{
"id": "d82776f1-55fe-4977-9db0-f23d17a1ea37",
"listId": "91b2b60d-a61b-4d81-bfc8-44ca4ad152ba",
"title": "Adding Support for XML Documents Integration for All Exists Assemblies in Swagger",
"description": "",
"labels": [],
"checkboxes": [],
"comments": []
},
{
"id": "07e06cce-8c53-479c-8a91-d311b228eba5",
"listId": "91b2b60d-a61b-4d81-bfc8-44ca4ad152ba",
"title": "Override Content Base Actions for using Enrichers ...",
"description": "",
"labels": [],
"checkboxes": [],
"comments": []
},
{
"id": "5930bcbb-4c5a-493a-afbe-1afcfd18501f",
"listId": "91b2b60d-a61b-4d81-bfc8-44ca4ad152ba",
"title": "Fix Enricher Issues on X AiData Service ...",
"description": "",
"labels": [],
"checkboxes": [
{
"id": "4752f2ad-1457-4acc-ad5b-ab4e853fd66b",
"title": "Remove all Enrichers from Repository Services ...",
"checked": true
}
],
"comments": []
},
{
"id": "d8a9ddfc-0b53-4313-aac1-4afdf5261691",
"listId": "91b2b60d-a61b-4d81-bfc8-44ca4ad152ba",
"title": "Add Mapper Configs for AI Models ...",
"description": "",
"labels": [],
"checkboxes": [],
"comments": []
},
{
"id": "7af4f8b4-5a5a-43d2-b154-026e13da1d92",
"listId": "91b2b60d-a61b-4d81-bfc8-44ca4ad152ba",
"title": "Add Support for IXAiDataProvider",
"description": "Data Provider needs to Provides all requirements of Data Manipulation of AI Models and also provides Default Project and Default Conversation for Data Handling ...",
"labels": [],
"checkboxes": [
{
"id": "e2abaca1-99cf-424a-870f-21f330445bbe",
"title": "Integrate all requirement actions",
"checked": true
},
{
"id": "f496ccaf-6d9e-43df-ab9e-2e2192bc7ef1",
"title": "Prepare Seeding Default Project and Default Conversation ",
"checked": true
}
],
"comments": []
},
{
"id": "38a94972-d86a-49a3-8917-9b2d958df660",
"listId": "91b2b60d-a61b-4d81-bfc8-44ca4ad152ba",
"title": "Complete Audio Transcript ...",
"description": "",
"labels": [],
"checkboxes": [],
"comments": []
},
{
"id": "5cccaa60-c985-4a99-93eb-adb38a1f79db",
"listId": "91b2b60d-a61b-4d81-bfc8-44ca4ad152ba",
"title": "Complete OCR Preparation ...", "title": "Complete OCR Preparation ...",
"description": "", "description": "",
"labels": [], "labels": [],
@@ -641,7 +767,7 @@
}, },
{ {
"id": "1c3b121a-08d5-44b1-a991-4fc95f7ebe15", "id": "1c3b121a-08d5-44b1-a991-4fc95f7ebe15",
"listId": "8c15334f-3b2e-4eca-999e-4c887cb628e9", "listId": "91b2b60d-a61b-4d81-bfc8-44ca4ad152ba",
"title": "Add AiService Mechanism ...", "title": "Add AiService Mechanism ...",
"description": "", "description": "",
"labels": [], "labels": [],
@@ -653,102 +779,8 @@
} }
], ],
"comments": [] "comments": []
},
{
"id": "7af4f8b4-5a5a-43d2-b154-026e13da1d92",
"listId": "8c15334f-3b2e-4eca-999e-4c887cb628e9",
"title": "Add Support for IXAiDataProvider",
"description": "Data Provider needs to Provides all requirements of Data Manipulation of AI Models and also provides Default Project and Default Conversation for Data Handling ...",
"labels": [],
"checkboxes": [
{
"id": "e2abaca1-99cf-424a-870f-21f330445bbe",
"title": "Integrate all requirement actions",
"checked": false
},
{
"id": "f496ccaf-6d9e-43df-ab9e-2e2192bc7ef1",
"title": "Prepare Seeding Default Project and Default Conversation ",
"checked": false
}
],
"comments": []
},
{
"id": "d8a9ddfc-0b53-4313-aac1-4afdf5261691",
"listId": "8c15334f-3b2e-4eca-999e-4c887cb628e9",
"title": "Add Mapper Configs for AI Models ...",
"description": "",
"labels": [],
"checkboxes": [],
"comments": []
},
{
"id": "5930bcbb-4c5a-493a-afbe-1afcfd18501f",
"listId": "8c15334f-3b2e-4eca-999e-4c887cb628e9",
"title": "Fix Enricher Issues on X AiData Service ...",
"description": "",
"labels": [],
"checkboxes": [
{
"id": "4752f2ad-1457-4acc-ad5b-ab4e853fd66b",
"title": "Remove all Enrichers from Repository Services ...",
"checked": false
}
],
"comments": []
},
{
"id": "07e06cce-8c53-479c-8a91-d311b228eba5",
"listId": "8c15334f-3b2e-4eca-999e-4c887cb628e9",
"title": "Override Content Base Actions for using Enrichers ...",
"description": "",
"labels": [],
"checkboxes": [],
"comments": []
},
{
"id": "d82776f1-55fe-4977-9db0-f23d17a1ea37",
"listId": "8c15334f-3b2e-4eca-999e-4c887cb628e9",
"title": "Adding Support for XML Documents Integration for All Exists Assemblies in Swagger",
"description": "",
"labels": [],
"checkboxes": [],
"comments": []
},
{
"id": "a42dd42b-8fe0-4853-955e-e06770784e41",
"listId": "8c15334f-3b2e-4eca-999e-4c887cb628e9",
"title": "Add Support for Kafka in xEvent Service ...",
"description": "",
"labels": [],
"checkboxes": [],
"comments": []
},
{
"id": "58804ad9-952c-4685-9d59-ca4b67188240",
"listId": "8c15334f-3b2e-4eca-999e-4c887cb628e9",
"title": "Add Support for ZeroMQ in xEventService ...",
"description": "",
"labels": [],
"checkboxes": [],
"comments": []
},
{
"id": "d5e2e05d-4205-452f-9899-5ad6f95007a6",
"listId": "8c15334f-3b2e-4eca-999e-4c887cb628e9",
"title": "Add Support for Tags in Content Service ...",
"description": "",
"labels": [],
"checkboxes": [],
"comments": []
} }
] ]
},
{
"id": "91b2b60d-a61b-4d81-bfc8-44ca4ad152ba",
"title": "Done",
"cards": []
} }
], ],
"archive": { "archive": {
+244
View File
@@ -0,0 +1,244 @@
<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>مستند فنی: اجرای مدل GGUF برای OCR چندزبانه با Ollama</title>
<style>
/* قالب ثابت مستندات */
body {
font-family: 'Tahoma', 'Segoe UI', Arial, sans-serif;
line-height: 1.8;
color: #333;
background-color: #f4f6f8;
margin: 0;
padding: 20px;
}
.container {
max-width: 900px;
margin: 0 auto;
background: #ffffff;
padding: 35px;
border-radius: 10px;
box-shadow: 0 6px 16px rgba(0,0,0,0.08);
}
.header {
border-bottom: 3px solid #2c3e50;
padding-bottom: 20px;
margin-bottom: 30px;
}
.header h1 {
color: #2c3e50;
margin: 0;
font-size: 26px;
font-weight: bold;
}
.meta-info {
display: flex;
flex-wrap: wrap;
gap: 15px;
margin-top: 20px;
font-size: 14px;
color: #444;
}
.meta-info span {
background: #e8ecef;
padding: 6px 14px;
border-radius: 6px;
font-weight: 500;
}
.section {
margin-bottom: 35px;
}
.section h2 {
color: #2980b9;
border-right: 5px solid #2980b9;
padding-right: 15px;
font-size: 22px;
margin-bottom: 20px;
}
.step {
background: #f8fbff;
border: 1px solid #d6e4f0;
border-radius: 8px;
padding: 20px;
margin-bottom: 20px;
transition: transform 0.2s;
}
.step:hover {
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0,0,0,0.05);
}
.step h3 {
margin-top: 0;
color: #1a5276;
font-size: 18px;
}
code {
background: #2d3436;
color: #55efc4;
padding: 3px 8px;
border-radius: 5px;
font-family: 'Courier New', Courier, monospace;
font-size: 14px;
direction: ltr;
display: inline-block;
}
pre {
background: #2d3436;
color: #dfe6e9;
padding: 20px;
border-radius: 8px;
overflow-x: auto;
direction: ltr;
text-align: left;
font-size: 14px;
line-height: 1.5;
}
.footer {
margin-top: 50px;
padding-top: 25px;
border-top: 2px solid #eee;
text-align: center;
font-size: 13px;
color: #777;
}
.note {
background: #fff8e1;
border: 1px solid #ffecb3;
color: #856404;
padding: 15px;
border-radius: 8px;
margin: 20px 0;
border-right: 4px solid #ffc107;
}
ul, ol {
padding-right: 25px;
}
li {
margin-bottom: 8px;
}
</style>
</head>
<body>
<div class="container">
<!-- سربرگ مستند -->
<div class="header">
<h1>مستند فنی: معرفی و اجرای مدل GGUF برای OCR چندزبانه با Ollama</h1>
<div class="meta-info">
<span>توسعه‌دهنده: هادی خزاعی اصل</span>
<span>شرکت: فن آوران ساحر علم</span>
<span>تاریخ تدوین: شنبه، ۱۱ مهر ۱۴۰۵</span>
<span>نسخه مستند: 1.0.0</span>
</div>
</div>
<!-- بخش ۱: مقدمه -->
<div class="section">
<h2>۱. مقدمه و هدف</h2>
<p>این مستند با هدف راهنمایی گام‌به‌گام مهندسان و توسعه‌دهندگان برای انتخاب، دانلود و اجرای بهینه‌ترین مدل‌های بینایی-زبانی (Vision-Language) با فرمت GGUF جهت انجام عملیات OCR (بازشناسی نوری کاراکتر) روی اسناد چندزبانه با استفاده از ابزار Ollama تهیه شده است.</p>
</div>
<!-- بخش ۲: معرفی مدل‌ها -->
<div class="section">
<h2>۲. معرفی مدل‌های پیشنهادی</h2>
<p>بر اساس جست‌وجوهای تخصصی در پلتفرم Hugging Face، مدل‌های زیر بهترین عملکرد را برای OCR چندزبانه در قالب GGUF و با سازگاری کامل با Ollama ارائه می‌دهند:</p>
<div class="step">
<h3>گزینه اول (پیشنهاد ویژه): Qwen2.5-VL (نسخه 7B یا 3B)</h3>
<p>مدل Qwen2.5-VL قابلیت‌های OCR خود را به سطح جدیدی ارتقا داده و از پشتیبانی چندزبانه، چندسناریویی و تشخیص متن در جهت‌های مختلف برخوردار است [[34]]. این مدل توسط تیم Qwen در Alibaba Cloud توسعه یافته و سازگاری عالی با Ollama دارد [[30]].</p>
<ul>
<li><strong>حجم و کارایی:</strong> نسخه 3B برای سیستم‌های با منابع محدود و نسخه 7B برای دقت بالاتر در اسناد پیچیده پیشنهاد می‌شود.</li>
<li><strong>پشتیبانی زبانی:</strong> پشتیبانی ذاتی و قدرتمند از فارسی، انگلیسی، عربی، چینی و بیش از 30 زبان دیگر.</li>
</ul>
</div>
<div class="step">
<h3>گزینه دوم: DeepSeek-OCR (نسخه GGUF)</h3>
<p>این مدل به‌طور خاص برای انجام OCR با توکن‌های کارآمد طراحی شده و متن‌های چاپی و دست‌نویس را در زبان‌های اصلی شناسایی می‌کند [[1]]. نسخه GGUF این مدل (مانند <code>NexaAI/DeepSeek-OCR-GGUF</code>) برای استنتاج محلی بهینه‌سازی شده است [[4]].</p>
</div>
<div class="step">
<h3>گزینه سوم: Unlimited-OCR-GGUF</h3>
<p>یک مدل بینایی-زبانی 3 میلیارد پارامتری که بر پایه DeepSeek-OCR ساخته شده و عملکرد آن را در وظایف تخصصی OCR ارتقا می‌دهد [[2]].</p>
</div>
</div>
<!-- بخش ۳: پیش‌نیازها -->
<div class="section">
<h2>۳. پیش‌نیازهای سیستم</h2>
<ul>
<li>نصب بودن آخرین نسخه <strong>Ollama</strong> (نسخه 0.13.0 یا بالاتر برای پشتیبانی بهینه از مدل‌های بینایی پیشنهاد می‌شود) [[41]].</li>
<li>حداقل 8 گیگابایت رم (برای نسخه 3B) یا 16 گیگابایت رم (برای نسخه 7B).</li>
<li>اتصال پایدار به اینترنت برای دانلود اولیه وزن‌های مدل.</li>
</ul>
</div>
<!-- بخش ۴: راهنمای گام‌به‌گام -->
<div class="section">
<h2>۴. راهنمای گام‌به‌گام اجرا</h2>
<div class="step">
<h3>گام ۱: اجرای مستقیم مدل Qwen2.5-VL از طریق Ollama (ساده‌ترین روش)</h3>
<p>ترمینال یا خط فرمان خود را باز کرده و دستور زیر را اجرا کنید. این دستور به‌طور خودکار مدل را دانلود و محیط تعاملی را راه‌اندازی می‌کند:</p>
<pre><code>ollama run qwen2.5vl</code></pre>
<p>برای استفاده از نسخه سبک‌تر و سریع‌تر، می‌توانید از دستور <code>ollama run qwen2.5vl:3b</code> استفاده نمایید.</p>
</div>
<div class="step">
<h3>گام ۲: اجرای مدل‌های GGUF سفارشی از Hugging Face</h3>
<p>اگر می‌خواهید از نسخه‌های خاص کوانتایز شده (مانند <code>unsloth/Qwen2.5-VL-7B-Instruct-GGUF</code>) استفاده کنید، مراحل زیر را دنبال کنید:</p>
<ol>
<li>فایل مدل GGUF مورد نظر (مثلاً با کوانتایزیشن <code>Q4_K_M</code>) را از Hugging Face دانلود کنید.</li>
<li>در همان دایرکتوری، یک فایل متنی با نام <code>Modelfile</code> (بدون پسوند) ایجاد کنید.</li>
<li>محتوای فایل <code>Modelfile</code> را به صورت زیر تنظیم کنید:</li>
</ol>
<pre><code>FROM ./Qwen2.5-VL-7B-Instruct-Q4_K_M.gguf
TEMPLATE """{{ if .System }}&lt;|im_start|&gt;system
{{ .System }}&lt;|im_end|&gt;
{{ end }}&lt;|im_start|&gt;user
{{ .Prompt }}&lt;|im_end|&gt;
&lt;|im_start|&gt;assistant
"""
SYSTEM "شما یک دستیار هوشمند و متخصص در استخراج دقیق متن از تصاویر و اسناد چندزبانه هستید. فقط متن موجود در تصویر را بدون توضیح اضافی بازگردانید."
PARAMETER temperature 0.1
</code></pre>
<ol start="4">
<li>مدل سفارشی را در Ollama بسازید:</li>
</ol>
<pre><code>ollama create qwen2.5vl-ocr-custom -f Modelfile</code></pre>
<ol start="5">
<li>مدل ساخته شده را اجرا کنید:</li>
</ol>
<pre><code>ollama run qwen2.5vl-ocr-custom</code></pre>
</div>
<div class="step">
<h3>گام ۳: نحوه ارسال تصویر برای عملیات OCR</h3>
<p>پس از اجرای مدل در محیط تعاملی Ollama، می‌توانید مسیر محلی تصویر یا سند خود را وارد کرده و درخواست استخراج متن کنید. مثال:</p>
<pre><code>/path/to/your/document.jpg
لطفاً تمام متن موجود در این تصویر را به دقت استخراج کن و به زبان فارسی خروجی بده.</code></pre>
</div>
</div>
<!-- بخش ۵: نکات بهینه‌سازی -->
<div class="section">
<h2>۵. نکات بهینه‌سازی و عیب‌یابی</h2>
<div class="note">
<strong>نکته تخصصی:</strong> برای اسناد چندزبانه که شامل زبان فارسی هستند، مدل‌های سری Qwen-VL به دلیل آموزش گسترده روی داده‌های چندزبانه، عملکرد بسیار بهتری نسبت به مدل‌های اختصاصی OCR قدیمی دارند [[35]].
</div>
<ul>
<li><strong>کاهش مصرف حافظه:</strong> همواره از کوانتایزیشن‌های <code>Q4_K_M</code> یا <code>Q5_K_M</code> استفاده کنید که تعادل عالی بین دقت و سرعت ارائه می‌دهند.</li>
<li><strong>خطای Vision:</strong> اگر مدل تصویر را نخواند، مطمئن شوید که نسخه Ollama شما به‌روز است و از فرمت‌های تصویری استاندارد مانند JPG، PNG یا WebP استفاده می‌کنید.</li>
<li><strong>افزایش دقت خروجی:</strong> پارامتر <code>temperature</code> را در <code>Modelfile</code> روی مقادیر پایین (مانند 0.1 یا 0.2) تنظیم کنید تا مدل خلاقیت کمتر و وفاداری بیشتری به متن اصلی تصویر داشته باشد.</li>
</ul>
</div>
<!-- پاورقی -->
<div class="footer">
<p>تمامی حقوق مادی و معنوی این مستند متعلق به شرکت <strong>فن آوران ساحر علم</strong> می‌باشد.</p>
<p>توسعه و تدوین: <strong>هادی خزاعی اصل</strong> | تاریخ بازنگری: شنبه، ۱۱ مهر ۱۴۰۵</p>
</div>
</div>
</body>
</html>
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,173 @@
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xAiService\Constants\ConfigurationNodeNames.cs
namespace xAiService.Constants
{
public partial struct ConfigurationNodeNames
{
public const string AI_SERVICE_NODE = "AIServiceConfiguration";
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xAiService\Constants\XAiServiceConstants.cs
namespace xAiService.Constants
{
public struct XAiServiceConstants
{
//
// Service Extensions Log Tag ...
public const string XAiServiceDILogTag = "XAiService";
//
// File Provider Identifiers ...
public const string XAiProjectFilesIdentifier = "AiPrjF";
public const string XAiMessageFilesIdentifier = "AiMsgF";
public const string XMetaDataFileIdsIdentifier = "FileIds";
public const string XAiConversationFilesIdentifier = "AiCnvrF";
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xAiService\DI\XDIHelperExtension.cs
namespace xAiService.DI
{
public static partial class XDIHelperExtension
{ }
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xAiService\Extensions\XAiServiceExtensions.cs
using xCommons.Extensions;
using xExceptions.Constants;
using xIdentityModels.Models;
namespace xAiService.Extensions
{
public static class XAiServiceExtensions
{
/// <summary>
/// Validate User Info ...
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
public static bool IsValid(this XUserClaimsInfoDto source)
{
//
var result =
!source.IsNullOrDefault() &&
!source.UserId.IsNullOrEmpty() &&
!source.AccessToken.IsNullOrEmpty();
//
return result;
}
/// <summary>
/// Validate User Info ...
/// </summary>
/// <param name="source"></param>
/// <param name="invalidException"></param>
public static void Validate(
this XUserClaimsInfoDto source,
XException invalidException = XException.InvalidArgs
)
{
//
var isValid = source.IsValid();
if (!isValid)
{
invalidException.Throw();
}
}
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xAiService\Helpers\VectorHelper.cs
using System;
using xCommons.Extensions;
namespace xAiService.Helpers
{
public static class VectorHelper
{
/// <summary>
/// Normalize a Vector ...
/// </summary>
/// <param name="vector"></param>
public static void Normalize(float[] vector)
{
//
// Validate ...
if (vector.IsNull() || !vector.HasChild())
{
return;
}
//
float sum = 0f;
foreach (var value in vector)
{
sum += value * value;
}
//
float norm = MathF.Sqrt(sum);
if (norm <= 1e-9f)
{
return;
}
//
for (int i = 0; i < vector.Length; i++)
{
vector[i] /= norm;
}
}
/// <summary>
/// Similarity Check ...
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static float CosineSimilarity(float[] a, float[] b)
{
//
if (a.IsNull() || b.IsNull())
{
return 0f;
}
//
if (a.Length != b.Length)
{
return 0f;
}
//
float dot = 0f;
float normA = 0f;
float normB = 0f;
for (int i = 0; i < a.Length; i++)
{
//
dot += a[i] * b[i];
normA += a[i] * a[i];
normB += b[i] * b[i];
}
//
float denominator = MathF.Sqrt(normA) * MathF.Sqrt(normB);
if (denominator <= 1e-9f)
{
return 0f;
}
//
var result = dot / denominator;
return result;
}
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,253 @@
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xExceptions\Attributes\StringValueAttribute.cs
using System;
namespace xExceptions.Attributes
{
/// <summary>
/// an attribute which attached to enums to carry propper string
/// </summary>
public partial class StringValueAttribute : Attribute {
public string StringValue { get; set; }
public StringValueAttribute (string value) {
this.StringValue = value;
}
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xExceptions\Constants\XException.cs
using xExceptions.Attributes;
namespace xExceptions.Constants
{
public enum XException {
//
#region Invalid Exceptions 1xx ...
[StringValue ("Invalid Data ...")]
InvalidData = 100,
//
[StringValue ("Invalid Date ...")]
InvalidDate = 101,
//
[StringValue ("Bad Request ...")]
BadRequest = 102,
//
[StringValue ("Invalid Args ...")]
InvalidArgs = 103,
//
[StringValue ("Invalid Message ...")]
InvalidMessage = 104,
//
[StringValue ("Invalid Token ...")]
InvalidToken = 105,
//
[StringValue ("Invalid Verification Code ...")]
InvalidVerificationCode = 106,
//
[StringValue ("Invalid Email Address ...")]
InvalidEmailAddress = 107,
//
[StringValue ("Invalid Mobile Number ...")]
InvalidMobileNumber = 108,
//
[StringValue ("Invalid Password ...")]
InvalidPassword = 109,
//
[StringValue ("Inavlid Url ...")]
InavlidUrl = 110,
//
[StringValue ("Invalid Device ...")]
InvalidDevice = 111,
//
[StringValue ("Invalid Profile Image ...")]
InvalidProfileImage = 112,
//
[StringValue ("Invalid File ...")]
InavlidFile = 113,
//
[StringValue ("Invalid Username ...")]
InvalidUserName = 114,
#endregion
//
#region Not (...) Exceptions 2xx ...
//
[StringValue ("Not Found ...")]
NotFound = 200,
//
[StringValue ("Not Allowed ...")]
NotAllowed = 201,
//
[StringValue ("Not Authorized ...")]
NotAuthorized = 202,
//
[StringValue ("Not Visible ...")]
NotVisible = 203,
#endregion
//
#region User/Registration/Account/Bann Exceptions 3xx ...
//
[StringValue ("Account Locked out Until:{0}")]
AccountLockedOut = 300,
//
[StringValue ("Login Failed ...")]
LoginFailed = 301,
//
[StringValue ("User Registered Before ...")]
UserRegisteredBefore = 302,
//
[StringValue ("User Disabled ...")]
UserDisabled = 303,
//
[StringValue ("Device Banned Until:{0}")]
DeviceBanned = 304,
//
[StringValue ("You can't Request Verification code Until:{0}")]
VerificationCodeResendNotAllowed = 305,
//
[StringValue ("Passwords Same ...")]
PasswordsSame = 306,
//
[StringValue ("Mobiles Same ...")]
MobilesSame = 307,
//
[StringValue ("Emails Same ...")]
EmailsSame = 308,
//
[StringValue ("Mobile In Used ...")]
MobileInUsed = 309,
//
[StringValue ("Email In Used ...")]
EmailInUsed = 310,
//
[StringValue ("Mobile Not Confirmed ...")]
MobileNotConfirmed = 311,
//
[StringValue ("Email Not Confirmed ...")]
EmailNotConfirmed = 312,
//
[StringValue ("Post Banned ...")]
PostBanned = 313,
//
[StringValue ("User Banned ...")]
UserBanned = 314,
#endregion
//
#region General Exceptions 4xx ...
//
[StringValue ("Unknown Error ...")]
Unknown = 400,
//
[StringValue ("Duplicate ...")]
Duplicate = 401,
//
[StringValue ("Action Failed ...")]
ActionFailed = 402,
//
[StringValue ("Expired Date ...")]
ExpiredDate = 403,
//
[StringValue ("Unavailable ...")]
Unavailable = 404,
//
[StringValue ("Max Allowed Tag Exceeded ...")]
MaxAllowedTagExceeded = 405,
//
[StringValue ("Timed out ...")]
Timeout = 406,
#endregion
//
#region File Exceptions 5xx ...
//
[StringValue ("Empty File ...")]
EmptyFile = 500,
//
[StringValue ("max File size exceeded ...")]
MaxFileSizeExceeded = 501,
//
[StringValue ("Unsupported File Type ...")]
UnsupportedFileType = 502,
//
[StringValue ("Max Allowed Media Exceeded ...")]
MaxAllowedMediaExceeded = 503,
#endregion
//
#region Configuration Exceptions 6xx ...
//
[StringValue ("Invalid Configuration ...")]
InvalidConfiguration = 600,
//
[StringValue ("Storage Service Initiallization Failed ...")]
StorageServiceInitialFailed = 601,
//
[StringValue ("Message Service Initialization Failed ...")]
MessageServiceInitialFailed = 602,
#endregion
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xExceptions\Models\XError.cs
namespace xExceptions.Models {
public partial class XError {
/// <summary>
/// th ID of Error
/// </summary>
/// <value></value>
public int Id { get; set; }
/// <summary>
/// the String Value of Error
/// </summary>
/// <value></value>
public string Message { get; set; }
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,607 @@
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xHttpService\Configurations\XHttpServiceConfiguration.cs
namespace xHttpService.Configurations {
public partial class XHttpServiceConfiguration {
/// <summary>
/// Determines Http Handler Check SSL or not ...
/// </summary>
/// <value></value>
public bool DisableSSLCheck { get; set; }
public int DefaultClientTimeout { get; set; } = 360;
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xHttpService\Constants\ConfigurationNodeNames.cs
namespace xHttpService.Constants {
public partial struct ConfigurationNodeNames {
public const string HTTP_SERVICE_NODE_NAME = "HttpServiceConfiguration";
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xHttpService\Constants\XHttpMethod.cs
using xExceptions.Attributes;
namespace xHttpService.Constants {
public enum XHttpMethod {
[StringValue ("GET")]
GET,
[StringValue ("POST")]
POST,
[StringValue ("PUT")]
PUT,
[StringValue ("DELETE")]
DELETE
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xHttpService\DI\XDIHelperExtension.cs
using System;
using xCommons.Extensions;
using xHttpService.Constants;
using xHttpService.Providers;
using xHttpService.Interfaces;
using xHttpService.Configurations;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace xHttpService.DI {
public static partial class XDIHelperExtension {
/// <summary>
/// Retrieve XHttpService Configuration from AppSettings
/// </summary>
/// <param name="configuration"></param>
/// <returns></returns>
public static XHttpServiceConfiguration GetXHttpServiceConfiguration (this IConfiguration configuration) {
//
var xHttpSection = configuration.GetSection (ConfigurationNodeNames.HTTP_SERVICE_NODE_NAME);
return xHttpSection.Get<XHttpServiceConfiguration> ();
}
/// <summary>
/// Register XHttpService Configuration
/// </summary>
/// <param name="services"></param>
/// <param name="configuration"></param>
public static void AddXHttpServiceConfiguration (
this IServiceCollection services,
IConfiguration configuration
) {
//
var httpServiceConfiguration = configuration.GetXHttpServiceConfiguration ();
services.AddXHttpServiceConfiguration(httpServiceConfiguration);
}
/// <summary>
/// Register XHttpService Configuration
/// </summary>
/// <param name="services"></param>
/// <param name="configuration"></param>
public static void AddXHttpServiceConfiguration (
this IServiceCollection services,
XHttpServiceConfiguration configuration
) {
//
if (configuration.IsNull ()) {
Console.WriteLine($"xHttpService: there is no provided configurations, using default ...");
configuration = new XHttpServiceConfiguration ();
}
//
services.AddSingleton<XHttpServiceConfiguration> (configuration);
}
/// <summary>
/// Register XHttpService on DI ...
/// </summary>
/// <param name="services"></param>
/// <param name="configuration"></param>
public static void AddXHttpService (
this IServiceCollection services,
IConfiguration configuration
) {
//
// Register Service Configuration ...
if (services.GetRegisteredService<XHttpServiceConfiguration> ().IsNull ()) {
services.AddXHttpServiceConfiguration (configuration);
}
//
// Register Service ...
services.AddSingleton<IXHttpProvider, XHttpProvider> ();
}
/// <summary>
/// Register XHttpService on DI ...
/// </summary>
/// <param name="services"></param>
/// <param name="configuration"></param>
public static void AddXHttpService (
this IServiceCollection services,
XHttpServiceConfiguration configuration
) {
//
// Register Service Configuration ...
if (services.GetRegisteredService<XHttpServiceConfiguration> ().IsNull ()) {
services.AddXHttpServiceConfiguration (configuration);
}
//
// Register Service ...
services.AddSingleton<IXHttpProvider, XHttpProvider> ();
}
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xHttpService\Extensions\RestSharpExtensions.cs
using RestSharp;
using xModels.Dtos;
using xCommons.Constants;
using xCommons.Extensions;
namespace xHttpService.Extensions
{
public static partial class RestSharpExtensions
{
/// <summary>
/// Attach an instance of XQuery to a RestRequest object
/// </summary>
/// <param name="source"></param>
/// <param name="query"></param>
/// <returns></returns>
public static RestRequest AttachXQuery(
this RestRequest source,
XQuery query
)
{
//
if (query.IsNull())
{
return source;
}
//
// ContainsDetail ...
//
var containsDetailKey = System.Uri.EscapeDataString(nameof(query.ContainsDetail));
var containsDetailValue = query.ContainsDetail.AsHttpParamString();
source.AddQueryParameter(containsDetailKey, containsDetailValue);
//
// IsAscending ...
var isAscendingKey = System.Uri.EscapeDataString(nameof(query.IsAscending));
var isAscendingValue = query.IsAscending.AsHttpParamString();
source.AddQueryParameter(isAscendingKey, isAscendingValue);
//
// Filter ...
if (!query.Filter.IsNullOrEmpty())
{
//
var key = System.Uri.EscapeDataString(nameof(query.Filter));
var value = query.Filter.AsHttpParamString();
source.AddQueryParameter(key, value);
}
//
// SortBy ...
if (!query.SortBy.IsNullOrEmpty())
{
//
var key = System.Uri.EscapeDataString(nameof(query.SortBy));
var value = query.SortBy.AsHttpParamString();
source.AddQueryParameter(key, value);
}
//
// Page ...
if (query.Page > 0)
{
//
var key = System.Uri.EscapeDataString(nameof(query.Page));
var value = query.Page.AsHttpParamString();
source.AddQueryParameter(key, value);
}
//
// PageSize ...
if (query.PageSize > 0)
{
//
var key = System.Uri.EscapeDataString(nameof(query.PageSize));
var value = query.PageSize.AsHttpParamString();
source.AddQueryParameter(key, value);
}
//
return source;
}
/// <summary>
/// Add Dest User to Query Strings ...
/// </summary>
/// <param name="source"></param>
/// <param name="destUser"></param>
/// <returns></returns>
public static RestRequest AttachDestUser(
this RestRequest source,
string destUser
)
{
//
if (destUser.IsNullOrEmpty())
{
return source;
}
//
var destUserKey = System.Uri.EscapeDataString(nameof(destUser));
var destUserValue = destUser.AsHttpParamString();
source.AddQueryParameter(destUserKey, destUserValue);
//
return source;
}
/// <summary>
/// Add XPoweredBy Header to specific RestRequest Headers ...
/// </summary>
/// <param name="source"></param>
/// <param name="poweredByValue"></param>
/// <returns></returns>
public static RestRequest AddXPoweredBy(
this RestRequest source,
string poweredByValue
)
{
//
source.AddHeader(
XAuthorization.XPoweredBy,
poweredByValue
);
//
return source;
}
/// <summary>
/// Add XAccessToken Header to specific RestRequest Headers ...
/// </summary>
/// <param name="source"></param>
/// <param name="poweredByValue"></param>
/// <returns></returns>
public static RestRequest AddXAccessToken(
this RestRequest source,
string token
)
{
//
token = $"{XAuthentication.BEARER} {token}";
//
source.AddHeader(
XAuthorization.Header,
token
);
//
return source;
}
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xHttpService\Interfaces\IXHttpProvider.cs
using RestSharp;
using System.Net.Http;
using System.Threading.Tasks;
using xHttpService.Constants;
using xIdentityModels.Models;
using System.Collections.Generic;
namespace xHttpService.Interfaces {
public partial interface IXHttpProvider {
HttpClient GetHttpClient ();
RestClient GetRestClient (
string baseUrl = null,
string poweredByValue = null,
XTokenResponse tokens = null
);
RestRequest GetRestRequet (
string endpoint,
IDictionary<string, string> @params = null,
IDictionary<string, string> headers = null,
IDictionary<string, string> queryStrings = null
);
Task<T> RunRestRequest<T> (
RestClient client,
RestRequest request,
XHttpMethod method
);
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xHttpService\Providers\XHttpProvider.cs
using System;
using RestSharp;
using xModels.Base;
using System.Net.Http;
using xCommons.Constants;
using xCommons.Extensions;
using xExceptions.Constants;
using System.Threading.Tasks;
using xHttpService.Constants;
using xIdentityModels.Models;
using xHttpService.Interfaces;
using RestSharp.Authenticators;
using System.Collections.Generic;
using xHttpService.Configurations;
using Microsoft.Extensions.Logging;
namespace xHttpService.Providers {
public partial class XHttpProvider : XBaseClass, IXHttpProvider {
private readonly XHttpServiceConfiguration configuration;
public XHttpProvider (
ILoggerFactory loggerFactory,
XHttpServiceConfiguration configuration
) : base (loggerFactory) {
this.configuration = configuration;
}
//
#region Actions ...
/// <summary>
/// Get an Instance of Http Client
/// </summary>
/// <returns></returns>
public HttpClient GetHttpClient () {
//
HttpClient httpClient = null;
httpClient = new HttpClient ();
//
if (configuration.DisableSSLCheck) {
//
var httpHandler = new HttpClientHandler ();
httpHandler.ServerCertificateCustomValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
//
httpClient = new HttpClient (httpHandler);
}
//
// Set Timeout ...
httpClient.Timeout = TimeSpan
.FromSeconds (configuration.DefaultClientTimeout);
//
return httpClient;
}
/// <summary>
/// Get an Instance of RestClient
/// </summary>
/// <param name="baseUrl"></param>
/// <param name="poweredByValue"></param>
/// <param name="tokens"></param>
/// <returns></returns>
public RestClient GetRestClient (
string baseUrl = null,
string poweredByValue = null,
XTokenResponse tokens = null
) {
//
var client = new RestClient (baseUrl);
//
// Add XPowered By to Default Headers ...
if (!poweredByValue.IsNullOrEmpty ()) {
client.AddDefaultHeader (XAuthorization.XPoweredBy, poweredByValue);
}
//
// Set Authenticator ...
if (!tokens.IsNull () &&
!tokens.AccessToken.IsNullOrEmpty ()) {
client.Authenticator = new JwtAuthenticator (tokens.AccessToken);
}
//
// Refresh Token ...
if (!tokens.IsNull () &&
!tokens.RefreshToken.IsNullOrEmpty ()) {
client.AddDefaultHeader (XAuthorization.RefreshToken, tokens.RefreshToken);
}
//
// ExpiresAt ...
if (!tokens.IsNull () &&
tokens.ExpiresAt > 0) {
client.AddDefaultHeader (XAuthorization.ExpiresAt, tokens.ExpiresAt.AsHttpParamString ());
}
//
// Set Default Timeout ...
client.Timeout = configuration.DefaultClientTimeout;
//
// SSL Validation Handler ...
if (configuration.DisableSSLCheck) {
client.RemoteCertificateValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;
}
//
return client;
}
/// <summary>
/// Get an Instance of RestRequest
/// </summary>
/// <param name="endpoint"></param>
/// <param name="params"></param>
/// <param name="headers"></param>
/// <param name="queryStrings"></param>
/// <returns></returns>
public RestRequest GetRestRequet (
string endpoint,
IDictionary<string, string> @params = null,
IDictionary<string, string> headers = null,
IDictionary<string, string> queryStrings = null
) {
//
var url = endpoint.ToString ();
//
// Add Route Payloads ...
if (!@params.IsNull () && @params.Count > 0) {
//
var enumerator = @params.GetEnumerator ();
while (enumerator.MoveNext ()) {
//
var item = enumerator.Current;
//
url = url.Replace (item.Key, item.Value.ToUrlEncoded ());
}
}
//
// Add Query Strings ...
if (!queryStrings.IsNull () && queryStrings.Count > 0) {
//
url = $"{url}?";
var enumerator = queryStrings.GetEnumerator ();
while (enumerator.MoveNext ()) {
//
var item = enumerator.Current;
//
url += $"{item.Key}={item.Value.ToUrlEncoded ()}&";
}
//
// remove lates & ...
if (url.EndsWith ("&")) {
url = url.Substring (0, url.Length - 1);
}
}
//
// Create request ...
var request = new RestRequest (url, DataFormat.Json);
//
// Add Headers to request ...
if (!headers.IsNull () && headers.Count > 0) {
//
var enumerator = headers.GetEnumerator ();
while (enumerator.MoveNext ()) {
//
var item = enumerator.Current;
request.AddHeader (item.Key, item.Value);
}
}
//
return request;
}
/// <summary>
/// Handle Call Specific Request and retrieve Response
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="method"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public async Task<T> RunRestRequest<T> (
RestClient client,
RestRequest request,
XHttpMethod method
) {
//
var response = await Task.Run (() => {
//
IRestResponse resp = null;
//
// Call Endpoint Service using Specified Method ...
switch (method) {
//
// Get ...
case XHttpMethod.GET:
resp = client.Get (request);
break;
//
// Put ...
case XHttpMethod.PUT:
resp = client.Put (request);
break;
//
// Post ...
case XHttpMethod.POST:
resp = client.Post (request);
break;
//
// Delete ...
case XHttpMethod.DELETE:
resp = client.Delete (request);
break;
}
//
if (!resp.IsSuccessful) {
//
// UnAuthorized ...
if (resp.StatusCode == System.Net.HttpStatusCode.Unauthorized) {
XException.NotAuthorized.Throw ();
}
//
// NotFound ...
if (resp.StatusCode == System.Net.HttpStatusCode.NotFound) {
XException.NotFound.Throw ();
}
//
// Timeout ...
if (!resp.ErrorMessage.IsNullOrEmpty () &&
resp.ErrorMessage.Contains ("timed out")) {
XException.Timeout.Throw ();
}
//
// ErrorMessage ...
if (!resp.ErrorMessage.IsNullOrEmpty ()) {
throw new Exception (resp.ErrorMessage);
}
//
// Default Exception ...
XException.BadRequest.Throw ();
}
//
var result = resp.Content.FromJSON<T> ();
return result;
});
//
return response;
}
#endregion
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,727 @@
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xMessageService\Constants\ConfigurationNodeNames.cs
namespace xMessageService.Constants {
public partial struct ConfigurationNodeNames {
public const string MESSAGE_NODE_NAME = "MessageConfiguration";
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xMessageService\Constants\xMessageServiceConstants.cs
namespace xMessageService.Constants {
public struct xMessageServiceConstants {
public const string DEFAULT_EMPTY_PROVIDER = "EMPTY";
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xMessageService\DI\XDIHelperExtension.cs
using System;
using System.Linq;
using xCommons.Extensions;
using xMessageService.Models;
using xMessageService.Constants;
using xMessageService.Providers;
using System.Collections.Generic;
using xMessageService.Interfaces;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace xMessageService.DI {
public static partial class XDIHelperExtension {
/// <summary>
/// Retrieve XMessage Configuration from App Settings
/// </summary>
/// <param name="config"></param>
/// <returns></returns>
public static XMessageConfiguration GetXMessageConfiguration (this IConfiguration config) {
//
var xMessageConfigSection = config.GetSection (ConfigurationNodeNames.MESSAGE_NODE_NAME);
var xMessageConfiguration = xMessageConfigSection.Get<XMessageConfiguration> ();
//
var defaultMailConfiguration = new Dictionary<string, XMailConfiguration> {
["EMPTY"] =
new XMailConfiguration {
Title = xMessageServiceConstants.DEFAULT_EMPTY_PROVIDER,
Host = "",
Port = 25,
EnableSsl = false,
Username = "",
Password = ""
}
};
//
var defaultSmsConfiguration = new Dictionary<string, XSmsConfiguration> {
["EMPTY"] =
new XSmsConfiguration {
ServiceUrl = "",
Username = "",
Password = "",
LineNumber = "",
UserApiKey = "",
SecretKey = "",
}
};
//
if (xMessageConfiguration.IsNull ()) {
//
xMessageConfiguration = new XMessageConfiguration {
DefaultSMSProvider = xMessageServiceConstants.DEFAULT_EMPTY_PROVIDER,
DefaultMailProvider = xMessageServiceConstants.DEFAULT_EMPTY_PROVIDER,
MailConfigurations = defaultMailConfiguration,
SmsConfigurations = defaultSmsConfiguration
};
//
// Warn Message is Default Configuration ...
Console.WriteLine ($"IMPORTANT: xMessageService Configuration is Default, so the Service can't works properly ...");
}
//
// Handle Default Mail Provider ...
if (xMessageConfiguration.DefaultMailProvider.IsNullOrEmpty ()) {
//
if (xMessageConfiguration.IsNull () ||
//
xMessageConfiguration.MailConfigurations.IsNull () ||
xMessageConfiguration.MailConfigurations.Count == 0) {
//
Console.WriteLine ("There is no defined Mail Provider Configurations ...");
xMessageConfiguration.DefaultMailProvider = xMessageServiceConstants.DEFAULT_EMPTY_PROVIDER;
}
//
if (xMessageConfiguration.DefaultMailProvider == xMessageServiceConstants.DEFAULT_EMPTY_PROVIDER) {
xMessageConfiguration.MailConfigurations = defaultMailConfiguration;
} else {
xMessageConfiguration.DefaultMailProvider = xMessageConfiguration.MailConfigurations.Keys.First ();
}
}
//
// Handle Default SMS Provider ...
if (xMessageConfiguration.DefaultSMSProvider.IsNullOrEmpty ()) {
//
if (xMessageConfiguration.IsNull () ||
xMessageConfiguration.SmsConfigurations.IsNull () ||
xMessageConfiguration.SmsConfigurations.Count == 0) {
//
Console.WriteLine ("There is no defined SMS Provider Configurations ...");
xMessageConfiguration.DefaultSMSProvider = xMessageServiceConstants.DEFAULT_EMPTY_PROVIDER;
}
//
if (xMessageConfiguration.DefaultSMSProvider == xMessageServiceConstants.DEFAULT_EMPTY_PROVIDER) {
xMessageConfiguration.SmsConfigurations = defaultSmsConfiguration;
} else {
xMessageConfiguration.DefaultSMSProvider = xMessageConfiguration.SmsConfigurations.Keys.First ();
}
}
//
return xMessageConfiguration;
}
/// <summary>
/// Register XMessage Service
/// </summary>
/// <param name="services"></param>
/// <param name="config"></param>
public static void AddXMessageService (this IServiceCollection services, IConfiguration config) {
//
var xMessageConfiguration = config.GetXMessageConfiguration ();
services.AddSingleton<XMessageConfiguration> (xMessageConfiguration);
//
// Register SMS Service ...
var xSmsService = new XSmsService (
xMessageConfiguration.DefaultSMSProvider,
xMessageConfiguration.SmsConfigurations
);
services.AddSingleton<IXSmsService> (xSmsService);
//
// Register Mail Service ...
var xMailService = new XMailService (
xMessageConfiguration.DefaultMailProvider,
xMessageConfiguration.MailConfigurations
);
services.AddSingleton<IXMailService> (xMailService);
//
// Register MEssage Provider ...
services.AddSingleton<IXMessageProvider, XMessageProvider> ();
}
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xMessageService\Interfaces\IXMailService.cs
using System.Threading.Tasks;
using xMessageService.Models;
namespace xMessageService.Interfaces {
public partial interface IXMailService {
Task SendMailAsync (
XMessage message,
string provider = null
);
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xMessageService\Interfaces\IXMessageProvider.cs
using System;
using System.Threading.Tasks;
using xMessageService.Models;
namespace xMessageService.Interfaces {
public partial interface IXMessageProvider {
bool IsReady (
bool? checkMailService = false,
bool? checkSmsService = false
);
Task SendMailAsync (
XMessage message,
string provider = null,
bool throwException = true,
Exception exception = null
);
Task SendSmsAsync (
XMessage message,
string provider = null,
bool throwException = true,
Exception exception = null
);
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xMessageService\Interfaces\IXSmsService.cs
using System.Threading.Tasks;
using xMessageService.Models;
namespace xMessageService.Interfaces {
public partial interface IXSmsService {
Task SendSmsAsync (
XMessage message,
string provider = null
);
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xMessageService\Models\XMailConfiguration.cs
namespace xMessageService.Models {
public partial class XMailConfiguration {
public string Title { get; set; }
public string Host { get; set; }
public int Port { get; set; }
public bool EnableSsl { get; set; }
public string Username { get; set; }
public string Password { get; set; }
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xMessageService\Models\XMessage.cs
using xModels.Base;
using System.Collections.Generic;
namespace xMessageService.Models {
public partial class XMessage : XBaseDto {
public HashSet<string> Recievers { get; set; } = new HashSet<string> ();
public string Message { get; set; }
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xMessageService\Models\XMessageConfiguration.cs
using System.Collections.Generic;
namespace xMessageService.Models {
public partial class XMessageConfiguration {
public string DefaultSMSProvider { get; set; }
public string DefaultMailProvider { get; set; }
public IDictionary<string, XMailConfiguration> MailConfigurations { get; set; }
public IDictionary<string, XSmsConfiguration> SmsConfigurations { get; set; }
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xMessageService\Models\XSmsConfiguration.cs
namespace xMessageService.Models {
public partial class XSmsConfiguration {
public string ServiceUrl { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string LineNumber { get; set; }
public string UserApiKey { get; set; }
public string SecretKey { get; set; }
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xMessageService\Providers\XMailService.cs
using System;
using System.Net;
using System.Net.Mail;
using xCommons.Extensions;
using xExceptions.Constants;
using System.Threading.Tasks;
using xMessageService.Models;
using System.Collections.Generic;
using xMessageService.Interfaces;
namespace xMessageService.Providers {
public partial class XMailService : IXMailService {
private SmtpClient smtpClient;
private readonly string defaultProvider;
private readonly IDictionary<string, XMailConfiguration> configurations;
public XMailService (
string defaultProvider,
IDictionary<string, XMailConfiguration> configurations
) {
this.defaultProvider = defaultProvider;
this.configurations = configurations;
//
// Get instance of SMTP Client ...
PrepareSmtpClient ();
}
public Task SendMailAsync (
XMessage message,
string provider = null
) {
//
// Run Send Mail Asynchronous ...
return Task.Run (() => {
SendMail (message, provider);
});
}
#region Private ...
/// <summary>
/// Validate and Retrieve Provider Configuration for Service
/// </summary>
/// <param name="provider"></param>
/// <returns></returns>
private XMailConfiguration GetConfiguration (string provider = null) {
//
if (provider.IsNullOrEmpty ()) {
provider = defaultProvider;
}
//
if (!configurations.Keys.Contains (provider)) {
XException.MessageServiceInitialFailed.Throw ();
}
//
return configurations[provider];
}
/// <summary>
/// Prepare SMTP Client by Using Specified/Default Provider
/// </summary>
/// <param name="provider"></param>
private void PrepareSmtpClient (string provider = null) {
//
var config = GetConfiguration (provider);
if (config.IsNull()) {
return;
}
//
smtpClient = new SmtpClient () {
Host = config.Host,
Port = config.Port,
EnableSsl = config.EnableSsl,
UseDefaultCredentials = false,
Credentials = new NetworkCredential (
config.Username,
config.Password)
};
}
/// <summary>
/// Prepare Mail Message With Specified/Default Provider
/// </summary>
/// <param name="message"></param>
/// <param name="provider"></param>
/// <returns></returns>
private MailMessage PrepareMailMessage (
XMessage message,
string provider = null
) {
//
if (message == null ||
message.Message.IsNullOrEmpty () ||
message.Recievers.Count == 0) {
XException.InvalidMessage.Throw ();
}
//
var config = GetConfiguration (provider);
var mailMessage = new MailMessage () {
From = new MailAddress (config.Username),
Subject = config.Title,
Body = message.Message
};
//
foreach (var reciever in message.Recievers) {
mailMessage.To.Add (reciever);
}
//
return mailMessage;
}
/// <summary>
/// Send Mail Using Specified/Default Provider
/// </summary>
/// <param name="message"></param>
/// <param name="provider"></param>
private void SendMail (
XMessage message,
string provider = null
) {
//
if (smtpClient.IsNull()) {
//
Console.WriteLine ($"SMTP Error: MessageServiceInitialFailed ...");
XException.MessageServiceInitialFailed.Throw ();
}
//
var mailMessage = PrepareMailMessage (message, provider);
//
try {
smtpClient.Send (mailMessage);
} catch (Exception ex) {
//
Console.WriteLine ($"SMTP Error: {ex.Message}");
XException.MessageServiceInitialFailed.Throw ();
}
}
#endregion
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xMessageService\Providers\XMessageProvider.cs
using System;
using xCommons.Extensions;
using xExceptions.Constants;
using System.Threading.Tasks;
using xMessageService.Models;
using xMessageService.Interfaces;
using Microsoft.Extensions.Logging;
namespace xMessageService.Providers {
public partial class XMessageProvider : IXMessageProvider {
private readonly XMessageConfiguration configuration;
private readonly ILogger<XMessageProvider> logger;
private readonly IXSmsService smsService;
private readonly IXMailService mailService;
public XMessageProvider (
XMessageConfiguration configuration,
ILogger<XMessageProvider> logger,
IXSmsService smsService,
IXMailService mailService
) {
this.configuration = configuration;
this.logger = logger;
this.smsService = smsService;
this.mailService = mailService;
}
/// <summary>
/// Send a Mail Message
/// </summary>
/// <param name="message"></param>
/// <param name="provider"></param>
/// <param name="throwException"></param>
/// <param name="exception"></param>
/// <returns></returns>
public async Task SendMailAsync (
XMessage message,
string provider = null,
bool throwException = true,
Exception exception = null
) {
//
if (exception.IsNull ()) {
exception = XException.ActionFailed.ToException ();
}
//
try {
await mailService.SendMailAsync (message, provider);
} catch (Exception ex) {
//
logger.LogError ($"Exeption: {ex.Message}");
//
if (throwException) {
throw exception;
}
}
}
/// <summary>
/// Send SMS Message
/// </summary>
/// <param name="message"></param>
/// <param name="provider"></param>
/// <param name="throwException"></param>
/// <param name="exception"></param>
/// <returns></returns>
public async Task SendSmsAsync (
XMessage message,
string provider = null,
bool throwException = true,
Exception exception = null
) {
//
if (exception.IsNull ()) {
exception = XException.ActionFailed.ToException ();
}
//
try {
await smsService.SendSmsAsync (message, provider);
} catch {
if (throwException) {
throw exception;
}
}
}
/// <summary>
/// Check Message Provider is Ready or not
/// </summary>
/// <param name="checkMailService"></param>
/// <param name="checkSmsService"></param>
/// <returns></returns>
public bool IsReady (
bool? checkMailService = false,
bool? checkSmsService = false
) {
//
var result = true;
//
// Check Mail Service ...
if (checkMailService.HasValue &&
checkMailService.GetValueOrDefault ()) {
result = result && mailService != null;
}
//
// Check Sms Service ...
if (checkSmsService.HasValue &&
checkSmsService.GetValueOrDefault ()) {
result = result && smsService != null;
}
//
return result;
}
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xMessageService\Providers\XSmsService.cs
using System;
using RestSharp;
using PhoneNumbers;
using xCommons.Extensions;
using xExceptions.Constants;
using System.Threading.Tasks;
using xMessageService.Models;
using System.Collections.Generic;
using xMessageService.Interfaces;
namespace xMessageService.Providers {
public partial class XSmsService : IXSmsService {
private string serviceUrl;
private readonly string defaultProvider;
private readonly IDictionary<string, XSmsConfiguration> configurations;
public XSmsService (
string defaultProvider,
IDictionary<string, XSmsConfiguration> configurations
) {
this.defaultProvider = defaultProvider;
this.configurations = configurations;
//
PrepareServiceUrl ();
}
public Task SendSmsAsync (
XMessage message,
string provider = null
) {
//
// Run Send SMS Asynchronous ...
return Task.Run (() => {
SendSMS (message, provider);
});
}
#region Private ...
/// <summary>
/// Prepare Service Url for Specified/Default Provider
/// </summary>
/// <param name="provider"></param>
private void PrepareServiceUrl (string provider = null) {
//
if (provider.IsNullOrEmpty ()) {
provider = defaultProvider;
}
//
var config = GetConfiguration (provider);
if (config.IsNull ()) {
return;
}
//
serviceUrl = config.ServiceUrl;
serviceUrl += "&username=" + config.Username + "&password=" + config.Password + "&";
}
/// <summary>
/// Prepare Service url for Integrating XMessage by
/// using Specified/Default Provider Configurations
/// </summary>
/// <param name="message"></param>
/// <param name="provider"></param>
private void PrepareSmsMessage (
XMessage message,
string provider = null
) {
//
if (message == null ||
message.Message.IsNullOrEmpty () ||
message.Recievers.Count == 0) {
XException.InvalidMessage.Throw ();
}
//
// Validating Mobile Numbers ...
var phoneNumberUtil = PhoneNumbers.PhoneNumberUtil.GetInstance ();
var recieversList = "";
//
PrepareServiceUrl (provider);
//
foreach (var reciever in message.Recievers) {
try {
//
var mPhoneNumber = phoneNumberUtil.Parse (reciever, null);
if (phoneNumberUtil.IsValidNumber (mPhoneNumber)) {
//
// Format Phone Numbers to the '+989120000000' pattern ...
var recieverPhone = phoneNumberUtil.Format (mPhoneNumber, PhoneNumberFormat.E164);
if (recieversList.Length > 0) {
recieversList += ",";
}
recieversList += reciever;
}
} catch { }
}
//
var config = GetConfiguration ();
//
// Preparing All Content and Configurations for Sending Messages ...
serviceUrl += "to=" +
recieversList +
"&message=" +
message.Message +
"&from=" +
config.LineNumber +
"&flash=" +
false;
}
/// <summary>
/// Send a Message as SMS by Specified/Default Provider
/// </summary>
/// <param name="message"></param>
/// <param name="provider"></param>
private void SendSMS (
XMessage message,
string provider = null
) {
//
if (serviceUrl.IsNullOrEmpty ()) {
//
Console.WriteLine ($"SMS Error: MessageServiceInitialFailed ...");
XException.MessageServiceInitialFailed.Throw ();
}
//
try {
//
// preparing Service Url based on message data ...
PrepareSmsMessage (message, provider);
//
// Implementing Service Calling Using RestSharp Library ...
// We Select RestSharp because it supports Sync/Async Calls ...
var client = new RestClient (serviceUrl);
var request = new RestRequest (Method.POST);
//
// Send Request ...
var response = client.Execute (request);
} catch (Exception ex) {
Console.WriteLine ($"SMS Error: {ex.Message}");
XException.MessageServiceInitialFailed.Throw ();
}
}
/// <summary>
/// Validate and Retrieve Provider Configuration for Service
/// </summary>
/// <param name="provider"></param>
/// <returns></returns>
private XSmsConfiguration GetConfiguration (string provider = null) {
//
if (
provider.IsNullOrEmpty () ||
provider.ToNormalString () == "empty"
) {
//
provider = defaultProvider;
return null;
}
//
if (!configurations.Keys.Contains (provider)) {
XException.MessageServiceInitialFailed.Throw ();
}
//
return configurations[provider];
}
#endregion
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,574 @@
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xTermsAndConditionsService\Configurations\XTermsAndConditionsServiceConfiguration.cs
using xDataService.Constants;
using System.Collections.Generic;
using xStringService.Models.Dtos;
namespace xTermsAndConditionsService.Configurations
{
/// <summary>
/// Terms and Conditions Configuration ...
/// </summary>
public class XTermsAndConditionsServiceConfiguration
{
/// <summary>
/// Terms And Conditions Resource Title in XString Table ...
/// </summary>
public string ResourceTitle { get; set; } = "terms_and_conditions";
/// <summary>
/// Seeding Mode for Terms and Conditions ...
/// </summary>
public XDbSeedingMode SeedingMode { get; set; } = XDbSeedingMode.AddIfNotExists;
/// <summary>
/// Default Terms and Conditions for Add to Databse on App Startup ...
/// </summary>
public List<XStringDto> TermsAndConditions { get; set; } = null;
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xTermsAndConditionsService\Constants\ConfigurationNodeNames.cs
namespace xTermsAndConditionsService.Constants
{
public partial struct ConfigurationNodeNames
{
public const string TERMS_AND_CONDITIONS_SERVICE_NODE = "TermsAndConditionsService";
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xTermsAndConditionsService\Constants\XTermsAndConditionsServiceConstants.cs
namespace xTermsAndConditionsService.Constants
{
public struct XTermsAndConditionsServiceConstants
{
//
// Service Extensions Log Tag ...
public const string XTermsAndConditionsServiceDILogTag = "XTermsAndConditionsService";
//
// Table Mapping Identifiers ...
//
// GraphQL Collection Mappings ...
//
// Hubs ...
//
// Custome Constants ...
//
// EF Repositories Helper Extensions ...
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xTermsAndConditionsService\Controllers\XTermsAndConditionsControllerBase.cs
using xCommons.Providers;
using xCommons.Configurations;
using xStringService.Controllers;
using xIdentityService.Interfaces;
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Authorization;
using xTermsAndConditionsService.Interfaces;
namespace xTermsAndConditionsService.Controllers
{
/// <summary>
/// a Base Controller Implementation for Providing Base Actions of
/// Terms and Conditions Provided Actions ...
/// </summary>
[AllowAnonymous]
public abstract class XTermsAndConditionsControllerBase : XBaseResourceProviderControllerBase<IXTermsAndConditionsProvider>, IXTermsAndConditionsController
{
protected XTermsAndConditionsControllerBase(
ILogger<XTermsAndConditionsControllerBase> logger,
XAppConfiguration appConfiguration,
IXIdentityProvider identityProvider,
XValidationProvider validationProvider,
IXTermsAndConditionsProvider provider
) : base(
logger,
appConfiguration,
identityProvider,
validationProvider,
provider
)
{ }
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xTermsAndConditionsService\DI\XDIHelperExtension.cs
using System;
using System.Linq;
using xPushService.DI;
using xCommons.Extensions;
using xPushService.Helpers;
using xExceptions.Constants;
using xCommons.Configurations;
using Microsoft.AspNetCore.Builder;
using xStringService.Interfaces.Dtos;
using xTermsAndConditionsService.Hubs;
using Microsoft.Extensions.Configuration;
using xTermsAndConditionsService.Constants;
using xTermsAndConditionsService.Providers;
using xTermsAndConditionsService.Interfaces;
using Microsoft.Extensions.DependencyInjection;
using xTermsAndConditionsService.Configurations;
namespace xTermsAndConditionsService.DI
{
public static class XDIHelperExtension
{
/// <summary>
/// Retrieve xTermsAndConditionsService Configuration from AppSettings ...
/// </summary>
/// <param name="configuration"></param>
/// <returns></returns>
public static XTermsAndConditionsServiceConfiguration GetXTermsAndConditionsServiceConfiguration(
this IConfiguration configuration
)
{
//
var section = configuration.GetSection(ConfigurationNodeNames.TERMS_AND_CONDITIONS_SERVICE_NODE);
var result = section.Get<XTermsAndConditionsServiceConfiguration>();
//
return result;
}
/// <summary>
/// Extract xTermsAndConditionsService Configurations from AppSettings
/// and Register it in DI ...
/// </summary>
/// <param name="services"></param>
/// <param name="configuration"></param>
public static void AddXTermsAndConditionsConfiguration(
this IServiceCollection services,
IConfiguration configuration
)
{
//
var serviceConfiguration = configuration.GetXTermsAndConditionsServiceConfiguration();
services.AddXTermsAndConditionsConfiguration(serviceConfiguration);
}
/// <summary>
/// Register xTermsAndConditionsService Configurations in DI ...
/// </summary>
/// <param name="services"></param>
/// <param name="configuration"></param>
public static void AddXTermsAndConditionsConfiguration(
this IServiceCollection services,
XTermsAndConditionsServiceConfiguration configuration
)
{
//
if (configuration.IsNull())
{
Log($"there is no provided configurations, using default ...");
configuration = new XTermsAndConditionsServiceConfiguration();
}
//
services.AddSingleton(configuration);
}
/// <summary>
/// Register TermsConditions Provider ...
/// </summary>
/// <param name="services"></param>
/// <param name="configuration">provided AppSettings Configuration</param>
/// <param name="lifeTime"></param>
public static void AddXTermsConditionsService(
this IServiceCollection services,
IConfiguration configuration,
ServiceLifetime lifeTime = ServiceLifetime.Transient
)
{
//
AddTermsAndConditionsService(
services: services,
lifeTime: lifeTime,
configuration: configuration
);
}
/// <summary>
/// Register TermsConditions Provider ...
/// </summary>
/// <param name="services"></param>
/// <param name="configuration">provided xTermsAndConditionsService Configuration</param>
/// <param name="lifeTime"></param>
public static void AddXTermsConditionsService(
this IServiceCollection services,
XTermsAndConditionsServiceConfiguration configuration,
ServiceLifetime lifeTime = ServiceLifetime.Transient
)
{
//
AddTermsAndConditionsService(
services: services,
lifeTime: lifeTime,
serviceConfiguration: configuration
);
}
public static void UseXTermsAndConditionsService(
this IApplicationBuilder app
)
{
//
// Create an Scope for Services Acess ...
using (var scope = app.ApplicationServices.CreateScope())
{
//
// Inject Requirements ...
var stringProvider = scope.ServiceProvider.GetService<IXStringServiceProvider>();
var serviceConfiguration = scope.ServiceProvider.GetService<XTermsAndConditionsServiceConfiguration>();
//
// Using XTerms Hub ...
var pushHelper = new XPushServiceHelper();
pushHelper.AddHub<XTermsHub>("terms");
app.UseXPushService(pushHelper);
//
// Validate Requirements Exists ...
var isValid =
!stringProvider.IsNull() &&
!serviceConfiguration.IsNull() &&
!serviceConfiguration.TermsAndConditions.IsNull() &&
serviceConfiguration.TermsAndConditions.HasChild() &&
serviceConfiguration.SeedingMode != xDataService.Constants.XDbSeedingMode.None;
if (isValid)
{
//
// Prepare Default Terms ...
serviceConfiguration
.TermsAndConditions
.ToList()
.ForEach(t => t.ResourceTitle = serviceConfiguration.ResourceTitle);
//
// Loop through Terms and Conditions for Seeding ...
foreach (var item in serviceConfiguration.TermsAndConditions)
{
//
// Detect Exists Item ...
var exists = stringProvider.FindOneAsync(
predicate: x =>
x.Language == item.Language &&
x.ResourceTitle == item.ResourceTitle
)
.GetAwaiter()
.GetResult();
//
var isExists = !exists.IsNullOrDefault();
//
switch (serviceConfiguration.SeedingMode)
{
//
case xDataService.Constants.XDbSeedingMode.AddOrUpdate:
//
// Update Exists by new Provided ...
exists.TranslatedValue = item.TranslatedValue;
exists = stringProvider.UpdateAsync(
id: exists.Id,
item: exists,
saveChanges: true
)
.GetAwaiter()
.GetResult();
//
Log($"Refresh Terms and Conditions of {exists.Language}");
break;
//
case xDataService.Constants.XDbSeedingMode.AddIfNotExists:
//
if (!isExists)
{
//
exists = stringProvider.AddAsync(
item: item,
saveChanges: true
)
.GetAwaiter()
.GetResult();
//
Log($"Add Terms and Conditions for {exists.Language}");
}
break;
}
}
}
}
}
//
#region Private ...
/// <summary>
/// a LogTag for Service ...
/// </summary>
private static string XLogTag = XTermsAndConditionsServiceConstants.XTermsAndConditionsServiceDILogTag;
/// <summary>
/// print a log in Console ...
/// </summary>
/// <param name="message"></param>
private static void Log(string message)
{
Console.WriteLine($"{XLogTag} => {message}");
}
/// <summary>
/// Add Terms and Conditions Provider Service ...
/// </summary>
/// <param name="services"></param>
/// <param name="lifeTime"></param>
private static void AddTermsAndConditionsService(
IServiceCollection services,
IConfiguration configuration = null,
XTermsAndConditionsServiceConfiguration serviceConfiguration = null,
ServiceLifetime lifeTime = ServiceLifetime.Transient
)
{
//
var exception = XException.InvalidArgs.ToException(); ;
//
// Services ...
var isServicesExists = !services.IsNull();
if (!isServicesExists)
{
//
Log("AddTermsAndConditions failed, services not provided ...");
throw exception;
}
//
// Validate Configuration ...
var isConfigValid = !configuration.IsNull() || !serviceConfiguration.IsNull();
if (!isConfigValid)
{
//
Log("AddTermsAndConditions failed, configuration not provided ...");
throw exception;
}
//
// Lifetime ...
var isLifetimeExists = !lifeTime.IsNull();
if (!isLifetimeExists)
{
//
Log("AddTermsAndConditions failed, lifetime not provided ...");
throw exception;
}
//
// Check Dependencies Exists ...
var isDependenciesPassed = !services
.GetRegisteredService<XAppConfiguration>()
.IsNull() &&
!services.GetRegisteredService<IXStringServiceProvider>()
.IsNull();
if (!isDependenciesPassed)
{
//
Log("AddTermsAndConditions failed due Dependencies Issues, IXStringServiceProvider or XAppConfiguration not provided ...");
throw exception;
}
//
// Service Configuration Handler ...
if (serviceConfiguration.IsNull())
{
serviceConfiguration = configuration.GetXTermsAndConditionsServiceConfiguration();
}
services.AddXTermsAndConditionsConfiguration(serviceConfiguration);
//
// Register Resource Providers ...
services.Add(new ServiceDescriptor(typeof(IXTermsAndConditionsProvider), typeof(XTermsAndConditionsProvider), lifeTime));
}
#endregion
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xTermsAndConditionsService\Hubs\XTermsHub.cs
using System.Threading;
using xPushService.Base;
using xCommons.Extensions;
using System.Threading.Tasks;
using xPushService.Constants;
using xStringService.Models.Dtos;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Logging;
namespace xTermsAndConditionsService.Hubs
{
/// <summary>
/// a Hub for Notifing Terms and Conditions Events to Connected Clients ...
/// </summary>
public class XTermsHub : XBaseHub
{
public XTermsHub(
ILogger<XTermsHub> logger
) : base(logger)
{
}
//
#region Hub Actions ...
/// <summary>
/// Add Specified Terms and Conditions ...
/// </summary>
/// <param name="entity"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task Add(
XStringDto entity,
CancellationToken cancellationToken = default
)
{
//
var connectionId = Context.ConnectionId;
if (!connectionId.IsNullOrEmpty())
{
//
await Clients
.AllExcept(connectionId)
.SendAsync(
XBaseEntityHubAction.Add.GetStringValue(),
entity.ToJSON(camelCase: true),
connectionId,
cancellationToken
);
}
}
/// <summary>
/// Deleted Specified Terms and Conditions ...
/// </summary>
/// <param name="entity"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task Delete(
XStringDto entity,
CancellationToken cancellationToken = default
)
{
//
var connectionId = Context.ConnectionId;
if (!connectionId.IsNullOrEmpty())
{
//
await Clients
.AllExcept(connectionId)
.SendAsync(
XBaseEntityHubAction.Delete.GetStringValue(),
entity.ToJSON(camelCase: true),
connectionId,
cancellationToken
);
}
}
/// <summary>
/// Notify an Entity Updated ...
/// </summary>
/// <param name="entity"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task Update(
XStringDto entity,
CancellationToken cancellationToken = default
)
{
//
var connectionId = Context.ConnectionId;
if (!connectionId.IsNullOrEmpty())
{
//
await Clients
.AllExcept(connectionId)
.SendAsync(
XBaseEntityHubAction.Update.GetStringValue(),
entity.ToJSON(camelCase: true),
connectionId,
cancellationToken
);
}
}
#endregion
}
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xTermsAndConditionsService\Interfaces\IXTermsAndConditionsController.cs
using xStringService.Interfaces;
namespace xTermsAndConditionsService.Interfaces
{
/// <summary>
/// an Interface for Describing Terms and Conditions Management Controller Actions ...
/// </summary>
public interface IXTermsAndConditionsController : IXBaseResourceProviderController
{ }
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xTermsAndConditionsService\Interfaces\IXTermsAndConditionsProvider.cs
using xStringService.Interfaces;
namespace xTermsAndConditionsService.Interfaces
{
/// <summary>
/// an Interface for Describing Terms and Conditions Management Provided Actions ...
/// </summary>
public interface IXTermsAndConditionsProvider : IXResourceProvider
{ }
}
### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\Modules\xTermsAndConditionsService\Providers\XTermsAndConditionsProvider.cs
using xStringService.Providers;
using xStringService.Interfaces.Dtos;
using xTermsAndConditionsService.Interfaces;
using xTermsAndConditionsService.Configurations;
namespace xTermsAndConditionsService.Providers
{
/// <summary>
/// an Implementation of Terms and Conditions Management Provided Actions ...
/// </summary>
public class XTermsAndConditionsProvider : XBaseResourceProvider, IXTermsAndConditionsProvider
{
public XTermsAndConditionsProvider(
IXStringServiceProvider provider,
XTermsAndConditionsServiceConfiguration configuration
) : base(
resource: "NULL",
provider
)
{
//
// Since we nee to Set Resource Title of Terms and Conditions
// during instancing using Provided Configurations ...
// set this value here ...
resource = configuration.ResourceTitle;
}
}
}
File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 646 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 819 KiB

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More