Widget SiriKit intent enum value for index - sirikit

I'm trying to add another SiriKit intent to my Widget to allow user to select a reddit category such as top, hot, new etc. I've set my enum in my custom intents. My question is how do I get the display name from the index? It's being assigned to a URL string so the rawValue won't work. I attempted to use Sort(rawValue:configuration.sort.rawValue)! with the same results https://www.reddit.com/r/swiftui/1.json. I need the url to behttps://www.reddit.com/r/swiftui/hot.json.

I ended up creating an Int enum containing the same as in my intentdefinition. Then created an extension for my enum to return a string value for the intent's rawValue. I was mistaken that my intentdefinition would provide me a string value for the index.
enum SortBy : Int {
case hot = 1
case new
case controversial
case top
case rising
}
extension SortBy {
var sortValue: String {
switch self {
case .hot:
return "hot"
case .new:
return "new"
case .controversial:
return "controversial"
case .top:
return "top"
case .rising:
return "rising"
}
}
}
SortBy(rawValue: configuration.sort.rawValue)!

Related

Convert user input value into string in QML

I have my function checkPinCode() that will check the user entered pincode with the actual pincode.
Here I am facing a problem to get the user entered input value into string. Since the text field has the pincode as string. So i need to convert the user entered input also to a string during the comparison. How can I convert my pincodeSetting.value to a string. And I am new to QML. It would be nice if some one helps.
function checkPinCode() {
var pinOk = (pinCodeEdit.text === NTModelDBCpp.systemSettings.pincodeSetting.value)
if (false === pinOk) {
pinCodeEdit.text = "";
invalidPinText.visible = true;
}
return pinOk;
move this function(checkPinCode) in your c++ class and do your work in your c++ code
bool NTModelDBCpp::checkPinCode(int pincode){
return pincode === value;
}
and use in qml.the convertion will done automatically.
if(NTModelDBCpp.checkPinCode(yourText){
}
define the checkPinCode as static method in your .h c++ file

JSON Lists not removing duplicates with Distinct command

Currently I am querying a web service that returns a JSON string.
url = #"redacted url;
returnValue = new WebClient().DownloadString(url);
I am putting the return results into a list of items defined in a model class. I am then running a second JSON call searching a different field with that same search term.
url2 = #"redacted url2;
returnValue2 = new WebClient().DownloadString(url2);
I then create my lists and combine the lists using AddRange.
List<Order> shipments = JsonConvert.DeserializeObject<List<Order>>(returnValue);
List<Order> shipments2 = JsonConvert.DeserializeObject<List<Order>>(returnValue2);
shipments.AddRange(shipments2);
As a result there are some duplicates. To try and only return unique records I am using the command Distinct when sending to my MVC view from the controller.
return View(shipments.OrderBy(x => x.dtDateReceived).Distinct().ToList());
But for some reason it's still returning duplicates.
Any ideas on what I am doing wrong here?
Thanks in advance for any help!
I ended up correcting it using Shyju's comment above.
I changed the Distinct to the following.
return View(shipments.OrderBy(x => x.dtDateReceived).Distinct(new OrderComparer()).ToList());
Then built the following compare functions
// Custom comparer for the Order class
class OrderComparer : IEqualityComparer<Order>
{
// Orders are equal if their names and order numbers are equal.
public bool Equals(Order x, Order y)
{
//Check whether the compared objects reference the same data.
if (Object.ReferenceEquals(x, y)) return true;
//Check whether any of the compared objects is null.
if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
return false;
//Check whether the order's properties are equal.
return x.sWorkOrderNumber == y.sWorkOrderNumber && x.sCustomerOrderName == y.sCustomerOrderName;
}
// If Equals() returns true for a pair of objects
// then GetHashCode() must return the same value for these objects.
public int GetHashCode(Order order)
{
//Check whether the object is null
if (Object.ReferenceEquals(order, null)) return 0;
//Get hash code for the sCustomerOrderName field if it is not null.
int hashOrderName = order.sCustomerOrderName == null ? 0 : order.sCustomerOrderName.GetHashCode();
//Get hash code for the sWorkOrderNumber field.
int hashOrderCode = order.sWorkOrderNumber.GetHashCode();
//Calculate the hash code for the order.
return hashOrderName ^ hashOrderCode;
}
}

Why does Spring LDAP's LdapTemplate not return title, department & company attributes?

I'm using spring-ldap-core-2.3.1.RELEASE.jar over JDK 1.8 & Tomcat 8.0 to access AD information through LdapTemplate. The attributes such as title,department & company are not being returned by the ldapTemplate.search(..,.,..) method.
I'm using the following lines of code to search :-
LdapQuery ldapQuery = LdapQueryBuilder.query()
.where("objectclass").is("user")
.and("objectcategory").is("person")
.and("cn").like(strWildcardText+"*");
ldapTemplate.search(ldapQuery, new ADUserAttributesMapper());
Following is the ADUserAttributesMapper class :-
public class ADUserAttributesMapper implements AttributesMapper<ADUserBean> {
#Override
public ADUserBean mapFromAttributes(Attributes attributes) throws NamingException {
if(attributes==null) {
return null;
}
adUserBean.setName((attributes.get("name")!=null) ? attributes.get("name").get().toString() : null);
adUserBean.setCommonName((attributes.get("cn")!=null) ? attributes.get("cn").get().toString() : null);
adUserBean.setDisplayName((attributes.get("displayname")!=null) ? attributes.get("displayname").get().toString() : null);
adUserBean.setGivenName((attributes.get("givenname")!=null) ? attributes.get("givenname").get().toString() : null); // for FIRST NAME
adUserBean.setMiddleName((attributes.get("initials")!=null) ? attributes.get("initials").get().toString() : null); // for MIDDLE NAME / INITIALS
adUserBean.setLastName((attributes.get("sn")!=null) ? attributes.get("sn").get().toString() : null); // for LAST NAME
adUserBean.setDepartment((attributes.get("department")!=null) ? attributes.get("department").get().toString() : null);
adUserBean.setUserPrincipalName((attributes.get("userprincipalname")!=null) ? attributes.get("userprincipalname").get().toString() : null); // Logon Name
adUserBean.setsAMAccountName((attributes.get("samaccountname")!=null) ? attributes.get("samaccountname").get().toString() : null); // Logon Name (pre-Windows 2000)
adUserBean.setDistinguishedName((attributes.get("distinguishedname")!=null) ? attributes.get("distinguishedname").get().toString() : null);
adUserBean.setMailID((attributes.get("mail")!=null) ? attributes.get("mail").get().toString() : null);
adUserBean.setTitle((attributes.get("title")!=null) ? attributes.get("title").get().toString() : null); // Job Title
adUserBean.setTelephoneNumber((attributes.get("telephonenumber")!=null) ? attributes.get("telephonenumber").get().toString() : null);
adUserBean.setObjectCategory((attributes.get("objectcategory")!=null) ? attributes.get("objectcategory").get().toString() : null);
return adUserBean;
}
}
The title,department & company attributes belong to the Organization tab of the AD user properties as shown in the below image :-
Also, from the General tab the initials(initials) attribute is not being picked up/listed by Spring-LDAP's ldapTemplate. The LdapQueryBuilder.query() object has access to attributes(...) method that takes a string array of attribute names that are to be fetched. But even after mentioning them there explicitly, values for attributes such as initials, title, department & company are not returned.
The LDAP Browser plugin within the Eclipse IDE lists the title,department & company properties under the Organization tab without a problem.
Even the com4j API returns the title, department & company attributes.
Is there any configuration that is limiting the attribute(s) listing or is it a limitation with Spring-LDAP API itself? Are these attributes not part of BasicAttributes? How to fetch these attributes through Spring-LDAP?
UPDATE (01-Aug-2017):
The plain Java JNDI approach/code does NOT return department,company,title attributes (even with these attributes being explicitly mentioned in attributes string array), but surprisingly it does return the initials attribute value.
UPDATE (02-Aug-2017):
Similar to #Pierre's suggestion (below) tried the following code using SearchControls object :-
String strFilter= "(&(objectclass=top)(cn=cgma*))";
String[] attrs = new String[] {"cn","givenName","sn","initials","title","department","company"};
long maxResults = 10; // for example
SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
searchControls.setReturningAttributes(attrs);
searchControls.setCountLimit(maxResults);
List<String> aLstOfADUsers = ldapTemplate.search("",strFilter,searchControls,new AttributesMapper<String>()
{
public String mapFromAttributes(Attributes attrs) throws NamingException {
try
{
System.out.println(attrs.toString());
return attrs.get("cn").get().toString();
}
catch(Exception ex) {
ex.printStackTrace();
return null;
}
}
});
return aLstOfADUsers;
Even this does not return the initials, title, company & department attribute values.
The person attributes might be internal attributes which you wouldn't get back by default. You can specify explicitly which attributes you want returned BUT not in the search method you're using (the one where you pass in an LdapQuery object). If you take a look at the org.springframework.ldap.core.LdapTemplate class, it doesn't seem like you can pass in the SearchControls object to the method signature you're using. So, to be able to specify attributes to fetch, replace this:
LdapQuery ldapQuery = LdapQueryBuilder.query()
.where("objectclass").is("user")
.and("objectcategory").is("person")
.and("cn").like(strWildcardText+"*");
ldapTemplate.search(ldapQuery, new ADUserAttributesMapper());
With this:
LikeFilter filter = new LikeFilter("cn", strWildcardText+"*");
// list of attributes to retrieve
String[] attrs = new String[] {"title","department","company"};
long maxResults = 10; // for example
SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
searchControls.setReturningAttributes(attrs);
searchControls.setCountLimit(numResults);
ldapTemplate.search(DistinguishedName.EMPTY_PATH, filter.encode(), searchControls, new ADUserAttributesMapper());
The above should work. You could also try something like this (I haven't tried that yet):
ldapTemplate.search( "dc=yourorg,dc=com",
"(&(cn=" +strWildcardText + "*)(&(objectClass=person)(objectcategory=person)))",
SearchControls.SUBTREE_SCOPE,
new String[]{ "title","department","company" },
new ADUserAttributesMapper() );
Finally, to get ALL attributes back, ask to retrieve ALL attributes in the code above (my above example only asked for 3 attributes, this would return ALL of them):
String[] attrs = new String[]{"*","+"};
This is based on your AttributesMapper. I don't know what ADUserAttributesMapper is, so you'd have to provide that implementation.
Here's the javadoc for this interface. http://docs.spring.io/spring-ldap/docs/current/apidocs/org/springframework/ldap/core/AttributesMapper.html
Change ldap port from 3268 to 389

How to skip displaying a content item in Orchard CMS?

I have a content part that provides a begin timestamp and end timestamp option. These 2 fields are used to define a period of time in which the content item should be displayed.
I now have difficulties to implement a skip approach whereas content items should not be displayed / skipped when the period of time does not span the current time.
Digging in the source code and trying to find an entry point for my approach resulted in the following content handler
public class SkipContentHandler : Orchard.ContentManagement.Handlers.ContentHandler
{
protected override void BuildDisplayShape(Orchard.ContentManagement.Handlers.BuildDisplayContext aContext)
{
if (...) // my condition to process only content shapes which need to be skipped
{
aContext.Shape = null; // return null shape to skip it
}
}
}
This works but there are several side effects
I had to alter the source code of BuildDisplayContext as the Shape is normally read only
List shape may displayed a wrong pager when it contains content items with my content part because the Count() call in ContainerPartDriver.Display() is executed before BuildDisplay()
calling the URL of a content item that is skipped results in an exception because View(null) is abigious
So, what would be the correct approach here or is there any module in existence that does the job? I couldn't find one.
This is a quite complex task. There are several steps needed to achieve a proper skipping of display items:
Create the part correctly
There are a few pitfalls here as when coming to the task of adding a part view one might utilize Orchards date time editor in connection with the DateTime properties. But this brings a heck of a lot of additional issues to the table but these don't really relate to the question.
If someone is interested in how to use Orchards date time editor then i can post this code too, but for now it would only blow up the code unnecessarly.
So here we go, the part class...
public class ValidityPart : Orchard.ContentManagement.ContentPart<ValidityPartRecord>
{
// public
public System.DateTime? ValidFromUtc
{
get { return Retrieve(r => r.ValidFromUtc); }
set { Store(r => r.ValidFromUtc, value); }
}
...
public System.DateTime? ValidTillUtc
{
get { return Retrieve(r => r.ValidTillUtc); }
set { Store(r => r.ValidTillUtc, value); }
}
...
public bool IsContentItemValid()
{
var lUtcNow = System.DateTime.UtcNow;
return (ValidFromUtc == null || ValidFromUtc.Value <= lUtcNow) && (ValidTillUtc == null || ValidTillUtc.Value >= lUtcNow);
}
...
}
...and the record class...
public class ValidityPartRecord : Orchard.ContentManagement.Records.ContentPartRecord
{
// valid from value as UTC to use Orchard convention (see CommonPart table) and to be compatible with projections
// (date/time tokens work with UTC values, see https://github.com/OrchardCMS/Orchard/issues/6963 for a related issue)
public virtual System.DateTime? ValidFromUtc { get; set; }
// valid from value as UTC to use Orchard convention (see CommonPart table) and to be compatible with projections
// (date/time tokens work with UTC values, see https://github.com/OrchardCMS/Orchard/issues/6963 for a related issue)
public virtual System.DateTime? ValidTillUtc { get; set; }
}
Create a customized content query class
public class MyContentQuery : Orchard.ContentManagement.DefaultContentQuery
{
// public
public ContentQuery(Orchard.ContentManagement.IContentManager aContentManager,
Orchard.Data.ITransactionManager aTransactionManager,
Orchard.Caching.ICacheManager aCacheManager,
Orchard.Caching.ISignals aSignals,
Orchard.Data.IRepository<Orchard.ContentManagement.Records.ContentTypeRecord> aContentTypeRepository,
Orchard.IWorkContextAccessor aWorkContextAccessor)
: base(aContentManager, aTransactionManager, aCacheManager, aSignals, aContentTypeRepository)
{
mWorkContextAccessor = aWorkContextAccessor;
}
protected override void BeforeExecuteQuery(NHibernate.ICriteria aContentItemVersionCriteria)
{
base.BeforeExecuteQuery(aContentItemVersionCriteria);
// note:
// this method will be called each time a query for multiple items is going to be executed (e.g. content items of a container, layers, menus),
// this gives us the chance to add a validity criteria
var lWorkContext = mWorkContextAccessor.GetContext();
// exclude admin as content items should still be displayed / accessible when invalid as validity needs to be editable
if (lWorkContext == null || !Orchard.UI.Admin.AdminFilter.IsApplied(lWorkContext.HttpContext.Request.RequestContext))
{
var lUtcNow = System.DateTime.UtcNow;
// left outer join of ValidityPartRecord table as part is optional (not present on all content types)
var ValidityPartRecordCriteria = aContentItemVersionCriteria.CreateCriteria(
"ContentItemRecord.ValidityPartRecord", // string adopted from foreach loops in Orchard.ContentManagement.DefaultContentQuery.WithQueryHints()
NHibernate.SqlCommand.JoinType.LeftOuterJoin
);
// add validity criterion
ValidityPartRecordCriteria.Add(
NHibernate.Criterion.Restrictions.And(
NHibernate.Criterion.Restrictions.Or(
NHibernate.Criterion.Restrictions.IsNull("ValidFromUtc"),
NHibernate.Criterion.Restrictions.Le("ValidFromUtc", lUtcNow)
),
NHibernate.Criterion.Restrictions.Or(
NHibernate.Criterion.Restrictions.IsNull("ValidTillUtc"),
NHibernate.Criterion.Restrictions.Ge("ValidTillUtc", lUtcNow)
)
)
);
}
}
// private
Orchard.IWorkContextAccessor mWorkContextAccessor;
}
This essentially adds a left join of the validity part fields to the SQL query (content query) and extends the WHERE statement with the validity condition.
Please note that this step is only possible with the solution described the following issue: https://github.com/OrchardCMS/Orchard/issues/6978
Register the content query class
public class ContentModule : Autofac.Module
{
protected override void Load(Autofac.ContainerBuilder aBuilder)
{
aBuilder.RegisterType<MyContentQuery>().As<Orchard.ContentManagement.IContentQuery>().InstancePerDependency();
}
}
Create a customized content manager
public class ContentManager : Orchard.ContentManagement.DefaultContentManager
{
// public
public ContentManager(
Autofac.IComponentContext aContext,
Orchard.Data.IRepository<Orchard.ContentManagement.Records.ContentTypeRecord> aContentTypeRepository,
Orchard.Data.IRepository<Orchard.ContentManagement.Records.ContentItemRecord> aContentItemRepository,
Orchard.Data.IRepository<Orchard.ContentManagement.Records.ContentItemVersionRecord> aContentItemVersionRepository,
Orchard.ContentManagement.MetaData.IContentDefinitionManager aContentDefinitionManager,
Orchard.Caching.ICacheManager aCacheManager,
System.Func<Orchard.ContentManagement.IContentManagerSession> aContentManagerSession,
System.Lazy<Orchard.ContentManagement.IContentDisplay> aContentDisplay,
System.Lazy<Orchard.Data.ITransactionManager> aTransactionManager,
System.Lazy<System.Collections.Generic.IEnumerable<Orchard.ContentManagement.Handlers.IContentHandler>> aHandlers,
System.Lazy<System.Collections.Generic.IEnumerable<Orchard.ContentManagement.IIdentityResolverSelector>> aIdentityResolverSelectors,
System.Lazy<System.Collections.Generic.IEnumerable<Orchard.Data.Providers.ISqlStatementProvider>> aSqlStatementProviders,
Orchard.Environment.Configuration.ShellSettings aShellSettings,
Orchard.Caching.ISignals aSignals,
Orchard.IWorkContextAccessor aWorkContextAccessor)
: base(aContext, aContentTypeRepository, aContentItemRepository, aContentItemVersionRepository, aContentDefinitionManager, aCacheManager, aContentManagerSession,
aContentDisplay, aTransactionManager, aHandlers, aIdentityResolverSelectors, aSqlStatementProviders, aShellSettings, aSignals)
{
mWorkContextAccessor = aWorkContextAccessor;
}
public override ContentItem Get(int aId, Orchard.ContentManagement.VersionOptions aOptions, Orchard.ContentManagement.QueryHints aHints)
{
var lResult = base.Get(aId, aOptions, aHints);
if (lResult != null)
{
// note:
// the validity check is done here (after the query has been executed!) as changing base.GetManyImplementation() to
// apply the validity critera directly to the query (like in ContentQuery) will not work due to a second attempt to retrieve the
// content item from IRepository<> (see base.GetManyImplementation(), comment "check in memory") when the query
// returns no data (and the query should not return data when the validity critera is false)
//
// http://stackoverflow.com/q/37841249/3936440
var lWorkContext = mWorkContextAccessor.GetContext();
// exclude admin as content items should still be displayed / accessible when invalid as validity needs to be editable
if (lWorkContext == null || !Orchard.UI.Admin.AdminFilter.IsApplied(lWorkContext.HttpContext.Request.RequestContext))
{
var lValidityPart = lResult.As<ValidityPart>();
if (lValidityPart != null)
{
if (lValidityPart.IsContentItemValid())
{
// content item is valid
}
else
{
// content item is not valid, return null (adopted from base.Get())
lResult = null;
}
}
}
}
return lResult;
}
// private
Orchard.IWorkContextAccessor mWorkContextAccessor;
}
Steps 2-4 are needed when having content items whereas the content type has a Container and Containable part or even content items which are processed / displayed separately. Here you normally cannot customize the content query that is executed behind the scenes.
Steps 2-4 are not needed if you use the Projection module. But again, this brings a few other issues to the table as reported in this issue: https://github.com/OrchardCMS/Orchard/issues/6979

N2: Set default values for ContentItems

When using N2 CMS:
If I want to set some default values when a new ContentItem is created (e.g. setting the CreatedByUser value for a new Page so I can record who originally created it) where is the best place to put that code?
I figure the constructor of the ContentItem isn't ideal because that will get called when existing objects are loaded.
If you're using the Get/SetDetail syntax then you can do something like this in the property getter:
public virtual string TopImage
{
get { return (string)(GetDetail("TopImage") ?? string.Empty); }
set { SetDetail("TopImage", value); }
}
That's a bit ugly, so there's also an overload for Get/Set detail that lets you specify the default:
public virtual string TopImage
{
get { return GetDetail("TopImage", String.Empty /* Default */); }
set { SetDetail("TopImage", value, String.Empty /* Default */); }
}
If you want to save a value when something is saved then try overriding the AddTo method on the ContentItem. This is called every time the object is saved, so be careful if you only want to call it the first time something is saved (ID == 0 when an Item is "new")

Resources