mirror of
https://repository.entgra.net/community/device-mgt-core.git
synced 2025-10-06 02:01:45 +00:00
Merge branch 'application-mgt-new' of https://gitlab.com/entgra/carbon-device-mgt into application-mgt-new
This commit is contained in:
commit
7f70dd96e0
@ -0,0 +1,41 @@
|
|||||||
|
/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
|
||||||
|
* Version 2.0 (the "License"); you may not use this file except
|
||||||
|
* in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.wso2.carbon.device.application.mgt.common.response;
|
||||||
|
|
||||||
|
public class Category {
|
||||||
|
|
||||||
|
private String categoryName;
|
||||||
|
|
||||||
|
private boolean isCategoryDeletable;
|
||||||
|
|
||||||
|
public String getCategoryName() {
|
||||||
|
return categoryName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCategoryName(String categoryName) {
|
||||||
|
this.categoryName = categoryName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCategoryDeletable() {
|
||||||
|
return isCategoryDeletable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCategoryDeletable(boolean categoryDeletable) {
|
||||||
|
isCategoryDeletable = categoryDeletable;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,41 @@
|
|||||||
|
/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
|
||||||
|
* Version 2.0 (the "License"); you may not use this file except
|
||||||
|
* in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.wso2.carbon.device.application.mgt.common.response;
|
||||||
|
|
||||||
|
public class Tag {
|
||||||
|
|
||||||
|
private String tagName;
|
||||||
|
|
||||||
|
private boolean isTagDeletable;
|
||||||
|
|
||||||
|
public String getTagName() {
|
||||||
|
return tagName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTagName(String tagName) {
|
||||||
|
this.tagName = tagName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isTagDeletable() {
|
||||||
|
return isTagDeletable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTagDeletable(boolean tagDeletable) {
|
||||||
|
isTagDeletable = tagDeletable;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -29,6 +29,8 @@ import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManage
|
|||||||
import org.wso2.carbon.device.application.mgt.common.exception.RequestValidatingException;
|
import org.wso2.carbon.device.application.mgt.common.exception.RequestValidatingException;
|
||||||
import org.wso2.carbon.device.application.mgt.common.response.Application;
|
import org.wso2.carbon.device.application.mgt.common.response.Application;
|
||||||
import org.wso2.carbon.device.application.mgt.common.response.ApplicationRelease;
|
import org.wso2.carbon.device.application.mgt.common.response.ApplicationRelease;
|
||||||
|
import org.wso2.carbon.device.application.mgt.common.response.Category;
|
||||||
|
import org.wso2.carbon.device.application.mgt.common.response.Tag;
|
||||||
import org.wso2.carbon.device.application.mgt.common.wrapper.ApplicationReleaseWrapper;
|
import org.wso2.carbon.device.application.mgt.common.wrapper.ApplicationReleaseWrapper;
|
||||||
import org.wso2.carbon.device.application.mgt.common.wrapper.ApplicationUpdateWrapper;
|
import org.wso2.carbon.device.application.mgt.common.wrapper.ApplicationUpdateWrapper;
|
||||||
import org.wso2.carbon.device.application.mgt.common.wrapper.ApplicationWrapper;
|
import org.wso2.carbon.device.application.mgt.common.wrapper.ApplicationWrapper;
|
||||||
@ -228,4 +230,8 @@ public interface ApplicationManager {
|
|||||||
|
|
||||||
void addAplicationCategories(List<String> categories) throws ApplicationManagementException;
|
void addAplicationCategories(List<String> categories) throws ApplicationManagementException;
|
||||||
|
|
||||||
}
|
List<Tag> getRegisteredTags() throws ApplicationManagementException;
|
||||||
|
|
||||||
|
List<Category> getRegisteredCategories() throws ApplicationManagementException;
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@ -53,6 +53,8 @@ public interface ApplicationDAO {
|
|||||||
|
|
||||||
List<Integer> getTagIdsForTagNames (List<String> tagNames, int tenantId) throws ApplicationManagementDAOException;
|
List<Integer> getTagIdsForTagNames (List<String> tagNames, int tenantId) throws ApplicationManagementDAOException;
|
||||||
|
|
||||||
|
List<Integer> getDistinctTagIdsInTagMapping() throws ApplicationManagementDAOException;
|
||||||
|
|
||||||
void addTagMapping (List<Integer> tagIds, int applicationId, int tenantId) throws ApplicationManagementDAOException;
|
void addTagMapping (List<Integer> tagIds, int applicationId, int tenantId) throws ApplicationManagementDAOException;
|
||||||
|
|
||||||
List<String> getAppTags(int appId, int tenantId) throws ApplicationManagementDAOException;
|
List<String> getAppTags(int appId, int tenantId) throws ApplicationManagementDAOException;
|
||||||
@ -65,6 +67,8 @@ public interface ApplicationDAO {
|
|||||||
|
|
||||||
List<CategoryDTO> getAllCategories(int tenantId) throws ApplicationManagementDAOException;
|
List<CategoryDTO> getAllCategories(int tenantId) throws ApplicationManagementDAOException;
|
||||||
|
|
||||||
|
List<Integer> getDistinctCategoryIdsInCategoryMapping() throws ApplicationManagementDAOException;
|
||||||
|
|
||||||
void addCategories(List<String> categories, int tenantId) throws ApplicationManagementDAOException;
|
void addCategories(List<String> categories, int tenantId) throws ApplicationManagementDAOException;
|
||||||
|
|
||||||
void addCategoryMapping(List<Integer> categoryIds, int applicationId, int tenantId)
|
void addCategoryMapping(List<Integer> categoryIds, int applicationId, int tenantId)
|
||||||
|
|||||||
@ -746,6 +746,34 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Integer> getDistinctCategoryIdsInCategoryMapping() throws ApplicationManagementDAOException {
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
|
log.debug("Request received in DAO Layer to get distinct category ids for given tag names");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Connection conn = this.getDBConnection();
|
||||||
|
List<Integer> distinctCategoryIds = new ArrayList<>();
|
||||||
|
String sql = "SELECT DISTINCT AP_APP_CATEGORY.ID AS ID FROM AP_APP_CATEGORY";
|
||||||
|
try (PreparedStatement ps = conn.prepareStatement(sql)) {
|
||||||
|
try (ResultSet rs = ps.executeQuery()) {
|
||||||
|
while (rs.next()) {
|
||||||
|
distinctCategoryIds.add(rs.getInt("ID"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return distinctCategoryIds;
|
||||||
|
} catch (DBConnectionException e) {
|
||||||
|
throw new ApplicationManagementDAOException(
|
||||||
|
"Error occurred while obtaining the DB connection when getting distinct category ids in tag mapping",
|
||||||
|
e);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new ApplicationManagementDAOException(
|
||||||
|
"Error occurred while getting distinct category ids in tag mapping", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addCategories(List<String> categories, int tenantId) throws ApplicationManagementDAOException {
|
public void addCategories(List<String> categories, int tenantId) throws ApplicationManagementDAOException {
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
@ -872,6 +900,31 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Integer> getDistinctTagIdsInTagMapping() throws ApplicationManagementDAOException {
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
|
log.debug("Request received in DAO Layer to get distinct tag ids for given tag names");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Connection conn = this.getDBConnection();
|
||||||
|
List<Integer> distinctTagIds = new ArrayList<>();
|
||||||
|
String sql = "SELECT DISTINCT AP_APP_TAG.ID AS ID FROM AP_APP_TAG";
|
||||||
|
try (PreparedStatement ps = conn.prepareStatement(sql)) {
|
||||||
|
try (ResultSet rs = ps.executeQuery()) {
|
||||||
|
while (rs.next()) {
|
||||||
|
distinctTagIds.add(rs.getInt("ID"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return distinctTagIds;
|
||||||
|
} catch (DBConnectionException e) {
|
||||||
|
throw new ApplicationManagementDAOException(
|
||||||
|
"Error occurred while obtaining the DB connection when getting distinct tag ids in tag mapping", e);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new ApplicationManagementDAOException("Error occurred while getting distinct tag ids in tag mapping", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void addTagMapping (List<Integer> tagIds, int applicationId, int tenantId) throws ApplicationManagementDAOException {
|
public void addTagMapping (List<Integer> tagIds, int applicationId, int tenantId) throws ApplicationManagementDAOException {
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("Request received in DAO Layer to add tags");
|
log.debug("Request received in DAO Layer to add tags");
|
||||||
|
|||||||
@ -50,6 +50,8 @@ import org.wso2.carbon.device.application.mgt.common.exception.ResourceManagemen
|
|||||||
import org.wso2.carbon.device.application.mgt.common.exception.TransactionManagementException;
|
import org.wso2.carbon.device.application.mgt.common.exception.TransactionManagementException;
|
||||||
import org.wso2.carbon.device.application.mgt.common.response.Application;
|
import org.wso2.carbon.device.application.mgt.common.response.Application;
|
||||||
import org.wso2.carbon.device.application.mgt.common.response.ApplicationRelease;
|
import org.wso2.carbon.device.application.mgt.common.response.ApplicationRelease;
|
||||||
|
import org.wso2.carbon.device.application.mgt.common.response.Category;
|
||||||
|
import org.wso2.carbon.device.application.mgt.common.response.Tag;
|
||||||
import org.wso2.carbon.device.application.mgt.common.services.ApplicationManager;
|
import org.wso2.carbon.device.application.mgt.common.services.ApplicationManager;
|
||||||
import org.wso2.carbon.device.application.mgt.common.services.ApplicationStorageManager;
|
import org.wso2.carbon.device.application.mgt.common.services.ApplicationStorageManager;
|
||||||
import org.wso2.carbon.device.application.mgt.common.wrapper.ApplicationReleaseWrapper;
|
import org.wso2.carbon.device.application.mgt.common.wrapper.ApplicationReleaseWrapper;
|
||||||
@ -1845,6 +1847,57 @@ public class ApplicationManagerImpl implements ApplicationManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Tag> getRegisteredTags() throws ApplicationManagementException {
|
||||||
|
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
|
||||||
|
try {
|
||||||
|
ConnectionManagerUtil.openDBConnection();
|
||||||
|
List<TagDTO> tags = applicationDAO.getAllTags(tenantId);
|
||||||
|
List<Integer> mappedTagIds = applicationDAO.getDistinctTagIdsInTagMapping();
|
||||||
|
List<Tag> responseTagList = new ArrayList<>();
|
||||||
|
tags.forEach(tag -> {
|
||||||
|
Tag responseTag = new Tag();
|
||||||
|
if (!mappedTagIds.contains(tag.getId())) {
|
||||||
|
responseTag.setTagDeletable(true);
|
||||||
|
}
|
||||||
|
responseTag.setTagName(tag.getTagName());
|
||||||
|
responseTagList.add(responseTag);
|
||||||
|
});
|
||||||
|
return responseTagList;
|
||||||
|
} catch (ApplicationManagementDAOException e) {
|
||||||
|
String msg = "Error occurred when getting registered tags from the system.";
|
||||||
|
log.error(msg);
|
||||||
|
throw new ApplicationManagementException(msg);
|
||||||
|
} finally {
|
||||||
|
ConnectionManagerUtil.closeDBConnection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Category> getRegisteredCategories() throws ApplicationManagementException {
|
||||||
|
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
|
||||||
|
try {
|
||||||
|
ConnectionManagerUtil.openDBConnection();
|
||||||
|
List<CategoryDTO> categories = applicationDAO.getAllCategories(tenantId);
|
||||||
|
List<Integer> mappedCategoryIds = applicationDAO.getDistinctCategoryIdsInCategoryMapping();
|
||||||
|
List<Category> responseCategoryList = new ArrayList<>();
|
||||||
|
categories.forEach(category -> {
|
||||||
|
Category responseCategory = new Category();
|
||||||
|
if (!mappedCategoryIds.contains(category.getId())) {
|
||||||
|
responseCategory.setCategoryDeletable(true);
|
||||||
|
}
|
||||||
|
responseCategory.setCategoryName(category.getCategoryName());
|
||||||
|
responseCategoryList.add(responseCategory);
|
||||||
|
});
|
||||||
|
return responseCategoryList;
|
||||||
|
} catch (ApplicationManagementDAOException e) {
|
||||||
|
String msg = "Error occurred when getting registered tags from the system.";
|
||||||
|
log.error(msg);
|
||||||
|
throw new ApplicationManagementException(msg);
|
||||||
|
} finally {
|
||||||
|
ConnectionManagerUtil.closeDBConnection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void validateFilter(Filter filter) throws BadRequestException {
|
private void validateFilter(Filter filter) throws BadRequestException {
|
||||||
if (filter == null) {
|
if (filter == null) {
|
||||||
String msg = "Filter validation is failed, Filter shouldn't be null, hence please verify the request payload";
|
String msg = "Filter validation is failed, Filter shouldn't be null, hence please verify the request payload";
|
||||||
|
|||||||
@ -29,7 +29,6 @@ import org.wso2.carbon.user.api.UserRealm;
|
|||||||
import org.wso2.carbon.user.api.UserStoreException;
|
import org.wso2.carbon.user.api.UserStoreException;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
|||||||
@ -772,11 +772,6 @@ public interface ApplicationManagementPublisherAPI {
|
|||||||
code = 200,
|
code = 200,
|
||||||
message = "OK. \n Successfully got Lifecycle Config.",
|
message = "OK. \n Successfully got Lifecycle Config.",
|
||||||
response = ApplicationList.class),
|
response = ApplicationList.class),
|
||||||
@ApiResponse(
|
|
||||||
code = 404,
|
|
||||||
message = "Not Found. There doesn't have an defined <LifecycleStates> in app management "
|
|
||||||
+ "configuration file." +
|
|
||||||
"query."),
|
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
code = 500,
|
code = 500,
|
||||||
message = "Internal Server Error. \n Error occurred while getting the lifecycle config.",
|
message = "Internal Server Error. \n Error occurred while getting the lifecycle config.",
|
||||||
@ -784,4 +779,62 @@ public interface ApplicationManagementPublisherAPI {
|
|||||||
})
|
})
|
||||||
Response getLifecycleConfig();
|
Response getLifecycleConfig();
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/tags")
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@ApiOperation(
|
||||||
|
consumes = MediaType.APPLICATION_JSON,
|
||||||
|
produces = MediaType.APPLICATION_JSON,
|
||||||
|
httpMethod = "GET",
|
||||||
|
value = "get registered application tags",
|
||||||
|
notes = "This will get registered application tags",
|
||||||
|
tags = "Application Management",
|
||||||
|
extensions = {
|
||||||
|
@Extension(properties = {
|
||||||
|
@ExtensionProperty(name = SCOPE, value = "perm:app:publisher:update")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
@ApiResponses(
|
||||||
|
value = {
|
||||||
|
@ApiResponse(
|
||||||
|
code = 200,
|
||||||
|
message = "OK. \n Successfully got Application tags.",
|
||||||
|
response = ApplicationList.class),
|
||||||
|
@ApiResponse(
|
||||||
|
code = 500,
|
||||||
|
message = "Internal Server Error. \n Error occurred while getting application tags.",
|
||||||
|
response = ErrorResponse.class)
|
||||||
|
})
|
||||||
|
Response getTags();
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/categories")
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@ApiOperation(
|
||||||
|
consumes = MediaType.APPLICATION_JSON,
|
||||||
|
produces = MediaType.APPLICATION_JSON,
|
||||||
|
httpMethod = "GET",
|
||||||
|
value = "get registered application categories",
|
||||||
|
notes = "This will get registered application categories.",
|
||||||
|
tags = "Application Management",
|
||||||
|
extensions = {
|
||||||
|
@Extension(properties = {
|
||||||
|
@ExtensionProperty(name = SCOPE, value = "perm:app:publisher:update")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
@ApiResponses(
|
||||||
|
value = {
|
||||||
|
@ApiResponse(
|
||||||
|
code = 200,
|
||||||
|
message = "OK. \n Successfully got application categories.",
|
||||||
|
response = ApplicationList.class),
|
||||||
|
@ApiResponse(
|
||||||
|
code = 500,
|
||||||
|
message = "Internal Server Error. \n Error occurred while getting application categories.",
|
||||||
|
response = ErrorResponse.class)
|
||||||
|
})
|
||||||
|
Response getCategories();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,6 +27,8 @@ import org.wso2.carbon.device.application.mgt.common.exception.LifecycleManageme
|
|||||||
import org.wso2.carbon.device.application.mgt.common.exception.RequestValidatingException;
|
import org.wso2.carbon.device.application.mgt.common.exception.RequestValidatingException;
|
||||||
import org.wso2.carbon.device.application.mgt.common.response.Application;
|
import org.wso2.carbon.device.application.mgt.common.response.Application;
|
||||||
import org.wso2.carbon.device.application.mgt.common.response.ApplicationRelease;
|
import org.wso2.carbon.device.application.mgt.common.response.ApplicationRelease;
|
||||||
|
import org.wso2.carbon.device.application.mgt.common.response.Category;
|
||||||
|
import org.wso2.carbon.device.application.mgt.common.response.Tag;
|
||||||
import org.wso2.carbon.device.application.mgt.common.services.AppmDataHandler;
|
import org.wso2.carbon.device.application.mgt.common.services.AppmDataHandler;
|
||||||
import org.wso2.carbon.device.application.mgt.common.wrapper.ApplicationReleaseWrapper;
|
import org.wso2.carbon.device.application.mgt.common.wrapper.ApplicationReleaseWrapper;
|
||||||
import org.wso2.carbon.device.application.mgt.common.wrapper.ApplicationUpdateWrapper;
|
import org.wso2.carbon.device.application.mgt.common.wrapper.ApplicationUpdateWrapper;
|
||||||
@ -476,6 +478,38 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Override
|
||||||
|
@Consumes("application/json")
|
||||||
|
@Path("/tags")
|
||||||
|
public Response getTags() {
|
||||||
|
ApplicationManager applicationManager = APIUtil.getApplicationManager();
|
||||||
|
try {
|
||||||
|
List<Tag> tags = applicationManager.getRegisteredTags();
|
||||||
|
return Response.status(Response.Status.OK).entity(tags).build();
|
||||||
|
} catch (ApplicationManagementException e) {
|
||||||
|
String msg = "Error Occurred while getting registered tags.";
|
||||||
|
log.error(msg);
|
||||||
|
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Override
|
||||||
|
@Consumes("application/json")
|
||||||
|
@Path("/categories")
|
||||||
|
public Response getCategories() {
|
||||||
|
ApplicationManager applicationManager = APIUtil.getApplicationManager();
|
||||||
|
try {
|
||||||
|
List<Category> categories = applicationManager.getRegisteredCategories();
|
||||||
|
return Response.status(Response.Status.OK).entity(categories).build();
|
||||||
|
} catch (ApplicationManagementException e) {
|
||||||
|
String msg = "Error Occurred while getting registered categories.";
|
||||||
|
log.error(msg);
|
||||||
|
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* Construct the screenshot list by evaluating the availability of each screenshot.
|
* Construct the screenshot list by evaluating the availability of each screenshot.
|
||||||
*
|
*
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user