func (res *Resource) SearchAttrs(columns ...string) []string { if len(columns) > 0 { res.searchAttrs = columns res.SearchHandler = func(keyword string, context *qor.Context) *gorm.DB { db := context.GetDB() var conditions []string var keywords []interface{} scope := db.NewScope(res.Value) for _, column := range columns { if field, ok := scope.FieldByName(column); ok { switch field.Field.Kind() { case reflect.String: conditions = append(conditions, fmt.Sprintf("upper(%v) like upper(?)", scope.Quote(field.DBName))) keywords = append(keywords, "%"+keyword+"%") case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: if _, err := strconv.Atoi(keyword); err == nil { conditions = append(conditions, fmt.Sprintf("%v = ?", scope.Quote(field.DBName))) keywords = append(keywords, keyword) } case reflect.Float32, reflect.Float64: if _, err := strconv.ParseFloat(keyword, 64); err == nil { conditions = append(conditions, fmt.Sprintf("%v = ?", scope.Quote(field.DBName))) keywords = append(keywords, keyword) } case reflect.Struct: // time ? if _, ok := field.Field.Interface().(time.Time); ok { if parsedTime, err := now.Parse(keyword); err == nil { conditions = append(conditions, fmt.Sprintf("%v = ?", scope.Quote(field.DBName))) keywords = append(keywords, parsedTime) } } case reflect.Ptr: // time ? if _, ok := field.Field.Interface().(*time.Time); ok { if parsedTime, err := now.Parse(keyword); err == nil { conditions = append(conditions, fmt.Sprintf("%v = ?", scope.Quote(field.DBName))) keywords = append(keywords, parsedTime) } } default: conditions = append(conditions, fmt.Sprintf("%v = ?", scope.Quote(field.DBName))) keywords = append(keywords, keyword) } } } if len(conditions) > 0 { return context.GetDB().Where(strings.Join(conditions, " OR "), keywords...) } else { return context.GetDB() } } } return res.searchAttrs }
/* date format 2015-01-23 */ func GetChartData(table, start, end string) (res []Chart) { startdate, err := now.Parse(start) if err != nil { return } enddate, err := now.Parse(end) if err != nil || enddate.UnixNano() < startdate.UnixNano() { enddate = now.EndOfDay() } else { enddate = enddate.AddDate(0, 0, 1) } db.DB.Table(table).Where("created_at > ? AND created_at < ?", startdate, enddate).Select("date(created_at) as date, count(*) as total").Group("date(created_at)").Order("date(created_at)").Scan(&res) return }
// GetLeadChanges get a series of changes based on a data/time string and list ID func GetLeadChanges(req Requester, dateTime string, listID string, fields string) (leadChanges *LeadChange, err error) { tNow, err := now.Parse(dateTime) if err != nil { logrus.Error("couldn't parse date-time: ", err) return nil, err } dateTime = tNow.Format("2006-01-02T15:04-0800") token, err := getPagingToken(req, dateTime) if err != nil { return nil, err } urlQuery := url.Values{} urlQuery.Set("nextPageToken", token) urlQuery.Set("fields", fields) urlQuery.Set("listId", listID) url := fmt.Sprintf("activities/leadchanges.json?%s", urlQuery.Encode()) logrus.Debug("url: ", url) body, err := req.Get(url) if err != nil { return nil, err } logrus.Debug("Body: ", string(body)) err = json.Unmarshal(body, &leadChanges) if err != nil { logrus.Error("Error with JSON: ", err) } return leadChanges, err }
// DefaultOrRawTimestamp will compare the timestamp and the raw timestamp to // each other and return the given timestamp if the raw and the timestamp are // the same. Else it will parse the raw timestamp and return that. This is // mostly used for determining if a timestamp flag was given or not (see // commands package). func DefaultOrRawTimestamp(timestamp time.Time, raw string) (time.Time, error) { if timestamp.String() == raw { return timestamp, nil } parsed, err := now.Parse(raw) if err != nil { return time.Time{}, errgo.Notef(err, "can not parse timestamp") } return parsed, nil }
func parse(response string) (record *Record, err error) { for _, line := range strings.Split(response, "\n") { line = strings.TrimSpace(line) if line == "" || !strings.Contains(line, ":") { continue } parts := strings.SplitN(line, ":", 2) key, value := strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1]) if strings.ToLower(key) == "creation date" || strings.ToLower(key) == "changed" || strings.ToLower(key) == "domain create date" { if parsedDate, parseErr := now.Parse(value); parseErr != nil { err = parseErr } else { record = &Record{CreatedOn: parsedDate, Registered: true} } return } } return nil, errors.New("Unable to parse whois record") }
// GetActivity get a series of activities based on a data/time string and optional list/leads ID func GetActivity(req Requester, activityReq ActivityRequest) (activities *Activity, err error) { if activityReq.ActivityTypeID == "" { logrus.Error("Missing activity ID") return nil, errors.New("missing activity ID") } tNow, err := now.Parse(activityReq.DateTime) if err != nil { logrus.Error("couldn't parse date-time: ", err) return nil, err } activityReq.DateTime = tNow.Format("2006-01-02T15:04-0800") token, err := getPagingToken(req, activityReq.DateTime) if err != nil { return nil, err } urlQuery := url.Values{} urlQuery.Set("nextPageToken", token) urlQuery.Set("activityTypeIds", activityReq.ActivityTypeID) if activityReq.ListID != "" { urlQuery.Set("listId", activityReq.ListID) } if len(activityReq.LeadIDs) > 0 { for _, leadID := range activityReq.LeadIDs { urlQuery.Add("leadIds", leadID) } } url := fmt.Sprintf("activities.json?%s", urlQuery.Encode()) logrus.Debug("url: ", url) body, err := req.Get(url) if err != nil { return nil, err } logrus.Debug("Body: ", string(body)) err = json.Unmarshal(body, &activities) if err != nil { logrus.Error("Error with JSON: ", err) } return activities, err }
func (res *Resource) SearchAttrs(columns ...string) []string { if len(columns) != 0 || res.searchAttrs == nil { if len(columns) == 0 { columns = res.ConvertSectionToStrings(res.indexSections) } if len(columns) > 0 { res.searchAttrs = &columns res.SearchHandler = func(keyword string, context *qor.Context) *gorm.DB { db := context.GetDB() var joinConditionsMap = map[string][]string{} var conditions []string var keywords []interface{} scope := db.NewScope(res.Value) for _, column := range columns { currentScope, nextScope := scope, scope if strings.Contains(column, ".") { for _, field := range strings.Split(column, ".") { column = field currentScope = nextScope if field, ok := scope.FieldByName(field); ok { if relationship := field.Relationship; relationship != nil { nextScope = currentScope.New(reflect.New(field.Field.Type()).Interface()) key := fmt.Sprintf("LEFT JOIN %v ON", nextScope.TableName()) for index := range relationship.ForeignDBNames { if relationship.Kind == "has_one" || relationship.Kind == "has_many" { joinConditionsMap[key] = append(joinConditionsMap[key], fmt.Sprintf("%v.%v = %v.%v", nextScope.QuotedTableName(), scope.Quote(relationship.ForeignDBNames[index]), currentScope.QuotedTableName(), scope.Quote(relationship.AssociationForeignDBNames[index]), )) } else if relationship.Kind == "belongs_to" { joinConditionsMap[key] = append(joinConditionsMap[key], fmt.Sprintf("%v.%v = %v.%v", currentScope.QuotedTableName(), scope.Quote(relationship.ForeignDBNames[index]), nextScope.QuotedTableName(), scope.Quote(relationship.AssociationForeignDBNames[index]), )) } } } } } } var tableName = currentScope.Quote(currentScope.TableName()) if field, ok := currentScope.FieldByName(column); ok && field.IsNormal { switch field.Field.Kind() { case reflect.String: conditions = append(conditions, fmt.Sprintf("upper(%v.%v) like upper(?)", tableName, scope.Quote(field.DBName))) keywords = append(keywords, "%"+keyword+"%") case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: if _, err := strconv.Atoi(keyword); err == nil { conditions = append(conditions, fmt.Sprintf("%v.%v = ?", tableName, scope.Quote(field.DBName))) keywords = append(keywords, keyword) } case reflect.Float32, reflect.Float64: if _, err := strconv.ParseFloat(keyword, 64); err == nil { conditions = append(conditions, fmt.Sprintf("%v.%v = ?", tableName, scope.Quote(field.DBName))) keywords = append(keywords, keyword) } case reflect.Bool: if value, err := strconv.ParseBool(keyword); err == nil { conditions = append(conditions, fmt.Sprintf("%v.%v = ?", tableName, scope.Quote(field.DBName))) keywords = append(keywords, value) } case reflect.Struct: // time ? if _, ok := field.Field.Interface().(time.Time); ok { if parsedTime, err := now.Parse(keyword); err == nil { conditions = append(conditions, fmt.Sprintf("%v.%v = ?", tableName, scope.Quote(field.DBName))) keywords = append(keywords, parsedTime) } } case reflect.Ptr: // time ? if _, ok := field.Field.Interface().(*time.Time); ok { if parsedTime, err := now.Parse(keyword); err == nil { conditions = append(conditions, fmt.Sprintf("%v.%v = ?", tableName, scope.Quote(field.DBName))) keywords = append(keywords, parsedTime) } } default: conditions = append(conditions, fmt.Sprintf("%v.%v = ?", tableName, scope.Quote(field.DBName))) keywords = append(keywords, keyword) } } } // join conditions if len(joinConditionsMap) > 0 { var joinConditions []string for key, values := range joinConditionsMap { joinConditions = append(joinConditions, fmt.Sprintf("%v %v", key, strings.Join(values, " AND "))) } db = db.Joins(strings.Join(joinConditions, " ")) } // search conditions if len(conditions) > 0 { return db.Where(strings.Join(conditions, " OR "), keywords...) } else { return db } } } } return columns }
func (meta *Meta) updateMeta() { if meta.Name == "" { utils.ExitWithMsg("Meta should have name: %v", reflect.ValueOf(meta).Type()) } else if meta.Alias == "" { meta.Alias = meta.Name } if meta.Label == "" { meta.Label = utils.HumanizeString(meta.Name) } var ( scope = &gorm.Scope{Value: meta.base.Value} nestedField = strings.Contains(meta.Alias, ".") field *gorm.StructField hasColumn bool ) if nestedField { subModel, name := utils.ParseNestedField(reflect.ValueOf(meta.base.Value), meta.Alias) subScope := &gorm.Scope{Value: subModel.Interface()} field, hasColumn = getField(subScope.GetStructFields(), name) } else { if field, hasColumn = getField(scope.GetStructFields(), meta.Alias); hasColumn { meta.Alias = field.Name if field.IsNormal { meta.DBName = field.DBName } } } var fieldType reflect.Type if hasColumn { fieldType = field.Struct.Type for fieldType.Kind() == reflect.Ptr { fieldType = fieldType.Elem() } } // Set Meta Type if meta.Type == "" && hasColumn { if relationship := field.Relationship; relationship != nil { if relationship.Kind == "has_one" { meta.Type = "single_edit" } else if relationship.Kind == "has_many" { meta.Type = "collection_edit" } else if relationship.Kind == "belongs_to" { meta.Type = "select_one" } else if relationship.Kind == "many_to_many" { meta.Type = "select_many" } } else { switch fieldType.Kind().String() { case "string": if size, ok := utils.ParseTagOption(field.Tag.Get("sql"))["SIZE"]; ok { if i, _ := strconv.Atoi(size); i > 255 { meta.Type = "text" } else { meta.Type = "string" } } else if text, ok := utils.ParseTagOption(field.Tag.Get("sql"))["TYPE"]; ok && text == "text" { meta.Type = "text" } else { meta.Type = "string" } case "bool": meta.Type = "checkbox" default: if regexp.MustCompile(`^(.*)?(u)?(int)(\d+)?`).MatchString(fieldType.Kind().String()) { meta.Type = "number" } else if regexp.MustCompile(`^(.*)?(float)(\d+)?`).MatchString(fieldType.Kind().String()) { meta.Type = "float" } else if _, ok := reflect.New(fieldType).Interface().(*time.Time); ok { meta.Type = "datetime" } else if _, ok := reflect.New(fieldType).Interface().(media_library.MediaLibrary); ok { meta.Type = "file" } } } } // Set Meta Resource if meta.Resource == nil { if hasColumn && (field.Relationship != nil) { var result interface{} if fieldType.Kind().String() == "struct" { result = reflect.New(fieldType).Interface() } else if fieldType.Kind().String() == "slice" { refelectType := fieldType.Elem() for refelectType.Kind() == reflect.Ptr { refelectType = refelectType.Elem() } result = reflect.New(refelectType).Interface() } res := meta.base.GetAdmin().NewResource(result) res.compile() meta.Resource = res } } // Set Meta Valuer if meta.Valuer == nil { if hasColumn { meta.Valuer = func(value interface{}, context *qor.Context) interface{} { scope := context.GetDB().NewScope(value) alias := meta.Alias if nestedField { fields := strings.Split(alias, ".") alias = fields[len(fields)-1] } if f, ok := scope.FieldByName(alias); ok { if field.Relationship != nil { if f.Field.CanAddr() && !scope.PrimaryKeyZero() { context.GetDB().Model(value).Related(f.Field.Addr().Interface(), meta.Alias) } } if f.Field.CanAddr() { return f.Field.Addr().Interface() } else { return f.Field.Interface() } } return "" } } else { utils.ExitWithMsg("Unsupported meta name %v for resource %v", meta.Name, reflect.TypeOf(meta.base.Value)) } } scopeField, _ := scope.FieldByName(meta.Alias) // Set Meta Collection if meta.Collection != nil { if maps, ok := meta.Collection.([]string); ok { meta.GetCollection = func(interface{}, *qor.Context) (results [][]string) { for _, value := range maps { results = append(results, []string{value, value}) } return } } else if maps, ok := meta.Collection.([][]string); ok { meta.GetCollection = func(interface{}, *qor.Context) [][]string { return maps } } else if f, ok := meta.Collection.(func(interface{}, *qor.Context) [][]string); ok { meta.GetCollection = f } else { utils.ExitWithMsg("Unsupported Collection format for meta %v of resource %v", meta.Name, reflect.TypeOf(meta.base.Value)) } } else if meta.Type == "select_one" || meta.Type == "select_many" { if scopeField.Relationship != nil { fieldType := scopeField.StructField.Struct.Type if fieldType.Kind() == reflect.Slice { fieldType = fieldType.Elem() } meta.GetCollection = func(value interface{}, context *qor.Context) (results [][]string) { values := reflect.New(reflect.SliceOf(fieldType)).Interface() context.GetDB().Find(values) reflectValues := reflect.Indirect(reflect.ValueOf(values)) for i := 0; i < reflectValues.Len(); i++ { scope := scope.New(reflectValues.Index(i).Interface()) primaryKey := fmt.Sprintf("%v", scope.PrimaryKeyValue()) results = append(results, []string{primaryKey, utils.Stringify(reflectValues.Index(i).Interface())}) } return } } else { utils.ExitWithMsg("%v meta type %v needs Collection", meta.Name, meta.Type) } } if meta.Setter == nil && hasColumn { if relationship := field.Relationship; relationship != nil { if meta.Type == "select_one" || meta.Type == "select_many" { meta.Setter = func(resource interface{}, metaValue *resource.MetaValue, context *qor.Context) { scope := &gorm.Scope{Value: resource} reflectValue := reflect.Indirect(reflect.ValueOf(resource)) field := reflectValue.FieldByName(meta.Alias) if field.Kind() == reflect.Ptr { if field.IsNil() { field.Set(utils.NewValue(field.Type()).Elem()) } for field.Kind() == reflect.Ptr { field = field.Elem() } } primaryKeys := utils.ToArray(metaValue.Value) // associations not changed for belongs to if relationship.Kind == "belongs_to" && len(relationship.ForeignFieldNames) == 1 { oldPrimaryKeys := utils.ToArray(reflectValue.FieldByName(relationship.ForeignFieldNames[0]).Interface()) // if not changed if equalAsString(primaryKeys, oldPrimaryKeys) { return } // if removed if len(primaryKeys) == 0 { field := reflectValue.FieldByName(relationship.ForeignFieldNames[0]) field.Set(reflect.Zero(field.Type())) } } if len(primaryKeys) > 0 { context.GetDB().Where(primaryKeys).Find(field.Addr().Interface()) } // Replace many 2 many relations if relationship.Kind == "many_to_many" { if !scope.PrimaryKeyZero() { context.GetDB().Model(resource).Association(meta.Alias).Replace(field.Interface()) field.Set(reflect.Zero(field.Type())) } } } } } else { meta.Setter = func(resource interface{}, metaValue *resource.MetaValue, context *qor.Context) { if metaValue == nil { return } value := metaValue.Value alias := meta.Alias if nestedField { fields := strings.Split(alias, ".") alias = fields[len(fields)-1] } field := reflect.Indirect(reflect.ValueOf(resource)).FieldByName(alias) if field.Kind() == reflect.Ptr { if field.IsNil() { field.Set(utils.NewValue(field.Type()).Elem()) } for field.Kind() == reflect.Ptr { field = field.Elem() } } if field.IsValid() && field.CanAddr() { switch field.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: field.SetInt(utils.ToInt(value)) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: field.SetUint(utils.ToUint(value)) case reflect.Float32, reflect.Float64: field.SetFloat(utils.ToFloat(value)) case reflect.Bool: // TODO: add test if utils.ToString(value) == "true" { field.SetBool(true) } else { field.SetBool(false) } default: if scanner, ok := field.Addr().Interface().(sql.Scanner); ok { if scanner.Scan(value) != nil { scanner.Scan(utils.ToString(value)) } } else if reflect.TypeOf("").ConvertibleTo(field.Type()) { field.Set(reflect.ValueOf(utils.ToString(value)).Convert(field.Type())) } else if reflect.TypeOf([]string{}).ConvertibleTo(field.Type()) { field.Set(reflect.ValueOf(utils.ToArray(value)).Convert(field.Type())) } else if rvalue := reflect.ValueOf(value); reflect.TypeOf(rvalue.Type()).ConvertibleTo(field.Type()) { field.Set(rvalue.Convert(field.Type())) } else if _, ok := field.Addr().Interface().(*time.Time); ok { if str := utils.ToString(value); str != "" { if newTime, err := now.Parse(str); err == nil { field.Set(reflect.ValueOf(newTime)) } } } else { var buf = bytes.NewBufferString("") json.NewEncoder(buf).Encode(value) if err := json.NewDecoder(strings.NewReader(buf.String())).Decode(field.Addr().Interface()); err != nil { utils.ExitWithMsg("Can't set value %v to %v [meta %v]", reflect.ValueOf(value).Type(), field.Type(), meta) } } } } } } } if nestedField { oldvalue := meta.Valuer meta.Valuer = func(value interface{}, context *qor.Context) interface{} { return oldvalue(utils.GetNestedModel(value, meta.Alias, context), context) } oldSetter := meta.Setter meta.Setter = func(resource interface{}, metaValue *resource.MetaValue, context *qor.Context) { oldSetter(utils.GetNestedModel(resource, meta.Alias, context), metaValue, context) } } }
func (f *defaultFeedparserImpl) FetchChannel(channel *models.Channel) error { result, err := fetch(channel.URL) if err != nil { return err } // update channel f.Log.Info("Channel:"+channel.Title, " podcasts:", len(result.Items)) channel.Title = result.Channel.Title channel.Image = result.Channel.Image.Url channel.Description = result.Channel.Description website := result.getWebsiteURL() if website != "" { channel.Website.String = website channel.Website.Valid = true } // we just want unique categories categoryMap := make(map[string]string) for _, category := range result.Channel.Categories { categoryMap[category.Text] = category.Text } var categories []string for _, category := range categoryMap { categories = append(categories, category) } channel.Categories.String = strings.Join(categories, " ") channel.Categories.Valid = true if err := f.DB.Channels.Create(channel); err != nil { return err } for _, item := range result.Items { podcast := &models.Podcast{ ChannelID: channel.ID, Title: item.Title, Description: item.Description, } if len(item.Enclosures) == 0 { continue } podcast.EnclosureURL = item.Enclosures[0].Url if item.Guid == nil { f.Log.Debug("Podcast ID:" + podcast.Title + " has no GUID, using pub date") // use pub date + URL as standin Guid podcast.Guid = item.PubDate + ":" + podcast.EnclosureURL } else { podcast.Guid = *item.Guid } if item.Source != nil { podcast.Source = item.Source.Url } if podcast.Guid == "" { f.Log.Error("Could not find suitable GUID for " + podcast.Title) } var pubDate time.Time // try using the builtin RSS parser first if pubDate, err = item.ParsedPubDate(); err != nil { // try some other parsers pubDate, err = now.Parse(item.PubDate) // pubdate will be "empty", we'll have to live with that // but log anyway to see if we can fix that format if err != nil { f.Log.Error(err) } } podcast.PubDate = pubDate if err = f.DB.Podcasts.Create(podcast); err != nil { return err } } return nil }
func (meta *Meta) Initialize() error { var ( nestedField = strings.Contains(meta.FieldName, ".") field = meta.FieldStruct hasColumn = meta.FieldStruct != nil ) var fieldType reflect.Type if hasColumn { fieldType = field.Struct.Type for fieldType.Kind() == reflect.Ptr { fieldType = fieldType.Elem() } } // Set Meta Valuer if meta.Valuer == nil { if hasColumn { meta.Valuer = func(value interface{}, context *qor.Context) interface{} { scope := context.GetDB().NewScope(value) fieldName := meta.FieldName if nestedField { fields := strings.Split(fieldName, ".") fieldName = fields[len(fields)-1] } if f, ok := scope.FieldByName(fieldName); ok { if f.Relationship != nil && f.Field.CanAddr() && !scope.PrimaryKeyZero() { context.GetDB().Model(value).Related(f.Field.Addr().Interface(), meta.FieldName) } return f.Field.Interface() } return "" } } else { utils.ExitWithMsg("Unsupported meta name %v for resource %v", meta.FieldName, reflect.TypeOf(meta.Resource.GetResource().Value)) } } if meta.Setter == nil && hasColumn { if relationship := field.Relationship; relationship != nil { if relationship.Kind == "belongs_to" || relationship.Kind == "many_to_many" { meta.Setter = func(resource interface{}, metaValue *MetaValue, context *qor.Context) { scope := &gorm.Scope{Value: resource} reflectValue := reflect.Indirect(reflect.ValueOf(resource)) field := reflectValue.FieldByName(meta.FieldName) if field.Kind() == reflect.Ptr { if field.IsNil() { field.Set(utils.NewValue(field.Type()).Elem()) } for field.Kind() == reflect.Ptr { field = field.Elem() } } primaryKeys := utils.ToArray(metaValue.Value) // associations not changed for belongs to if relationship.Kind == "belongs_to" && len(relationship.ForeignFieldNames) == 1 { oldPrimaryKeys := utils.ToArray(reflectValue.FieldByName(relationship.ForeignFieldNames[0]).Interface()) // if not changed if fmt.Sprint(primaryKeys) == fmt.Sprint(oldPrimaryKeys) { return } // if removed if len(primaryKeys) == 0 { field := reflectValue.FieldByName(relationship.ForeignFieldNames[0]) field.Set(reflect.Zero(field.Type())) } } if len(primaryKeys) > 0 { context.GetDB().Where(primaryKeys).Find(field.Addr().Interface()) } // Replace many 2 many relations if relationship.Kind == "many_to_many" { if !scope.PrimaryKeyZero() { context.GetDB().Model(resource).Association(meta.FieldName).Replace(field.Interface()) field.Set(reflect.Zero(field.Type())) } } } } } else { meta.Setter = func(resource interface{}, metaValue *MetaValue, context *qor.Context) { if metaValue == nil { return } value := metaValue.Value fieldName := meta.FieldName if nestedField { fields := strings.Split(fieldName, ".") fieldName = fields[len(fields)-1] } field := reflect.Indirect(reflect.ValueOf(resource)).FieldByName(fieldName) if field.Kind() == reflect.Ptr { if field.IsNil() { field.Set(utils.NewValue(field.Type()).Elem()) } for field.Kind() == reflect.Ptr { field = field.Elem() } } if field.IsValid() && field.CanAddr() { switch field.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: field.SetInt(utils.ToInt(value)) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: field.SetUint(utils.ToUint(value)) case reflect.Float32, reflect.Float64: field.SetFloat(utils.ToFloat(value)) case reflect.Bool: // TODO: add test if utils.ToString(value) == "true" { field.SetBool(true) } else { field.SetBool(false) } default: if scanner, ok := field.Addr().Interface().(sql.Scanner); ok { if scanner.Scan(value) != nil { scanner.Scan(utils.ToString(value)) } } else if reflect.TypeOf("").ConvertibleTo(field.Type()) { field.Set(reflect.ValueOf(utils.ToString(value)).Convert(field.Type())) } else if reflect.TypeOf([]string{}).ConvertibleTo(field.Type()) { field.Set(reflect.ValueOf(utils.ToArray(value)).Convert(field.Type())) } else if rvalue := reflect.ValueOf(value); reflect.TypeOf(rvalue.Type()).ConvertibleTo(field.Type()) { field.Set(rvalue.Convert(field.Type())) } else if _, ok := field.Addr().Interface().(*time.Time); ok { if str := utils.ToString(value); str != "" { if newTime, err := now.Parse(str); err == nil { field.Set(reflect.ValueOf(newTime)) } } } else { var buf = bytes.NewBufferString("") json.NewEncoder(buf).Encode(value) if err := json.NewDecoder(strings.NewReader(buf.String())).Decode(field.Addr().Interface()); err != nil { utils.ExitWithMsg("Can't set value %v to %v [meta %v]", reflect.TypeOf(value), field.Type(), meta) } } } } } } } if nestedField { oldvalue := meta.Valuer meta.Valuer = func(value interface{}, context *qor.Context) interface{} { return oldvalue(getNestedModel(value, meta.FieldName, context), context) } oldSetter := meta.Setter meta.Setter = func(resource interface{}, metaValue *MetaValue, context *qor.Context) { oldSetter(getNestedModel(resource, meta.FieldName, context), metaValue, context) } } return nil }
func (f *feedparserImpl) Fetch(channel *models.Channel) error { result, err := fetch(channel.URL) if err != nil { return err } channel.Title = result.channel.Title channel.Image = result.channel.Image.Url channel.Description = result.channel.Description website := result.getWebsiteURL() if website != "" { channel.Website.String = website channel.Website.Valid = true } // we just want unique categories categoryMap := make(map[string]string) for _, category := range result.channel.Categories { categoryMap[category.Text] = category.Text } var categories []string for _, category := range categoryMap { categories = append(categories, category) } channel.Categories.String = strings.Join(categories, " ") channel.Categories.Valid = true var podcasts []*models.Podcast for _, item := range result.items { podcast := &models.Podcast{ Title: item.Title, Description: item.Description, } podcast.EnclosureURL = item.Enclosures[0].Url if item.Guid == nil { // use pub date + URL as standin Guid podcast.Guid = item.PubDate + ":" + podcast.EnclosureURL } else { podcast.Guid = *item.Guid } if item.Source != nil { podcast.Source = item.Source.Url } var pubDate time.Time // try using the builtin RSS parser first if pubDate, err = item.ParsedPubDate(); err != nil { // try some other parsers pubDate, err = now.Parse(item.PubDate) // pubdate will be "empty", we'll have to live with that } podcast.PubDate = pubDate podcasts = append(podcasts, podcast) } channel.Podcasts = podcasts return nil }