#112 Anonymous Scopes

本文介绍了一种使用动态范围和匿名作用域来改进高级搜索表单条件逻辑的方法。通过 ActiveRecord 的 scoped 方法,可以灵活地生成带有条件的查询,这些条件可以根据用户输入的关键词、价格范围和类别进行调整。
The scoped method allows you to generate named scopes on the fly. In this episode I show how to use anonymous scopes to improve the conditional logic which was used in the previous episode on advanced search form.
# config/initializers/global_named_scopes.rb
class ActiveRecord::Base
named_scope :conditions, lambda { |*args| {:conditions => args} }
end

# models/search.rb
def find_products
scope = Product.scoped({})
scope = scope.conditions "products.name LIKE ?", "%#{keywords}%" unless keywords.blank?
scope = scope.conditions "products.price >= ?", minimum_price unless minimum_price.blank?
scope = scope.conditions "products.price <= ?", maximum_price unless maximum_price.blank?
scope = scope.conditions "products.category_id = ?", category_id unless category_id.blank?
scope
end
/****************************************************************************** * Copyright (c) 2018-2018 TP-Link Systems Inc. * * Filename: soap_wsdd.c * Version: 1.0 * Description: soap 处理函数头文件 * Author: liyijie<liyijie@tp-link.com.cn> * Date: 2018-10-30 ******************************************************************************/ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <arpa/inet.h> #include "soap_global.h" #include "soap_parse.h" #include "soap_pack.h" #include "soap_wsdd.h" /****************************************************************************** * 函数名称: soap_check_scope() * 函数描述: 检查输入的scope是否在设备保存的scope列表内 * 输 入: scopes -- 输入的scope字串 * 输 出: N/A * 返 回 值: TRUE/FALSE ******************************************************************************/ LOCAL S32 soap_check_scope(char *scopes) { int i = 0; S32 flag = -1; S32 len = 0; char *s = NULL; char *e = NULL; char *t = NULL; SOAP_NODE *node = NULL; if (scopes == NULL) { return 0; } if (strnlen(scopes, 1) == 0) { return 0; } for (t = scopes; t && strnlen(t, 1); t++) { e = (char *)strchr(t, &#39; &#39;); if (e != NULL) { len = e - t; } else { len = strlen(scopes) - (t - scopes); } if (len <= 0) { break; } for (i = 0; i < FIX_SCOPE_NUM; i++) { s = G_TP_FIXED_SCOPE[i]; if ( 0 == strncmp(s, t, len) && (&#39;/&#39; == *(s + len) || &#39;\0&#39; == *(s + len)) ) { flag = 0; break; } } if (0 == flag) { break; } for (node = g_scope_list; node; node = node->next) { s = (char*)node->data; if (0 == strncmp(s, t, len) && (&#39;/&#39; == *(s + len) || &#39;\0&#39; == *(s + len))) { flag = 0; break; } } if ( 0 == flag ) { break; } if (NULL != e) { t = strchr(e, &#39; &#39;); } else { t = NULL; } if (!t) { break; } } return flag; } LOCAL S32 soap_out_scopes_item(ONVIF_BUF *xml_buf) { SOAP_NODE *node = NULL; char scope_string[FIX_SCOPE_NUM * LEN_INFO + FIX_SCOPE_NUM] = {0}; if (xml_buf == NULL) { ONVIF_WARN("xml_buf == NULL."); return ERROR; } /* wsdd:Scopes begin */ SOAP_IF_FAIL_RET(soap_element_begin_out(xml_buf, "wsdd:Scopes", NULL)); snprintf(scope_string, sizeof(scope_string), "%s %s %s %s %s", G_TP_FIXED_SCOPE[0], G_TP_FIXED_SCOPE[1], G_TP_FIXED_SCOPE[2], G_TP_FIXED_SCOPE[3], G_TP_FIXED_SCOPE[4]); SOAP_IF_FAIL_RET(onvif_buf_append_string(xml_buf, scope_string, strlen(scope_string))); for (node = g_scope_list; node; node = node->next) { if (node->data != NULL) { SOAP_IF_FAIL_RET(onvif_buf_append_string(xml_buf, " ", 1)); SOAP_IF_FAIL_RET(onvif_buf_append_string(xml_buf, (char *)node->data, strlen((char *)node->data))); } } /* wsdd:Scopes end */ SOAP_IF_FAIL_RET(soap_element_end_out(xml_buf, "wsdd:Scopes")); return OK; } /****************************************************************************** * 函数名称: soap_out_wsdd_hello_type() * 函数描述: 组装wsdd:Hello element内容 * 输 入: xml_buf -- 存放输出xml字串的内存地址 * data -- 为空 * 输 出: N/A * 返 回 值: ERROR/OK ******************************************************************************/ LOCAL S32 soap_out_wsdd_hello_type(ONVIF_BUF *xml_buf, void *data) { S32 len = 0; char tmp_str[LEN_INFO] = {0}; char ip_str[LEN_IP] = {0}; char mac_str[LEN_MAC] = {0}; if (xml_buf == NULL) { ONVIF_WARN("xml_buf == NULL."); return ERROR; } SOAP_IF_FAIL_RET(onvif_get_ip_str(ip_str, LEN_IP)); SOAP_IF_FAIL_RET(onvif_get_mac_str(mac_str, LEN_MAC, FALSE)); /* wsdd:Hello begin */ SOAP_IF_FAIL_RET(soap_element_begin_out(xml_buf, "wsdd:Hello", NULL)); /* wsa:EndpointReference */ len = snprintf(tmp_str, sizeof(tmp_str), "uuid:%s%s", UUID_PREFIX_FMAT, mac_str); if (len < 0 || len >= sizeof(tmp_str)) { return ERROR; } SOAP_IF_FAIL_RET(soap_out_wsa_endpoint_reference(xml_buf, "wsa:EndpointReference", tmp_str)); /* wsdd:Types */ SOAP_IF_FAIL_RET(soap_element(xml_buf, "wsdd:Types", G_TYPES_VAL_STR, NULL)); /* wsdd:Scopes */ SOAP_IF_FAIL_RET(soap_out_scopes_item(xml_buf)); /* wsdd:XAddrs */ len = snprintf(tmp_str, sizeof(tmp_str), "http://%s:%d/onvif/device_service", ip_str, ONVIF_PORT_FOR_MAIN); if (len < 0 || len >= sizeof(tmp_str)) { return ERROR; } SOAP_IF_FAIL_RET(soap_element(xml_buf, "wsdd:XAddrs", tmp_str, NULL)); /* wsdd:MetadataVersion */ SOAP_IF_FAIL_RET(soap_element(xml_buf, "wsdd:MetadataVersion", "1", NULL)); SOAP_IF_FAIL_RET(soap_element_end_out(xml_buf, "wsdd:Hello")); return OK; } /****************************************************************************** * 函数名称: soap_out_wsdd_probe_match_type() * 函数描述: 组装wsdd:ProbeMatch element内容 * 输 入: xml_buf -- 存放输出xml字串的内存地址 * 输 出: N/A * 返 回 值: ERROR/OK ******************************************************************************/ LOCAL S32 soap_out_wsdd_probe_match_type(ONVIF_BUF *xml_buf) { S32 len = 0; char tmp_str[LEN_INFO] = {0}; char ip_str[LEN_IP] = {0}; char mac_str[LEN_MAC] = {0}; if (xml_buf == NULL) { ONVIF_WARN("xml_buf == NULL."); return ERROR; } SOAP_IF_FAIL_RET(onvif_get_ip_str(ip_str, LEN_IP)); SOAP_IF_FAIL_RET(onvif_get_mac_str(mac_str, LEN_MAC, FALSE)); /* wsdd:ProbeMatch begin */ SOAP_IF_FAIL_RET(soap_element_begin_out(xml_buf, "wsdd:ProbeMatch", NULL)); /* wsa:EndpointReference */ len = snprintf(tmp_str, sizeof(tmp_str), "uuid:%s%s", UUID_PREFIX_FMAT, mac_str); if (len < 0 || len >= sizeof(tmp_str)) { return ERROR; } SOAP_IF_FAIL_RET(soap_out_wsa_endpoint_reference(xml_buf, "wsa:EndpointReference", tmp_str)); /* wsdd:Types */ SOAP_IF_FAIL_RET(soap_element(xml_buf, "wsdd:Types", G_TYPES_VAL_STR, NULL)); /* wsdd:Scopes */ SOAP_IF_FAIL_RET(soap_out_scopes_item(xml_buf)); /* wsdd:XAddrs */ len = snprintf(tmp_str, sizeof(tmp_str), "http://%s:%d/onvif/device_service", ip_str, ONVIF_PORT_FOR_MAIN); if (len < 0 || len >= sizeof(tmp_str)) { return ERROR; } SOAP_IF_FAIL_RET(soap_element(xml_buf, "wsdd:XAddrs", tmp_str, NULL)); /* wsdd:MetadataVersion */ SOAP_IF_FAIL_RET(soap_element(xml_buf, "wsdd:MetadataVersion", "1", NULL)); /* wsdd:ProbeMatch end */ SOAP_IF_FAIL_RET(soap_element_end_out(xml_buf, "wsdd:ProbeMatch")); return OK; } /****************************************************************************** * 函数名称: soap_out_wsdd_probe_matches() * 函数描述: 组装wsdd:ProbeMatches element内容 * 输 入: xml_buf -- 存放输出xml字串的内存地址 * data -- 为空 * 输 出: N/A * 返 回 值: ERROR/OK ******************************************************************************/ LOCAL S32 soap_out_wsdd_probe_matches(ONVIF_BUF *xml_buf, void *data) { if (xml_buf == NULL) { ONVIF_WARN("xml_buf == NULL."); return ERROR; } /* wsdd:ProbeMatches begin */ SOAP_IF_FAIL_RET(soap_element_begin_out(xml_buf, "wsdd:ProbeMatches", NULL)); /* wsdd:ProbeMatch */ SOAP_IF_FAIL_RET(soap_out_wsdd_probe_match_type(xml_buf)); /* wsdd:ProbeMatches end */ SOAP_IF_FAIL_RET(soap_element_end_out(xml_buf, "wsdd:ProbeMatches")); return OK; } /********************************************************************************* * Soap wsdd req parse *********************************************************************************/ /****************************************************************************** * 函数名称: soap_wsdd_probe_req_parse() * 函数描述: 解析发现报文的具体内容 * 输 入: soap -- soap结构体 * req_buf -- 请求内容 * buf_len -- 请求内容长度 * 输 出: N/A * 返 回 值: ERROR/OK ******************************************************************************/ LOCAL S32 soap_wsdd_probe_req_parse(SOAP_CONTEXT *soap, char **req_buf, S32 buf_len) { S32 ch = 0; char charbuf[LEN_INFO] = {0}; char *str_start = NULL; char **p = req_buf; if (soap == NULL) { ONVIF_TRACE("soap == NULL."); return ERROR; } if (req_buf == NULL || *req_buf == NULL || buf_len <= 0) { ONVIF_TRACE("no request context to parse."); return OK; } str_start = *req_buf; while (((*p) - str_start) < buf_len) { if ((ch = soap_get_tag(str_start, buf_len, p, charbuf, sizeof(charbuf))) == EOF) { goto error_parse; } if (charbuf[0] == &#39;/&#39;) { continue; } if (TRUE == soap_match_tag(charbuf, "Types")) { if (OK != soap_parse_element_value(str_start, buf_len, p, ch, soap->types, sizeof(soap->types))) { goto error_parse; } ONVIF_TRACE("Types: %s", soap->types); } if (TRUE == soap_match_tag(charbuf, "Scopes")) { if (OK != soap_parse_element_value(str_start, buf_len, p, ch, soap->scopes_item, sizeof(soap->scopes_item))) { goto error_parse; } ONVIF_TRACE("Scopes: %s", soap->scopes_item); } if (TRUE == soap_match_tag(charbuf, "MatchBy")) { if (OK != soap_parse_element_value(str_start, buf_len, p, ch, soap->scopes_matchby, sizeof(soap->scopes_matchby))) { goto error_parse; } ONVIF_TRACE("MatchBy: %s", soap->scopes_matchby); } } return OK; error_parse: return ERROR; } /****************************************************************************** * 函数名称: soap_wsdd_hello() * 函数描述: 发送onvif Hello报文 * 输 入: soap -- soap结构体 * 输 出: N/A * 返 回 值: ERROR/OK ******************************************************************************/ S32 soap_wsdd_hello(SOAP_CONTEXT *soap) { if (soap == NULL) { ONVIF_TRACE("soap == NULL."); return ERROR; } SOAP_IF_FAIL_RET(soap_generate_xml((p_out_fun)(soap_out_wsdd_hello_type), soap, NULL)); return onvif_send_udp_packet(soap->sock, inet_addr(ONVIF_MCAST_IP), htons(ONVIF_PORT_FOR_DISCV), soap->xml_buf.start, (soap->xml_buf.last - soap->xml_buf.start)); } /****************************************************************************** * 函数名称: soap_wsdd_probe_handle() * 函数描述: 发现请求的处理函数 * 输 入: soap -- soap结构体 * 输 出: N/A * 返 回 值: ERROR/OK ******************************************************************************/ LOCAL S32 soap_wsdd_probe_handle(SOAP_CONTEXT *soap) { S32 request_len = 0; BOOL match = FALSE; char *xml_buf = NULL; char **xml_str = NULL; char ifname[LEN_IFNAME] = {0}; S32 scopes_matchby_flag = 0; if (soap == NULL) { ONVIF_WARN("soap == NULL."); return ERROR; } if (onvif_get_discv_mode() == DIS_MODE_NO) { ONVIF_DEBUG("discover mode is non-discoverable."); return OK; } if (soap->request_begin != NULL && soap->request_end != NULL) { request_len = soap->request_end - soap->request_begin; if (request_len < 0) { ONVIF_WARN("request_len < 0."); return ERROR; } xml_buf = soap->request_begin; xml_str = (char **)&xml_buf; if (strstr(xml_buf, "<d:Scopes MatchBy=\"http://schemas.xmlsoap.org/ws/2005/04/discovery/rfc3986\"></d:Scopes>") != NULL) { scopes_matchby_flag = 1; } } else { ONVIF_ERROR("soap request content is NULL."); return ERROR; } if (OK != soap_wsdd_probe_req_parse(soap, xml_str, request_len)) { return ERROR; } if (soap->types[0] != &#39;\0&#39;) { if(0 == strcmp("tds:Device", soap->types) || 0 == strcmp("tdn:NetworkVideoTransmitter", soap->types) || 0 == strcmp("dn:NetworkVideoTransmitter", soap->types)) { match = TRUE; } else if(0 == strcmp("dn:NetworkVideoRecorder", soap->types) || 0 == strcmp("tdn:NetworkVideoRecorder", soap->types)) { return OK; } } else { match = TRUE; } if (match) { if (onvif_get_netdevice_name(soap->ifindex, ifname, LEN_IFNAME) == 0 && strncmp(ifname, IFNAME_AP, LEN_IFNAME) != 0) { /* 通知IPCD进行probe IP的跟随修改 */ NSD_SEND(NSD_PROBE_IP, (U8*)(&soap->in_ip), sizeof(soap->in_ip)); } } if (soap->scopes_item[0] != &#39;\0&#39;) { if (soap->scopes_matchby[0] != &#39;\0&#39;) { if (soap->has_header) { snprintf(soap->header.wsa_action, sizeof(soap->header.wsa_action), "http://schemas.xmlsoap.org/ws/2005/04/discovery/fault"); snprintf(soap->header.wsa_to, sizeof(soap->header.wsa_to), "http://schemas.xmlsoap.org/ws/2005/04/addressing/role/anonymous"); } soap_fault(soap, "SOAP-ENV:Sender", "wsdd:MatchingRuleNotSupported", NULL, "the matching rule specified is not supported"); soap->error = SOAP_FAULT; return ERROR; } if (0 != soap_check_scope(soap->scopes_item)) { return ERROR; } } if (scopes_matchby_flag == 1) { if (soap->has_header) { snprintf(soap->header.wsa_action, sizeof(soap->header.wsa_action), "http://schemas.xmlsoap.org/ws/2005/04/discovery/fault"); snprintf(soap->header.wsa_to, sizeof(soap->header.wsa_to), "http://schemas.xmlsoap.org/ws/2005/04/addressing/role/anonymous"); } soap_fault(soap, "SOAP-ENV:Sender", "wsdd:MatchingRuleNotSupported", NULL, "the matching rule specified is not supported"); soap->error = SOAP_FAULT; return ERROR; } //SOAP_IF_FAIL_RET(soap_generate_xml((p_out_fun)(soap_out_wsdd_probe_matches), soap, NULL)); //return onvif_send_udp_packet(soap->sock, soap->in_ip, htons(ONVIF_PORT_FOR_DISCV), // soap->xml_buf.start, (soap->xml_buf.last - soap->xml_buf.start)); if (soap->header.wsa_relates_to[0] == &#39;\0&#39;) { snprintf(soap->header.wsa_relates_to, sizeof(soap->header.wsa_relates_to), "%s", soap->header.wsa_msg_id); } if (soap->header.wsa_action[0] != &#39;\0&#39;) { onvif_str_append_chr(soap->header.wsa_action, sizeof(soap->header.wsa_action), "Matches"); } return soap_generate_xml((p_out_fun)(soap_out_wsdd_probe_matches), soap, NULL); } /********************************************************************************* * Soap wsdd Handles init *********************************************************************************/ void soap_wsdd_handle_init() { soap_tag_handle_add("Probe", soap_wsdd_probe_handle); } ——这个能不能详解一下,尤其是要讲清楚每个函数的功能及输入输出,整个模块的结构/功能以及对外接口
08-31
标题基于Python的自主学习系统后端设计与实现AI更换标题第1章引言介绍自主学习系统的研究背景、意义、现状以及本文的研究方法和创新点。1.1研究背景与意义阐述自主学习系统在教育技术领域的重要性和应用价值。1.2国内外研究现状分析国内外在自主学习系统后端技术方面的研究进展。1.3研究方法与创新点概述本文采用Python技术栈的设计方法和系统创新点。第2章相关理论与技术总结自主学习系统后端开发的相关理论和技术基础。2.1自主学习系统理论阐述自主学习系统的定义、特征和理论基础。2.2Python后端技术栈介绍DjangoFlask等Python后端框架及其适用场景。2.3数据库技术讨论关系型和非关系型数据库在系统中的应用方案。第3章系统设计与实现详细介绍自主学习系统后端的设计方案和实现过程。3.1系统架构设计提出基于微服务的系统架构设计方案。3.2核心模块设计详细说明用户管理、学习资源管理、进度跟踪等核心模块设计。3.3关键技术实现阐述个性化推荐算法、学习行为分析等关键技术的实现。第4章系统测试与评估对系统进行功能测试和性能评估。4.1测试环境与方法介绍测试环境配置和采用的测试方法。4.2功能测试结果展示各功能模块的测试结果和问题修复情况。4.3性能评估分析分析系统在高并发等场景下的性能表现。第5章结论与展望总结研究成果并提出未来改进方向。5.1研究结论概括系统设计的主要成果和技术创新。5.2未来展望指出系统局限性并提出后续优化方向。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值