Пример #1
0
func Save(db *sqlite3.Conn, table string, uid string, obj *jason.Object) error {
	handle_err := func(col string, e error) {
		if e != nil {
			logger.Error("Error inserting %v into %v: %v", col, table, e.Error())
		}
	}

	err := db.Exec(fmt.Sprintf("insert or ignore into %v ( uid ) values (?)", table), uid)
	handle_err("", err)
	for k, v := range obj.Map() {
		if k == "uid" {
			continue
		}
		// Are we a string or a number?
		if i, err := v.Int64(); err == nil {
			err = db.Exec(fmt.Sprintf("update %v set %v = ? where uid = ?", table, k), i, uid)
			handle_err(k, err)
		}
		if f, err := v.Float64(); err == nil {
			err = db.Exec(fmt.Sprintf("update %v set %v = ? where uid = ?", table, k), f, uid)
			handle_err(k, err)
		}
		if s, err := v.String(); err == nil {
			err = db.Exec(fmt.Sprintf("update %v set %v = ? where uid = ?", table, k), s, uid)
			handle_err(k, err)
		}
		if arr, err := obj.GetFloat64Array(k); err == nil {
			s := fmt.Sprintf("%v", arr)
			err = db.Exec(fmt.Sprintf("update %v set %v = ? where uid = ?", table, k), s, uid)
			handle_err(k, err)
		}
	}
	return err
}
Пример #2
0
// Internal helper function to get a string from a jason.Object
func jasonGetString(o *jason.Object, key string) string {
	if o == nil || key == "" {
		return ""
	}
	v, _ := o.GetString(key)
	return v
}
Пример #3
0
// Internal helper function to get a string slice from a jason.Object
func jasonGetStringArray(o *jason.Object, key string) []string {
	if o == nil || key == "" {
		return []string{}
	}
	v, _ := o.GetStringArray(key)
	return v
}
Пример #4
0
func PrintLsFromJSON(json *jason.Object, version int, long bool, blobs bool, item string) {

	var thisVersion int

	blobArray, _ := json.GetObjectArray("Blobs")
	versionArray, _ := json.GetObjectArray("Versions")

	// if version set to zero, use lastest, else use the one given

	if version == 0 {
		thisVersion = len(versionArray)
	} else {
		thisVersion = version
	}

	// Find the version in the JSON, and its subtending slot map

	versionElement := versionArray[thisVersion-1]
	slotMap, _ := versionElement.GetObject("Slots")

	// sort the Slot Keys (filenames) in an array

	keyMap := []string{}

	for key, _ := range slotMap.Map() {
		keyMap = append(keyMap, key)

	}

	sort.Strings(keyMap)

	// Print the slots in the sorted order

	if long {
		fmt.Println("Blob       Size Date                 Creator File")
		fmt.Println("-------------------------------------------------------------------------------------")
	}

	for i := range keyMap {

		if long {
			blobID, _ := slotMap.GetInt64(keyMap[i])
			itemSize, _ := blobArray[blobID-1].GetInt64("Size")
			saveDate, _ := blobArray[blobID-1].GetString("SaveDate")
			creator, _ := blobArray[blobID-1].GetString("Creator")

			fmt.Printf("%03d %12d %s %-8s ", blobID, itemSize, strings.Split(strings.Replace(saveDate, "T", " ", 1), ".")[0], creator)
		}

		fmt.Printf("%s/", item)

		if version != 0 {
			fmt.Printf("@%d/", thisVersion)
		}

		fmt.Printf("%s ", keyMap[i])
		fmt.Printf("\n")
	}
}
Пример #5
0
// Return device make/model from json imageinfo object.
func extractCamera(imageinfo *jason.Object) (string, string) {
	metadata, err := imageinfo.GetObjectArray("commonmetadata")
	if err != nil {
		// metadata is null in some cases
		return "", ""
	} else {
		return findCamera(metadata)
	}
}
Пример #6
0
// CheckAPIKey performs a test API call with the API key
// provided in the configuration file to determine if the
// service should be enabled.
func (yt *YouTube) CheckAPIKey() error {
	var (
		response *http.Response
		v        *jason.Object
		err      error
	)

	if viper.GetString("api_keys.youtube") == "" {
		return errors.New("No YouTube API key has been provided")
	}
	url := "https://www.googleapis.com/youtube/v3/videos?part=snippet&id=KQY9zrjPBjo&key=%s"
	response, err = http.Get(fmt.Sprintf(url, viper.GetString("api_keys.youtube")))
	defer response.Body.Close()
	if err != nil {
		return err
	}

	if v, err = jason.NewObjectFromReader(response.Body); err != nil {
		return err
	}

	if v, err = v.GetObject("error"); err == nil {
		message, _ := v.GetString("message")
		code, _ := v.GetInt64("code")
		errArray, _ := v.GetObjectArray("errors")
		reason, _ := errArray[0].GetString("reason")

		return fmt.Errorf("%d: %s (reason: %s)", code, message, reason)
	}
	return nil
}
Пример #7
0
func PrintListFromJSON(json *jason.Object) {

	versionArray, _ := json.GetObjectArray("Versions")

	for _, version := range versionArray {
		versionID, _ := version.GetInt64("ID")
		saveDate, _ := version.GetString("SaveDate")
		creator, _ := version.GetString("Creator")
		note, _ := version.GetString("Note")

		if note == "" {
			note = "\"\""
		}

		fmt.Printf("@%02d %s %s %s\n", versionID, strings.Split(strings.Replace(saveDate, "T", " ", 1), ".")[0], creator, note)
	}
}
Пример #8
0
// Return page data from JSON, or nil if page is "-1", i.e., not found.
// Assumes only a single page was requested.
func GetJsonPage(json *jason.Object) *jason.Object {
	pages, err := json.GetObject("query", "pages")
	if err != nil {
		panic(err)
	}
	for key, value := range pages.Map() {
		if key == "-1" {
			return nil
		} else {
			valueObj, err := value.Object()
			if err != nil {
				panic(err)
			}
			return valueObj
		}
	}
	panic("getJsonPage fallthrough")
}
Пример #9
0
func (yt *YouTube) getTrack(id string, submitter *gumble.User, offset time.Duration) (bot.Track, error) {
	var (
		resp *http.Response
		err  error
		v    *jason.Object
	)

	videoURL := "https://www.googleapis.com/youtube/v3/videos?part=snippet,contentDetails&id=%s&key=%s"
	resp, err = http.Get(fmt.Sprintf(videoURL, id, viper.GetString("api_keys.youtube")))
	defer resp.Body.Close()
	if err != nil {
		return bot.Track{}, err
	}

	v, err = jason.NewObjectFromReader(resp.Body)
	if err != nil {
		return bot.Track{}, err
	}
	items, _ := v.GetObjectArray("items")
	if len(items) == 0 {
		return bot.Track{}, errors.New("This YouTube video is private")
	}
	item := items[0]
	title, _ := item.GetString("snippet", "title")
	thumbnail, _ := item.GetString("snippet", "thumbnails", "high", "url")
	author, _ := item.GetString("snippet", "channelTitle")
	durationString, _ := item.GetString("contentDetails", "duration")
	durationConverted, _ := duration.FromString(durationString)
	duration := durationConverted.ToDuration()

	return bot.Track{
		ID:             id,
		URL:            "https://youtube.com/watch?v=" + id,
		Title:          title,
		Author:         author,
		Submitter:      submitter.Name,
		Service:        yt.ReadableName,
		Filename:       id + ".track",
		ThumbnailURL:   thumbnail,
		Duration:       duration,
		PlaybackOffset: offset,
		Playlist:       nil,
	}, nil
}
Пример #10
0
func MakeStubFromJSON(json *jason.Object, item string, pathPrefix string) {

	versionArray, _ := json.GetObjectArray("Versions")

	thisVersion := len(versionArray)

	// Find the version in the JSON, and its subtending slot map

	versionElement := versionArray[thisVersion-1]
	slotMap, _ := versionElement.GetObject("Slots")

	for key, _ := range slotMap.Map() {
		targetFile := path.Join(pathPrefix, key)

		// create target directory, return on error

		targetDir, _ := path.Split(targetFile)

		err := os.MkdirAll(targetDir, 0755)

		if err != nil {
			fmt.Printf("Error: could not create directory %s\n%s\n", err.Error())
			return
		}

		filePtr, err := os.Create(targetFile)

		if err != nil {
			fmt.Printf("Error: could not file directory %s\n%s\n", err.Error())
			return
		}

		err = filePtr.Close()

		if err != nil {
			fmt.Printf("Error: could not close file %s\n%s\n", err.Error())
			return
		}

		fmt.Println(targetFile)
	}

}
Пример #11
0
func (f *FileList) BuildListFromJSON(json *jason.Object) {

	blobArray, _ := json.GetObjectArray("Blobs")
	versionArray, _ := json.GetObjectArray("Versions")

	// build lovely mapping of md5 to blobs
	for _, blob := range blobArray {
		md5Sum, _ := blob.GetString("MD5")
		DecodedMD5, _ := base64.StdEncoding.DecodeString(md5Sum)
		blobID, _ := blob.GetInt64("ID")
		f.Blobs[hex.EncodeToString(DecodedMD5)] = blobID
	}

	for _, version := range versionArray {
		versionID, _ := version.GetInt64("ID")
		slotMap, _ := version.GetObject("Slots")

		for key, _ := range slotMap.Map() {

			blobID, _ := slotMap.GetInt64(key)
			md5Sum, _ := blobArray[blobID-1].GetString("MD5")
			DecodedMD5, _ := base64.StdEncoding.DecodeString(md5Sum)

			innerMap, ok := f.Files[key]

			if !ok {
				innerMap = make(map[int64][]byte)
				f.Files[key] = innerMap
			}

			f.Files[key][blobID] = DecodedMD5

			// maps files in latest version to their blobs
			if versionID == int64(len(versionArray)) {
				f.Blobs[key] = blobID
			}
		}
	}
}
Пример #12
0
// GetTracks uses the passed URL to find and return
// tracks associated with the URL. An error is returned
// if any error occurs during the API call.
func (sc *SoundCloud) GetTracks(url string, submitter *gumble.User) ([]interfaces.Track, error) {
	var (
		apiURL string
		err    error
		resp   *http.Response
		v      *jason.Object
		track  bot.Track
		tracks []interfaces.Track
	)

	urlSplit := strings.Split(url, "#t=")

	apiURL = "http://api.soundcloud.com/resolve?url=%s&client_id=%s"

	if sc.isPlaylist(url) {
		// Submitter has added a playlist!
		resp, err = http.Get(fmt.Sprintf(apiURL, urlSplit[0], viper.GetString("api_keys.soundcloud")))
		defer resp.Body.Close()
		if err != nil {
			return nil, err
		}

		v, err = jason.NewObjectFromReader(resp.Body)
		if err != nil {
			return nil, err
		}

		title, _ := v.GetString("title")
		permalink, _ := v.GetString("permalink_url")
		playlist := &bot.Playlist{
			ID:        permalink,
			Title:     title,
			Submitter: submitter.Name,
			Service:   sc.ReadableName,
		}

		var scTracks []*jason.Object
		scTracks, err = v.GetObjectArray("tracks")
		if err != nil {
			return nil, err
		}

		dummyOffset, _ := time.ParseDuration("0s")
		for _, t := range scTracks {
			track, err = sc.getTrack(t, dummyOffset, submitter)
			if err != nil {
				// Skip this track.
				continue
			}
			track.Playlist = playlist
			tracks = append(tracks, track)
		}

		if len(tracks) == 0 {
			return nil, errors.New("Invalid playlist. No tracks were added")
		}
		return tracks, nil
	}

	// Submitter has added a track!

	offset := 0
	// Calculate track offset if needed
	if len(urlSplit) == 2 {
		timeSplit := strings.Split(urlSplit[1], ":")
		multiplier := 1
		for i := len(timeSplit) - 1; i >= 0; i-- {
			time, _ := strconv.Atoi(timeSplit[i])
			offset += time * multiplier
			multiplier *= 60
		}
	}
	playbackOffset, _ := time.ParseDuration(fmt.Sprintf("%ds", offset))

	resp, err = http.Get(fmt.Sprintf(apiURL, urlSplit[0], viper.GetString("api_keys.soundcloud")))
	defer resp.Body.Close()
	if err != nil {
		return nil, err
	}

	v, err = jason.NewObjectFromReader(resp.Body)
	if err != nil {
		return nil, err
	}
	track, err = sc.getTrack(v, playbackOffset, submitter)
	if err != nil {
		return nil, err
	}

	tracks = append(tracks, track)
	return tracks, nil
}
Пример #13
0
func (sc *SoundCloud) getTrack(obj *jason.Object, offset time.Duration, submitter *gumble.User) (bot.Track, error) {
	title, _ := obj.GetString("title")
	idInt, _ := obj.GetInt64("id")
	id := strconv.FormatInt(idInt, 10)
	url, _ := obj.GetString("permalink_url")
	author, _ := obj.GetString("user", "username")
	authorURL, _ := obj.GetString("user", "permalink_url")
	durationMS, _ := obj.GetInt64("duration")
	duration, _ := time.ParseDuration(fmt.Sprintf("%dms", durationMS))
	thumbnail, err := obj.GetString("artwork_url")
	if err != nil {
		// Track has no artwork, using profile avatar instead.
		thumbnail, _ = obj.GetString("user", "avatar_url")
	}

	return bot.Track{
		ID:             id,
		URL:            url,
		Title:          title,
		Author:         author,
		AuthorURL:      authorURL,
		Submitter:      submitter.Name,
		Service:        sc.ReadableName,
		Filename:       id + ".track",
		ThumbnailURL:   thumbnail,
		Duration:       duration,
		PlaybackOffset: offset,
		Playlist:       nil,
	}, nil
}
Пример #14
0
// GetTracks uses the passed URL to find and return
// tracks associated with the URL. An error is returned
// if any error occurs during the API call.
func (yt *YouTube) GetTracks(url string, submitter *gumble.User) ([]interfaces.Track, error) {
	var (
		playlistURL      string
		playlistItemsURL string
		id               string
		err              error
		resp             *http.Response
		v                *jason.Object
		track            bot.Track
		tracks           []interfaces.Track
	)

	playlistURL = "https://www.googleapis.com/youtube/v3/playlists?part=snippet&id=%s&key=%s"
	playlistItemsURL = "https://www.googleapis.com/youtube/v3/playlistItems?part=snippet,contentDetails&playlistId=%s&maxResults=%d&key=%s&pageToken=%s"
	id, err = yt.getID(url)
	if err != nil {
		return nil, err
	}

	if yt.isPlaylist(url) {
		resp, err = http.Get(fmt.Sprintf(playlistURL, id, viper.GetString("api_keys.youtube")))
		defer resp.Body.Close()
		if err != nil {
			return nil, err
		}

		v, err = jason.NewObjectFromReader(resp.Body)
		if err != nil {
			return nil, err
		}

		items, _ := v.GetObjectArray("items")
		item := items[0]

		title, _ := item.GetString("snippet", "title")

		playlist := &bot.Playlist{
			ID:        id,
			Title:     title,
			Submitter: submitter.Name,
			Service:   yt.ReadableName,
		}

		maxItems := math.MaxInt32
		if viper.GetInt("queue.max_tracks_per_playlist") > 0 {
			maxItems = viper.GetInt("queue.max_tracks_per_playlist")
		}

		pageToken := ""
		for len(tracks) < maxItems {
			curResp, curErr := http.Get(fmt.Sprintf(playlistItemsURL, id, maxItems, viper.GetString("api_keys.youtube"), pageToken))
			defer curResp.Body.Close()
			if curErr != nil {
				// An error occurred, simply skip this track.
				continue
			}

			v, err = jason.NewObjectFromReader(curResp.Body)
			if err != nil {
				// An error occurred, simply skip this track.
				continue
			}

			curTracks, _ := v.GetObjectArray("items")
			for _, track := range curTracks {
				videoID, _ := track.GetString("snippet", "resourceId", "videoId")

				// Unfortunately we have to execute another API call for each video as the YouTube API does not
				// return video durations from the playlistItems endpoint...
				newTrack, _ := yt.getTrack(videoID, submitter)
				newTrack.Playlist = playlist
				tracks = append(tracks, newTrack)

				if len(tracks) >= maxItems {
					break
				}
			}
		}

		if len(tracks) == 0 {
			return nil, errors.New("Invalid playlist. No tracks were added")
		}
		return tracks, nil
	}

	track, err = yt.getTrack(id, submitter)
	if err != nil {
		return nil, err
	}
	tracks = append(tracks, track)
	return tracks, nil
}
Пример #15
0
Файл: where.go Проект: aiyi/go
func parseCondition(v *jason.Object) (c *Condition, err error) {
	conds, err := v.Object()
	if conds == nil {
		fmt.Println("get conds failed")
		return nil, err
	}

	c = &Condition{}

	for ck, cv := range conds.Map() {
		ea := &[]Expression{}

		eo, err := cv.Object()
		if err != nil {
			// cv is value
			e := &Expression{}
			e.op = "$eq"

			switch cv.Interface().(type) {
			case []interface{}:
				e.value, _ = cv.Array()
			case bool:
				e.value, _ = cv.Boolean()
			case string:
				e.value, _ = cv.String()
			case json.Number:
				e.value, _ = cv.Number()
			default:
				continue
				/*
					e.value = cv.Interface()
					fmt.Println(cv, " unsupported type ",
						reflect.ValueOf(cv.Interface()).Type())
				*/
			}

			*ea = append(*ea, *e)
		} else {
			// cv is a object
			i := 0
			for ek, ev := range eo.Map() {
				e := &Expression{}
				e.op = ek

				switch ev.Interface().(type) {
				case []interface{}:
					e.value, _ = ev.Array()
				case bool:
					e.value, _ = ev.Boolean()
				case string:
					e.value, _ = ev.String()
				case json.Number:
					e.value, _ = ev.Number()
				default:
					continue
					/*
						e.value = ev.Interface()
						fmt.Println(ev, " unsupported type ",
							reflect.ValueOf(ev.Interface()).Type())
					*/
				}

				*ea = append(*ea, *e)
				i += 1
			}
		}

		(*c)[ck] = ea
	}

	return c, nil
}
Пример #16
0
// GetTracks uses the passed URL to find and return
// tracks associated with the URL. An error is returned
// if any error occurs during the API call.
func (mc *Mixcloud) GetTracks(url string, submitter *gumble.User) ([]interfaces.Track, error) {
	var (
		apiURL string
		err    error
		resp   *http.Response
		v      *jason.Object
		tracks []interfaces.Track
	)

	apiURL = strings.Replace(url, "www", "api", 1)

	// Track playback offset is not present in Mixcloud URLs,
	// so we can safely assume that users will not request
	// a playback offset in the URL.
	offset, _ := time.ParseDuration("0s")

	resp, err = http.Get(apiURL)
	defer resp.Body.Close()
	if err != nil {
		return nil, err
	}

	v, err = jason.NewObjectFromReader(resp.Body)
	if err != nil {
		return nil, err
	}

	id, _ := v.GetString("slug")
	trackURL, _ := v.GetString("url")
	title, _ := v.GetString("name")
	author, _ := v.GetString("user", "username")
	authorURL, _ := v.GetString("user", "url")
	durationSecs, _ := v.GetInt64("audio_length")
	duration, _ := time.ParseDuration(fmt.Sprintf("%ds", durationSecs))
	thumbnail, err := v.GetString("pictures", "large")
	if err != nil {
		// Track has no artwork, using profile avatar instead.
		thumbnail, _ = v.GetString("user", "pictures", "large")
	}

	track := bot.Track{
		ID:             id,
		URL:            trackURL,
		Title:          title,
		Author:         author,
		AuthorURL:      authorURL,
		Submitter:      submitter.Name,
		Service:        mc.ReadableName,
		ThumbnailURL:   thumbnail,
		Filename:       id + ".track",
		Duration:       duration,
		PlaybackOffset: offset,
		Playlist:       nil,
	}

	tracks = append(tracks, track)

	return tracks, nil
}