(feat): image service
This commit is contained in:
parent
d9d0a14083
commit
697c7692d0
@ -25,16 +25,13 @@
|
||||
}
|
||||
],
|
||||
"url": {
|
||||
"raw": "https://localhost:7151/api/Content/404c8232-9048-4519-bfba-6e78dc7005ca?locale=en-US",
|
||||
"protocol": "https",
|
||||
"raw": "{{baseUrl}}/Content/{{siteId}}?locale=en-US",
|
||||
"host": [
|
||||
"localhost"
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"port": "7151",
|
||||
"path": [
|
||||
"api",
|
||||
"Content",
|
||||
"404c8232-9048-4519-bfba-6e78dc7005ca"
|
||||
"{{siteId}}"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
@ -68,16 +65,14 @@
|
||||
}
|
||||
],
|
||||
"url": {
|
||||
"raw": "https://localhost:7151/api/CategoryItem/404c8232-9048-4519-bfba-6e78dc7005ca/e154e33f-3cc7-468d-bb66-e0390ddb9ae0",
|
||||
"protocol": "https",
|
||||
"raw": "{{baseUrl}}//CategoryItem/{{siteId}}/e154e33f-3cc7-468d-bb66-e0390ddb9ae0",
|
||||
"host": [
|
||||
"localhost"
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"port": "7151",
|
||||
"path": [
|
||||
"api",
|
||||
"",
|
||||
"CategoryItem",
|
||||
"404c8232-9048-4519-bfba-6e78dc7005ca",
|
||||
"{{siteId}}",
|
||||
"e154e33f-3cc7-468d-bb66-e0390ddb9ae0"
|
||||
]
|
||||
}
|
||||
@ -101,16 +96,13 @@
|
||||
}
|
||||
],
|
||||
"url": {
|
||||
"raw": "https://localhost:7151/api/CategoryItem/404c8232-9048-4519-bfba-6e78dc7005ca?slug=default",
|
||||
"protocol": "https",
|
||||
"raw": "{{baseUrl}}/CategoryItem/{{siteId}}?slug=default",
|
||||
"host": [
|
||||
"localhost"
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"port": "7151",
|
||||
"path": [
|
||||
"api",
|
||||
"CategoryItem",
|
||||
"404c8232-9048-4519-bfba-6e78dc7005ca"
|
||||
"{{siteId}}"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
@ -143,16 +135,14 @@
|
||||
"raw": "{\r\n \"l10n\": [\r\n {\r\n \"locale\": \"\",\r\n \"slug\": \"guides\",\r\n \"text\": \"Guides\"\r\n }\r\n ]\r\n}"
|
||||
},
|
||||
"url": {
|
||||
"raw": "https://localhost:7151/api/CategoryItem/404c8232-9048-4519-bfba-6e78dc7005ca",
|
||||
"protocol": "https",
|
||||
"raw": "{{baseUrl}}//CategoryItem/{{siteId}}",
|
||||
"host": [
|
||||
"localhost"
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"port": "7151",
|
||||
"path": [
|
||||
"api",
|
||||
"",
|
||||
"CategoryItem",
|
||||
"404c8232-9048-4519-bfba-6e78dc7005ca"
|
||||
"{{siteId}}"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -179,16 +169,14 @@
|
||||
"raw": "{\r\n \"l10n\": [\r\n {\r\n \"locale\": \"en-US\",\r\n \"slug\": \"guides\",\r\n \"text\": \"Guides\"\r\n },\r\n {\r\n \"locale\": \"it-IT\",\r\n \"slug\": \"guide\",\r\n \"text\": \"Guide\"\r\n }\r\n ]\r\n}"
|
||||
},
|
||||
"url": {
|
||||
"raw": "https://localhost:7151/api/CategoryItem/404c8232-9048-4519-bfba-6e78dc7005ca/2c50f4de-70f2-4414-aabc-7a0d2eb0e203",
|
||||
"protocol": "https",
|
||||
"raw": "{{baseUrl}}//CategoryItem/{{siteId}}/2c50f4de-70f2-4414-aabc-7a0d2eb0e203",
|
||||
"host": [
|
||||
"localhost"
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"port": "7151",
|
||||
"path": [
|
||||
"api",
|
||||
"",
|
||||
"CategoryItem",
|
||||
"404c8232-9048-4519-bfba-6e78dc7005ca",
|
||||
"{{siteId}}",
|
||||
"2c50f4de-70f2-4414-aabc-7a0d2eb0e203"
|
||||
]
|
||||
}
|
||||
@ -212,17 +200,14 @@
|
||||
}
|
||||
],
|
||||
"url": {
|
||||
"raw": "https://localhost:7151/api/CategoryItem/404c8232-9048-4519-bfba-6e78dc7005ca/2c50f4de-70f2-4414-aabc-7a0d2eb0e203",
|
||||
"protocol": "https",
|
||||
"raw": "{{baseUrl}}/CategoryItem/{{siteId}}/e154e33f-3cc7-468d-bb66-e0390ddb9ae0",
|
||||
"host": [
|
||||
"localhost"
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"port": "7151",
|
||||
"path": [
|
||||
"api",
|
||||
"CategoryItem",
|
||||
"404c8232-9048-4519-bfba-6e78dc7005ca",
|
||||
"2c50f4de-70f2-4414-aabc-7a0d2eb0e203"
|
||||
"{{siteId}}",
|
||||
"e154e33f-3cc7-468d-bb66-e0390ddb9ae0"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -250,16 +235,13 @@
|
||||
}
|
||||
],
|
||||
"url": {
|
||||
"raw": "https://localhost:7151/api/CategoryItems/404c8232-9048-4519-bfba-6e78dc7005ca",
|
||||
"protocol": "https",
|
||||
"raw": "{{baseUrl}}/CategoryItems/{{siteId}}",
|
||||
"host": [
|
||||
"localhost"
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"port": "7151",
|
||||
"path": [
|
||||
"api",
|
||||
"CategoryItems",
|
||||
"404c8232-9048-4519-bfba-6e78dc7005ca"
|
||||
"{{siteId}}"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -282,16 +264,13 @@
|
||||
}
|
||||
],
|
||||
"url": {
|
||||
"raw": "https://localhost:7151/api/CategoryItems/404c8232-9048-4519-bfba-6e78dc7005ca?locale=en-US",
|
||||
"protocol": "https",
|
||||
"raw": "{{baseUrl}}/CategoryItems/{{siteId}}?locale=en-US",
|
||||
"host": [
|
||||
"localhost"
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"port": "7151",
|
||||
"path": [
|
||||
"api",
|
||||
"CategoryItems",
|
||||
"404c8232-9048-4519-bfba-6e78dc7005ca"
|
||||
"{{siteId}}"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
@ -320,16 +299,13 @@
|
||||
}
|
||||
],
|
||||
"url": {
|
||||
"raw": "https://localhost:7151/api/CategoryItems/404c8232-9048-4519-bfba-6e78dc7005ca",
|
||||
"protocol": "https",
|
||||
"raw": "{{baseUrl}}/CategoryItems/{{siteId}}",
|
||||
"host": [
|
||||
"localhost"
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"port": "7151",
|
||||
"path": [
|
||||
"api",
|
||||
"CategoryItems",
|
||||
"404c8232-9048-4519-bfba-6e78dc7005ca"
|
||||
"{{siteId}}"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -341,78 +317,7 @@
|
||||
"name": "ShopItem",
|
||||
"item": [
|
||||
{
|
||||
"name": "01-Get",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json",
|
||||
"type": "default"
|
||||
},
|
||||
{
|
||||
"key": "Accept",
|
||||
"value": "application/json",
|
||||
"type": "default"
|
||||
}
|
||||
],
|
||||
"url": {
|
||||
"raw": "https://localhost:7151/api/ShopItem/404c8232-9048-4519-bfba-6e78dc7005ca/SKU-01",
|
||||
"protocol": "https",
|
||||
"host": [
|
||||
"localhost"
|
||||
],
|
||||
"port": "7151",
|
||||
"path": [
|
||||
"api",
|
||||
"ShopItem",
|
||||
"404c8232-9048-4519-bfba-6e78dc7005ca",
|
||||
"SKU-01"
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "02-GetSlug",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json",
|
||||
"type": "default"
|
||||
},
|
||||
{
|
||||
"key": "Accept",
|
||||
"value": "application/json",
|
||||
"type": "default"
|
||||
}
|
||||
],
|
||||
"url": {
|
||||
"raw": "https://localhost:7151/api/ShopItem/404c8232-9048-4519-bfba-6e78dc7005ca?slug=shop-catalog-item-01",
|
||||
"protocol": "https",
|
||||
"host": [
|
||||
"localhost"
|
||||
],
|
||||
"port": "7151",
|
||||
"path": [
|
||||
"api",
|
||||
"ShopItem",
|
||||
"404c8232-9048-4519-bfba-6e78dc7005ca"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
"key": "slug",
|
||||
"value": "shop-catalog-item-01"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "03-Post",
|
||||
"name": "01-Post",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"header": [
|
||||
@ -429,19 +334,16 @@
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\r\n \"l10n\":[\r\n {\r\n \"locale\":\"en-US\",\r\n \"slug\":\"shop-catalog-item-05\",\r\n \"description\": \"Descritpion...\",\r\n \"title\":\"Shop item title\",\r\n \"shortText\":\"Shor text...\",\r\n \"text\":\"Text...\",\r\n \"contentType\": \"HTML\",\r\n \"badges\":[\r\n \"sale\"\r\n ]\r\n }\r\n ],\r\n \r\n \"tags\":[\r\n \"react\",\r\n \"redux\",\r\n \"webapi\"\r\n ],\r\n \"categories\":[\r\n \"e154e33f-3cc7-468d-bb66-e0390ddb9ae0\"\r\n ],\r\n \"brandName\":\"Mongodb Brand & Name\",\r\n \"rating\":4.5,\r\n \"price\":20,\r\n \"newPrice\":10,\r\n \"quantity\":100\r\n}"
|
||||
"raw": "{\r\n \"siteId\": \"404c8232-9048-4519-bfba-6e78dc7005ca\",\r\n \"l10n\": [\r\n {\r\n \"locale\": \"en-US\",\r\n \"slug\": \"shop-catalog-item-05\",\r\n \"description\": \"Lorem ipsum, dolor sit amet consectetur adipisicing elit.\",\r\n \"title\": \"Shop item title\",\r\n \"shortText\": \"Lorem ipsum, dolor sit amet consectetur adipisicing elit. Eaque fugit ratione dicta mollitia. Officiis ad...\",\r\n \"text\": \"<p>Lorem ipsum, dolor sit amet consectetur adipisicing elit.</p>\",\r\n \"textFormat\": \"HTML\",\r\n \"plainText\": \"Lorem ipsum, dolor sit amet consectetur adipisicing elit.\",\r\n \"badges\": [\r\n \"sale\"\r\n ]\r\n }\r\n ],\r\n\t\"mediaAttachments\": [\r\n\t {\r\n\t\t\"src\": \"api/Image/450x300/5033d24e-a7c3-4960-ac3c-f396d6773692\",\r\n\t\t\"mediaType\": \"image\",\r\n\t\t\"l10n\": [\r\n {\r\n \"locale\": \"en-US\",\r\n \"alt\": \"...\",\r\n\t\t\t\"target\": \"/title-image\",\r\n\t\t\t\"title\": \"Title image\",\r\n\t\t\t\"description\": \"Title image description.\"\r\n\t }\r\n ]\r\n\t }\r\n\t],\r\n \"author\": \"fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60\",\r\n \"created\": {\r\n \"$date\": \"2022-01-01T00:00:00.000Z\"\r\n },\r\n \"tags\": [\r\n \"react\",\r\n \"redux\",\r\n \"webapi\"\r\n ],\r\n \"brandName\": \"Mongodb Brand & Name\",\r\n \"sku\": \"SKU-05\",\r\n \"rating\": 4.5,\r\n \"price\": 20,\r\n \"newPrice\": 10,\r\n \"quantity\": 100\r\n }"
|
||||
},
|
||||
"url": {
|
||||
"raw": "https://localhost:7151/api/ShopItem/404c8232-9048-4519-bfba-6e78dc7005ca/SKU-05",
|
||||
"protocol": "https",
|
||||
"raw": "{{baseUrl}}/ShopItem/{{siteId}}/SKU-05",
|
||||
"host": [
|
||||
"localhost"
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"port": "7151",
|
||||
"path": [
|
||||
"api",
|
||||
"ShopItem",
|
||||
"404c8232-9048-4519-bfba-6e78dc7005ca",
|
||||
"{{siteId}}",
|
||||
"SKU-05"
|
||||
]
|
||||
}
|
||||
@ -449,7 +351,74 @@
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "04-Put",
|
||||
"name": "02-Get",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json",
|
||||
"type": "default"
|
||||
},
|
||||
{
|
||||
"key": "Accept",
|
||||
"value": "application/json",
|
||||
"type": "default"
|
||||
}
|
||||
],
|
||||
"url": {
|
||||
"raw": "{{baseUrl}}//ShopItem/{{siteId}}/SKU-05",
|
||||
"host": [
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"path": [
|
||||
"",
|
||||
"ShopItem",
|
||||
"{{siteId}}",
|
||||
"SKU-05"
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "03-GetSlug",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json",
|
||||
"type": "default"
|
||||
},
|
||||
{
|
||||
"key": "Accept",
|
||||
"value": "application/json",
|
||||
"type": "default"
|
||||
}
|
||||
],
|
||||
"url": {
|
||||
"raw": "{{baseUrl}}/ShopItem/{{siteId}}?slug=shop-catalog-item-05",
|
||||
"host": [
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"path": [
|
||||
"",
|
||||
"ShopItem",
|
||||
"{{siteId}}"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
"key": "slug",
|
||||
"value": "shop-catalog-item-05"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "05-Put",
|
||||
"request": {
|
||||
"method": "PUT",
|
||||
"header": [
|
||||
@ -466,19 +435,16 @@
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\r\n \"l10n\":[\r\n {\r\n \"locale\":\"en-US\",\r\n \"slug\":\"shop-catalog-item-05\",\r\n \"description\": \"New Descritpion...\",\r\n \"title\":\"Shop item title\",\r\n \"shortText\":\"New Shor text...\",\r\n \"text\":\"New Text...\",\r\n \"contentType\": \"HTML\",\r\n \"badges\":[\r\n \"sale\"\r\n ]\r\n }\r\n ],\r\n \r\n \"tags\":[\r\n \"react\",\r\n \"redux\",\r\n \"webapi\"\r\n ],\r\n \"categories\":[\r\n \"e154e33f-3cc7-468d-bb66-e0390ddb9ae0\"\r\n ],\r\n \"brandName\":\"Mongodb Brand & Name\",\r\n \"rating\":4.5,\r\n \"price\":20,\r\n \"newPrice\":10,\r\n \"quantity\":100\r\n}"
|
||||
"raw": "{\r\n \"siteId\": \"404c8232-9048-4519-bfba-6e78dc7005ca\",\r\n \"l10n\": [\r\n {\r\n \"locale\": \"en-US\",\r\n \"slug\": \"shop-catalog-item-05\",\r\n \"description\": \"Lorem ipsum, dolor sit amet consectetur adipisicing elit.\",\r\n \"title\": \"Shop item title\",\r\n \"shortText\": \"Lorem ipsum, dolor sit amet consectetur adipisicing elit. Eaque fugit ratione dicta mollitia. Officiis ad...\",\r\n \"text\": \"<p>Lorem ipsum, dolor sit amet consectetur adipisicing elit.</p>\",\r\n \"textFormat\": \"HTML\",\r\n \"plainText\": \"Lorem ipsum, dolor sit amet consectetur adipisicing elit.\",\r\n \"badges\": [\r\n \"sale\"\r\n ]\r\n }\r\n ],\r\n\t\"mediaAttachments\": [\r\n\t {\r\n\t\t\"src\": \"api/Image/450x300/5033d24e-a7c3-4960-ac3c-f396d6773692\",\r\n\t\t\"mediaType\": \"image\",\r\n\t\t\"l10n\": [\r\n {\r\n \"locale\": \"en-US\",\r\n \"alt\": \"...\",\r\n\t\t\t\"target\": \"/title-image\",\r\n\t\t\t\"title\": \"Title image\",\r\n\t\t\t\"description\": \"Title image description.\"\r\n\t }\r\n ]\r\n\t }\r\n\t],\r\n \"author\": \"fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60\",\r\n \"created\": {\r\n \"$date\": \"2022-01-01T00:00:00.000Z\"\r\n },\r\n \"tags\": [\r\n \"react\",\r\n \"redux\",\r\n \"webapi\"\r\n ],\r\n \"categories\": [\r\n \"e154e33f-3cc7-468d-bb66-e0390ddb9ae0\"\r\n ],\r\n \"brandName\": \"Mongodb Brand & Name\",\r\n \"sku\": \"SKU-05\",\r\n \"rating\": 4.5,\r\n \"price\": 20,\r\n \"newPrice\": 10,\r\n \"quantity\": 100\r\n }"
|
||||
},
|
||||
"url": {
|
||||
"raw": "https://localhost:7151/api/ShopItem/404c8232-9048-4519-bfba-6e78dc7005ca/SKU-05",
|
||||
"protocol": "https",
|
||||
"raw": "{{baseUrl}}/ShopItem/{{siteId}}/SKU-05",
|
||||
"host": [
|
||||
"localhost"
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"port": "7151",
|
||||
"path": [
|
||||
"api",
|
||||
"ShopItem",
|
||||
"404c8232-9048-4519-bfba-6e78dc7005ca",
|
||||
"{{siteId}}",
|
||||
"SKU-05"
|
||||
]
|
||||
}
|
||||
@ -486,7 +452,7 @@
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "05-Delete",
|
||||
"name": "06-Delete",
|
||||
"request": {
|
||||
"method": "DELETE",
|
||||
"header": [
|
||||
@ -502,16 +468,13 @@
|
||||
}
|
||||
],
|
||||
"url": {
|
||||
"raw": "https://localhost:7151/api/ShopItem/404c8232-9048-4519-bfba-6e78dc7005ca/SKU-05",
|
||||
"protocol": "https",
|
||||
"raw": "{{baseUrl}}/ShopItem/{{siteId}}/SKU-05",
|
||||
"host": [
|
||||
"localhost"
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"port": "7151",
|
||||
"path": [
|
||||
"api",
|
||||
"ShopItem",
|
||||
"404c8232-9048-4519-bfba-6e78dc7005ca",
|
||||
"{{siteId}}",
|
||||
"SKU-05"
|
||||
]
|
||||
}
|
||||
@ -540,16 +503,13 @@
|
||||
}
|
||||
],
|
||||
"url": {
|
||||
"raw": "https://localhost:7151/api/ShopItems/404c8232-9048-4519-bfba-6e78dc7005ca?currentPage=1&itemsPerPage=4",
|
||||
"protocol": "https",
|
||||
"raw": "{{baseUrl}}/ShopItems/{{siteId}}?currentPage=1&itemsPerPage=4",
|
||||
"host": [
|
||||
"localhost"
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"port": "7151",
|
||||
"path": [
|
||||
"api",
|
||||
"ShopItems",
|
||||
"404c8232-9048-4519-bfba-6e78dc7005ca"
|
||||
"{{siteId}}"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
@ -582,16 +542,13 @@
|
||||
}
|
||||
],
|
||||
"url": {
|
||||
"raw": "https://localhost:7151/api/ShopItems/404c8232-9048-4519-bfba-6e78dc7005ca?currentPage=2&itemsPerPage=2&locale=en-US",
|
||||
"protocol": "https",
|
||||
"raw": "{{baseUrl}}/ShopItems/{{siteId}}?currentPage=2&itemsPerPage=2&locale=en-US",
|
||||
"host": [
|
||||
"localhost"
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"port": "7151",
|
||||
"path": [
|
||||
"api",
|
||||
"ShopItems",
|
||||
"404c8232-9048-4519-bfba-6e78dc7005ca"
|
||||
"{{siteId}}"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
@ -628,16 +585,13 @@
|
||||
}
|
||||
],
|
||||
"url": {
|
||||
"raw": "https://localhost:7151/api/ShopItems/404c8232-9048-4519-bfba-6e78dc7005ca",
|
||||
"protocol": "https",
|
||||
"raw": "{{baseUrl}}/ShopItems/{{siteId}}",
|
||||
"host": [
|
||||
"localhost"
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"port": "7151",
|
||||
"path": [
|
||||
"api",
|
||||
"ShopItems",
|
||||
"404c8232-9048-4519-bfba-6e78dc7005ca"
|
||||
"{{siteId}}"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -665,16 +619,13 @@
|
||||
}
|
||||
],
|
||||
"url": {
|
||||
"raw": "https://localhost:7151/api/ShopCartItem/404c8232-9048-4519-bfba-6e78dc7005ca/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60/SKU-04?locale=en-US",
|
||||
"protocol": "https",
|
||||
"raw": "{{baseUrl}}/ShopCartItem/{{siteId}}/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60/SKU-04?locale=en-US",
|
||||
"host": [
|
||||
"localhost"
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"port": "7151",
|
||||
"path": [
|
||||
"api",
|
||||
"ShopCartItem",
|
||||
"404c8232-9048-4519-bfba-6e78dc7005ca",
|
||||
"{{siteId}}",
|
||||
"fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60",
|
||||
"SKU-04"
|
||||
],
|
||||
@ -709,16 +660,14 @@
|
||||
"raw": "{\r\n \"quantity\": 1\r\n}"
|
||||
},
|
||||
"url": {
|
||||
"raw": "https://localhost:7151/api/ShopCartItem/404c8232-9048-4519-bfba-6e78dc7005ca/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60/SKU-05",
|
||||
"protocol": "https",
|
||||
"raw": "{{baseUrl}}//ShopCartItem/{{siteId}}/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60/SKU-05",
|
||||
"host": [
|
||||
"localhost"
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"port": "7151",
|
||||
"path": [
|
||||
"api",
|
||||
"",
|
||||
"ShopCartItem",
|
||||
"404c8232-9048-4519-bfba-6e78dc7005ca",
|
||||
"{{siteId}}",
|
||||
"fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60",
|
||||
"SKU-05"
|
||||
]
|
||||
@ -747,16 +696,13 @@
|
||||
"raw": "{\r\n \"quantity\": 5\r\n}"
|
||||
},
|
||||
"url": {
|
||||
"raw": "https://localhost:7151/api/ShopCartItem/404c8232-9048-4519-bfba-6e78dc7005ca/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60/SKU-04",
|
||||
"protocol": "https",
|
||||
"raw": "{{baseUrl}}/ShopCartItem/{{siteId}}/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60/SKU-04",
|
||||
"host": [
|
||||
"localhost"
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"port": "7151",
|
||||
"path": [
|
||||
"api",
|
||||
"ShopCartItem",
|
||||
"404c8232-9048-4519-bfba-6e78dc7005ca",
|
||||
"{{siteId}}",
|
||||
"fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60",
|
||||
"SKU-04"
|
||||
]
|
||||
@ -781,16 +727,13 @@
|
||||
}
|
||||
],
|
||||
"url": {
|
||||
"raw": "https://localhost:7151/api/ShopCartItem/404c8232-9048-4519-bfba-6e78dc7005ca/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60/SKU-04",
|
||||
"protocol": "https",
|
||||
"raw": "{{baseUrl}}/ShopCartItem/{{siteId}}/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60/SKU-04",
|
||||
"host": [
|
||||
"localhost"
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"port": "7151",
|
||||
"path": [
|
||||
"api",
|
||||
"ShopCartItem",
|
||||
"404c8232-9048-4519-bfba-6e78dc7005ca",
|
||||
"{{siteId}}",
|
||||
"fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60",
|
||||
"SKU-04"
|
||||
]
|
||||
@ -820,16 +763,13 @@
|
||||
}
|
||||
],
|
||||
"url": {
|
||||
"raw": "https://localhost:7151/api/ShopCartItems/404c8232-9048-4519-bfba-6e78dc7005ca/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60?locale=en-US",
|
||||
"protocol": "https",
|
||||
"raw": "{{baseUrl}}/ShopCartItems/{{siteId}}/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60?locale=en-US",
|
||||
"host": [
|
||||
"localhost"
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"port": "7151",
|
||||
"path": [
|
||||
"api",
|
||||
"ShopCartItems",
|
||||
"404c8232-9048-4519-bfba-6e78dc7005ca",
|
||||
"{{siteId}}",
|
||||
"fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60"
|
||||
],
|
||||
"query": [
|
||||
@ -859,16 +799,13 @@
|
||||
}
|
||||
],
|
||||
"url": {
|
||||
"raw": "https://localhost:7151/api/ShopCartItems/404c8232-9048-4519-bfba-6e78dc7005ca/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60",
|
||||
"protocol": "https",
|
||||
"raw": "{{baseUrl}}/ShopCartItems/{{siteId}}/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60",
|
||||
"host": [
|
||||
"localhost"
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"port": "7151",
|
||||
"path": [
|
||||
"api",
|
||||
"ShopCartItems",
|
||||
"404c8232-9048-4519-bfba-6e78dc7005ca",
|
||||
"{{siteId}}",
|
||||
"fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60"
|
||||
]
|
||||
}
|
||||
@ -897,16 +834,13 @@
|
||||
}
|
||||
],
|
||||
"url": {
|
||||
"raw": "https://localhost:7151/api/BlogItem/404c8232-9048-4519-bfba-6e78dc7005ca/11f2f5f8-1270-4640-b082-c2e7ea8e60b4",
|
||||
"protocol": "https",
|
||||
"raw": "{{baseUrl}}/BlogItem/{{siteId}}/11f2f5f8-1270-4640-b082-c2e7ea8e60b4",
|
||||
"host": [
|
||||
"localhost"
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"port": "7151",
|
||||
"path": [
|
||||
"api",
|
||||
"BlogItem",
|
||||
"404c8232-9048-4519-bfba-6e78dc7005ca",
|
||||
"{{siteId}}",
|
||||
"11f2f5f8-1270-4640-b082-c2e7ea8e60b4"
|
||||
]
|
||||
}
|
||||
@ -930,16 +864,13 @@
|
||||
}
|
||||
],
|
||||
"url": {
|
||||
"raw": "https://localhost:7151/api/BlogItem/404c8232-9048-4519-bfba-6e78dc7005ca?slug=privacy-terms-and-conditions",
|
||||
"protocol": "https",
|
||||
"raw": "{{baseUrl}}/BlogItem/{{siteId}}?slug=privacy-terms-and-conditions",
|
||||
"host": [
|
||||
"localhost"
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"port": "7151",
|
||||
"path": [
|
||||
"api",
|
||||
"BlogItem",
|
||||
"404c8232-9048-4519-bfba-6e78dc7005ca"
|
||||
"{{siteId}}"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
@ -972,16 +903,13 @@
|
||||
"raw": "{\r\n\r\n \"l10n\": [\r\n {\r\n \"locale\": \"en-US\",\r\n \"slug\": \"hello-world\",\r\n \"description\": \"Hello world description\",\r\n \"title\": \"Hello world title\",\r\n \"shortText\": \"Hello world short text\",\r\n \"text\": \"<p>Hello World</p>\",\r\n \"contentType\": \"HTML\",\r\n \"badges\": [\r\n \"post\"\r\n ]\r\n }\r\n ],\r\n \"images\": [\r\n {\r\n \"l10n\": [\r\n {\r\n \"locale\": \"en-US\",\r\n \"alt\": \"...\"\r\n },\r\n {\r\n \"locale\": \"it-IT\",\r\n \"alt\": \"...\"\r\n }\r\n ]\r\n }\r\n ],\r\n \"tags\": [\r\n \"privacy\",\r\n \"terms\"\r\n ],\r\n \"categories\": [\r\n \"e154e33f-3cc7-468d-bb66-e0390ddb9ae0\" \r\n ],\r\n \"familyFriendly\": true\r\n}"
|
||||
},
|
||||
"url": {
|
||||
"raw": "https://localhost:7151/api/BlogItem/404c8232-9048-4519-bfba-6e78dc7005ca",
|
||||
"protocol": "https",
|
||||
"raw": "{{baseUrl}}/BlogItem/{{siteId}}",
|
||||
"host": [
|
||||
"localhost"
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"port": "7151",
|
||||
"path": [
|
||||
"api",
|
||||
"BlogItem",
|
||||
"404c8232-9048-4519-bfba-6e78dc7005ca"
|
||||
"{{siteId}}"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -1008,16 +936,13 @@
|
||||
"raw": "{\r\n\r\n \"l10n\": [\r\n {\r\n \"locale\": \"en-US\",\r\n \"slug\": \"hello-world\",\r\n \"description\": \"Hello world description\",\r\n \"title\": \"Hello world title\",\r\n \"shortText\": \"Hello world short text\",\r\n \"text\": \"<p>New Hello World</p>\",\r\n \"contentType\": \"HTML\",\r\n \"badges\": [\r\n \"post\"\r\n ]\r\n }\r\n ],\r\n \"images\": [\r\n {\r\n \"l10n\": [\r\n {\r\n \"locale\": \"en-US\",\r\n \"alt\": \"...\"\r\n },\r\n {\r\n \"locale\": \"it-IT\",\r\n \"alt\": \"...\"\r\n }\r\n ]\r\n }\r\n ],\r\n \"tags\": [\r\n \"privacy\",\r\n \"terms\"\r\n ],\r\n \"categories\": [\r\n \"e154e33f-3cc7-468d-bb66-e0390ddb9ae0\" \r\n ],\r\n \"familyFriendly\": true\r\n}"
|
||||
},
|
||||
"url": {
|
||||
"raw": "https://localhost:7151/api/BlogItem/404c8232-9048-4519-bfba-6e78dc7005ca/94feda90-ddf6-4717-8879-9c7139e7ff30",
|
||||
"protocol": "https",
|
||||
"raw": "{{baseUrl}}/BlogItem/{{siteId}}/94feda90-ddf6-4717-8879-9c7139e7ff30",
|
||||
"host": [
|
||||
"localhost"
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"port": "7151",
|
||||
"path": [
|
||||
"api",
|
||||
"BlogItem",
|
||||
"404c8232-9048-4519-bfba-6e78dc7005ca",
|
||||
"{{siteId}}",
|
||||
"94feda90-ddf6-4717-8879-9c7139e7ff30"
|
||||
]
|
||||
}
|
||||
@ -1041,16 +966,13 @@
|
||||
}
|
||||
],
|
||||
"url": {
|
||||
"raw": "https://localhost:7151/api/BlogItem/404c8232-9048-4519-bfba-6e78dc7005ca/94feda90-ddf6-4717-8879-9c7139e7ff30",
|
||||
"protocol": "https",
|
||||
"raw": "{{baseUrl}}/BlogItem/{{siteId}}/94feda90-ddf6-4717-8879-9c7139e7ff30",
|
||||
"host": [
|
||||
"localhost"
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"port": "7151",
|
||||
"path": [
|
||||
"api",
|
||||
"BlogItem",
|
||||
"404c8232-9048-4519-bfba-6e78dc7005ca",
|
||||
"{{siteId}}",
|
||||
"94feda90-ddf6-4717-8879-9c7139e7ff30"
|
||||
]
|
||||
}
|
||||
@ -1079,16 +1001,13 @@
|
||||
}
|
||||
],
|
||||
"url": {
|
||||
"raw": "https://localhost:7151/api/BlogItems/404c8232-9048-4519-bfba-6e78dc7005ca?currentPage=2&itemsPerPage=2",
|
||||
"protocol": "https",
|
||||
"raw": "{{baseUrl}}/BlogItems/{{siteId}}?currentPage=2&itemsPerPage=2",
|
||||
"host": [
|
||||
"localhost"
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"port": "7151",
|
||||
"path": [
|
||||
"api",
|
||||
"BlogItems",
|
||||
"404c8232-9048-4519-bfba-6e78dc7005ca"
|
||||
"{{siteId}}"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
@ -1121,16 +1040,13 @@
|
||||
}
|
||||
],
|
||||
"url": {
|
||||
"raw": "https://localhost:7151/api/BlogItems/404c8232-9048-4519-bfba-6e78dc7005ca?currentPage=2&itemsPerPage=2&locale=en-US",
|
||||
"protocol": "https",
|
||||
"raw": "{{baseUrl}}/BlogItems/{{siteId}}?currentPage=2&itemsPerPage=2&locale=en-US",
|
||||
"host": [
|
||||
"localhost"
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"port": "7151",
|
||||
"path": [
|
||||
"api",
|
||||
"BlogItems",
|
||||
"404c8232-9048-4519-bfba-6e78dc7005ca"
|
||||
"{{siteId}}"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
@ -1167,16 +1083,13 @@
|
||||
}
|
||||
],
|
||||
"url": {
|
||||
"raw": "https://localhost:7151/api/BlogItems/404c8232-9048-4519-bfba-6e78dc7005ca",
|
||||
"protocol": "https",
|
||||
"raw": "{{baseUrl}}/BlogItems/{{siteId}}",
|
||||
"host": [
|
||||
"localhost"
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"port": "7151",
|
||||
"path": [
|
||||
"api",
|
||||
"BlogItems",
|
||||
"404c8232-9048-4519-bfba-6e78dc7005ca"
|
||||
"{{siteId}}"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -1204,16 +1117,84 @@
|
||||
}
|
||||
],
|
||||
"url": {
|
||||
"raw": "https://localhost:7151/api/File/404c8232-9048-4519-bfba-6e78dc7005ca/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60/3930ff55-67e1-4763-be59-37407f91e0a9",
|
||||
"protocol": "https",
|
||||
"raw": "{{baseUrl}}/File/{{siteId}}/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60/4f163ea9-1786-4192-8efa-3b8ea9ca88fa",
|
||||
"host": [
|
||||
"localhost"
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"port": "7151",
|
||||
"path": [
|
||||
"api",
|
||||
"File",
|
||||
"404c8232-9048-4519-bfba-6e78dc7005ca",
|
||||
"{{siteId}}",
|
||||
"fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60",
|
||||
"4f163ea9-1786-4192-8efa-3b8ea9ca88fa"
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "02-Post",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json",
|
||||
"type": "default"
|
||||
},
|
||||
{
|
||||
"key": "Accept",
|
||||
"value": "application/ecmascript",
|
||||
"type": "default"
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "formdata",
|
||||
"formdata": [
|
||||
{
|
||||
"key": "file",
|
||||
"type": "file",
|
||||
"src": "/C:/Users/maksym/Desktop/Arpeggios.gp"
|
||||
}
|
||||
]
|
||||
},
|
||||
"url": {
|
||||
"raw": "{{baseUrl}}/File/{{siteId}}/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60",
|
||||
"host": [
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"path": [
|
||||
"File",
|
||||
"{{siteId}}",
|
||||
"fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60"
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "04-Delete",
|
||||
"request": {
|
||||
"method": "DELETE",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json",
|
||||
"type": "default"
|
||||
},
|
||||
{
|
||||
"key": "Accept",
|
||||
"value": "application/json",
|
||||
"type": "default"
|
||||
}
|
||||
],
|
||||
"url": {
|
||||
"raw": "{{baseUrl}}/File/{{siteId}}/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60/3930ff55-67e1-4763-be59-37407f91e0a9",
|
||||
"host": [
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"path": [
|
||||
"File",
|
||||
"{{siteId}}",
|
||||
"fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60",
|
||||
"3930ff55-67e1-4763-be59-37407f91e0a9"
|
||||
]
|
||||
@ -1254,16 +1235,13 @@
|
||||
]
|
||||
},
|
||||
"url": {
|
||||
"raw": "https://localhost:7151/api/Files/404c8232-9048-4519-bfba-6e78dc7005ca/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60",
|
||||
"protocol": "https",
|
||||
"raw": "{{baseUrl}}/Files/{{siteId}}/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60",
|
||||
"host": [
|
||||
"localhost"
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"port": "7151",
|
||||
"path": [
|
||||
"api",
|
||||
"Files",
|
||||
"404c8232-9048-4519-bfba-6e78dc7005ca",
|
||||
"{{siteId}}",
|
||||
"fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60"
|
||||
]
|
||||
}
|
||||
@ -1298,16 +1276,13 @@
|
||||
]
|
||||
},
|
||||
"url": {
|
||||
"raw": "https://localhost:7151/api/Files/404c8232-9048-4519-bfba-6e78dc7005ca/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60",
|
||||
"protocol": "https",
|
||||
"raw": "{{baseUrl}}/Files/{{siteId}}/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60",
|
||||
"host": [
|
||||
"localhost"
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"port": "7151",
|
||||
"path": [
|
||||
"api",
|
||||
"Files",
|
||||
"404c8232-9048-4519-bfba-6e78dc7005ca",
|
||||
"{{siteId}}",
|
||||
"fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60"
|
||||
]
|
||||
}
|
||||
@ -1315,6 +1290,63 @@
|
||||
"response": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Image",
|
||||
"item": [
|
||||
{
|
||||
"name": "01-Get",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "{{baseUrl}}/Image/{{siteId}}/450x300/55ecc564-c086-4e77-a8b2-ef32c2a8c280",
|
||||
"host": [
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"path": [
|
||||
"Image",
|
||||
"{{siteId}}",
|
||||
"450x300",
|
||||
"55ecc564-c086-4e77-a8b2-ef32c2a8c280"
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"event": [
|
||||
{
|
||||
"listen": "prerequest",
|
||||
"script": {
|
||||
"type": "text/javascript",
|
||||
"exec": [
|
||||
""
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"listen": "test",
|
||||
"script": {
|
||||
"type": "text/javascript",
|
||||
"exec": [
|
||||
""
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"variable": [
|
||||
{
|
||||
"key": "baseUrl",
|
||||
"value": "https://localhost:7151/api",
|
||||
"type": "default"
|
||||
},
|
||||
{
|
||||
"key": "siteId",
|
||||
"value": "404c8232-9048-4519-bfba-6e78dc7005ca",
|
||||
"type": "default"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -41,11 +41,11 @@ namespace DataProviders.Abstractions {
|
||||
#endregion
|
||||
|
||||
#region Download
|
||||
private protected (BucketFile?, IDomainResult) Download(Guid siteId, Guid userId, Guid fileId, string bucketName) =>
|
||||
DownloadAsync(siteId, userId, fileId, bucketName).Result;
|
||||
private protected (List<BucketFile>?, IDomainResult) Download(FilterDefinition<GridFSFileInfo> filter, string bucketName) =>
|
||||
DownloadAsync(filter, bucketName).Result;
|
||||
|
||||
private protected Task<(BucketFile?, IDomainResult)> DownloadAsync(Guid siteId, Guid userId, Guid fileId, string bucketName) =>
|
||||
DownloadAsyncCore(siteId, userId, fileId, bucketName);
|
||||
private protected Task<(List<BucketFile>?, IDomainResult)> DownloadAsync(FilterDefinition<GridFSFileInfo> filter, string bucketName) =>
|
||||
DownloadAsyncCore(filter, bucketName);
|
||||
#endregion
|
||||
|
||||
#region Delete
|
||||
@ -115,49 +115,49 @@ namespace DataProviders.Abstractions {
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<(BucketFile?, IDomainResult)> DownloadAsyncCore(Guid siteId, Guid userId, Guid fileId, string bucketName) {
|
||||
private async Task<(List<BucketFile>?, IDomainResult)> DownloadAsyncCore(FilterDefinition<GridFSFileInfo> filter, string bucketName) {
|
||||
try {
|
||||
var filter = Builders<GridFSFileInfo>.Filter.And(
|
||||
Builders<GridFSFileInfo>.Filter.Eq(x => x.Metadata["siteId"], $"{siteId}"),
|
||||
Builders<GridFSFileInfo>.Filter.Eq(x => x.Metadata["userId"], $"{userId}"),
|
||||
Builders<GridFSFileInfo>.Filter.Eq(x => x.Filename, $"{fileId}")
|
||||
);
|
||||
|
||||
var sort = Builders<GridFSFileInfo>.Sort.Descending(x => x.UploadDateTime);
|
||||
|
||||
var bucket = CreateBucket(bucketName);
|
||||
|
||||
using var cursor = await bucket.FindAsync(filter, new GridFSFindOptions {
|
||||
Limit = 1,
|
||||
Sort = sort,
|
||||
});
|
||||
|
||||
var result = new List<BucketFile>();
|
||||
|
||||
// fileInfo either has the matching file information or is null
|
||||
var fileInfo = (await cursor.ToListAsync()).FirstOrDefault();
|
||||
foreach (var fileInfo in await cursor.ToListAsync()) {
|
||||
if (fileInfo == null)
|
||||
return IDomainResult.NotFound<BucketFile?>();
|
||||
return IDomainResult.NotFound<List<BucketFile>?>();
|
||||
|
||||
var fileName = fileInfo.Metadata["fileName"].ToString() ?? "";
|
||||
if (fileName == null)
|
||||
return IDomainResult.Failed<BucketFile?>();
|
||||
return IDomainResult.Failed<List<BucketFile>?>();
|
||||
|
||||
var contentType = fileInfo.Metadata["contentType"].ToString() ?? "";
|
||||
if (contentType == null)
|
||||
return IDomainResult.Failed<BucketFile?>();
|
||||
return IDomainResult.Failed<List<BucketFile>?>();
|
||||
|
||||
var bytes = await bucket.DownloadAsBytesByNameAsync($"{fileId}", new GridFSDownloadByNameOptions {
|
||||
var bytes = await bucket.DownloadAsBytesByNameAsync($"{fileInfo.Filename}", new GridFSDownloadByNameOptions {
|
||||
Revision = -1
|
||||
});
|
||||
|
||||
if(bytes == null)
|
||||
return IDomainResult.Failed<BucketFile?>();
|
||||
if (bytes == null)
|
||||
return IDomainResult.Failed<List<BucketFile>?>();
|
||||
|
||||
return IDomainResult.Success(new BucketFile(fileName, bytes, contentType));
|
||||
result.Add(new BucketFile(fileName, bytes, contentType));
|
||||
}
|
||||
|
||||
return result.Count > 0
|
||||
? IDomainResult.Success(result)
|
||||
: IDomainResult.NotFound<List<BucketFile>?>();
|
||||
|
||||
}
|
||||
catch (Exception ex) {
|
||||
_logger.LogError(ex, "Bucket data provider error");
|
||||
return IDomainResult.Failed<BucketFile?>();
|
||||
return IDomainResult.Failed<List<BucketFile>?>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -5,6 +5,7 @@ using DomainResults.Common;
|
||||
using MongoDB.Driver;
|
||||
|
||||
using DataProviders.Abstractions;
|
||||
using MongoDB.Driver.GridFS;
|
||||
|
||||
namespace DataProviders.Buckets {
|
||||
|
||||
@ -46,6 +47,29 @@ namespace DataProviders.Buckets {
|
||||
/// <returns></returns>
|
||||
public (List<Guid>?, IDomainResult) UploadMany(Guid siteId, Guid userId, List<BucketFile> files) => UploadMany(siteId, userId, files, _bucketName);
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="siteId"></param>
|
||||
/// <param name="fileId"></param>
|
||||
/// <returns></returns>
|
||||
public (BucketFile?, IDomainResult) Download(Guid siteId, Guid fileId) {
|
||||
var filter = Builders<GridFSFileInfo>.Filter.And(
|
||||
Builders<GridFSFileInfo>.Filter.Eq(x => x.Metadata["siteId"], $"{siteId}"),
|
||||
Builders<GridFSFileInfo>.Filter.Eq(x => x.Metadata["private"], false),
|
||||
Builders<GridFSFileInfo>.Filter.Eq(x => x.Filename, $"{fileId}")
|
||||
);
|
||||
|
||||
var (list, result) = Download(filter, _bucketName);
|
||||
|
||||
if (!result.IsSuccess || list == null)
|
||||
return (null, result);
|
||||
|
||||
return (list.First(), result);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
@ -53,7 +77,21 @@ namespace DataProviders.Buckets {
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="fileId"></param>
|
||||
/// <returns></returns>
|
||||
public (BucketFile?, IDomainResult) Download(Guid siteId, Guid userId, Guid fileId) => Download(siteId, userId, fileId, _bucketName);
|
||||
public (BucketFile?, IDomainResult) Download(Guid siteId, Guid userId, Guid fileId) {
|
||||
|
||||
var filter = Builders<GridFSFileInfo>.Filter.And(
|
||||
Builders<GridFSFileInfo>.Filter.Eq(x => x.Metadata["siteId"], $"{siteId}"),
|
||||
Builders<GridFSFileInfo>.Filter.Eq(x => x.Metadata["userId"], $"{userId}"),
|
||||
Builders<GridFSFileInfo>.Filter.Eq(x => x.Filename, $"{fileId}")
|
||||
);
|
||||
|
||||
var (list, result) = Download(filter, _bucketName);
|
||||
|
||||
if (!result.IsSuccess || list == null)
|
||||
return (null, result);
|
||||
|
||||
return (list.First(), result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
|
||||
@ -1,10 +1,17 @@
|
||||
using DomainResults.Common;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
using DomainResults.Common;
|
||||
|
||||
using MongoDB.Driver;
|
||||
|
||||
using DataProviders.Abstractions;
|
||||
|
||||
namespace DataProviders.Buckets {
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public interface IBucketDataProvider {
|
||||
public interface IImageBucketDataProvider {
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
@ -24,6 +31,14 @@ namespace DataProviders.Buckets {
|
||||
/// <returns></returns>
|
||||
(List<Guid>?, IDomainResult) UploadMany(Guid siteId, Guid userId, List<BucketFile> files);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="siteId"></param>
|
||||
/// <param name="fileId"></param>
|
||||
/// <returns></returns>
|
||||
(BucketFile?, IDomainResult) Download(Guid siteId, Guid fileId);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
@ -50,4 +65,20 @@ namespace DataProviders.Buckets {
|
||||
/// <returns></returns>
|
||||
IDomainResult DeletMany(Guid siteId, Guid userId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ImageBucketDataProvider : SpecificBucketDataProviderBase, IImageBucketDataProvider {
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="logger"></param>
|
||||
/// <param name="client"></param>
|
||||
public ImageBucketDataProvider(
|
||||
ILogger<BucketDataProviderBase> logger,
|
||||
IMongoClient client
|
||||
) : base(logger, client, "images") { }
|
||||
}
|
||||
}
|
||||
@ -1,26 +0,0 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
using DomainResults.Common;
|
||||
|
||||
using MongoDB.Driver;
|
||||
|
||||
using DataProviders.Abstractions;
|
||||
|
||||
namespace DataProviders.Buckets {
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ImagesBucketDataProvider : SpecificBucketDataProviderBase, IBucketDataProvider {
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="logger"></param>
|
||||
/// <param name="client"></param>
|
||||
public ImagesBucketDataProvider(
|
||||
ILogger<BucketDataProviderBase> logger,
|
||||
IMongoClient client
|
||||
) : base(logger, client, "images") { }
|
||||
}
|
||||
}
|
||||
@ -11,7 +11,7 @@ using Core.DomainObjects.Documents;
|
||||
namespace DataProviders.Collections {
|
||||
|
||||
public interface IContentDataProvider {
|
||||
(Content?, IDomainResult) Get(Guid siteId, string locale);
|
||||
(List<Content>?, IDomainResult) Get(Guid siteId);
|
||||
}
|
||||
|
||||
public class ContentDataProvider : CollectionDataProviderBase<Content>, IContentDataProvider {
|
||||
@ -24,14 +24,6 @@ namespace DataProviders.Collections {
|
||||
ISessionService sessionService) : base(logger, client, idGenerator, sessionService) {
|
||||
}
|
||||
|
||||
public (Content?, IDomainResult) Get(Guid siteId, string locale) {
|
||||
var (list, result) = GetWithPredicate(x => x.SiteId == siteId
|
||||
&& (x.Localization.Locale == null || x.Localization.Locale.ToLower() == locale.ToLower()), 0, 0, _collectionName);
|
||||
|
||||
if (!result.IsSuccess || list == null)
|
||||
return (null, result);
|
||||
|
||||
return (list.First(), result);
|
||||
}
|
||||
public (List<Content>?, IDomainResult) Get(Guid siteId) => GetWithPredicate(x => x.SiteId == siteId, _collectionName);
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,7 +29,7 @@ namespace DataProviders.Extensions
|
||||
#endregion
|
||||
|
||||
#region Buckets
|
||||
services.AddSingleton<IBucketDataProvider, ImagesBucketDataProvider>();
|
||||
services.AddSingleton<IImageBucketDataProvider, ImageBucketDataProvider>();
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,107 @@
|
||||
using System;
|
||||
using SixLabors.Fonts;
|
||||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.Drawing.Processing;
|
||||
using SixLabors.ImageSharp.Processing;
|
||||
|
||||
namespace ImageProvider.Extensions {
|
||||
internal static class IImageProcessingContextExtensions {
|
||||
internal static IImageProcessingContext ApplyScalingWaterMark(this IImageProcessingContext processingContext, Font font, string text, Color color, float padding, bool wordwrap) {
|
||||
if (wordwrap) {
|
||||
return processingContext.ApplyScalingWaterMarkWordWrap(font, text, color, padding);
|
||||
}
|
||||
else {
|
||||
return processingContext.ApplyScalingWaterMarkSimple(font, text, color, padding);
|
||||
}
|
||||
}
|
||||
|
||||
internal static IImageProcessingContext ApplyScalingWaterMarkSimple(this IImageProcessingContext processingContext,
|
||||
Font font,
|
||||
string text,
|
||||
Color color,
|
||||
float padding) {
|
||||
Size imgSize = processingContext.GetCurrentSize();
|
||||
|
||||
float targetWidth = imgSize.Width - (padding * 2);
|
||||
float targetHeight = imgSize.Height - (padding * 2);
|
||||
|
||||
// measure the text size
|
||||
FontRectangle size = TextMeasurer.Measure(text, new RendererOptions(font));
|
||||
|
||||
//find out how much we need to scale the text to fill the space (up or down)
|
||||
float scalingFactor = Math.Min(imgSize.Width / size.Width, imgSize.Height / size.Height);
|
||||
|
||||
//create a new font
|
||||
Font scaledFont = new Font(font, scalingFactor * font.Size);
|
||||
|
||||
var center = new PointF(imgSize.Width / 2, imgSize.Height / 2);
|
||||
var textGraphicOptions = new TextGraphicsOptions() {
|
||||
TextOptions = {
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
VerticalAlignment = VerticalAlignment.Center
|
||||
}
|
||||
};
|
||||
return processingContext.DrawText(textGraphicOptions, text, scaledFont, color, center);
|
||||
}
|
||||
|
||||
internal static IImageProcessingContext ApplyScalingWaterMarkWordWrap(this IImageProcessingContext processingContext,
|
||||
Font font,
|
||||
string text,
|
||||
Color color,
|
||||
float padding) {
|
||||
Size imgSize = processingContext.GetCurrentSize();
|
||||
float targetWidth = imgSize.Width - (padding * 2);
|
||||
float targetHeight = imgSize.Height - (padding * 2);
|
||||
|
||||
float targetMinHeight = imgSize.Height - (padding * 3); // must be with in a margin width of the target height
|
||||
|
||||
// now we are working i 2 dimensions at once and can't just scale because it will cause the text to
|
||||
// reflow we need to just try multiple times
|
||||
|
||||
var scaledFont = font;
|
||||
FontRectangle s = new FontRectangle(0, 0, float.MaxValue, float.MaxValue);
|
||||
|
||||
float scaleFactor = (scaledFont.Size / 2); // every time we change direction we half this size
|
||||
int trapCount = (int)scaledFont.Size * 2;
|
||||
if (trapCount < 10) {
|
||||
trapCount = 10;
|
||||
}
|
||||
|
||||
bool isTooSmall = false;
|
||||
|
||||
while ((s.Height > targetHeight || s.Height < targetMinHeight) && trapCount > 0) {
|
||||
if (s.Height > targetHeight) {
|
||||
if (isTooSmall) {
|
||||
scaleFactor = scaleFactor / 2;
|
||||
}
|
||||
|
||||
scaledFont = new Font(scaledFont, scaledFont.Size - scaleFactor);
|
||||
isTooSmall = false;
|
||||
}
|
||||
|
||||
if (s.Height < targetMinHeight) {
|
||||
if (!isTooSmall) {
|
||||
scaleFactor = scaleFactor / 2;
|
||||
}
|
||||
scaledFont = new Font(scaledFont, scaledFont.Size + scaleFactor);
|
||||
isTooSmall = true;
|
||||
}
|
||||
trapCount--;
|
||||
|
||||
s = TextMeasurer.Measure(text, new RendererOptions(scaledFont) {
|
||||
WrappingWidth = targetWidth
|
||||
});
|
||||
}
|
||||
|
||||
var center = new PointF(padding, imgSize.Height / 2);
|
||||
var textGraphicOptions = new TextGraphicsOptions() {
|
||||
TextOptions = {
|
||||
HorizontalAlignment = HorizontalAlignment.Left,
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
WrapTextWidth = targetWidth
|
||||
}
|
||||
};
|
||||
return processingContext.DrawText(textGraphicOptions, text, scaledFont, color, center);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
using SixLabors.Fonts;
|
||||
|
||||
namespace ImageProvider.Extensions {
|
||||
public static class ServiceCollectionExtensions {
|
||||
public static void RegisterImageProvider(this IServiceCollection services) {
|
||||
services.AddSingleton<IFontCollection>(x => {
|
||||
var fontCollection = new FontCollection();
|
||||
|
||||
foreach (var font in Directory.EnumerateFiles(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Fonts"), "*.ttf", SearchOption.AllDirectories))
|
||||
fontCollection.Install(font);
|
||||
|
||||
return fontCollection;
|
||||
});
|
||||
|
||||
services.AddSingleton<IImageProvider, ImageProvider>();
|
||||
}
|
||||
}
|
||||
}
|
||||
23
webapi/Services/ImageProvider/Fonts/FontStylesEnum.cs
Normal file
23
webapi/Services/ImageProvider/Fonts/FontStylesEnum.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using Core.Abstractions;
|
||||
using SixLabors.Fonts;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ImageProvider.Fonts {
|
||||
public class FontStylesEnum : Enumeration {
|
||||
|
||||
public FontStyle FontStyle { get; private set; }
|
||||
|
||||
public static FontStylesEnum Regular = new(0, "Regular", FontStyle.Regular);
|
||||
public static FontStylesEnum Bold = new(0, "Bold", FontStyle.Bold);
|
||||
public static FontStylesEnum Italic = new(0, "Italic", FontStyle.Italic);
|
||||
public static FontStylesEnum BoldItalic = new(0, "BoldItalic", FontStyle.BoldItalic);
|
||||
|
||||
private FontStylesEnum(int id, string displayName, FontStyle fontStyle) : base(id, displayName) {
|
||||
FontStyle = fontStyle;
|
||||
}
|
||||
}
|
||||
}
|
||||
10
webapi/Services/ImageProvider/Fonts/FontsEnum.cs
Normal file
10
webapi/Services/ImageProvider/Fonts/FontsEnum.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using Core.Abstractions;
|
||||
|
||||
namespace ImageProvider.Fonts {
|
||||
public class FontsEnum : Enumeration {
|
||||
|
||||
public static FontsEnum Montserrat = new(0, "Montserrat");
|
||||
|
||||
private FontsEnum(int id, string displayName) : base(id, displayName) { }
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
101
webapi/Services/ImageProvider/ImageBuilder.cs
Normal file
101
webapi/Services/ImageProvider/ImageBuilder.cs
Normal file
@ -0,0 +1,101 @@
|
||||
using SixLabors.Fonts;
|
||||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.Formats;
|
||||
using SixLabors.ImageSharp.Formats.Gif;
|
||||
using SixLabors.ImageSharp.Formats.Jpeg;
|
||||
using SixLabors.ImageSharp.Formats.Pbm;
|
||||
using SixLabors.ImageSharp.Formats.Png;
|
||||
using SixLabors.ImageSharp.Formats.Tga;
|
||||
using SixLabors.ImageSharp.Formats.Tiff;
|
||||
using SixLabors.ImageSharp.Formats.Webp;
|
||||
using SixLabors.ImageSharp.Processing;
|
||||
|
||||
using ImageProvider.Extensions;
|
||||
|
||||
namespace ImageProvider {
|
||||
public class ImageBuilder : IDisposable {
|
||||
|
||||
private Image _image;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="bytes"></param>
|
||||
public ImageBuilder(byte[] bytes) {
|
||||
_image = Image.Load(bytes);
|
||||
}
|
||||
|
||||
public void Load(byte[] bytes) {
|
||||
_image = Image.Load(bytes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="font"> for scaling water mark size is largely ignored.</param>
|
||||
/// <param name="text"></param>
|
||||
public void Watermark(Font font, string text) =>
|
||||
_image = _image.Clone(ctx => ctx.ApplyScalingWaterMark(font, text, Color.HotPink, 5, false));
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="font"> for scaling water mark size is largely ignored.</param>
|
||||
/// <param name="longText"></param>
|
||||
public void WatermarkWordWrap(Font font, string longText) =>
|
||||
_image = _image.Clone(ctx => ctx.ApplyScalingWaterMark(font, longText, Color.HotPink, 5, true));
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="width"></param>
|
||||
/// <param name="height"></param>
|
||||
public void Resize(int width, int height) =>
|
||||
_image.Mutate(img => img.Resize(width, height));
|
||||
|
||||
public void FitWidthResize(int width) {
|
||||
_image.Mutate(x => x.Resize(new ResizeOptions {
|
||||
Size = new Size(width, width),
|
||||
Mode = ResizeMode.Max
|
||||
}));
|
||||
}
|
||||
|
||||
public void FitHeightResize(int height) {
|
||||
_image.Mutate(x => x.Resize(new ResizeOptions {
|
||||
Size = new Size(height, height),
|
||||
Mode = ResizeMode.Max
|
||||
}));
|
||||
}
|
||||
|
||||
public void Crop(int cWidth, int cHeigth) =>
|
||||
Crop((_image.Width - cWidth) / 2, (_image.Height - cHeigth) / 2, cWidth, cHeigth);
|
||||
|
||||
public void Crop(int x, int y, int cWidth, int cHeigth) =>
|
||||
_image.Mutate(img => img.Crop(new Rectangle(x, y, cWidth, cHeigth)));
|
||||
|
||||
|
||||
|
||||
private byte[] Buid(IImageEncoder encoder) {
|
||||
using var ms = new MemoryStream();
|
||||
_image.Save(ms, encoder);
|
||||
|
||||
return ms.ToArray();
|
||||
}
|
||||
|
||||
public byte[] ToGif() => Buid(new GifEncoder());
|
||||
|
||||
public byte[] ToJpeg() => Buid(new JpegEncoder());
|
||||
|
||||
public byte[] ToPbm() => Buid(new PbmEncoder());
|
||||
|
||||
public byte[] ToPng() => Buid(new PngEncoder());
|
||||
|
||||
public byte[] ToTga() => Buid(new TgaEncoder());
|
||||
|
||||
public byte[] ToTiff() => Buid(new TiffEncoder());
|
||||
|
||||
public byte[] ToWebp() => Buid(new WebpEncoder());
|
||||
|
||||
public void Dispose() => _image.Dispose();
|
||||
}
|
||||
}
|
||||
69
webapi/Services/ImageProvider/ImageProvider.cs
Normal file
69
webapi/Services/ImageProvider/ImageProvider.cs
Normal file
@ -0,0 +1,69 @@
|
||||
using DomainResults.Common;
|
||||
using ImageProvider.Fonts;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using SixLabors.Fonts;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ImageProvider {
|
||||
|
||||
public interface IImageProvider {
|
||||
(byte[]?, IDomainResult) Resize(byte[] bytes, int width, int height);
|
||||
(byte[]?, IDomainResult) ResizeAndWatermark(byte[] bytes, int width, int height, FontsEnum fontName, FontStylesEnum fontStyle, string text);
|
||||
}
|
||||
|
||||
public class ImageProvider : IImageProvider {
|
||||
|
||||
private readonly ILogger<ImageProvider> _logger;
|
||||
private readonly IFontCollection _fontCollection;
|
||||
|
||||
public ImageProvider(
|
||||
ILogger<ImageProvider> logger,
|
||||
IFontCollection fontCollection
|
||||
) {
|
||||
_logger = logger;
|
||||
_fontCollection = fontCollection;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="bytes"></param>
|
||||
/// <param name="width"></param>
|
||||
/// <param name="height"></param>
|
||||
/// <returns></returns>
|
||||
public (byte[]?, IDomainResult) Resize(byte[] bytes, int width, int height) {
|
||||
try {
|
||||
using var imageBuilder = new ImageBuilder(bytes);
|
||||
imageBuilder.Resize(width, height);
|
||||
|
||||
return IDomainResult.Success(imageBuilder.ToJpeg());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
_logger.LogError("Unhandled exception", ex);
|
||||
return IDomainResult.Failed<byte[]?>();
|
||||
}
|
||||
}
|
||||
|
||||
public (byte[]?, IDomainResult) ResizeAndWatermark(byte[] bytes, int width, int height, FontsEnum fontName, FontStylesEnum fontStyle, string text) {
|
||||
try {
|
||||
var font = _fontCollection.Families.Single(x => x.Name == fontName.Name)
|
||||
.CreateFont(10, fontStyle.FontStyle);
|
||||
|
||||
using var imageBuilder = new ImageBuilder(bytes);
|
||||
imageBuilder.FitWidthResize(width);
|
||||
imageBuilder.Crop(width, height);
|
||||
// imageBuilder.Watermark(font, text);
|
||||
|
||||
return IDomainResult.Success(imageBuilder.ToJpeg());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
_logger.LogError("Unhandled exception", ex);
|
||||
return IDomainResult.Failed<byte[]?>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
78
webapi/Services/ImageProvider/ImageProvider.csproj
Normal file
78
webapi/Services/ImageProvider/ImageProvider.csproj
Normal file
@ -0,0 +1,78 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="DomainResult.Common" Version="3.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
|
||||
<PackageReference Include="SixLabors.Fonts" Version="1.0.0-beta0013" />
|
||||
<PackageReference Include="SixLabors.ImageSharp" Version="2.1.3" />
|
||||
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta11" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\DataProviders\DataProviders.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="Fonts\Montserrat\Montserrat-Black.ttf">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Fonts\Montserrat\Montserrat-BlackItalic.ttf">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Fonts\Montserrat\Montserrat-Bold.ttf">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Fonts\Montserrat\Montserrat-BoldItalic.ttf">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Fonts\Montserrat\Montserrat-ExtraBold.ttf">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Fonts\Montserrat\Montserrat-ExtraBoldItalic.ttf">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Fonts\Montserrat\Montserrat-ExtraLight.ttf">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Fonts\Montserrat\Montserrat-ExtraLightItalic.ttf">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Fonts\Montserrat\Montserrat-Italic.ttf">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Fonts\Montserrat\Montserrat-Light.ttf">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Fonts\Montserrat\Montserrat-LightItalic.ttf">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Fonts\Montserrat\Montserrat-Medium.ttf">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Fonts\Montserrat\Montserrat-MediumItalic.ttf">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Fonts\Montserrat\Montserrat-Regular.ttf">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Fonts\Montserrat\Montserrat-SemiBold.ttf">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Fonts\Montserrat\Montserrat-SemiBoldItalic.ttf">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Fonts\Montserrat\Montserrat-Thin.ttf">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Fonts\Montserrat\Montserrat-ThinItalic.ttf">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@ -1,5 +0,0 @@
|
||||
namespace ImageService {
|
||||
public class Class1 {
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,9 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
@ -27,7 +27,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExtensionsTests", "Tests\Ex
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CoreTests", "Tests\Core\CoreTests.csproj", "{04CB9827-AA6D-4708-A26D-8420C842506D}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ImageService", "Services\ImageService\ImageService.csproj", "{16552644-D7EE-4B4A-A725-79909A8103DE}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ImageProvider", "Services\ImageProvider\ImageProvider.csproj", "{16552644-D7EE-4B4A-A725-79909A8103DE}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FileSecurityService", "Services\FileSecurityService\FileSecurityService.csproj", "{AD515653-9145-4894-9017-0ABA5A5892F4}"
|
||||
EndProject
|
||||
|
||||
52
webapi/WeatherForecast/Controllers/ImageController.cs
Normal file
52
webapi/WeatherForecast/Controllers/ImageController.cs
Normal file
@ -0,0 +1,52 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
|
||||
using WeatherForecast.Services;
|
||||
using DomainResults.Mvc;
|
||||
|
||||
namespace WeatherForecast.Controllers {
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[AllowAnonymous]
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
public class ImageController : ControllerBase {
|
||||
|
||||
private readonly IImageService _imageService;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="imgeService"></param>
|
||||
public ImageController(
|
||||
IImageService imgeService
|
||||
) {
|
||||
_imageService = imgeService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="siteId"></param>
|
||||
/// <param name="width"></param>
|
||||
/// <param name="height"></param>
|
||||
/// <param name="imageId"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{siteId}/{width}x{height}/{imageId}")]
|
||||
public IActionResult Get([FromRoute] Guid siteId, [FromRoute] int width, [FromRoute] int height, [FromRoute] Guid imageId) {
|
||||
|
||||
var (file, result) = _imageService.Get(siteId, width, height, imageId);
|
||||
|
||||
if (!result.IsSuccess || file == null)
|
||||
return result.ToActionResult();
|
||||
|
||||
var stream = new MemoryStream(file.Bytes);
|
||||
return new FileStreamResult(stream, file.ContentType) {
|
||||
FileDownloadName = file.Name
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -49,11 +49,10 @@ namespace WeatherForecast.Models.Requests {
|
||||
|
||||
return new ShopItem() {
|
||||
L10n = L10n.Select(x => x.ToDomainObject()).ToList(),
|
||||
// Images
|
||||
MediaAttachments = MediaAttachments?.Select(x => x.ToDomainObject()).ToList(),
|
||||
// Author
|
||||
Created = DateTime.UtcNow,
|
||||
Tags = Tags,
|
||||
Categories = Categories,
|
||||
FamilyFriendly = FamilyFriendly,
|
||||
|
||||
BrandName = BrandName,
|
||||
|
||||
@ -87,12 +87,12 @@ namespace WeatherForecast.Services {
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="siteId"></param>
|
||||
/// <param name="requestModel"></param>
|
||||
/// <param name="requestData"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public (Guid?, IDomainResult) Post(Guid siteId, BlogItemRequestModel requestModel) {
|
||||
public (Guid?, IDomainResult) Post(Guid siteId, BlogItemRequestModel requestData) {
|
||||
try {
|
||||
var item = requestModel.ToDomainObject();
|
||||
var item = requestData.ToDomainObject();
|
||||
item.SiteId = siteId;
|
||||
|
||||
var (_, getResult) = _blogCatalogDataProvider.GetBySlugs(item.SiteId, item.L10n.Select(x => x.Slug).ToList());
|
||||
@ -102,7 +102,7 @@ namespace WeatherForecast.Services {
|
||||
// TODO: should be recovered from users by jwt
|
||||
item.Author = "fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60".ToGuid();
|
||||
|
||||
var (categories, addCategoriesResult) = AddCategoryIfNullOrEmpty(siteId, item.Categories);
|
||||
var (categories, addCategoriesResult) = AddCategoryIfNullOrEmpty(siteId, requestData.Categories);
|
||||
if (!addCategoriesResult.IsSuccess || categories == null)
|
||||
return (null, addCategoriesResult);
|
||||
|
||||
@ -194,7 +194,7 @@ namespace WeatherForecast.Services {
|
||||
newItem.Created = item.Created;
|
||||
newItem.Author = item.Author;
|
||||
|
||||
var (categories, addCategoriesResult) = AddCategoryIfNullOrEmpty(siteId, item.Categories);
|
||||
var (categories, addCategoriesResult) = AddCategoryIfNullOrEmpty(siteId, requestData.Categories);
|
||||
if (!addCategoriesResult.IsSuccess || categories == null)
|
||||
return (null, addCategoriesResult);
|
||||
|
||||
|
||||
@ -49,12 +49,11 @@ namespace WeatherForecast.Services {
|
||||
/// <returns></returns>
|
||||
public (ContentResponseModel?, IDomainResult) GetContent(Guid siteId, string locale) {
|
||||
try {
|
||||
var (content, result) = _contentDataProvider.Get(siteId, locale);
|
||||
|
||||
var (content, result) = _contentDataProvider.Get(siteId);
|
||||
if (!result.IsSuccess || content == null)
|
||||
return (null, result);
|
||||
|
||||
return IDomainResult.Success(new ContentResponseModel(content));
|
||||
return IDomainResult.Success(new ContentResponseModel(content.Single(x => x.Localization.Locale == locale)));
|
||||
}
|
||||
catch (Exception ex) {
|
||||
_logger.LogError(ex, "Unhandled exception");
|
||||
|
||||
@ -44,7 +44,7 @@ namespace WeatherForecast.Services {
|
||||
|
||||
private readonly ILogger<FilesService> _logger;
|
||||
private readonly IFilesService _filesService;
|
||||
private readonly IBucketDataProvider _imageBucketDataProvider;
|
||||
private readonly IImageBucketDataProvider _imageBucketDataProvider;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
@ -55,7 +55,7 @@ namespace WeatherForecast.Services {
|
||||
public FileService(
|
||||
ILogger<FilesService> logger,
|
||||
IFilesService filesService,
|
||||
IBucketDataProvider imageBucketDataProvider
|
||||
IImageBucketDataProvider imageBucketDataProvider
|
||||
) {
|
||||
_logger = logger;
|
||||
_filesService = filesService;
|
||||
|
||||
@ -35,7 +35,7 @@ namespace WeatherForecast.Services {
|
||||
|
||||
private readonly ILogger<FilesService> _logger;
|
||||
private readonly IFileSecurityService _fileSecurityService;
|
||||
private readonly IBucketDataProvider _imageBucketDataProvider;
|
||||
private readonly IImageBucketDataProvider _imageBucketDataProvider;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
@ -45,7 +45,7 @@ namespace WeatherForecast.Services {
|
||||
public FilesService(
|
||||
ILogger<FilesService> logger,
|
||||
IFileSecurityService fileSecurityService,
|
||||
IBucketDataProvider imageBucketDataProvider
|
||||
IImageBucketDataProvider imageBucketDataProvider
|
||||
) {
|
||||
_logger = logger;
|
||||
_fileSecurityService = fileSecurityService;
|
||||
|
||||
88
webapi/WeatherForecast/Services/ImageService.cs
Normal file
88
webapi/WeatherForecast/Services/ImageService.cs
Normal file
@ -0,0 +1,88 @@
|
||||
|
||||
using DataProviders;
|
||||
using DataProviders.Buckets;
|
||||
using DataProviders.Collections;
|
||||
using DomainResults.Common;
|
||||
using ImageProvider;
|
||||
using ImageProvider.Fonts;
|
||||
|
||||
namespace WeatherForecast.Services {
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public interface IImageService {
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="siteId"></param>
|
||||
/// <param name="width"></param>
|
||||
/// <param name="height"></param>
|
||||
/// <param name="imageId"></param>
|
||||
/// <returns></returns>
|
||||
(BucketFile?, IDomainResult) Get(Guid siteId, int width, int height, Guid imageId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ImageService : IImageService {
|
||||
|
||||
private readonly ILogger<ImageService> _logger;
|
||||
private readonly IImageBucketDataProvider _imageBucketDataProvider;
|
||||
private readonly IImageProvider _imageProvider;
|
||||
private readonly IContentDataProvider _contentDataProvider;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="logger"></param>
|
||||
/// <param name="imageBucketDataProvider"></param>
|
||||
/// <param name="imageProvider"></param>
|
||||
public ImageService(
|
||||
ILogger<ImageService> logger,
|
||||
IImageBucketDataProvider imageBucketDataProvider,
|
||||
IImageProvider imageProvider,
|
||||
IContentDataProvider contentDataProvider
|
||||
|
||||
) {
|
||||
_logger = logger;
|
||||
_imageBucketDataProvider = imageBucketDataProvider;
|
||||
_imageProvider = imageProvider;
|
||||
_contentDataProvider = contentDataProvider;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="siteId"></param>
|
||||
/// <param name="width"></param>
|
||||
/// <param name="height"></param>
|
||||
/// <param name="imageId"></param>
|
||||
/// <returns></returns>
|
||||
public (BucketFile?, IDomainResult) Get(Guid siteId, int width, int height, Guid imageId) {
|
||||
try {
|
||||
var (file, downloadResult) = _imageBucketDataProvider.Download(siteId, imageId);
|
||||
if (!downloadResult.IsSuccess || file == null)
|
||||
return IDomainResult.Failed<BucketFile?> ();
|
||||
|
||||
var (content, getContentResult) = _contentDataProvider.Get(siteId);
|
||||
if (!getContentResult.IsSuccess || content == null)
|
||||
return IDomainResult.Failed<BucketFile?>();
|
||||
|
||||
var (image, transformResult) = _imageProvider.ResizeAndWatermark(file.Bytes, width, height, FontsEnum.Montserrat, FontStylesEnum.Regular, content.First().SiteName);
|
||||
if (!transformResult.IsSuccess || image == null)
|
||||
return IDomainResult.Failed<BucketFile?>();
|
||||
|
||||
return IDomainResult.Success(new BucketFile(file.Name, image, "image/jpeg"));
|
||||
}
|
||||
catch (Exception ex) {
|
||||
_logger.LogError(ex, "Unhandled exception");
|
||||
return IDomainResult.Failed<BucketFile?> (ex.Message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@ -89,11 +89,11 @@ namespace WeatherForecast.Services {
|
||||
/// </summary>
|
||||
/// <param name="siteId"></param>
|
||||
/// <param name="sku"></param>
|
||||
/// <param name="requestModel"></param>
|
||||
/// <param name="requestData"></param>
|
||||
/// <returns></returns>
|
||||
public (Guid?, IDomainResult) Post(Guid siteId, string sku, ShopItemRequestModel requestModel) {
|
||||
public (Guid?, IDomainResult) Post(Guid siteId, string sku, ShopItemRequestModel requestData) {
|
||||
try {
|
||||
var item = requestModel.ToDomainObject();
|
||||
var item = requestData.ToDomainObject();
|
||||
|
||||
item.SiteId = siteId;
|
||||
item.Sku = sku;
|
||||
@ -105,7 +105,7 @@ namespace WeatherForecast.Services {
|
||||
// TODO: should be recovered from users by jwt
|
||||
item.Author = "fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60".ToGuid();
|
||||
|
||||
var (categories, addCategoriesResult) = AddCategoryIfNullOrEmpty(siteId, item.Categories);
|
||||
var (categories, addCategoriesResult) = AddCategoryIfNullOrEmpty(siteId, requestData.Categories);
|
||||
if (!addCategoriesResult.IsSuccess || categories == null)
|
||||
return (null, addCategoriesResult);
|
||||
|
||||
@ -197,7 +197,7 @@ namespace WeatherForecast.Services {
|
||||
newItem.Created = item.Created;
|
||||
newItem.Author = item.Author;
|
||||
|
||||
var (categories, addCategoriesResult) = AddCategoryIfNullOrEmpty(siteId, item.Categories);
|
||||
var (categories, addCategoriesResult) = AddCategoryIfNullOrEmpty(siteId, requestData.Categories);
|
||||
if (!addCategoriesResult.IsSuccess || categories == null)
|
||||
return (null, addCategoriesResult);
|
||||
|
||||
|
||||
@ -7,6 +7,7 @@ using WeatherForecast.Services;
|
||||
using DataProviders.Extensions;
|
||||
using System.Text.Json.Serialization;
|
||||
using FileSecurityService.Extensions;
|
||||
using ImageProvider.Extensions;
|
||||
|
||||
namespace WeatherForecast {
|
||||
|
||||
@ -83,9 +84,11 @@ namespace WeatherForecast {
|
||||
|
||||
services.AddScoped<IFileService, FileService>();
|
||||
services.AddScoped<IFilesService, FilesService>();
|
||||
services.AddScoped<IImageService, ImageService>();
|
||||
|
||||
services.RegisterDataproviders(appSettings);
|
||||
services.RegisterFileSecurityService();
|
||||
services.RegisterImageProvider();
|
||||
|
||||
#region Swagger
|
||||
services.ConfigureSwaggerGen(options => {
|
||||
|
||||
@ -29,6 +29,7 @@
|
||||
<ProjectReference Include="..\DataProviders\DataProviders.csproj" />
|
||||
<ProjectReference Include="..\Extensions\Extensions.csproj" />
|
||||
<ProjectReference Include="..\Services\FileSecurityService\FileSecurityService.csproj" />
|
||||
<ProjectReference Include="..\Services\ImageProvider\ImageProvider.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user